Menu |
|---|
Board style |
|---|
Affiliates |
|---|
Top Posters |
|---|
Newest members |
|---|
|
|
Welcome to Home Brew Games. Registration is simple and free, and gives you access to the whole site. Why not check out our resource manager, our scripting forums, project boards, and everything else we have to offer? We have a team of dedicated staff at hand who are interested and experienced in indie gaming. Any game engine is allowed, though our RPG Maker boards have been the largest of their kind for many years. We have a rich history, and promise a rich future too!
|
Gus' Text Input Module |
Posted by: Gu574v0 » Wed Sep 01, 2010 10:40 am
Forum: Scripts
Gus' Text Input Module Version: 1.00 By: Gustavo Bicalho (Gu574v0; Gust) Introduction Gus' Text Input Module (GTI) is an input module to complement the old ones. It provides a way to capture key presses like a text editor would: with special signs, diacritical marks and respecting the keyboard layout. The old input modules can't do that, so they are not appropriate for text input (like allowing the player to write a name or a memo). On the other side, this input module doesn't track key-ups and downs, so it's not really appropriate for normal game play because you can't get the current state of a key, you can only know which characters were typed since the last update; and it will only pick key presses that create characters. But anyway, GTI won't break any input system, so it can be used together with them. That said, my advice: use a good old input module (or just the default one) for general gameplay, and activate GTI whenever you need text input. I don't know exactly how many people out there wanted to let the player type something and couldn't, but I hope this can be used to make user interface friendlier. Features - Characters typed are read correctly, accordingly to the keyboard layout.
- Won't break the old input modules (unless they have a DLL that also messes with the window procedures, but I don't think any of them does that. Anyway, if that is the case, placing GTI under those scripts should solve the problem.)
- The module is updated automatically by the Input module.
Script Download of the DLL DLL Source Code (if you want to check it out) -
- #================================================================
- # ** GTI - Gus' Text Input for RPG Maker XP/VX
- # (CC-BY) Gustavo Bicalho
- #---------------------------------------------------------------
- # * Version 1.00
- # - First release
- #---------------------------------------------------------------
- # Gus' Text Input (GTI) is an input module to complement the old
- # ones. It provides a way to capture key presses like a text
- # editor would: with special signs, diacritical marks and
- # respecting the keyboard layout. The old input modules can't
- # do that, so they are not appropriate for text input.
- #
- # On the other side, this input module doesn't track key-ups and
- # downs, so it's not appropriate for normal game play because
- # you can't get the current state of a key, you can only know
- # which characters were typed since the last update.
- #
- # Anyway, GTI won't break any input system, so it can be used
- # together with them.
- #
- # That said, my advice: use a good old input module (or just
- # the default one) for general gameplay, and activate GTI
- # whenever you need text input.
- #
- # * PLACE THIS SCRIPT ABOVE MAIN *
- #---------------------------------------------------------------
- # Some Info:
- #
- # 1) GTI is updated automatically by the Input module update.
- # So all you need to do is iterate through the events list
- # (GTI.events) and handle each event. If you call the update
- # method directly, you'll lose the events cought in the previous
- # update. The events list is cleared when the module updates,
- # so don't bother doing that.
- #
- # 2) Each event is an array where the first element is a string
- # containing the character typed (this string can be several
- # bytes long, because of the UTF-8 encoding. But it's one
- # character per event).
- # The second element in the array is the repeat count: when
- # the user holds a key, Windows sometimes will send one event
- # for several "repeats", with the repeat count indicating how
- # many repeats that event represents. Most of the time, however,
- # Windows will send one event per repeat. So you could ignore
- # the repeat count without losing any important info.
- #
- # 3) A few constants are provided which represent common
- # special keys. You should probably make a few other tests to
- # check if a character is printable before writing them to the
- # screen or whatever.
- #
- # 4) GTI is NOT thread-safe. I know almost nobody uses threads
- # in RGSS, but I thought I should warn you anyway.
- #================================================================
- module GTI
- #-------------------------------------------------------------
- # * Special key strings
- #-------------------------------------------------------------
- BACKSPACE = "\010"
- ESCAPE = "\e"
- RETURN = "\r"
-
- #-------------------------------------------------------------
- # * WinApi and GTI DLL constants and callers.
- #-------------------------------------------------------------
- DLL_NAME = 'GusTextInput'
- HookTextInput = Win32API.new(DLL_NAME,'HookTextInput','L','L')
- UnhookTextInput = Win32API.new(DLL_NAME,'UnhookTextInput','','L')
- PopEvent = Win32API.new(DLL_NAME,'PopEvent','P','I')
- GetActiveWindow = Win32API.new('user32', 'GetActiveWindow', '', 'L')
-
- #-------------------------------------------------------------
- # * GTI.running?
- # Returns true if GTI is active, false otherwise.
- #-------------------------------------------------------------
- @@running = false
- def self.running?
- return @@running
- end
-
- #-------------------------------------------------------------
- # * GTI.events
- # Returns the event list, where the events catch at the
- # last update are stored for handling.
- #-------------------------------------------------------------
- @@events = []
- def self.events
- return @@events
- end
-
- #-------------------------------------------------------------
- # * GTI.start
- # Activates the text input.
- #-------------------------------------------------------------
- def self.start
- return if @@running
- # Call the DLL method that activates the text input on
- # the game window
- err = HookTextInput.call(GetActiveWindow.call)
- # err stores the error code. If it's 0, it's ok.
- # If it's different from 0, raises an exception.
- # This will never happen unless you're using another thing
- # that also messes with the window procs, so you don't
- # need to worry.
- raise "Couldn't hook the text input. Error #{err}" if (err != 0)
- @@running = true; # GTI is now running
- end
-
- #-------------------------------------------------------------
- # * GTI.stop
- # Deactivates the text input.
- #-------------------------------------------------------------
- def self.stop
- return if !@@running
- # Call the DLL method that deactivates the text input
- err = UnhookTextInput.call
- # err stores the error code. If it's 0, it's ok.
- # If it's different from 0, raises an exception.
- # This will never happen unless you're using another thing
- # that also messes with the window procs, so you don't
- # need to worry.
- raise "Couldn't unhook the text input. Error #{err}" if (err != 0)
- @@running = false # GTI is not running anymore
- end
-
- #-------------------------------------------------------------
- # * GTI.update
- # Updates the module, popping the events from the DLL event
- # stack and placing them at the event list.
- #-------------------------------------------------------------
- def self.update
- return if !@@running # Stop if GTI is not running
- @@events.clear; # Clear the event list
- # While there are events on the event stack, pop one
- # and add it to the event list.
- while ((c = GTI.pop) != nil)
- @@events.push(c)
- end
- end
-
- private
-
- #-------------------------------------------------------------
- # * GTI.pop
- # Pops an event from the DLL event stack. Users shouldn't
- # call this method. Use the event list instead.
- #-------------------------------------------------------------
- def self.pop
- # Allocate space so the DLL can put its data there
- # The DLL needs a 8-byte string.
- String s = ' '*8
- # Call the PopEvent method from the DLL. It puts the data
- # in the string bytes, and returns the number of bytes
- # used to store the character. This number is up to 4.
- # If it returns 0, there were no events to pop, so
- # return nil.
- return nil if ((ret = PopEvent.call(s)) == 0)
- # Copy the part of s that store the character
- n = s[0,ret]
- # Unpack the string to get its bytes' values. We'll
- # only need the 5th byte (that's the first C), that stores
- # the repeat count for the event.
- s = s.unpack("LCCCC")
- return [n,s[1]] # Array with character and repeat count
- end
-
- end
-
- #================================================================
- # ** Input
- #---------------------------------------------------------------
- # Changes the Input.update method so it calls GTI.update.
- #================================================================
- module Input
- class << self
- unless method_defined?(:gus_gti_input_update)
- alias :gus_gti_input_update :update
-
- def update
- gus_gti_input_update
- GTI.update
- end
- end
- end
- end
-
Expand to see the code. Instructions Place this script above Main, and below the default scripts (and below any scripts with custom DLLs that mess with the window). Place the GusTextInput.dll in the same directory as Game.exe. Whenever you need text input, call GTI.start to start the event processing. You can just leave it running through the whole game, or activate it only in Scenes where you need it and then call GTI.stop to stop it. The latter is probably the best if you need performance. Anyway, once you activate it, you can get the event list (an array) from GTI.events at each update. The list is cleared when the module is updated, so each frame you get only the event of that frame. You can then iterate through the list, processing each event (the first of the list happened first and therefore should be processed first. Just use an each statement). Below is an example of how Scene_Name could be implemented using GTI: - class Scene_Name
-
- def main
- @actor = $game_actors[$game_temp.name_actor_id]
- @edit_window = Window_NameEdit.new(@actor, $game_temp.name_max_char)
- Graphics.transition
- GTI.start # Start Text Input
-
- loop do
- Graphics.update
- Input.update
- update
-
- if $scene != self
- break
- end
- end
-
- GTI.stop # Stop Text Input
- Graphics.freeze
- @edit_window.dispose
- end
-
- #this handles the events as they come
- def handle_input(c)
- if c[0] == GTI::BACKSPACE #if a backspace is received, go back
- @edit_window.back
- return
- elsif c[0] == GTI::RETURN # a return, confirm
- if @edit_window.name == "" # if the box is empty
- @edit_window.restore_default # restore the default name
- $game_system.se_play($data_system.buzzer_se)
- return
- end
- # Set the actor name and go back to the map
- @actor.name = @edit_window.name
- $game_system.se_play($data_system.decision_se)
- $scene = Scene_Map.new
- return
- elsif c[0] == GTI::ESCAPE # escape pressed, back to the map
- $scene = Scene_Map.new
- return
- else # any other key pressed is added to the name
- if @edit_window.index == $game_temp.name_max_char
- $game_system.se_play($data_system.buzzer_se)
- return
- end
- @edit_window.add(c[0]*c[1])
- return
- end
- end
-
- def update
- @edit_window.update
- # Iterate the event list, calling the handler method
- GTI.events.each { |c| handle_input(c) }
- end
- end
-
Expand to see the code. Terms and Conditions - You can redistribute and change this script and the DLL as you wish, as long as you give credit to me (Gustavo Bicalho) as the original creator.
|
|
Views: 106 • Comments: 15 • Write comments
[ Back ] Top
|
|
 |
In total there are 137 users online :: 39 trolls, 0 hidden and 98 guests (based on users active over the past 120 minutes) Most trolls ever online was 521 on Wed Apr 02, 2008 6:25 am
Registered users: Alexander Morou, Ask Jeeves [Bot], Baidu [Spider], benos, berka, blink_, calvin624, Celesinator, Charlie Fleed, creamdonut, dadevster, demuirge, dricc, eatpie75, Exabot [Bot], Fayte, Fenwick, fox5, friend, Glitchfinder, Google [Bot], Google Adsense [Bot], Gu574v0, HarryE, J.D. Slasha, Kelg, Landarma, Loofah, Maria1, MicKo, MSN [Bot], MSNbot Media, showpei, SnowHero, Spooky, swick, Tassadar, windsaver, Yahoo [Bot] |
| Legend :: Administrators, Contest Winner, Global moderators, Moderators, Sponsors, Technical Administrator |
|
Links |
|---|
|