[Fuse-for-macosx-commits] SF.net SVN: fuse-for-macosx:[635] trunk/fuse/fusepb
Brought to you by:
fredm
From: <fr...@us...> - 2010-04-06 11:24:44
|
Revision: 635 http://fuse-for-macosx.svn.sourceforge.net/fuse-for-macosx/?rev=635&view=rev Author: fredm Date: 2010-04-06 11:24:38 +0000 (Tue, 06 Apr 2010) Log Message: ----------- prevents problems with pressing one "special" key and releasing another (because more than one were pressed or shift was released before the key itself) Modified Paths: -------------- trunk/fuse/fusepb/Fuse.xcodeproj/project.pbxproj trunk/fuse/fusepb/models/Emulator.h trunk/fuse/fusepb/models/Emulator.m Added Paths: ----------- trunk/fuse/fusepb/keystate.c trunk/fuse/fusepb/keystate.h Modified: trunk/fuse/fusepb/Fuse.xcodeproj/project.pbxproj =================================================================== --- trunk/fuse/fusepb/Fuse.xcodeproj/project.pbxproj 2010-04-05 13:34:11 UTC (rev 634) +++ trunk/fuse/fusepb/Fuse.xcodeproj/project.pbxproj 2010-04-06 11:24:38 UTC (rev 635) @@ -158,6 +158,8 @@ B631BA0F1025878600BE1EE1 /* opus.rom in Resources */ = {isa = PBXBuildFile; fileRef = B631BA0E1025878600BE1EE1 /* opus.rom */; }; B63225EC0C66BA1300BB081B /* osname.c in Sources */ = {isa = PBXBuildFile; fileRef = B63225EB0C66BA1300BB081B /* osname.c */; }; B63225EE0C66BA3700BB081B /* paths.c in Sources */ = {isa = PBXBuildFile; fileRef = B63225ED0C66BA3700BB081B /* paths.c */; }; + B635EAE7116A0FE500A166F2 /* keystate.c in Sources */ = {isa = PBXBuildFile; fileRef = B635EAE5116A0FE500A166F2 /* keystate.c */; }; + B635EAE8116A0FE500A166F2 /* keystate.h in Headers */ = {isa = PBXBuildFile; fileRef = B635EAE6116A0FE500A166F2 /* keystate.h */; }; B6374FA50F178298003CE6E2 /* timer.c in Sources */ = {isa = PBXBuildFile; fileRef = B6374FA40F178298003CE6E2 /* timer.c */; }; B639B7680A6BAFCF00927E24 /* csw.icns in Resources */ = {isa = PBXBuildFile; fileRef = B639B7670A6BAFCF00927E24 /* csw.icns */; }; B639B7D10A6BB45600927E24 /* raw.icns in Resources */ = {isa = PBXBuildFile; fileRef = B639B7D00A6BB45600927E24 /* raw.icns */; }; @@ -422,6 +424,8 @@ B63225F30C66BA7400BB081B /* timer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = timer.h; sourceTree = "<group>"; }; B632C6AE03E5368700A864FD /* DebuggerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DebuggerController.h; path = controllers/DebuggerController.h; sourceTree = "<group>"; }; B632C6AF03E5368700A864FD /* DebuggerController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DebuggerController.m; path = controllers/DebuggerController.m; sourceTree = "<group>"; }; + B635EAE5116A0FE500A166F2 /* keystate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = keystate.c; sourceTree = SOURCE_ROOT; }; + B635EAE6116A0FE500A166F2 /* keystate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = keystate.h; sourceTree = SOURCE_ROOT; }; B6374FA40F178298003CE6E2 /* timer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = timer.c; path = timer/timer.c; sourceTree = SOURCE_ROOT; }; B6379299060AA0D300246736 /* se-0.rom */ = {isa = PBXFileReference; lastKnownFileType = file; name = "se-0.rom"; path = "../roms/se-0.rom"; sourceTree = SOURCE_ROOT; }; B637929A060AA0D300246736 /* se-1.rom */ = {isa = PBXFileReference; lastKnownFileType = file; name = "se-1.rom"; path = "../roms/se-1.rom"; sourceTree = SOURCE_ROOT; }; @@ -1154,6 +1158,8 @@ B6CE7E8A0B28027000EB65B3 /* cocoa */ = { isa = PBXGroup; children = ( + B635EAE5116A0FE500A166F2 /* keystate.c */, + B635EAE6116A0FE500A166F2 /* keystate.h */, B6042DBD0BBE2606000CC959 /* SDL_joystick */, B6CE7F3B0B2830A300EB65B3 /* cocoadisplay.h */, B6B99F890B5F798700EE408F /* cocoadisplay.m */, @@ -1441,6 +1447,7 @@ B631BA0010257CA400BE1EE1 /* opus.h in Headers */, B6DCBBD3114FA0E700DC9A11 /* internals.h in Headers */, B6DCBBEF114FA0E700DC9A11 /* tape_block.h in Headers */, + B635EAE8116A0FE500A166F2 /* keystate.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1756,6 +1763,7 @@ B6DCBC11114FA0E700DC9A11 /* z80em.c in Sources */, B6DCBC12114FA0E700DC9A11 /* zlib.c in Sources */, B6DCBC13114FA0E700DC9A11 /* zxs.c in Sources */, + B635EAE7116A0FE500A166F2 /* keystate.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; Added: trunk/fuse/fusepb/keystate.c =================================================================== --- trunk/fuse/fusepb/keystate.c (rev 0) +++ trunk/fuse/fusepb/keystate.c 2010-04-06 11:24:38 UTC (rev 635) @@ -0,0 +1,160 @@ +/* keystate.c: keyboard input state machine - prevents problems with pressing + one "special" key and releasing another (because more than one + were pressed or shift was released before the key) + Copyright (c) 2010 Fredrick Meunier + + $Id$ + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + Author contact information: + + E-mail: fr...@sp... + +*/ + +#include <stdio.h> + +#include "input.h" +#include "keyboard.h" +#include "keystate.h" + +enum states { + NONE, + NORMAL, + SPECIAL, + MAX_STATES +} current_state = NONE; + +static void action_sNONE_ePRESS_NORMAL( input_key ); +static void action_sNONE_ePRESS_SPECIAL( input_key ); +static void action_sNORMAL_ePRESS_NORMAL( input_key ); +static void action_sNORMAL_eRELEASE_NORMAL( input_key ); +static void action_sSPECIAL_ePRESS_NORMAL( input_key ); +static void action_sSPECIAL_ePRESS_SPECIAL( input_key ); +static void action_sSPECIAL_eRELEASE_SPECIAL( input_key ); +static void action_ignore( input_key ); + +void (*const state_table[MAX_STATES][MAX_EVENTS]) (input_key keysym) = { + + { action_sNONE_ePRESS_NORMAL, action_ignore, action_sNONE_ePRESS_SPECIAL, + action_ignore }, /* procedures for state NONE */ + + { action_sNORMAL_ePRESS_NORMAL, action_sNORMAL_eRELEASE_NORMAL, + action_ignore, action_ignore }, /* procedures for state NORMAL */ + + { action_sSPECIAL_ePRESS_NORMAL, action_ignore, + action_sSPECIAL_ePRESS_SPECIAL, + action_sSPECIAL_eRELEASE_SPECIAL }, /* procedures for state SPECIAL */ + +}; + +static input_key current_special; +static int normal_count = 0; + +void +press_key( input_key keysym ) +{ + input_event_t fuse_event; + fuse_event.type = INPUT_EVENT_KEYPRESS; + //fuse_event.types.key.native_key = fuse_keysym; + fuse_event.types.key.spectrum_key = keysym; + input_event( &fuse_event ); +} + +void +release_key( input_key keysym ) +{ + input_event_t fuse_event; + fuse_event.type = INPUT_EVENT_KEYRELEASE; + //fuse_event.types.key.native_key = fuse_keysym; + fuse_event.types.key.spectrum_key = keysym; + input_event( &fuse_event ); +} + +void action_ignore( input_key keysym ) {} + +void +action_sNONE_ePRESS_NORMAL( input_key keysym ) +{ + normal_count++; + press_key(keysym); + current_state = NORMAL; +} + +void +action_sNONE_ePRESS_SPECIAL( input_key keysym ) +{ + current_special = keysym; + /* override caps and symbol shifts if the user is pressing a special key that + * may require specific settings of these + */ + keyboard_release( KEYBOARD_Caps ); + keyboard_release( KEYBOARD_Symbol ); + press_key(keysym); + current_state = SPECIAL; +} + +void +action_sNORMAL_ePRESS_NORMAL( input_key keysym ) +{ + normal_count++; + // track depth, increment no of pressed NORMALs + press_key(keysym); +} + +void +action_sNORMAL_eRELEASE_NORMAL( input_key keysym ) +{ + normal_count--; + // track depth, if depth is 0 switch back to NONE + if( !normal_count ) current_state = NONE; + release_key(keysym); +} + +void +action_sSPECIAL_ePRESS_NORMAL( input_key keysym ) +{ + normal_count++; + release_key(current_special); + current_state = NORMAL; +} + +void +action_sSPECIAL_ePRESS_SPECIAL( input_key keysym ) +{ + // release old special key, press new one + release_key(current_special); + current_special = keysym; + press_key(current_special); +} + +void +action_sSPECIAL_eRELEASE_SPECIAL( input_key keysym ) +{ + current_state = NONE; + release_key(current_special); +} + +void +process_keyevent( enum events event, input_key keysym ) +{ + if(((event >=0) && (event < MAX_EVENTS)) && + ((current_state >= 0) && (current_state < MAX_STATES))) { + state_table[current_state][event]( keysym ); /* call the action procedure */ + } else { + /* invalid event/state - shouldn't happen, just ignore for now */ + } +} Added: trunk/fuse/fusepb/keystate.h =================================================================== --- trunk/fuse/fusepb/keystate.h (rev 0) +++ trunk/fuse/fusepb/keystate.h 2010-04-06 11:24:38 UTC (rev 635) @@ -0,0 +1,41 @@ +/* keystate.h: keyboard input state machine - prevents problems with pressing + one "special" key and releasing another (because more than one + were pressed or shift was released before the key) + Copyright (c) 2010 Fredrick Meunier + + $Id$ + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + Author contact information: + + E-mail: fr...@sp... + +*/ + +#ifndef KEYSTATE_H +#define KEYSTATE_H + +enum events { + PRESS_NORMAL, + RELEASE_NORMAL, + PRESS_SPECIAL, + RELEASE_SPECIAL, + MAX_EVENTS +}; + +void process_keyevent( enum events event, input_key keysym ); + +#endif /* #ifndef KEYSTATE_H */ Modified: trunk/fuse/fusepb/models/Emulator.h =================================================================== --- trunk/fuse/fusepb/models/Emulator.h 2010-04-05 13:34:11 UTC (rev 634) +++ trunk/fuse/fusepb/models/Emulator.h 2010-04-06 11:24:38 UTC (rev 635) @@ -18,7 +18,6 @@ Author contact information: E-mail: fr...@sp... - Postal address: 3/66 Roslyn Gardens, Ruscutters Bay, NSW 2011, Australia */ @@ -47,10 +46,6 @@ BOOL shiftDown; BOOL commandDown; - int cocoakeyboard_caps_shift_pressed; - int cocoakeyboard_symbol_shift_pressed; - input_key unicode_keysym; - DisplayOpenGLView *proxy_view; } +(Emulator *) instance; Modified: trunk/fuse/fusepb/models/Emulator.m =================================================================== --- trunk/fuse/fusepb/models/Emulator.m 2010-04-05 13:34:11 UTC (rev 634) +++ trunk/fuse/fusepb/models/Emulator.m 2010-04-06 11:24:38 UTC (rev 635) @@ -18,7 +18,6 @@ Author contact information: E-mail: fr...@sp... - Postal address: 3/66 Roslyn Gardens, Ruscutters Bay, NSW 2011, Australia */ @@ -34,6 +33,7 @@ #include "if1.h" #include "if2.h" #include "keyboard.h" +#include "keystate.h" #include "machine.h" #include "menu.h" #include "profile.h" @@ -128,10 +128,6 @@ shiftDown = NO; commandDown = NO; - cocoakeyboard_caps_shift_pressed = 0; - cocoakeyboard_symbol_shift_pressed = 0; - unicode_keysym = INPUT_KEY_NONE; - time = CFAbsoluteTimeGetCurrent(); /* set emulation time start time */ return self; @@ -746,42 +742,70 @@ return ptr ? *ptr : INPUT_KEY_NONE; } +// Things that will be implemented as multiple key presses in the emulation +// core +-(BOOL) isSpecial:(input_key)type +{ + switch( type ) { + case INPUT_KEY_Up: + case INPUT_KEY_Down: + case INPUT_KEY_Left: + case INPUT_KEY_Right: + case INPUT_KEY_BackSpace: + case INPUT_KEY_minus: + case INPUT_KEY_underscore: + case INPUT_KEY_equal: + case INPUT_KEY_plus: + case INPUT_KEY_semicolon: + case INPUT_KEY_colon: + case INPUT_KEY_apostrophe: + case INPUT_KEY_quotedbl: + case INPUT_KEY_numbersign: + case INPUT_KEY_comma: + case INPUT_KEY_less: + case INPUT_KEY_period: + case INPUT_KEY_greater: + case INPUT_KEY_slash: + case INPUT_KEY_question: + case INPUT_KEY_exclamation: + case INPUT_KEY_at: + case INPUT_KEY_dollar: + case INPUT_KEY_percent: + case INPUT_KEY_ampersand: + case INPUT_KEY_lbracket: + case INPUT_KEY_rbracket: + case INPUT_KEY_carat: + case INPUT_KEY_star: + return YES; + break; + default: + return NO; + } +} + -(void) keyChange:(NSEvent *)theEvent type:(input_event_type)type { + if( [theEvent isARepeat] == YES ) return; unsigned short keyCode = [theEvent keyCode]; NSString *characters = [theEvent charactersIgnoringModifiers]; if( NO == commandDown && [characters length] ) { input_key fuse_keysym; - input_event_t fuse_event; + enum events event_type; fuse_keysym = keysyms_remap( keyCode ); if( fuse_keysym == INPUT_KEY_NONE ) { fuse_keysym = [self otherKeysymsRemap:[characters characterAtIndex:0] inHash:unicode_keysyms_hash]; - if( fuse_keysym != INPUT_KEY_NONE ) { - unicode_keysym = fuse_keysym; - /* record current values of caps and symbol shift. We will temoprarily - * override these for the duration of the unicoded simulated keypresses - */ - if( ( cocoakeyboard_caps_shift_pressed = keyboard_state( KEYBOARD_Caps ) ) ) - { - keyboard_release( KEYBOARD_Caps ); - } - if( ( cocoakeyboard_symbol_shift_pressed = - keyboard_state( KEYBOARD_Symbol ) ) ) { - keyboard_release( KEYBOARD_Symbol ); - } - } } - fuse_event.type = type; - if( unicode_keysym == INPUT_KEY_NONE ) - fuse_event.types.key.native_key = fuse_keysym; - else - fuse_event.types.key.native_key = unicode_keysym; - fuse_event.types.key.spectrum_key = fuse_keysym; + if( [self isSpecial:fuse_keysym] == YES ) { + event_type = type == INPUT_EVENT_KEYPRESS ? PRESS_SPECIAL : + RELEASE_SPECIAL; + } else { + event_type = type == INPUT_EVENT_KEYPRESS ? PRESS_NORMAL : RELEASE_NORMAL; + } - input_event( &fuse_event ); + process_keyevent( event_type, fuse_keysym ); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |