diff --git a/sc2/ChangeLog b/sc2/ChangeLog index f6af1f8b4..c7e85b005 100644 --- a/sc2/ChangeLog +++ b/sc2/ChangeLog @@ -1,4 +1,5 @@ Changes towards version 0.3: +- Completely reworked the input system - Added PC version outtakes, from chmmravatar - Fix crash in PlayStream when whole file is prebuffered and its not speech (bug #259) -Mika diff --git a/sc2/content/starcon.key b/sc2/content/starcon.key index da948e478..bb1a45e35 100644 --- a/sc2/content/starcon.key +++ b/sc2/content/starcon.key @@ -1,88 +1,101 @@ -# File format: -# Three lines for Pause Key, Exit Key, Abort Key -# 10 lines for player 1, 10 lines for player 2 in the following order: -# Left, Right, Up, Down, Button 1, Button 2, Button 3, Button 4, -# Left Shift, Right Shift -# -# Each player's key listing can begin with an optional joystick declaration -# of the format: -# where X is the joystick port (0-based) and T is the -# threshold. Digital pads can use a threshold of 0, but analog joysticks -# may need a non-zero threshold to handle jittering -# -# Lines beginning with a '#' are ignored -# Each line contains one or two entries -# The first entry must be a keyboard key, enclosed in quotes -# Use "Up" for up arrow, "Down" for down arrow, etc. -# You can chord keys together like this: "F2,F3" -# The second entry, if present, will be separated from the first entry by a -# space. It represents a joystick button press / axis motion -# The format for joystick button presses is -# where n is the button number -# The format for joystick axis movement is -# or where n is the axis number, and the -# + or - represents the direction of movement -# You can combine two joystick button presses with -# where n and m are button numbers -# ---------------------------------------------------------------------------- -# -# Pause -"F1" -# Exit -"F10" -# Abort -"F12" -# -# Player 1 (keyboard only) -# -"Left" -"Right" -"Up" -"Down" -"Enter" -" " -"RCtrl" -"Esc" -"LShift" -"RShift" -# -# Example Player 1 (for a 2-axis, 2-button joypad) -# -# -#"Left" -#"Right" -#"Up" -#"Down" -#"Enter" -#" " -#"RCtrl" -#"Esc" -#"LShift" -#"RShift" -# -# Example Player 1 (for a gravis xterminator) -# -# -#"Left" -#"Right" -#"Up" -#"Down" -#"Enter" -#" " -#"RCtrl" -#"Esc" -#"LShift" -#"RShift" -# -# Player 2 (keyboard only) -# -"s" -"f" -"e" -"d" -"w" -"q" -"a" -"" -"" -"" +# Sample UQM input configuration file. This file may replace the +# automatically generated keys.cfg if you wish; there is no difference +# in behavior. This one just has more comments in it. + +# This is the actual key configuration. Most keys can be described in +# a straightforward manner; consult the name table in +# src/sc2code/libs/input/sdl/keynames.c for the names of unusual keys. +# Most keys can be named by just the symbol they produce. + +Menu-Select: key Return +Player-1-Thrust: key Return +Lander-Thrust: key Return +Player-1-Escape: key Escape +Lander-Escape: key Escape +Menu-Cancel: key Space +Player-1-Weapon: key Space +Lander-Weapon: key Space +Player-2-Left: key a +Player-2-Right: key d +Player-2-Weapon: key t +Player-2-Thrust: key w +Player-2-Special: key y +Menu-Down: key Keypad-2 +Menu-Page-Down: key Keypad-3 +Menu-Left: key Keypad-4 +Player-1-Left: key Keypad-4 +Lander-Left: key Keypad-4 +Menu-Right: key Keypad-6 +Player-1-Right: key Keypad-6 +Lander-Right: key Keypad-6 +Menu-Up: key Keypad-8 +Player-1-Thrust: key Keypad-8 +Lander-Thrust: key Keypad-8 +Menu-Page-Up: key Keypad-9 +Menu-Zoom-Out: key Keypad-- +Menu-Zoom-In: key Keypad-+ +Menu-Select: key Keypad-Enter +Player-1-Thrust: key Keypad-Enter +Lander-Thrust: key Keypad-Enter +Menu-Up: key Up +Player-1-Thrust: key Up +Lander-Thrust: key Up +Menu-Down: key Down +Menu-Right: key Right +Player-1-Right: key Right +Lander-Right: key Right +Menu-Left: key Left +Player-1-Left: key Left +Lander-Left: key Left +Menu-Page-Up: key PageUp +Menu-Zoom-In: key PageUp +Menu-Page-Down: key PageDown +Menu-Zoom-Out: key PageDown +Pause: key F1 +Exit: key F10 +Abort: key F12 +Player-1-Weapon: key RightShift +Lander-Weapon: key RightShift +Player-1-Special: key RightControl + +# This is a sample joystick configuration. This is intended to work +# primarily under WinXP with a USB analag/digital gamepad. The +# digital aspect of the gamepad happens to present itself to the +# system as a POV hat. This configuration allows either the digital +# or analog stick to be used simultaneously. + +# joystick 0 threshold 10000 # How far to move before it counts; 0-30000 +# Menu-Left: joystick 0 axis 0 negative +# Player-1-Left: joystick 0 axis 0 negative +# Lander-Left: joystick 0 axis 0 negative +# Menu-Right: joystick 0 axis 0 positive +# Player-1-Right: joystick 0 axis 0 positive +# Lander-Right: joystick 0 axis 0 positive +# Menu-Up: joystick 0 axis 1 negative +# Player-1-Thrust: joystick 0 axis 1 negative +# Lander-Thrust: joystick 0 axis 1 negative +# Menu-Down: joystick 0 axis 1 positive +# Menu-Cancel: joystick 0 button 0 +# Player-1-Special: joystick 0 button 0 +# Menu-Select: joystick 0 button 1 +# Player-1-Weapon: joystick 0 button 1 +# Lander-Weapon: joystick 0 button 1 +# Menu-Page-Up: joystick 0 button 4 +# Menu-Page-Down: joystick 0 button 5 +# Menu-Zoom-In: joystick 0 button 6 +# Player-1-Escape: joystick 0 button 6 +# Lander-Escape: joystick 0 button 6 +# Menu-Zoom-Out: joystick 0 button 7 + +# And now the POV hat controls. +# Menu-Left: joystick 0 hat 0 left +# Player-1-Left: joystick 0 hat 0 left +# Lander-Left: joystick 0 hat 0 left +# Menu-Right: joystick 0 hat 0 right +# Player-1-Right: joystick 0 hat 0 right +# Lander-Right: joystick 0 hat 0 right +# Menu-Up: joystick 0 hat 0 up +# Player-1-Thrust: joystick 0 hat 0 up +# Lander-Thrust: joystick 0 hat 0 up +# Menu-Down: joystick 0 hat 0 down + diff --git a/sc2/src/msvc++/UrQuanMasters.dsp b/sc2/src/msvc++/UrQuanMasters.dsp index f8ba742e7..46e3b2313 100644 --- a/sc2/src/msvc++/UrQuanMasters.dsp +++ b/sc2/src/msvc++/UrQuanMasters.dsp @@ -342,6 +342,26 @@ SOURCE=..\sc2code\libs\input\sdl\input.c SOURCE=..\sc2code\libs\input\sdl\input.h # End Source File +# Begin Source File + +SOURCE=..\sc2code\libs\input\sdl\keynames.c +# End Source File +# Begin Source File + +SOURCE=..\sc2code\libs\input\sdl\keynames.h +# End Source File +# Begin Source File + +SOURCE=..\sc2code\libs\input\sdl\vcontrol.c +# End Source File +# Begin Source File + +SOURCE=..\sc2code\libs\input\sdl\vcontrol.h +# End Source File +# Begin Source File + +SOURCE=..\sc2code\libs\input\sdl\vcontrol_malloc.h +# End Source File # End Group # Begin Source File @@ -2971,6 +2991,10 @@ SOURCE=..\sc2code\confirm.c # End Source File # Begin Source File +SOURCE=..\sc2code\controls.h +# End Source File +# Begin Source File + SOURCE=..\sc2code\credits.c # End Source File # Begin Source File diff --git a/sc2/src/sc2code/battle.c b/sc2/src/sc2code/battle.c index 9fd6c2200..97737bd28 100644 --- a/sc2/src/sc2code/battle.c +++ b/sc2/src/sc2code/battle.c @@ -18,6 +18,7 @@ #include "libs/graphics/gfx_common.h" //#include "starcon.h" +#include "controls.h" QUEUE disp_q; SIZE battle_counter; @@ -33,6 +34,7 @@ ProcessInput (void) && GET_GAME_STATE (STARBASE_AVAILABLE) && !GET_GAME_STATE (BOMB_CARRIER) ); + UpdateInputState (); for (cur_player = NUM_SIDES - 1; cur_player >= 0; --cur_player) { HSTARSHIP hBattleShip, hNextShip; @@ -40,7 +42,7 @@ ProcessInput (void) for (hBattleShip = GetHeadLink (&race_q[cur_player]); hBattleShip != 0; hBattleShip = hNextShip) { - INPUT_STATE InputState; + BATTLE_INPUT_STATE InputState; STARSHIPPTR StarShipPtr; StarShipPtr = LockStarShip (&race_q[cur_player], hBattleShip); @@ -50,12 +52,10 @@ ProcessInput (void) { CyborgDescPtr = StarShipPtr; - InputState = GetInputState (PlayerInput[cur_player]); + InputState = (*(PlayerInput[cur_player]))(); #if CREATE_JOURNAL JournalInput (InputState); #endif /* CREATE_JOURNAL */ - if (InputState & DEVICE_EXIT) - InputState = ConfirmExit (); #ifdef TESTING if ((InputState & DEVICE_BUTTON3) @@ -73,25 +73,19 @@ if ((InputState & DEVICE_BUTTON3) CyborgDescPtr->ship_input_state = 0; if (CyborgDescPtr->RaceDescPtr->ship_info.crew_level) { - if (GetInputXComponent (InputState) < 0) + + if (InputState & BATTLE_LEFT) CyborgDescPtr->ship_input_state |= LEFT; - else if (GetInputXComponent (InputState) > 0) + else if (InputState & BATTLE_RIGHT) CyborgDescPtr->ship_input_state |= RIGHT; - if (GetInputYComponent (InputState) < 0 - || (InputState & DEVICE_BUTTON1)) + if (InputState & BATTLE_THRUST) CyborgDescPtr->ship_input_state |= THRUST; - if (InputState & (DEVICE_BUTTON2 | DEVICE_RIGHTSHIFT)) + if (InputState & BATTLE_WEAPON) CyborgDescPtr->ship_input_state |= WEAPON; - if (InputState & (DEVICE_BUTTON3 | DEVICE_LEFTSHIFT)) + if (InputState & BATTLE_SPECIAL) CyborgDescPtr->ship_input_state |= SPECIAL; - if (CanRunAway - && cur_player == 0 - && ((PlayerControl[cur_player] & HUMAN_CONTROL) - || (InputState = GetInputState (NormalInput))) - && ((InputState & (DEVICE_BUTTON2 | DEVICE_RIGHTSHIFT)) - == (DEVICE_BUTTON2 | DEVICE_RIGHTSHIFT) - || (InputState & DEVICE_BUTTON4))) + if (CanRunAway && cur_player == 0 && (InputState & BATTLE_ESCAPE)) { ELEMENTPTR ElementPtr; diff --git a/sc2/src/sc2code/comm.c b/sc2/src/sc2code/comm.c index efc5bb98c..b766766a1 100644 --- a/sc2/src/sc2code/comm.c +++ b/sc2/src/sc2code/comm.c @@ -25,6 +25,7 @@ #include "options.h" #include "comm.h" #include "libs/sound/sound.h" +#include "controls.h" #include "endian_uqm.h" void InitOscilloscope (int x, int y, int width, int height, FRAME_DESC *f); @@ -51,8 +52,7 @@ volatile BOOLEAN summary = FALSE; typedef struct encounter_state { - BOOLEAN (*InputFunc) (INPUT_STATE InputState, struct encounter_state - *pES); + BOOLEAN (*InputFunc) (struct encounter_state *pES); COUNT MenuRepeatDelay; COUNT Initialized; @@ -1299,7 +1299,6 @@ SpewPhrases (COUNT wait_track) BOOLEAN ContinuityBreak; DWORD TimeIn; COUNT which_track; - INPUT_STATE InputState, LastInputState = (INPUT_STATE)~0; FRAME F; BOOLEAN passed = TRUE; @@ -1310,7 +1309,6 @@ SpewPhrases (COUNT wait_track) if (wait_track == 0) { wait_track = which_track = (COUNT)~0; - InputState = 0; goto Rewind; } @@ -1348,13 +1346,11 @@ SpewPhrases (COUNT wait_track) #if DEMO_MODE || CREATE_JOURNAL InputState = 0; #else /* !(DEMO_MODE || CREATE_JOURNAL) */ - InputState = GetInputState (NormalInput); + UpdateInputState (); #endif - if (InputState & DEVICE_EXIT) - InputState = ConfirmExit (); SetSemaphore (GraphicsSem); - if (InputState & (DEVICE_BUTTON2 | DEVICE_EXIT)) + if (CurrentMenuState.cancel) { SetSliderImage (SetAbsFrameIndex (ActivityFrame, 8)); JumpTrack (); @@ -1365,11 +1361,21 @@ SpewPhrases (COUNT wait_track) if (which_track) { - if (GetInputXComponent (InputState) > 0) + BOOLEAN left=FALSE, right=FALSE; + if (optSmoothScroll == OPT_PC) + { + left = CurrentMenuState.left; + right = CurrentMenuState.right; + } + else if (optSmoothScroll == OPT_3DO) + { + left = ImmediateMenuState.left; + right = ImmediateMenuState.right; + } + if (right) { SetSliderImage (SetAbsFrameIndex (ActivityFrame, 3)); - if (optSmoothScroll == OPT_PC && InputState != LastInputState - && !FastForward_Page ()) + if (optSmoothScroll == OPT_PC && !FastForward_Page ()) { SetSliderImage (SetAbsFrameIndex (ActivityFrame, 8)); JumpTrack (); @@ -1382,11 +1388,11 @@ SpewPhrases (COUNT wait_track) ContinuityBreak = TRUE; CommData.AlienFrame = 0; } - else if (GetInputXComponent (InputState) < 0) + else if (left) { Rewind: SetSliderImage (SetAbsFrameIndex (ActivityFrame, 4)); - if (optSmoothScroll == OPT_PC && InputState != LastInputState) + if (optSmoothScroll == OPT_PC) FastReverse_Page (); else if (optSmoothScroll == OPT_3DO) FastReverse_Smooth (); @@ -1414,7 +1420,6 @@ Rewind: || wait_track == (COUNT)~0) CommData.AlienFrame = F; } - LastInputState = InputState; } while (ContinuityBreak || ((which_track = PlayingTrack ()) && which_track <= wait_track)); @@ -1545,7 +1550,7 @@ AlienTalkSegue (COUNT wait_track) } static BOOLEAN -DoCommunication (INPUT_STATE InputState, PENCOUNTER_STATE pES) +DoCommunication (PENCOUNTER_STATE pES) { if (!(CommData.AlienTransitionDesc.AnimFlags & (TALK_INTRO | TALK_DONE))) { @@ -1564,7 +1569,9 @@ DoCommunication (INPUT_STATE InputState, PENCOUNTER_STATE pES) { SleepThreadUntil (TimeIn + ONE_SECOND / 120); TimeIn = GetTimeCounter (); - if (GetInputXComponent (GetInputState (NormalInput)) < 0) + // Warning! This used to re-gather input data to check for rewind. + UpdateInputState (); + if (CurrentMenuState.left) { FadeMusic (BACKGROUND_VOL, ONE_SECOND); SetSemaphore (GraphicsSem); @@ -1625,7 +1632,7 @@ DoCommunication (INPUT_STATE InputState, PENCOUNTER_STATE pES) ClearSemaphore (GraphicsSem); } - if (InputState & DEVICE_BUTTON1) + if (CurrentMenuState.select) { pES->phrase_buf_index = pES->response_list[pES->cur_response].response_text.CharCount; @@ -1647,7 +1654,7 @@ DoCommunication (INPUT_STATE InputState, PENCOUNTER_STATE pES) (*pES->response_list[pES->cur_response].response_func) (pES->response_list[pES->cur_response].response_ref); } - else if (InputState & DEVICE_BUTTON2 && + else if (CurrentMenuState.cancel && LOBYTE (GLOBAL (CurrentActivity)) != WON_LAST_BATTLE) { extern TFB_SoundChain *first_chain; @@ -1800,7 +1807,7 @@ DoCommunication (INPUT_STATE InputState, PENCOUNTER_STATE pES) else { response = pES->cur_response; - if (GetInputXComponent (InputState) < 0) + if (CurrentMenuState.left) { FadeMusic (BACKGROUND_VOL, ONE_SECOND); SetSemaphore (GraphicsSem); @@ -1848,10 +1855,10 @@ DoCommunication (INPUT_STATE InputState, PENCOUNTER_STATE pES) TaskSwitch (); while (CommData.AlienTalkDesc.AnimFlags & PAUSE_TALKING); } - else if (GetInputYComponent (InputState) < 0) + else if (CurrentMenuState.up) response = (BYTE)((response + (BYTE)(pES->num_responses - 1)) % pES->num_responses); - else if (GetInputYComponent (InputState) > 0) + else if (CurrentMenuState.down) response = (BYTE)((BYTE)(response + 1) % pES->num_responses); diff --git a/sc2/src/sc2code/confirm.c b/sc2/src/sc2code/confirm.c index 2e2a2edcf..8b0f443c7 100644 --- a/sc2/src/sc2code/confirm.c +++ b/sc2/src/sc2code/confirm.c @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include #include "starcon.h" #include "commglue.h" #include "libs/sound/trackplayer.h" @@ -26,11 +27,17 @@ void WaitForNoInput (SIZE Duration); //End Added by Chris -INPUT_STATE +/* TODO: Replace the TO EXIT PRESS B code with a 'real' confirmation + screen. To avoid confusion (especially now that there is no + in-game model of the 3DO controller exits are currently always + confirmed. */ + +BOOLEAN ConfirmExit (void) { - INPUT_STATE InputState; - +#if 0 + BOOLEAN result; + fprintf (stderr, "Confirming Exit!\n"); if (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE) SuspendGameClock (); else if (CommData.ConversationPhrases && PlayingTrack ()) @@ -38,13 +45,17 @@ ConfirmExit (void) SetSemaphore (GraphicsSem); if (GLOBAL (CurrentActivity) & CHECK_ABORT) - InputState = DEVICE_EXIT; + { + result = FALSE; + ExitRequested = FALSE; + } else { RECT r; STAMP s; FRAME F; CONTEXT oldContext; + UNICODE response; oldContext = SetContext (ScreenContext); @@ -63,38 +74,32 @@ ConfirmExit (void) FlushGraphics (); //SetSemaphore (GraphicsSem); - { - INPUT_STATE PressState; - - GLOBAL (CurrentActivity) |= CHECK_ABORT; - - PressState = GetInputState (NormalInput); - do - { - TaskSwitch (); - InputState = GetInputState (NormalInput); - if (PressState) - { - PressState = InputState; - InputState = 0; - } - } while (!InputState); - } + /* Possible bug... ConfirmExit is assuming + * CharacterMode is off. */ + EnableCharacterMode (); + GLOBAL (CurrentActivity) |= CHECK_ABORT; + do { + response = toupper (GetCharacter ()); + } while (response != 'Y' && response != 'N'); + DisableCharacterMode (); + ExitRequested = FALSE; s.frame = F; DrawStamp (&s); DestroyDrawable (ReleaseDrawable (s.frame)); - - if (InputState & DEVICE_BUTTON2) - InputState = DEVICE_EXIT; + if (response == 'Y') + { + GameExiting = TRUE; + result = TRUE; + } else { - InputState = 0; + result = FALSE; + GameExiting = FALSE; GLOBAL (CurrentActivity) &= ~CHECK_ABORT; WaitForNoInput (ONE_SECOND / 4); FlushInput (); } - SetContext (oldContext); } ClearSemaphore (GraphicsSem); @@ -104,7 +109,13 @@ ConfirmExit (void) else if (CommData.ConversationPhrases && PlayingTrack ()) ResumeTrack (); - return (InputState); + fprintf (stderr, "Exit was %sconfirmed.\n", result ? "" : "NOT "); + return (result); +#endif + GLOBAL (CurrentActivity) |= CHECK_ABORT; + ExitRequested = FALSE; + GameExiting = TRUE; + return TRUE; } diff --git a/sc2/src/sc2code/controls.h b/sc2/src/sc2code/controls.h new file mode 100644 index 000000000..acac35798 --- /dev/null +++ b/sc2/src/sc2code/controls.h @@ -0,0 +1,64 @@ +//Copyright Paul Reiche, Fred Ford. 1992-2002 + +/* + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _CONTROLS_H_ +#define _CONTROLS_H_ + +#include "starcon.h" +#include "compiler.h" + +// This struct controls the various controls available to the player. + +typedef struct _controller_input_state { + int p1_thrust, p1_left, p1_right, p1_weapon, p1_special, p1_escape; + int p2_thrust, p2_left, p2_right, p2_weapon, p2_special; + int lander_thrust, lander_left, lander_right, lander_weapon, lander_escape; + int pause, exit, abort; +} CONTROLLER_INPUT_STATE; + +typedef struct _menu_input_state { + int up, down, left, right, select, cancel, special; + int page_up, page_down, zoom_in, zoom_out; +} MENU_INPUT_STATE; + +typedef UBYTE BATTLE_INPUT_STATE; +#define BATTLE_LEFT ((BATTLE_INPUT_STATE)(1 << 0)) +#define BATTLE_RIGHT ((BATTLE_INPUT_STATE)(1 << 1)) +#define BATTLE_THRUST ((BATTLE_INPUT_STATE)(1 << 2)) +#define BATTLE_WEAPON ((BATTLE_INPUT_STATE)(1 << 3)) +#define BATTLE_SPECIAL ((BATTLE_INPUT_STATE)(1 << 4)) +#define BATTLE_ESCAPE ((BATTLE_INPUT_STATE)(1 << 5)) + +typedef BATTLE_INPUT_STATE (*battle_summary_func) (void); +extern battle_summary_func ComputerInput, HumanInput[NUM_PLAYERS]; +extern battle_summary_func PlayerInput[NUM_PLAYERS]; + +extern CONTROLLER_INPUT_STATE CurrentInputState; +extern MENU_INPUT_STATE CurrentMenuState; +extern volatile CONTROLLER_INPUT_STATE ImmediateInputState; +extern volatile MENU_INPUT_STATE ImmediateMenuState; + +void UpdateInputState (void); +void TFB_ResetControls (void); +void SetMenuRepeatDelay (DWORD min, DWORD max, DWORD step); +void SetDefaultMenuRepeatDelay (void); + +BATTLE_INPUT_STATE p1_combat_summary (void); +BATTLE_INPUT_STATE p2_combat_summary (void); + +#endif diff --git a/sc2/src/sc2code/cyborg.c b/sc2/src/sc2code/cyborg.c index d93377714..36c2689bc 100644 --- a/sc2/src/sc2code/cyborg.c +++ b/sc2/src/sc2code/cyborg.c @@ -1008,7 +1008,7 @@ Avoid (ELEMENTPTR ShipPtr, EVALUATE_DESCPTR EvalDescPtr) (void) EvalDescPtr; /* Satisfying compiler (unused parameter) */ } -INPUT_STATE +BATTLE_INPUT_STATE tactical_intelligence (void) { ELEMENTPTR ShipPtr; @@ -1325,22 +1325,19 @@ StarShipPtr->ship_input_state &= ~SPECIAL; StarShipPtr->ShipFacing = ShipFacing; { - INPUT_STATE InputState; + BATTLE_INPUT_STATE InputState; InputState = 0; if (StarShipPtr->ship_input_state & LEFT) - SetInputXComponent (&InputState, -1); + InputState |= BATTLE_LEFT; else if (StarShipPtr->ship_input_state & RIGHT) - SetInputXComponent (&InputState, 1); + InputState |= BATTLE_RIGHT; if (StarShipPtr->ship_input_state & THRUST) - SetInputYComponent (&InputState, -1); + InputState |= BATTLE_THRUST; if (StarShipPtr->ship_input_state & WEAPON) - InputState |= DEVICE_BUTTON2; + InputState |= BATTLE_WEAPON; if (StarShipPtr->ship_input_state & SPECIAL) - InputState |= DEVICE_BUTTON3; - if (InputState) - SetInputDevType (&InputState, JOYSTICK_DEVICE); - + InputState |= BATTLE_SPECIAL; return (InputState); } } diff --git a/sc2/src/sc2code/demo.h b/sc2/src/sc2code/demo.h index 9835a7540..338261e59 100644 --- a/sc2/src/sc2code/demo.h +++ b/sc2/src/sc2code/demo.h @@ -26,11 +26,6 @@ #define CREATE_JOURNAL 0 #endif /* CREATE_JOURNAL */ -extern INPUT_STATE demo_input (INPUT_REF InputRef, INPUT_STATE - InputState); - -extern INPUT_REF DemoInput; - #if !(DEMO_MODE || CREATE_JOURNAL) #define OpenJournal SeedRandomNumbers diff --git a/sc2/src/sc2code/displist.h b/sc2/src/sc2code/displist.h index 2e758ec64..7d8623450 100644 --- a/sc2/src/sc2code/displist.h +++ b/sc2/src/sc2code/displist.h @@ -38,12 +38,7 @@ typedef struct link } LINK; typedef LINK *PLINK; -#ifndef _INPINTRN_H -/* This ifndef is temporary to avoid a collision with inpintrn.h - This shouldn't be necessary, but SDL_wrappper.h isn't set up correctly - at the moment. */ typedef PBYTE BYTEPTR; -#endif typedef PUWORD WORDPTR; typedef PVOID VOIDPTR; typedef PLINK LINKPTR; diff --git a/sc2/src/sc2code/encount.c b/sc2/src/sc2code/encount.c index 9ea8ef94e..41745b4c0 100644 --- a/sc2/src/sc2code/encount.c +++ b/sc2/src/sc2code/encount.c @@ -17,9 +17,10 @@ */ #include "starcon.h" +#include "controls.h" static BOOLEAN -DoSelectAction (INPUT_STATE InputState, PMENU_STATE pMS) +DoSelectAction (PMENU_STATE pMS) { if (GLOBAL (CurrentActivity) & CHECK_ABORT) { @@ -31,7 +32,7 @@ DoSelectAction (INPUT_STATE InputState, PMENU_STATE pMS) pMS->Initialized = TRUE; pMS->InputFunc = DoSelectAction; } - else if (InputState & DEVICE_BUTTON1) + else if (CurrentMenuState.select) { switch (pMS->CurState) { @@ -54,7 +55,7 @@ DoSelectAction (INPUT_STATE InputState, PMENU_STATE pMS) printf ("Unknown option: %d\n", pMS->CurState); } } - DoMenuChooser (InputState, pMS, PM_CONVERSE); + DoMenuChooser (pMS, PM_CONVERSE); return (TRUE); } @@ -629,8 +630,6 @@ UninitEncounter (void) if (VictoryState) { - INPUT_STATE InputState; - #ifdef NEVER DestroyDrawable (ReleaseDrawable (s.frame)); #endif /* NEVER */ @@ -638,13 +637,13 @@ UninitEncounter (void) FlushInput (); Time = GetTimeCounter () + (ONE_SECOND * 3); ClearSemaphore (GraphicsSem); - while (!(InputState = AnyButtonPress (TRUE)) && GetTimeCounter () < Time) - ; + while (!(AnyButtonPress (TRUE)) && GetTimeCounter () < Time) + TaskSwitch (); SetSemaphore (GraphicsSem); - if (GetInputUNICODE (InputState) != 0x1B) /* Escape key */ + if (!CurrentInputState.p1_escape) { DrawFadeText (str1, str2, FALSE, &scavenge_r); - if (GetInputUNICODE (InputState) != 0x1B) /* Escape key */ + if (!CurrentInputState.p1_escape) { SetContextForeGroundColor (BLACK_COLOR); r.corner.x = scavenge_r.corner.x + 10; @@ -669,11 +668,11 @@ UninitEncounter (void) ); Time = GetTimeCounter () + ONE_SECOND * 2; ClearSemaphore (GraphicsSem); - while (!(InputState = AnyButtonPress (TRUE)) + while (!(AnyButtonPress (TRUE)) && GetTimeCounter () < Time) - ; + TaskSwitch (); SetSemaphore (GraphicsSem); - if (GetInputUNICODE (InputState) != 0x1B) /* Escape key */ + if (!CurrentInputState.p1_escape) DrawFadeText (str1, str2, FALSE, &scavenge_r); } } @@ -754,8 +753,8 @@ EncounterBattle (void) if (GLOBAL (glob_flags) & CYBORG_ENABLED) { nth_frame = MAKE_WORD (0, 0); - PlayerControl[0] = HUMAN_CONTROL | STANDARD_RATING, - PlayerInput[0] = NormalInput; + PlayerControl[0] = HUMAN_CONTROL | STANDARD_RATING; + PlayerInput[0] = HumanInput[0]; } SetResourceIndex (hResIndex); diff --git a/sc2/src/sc2code/fmv.c b/sc2/src/sc2code/fmv.c index d72048798..8135a1932 100644 --- a/sc2/src/sc2code/fmv.c +++ b/sc2/src/sc2code/fmv.c @@ -83,7 +83,7 @@ Introduction (void) BYTE xform_buf[1]; STAMP s; DWORD TimeOut; - INPUT_STATE InputState; + BOOLEAN InputState; xform_buf[0] = FadeAllToBlack; SleepThreadUntil (XFormColorMap ( @@ -111,6 +111,7 @@ Introduction (void) // } GLOBAL (CurrentActivity) &= ~CHECK_ABORT; + GameExiting = FALSE; xform_buf[0] = FadeAllToBlack; SleepThreadUntil (XFormColorMap ((COLORMAPPTR)xform_buf, ONE_SECOND / 2)); diff --git a/sc2/src/sc2code/gameinp.c b/sc2/src/sc2code/gameinp.c index d66b363b5..c38e366dd 100644 --- a/sc2/src/sc2code/gameinp.c +++ b/sc2/src/sc2code/gameinp.c @@ -17,86 +17,208 @@ */ #include "starcon.h" +#include "controls.h" + +battle_summary_func ComputerInput, HumanInput[NUM_PLAYERS]; +battle_summary_func PlayerInput[NUM_PLAYERS]; + +#define ACCELERATION_INCREMENT (ONE_SECOND / 12) typedef struct { - BOOLEAN (*InputFunc) (INPUT_STATE InputState, PVOID pInputState); + BOOLEAN (*InputFunc) (PVOID pInputState); COUNT MenuRepeatDelay; } INPUT_STATE_DESC; typedef INPUT_STATE_DESC *PINPUT_STATE_DESC; -INPUT_STATE OldInputState; +/* These static variables are the values that are set by the controllers. */ + +typedef struct +{ + DWORD up, down, left, right, select, cancel, special; + DWORD page_up, page_down, zoom_in, zoom_out; +} MENU_ANNOTATIONS; + + +CONTROLLER_INPUT_STATE CurrentInputState; +MENU_INPUT_STATE CurrentMenuState; +static MENU_INPUT_STATE CachedMenuState, OldMenuState; +static MENU_ANNOTATIONS RepeatDelays, Times; +static DWORD _max_accel, _min_accel, _step_accel; +int ExitState; + +volatile CONTROLLER_INPUT_STATE ImmediateInputState; +volatile MENU_INPUT_STATE ImmediateMenuState; + +static void +_clear_menu_state (void) +{ + DWORD initTime = GetTimeCounter (); + TFB_ResetControls (); + CurrentMenuState.up = 0; + CurrentMenuState.down = 0; + CurrentMenuState.left = 0; + CurrentMenuState.right = 0; + CurrentMenuState.select = 0; + CurrentMenuState.cancel = 0; + CurrentMenuState.special = 0; + CurrentMenuState.page_up = 0; + CurrentMenuState.page_down = 0; + CurrentMenuState.zoom_in = 0; + CurrentMenuState.zoom_out = 0; + CachedMenuState.up = 0; + CachedMenuState.down = 0; + CachedMenuState.left = 0; + CachedMenuState.right = 0; + CachedMenuState.select = 0; + CachedMenuState.cancel = 0; + CachedMenuState.special = 0; + CachedMenuState.page_up = 0; + CachedMenuState.page_down = 0; + CachedMenuState.zoom_in = 0; + CachedMenuState.zoom_out = 0; + RepeatDelays.up = _max_accel; + RepeatDelays.down = _max_accel; + RepeatDelays.left = _max_accel; + RepeatDelays.right = _max_accel; + RepeatDelays.select = _max_accel; + RepeatDelays.cancel = _max_accel; + RepeatDelays.special = _max_accel; + RepeatDelays.page_up = _max_accel; + RepeatDelays.page_down = _max_accel; + RepeatDelays.zoom_in = _max_accel; + RepeatDelays.zoom_out = _max_accel; + Times.up = initTime; + Times.down = initTime; + Times.left = initTime; + Times.right = initTime; + Times.select = initTime; + Times.cancel = initTime; + Times.special = initTime; + Times.page_up = initTime; + Times.page_down = initTime; + Times.zoom_in = initTime; + Times.zoom_out = initTime; +} + +static void +_check_for_pulse (int *current, int *cached, int *old, DWORD *accel, DWORD *newtime, DWORD *oldtime) +{ + if (*cached && *old) + { + if (*newtime - *oldtime < *accel) + { + *current = 0; + } + else + { + *current = *cached; + if (*accel > _min_accel) + *accel -= _step_accel; + if (*accel < _min_accel) + *accel = _min_accel; + *oldtime = *newtime; + } + } + else + { + *current = *cached; + *oldtime = *newtime; + *accel = _max_accel; + } +} + +void +UpdateInputState (void) +{ + DWORD NewTime; + /* First, if the game is, in fact, paused, we stall until + * unpaused. Every thread with control over game logic calls + * UpdateInputState routinely, so we handle pause and exit + * state updates here. */ + + if (GamePaused) + PauseGame (); + + if (ExitRequested) + { + ConfirmExit (); + } + + CurrentInputState = ImmediateInputState; + OldMenuState = CachedMenuState; + CachedMenuState = ImmediateMenuState; + NewTime = GetTimeCounter (); + _check_for_pulse(&CurrentMenuState.up, &CachedMenuState.up, &OldMenuState.up, &RepeatDelays.up, &NewTime, &Times.up); + _check_for_pulse(&CurrentMenuState.down, &CachedMenuState.down, &OldMenuState.down, &RepeatDelays.down, &NewTime, &Times.down); + _check_for_pulse(&CurrentMenuState.left, &CachedMenuState.left, &OldMenuState.left, &RepeatDelays.left, &NewTime, &Times.left); + _check_for_pulse(&CurrentMenuState.right, &CachedMenuState.right, &OldMenuState.right, &RepeatDelays.right, &NewTime, &Times.right); + _check_for_pulse(&CurrentMenuState.select, &CachedMenuState.select, &OldMenuState.select, &RepeatDelays.select, &NewTime, &Times.select); + _check_for_pulse(&CurrentMenuState.cancel, &CachedMenuState.cancel, &OldMenuState.cancel, &RepeatDelays.cancel, &NewTime, &Times.cancel); + _check_for_pulse(&CurrentMenuState.special, &CachedMenuState.special, &OldMenuState.special, &RepeatDelays.special, &NewTime, &Times.special); + _check_for_pulse(&CurrentMenuState.page_up, &CachedMenuState.page_up, &OldMenuState.page_up, &RepeatDelays.page_up, &NewTime, &Times.page_up); + _check_for_pulse(&CurrentMenuState.page_down, &CachedMenuState.page_down, &OldMenuState.page_down, &RepeatDelays.page_down, &NewTime, &Times.page_down); + _check_for_pulse(&CurrentMenuState.zoom_in, &CachedMenuState.zoom_in, &OldMenuState.zoom_in, &RepeatDelays.zoom_in, &NewTime, &Times.zoom_in); + _check_for_pulse(&CurrentMenuState.zoom_out, &CachedMenuState.zoom_out, &OldMenuState.zoom_out, &RepeatDelays.zoom_out, &NewTime, &Times.zoom_out); + + if (CurrentInputState.pause) + GamePaused = TRUE; + + if (CurrentInputState.exit) + ExitRequested = TRUE; +} + + +void +SetMenuRepeatDelay (DWORD min, DWORD max, DWORD step) +{ + _min_accel = min; + _max_accel = max; + _step_accel = step; + _clear_menu_state (); +} + +void +SetDefaultMenuRepeatDelay () +{ + _min_accel = ACCELERATION_INCREMENT; + _max_accel = MENU_REPEAT_DELAY; + _step_accel = ACCELERATION_INCREMENT; + _clear_menu_state (); +} void DoInput (PVOID pInputState) { - DWORD NewTime; - INPUT_STATE InputState; - - NewTime = GetTimeCounter (); - ((PINPUT_STATE_DESC)pInputState)->MenuRepeatDelay = MENU_REPEAT_DELAY; + SetMenuRepeatDelay (ACCELERATION_INCREMENT, MENU_REPEAT_DELAY, ACCELERATION_INCREMENT); do { TaskSwitch (); - NewTime = GetTimeCounter (); - InputState = GetInputState (NormalInput); + UpdateInputState (); #if DEMO_MODE || CREATE_JOURNAL if (ArrowInput != DemoInput) #endif { - static DWORD OldTime; - int test1,test2; - - test1=NewTime - OldTime; - test2=(DWORD)((PINPUT_STATE_DESC)pInputState)->MenuRepeatDelay; - - if (InputState == OldInputState - && NewTime - OldTime < - (DWORD)((PINPUT_STATE_DESC)pInputState)->MenuRepeatDelay) - InputState = 0; - else - { -#define ACCELERATION_INCREMENT (ONE_SECOND / 12) - if (InputState != OldInputState) - ((PINPUT_STATE_DESC)pInputState)->MenuRepeatDelay = - MENU_REPEAT_DELAY; - else if (((PINPUT_STATE_DESC)pInputState)->MenuRepeatDelay - <= ACCELERATION_INCREMENT) - ((PINPUT_STATE_DESC)pInputState)->MenuRepeatDelay = - ACCELERATION_INCREMENT; - else - ((PINPUT_STATE_DESC)pInputState)->MenuRepeatDelay -= - ACCELERATION_INCREMENT; - - if (OldInputState != (INPUT_STATE)~0L) - OldInputState = InputState; - else - { - OldInputState = InputState; - InputState = 0; - } - - OldTime = NewTime; - } - #if CREATE_JOURNAL JournalInput (InputState); #endif /* CREATE_JOURNAL */ } - if (InputState & DEVICE_EXIT) - InputState = ConfirmExit (); + if (CurrentInputState.exit) + ExitState = ConfirmExit (); if (MenuSounds && (pSolarSysState == 0 /* see if in menu */ || pSolarSysState->MenuState.CurState || pSolarSysState->MenuState.Initialized > 2) - && ((InputState & DEVICE_BUTTON1) - || GetInputXComponent (InputState) - || GetInputYComponent (InputState)) + && (CurrentMenuState.select + || CurrentMenuState.up + || CurrentMenuState.down + || CurrentMenuState.left + || CurrentMenuState.right) #ifdef NEVER && !PLRPlaying ((MUSIC_REF)~0) #endif /* NEVER */ @@ -105,68 +227,81 @@ DoInput (PVOID pInputState) SOUND S; S = MenuSounds; - if (InputState & DEVICE_BUTTON1) + if (CurrentMenuState.select) S = SetAbsSoundIndex (S, 1); PlaySoundEffect (S, 0, 0); } - } while ((*((PINPUT_STATE_DESC)pInputState)->InputFunc) - (InputState, pInputState)); - - OldInputState = (INPUT_STATE)~0L; + (pInputState)); } -INPUT_STATE -game_input (INPUT_REF InputRef, INPUT_STATE InputState) +BATTLE_INPUT_STATE +p1_combat_summary (void) { - if (LastActivity & (CHECK_LOAD | CHECK_RESTART)) - { - InputState = 0; - } - else if (InputState == 0 - && (InputState = GetInputState (ArrowInput)) == 0 - && (LOBYTE (GLOBAL (CurrentActivity)) == SUPER_MELEE - || (InputState = GetInputState (CombinedInput[0])) == 0)) - { - if ((InputState = GetInputState (JoystickInput[0])) == 0) - InputState = GetInputState (JoystickInput[1]); - } - (void) InputRef; /* Satisfying compiler (unused parameter) */ - return (InputState); + BATTLE_INPUT_STATE InputState = 0; + if (CurrentInputState.p1_thrust) + InputState |= BATTLE_THRUST; + if (CurrentInputState.p1_left) + InputState |= BATTLE_LEFT; + if (CurrentInputState.p1_right) + InputState |= BATTLE_RIGHT; + if (CurrentInputState.p1_weapon) + InputState |= BATTLE_WEAPON; + if (CurrentInputState.p1_special) + InputState |= BATTLE_SPECIAL; + if (CurrentInputState.p1_escape) + InputState |= BATTLE_ESCAPE; + return InputState; } -INPUT_STATE -combined_input0 (INPUT_REF InputRef, INPUT_STATE InputState) +BATTLE_INPUT_STATE +p2_combat_summary (void) { - if (LastActivity & (CHECK_LOAD | CHECK_RESTART)) - { - InputState = 0; - } - else if (InputState == 0 - && (InputState = GetInputState (JoystickInput[0])) == 0) - { - InputState = GetInputState (KeyboardInput[0]); - } - - (void) InputRef; /* Satisfying compiler (unused parameter) */ - return (InputState); + BATTLE_INPUT_STATE InputState = 0; + if (CurrentInputState.p2_thrust) + InputState |= BATTLE_THRUST; + if (CurrentInputState.p2_left) + InputState |= BATTLE_LEFT; + if (CurrentInputState.p2_right) + InputState |= BATTLE_RIGHT; + if (CurrentInputState.p2_weapon) + InputState |= BATTLE_WEAPON; + if (CurrentInputState.p2_special) + InputState |= BATTLE_SPECIAL; + return InputState; } - -INPUT_STATE -combined_input1 (INPUT_REF InputRef, INPUT_STATE InputState) +BOOLEAN +AnyButtonPress (BOOLEAN CheckSpecial) { - if (LastActivity & (CHECK_LOAD | CHECK_RESTART)) - { - InputState = 0; - } - else if (InputState == 0 - && (InputState = GetInputState (JoystickInput[1])) == 0) - { - InputState = GetInputState (KeyboardInput[1]); - } - - (void) InputRef; /* Satisfying compiler (unused parameter) */ - return (InputState); + (void) CheckSpecial; // Ignored + UpdateInputState (); + return CurrentInputState.p1_thrust + ||CurrentInputState.p1_left + ||CurrentInputState.p1_right + ||CurrentInputState.p1_weapon + ||CurrentInputState.p1_special + ||CurrentInputState.p1_escape + ||CurrentInputState.p2_thrust + ||CurrentInputState.p2_left + ||CurrentInputState.p2_right + ||CurrentInputState.p2_weapon + ||CurrentInputState.p2_special + ||CurrentInputState.lander_thrust + ||CurrentInputState.lander_left + ||CurrentInputState.lander_right + ||CurrentInputState.lander_weapon + ||CurrentInputState.lander_escape + ||CurrentMenuState.up + ||CurrentMenuState.down + ||CurrentMenuState.left + ||CurrentMenuState.right + ||CurrentMenuState.page_up + ||CurrentMenuState.page_down + ||CurrentMenuState.zoom_in + ||CurrentMenuState.zoom_out + ||CurrentMenuState.select + ||CurrentMenuState.cancel + ||CurrentMenuState.special; } diff --git a/sc2/src/sc2code/gameopt.c b/sc2/src/sc2code/gameopt.c index 02f322e42..c0eeeb023 100644 --- a/sc2/src/sc2code/gameopt.c +++ b/sc2/src/sc2code/gameopt.c @@ -21,6 +21,8 @@ #include "commglue.h" #include "options.h" #include "libs/graphics/gfx_common.h" +#include "inplib.h" +#include "controls.h" //Added by Chris @@ -86,7 +88,7 @@ enum SETTINGS }; -static BOOLEAN DoGameOptions (INPUT_STATE InputState, PMENU_STATE pMS); +static BOOLEAN DoGameOptions (PMENU_STATE pMS); enum { @@ -156,7 +158,7 @@ FeedbackSetting (BYTE which_setting) ClearSemaphore (GraphicsSem); } -static BOOLEAN DoSettings (INPUT_STATE InputState, PMENU_STATE pMS); +static BOOLEAN DoSettings (PMENU_STATE pMS); static BOOLEAN DrawDescriptionString (PMENU_STATE pMS, COUNT which_string, SIZE state) @@ -166,7 +168,7 @@ DrawDescriptionString (PMENU_STATE pMS, COUNT which_string, SIZE state) TEXT lf; COLOR BackGround, ForeGround; FONT Font; - static BOOLEAN DoNaming (INPUT_STATE InputState, PMENU_STATE pMS); + static BOOLEAN DoNaming (PMENU_STATE pMS); SetSemaphore (GraphicsSem); @@ -255,12 +257,11 @@ DrawDescriptionString (PMENU_STATE pMS, COUNT which_string, SIZE state) pchar_deltas = char_deltas; for (i = pMS->first_item.x; i > 0; --i) text_r.corner.x += (SIZE)*pchar_deltas++; - if (SerialInput) - { - if ((COUNT)pMS->first_item.x < lf.CharCount) /* end of line */ - --text_r.corner.x; - text_r.extent.width = 1; - } + if ((COUNT)pMS->first_item.x < lf.CharCount) /* end of line */ + --text_r.corner.x; + text_r.extent.width = 1; +#if 0 + /* This is code that's a remnant of non-keyboard systems */ else { if ((COUNT)pMS->first_item.x == lf.CharCount) /* end of line */ @@ -268,6 +269,7 @@ DrawDescriptionString (PMENU_STATE pMS, COUNT which_string, SIZE state) else text_r.extent.width = (SIZE)*pchar_deltas; } +#endif text_r.corner.y = r.corner.y; text_r.extent.height = r.extent.height; SetContextForeGroundColor (BLACK_COLOR); @@ -284,15 +286,23 @@ DrawDescriptionString (PMENU_STATE pMS, COUNT which_string, SIZE state) } static UWORD -DoTextEntry (PMENU_STATE pMS, INPUT_STATE InputState) +DoTextEntry (PMENU_STATE pMS) { UWORD ch; UNICODE *pStr, *pBaseStr; COUNT len; + BOOLEAN left = FALSE, right = FALSE; pBaseStr = ((GAME_DESC *)pMS->CurString)[pMS->CurState - pMS->first_item.y]; pStr = &pBaseStr[pMS->first_item.x]; len = wstrlen (pStr); + + ch = GetCharacter (); + +#if 0 + /* This code goes away, but is listed here anyway just in case someone decides + to port this to a keyboardless platform later */ + if (SerialInput) { ch = GetInputUNICODE (GetInputState (SerialInput)); @@ -301,46 +311,60 @@ DoTextEntry (PMENU_STATE pMS, INPUT_STATE InputState) { extern UWORD GetJoystickChar (INPUT_STATE InputState); - ch = GetJoystickChar (InputState); + ch = GetJoystickChar (); } +#endif switch (ch) { - case 0x7F: - if (len) - { - memmove (pStr, pStr + 1, len * sizeof (*pStr)); - len = (COUNT)~0; - } - break; - case '\b': - if (pMS->first_item.x) - { - memmove (pStr - 1, pStr, (len + 1) * sizeof (*pStr)); - --pMS->first_item.x; - - len = (COUNT)~0; - } - break; - default: - if (isprint (ch) && len + (pStr - pBaseStr) < MAX_DESC_CHARS) - { - if (SerialInput) - { - memmove (pStr + 1, pStr, (len + 1) * sizeof (*pStr)); - *pStr++ = ch; - ++pMS->first_item.x; - } - else - { - *pStr = ch; - if (len == 0) - *(pStr + 1) = '\0'; - } - - len = (COUNT)~0; - } - break; + case SK_DELETE: + if (len) + { + memmove (pStr, pStr + 1, len * sizeof (*pStr)); + len = (COUNT)~0; + } + break; + case '\b': + if (pMS->first_item.x) + { + memmove (pStr - 1, pStr, (len + 1) * sizeof (*pStr)); + --pMS->first_item.x; + + len = (COUNT)~0; + } + break; + case SK_LF_ARROW: + left = TRUE; + break; + case SK_RT_ARROW: + right = TRUE; + break; + default: + /* This really should use isprint, but for some + * ungodly reason some machines refuse to accept + * anything as printable */ + if (!isascii (ch)) { + fprintf (stderr, "%d is not ascii, it says.\n", ch); + } + if (!isprint (ch)) { + fprintf (stderr, "%d is not printable, it says.\n", ch); + } + if (isprint (ch) && (len + (pStr - pBaseStr) < MAX_DESC_CHARS)) + { + memmove (pStr + 1, pStr, (len + 1) * sizeof (*pStr)); + if (len == 0) + *(pStr + 1) = '\0'; + *pStr++ = ch; + ++pMS->first_item.x; +#if 0 + /* Joystick letter-entry mode */ + *pStr = ch; + if (len == 0) + *(pStr + 1) = '\0'; +#endif + len = (COUNT)~0; + } + break; } if (len == (COUNT)~0) @@ -352,7 +376,7 @@ DoTextEntry (PMENU_STATE pMS, INPUT_STATE InputState) --pMS->first_item.x; } } - else if (GetInputXComponent (InputState) < 0) + else if (left) { if (pMS->first_item.x) { @@ -360,7 +384,7 @@ DoTextEntry (PMENU_STATE pMS, INPUT_STATE InputState) DrawDescriptionString (pMS, pMS->CurState, 1); } } - else if (GetInputXComponent (InputState) > 0) + else if (right) { if (len) { @@ -373,7 +397,7 @@ DoTextEntry (PMENU_STATE pMS, INPUT_STATE InputState) } static BOOLEAN -DoNaming (INPUT_STATE InputState, PMENU_STATE pMS) +DoNaming (PMENU_STATE pMS) { if (GLOBAL (CurrentActivity) & CHECK_ABORT) return (FALSE); @@ -396,7 +420,9 @@ DoNaming (INPUT_STATE InputState, PMENU_STATE pMS) DrawStatusMessage (GAME_STRING (NAMING_STRING_BASE + 0)); ClearSemaphore (GraphicsSem); + EnableCharacterMode (); DoInput (pMS); + DisableCharacterMode (); pMS->InputFunc = DoSettings; pMS->CurState = (BYTE)pMS->delta_item; @@ -408,18 +434,18 @@ DoNaming (INPUT_STATE InputState, PMENU_STATE pMS) { UWORD ch; - if (pMS->Initialized == 1 && SerialInput) + if (pMS->Initialized == 1) { FlushInput (); pMS->Initialized = 2; return (TRUE); } - ch = DoTextEntry (pMS, InputState); + ch = DoTextEntry (pMS); - if (ch == '\n' || ch == 0x1B) + if (ch == '\n' || ch == '\r' || ch == 0x1B) { - if (ch == '\n') + if (ch == '\n' || ch == '\r') { if (pMS->delta_item == CHANGE_CAPTAIN_SETTING) wstrcpy (GLOBAL_SIS (CommanderName), @@ -448,7 +474,7 @@ DoNaming (INPUT_STATE InputState, PMENU_STATE pMS) } static BOOLEAN -DoSettings (INPUT_STATE InputState, PMENU_STATE pMS) +DoSettings (PMENU_STATE pMS) { BYTE cur_speed; @@ -463,8 +489,8 @@ DoSettings (INPUT_STATE InputState, PMENU_STATE pMS) pMS->Initialized = TRUE; pMS->InputFunc = DoSettings; } - else if ((InputState & DEVICE_BUTTON2) - || ((InputState & DEVICE_BUTTON1) + else if (CurrentMenuState.cancel + || (CurrentMenuState.select && pMS->CurState == EXIT_MENU_SETTING)) { SetSemaphore (GraphicsSem); @@ -475,7 +501,7 @@ DoSettings (INPUT_STATE InputState, PMENU_STATE pMS) pMS->InputFunc = DoGameOptions; pMS->Initialized = 0; } - else if (InputState & DEVICE_BUTTON1) + else if (CurrentMenuState.select) { switch (pMS->CurState) { @@ -513,8 +539,8 @@ DoSettings (INPUT_STATE InputState, PMENU_STATE pMS) FeedbackSetting (pMS->CurState); } - else if (DoMenuChooser (InputState, pMS, PM_SOUND_ON)) - FeedbackSetting (pMS->CurState); + else if (DoMenuChooser (pMS, PM_SOUND_ON)) + FeedbackSetting (pMS->CurState); return (TRUE); } @@ -883,7 +909,7 @@ LoadGameDescriptions (SUMMARY_DESC *pSD) } static BOOLEAN -DoPickGame (INPUT_STATE InputState, PMENU_STATE pMS) +DoPickGame (PMENU_STATE pMS) { BYTE NewState; STAMP s; @@ -926,7 +952,7 @@ Restart: pMS->Initialized = TRUE; goto ChangeGameSelection; } - else if (InputState & DEVICE_BUTTON2) + else if (CurrentMenuState.cancel) { SetSemaphore (GraphicsSem); SetFlashRect (NULL_PTR, (FRAME)0); @@ -953,7 +979,7 @@ Restart: } return (FALSE); } - else if (InputState & DEVICE_BUTTON1) + else if (CurrentMenuState.select) { pSD = &((SUMMARY_DESC *)pMS->CurString)[pMS->CurState]; if (pMS->delta_item == SAVE_GAME || pSD->year_index) @@ -1021,12 +1047,12 @@ RetrySave: else { NewState = pMS->CurState; - if (GetInputXComponent (InputState) < 0) + if (CurrentMenuState.left) { if (NewState-- == 0) NewState = MAX_SAVED_GAMES - 1; } - else if (GetInputXComponent (InputState) > 0) + else if (CurrentMenuState.right) { if (++NewState == MAX_SAVED_GAMES) NewState = 0; @@ -1103,8 +1129,7 @@ ChangeGameSelection: } static BOOLEAN -PickGame (PMENU_STATE - pMS) +PickGame (PMENU_STATE pMS) { BOOLEAN retval; CONTEXT OldContext; @@ -1197,17 +1222,14 @@ PickGame (PMENU_STATE } static BOOLEAN -DoGameOptions - (INPUT_STATE - InputState, - PMENU_STATE - pMS) +DoGameOptions (PMENU_STATE pMS) { + BOOLEAN force_select = FALSE; if (GLOBAL (CurrentActivity) & CHECK_ABORT) return (FALSE); if (LastActivity == CHECK_LOAD) - InputState = DEVICE_BUTTON1; + force_select = TRUE; if (pMS->Initialized <= 0) { @@ -1218,14 +1240,14 @@ DoGameOptions pMS->Initialized = 1; pMS->InputFunc = DoGameOptions; } - else if ((InputState & DEVICE_BUTTON2) - || ((InputState & DEVICE_BUTTON1) + else if (CurrentMenuState.cancel + || (CurrentMenuState.select && pMS->CurState == SETTINGS + 1)) { pMS->CurState = SETTINGS + 1; return (FALSE); } - else if (InputState & DEVICE_BUTTON1) + else if (CurrentMenuState.select || force_select) { switch (pMS->CurState) { @@ -1241,7 +1263,7 @@ DoGameOptions } } else - DoMenuChooser (InputState, pMS, PM_SAVE_GAME); + DoMenuChooser (pMS, PM_SAVE_GAME); return (TRUE); } diff --git a/sc2/src/sc2code/getchar.c b/sc2/src/sc2code/getchar.c index 247831fae..598997a29 100644 --- a/sc2/src/sc2code/getchar.c +++ b/sc2/src/sc2code/getchar.c @@ -29,20 +29,22 @@ SetJoystickChar (UWORD which_char) } UWORD -GetJoystickChar (INPUT_STATE InputState) +GetJoystickChar (void) { int dy; UWORD old_char; - if (InputState & DEVICE_BUTTON1) + if (CurrentMenuState.select) return ('\n'); - else if (InputState & DEVICE_BUTTON2) + else if (CurrentMenuState.cancel) return (0x1B); - else if (InputState & DEVICE_BUTTON3) + else if (CurrentMenuState.special) return (0x7F); old_char = cur_char; - dy = GetInputYComponent (InputState); + dy = 0; + if (CurrentMenuState.up) dy = -1; + else if (CurrentMenuState.down) dy = 1; if (dy) { if (cur_char == ' ') @@ -70,7 +72,7 @@ GetJoystickChar (INPUT_STATE InputState) } } - if ((InputState & (DEVICE_LEFTSHIFT | DEVICE_RIGHTSHIFT)) && isalpha (cur_char)) + if ((CurrentMenuState.page_up || CurrentMenuState.page_down) && isalpha (cur_char)) { if (islower (cur_char)) cur_char = toupper (cur_char); diff --git a/sc2/src/sc2code/intel.c b/sc2/src/sc2code/intel.c index 0b50c42a2..95d18864a 100644 --- a/sc2/src/sc2code/intel.c +++ b/sc2/src/sc2code/intel.c @@ -17,21 +17,23 @@ */ #include "starcon.h" +#include "controls.h" SIZE cur_player; -INPUT_STATE -computer_intelligence (INPUT_REF InputRef, INPUT_STATE InputState) +BATTLE_INPUT_STATE +computer_intelligence (void) { - if (InputState || LOBYTE (GLOBAL (CurrentActivity)) == IN_LAST_BATTLE) - return (InputState); + BATTLE_INPUT_STATE InputState; + if (LOBYTE (GLOBAL (CurrentActivity)) == IN_LAST_BATTLE) + return (0); if (CyborgDescPtr) { if (PlayerControl[cur_player] & CYBORG_CONTROL) InputState = tactical_intelligence (); else - InputState = GetInputState (CombinedInput[cur_player]); + InputState = (*(HumanInput[cur_player])) (); } else if (!(PlayerControl[cur_player] & PSYTRON_CONTROL)) InputState = 0; @@ -42,12 +44,11 @@ computer_intelligence (INPUT_REF InputRef, INPUT_STATE InputState) case SUPER_MELEE: { SleepThread (ONE_SECOND >> 1); - InputState = DEVICE_BUTTON1; /* pick a random ship */ + InputState = BATTLE_WEAPON; /* pick a random ship */ break; } } } - (void) InputRef; /* Satisfying compiler (unused parameter) */ return (InputState); } diff --git a/sc2/src/sc2code/intel.h b/sc2/src/sc2code/intel.h index f79b00d6f..0b7047e52 100644 --- a/sc2/src/sc2code/intel.h +++ b/sc2/src/sc2code/intel.h @@ -19,6 +19,8 @@ #ifndef _INTEL_H #define _INTEL_H +#include "controls.h" + typedef enum { PURSUE = 0, @@ -58,9 +60,8 @@ enum extern STARSHIPPTR CyborgDescPtr; -extern INPUT_STATE computer_intelligence (INPUT_REF InputRef, INPUT_STATE - InputState); -extern INPUT_STATE tactical_intelligence (void); +extern BATTLE_INPUT_STATE computer_intelligence (void); +extern BATTLE_INPUT_STATE tactical_intelligence (void); extern void ship_intelligence (ELEMENTPTR ShipPtr, EVALUATE_DESCPTR ObjectsOfConcern, COUNT ConcernCounter); extern BOOLEAN ship_weapons (ELEMENTPTR ShipPtr, ELEMENTPTR OtherPtr, diff --git a/sc2/src/sc2code/intro.c b/sc2/src/sc2code/intro.c index d9886e2ed..3be553514 100644 --- a/sc2/src/sc2code/intro.c +++ b/sc2/src/sc2code/intro.c @@ -42,7 +42,7 @@ Introduction (void) BYTE xform_buf[1]; STAMP s; DWORD TimeOut; - INPUT_STATE InputState; + BOOLEAN InputState; xform_buf[0] = FadeAllToBlack; SleepThreadUntil (XFormColorMap ( diff --git a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c index 7c98ba848..c639985dd 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c +++ b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c @@ -27,6 +27,7 @@ #include "uqmversion.h" #include "SDL_thread.h" #include "libs/graphics/drawcmd.h" +#include "libs/input/sdl/vcontrol.h" #include "bbox.h" SDL_Surface *SDL_Video; @@ -102,19 +103,13 @@ TFB_ProcessEvents () while (SDL_PollEvent (&Event)) { + /* Run through the InputEvent filter. */ + ProcessInputEvent (&Event); + /* Handle Graphics events. */ switch (Event.type) { case SDL_ACTIVEEVENT: /* Loose/gain visibility */ // TODO break; - case SDL_KEYDOWN: /* Key pressed */ - case SDL_KEYUP: /* Key released */ - ProcessKeyboardEvent (&Event); - break; - case SDL_JOYAXISMOTION: /* Joystick axis motion */ - case SDL_JOYBUTTONDOWN: /* Joystick button pressed */ - case SDL_JOYBUTTONUP: /* Joystick button released */ - ProcessJoystickEvent (&Event); - break; case SDL_QUIT: exit (0); break; @@ -128,6 +123,8 @@ TFB_ProcessEvents () break; } } + if (ImmediateInputState.abort) + exit (0); } void diff --git a/sc2/src/sc2code/libs/inplib.h b/sc2/src/sc2code/libs/inplib.h index f37e70540..70c660f89 100644 --- a/sc2/src/sc2code/libs/inplib.h +++ b/sc2/src/sc2code/libs/inplib.h @@ -21,17 +21,8 @@ #include "memlib.h" -typedef PVOID INPUT_REF; -typedef MEM_HANDLE INPUT_DEVICE; typedef DWORD INPUT_STATE; -typedef enum -{ - KEYBOARD_DEVICE = 0, - JOYSTICK_DEVICE, - MOUSE_DEVICE -} INPUT_DEVTYPE; - /* Serial Keyboard Pseudo UNICODE Equivalents */ #define SK_DELETE ((UNICODE)127) #define SK_LF_ARROW ((UNICODE)128) @@ -66,45 +57,9 @@ typedef enum #define SK_F11 ((UNICODE)155) #define SK_F12 ((UNICODE)156) -#define DEVTYPE_MASK 0x03 -#define GetInputUNICODE(is) (LOWORD (is)) -#define GetInputXComponent(is) ((SBYTE)(LOBYTE (LOWORD (is)))) -#define GetInputYComponent(is) ((SBYTE)(HIBYTE (LOWORD (is)))) -#define GetInputDevType(is) ((INPUT_DEVTYPE)(HIWORD (is) & DEVTYPE_MASK)) -#define SetInputUNICODE(is,a) \ - (*(is) = (*(is) & ~0x0000FFFFL) | (UNICODE)(a)) -#define SetInputXComponent(is,x) \ - (*(is) = (*(is) & ~0x000000FFL) | (BYTE)(x)) -#define SetInputYComponent(is,y) \ - (*(is) = (*(is) & ~0x0000FF00L) | (UWORD)((BYTE)(y) << 8)) -#define SetInputDevType(is,t) \ - (*(is) = (*(is) & ~0x00030000L) | ((DWORD)((t) & DEVTYPE_MASK) << 16)) -#define DEVICE_BUTTON1 ((INPUT_STATE)1 << 19) -#define DEVICE_BUTTON2 ((INPUT_STATE)1 << 20) -#define DEVICE_BUTTON3 ((INPUT_STATE)1 << 21) -#define DEVICE_BUTTON4 ((INPUT_STATE)1 << 22) -#define DEVICE_PAUSE ((INPUT_STATE)1 << 23) -#define DEVICE_EXIT ((INPUT_STATE)1 << 24) -#define DEVICE_LEFTSHIFT ((INPUT_STATE)1 << 25) -#define DEVICE_RIGHTSHIFT ((INPUT_STATE)1 << 26) - -extern BOOLEAN InitInput (BOOLEAN (*PauseFunc) (void), UNICODE Pause, - UNICODE Exit, UNICODE Abort); +extern BOOLEAN InitInput (void); extern BOOLEAN UninitInput (void); -extern INPUT_DEVICE CreateSerialKeyboardDevice (void); -extern INPUT_DEVICE CreateJoystickKeyboardDevice (UWORD lfkey, UWORD - rtkey, UWORD topkey, UWORD botkey, UWORD but1key, UWORD - but2key, UWORD but3key, UWORD but4key, UWORD shift1key, UWORD shift2key); -extern INPUT_DEVICE CreateJoystickDevice (COUNT port, UWORD threshold, - UWORD left, UWORD right, UWORD up, UWORD down, - UWORD but1, UWORD but2, UWORD but3, UWORD but4, UWORD s1, UWORD s2); -extern INPUT_DEVICE CreateInternalDevice (INPUT_STATE (*input_func) - (INPUT_REF InputRef, INPUT_STATE InputState)); -extern BOOLEAN DestroyInputDevice (INPUT_DEVICE InputDevice); -extern INPUT_REF CaptureInputDevice (INPUT_DEVICE InputDevice); -extern INPUT_DEVICE ReleaseInputDevice (INPUT_REF InputRef); -extern INPUT_STATE GetInputState (INPUT_REF InputRef); -extern INPUT_STATE AnyButtonPress (BOOLEAN DetectSpecial); +extern BOOLEAN AnyButtonPress (BOOLEAN DetectSpecial); extern void FlushInput (void); extern BOOLEAN KeyDown (UNICODE which_scan); @@ -118,32 +73,11 @@ extern void MoveMouse (SWORD x, SWORD y); extern BYTE LocateMouse (PSWORD px, PSWORD py); */ -/* - * joystick_buttons format - * Bit 15 - (0) - Button - * (1) - Axis - * Bit 14 - (0) - positive (n/a for buttons) - * (1) - negative (use chord for buttons) - * Bit 0-7 - button / axis number - * Bit 8-13 - chorded button - */ -#define JOYAXISMASK 0x8000 -/* axis number, sign */ -#define JOYAXIS(a,s) (0x8000 | (s < 0 ? 0x4000 : 0 ) | (a & 0xFF)) -#define JOYBUTTON(b) ((UWORD)(b & 0xFF)) -#define JOYCHORD(b1,b2) ((UWORD)(0x4000 | (b1 & 0xFF) | ((b2 & 0x3F) << 8))) -#define JOYISAXIS(v) (v & JOYAXISMASK) -#define JOYISCHORD(v) (v & 0x4000) -#define JOYGETVALUE(v) (v & 0xFF) -#define JOYGETSIGN(v) ((v & 0x4000) ? -1 : 1) -#define JOYGETCHORD(v) ((v & 0x3F00) >> 8) +/* Functions for dealing with Character Mode */ -#define KEYCHORD(k1, k2) ((UWORD) ((k1 & 0xFF) << 8) | (k2 & 0xFF)) -#define KEYGETCHORD(v) ((v & 0xFF00) >> 8) -#define KEYISCHORD(v) (v & 0xFF00) -#define KEYGETKEY(v) (v & 0xFF) - -extern UNICODE PauseKey, ExitKey, AbortKey; +void EnableCharacterMode (void); +void DisableCharacterMode (void); +UNICODE GetCharacter (void); #endif /* _INPLIB_H */ diff --git a/sc2/src/sc2code/libs/input/inpintrn.h b/sc2/src/sc2code/libs/input/inpintrn.h index df94cca03..dd2e5da08 100644 --- a/sc2/src/sc2code/libs/input/inpintrn.h +++ b/sc2/src/sc2code/libs/input/inpintrn.h @@ -21,108 +21,5 @@ #include "inplib.h" -#define NUM_INPUTS 10 -/* - * Inputs - * 0 - Left - * 1 - Right - * 2 - Up - * 3 - Down - * 4 - Button 1 - * 5 - Button 2 - * 6 - Button 3 - * 7 - Button 4 - * 8 - Left shift - * 9 - Right shift - */ - -typedef struct inp_dev -{ - INPUT_DEVICE ThisDevice; - union - { - UWORD key_equivalent[NUM_INPUTS]; - struct - { - BYTE joystick_port; - UWORD joystick_threshold; - /* See inplib.h for description of this field */ - UWORD joystick_buttons[NUM_INPUTS]; - } joystick_info; - } device; - INPUT_STATE (*input_func) (INPUT_REF InputRef, INPUT_STATE - InputState); -} INPUT_DESC; -typedef INPUT_DESC *PINPUT_DESC; -typedef PINPUT_DESC INPUT_DESCPTR; - -#define INPUT_DEVICE_PRIORITY DEFAULT_MEM_PRIORITY - -#ifndef _DISPLIST_H -/* This ifndef is temporary to avoid a collision with displist.h - This shouldn't be necessary, but SDL_wrappper.h isn't set up correctly - at the moment. */ -typedef PBYTE BYTEPTR; -#endif - -#define AllocInputDevice() \ - (INPUT_DEVICE)mem_allocate ((MEM_SIZE)sizeof (INPUT_DESC), \ - MEM_ZEROINIT, INPUT_DEVICE_PRIORITY, MEM_SIMPLE) -#define LockInputDevice(InputDevice) (INPUT_DESCPTR)mem_lock (InputDevice) -#define UnlockInputDevice(InputDevice) mem_unlock (InputDevice) -#define FreeInputDevice(InputDevice) mem_release (InputDevice) - -#define SetInputDeviceHandle(i,h) \ - ((INPUT_DESCPTR)(i))->ThisDevice = (h) -#define SetInputDeviceKeyEquivalents(i,l,r,t,b,b1,b2,b3,b4,s1,s2) \ - (((INPUT_DESCPTR)(i))->device.key_equivalent[0] = (l), \ - ((INPUT_DESCPTR)(i))->device.key_equivalent[1] = (r), \ - ((INPUT_DESCPTR)(i))->device.key_equivalent[2] = (t), \ - ((INPUT_DESCPTR)(i))->device.key_equivalent[3] = (b), \ - ((INPUT_DESCPTR)(i))->device.key_equivalent[4] = (b1), \ - ((INPUT_DESCPTR)(i))->device.key_equivalent[5] = (b2), \ - ((INPUT_DESCPTR)(i))->device.key_equivalent[6] = (b3), \ - ((INPUT_DESCPTR)(i))->device.key_equivalent[7] = (b4), \ - ((INPUT_DESCPTR)(i))->device.key_equivalent[8] = (s1), \ - ((INPUT_DESCPTR)(i))->device.key_equivalent[9] = (s2)) -#define SetInputDeviceJoystickButtons(i,l,r,t,b,b1,b2,b3,b4,s1,s2) \ - (((INPUT_DESCPTR)(i))->device.joystick_info.joystick_buttons[0] = l, \ - ((INPUT_DESCPTR)(i))->device.joystick_info.joystick_buttons[1] = r, \ - ((INPUT_DESCPTR)(i))->device.joystick_info.joystick_buttons[2] = t, \ - ((INPUT_DESCPTR)(i))->device.joystick_info.joystick_buttons[3] = b, \ - ((INPUT_DESCPTR)(i))->device.joystick_info.joystick_buttons[4] = b1, \ - ((INPUT_DESCPTR)(i))->device.joystick_info.joystick_buttons[5] = b2, \ - ((INPUT_DESCPTR)(i))->device.joystick_info.joystick_buttons[6] = b3, \ - ((INPUT_DESCPTR)(i))->device.joystick_info.joystick_buttons[7] = b4, \ - ((INPUT_DESCPTR)(i))->device.joystick_info.joystick_buttons[8] = s1, \ - ((INPUT_DESCPTR)(i))->device.joystick_info.joystick_buttons[9] = s2) -#define SetInputDeviceJoystickPort(i,p) \ - ((INPUT_DESCPTR)(i))->device.joystick_info.joystick_port = (p) -#define SetInputDeviceJoystickThreshold(i,t) \ - ((INPUT_DESCPTR)(i))->device.joystick_info.joystick_threshold = (t) -#define SetInputDeviceInputFunc(i,f) \ - ((INPUT_DESCPTR)(i))->input_func = (f) - -#define GetInputDeviceHandle(i) \ - ((INPUT_DESCPTR)(i))->ThisDevice -#define GetInputDeviceKeyEquivalentPtr(i) \ - ((INPUT_DESCPTR)(i))->device.key_equivalent -#define GetInputDeviceJoystickButtonPtr(i) \ - ((INPUT_DESCPTR)(i))->device.joystick_info.joystick_buttons -#define GetInputDeviceJoystickPort(i) \ - ((INPUT_DESCPTR)(i))->device.joystick_info.joystick_port -#define GetInputDeviceJoystickThreshold(i) \ - ((INPUT_DESCPTR)(i))->device.joystick_info.joystick_threshold -#define GetInputDeviceInputFunc(i) \ - ((INPUT_DESCPTR)(i))->input_func - -extern INPUT_STATE _get_serial_keyboard_state (INPUT_REF InputRef, - INPUT_STATE InputState); -extern INPUT_STATE _get_joystick_keyboard_state (INPUT_REF InputRef, - INPUT_STATE InputState); -extern INPUT_STATE _get_joystick_state (INPUT_REF InputRef, - INPUT_STATE InputState); -extern BOOLEAN _joystick_port_active (COUNT port); -extern INPUT_STATE _get_pause_exit_state (void); #endif /* _INPINTRN_H */ diff --git a/sc2/src/sc2code/libs/input/input_common.c b/sc2/src/sc2code/libs/input/input_common.c index ff2d1b7d5..436a3447b 100644 --- a/sc2/src/sc2code/libs/input/input_common.c +++ b/sc2/src/sc2code/libs/input/input_common.c @@ -19,172 +19,4 @@ #include "input_common.h" #include "inpintrn.h" -INPUT_DEVICE -CreateSerialKeyboardDevice (void) -{ - INPUT_DEVICE InputDevice; - - if ((InputDevice = AllocInputDevice ()) != (INPUT_DEVICE)NULL_PTR) - { - INPUT_DESCPTR InputPtr; - - if ((InputPtr = - LockInputDevice (InputDevice)) == (INPUT_DESCPTR)NULL_PTR) - { - FreeInputDevice (InputDevice); - InputDevice = (INPUT_DEVICE)NULL_PTR; - } - else - { - SetInputDeviceHandle (InputPtr, InputDevice); - SetInputDeviceInputFunc (InputPtr, _get_serial_keyboard_state); - - UnlockInputDevice (InputDevice); - } - } - - return (InputDevice); -} - -INPUT_DEVICE -CreateJoystickKeyboardDevice (UWORD lfkey, UWORD rtkey, UWORD - topkey, UWORD botkey, UWORD but1key, UWORD but2key, UWORD - but3key, UWORD but4key, UWORD shift1key, UWORD shift2key) -{ - INPUT_DEVICE InputDevice; - - if ((InputDevice = AllocInputDevice ()) != (INPUT_DEVICE)NULL_PTR) - { - INPUT_DESCPTR InputPtr; - - if ((InputPtr = - LockInputDevice (InputDevice)) == (INPUT_DESCPTR)NULL_PTR) - { - FreeInputDevice (InputDevice); - InputDevice = (INPUT_DEVICE)NULL_PTR; - } - else - { - SetInputDeviceHandle (InputPtr, InputDevice); - SetInputDeviceInputFunc (InputPtr, _get_joystick_keyboard_state); - SetInputDeviceKeyEquivalents (InputPtr, - lfkey, rtkey, topkey, botkey, - but1key, but2key, but3key, but4key, - shift1key, shift2key); - - UnlockInputDevice (InputDevice); - } - } - - return (InputDevice); -} - -INPUT_DEVICE -CreateJoystickDevice (COUNT port, UWORD threshold, UWORD left, UWORD right, - UWORD top, UWORD bottom, UWORD but1, UWORD but2, UWORD but3, UWORD but4, - UWORD s1, UWORD s2) -{ - INPUT_DEVICE InputDevice; - - if (!_joystick_port_active (port)) - InputDevice = (INPUT_DEVICE)NULL_PTR; - else if ((InputDevice = AllocInputDevice ()) != (INPUT_DEVICE)NULL_PTR) - { - INPUT_DESCPTR InputPtr; - - if ((InputPtr = - LockInputDevice (InputDevice)) == (INPUT_DESCPTR)NULL_PTR) - { - FreeInputDevice (InputDevice); - InputDevice = (INPUT_DEVICE)NULL_PTR; - } - else - { - SetInputDeviceHandle (InputPtr, InputDevice); - SetInputDeviceInputFunc (InputPtr, _get_joystick_state); - SetInputDeviceJoystickPort (InputPtr, port); - SetInputDeviceJoystickButtons (InputPtr, left, right, top, bottom, - but1, but2, but3, but4, s1, s2); - SetInputDeviceJoystickThreshold(InputPtr, threshold); - - UnlockInputDevice (InputDevice); - } - } - - return (InputDevice); -} - -INPUT_DEVICE -CreateInternalDevice (INPUT_STATE (*input_func) (INPUT_REF InputRef, - INPUT_STATE InputState)) -{ - INPUT_DEVICE InputDevice; - - if (input_func == NULL_PTR) - InputDevice = (INPUT_DEVICE)NULL_PTR; - else if ((InputDevice = AllocInputDevice ()) != (INPUT_DEVICE)NULL_PTR) - { - INPUT_DESCPTR InputPtr; - - if ((InputPtr = - LockInputDevice (InputDevice)) == (INPUT_DESCPTR)NULL_PTR) - { - FreeInputDevice (InputDevice); - InputDevice = (INPUT_DEVICE)NULL_PTR; - } - else - { - SetInputDeviceHandle (InputPtr, InputDevice); - SetInputDeviceInputFunc (InputPtr, input_func); - - UnlockInputDevice (InputDevice); - } - } - - return (InputDevice); -} - -INPUT_REF -CaptureInputDevice (INPUT_DEVICE InputDevice) -{ - if (InputDevice != (INPUT_DEVICE)NULL_PTR) - return ((INPUT_REF)LockInputDevice (InputDevice)); - - return ((INPUT_REF)NULL_PTR); -} - -INPUT_DEVICE -ReleaseInputDevice (INPUT_REF InputRef) -{ - INPUT_DEVICE InputDevice; - - if (InputRef == (INPUT_REF)NULL_PTR) - InputDevice = (INPUT_DEVICE)NULL_PTR; - else - { - InputDevice = GetInputDeviceHandle (InputRef); - UnlockInputDevice (InputDevice); - } - - return (InputDevice); -} - -BOOLEAN -DestroyInputDevice (INPUT_DEVICE InputDevice) -{ - if (InputDevice != (INPUT_DEVICE)NULL_PTR) - return (FreeInputDevice (InputDevice)); - - return (FALSE); -} - -INPUT_STATE -GetInputState (INPUT_REF InputRef) -{ - if (InputRef == 0) - return (_get_pause_exit_state ()); - else - return ((*GetInputDeviceInputFunc (InputRef)) - (InputRef, _get_pause_exit_state ())); -} - +volatile BOOLEAN ExitRequested, GameExiting, GamePaused; diff --git a/sc2/src/sc2code/libs/input/input_common.h b/sc2/src/sc2code/libs/input/input_common.h index 6ec6a0ca8..1a100e502 100644 --- a/sc2/src/sc2code/libs/input/input_common.h +++ b/sc2/src/sc2code/libs/input/input_common.h @@ -30,5 +30,6 @@ enum int TFB_InitInput (int driver, int flags); void TFB_UninitInput (void); +void TFB_CreateDefaultConfig (void); #endif diff --git a/sc2/src/sc2code/libs/input/sdl/Makeinfo b/sc2/src/sc2code/libs/input/sdl/Makeinfo index fb41891a8..86cd999e5 100644 --- a/sc2/src/sc2code/libs/input/sdl/Makeinfo +++ b/sc2/src/sc2code/libs/input/sdl/Makeinfo @@ -1 +1 @@ -uqm_CFILES="input.c" +uqm_CFILES="input.c keynames.c vcontrol.c" diff --git a/sc2/src/sc2code/libs/input/sdl/input.c b/sc2/src/sc2code/libs/input/sdl/input.c index 7108ce9d4..01aae6f59 100644 --- a/sc2/src/sc2code/libs/input/sdl/input.c +++ b/sc2/src/sc2code/libs/input/sdl/input.c @@ -18,37 +18,125 @@ #ifdef GFXMODULE_SDL +#include +#include #include "libs/graphics/sdl/sdl_common.h" #include "libs/input/input_common.h" +#include "libs/input/sdl/vcontrol.h" +#include "controls.h" +#include "libs/file.h" +#include "options.h" + -static Uint8 KeyboardDown[SDLK_LAST]; #define KBDBUFSIZE (1 << 8) static int kbdhead=0, kbdtail=0; static UNICODE kbdbuf[KBDBUFSIZE]; -static int nJoysticks = 0; -static SDL_Joystick **Joysticks = 0; - -static UBYTE **JoybuttonDown = 0; -static SWORD **JoyaxisValues = 0; - -static BOOLEAN (* PauseFunc) (void) = 0; static BOOLEAN InputInitialized = FALSE; UWORD UNICODEToKBD (UNICODE which_key); -UNICODE PauseKey = 0; -UNICODE ExitKey = 0; -UNICODE AbortKey = 0; +static BOOLEAN _in_character_mode = FALSE; + +static VControl_NameBinding control_names[] = { + { "Menu-Up", (int *)&ImmediateMenuState.up }, + { "Menu-Down", (int *)&ImmediateMenuState.down }, + { "Menu-Left", (int *)&ImmediateMenuState.left }, + { "Menu-Right", (int *)&ImmediateMenuState.right }, + { "Menu-Select", (int *)&ImmediateMenuState.select }, + { "Menu-Cancel", (int *)&ImmediateMenuState.cancel }, + { "Menu-Special", (int *)&ImmediateMenuState.special }, + { "Menu-Page-Up", (int *)&ImmediateMenuState.page_up }, + { "Menu-Page-Down", (int *)&ImmediateMenuState.page_down }, + { "Menu-Zoom-In", (int *)&ImmediateMenuState.zoom_in }, + { "Menu-Zoom-Out", (int *)&ImmediateMenuState.zoom_out }, + { "Player-1-Thrust", (int *)&ImmediateInputState.p1_thrust }, + { "Player-1-Left", (int *)&ImmediateInputState.p1_left }, + { "Player-1-Right", (int *)&ImmediateInputState.p1_right }, + { "Player-1-Weapon", (int *)&ImmediateInputState.p1_weapon }, + { "Player-1-Special", (int *)&ImmediateInputState.p1_special }, + { "Player-1-Escape", (int *)&ImmediateInputState.p1_escape }, + { "Player-2-Thrust", (int *)&ImmediateInputState.p2_thrust }, + { "Player-2-Left", (int *)&ImmediateInputState.p2_left }, + { "Player-2-Right", (int *)&ImmediateInputState.p2_right }, + { "Player-2-Weapon", (int *)&ImmediateInputState.p2_weapon }, + { "Player-2-Special", (int *)&ImmediateInputState.p2_special }, + { "Lander-Thrust", (int *)&ImmediateInputState.lander_thrust }, + { "Lander-Left", (int *)&ImmediateInputState.lander_left }, + { "Lander-Right", (int *)&ImmediateInputState.lander_right }, + { "Lander-Weapon", (int *)&ImmediateInputState.lander_weapon }, + { "Lander-Escape", (int *)&ImmediateInputState.lander_escape }, + { "Pause", (int *)&ImmediateInputState.pause }, + { "Exit", (int *)&ImmediateInputState.exit }, + { "Abort", (int *)&ImmediateInputState.abort }}; + + +static void +initKeyConfig(void) { + char userFile[PATH_MAX]; /* System-wide key config */ + int cb; + + cb = snprintf (userFile, PATH_MAX, "%skeys.cfg", configDir); + assert (cb != -1); + // Verified before: strlen (configDir) <= PATH_MAX - 13 + + if (fileExists (userFile)) { + FILE *fp; + int errors; + /* Should this really be an OpenResFile? The user + * won't be putting his configuration data in a .zip, + * will he? */ + fp = res_OpenResFile (userFile, "rt"); + errors = VControl_ReadConfiguration (fp); + res_CloseResFile (fp); + if (errors) + { + fprintf (stderr, "%d errors encountered in key configuration file.\n", errors); + /* This code should go away in 0.3; it's just + * to force people to upgrade and forestall a + * bunch of "none of my keys work anymore" bugs. + */ + if (errors > 5) + { + fprintf (stderr, "Hey! you haven't updated your keys.cfg to use the new system, have you?\nDelete %s and try again.\n", userFile); + } + else + { + fprintf (stderr, "Repair your %s file to continue.\n", userFile); + } + + exit (1); + } + } else { + FILE *fp = fopen (userFile, "wt"); + TFB_CreateDefaultConfig (); + + if (fp == NULL) + { + fprintf(stderr, "Warning: Could not copy default key config " + "to %s: %s.\n", userFile, strerror (errno)); + } + else + { + fprintf(stderr, "Copying default key config file to %s.\n", + userFile); + VControl_Dump (fp); + fclose (fp); + } + } +} int TFB_InitInput (int driver, int flags) { int i; + int nJoysticks; (void)driver; (void)flags; atexit (TFB_UninitInput); + GamePaused = GameExiting = ExitRequested = FALSE; + SDL_EnableUNICODE(1); if ((SDL_InitSubSystem(SDL_INIT_JOYSTICK)) == -1) @@ -62,33 +150,24 @@ TFB_InitInput (int driver, int flags) nJoysticks = SDL_NumJoysticks (); if (nJoysticks > 0) { - Joysticks = HMalloc(sizeof(SDL_Joystick*) * nJoysticks); - JoybuttonDown = HMalloc(sizeof(UBYTE*) * nJoysticks); - JoyaxisValues = HMalloc(sizeof(SWORD*) * nJoysticks); fprintf (stderr, "The names of the joysticks are:\n"); for(i = 0; i < nJoysticks; i++) { fprintf (stderr, " %s\n", SDL_JoystickName (i)); - Joysticks[i] = SDL_JoystickOpen (i); - JoybuttonDown[i] = HMalloc(sizeof(UBYTE) * - SDL_JoystickNumButtons(Joysticks[i])); - memset(JoybuttonDown[i], 0, sizeof(UBYTE) * - SDL_JoystickNumButtons(Joysticks[i])); - JoyaxisValues[i] = HMalloc(sizeof(SWORD) * - SDL_JoystickNumAxes(Joysticks[i])); - memset(JoyaxisValues[i], 0, sizeof(SWORD) * - SDL_JoystickNumAxes(Joysticks[i])); - fprintf (stderr, " %i axes, %i buttons\n", - SDL_JoystickNumAxes(Joysticks[i]), - SDL_JoystickNumButtons(Joysticks[i])); } SDL_JoystickEventState (SDL_ENABLE); } - for (i = 0; i < SDLK_LAST; i++) - { - KeyboardDown[i] = FALSE; - } + _in_character_mode = FALSE; + + /* Prepare the Virtual Controller system. */ + VControl_Init (); + VControl_RegisterNameTable (control_names); + + initKeyConfig (); + + VControl_ResetInput (); + InputInitialized = TRUE; return 0; } @@ -96,103 +175,151 @@ TFB_InitInput (int driver, int flags) void TFB_UninitInput (void) { - int j; - for (j = 0; j < nJoysticks; ++j) - { - HFree(JoyaxisValues[j]); - HFree(JoybuttonDown[j]); - SDL_JoystickClose(Joysticks[j]); - Joysticks[j] = 0; - } - HFree(Joysticks); + VControl_Uninit (); } void -ProcessKeyboardEvent(const SDL_Event *Event) +TFB_CreateDefaultConfig (void) +{ + /* Generate the default control structures. Arrow keys have + * the expected effect. ENTER is menu select, SPACE is menu + * cancel. In combat or on planet surfaces, move with the + * arrow keys, or thrust with ENTER, fire with SPACE or right + * SHIFT, and do your special with right CTRL. Escaping is + * handled by the ESCAPE key. Player 2 flies with W-A-D, + * fires with T, and does his special with Y. Pause is F1, + * Exit is F10, and Abort is F12. Zooming may be done with + * Page Up or Page Down, or with the + and - keys on the + * numeric keypad. + * + * All references to "the arrow keys" or "ENTER" may use the + * numeric keypad. */ + VControl_AddKeyBinding (SDLK_UP, (int *)&ImmediateMenuState.up); + VControl_AddKeyBinding (SDLK_DOWN, (int *)&ImmediateMenuState.down); + VControl_AddKeyBinding (SDLK_LEFT, (int *)&ImmediateMenuState.left); + VControl_AddKeyBinding (SDLK_RIGHT, (int *)&ImmediateMenuState.right); + VControl_AddKeyBinding (SDLK_RETURN, (int *)&ImmediateMenuState.select); + VControl_AddKeyBinding (SDLK_KP8, (int *)&ImmediateMenuState.up); + VControl_AddKeyBinding (SDLK_KP2, (int *)&ImmediateMenuState.down); + VControl_AddKeyBinding (SDLK_KP4, (int *)&ImmediateMenuState.left); + VControl_AddKeyBinding (SDLK_KP6, (int *)&ImmediateMenuState.right); + VControl_AddKeyBinding (SDLK_KP_ENTER, (int *)&ImmediateMenuState.select); + VControl_AddKeyBinding (SDLK_SPACE, (int *)&ImmediateMenuState.cancel); + VControl_AddKeyBinding (SDLK_PAGEUP, (int *)&ImmediateMenuState.page_up); + VControl_AddKeyBinding (SDLK_PAGEDOWN, (int *)&ImmediateMenuState.page_down); + VControl_AddKeyBinding (SDLK_KP9, (int *)&ImmediateMenuState.page_up); + VControl_AddKeyBinding (SDLK_KP3, (int *)&ImmediateMenuState.page_down); + VControl_AddKeyBinding (SDLK_PAGEUP, (int *)&ImmediateMenuState.zoom_in); + VControl_AddKeyBinding (SDLK_PAGEDOWN, (int *)&ImmediateMenuState.zoom_out); + VControl_AddKeyBinding (SDLK_KP_PLUS, (int *)&ImmediateMenuState.zoom_in); + VControl_AddKeyBinding (SDLK_KP_MINUS, (int *)&ImmediateMenuState.zoom_out); + + VControl_AddKeyBinding (SDLK_KP8, (int *)&ImmediateInputState.p1_thrust); + VControl_AddKeyBinding (SDLK_UP, (int *)&ImmediateInputState.p1_thrust); + VControl_AddKeyBinding (SDLK_RETURN, (int *)&ImmediateInputState.p1_thrust); + VControl_AddKeyBinding (SDLK_KP_ENTER, (int *)&ImmediateInputState.p1_thrust); + VControl_AddKeyBinding (SDLK_KP4, (int *)&ImmediateInputState.p1_left); + VControl_AddKeyBinding (SDLK_LEFT, (int *)&ImmediateInputState.p1_left); + VControl_AddKeyBinding (SDLK_KP6, (int *)&ImmediateInputState.p1_right); + VControl_AddKeyBinding (SDLK_RIGHT, (int *)&ImmediateInputState.p1_right); + VControl_AddKeyBinding (SDLK_SPACE, (int *)&ImmediateInputState.p1_weapon); + VControl_AddKeyBinding (SDLK_RSHIFT, (int *)&ImmediateInputState.p1_weapon); + VControl_AddKeyBinding (SDLK_RCTRL, (int *)&ImmediateInputState.p1_special); + VControl_AddKeyBinding (SDLK_ESCAPE, (int *)&ImmediateInputState.p1_escape); + + VControl_AddKeyBinding (SDLK_w, (int *)&ImmediateInputState.p2_thrust); + VControl_AddKeyBinding (SDLK_a, (int *)&ImmediateInputState.p2_left); + VControl_AddKeyBinding (SDLK_d, (int *)&ImmediateInputState.p2_right); + VControl_AddKeyBinding (SDLK_t, (int *)&ImmediateInputState.p2_weapon); + VControl_AddKeyBinding (SDLK_y, (int *)&ImmediateInputState.p2_special); + + VControl_AddKeyBinding (SDLK_KP8, (int *)&ImmediateInputState.lander_thrust); + VControl_AddKeyBinding (SDLK_UP, (int *)&ImmediateInputState.lander_thrust); + VControl_AddKeyBinding (SDLK_RETURN, (int *)&ImmediateInputState.lander_thrust); + VControl_AddKeyBinding (SDLK_KP_ENTER, (int *)&ImmediateInputState.lander_thrust); + VControl_AddKeyBinding (SDLK_KP4, (int *)&ImmediateInputState.lander_left); + VControl_AddKeyBinding (SDLK_LEFT, (int *)&ImmediateInputState.lander_left); + VControl_AddKeyBinding (SDLK_KP6, (int *)&ImmediateInputState.lander_right); + VControl_AddKeyBinding (SDLK_RIGHT, (int *)&ImmediateInputState.lander_right); + VControl_AddKeyBinding (SDLK_SPACE, (int *)&ImmediateInputState.lander_weapon); + VControl_AddKeyBinding (SDLK_RSHIFT, (int *)&ImmediateInputState.lander_weapon); + VControl_AddKeyBinding (SDLK_ESCAPE, (int *)&ImmediateInputState.lander_escape); + + VControl_AddKeyBinding (SDLK_F1, (int *)&ImmediateInputState.pause); + VControl_AddKeyBinding (SDLK_F10, (int *)&ImmediateInputState.exit); + VControl_AddKeyBinding (SDLK_F12, (int *)&ImmediateInputState.abort); +} + +void +EnableCharacterMode (void) +{ + kbdhead = kbdtail = 0; + _in_character_mode = TRUE; + VControl_ResetInput (); + +} + +void +DisableCharacterMode (void) +{ + VControl_ResetInput (); + _in_character_mode = FALSE; + kbdhead = kbdtail = 0; +} + +UNICODE +GetCharacter (void) +{ + UNICODE result; + while (kbdhead == kbdtail) + TaskSwitch (); + result = kbdbuf[kbdhead]; + kbdhead = (kbdhead + 1) & (KBDBUFSIZE - 1); + return result; +} + +void +ProcessInputEvent(const SDL_Event *Event) { - SDLKey k = Event->key.keysym.sym; - UNICODE map_key; if (!InputInitialized) return; - if (!Event->key.keysym.unicode && - (k == SDLK_CAPSLOCK || - k == SDLK_NUMLOCK)) - return; - - if (Event->type == SDL_KEYDOWN) + if (!_in_character_mode) { + VControl_HandleEvent (Event); + } + else + { + SDLKey k = Event->key.keysym.sym; + UNICODE map_key; + if (Event->type != SDL_KEYDOWN) + return; + if (!Event->key.keysym.unicode && + (k == SDLK_CAPSLOCK || + k == SDLK_NUMLOCK)) + return; if (Event->key.keysym.unicode != 0) map_key = (UNICODE) Event->key.keysym.unicode; else map_key = KBDToUNICODE(k); + kbdbuf[kbdtail] = map_key; kbdtail = (kbdtail + 1) & (KBDBUFSIZE - 1); if (kbdtail == kbdhead) kbdhead = (kbdhead + 1) & (KBDBUFSIZE - 1); - if (map_key == AbortKey) - exit(0); - //Store the actual key (without nay shift/ctrl modifiers) - //since the modifiers can't be retreived on a key-up - KeyboardDown[UNICODEToKBD (KBDToUNICODE (k))] |= 0x3; - } - else - { - KeyboardDown[UNICODEToKBD (KBDToUNICODE (k))] &= (~0x1); } } void -ProcessJoystickEvent (const SDL_Event* Event) +TFB_ResetControls (void) { - if (!InputInitialized) - return; - - switch (Event->type) - { - case SDL_JOYAXISMOTION: - JoyaxisValues[Event->jaxis.which][Event->jaxis.axis] = Event->jaxis.value; - break; - case SDL_JOYBUTTONDOWN: - JoybuttonDown[Event->jbutton.which][Event->jbutton.button] |= 0x3; - break; - case SDL_JOYBUTTONUP: - JoybuttonDown[Event->jbutton.which][Event->jbutton.button] &= (~0x1); - break; - } -} - -extern BOOLEAN -InitInput (BOOLEAN (*PFunc) (void), UNICODE Pause, UNICODE Exit, UNICODE Abort) -{ - PauseFunc = PFunc; - PauseKey = Pause; - ExitKey = Exit; - AbortKey = Abort; - InputInitialized = TRUE; - return (TRUE); -} - -//Status: Ignored -BOOLEAN -UninitInput (void) // Looks like it'll be empty -{ - BOOLEAN ret; - - // fprintf (stderr, "Unimplemented function activated: UninitInput()\n"); - ret = TRUE; - return (ret); + VControl_ResetInput (); } void FlushInput (void) { - int i; - kbdtail = kbdhead = 0; - for (i = 0; i < SDLK_LAST; ++i) - { - if (KeyboardDown[i] == 0x2) - KeyboardDown[i] &= ~0x2; - } + TFB_ResetControls (); + GameExiting = ExitRequested = FALSE; } // Translates from SDLKeys to values defined in inplib.h @@ -331,236 +458,4 @@ UNICODEToKBD (UNICODE which_key) } } -UNICODE -GetUNICODEKey (void) -{ - if (kbdtail != kbdhead) - { - UNICODE ch; - - ch = kbdbuf[kbdhead]; - kbdhead = (kbdhead + 1) & (KBDBUFSIZE - 1); - return (ch); - } - return (0); -} - -BOOLEAN -KeyDown (UNICODE which_scan) -{ - UWORD i; - - i = UNICODEToKBD(which_scan); - if (KeyboardDown[i] != 0) - { - KeyboardDown[i] &= (~0x2); - return TRUE; - } - else - return FALSE; -} - -INPUT_STATE -AnyButtonPress (BOOLEAN DetectSpecial) -{ - int i,j; - - if (DetectSpecial) - { - if (KeyDown (PauseKey) && PauseFunc) - PauseFunc(); - } - - for (i = 0; i < SDLK_LAST; ++i) - { - if (KeyboardDown[i]) - { - KeyboardDown[i] &= ~0x2; - return (DEVICE_BUTTON1); - } - } - for (j = 0; j < nJoysticks; ++j) - { - for (i = 0; i < SDL_JoystickNumButtons(Joysticks[j]); ++i) - { - if (JoybuttonDown[j][i]) - { - JoybuttonDown[j][i] &= ~0x2; - return (DEVICE_BUTTON1); - } - } - } - return (0); -} - -BOOLEAN -_joystick_port_active(COUNT port) //SDL handles this nicely. -{ - return SDL_JoystickOpened(port); -} - -INPUT_STATE -_get_pause_exit_state (void) -{ - INPUT_STATE InputState; - - InputState = 0; - if (KeyDown (PauseKey) && PauseFunc) - { - PauseFunc(); - } - else if (KeyDown (ExitKey)) - { - InputState = DEVICE_EXIT; - } - return (InputState); -} - -INPUT_STATE -_get_serial_keyboard_state (INPUT_REF ref, INPUT_STATE InputState) -{ - Uint16 key; - (void) ref; - - if ((key = GetUNICODEKey ()) == '\r') - key = '\n'; - if (key != 0) - { - SetInputUNICODE (&InputState, key); - SetInputDevType (&InputState, KEYBOARD_DEVICE); - } - else - InputState = 0; - - return (InputState); -} - -static BOOLEAN -GetKeyboardDown (UWORD value) -{ - if (KEYISCHORD(value)) - { - int k1, k2; - k1 = KeyDown(KEYGETKEY(value)); - k2 = KeyDown(KEYGETCHORD(value)); - if (k1 && k2) - return TRUE; - } - else - { - if (KeyDown(KEYGETKEY(value))) - return TRUE; - } - return FALSE; -} - -INPUT_STATE -_get_joystick_keyboard_state (INPUT_REF InputRef, INPUT_STATE InputState) -{ - SBYTE dx, dy; - UWORD* KeyEquivalentPtr; - - KeyEquivalentPtr = GetInputDeviceKeyEquivalentPtr (InputRef); - dx = (SBYTE)(GetKeyboardDown (KeyEquivalentPtr[1]) - - GetKeyboardDown (KeyEquivalentPtr[0])); - SetInputXComponent (&InputState, dx); - - KeyEquivalentPtr += 2; - dy = (SBYTE)(GetKeyboardDown (KeyEquivalentPtr[1]) - - GetKeyboardDown (KeyEquivalentPtr[0])); - SetInputYComponent (&InputState, dy); - - KeyEquivalentPtr += 2; - if (GetKeyboardDown (*KeyEquivalentPtr++)) - InputState |= DEVICE_BUTTON1; - if (GetKeyboardDown (*KeyEquivalentPtr++)) - InputState |= DEVICE_BUTTON2; - if (GetKeyboardDown (*KeyEquivalentPtr++)) - InputState |= DEVICE_BUTTON3; - if (GetKeyboardDown (*KeyEquivalentPtr++)) - InputState |= DEVICE_BUTTON4; - - if (GetKeyboardDown (*KeyEquivalentPtr++)) - InputState |= DEVICE_LEFTSHIFT; - if (GetKeyboardDown (*KeyEquivalentPtr++)) - InputState |= DEVICE_RIGHTSHIFT; - - if (InputState) - SetInputDevType (&InputState, JOYSTICK_DEVICE); - - return (InputState); -} - -static BOOLEAN -GetJoystickDown (int port, UWORD map, UWORD threshold) -{ - int axis, sign; - if (JOYISAXIS(map)) - { - axis = JOYGETVALUE(map); - sign = JOYGETSIGN(map); - if ((sign * JoyaxisValues[port][axis]) > threshold) - return TRUE; - } - else - { - if (JOYISCHORD(map)) - { - UBYTE b1 = JoybuttonDown[port][JOYGETVALUE(map)]; - UBYTE b2 = JoybuttonDown[port][JOYGETCHORD(map)]; - JoybuttonDown[port][JOYGETVALUE(map)] &= (~0x2); - JoybuttonDown[port][JOYGETCHORD(map)] &= (~0x2); - if (b1 && b2) - return TRUE; - } - else if (JoybuttonDown[port][JOYGETVALUE(map)]) - { - JoybuttonDown[port][JOYGETVALUE(map)] &= (~0x2); - return TRUE; - } - } - return FALSE; -} - -INPUT_STATE -_get_joystick_state (INPUT_REF ref, INPUT_STATE InputState) -{ - SBYTE dx, dy; - UWORD *JoystickButtons = GetInputDeviceJoystickButtonPtr(ref); - UWORD threshold = GetInputDeviceJoystickThreshold(ref); - int port = GetInputDeviceJoystickPort(ref); - - if (GetJoystickDown(port, JoystickButtons[0], threshold)) - dx = -1; - else if (GetJoystickDown(port, JoystickButtons[1], threshold)) - dx = 1; - else - dx = 0; - - if (GetJoystickDown(port, JoystickButtons[2], threshold)) - dy = -1; - else if (GetJoystickDown(port, JoystickButtons[3], threshold)) - dy = 1; - else - dy = 0; - - SetInputXComponent(&InputState, dx); - SetInputYComponent(&InputState, dy); - - if (GetJoystickDown(port, JoystickButtons[4], threshold)) - InputState |= DEVICE_BUTTON1; - if (GetJoystickDown(port, JoystickButtons[5], threshold)) - InputState |= DEVICE_BUTTON2; - if (GetJoystickDown(port, JoystickButtons[6], threshold)) - InputState |= DEVICE_BUTTON3; - if (GetJoystickDown(port, JoystickButtons[7], threshold)) - InputState |= DEVICE_LEFTSHIFT; - if (GetJoystickDown(port, JoystickButtons[8], threshold)) - InputState |= DEVICE_RIGHTSHIFT; - - if (InputState) - SetInputDevType(&InputState, JOYSTICK_DEVICE); - return InputState; -} - #endif diff --git a/sc2/src/sc2code/libs/input/sdl/input.h b/sc2/src/sc2code/libs/input/sdl/input.h index bc78cc65a..4688d92f1 100644 --- a/sc2/src/sc2code/libs/input/sdl/input.h +++ b/sc2/src/sc2code/libs/input/sdl/input.h @@ -19,9 +19,7 @@ #ifndef INPUT_H #define INPUT_H -UNICODE GetUNICODEKey (void); void FlushInput (void); -void ProcessKeyboardEvent (const SDL_Event *Event); -void ProcessJoystickEvent (const SDL_Event *Event); +void ProcessInputEvent (const SDL_Event *Event); #endif diff --git a/sc2/src/sc2code/libs/input/sdl/keynames.c b/sc2/src/sc2code/libs/input/sdl/keynames.c new file mode 100644 index 000000000..d99d4bcd6 --- /dev/null +++ b/sc2/src/sc2code/libs/input/sdl/keynames.c @@ -0,0 +1,189 @@ +#include +#include +#include "keynames.h" +#include "port.h" + +/* This code is adapted from the code in SDL_keysym.h. Though this + * would almost certainly be fast if we were to use a direct char * + * array, this technique permits us to be independent of the actual + * character encoding to keysyms. */ + +/* These names are case-insensitive when compared, but we format + * them to look pretty when output */ + +/* This version of Virtual Controller does not support SDLK_WORLD_* + * keysyms or the Num/Caps/ScrollLock keys. SDL treats locking keys + * specially, and we cannot treat them as normal keys. Pain, + * tragedy. */ + +typedef struct _keyname { + /* const */ char *name; + int code; +} keyname; + +static keyname keynames[] = { + {"Backspace", SDLK_BACKSPACE}, + {"Tab", SDLK_TAB}, + {"Clear", SDLK_CLEAR}, + {"Return", SDLK_RETURN}, + {"Pause", SDLK_PAUSE}, + {"Escape", SDLK_ESCAPE}, + {"Space", SDLK_SPACE}, + {"!", SDLK_EXCLAIM}, + {"\"", SDLK_QUOTEDBL}, + {"Hash", SDLK_HASH}, + {"$", SDLK_DOLLAR}, + {"&", SDLK_AMPERSAND}, + {"'", SDLK_QUOTE}, + {"(", SDLK_LEFTPAREN}, + {")", SDLK_RIGHTPAREN}, + {"*", SDLK_ASTERISK}, + {"+", SDLK_PLUS}, + {",", SDLK_COMMA}, + {"-", SDLK_MINUS}, + {".", SDLK_PERIOD}, + {"/", SDLK_SLASH}, + {"0", SDLK_0}, + {"1", SDLK_1}, + {"2", SDLK_2}, + {"3", SDLK_3}, + {"4", SDLK_4}, + {"5", SDLK_5}, + {"6", SDLK_6}, + {"7", SDLK_7}, + {"8", SDLK_8}, + {"9", SDLK_9}, + {":", SDLK_COLON}, + {";", SDLK_SEMICOLON}, + {"<", SDLK_LESS}, + {"=", SDLK_EQUALS}, + {">", SDLK_GREATER}, + {"?", SDLK_QUESTION}, + {"@", SDLK_AT}, + {"[", SDLK_LEFTBRACKET}, + {"\\", SDLK_BACKSLASH}, + {"]", SDLK_RIGHTBRACKET}, + {"^", SDLK_CARET}, + {"_", SDLK_UNDERSCORE}, + {"`", SDLK_BACKQUOTE}, + {"a", SDLK_a}, + {"b", SDLK_b}, + {"c", SDLK_c}, + {"d", SDLK_d}, + {"e", SDLK_e}, + {"f", SDLK_f}, + {"g", SDLK_g}, + {"h", SDLK_h}, + {"i", SDLK_i}, + {"j", SDLK_j}, + {"k", SDLK_k}, + {"l", SDLK_l}, + {"m", SDLK_m}, + {"n", SDLK_n}, + {"o", SDLK_o}, + {"p", SDLK_p}, + {"q", SDLK_q}, + {"r", SDLK_r}, + {"s", SDLK_s}, + {"t", SDLK_t}, + {"u", SDLK_u}, + {"v", SDLK_v}, + {"w", SDLK_w}, + {"x", SDLK_x}, + {"y", SDLK_y}, + {"z", SDLK_z}, + {"Delete", SDLK_DELETE}, + {"Keypad-0", SDLK_KP0}, + {"Keypad-1", SDLK_KP1}, + {"Keypad-2", SDLK_KP2}, + {"Keypad-3", SDLK_KP3}, + {"Keypad-4", SDLK_KP4}, + {"Keypad-5", SDLK_KP5}, + {"Keypad-6", SDLK_KP6}, + {"Keypad-7", SDLK_KP7}, + {"Keypad-8", SDLK_KP8}, + {"Keypad-9", SDLK_KP9}, + {"Keypad-.", SDLK_KP_PERIOD}, + {"Keypad-/", SDLK_KP_DIVIDE}, + {"Keypad-*", SDLK_KP_MULTIPLY}, + {"Keypad--", SDLK_KP_MINUS}, + {"Keypad-+", SDLK_KP_PLUS}, + {"Keypad-Enter", SDLK_KP_ENTER}, + {"Keypad-=", SDLK_KP_EQUALS}, + {"Up", SDLK_UP}, + {"Down", SDLK_DOWN}, + {"Right", SDLK_RIGHT}, + {"Left", SDLK_LEFT}, + {"Insert", SDLK_INSERT}, + {"Home", SDLK_HOME}, + {"End", SDLK_END}, + {"PageUp", SDLK_PAGEUP}, + {"PageDown", SDLK_PAGEDOWN}, + {"F1", SDLK_F1}, + {"F2", SDLK_F2}, + {"F3", SDLK_F3}, + {"F4", SDLK_F4}, + {"F5", SDLK_F5}, + {"F6", SDLK_F6}, + {"F7", SDLK_F7}, + {"F8", SDLK_F8}, + {"F9", SDLK_F9}, + {"F10", SDLK_F10}, + {"F11", SDLK_F11}, + {"F12", SDLK_F12}, + {"F13", SDLK_F13}, + {"F14", SDLK_F14}, + {"F15", SDLK_F15}, + {"RightShift", SDLK_RSHIFT}, + {"LeftShift", SDLK_LSHIFT}, + {"RightControl", SDLK_RCTRL}, + {"LeftControl", SDLK_LCTRL}, + {"RightAlt", SDLK_RALT}, + {"LeftAlt", SDLK_LALT}, + {"RightMeta", SDLK_RMETA}, + {"LeftMeta", SDLK_LMETA}, + {"RightSuper", SDLK_RSUPER}, + {"LeftSuper", SDLK_LSUPER}, + {"AltGr", SDLK_MODE}, + {"Compose", SDLK_COMPOSE}, + {"Help", SDLK_HELP}, + {"Print", SDLK_PRINT}, + {"SysReq", SDLK_SYSREQ}, + {"Break", SDLK_BREAK}, + {"Menu", SDLK_MENU}, + {"Power", SDLK_POWER}, + {"Euro", SDLK_EURO}, + {"Undo", SDLK_UNDO}, + {"Unknown", 0}}; +/* Last element must have code zero */ + +char * +VControl_code2name (int code) +{ + int i = 0; + while (1) + { + int test = keynames[i].code; + if (test == code || !test) + { + return keynames[i].name; + } + ++i; + } +} + +int +VControl_name2code (char *name) +{ + int i = 0; + while (1) + { + char *test = keynames[i].name; + int code = keynames[i].code; + if (!stricmp(test, name) || !code) + { + return code; + } + ++i; + } +} diff --git a/sc2/src/sc2code/libs/input/sdl/keynames.h b/sc2/src/sc2code/libs/input/sdl/keynames.h new file mode 100644 index 000000000..d4774d4c5 --- /dev/null +++ b/sc2/src/sc2code/libs/input/sdl/keynames.h @@ -0,0 +1,6 @@ +#ifndef _KEYNAMES_H_ +#define _KEYNAMES_H_ + +char *VControl_code2name (int code); +int VControl_name2code (char *code); +#endif diff --git a/sc2/src/sc2code/libs/input/sdl/vcontrol.c b/sc2/src/sc2code/libs/input/sdl/vcontrol.c new file mode 100644 index 000000000..e3762ced6 --- /dev/null +++ b/sc2/src/sc2code/libs/input/sdl/vcontrol.c @@ -0,0 +1,1237 @@ +#include +#include +#include +#include +#include "vcontrol.h" +#include "vcontrol_malloc.h" +#include "keynames.h" +#include "port.h" + +/* How many binding slots are allocated at once. */ +#define POOL_CHUNK_SIZE 64 + +typedef struct _vcontrol_keybinding { + int *target; + struct _vcontrol_keypool *parent; + struct _vcontrol_keybinding *next; +} keybinding; + +typedef struct _vcontrol_keypool { + keybinding pool[POOL_CHUNK_SIZE]; + int remaining; + struct _vcontrol_keypool *next; +} keypool; + +typedef struct _vcontrol_joystick_axis { + keybinding *neg, *pos; + int polarity; +} axis; + +typedef struct _vcontrol_joystick_hat { + keybinding *left, *right, *up, *down; + Uint8 last; +} hat; + +typedef struct _vcontrol_joystick { + SDL_Joystick *stick; + int numaxes, numbuttons, numhats; + int threshold; + axis *axes; + keybinding **buttons; + hat *hats; +} joystick; + +static keybinding *bindings[SDLK_LAST]; +static joystick *joysticks; +static int joycount; + +static keypool *pool; +static VControl_NameBinding *nametable; + +static keypool * +_allocate_key_chunk (void) +{ + keypool *x = vctrl_malloc (sizeof (keypool)); + if (x) + { + int i; + x->remaining = POOL_CHUNK_SIZE; + x->next = NULL; + for (i = 0; i < POOL_CHUNK_SIZE; i++) + { + x->pool[i].target = NULL; + x->pool[i].next = NULL; + x->pool[i].parent = x; + } + } + return x; +} + +static void +_free_key_pool (keypool *x) +{ + if (x) + { + _free_key_pool (x->next); + vctrl_free (x); + } +} + +static void +_create_joystick (int index) +{ + SDL_Joystick *stick; + int axes, buttons, hats; + if (index >= joycount) + { + fprintf (stderr, "VControl warning: Tried to open a non-existent joystick!"); + return; + } + if (joysticks[index].stick) + { + // Joystick is already created. Return. + return; + } + stick = SDL_JoystickOpen (index); + if (stick) + { + joystick *x = &joysticks[index]; + int j; + fprintf (stderr, "VControl opened joystick: %s\n", SDL_JoystickName (index)); + axes = SDL_JoystickNumAxes (stick); + buttons = SDL_JoystickNumButtons (stick); + hats = SDL_JoystickNumHats (stick); + fprintf (stderr, "%d axes, %d buttons, %d hats.\n", axes, buttons, hats); + x->numaxes = axes; + x->numbuttons = buttons; + x->numhats = hats; + x->axes = vctrl_malloc (sizeof (axis) * axes); + x->buttons = vctrl_malloc (sizeof (keybinding *) * buttons); + x->hats = vctrl_malloc (sizeof (hat) * hats); + for (j = 0; j < axes; j++) + { + x->axes[j].neg = x->axes[j].pos = NULL; + } + for (j = 0; j < hats; j++) + { + x->hats[j].left = x->hats[j].right = NULL; + x->hats[j].up = x->hats[j].down = NULL; + x->hats[j].last = SDL_HAT_CENTERED; + } + for (j = 0; j < buttons; j++) + { + x->buttons[j] = NULL; + } + x->stick = stick; + } + else + { + fprintf (stderr, "VControl: Could not initialize joystick #%d\n", index); + } +} + +static void +_destroy_joystick (int index) +{ + SDL_Joystick *stick = joysticks[index].stick; + if (stick) + { + SDL_JoystickClose (stick); + joysticks[index].stick = NULL; + vctrl_free (joysticks[index].axes); + vctrl_free (joysticks[index].buttons); + vctrl_free (joysticks[index].hats); + joysticks[index].numaxes = joysticks[index].numbuttons = 0; + joysticks[index].axes = NULL; + joysticks[index].buttons = NULL; + joysticks[index].hats = NULL; + } +} + +static void +_key_init (void) +{ + int i; + pool = _allocate_key_chunk (); + for (i = 0; i < SDLK_LAST; i++) + bindings[i] = NULL; + /* Prepare for possible joystick controls. We don't actually + GRAB joysticks unless we're asked to make a joystick + binding, though. */ + joycount = SDL_NumJoysticks (); + if (joycount) + { + joysticks = vctrl_malloc (sizeof (joystick) * joycount); + for (i = 0; i < joycount; i++) + { + joysticks[i].stick = NULL; + joysticks[i].numaxes = joysticks[i].numbuttons = 0; + joysticks[i].axes = NULL; + joysticks[i].buttons = NULL; + } + } + else + { + joysticks = NULL; + } +} + +static void +_key_uninit (void) +{ + int i; + _free_key_pool (pool); + for (i = 0; i < SDLK_LAST; i++) + bindings[i] = NULL; + pool = NULL; + for (i = 0; i < joycount; i++) + _destroy_joystick (i); + vctrl_free (joysticks); +} + +static void +_name_init (void) +{ + nametable = NULL; +} + +static void +_name_uninit (void) +{ + nametable = NULL; +} + +void +VControl_Init (void) +{ + _key_init (); + _name_init (); +} + +void +VControl_Uninit (void) +{ + _key_uninit (); + _name_uninit (); +} + +void +VControl_SetJoyThreshold (int port, int threshold) +{ + if (port >= 0 && port < joycount) + { + joysticks[port].threshold = threshold; + } + else + { + fprintf (stderr, "VControl_SetJoyThreshold passed illegal port %d\n", port); + } +} + + +static void +_add_binding (keybinding **newptr, int *target) +{ + keybinding *newbinding; + keypool *searchbase; + int i; + + /* Acquire a pointer to the keybinding * that we'll be + * overwriting. Along the way, ensure we haven't already + * bound this symbol to this target. If we have, return.*/ + while (*newptr != NULL) + { + if ((*newptr)->target == target) + { + return; + } + newptr = &((*newptr)->next); + } + + /* Now hunt through the binding pool for a free binding. */ + + /* First, find a chunk with free spots in it */ + + searchbase = pool; + while (searchbase->remaining == 0) + { + /* If we're completely full, allocate a new chunk */ + if (searchbase->next == NULL) + { + searchbase->next = _allocate_key_chunk (); + } + searchbase = searchbase->next; + } + + /* Now find a free binding within it */ + + newbinding = NULL; + for (i = 0; i < POOL_CHUNK_SIZE; i++) + { + if (searchbase->pool[i].target == NULL) + { + newbinding = &searchbase->pool[i]; + break; + } + } + + /* Sanity check. */ + if (!newbinding) + { + fprintf (stderr, "VControl_AddKeyBinding failed to find a free binding slot!\n"); + return; + } + + newbinding->target = target; + newbinding->next = NULL; + *newptr = newbinding; + searchbase->remaining--; +} + +static void +_remove_binding (keybinding **ptr, int *target) +{ + if (!(*ptr)) + { + /* Nothing bound to symbol; return. */ + return; + } + else if ((*ptr)->target == target) + { + keybinding *todel = *ptr; + *ptr = todel->next; + todel->target = NULL; + todel->next = NULL; + todel->parent->remaining++; + } + else + { + keybinding *prev = *ptr; + while (prev->next != NULL) + { + if (prev->next->target == target) + { + keybinding *todel = prev->next; + prev->next = todel->next; + todel->target = NULL; + todel->next = NULL; + todel->parent->remaining++; + } + } + } +} + +static void +_activate (keybinding *i) +{ + while (i != NULL) + { + *(i->target) = *(i->target)+1; + i = i->next; + } +} + +static void +_deactivate (keybinding *i) +{ + while (i != NULL) + { + if (*(i->target) > 0) + { + *(i->target) = *(i->target)-1; + } + i = i->next; + } +} + +void +VControl_AddKeyBinding (int symbol, int *target) +{ + _add_binding(&bindings[symbol], target); +} + +void +VControl_RemoveKeyBinding (int symbol, int *target) +{ + _remove_binding (&bindings[symbol], target); +} + +void +VControl_AddJoyAxisBinding (int port, int axis, int polarity, int *target) +{ + if (port >= 0 && port < joycount) + { + joystick *j = &joysticks[port]; + if (!(j->stick)) + _create_joystick (port); + if ((axis >= 0) && (axis < j->numaxes)) + { + if (polarity < 0) + { + _add_binding(&joysticks[port].axes[axis].neg, target); + } + else if (polarity > 0) + { + _add_binding(&joysticks[port].axes[axis].pos, target); + } + else + { + fprintf (stderr, "VControl: Attempted to bind to polarity zero\n"); + } + } + else + { + fprintf (stderr, "VControl: Attempted to bind to illegal axis %d\n", axis); + } + } + else + { + fprintf (stderr, "VControl: Attempted to bind to illegal port %d\n", port); + } +} + +void +VControl_RemoveJoyAxisBinding (int port, int axis, int polarity, int *target) +{ + if (port >= 0 && port < joycount) + { + joystick *j = &joysticks[port]; + if (!(j->stick)) + _create_joystick (port); + if ((axis >= 0) && (axis < j->numaxes)) + { + if (polarity < 0) + { + _remove_binding(&joysticks[port].axes[axis].neg, target); + } + else if (polarity > 0) + { + _remove_binding(&joysticks[port].axes[axis].pos, target); + } + else + { + fprintf (stderr, "VControl: Attempted to unbind from polarity zero\n"); + } + } + else + { + fprintf (stderr, "VControl: Attempted to unbind from illegal axis %d\n", axis); + } + } + else + { + fprintf (stderr, "VControl: Attempted to unbind from illegal port %d\n", port); + } +} + +void +VControl_AddJoyButtonBinding (int port, int button, int *target) +{ + if (port >= 0 && port < joycount) + { + joystick *j = &joysticks[port]; + if (!(j->stick)) + _create_joystick (port); + if ((button >= 0) && (button < j->numbuttons)) + { + _add_binding(&joysticks[port].buttons[button], target); + } + else + { + fprintf (stderr, "VControl: Attempted to bind to illegal button %d\n", button); + } + } + else + { + fprintf (stderr, "VControl: Attempted to bind to illegal port %d\n", port); + } +} + +void +VControl_RemoveJoyButtonBinding (int port, int button, int *target) +{ + if (port >= 0 && port < joycount) + { + joystick *j = &joysticks[port]; + if (!(j->stick)) + _create_joystick (port); + if ((button >= 0) && (button < j->numbuttons)) + { + _remove_binding (&joysticks[port].buttons[button], target); + } + else + { + fprintf (stderr, "VControl: Attempted to unbind from illegal button %d\n", button); + } + } + else + { + fprintf (stderr, "VControl: Attempted to unbind from illegal port %d\n", port); + } +} + +void +VControl_AddJoyHatBinding (int port, int which, Uint8 dir, int *target) +{ + if (port >= 0 && port < joycount) + { + joystick *j = &joysticks[port]; + if (!(j->stick)) + _create_joystick (port); + if ((which >= 0) && (which < j->numhats)) + { + if (dir == SDL_HAT_LEFT) + { + _add_binding(&joysticks[port].hats[which].left, target); + } + else if (dir == SDL_HAT_RIGHT) + { + _add_binding(&joysticks[port].hats[which].right, target); + } + else if (dir == SDL_HAT_UP) + { + _add_binding(&joysticks[port].hats[which].up, target); + } + else if (dir == SDL_HAT_DOWN) + { + _add_binding(&joysticks[port].hats[which].down, target); + } + else + { + fprintf (stderr, "VControl: Attempted to bind to illegal direction\n"); + } + } + else + { + fprintf (stderr, "VControl: Attempted to bind to illegal hat %d\n", which); + } + } + else + { + fprintf (stderr, "VControl: Attempted to bind to illegal port %d\n", port); + } +} + +void +VControl_RemoveJoyHatBinding (int port, int which, Uint8 dir, int *target) +{ + if (port >= 0 && port < joycount) + { + joystick *j = &joysticks[port]; + if (!(j->stick)) + _create_joystick (port); + if ((which >= 0) && (which < j->numhats)) + { + if (dir == SDL_HAT_LEFT) + { + _remove_binding(&joysticks[port].hats[which].left, target); + } + else if (dir == SDL_HAT_RIGHT) + { + _remove_binding(&joysticks[port].hats[which].right, target); + } + else if (dir == SDL_HAT_UP) + { + _remove_binding(&joysticks[port].hats[which].up, target); + } + else if (dir == SDL_HAT_DOWN) + { + _remove_binding(&joysticks[port].hats[which].down, target); + } + else + { + fprintf (stderr, "VControl: Attempted to unbind from illegal direction\n"); + } + } + else + { + fprintf (stderr, "VControl: Attempted to unbind from illegal hat %d\n", which); + } + } + else + { + fprintf (stderr, "VControl: Attempted to unbind from illegal port %d\n", port); + } +} + +void +VControl_RemoveAllBindings () +{ + _key_uninit (); + _key_init (); +} + +void +VControl_ProcessKeyDown (int symbol) +{ + _activate (bindings[symbol]); +} + +void +VControl_ProcessKeyUp (int symbol) +{ + _deactivate (bindings[symbol]); +} + +void +VControl_ProcessJoyButtonDown (int port, int button) +{ + if (!joysticks[port].stick) + return; + _activate (joysticks[port].buttons[button]); +} + +void +VControl_ProcessJoyButtonUp (int port, int button) +{ + if (!joysticks[port].stick) + return; + _deactivate (joysticks[port].buttons[button]); +} + +void +VControl_ProcessJoyAxis (int port, int axis, int value) +{ + int t; + if (!joysticks[port].stick) + return; + t = joysticks[port].threshold; + if (value > t) + { + if (joysticks[port].axes[axis].polarity != 1) + { + if (joysticks[port].axes[axis].polarity == -1) + { + _deactivate (joysticks[port].axes[axis].neg); + } + joysticks[port].axes[axis].polarity = 1; + _activate (joysticks[port].axes[axis].pos); + } + } + else if (value < -t) + { + if (joysticks[port].axes[axis].polarity != -1) + { + if (joysticks[port].axes[axis].polarity == 1) + { + _deactivate (joysticks[port].axes[axis].pos); + } + joysticks[port].axes[axis].polarity = -1; + _activate (joysticks[port].axes[axis].neg); + } + } + else + { + if (joysticks[port].axes[axis].polarity == -1) + { + _deactivate (joysticks[port].axes[axis].neg); + } + else if (joysticks[port].axes[axis].polarity == 1) + { + _deactivate (joysticks[port].axes[axis].pos); + } + joysticks[port].axes[axis].polarity = 0; + } +} + +void +VControl_ProcessJoyHat (int port, int which, Uint8 value) +{ + Uint8 old; + if (!joysticks[port].stick) + return; + old = joysticks[port].hats[which].last; + if (!(old & SDL_HAT_LEFT) && (value & SDL_HAT_LEFT)) + _activate (joysticks[port].hats[which].left); + if (!(old & SDL_HAT_RIGHT) && (value & SDL_HAT_RIGHT)) + _activate (joysticks[port].hats[which].right); + if (!(old & SDL_HAT_UP) && (value & SDL_HAT_UP)) + _activate (joysticks[port].hats[which].up); + if (!(old & SDL_HAT_DOWN) && (value & SDL_HAT_DOWN)) + _activate (joysticks[port].hats[which].down); + if ((old & SDL_HAT_LEFT) && !(value & SDL_HAT_LEFT)) + _deactivate (joysticks[port].hats[which].left); + if ((old & SDL_HAT_RIGHT) && !(value & SDL_HAT_RIGHT)) + _deactivate (joysticks[port].hats[which].right); + if ((old & SDL_HAT_UP) && !(value & SDL_HAT_UP)) + _deactivate (joysticks[port].hats[which].up); + if ((old & SDL_HAT_DOWN) && !(value & SDL_HAT_DOWN)) + _deactivate (joysticks[port].hats[which].down); + joysticks[port].hats[which].last = value; +} + +void +VControl_ResetInput () +{ + /* Step through every valid entry in the binding pool and zero + * them out. This will probably zero entries multiple times; + * oh well, no harm done. */ + + keypool *base = pool; + while (base != NULL) + { + int i; + for (i = 0; i < POOL_CHUNK_SIZE; i++) + { + if(base->pool[i].target) + { + *(base->pool[i].target) = 0; + } + } + base = base->next; + } +} + +void +VControl_HandleEvent (const SDL_Event *e) +{ + switch (e->type) + { + case SDL_KEYDOWN: + VControl_ProcessKeyDown (e->key.keysym.sym); + break; + case SDL_KEYUP: + VControl_ProcessKeyUp (e->key.keysym.sym); + break; + case SDL_JOYAXISMOTION: + VControl_ProcessJoyAxis (e->jaxis.which, e->jaxis.axis, e->jaxis.value); + break; + case SDL_JOYHATMOTION: + VControl_ProcessJoyHat (e->jhat.which, e->jhat.hat, e->jhat.value); + break; + case SDL_JOYBUTTONDOWN: + VControl_ProcessJoyButtonDown (e->jbutton.which, e->jbutton.button); + break; + case SDL_JOYBUTTONUP: + VControl_ProcessJoyButtonUp (e->jbutton.which, e->jbutton.button); + break; + default: + break; + } +} + +void +VControl_RegisterNameTable (VControl_NameBinding *table) +{ + nametable = table; +} + +static char * +_target2name (int *target) +{ + VControl_NameBinding *b = nametable; + while (b->target) + { + if (target == b->target) + { + return b->name; + } + ++b; + } + return NULL; +} + +static int * +_name2target (char *name) +{ + VControl_NameBinding *b = nametable; + while (b->target) + { + if (!stricmp (name, b->name)) + { + return b->target; + } + ++b; + } + return NULL; +} + +static void +_dump_keybindings (FILE *out, keybinding *kb, char *name) +{ + while (kb != NULL) + { + char *targetname = _target2name (kb->target); + fprintf (out, "%s: %s\n", targetname, name); + kb = kb->next; + } +} + +void +VControl_Dump (FILE *out) +{ + int i; + char namebuffer[64]; + + /* Print out keyboard bindings */ + for (i = 0; i < SDLK_LAST; i++) + { + keybinding *kb = bindings[i]; + if (kb != NULL) + { + sprintf (namebuffer, "key %s", VControl_code2name (i)); + _dump_keybindings (out, kb, namebuffer); + } + } + + /* Print out joystick bindings */ + for (i = 0; i < joycount; i++) + { + if (joysticks[i].stick) + { + int j; + + fprintf (out, "joystick %d threshold %d\n", i, joysticks[i].threshold); + for (j = 0; j < joysticks[i].numaxes; j++) + { + sprintf (namebuffer, "joystick %d axis %d negative", i, j); + _dump_keybindings (out, joysticks[i].axes[j].neg, namebuffer); + sprintf (namebuffer, "joystick %d axis %d positive", i, j); + _dump_keybindings (out, joysticks[i].axes[j].pos, namebuffer); + } + for (j = 0; j < joysticks[i].numbuttons; j++) + { + keybinding *kb = joysticks[i].buttons[j]; + if (kb != NULL) + { + sprintf (namebuffer, "joystick %d button %d", i, j); + _dump_keybindings (out, kb, namebuffer); + } + } + for (j = 0; j < joysticks[i].numhats; j++) + { + sprintf (namebuffer, "joystick %d hat %d left", i, j); + _dump_keybindings (out, joysticks[i].hats[j].left, namebuffer); + sprintf (namebuffer, "joystick %d hat %d right", i, j); + _dump_keybindings (out, joysticks[i].hats[j].right, namebuffer); + sprintf (namebuffer, "joystick %d hat %d up", i, j); + _dump_keybindings (out, joysticks[i].hats[j].up, namebuffer); + sprintf (namebuffer, "joystick %d hat %d down", i, j); + _dump_keybindings (out, joysticks[i].hats[j].down, namebuffer); + } + } + } + +#ifdef VCONTROL_DEBUG + /* Print out allocation data */ + { + keypool bp = pool; + i = 0; + while (bp != NULL) + { + fprintf (out, "# Internal Debug: Chunk #%i: %d slots remaining.\n", i, bp->remaining); + i++; + bp = bp->next; + } + fprintf (out, "# Internal Debug: %d chunks allocated.\n", i); + } +#endif +} + +/* Configuration file grammar is as follows: One command per line, + * hashes introduce comments that persist to end of line. Blank lines + * are ignored. + * + * Terminals are represented here as quoted strings, e.g. "foo" for + * the literal string foo. These are matched case-insensitively. + * Special terminals are: + * + * KEYNAME: This names a key, as defined in keynames.c. + * IDNAME: This is an arbitrary string of alphanumerics, + * case-insensitive, and ending with a colon. This + * names an application-specific control value. + * NUM: This is an unsigned integer. + * EOF: End of file + * + * Nonterminals (the grammar itself) have the following productions: + * + * configline <- IDNAME binding + * | "joystick" NUM "threshold" NUM + * + * binding <- "key" KEYNAME + * | "joystick" NUM joybinding + * + * joybinding <- "axis" NUM polarity + * | "button" NUM + * | "hat" NUM direction + * + * polarity <- "positive" | "negative" + * + * dir <- "up" | "down" | "left" | "right" + * + * This grammar is amenable to simple recursive descent parsing; + * in fact, it's fully LL(1). */ + +/* Actual maximum line and token sizes are two less than this, since + * we need space for the \n\0 at the end */ +#define LINE_SIZE 256 +#define TOKEN_SIZE 64 + +typedef struct _vcontrol_parse_state { + char line[LINE_SIZE]; + char token[TOKEN_SIZE]; + int index; + int error; + int linenum; +} parse_state; + +static void +_next_token (parse_state *state) +{ + int index, base; + + state->token[0] = 0; + /* skip preceding whitespace */ + base = state->index; + while (state->line[base] && isspace (state->line[base])) + { + base++; + } + + index = 0; + while (index < (TOKEN_SIZE-1) && state->line[base+index] && !isspace (state->line[base+index])) + { + state->token[index] = state->line[base+index]; + index++; + } + state->token[index] = 0; + + /* If the token was too long, skip ahead until we get to whitespace */ + while (state->line[base+index] && !isspace (state->line[base+index])) + { + index++; + } + + state->index = base+index; +} + +static void +_next_line (parse_state *state, FILE *in) +{ + int i, ch; + state->linenum++; + for (i = 0; i < LINE_SIZE-1; i++) + { + if (feof (in)) + { + break; + } + ch = fgetc (in); + if (ch == '#' || ch == '\n' || ch == -1) + { + /* If this line is blank or all commented, include some + * whitespace. This lets us detect EOF as a completely + * blank line. */ + if (i==0) + { + state->line[i] = '\n'; + i++; + } + break; + } + state->line[i] = ch; + } + state->line[i] = '\0'; + /* Skip to end of line */ + while (ch != '\n' && !feof (in)) + { + ch = fgetc (in); + } + state->token[0] = 0; + state->index = 0; + state->error = 0; +} + +static void +_expected_error (parse_state *state, char *expected) +{ + fprintf (stderr, "VControl: Expected '%s' on config file line %d\n", expected, state->linenum); + state->error = 1; +} + +static void +_consume (parse_state *state, char *expected) +{ + if (stricmp (expected, state->token)) + { + _expected_error (state, expected); + } + _next_token (state); +} + +static int +_consume_keyname (parse_state *state) +{ + int keysym = VControl_name2code (state->token); + if (!keysym) + { + fprintf (stderr, "VControl: Illegal key name '%s' on config file line %d\n", state->token, state->linenum); + state->error = 1; + } + _next_token (state); + return keysym; +} + +static int * +_consume_idname (parse_state *state) +{ + int *result = NULL; + int index = 0; + while (state->token[index]) + { + index++; + } + + if (index == 0) + { + fprintf (stderr, "VControl: Can't happen: blank token to _consume_idname (line %d)\n", state->linenum); + state->error = 1; + return NULL; + } + + index--; + if (state->token[index] != ':') + { + _expected_error (state, ":"); + return NULL; + } + + state->token[index] = 0; /* remove trailing colon */ + + result = _name2target (state->token); + _next_token (state); + + if (!result) + { + fprintf (stderr, "VControl: Illegal command type '%s' on config file line %d\n", state->token, state->linenum); + state->error = 1; + } + return result; +} + +static int +_consume_num (parse_state *state) +{ + char *end; + int result = strtol (state->token, &end, 10); + if (*end != '\0') + { + fprintf (stderr, "VControl: Expected integer on config line %d\n", state->linenum); + state->error = 1; + } + _next_token (state); + return result; +} + +static int +_consume_polarity (parse_state *state) +{ + int result = 0; + if (!stricmp (state->token, "positive")) + { + result = 1; + } + else if (!stricmp (state->token, "negative")) + { + result = -1; + } + else + { + _expected_error (state, "positive' or 'negative"); + } + _next_token (state); + return result; +} + +static Uint8 +_consume_dir (parse_state *state) +{ + Uint8 result = 0; + if (!stricmp (state->token, "left")) + { + result = SDL_HAT_LEFT; + } + else if (!stricmp (state->token, "right")) + { + result = SDL_HAT_RIGHT; + } + else if (!stricmp (state->token, "up")) + { + result = SDL_HAT_UP; + } + else if (!stricmp (state->token, "down")) + { + result = SDL_HAT_DOWN; + } + else + { + _expected_error (state, "left', 'right', 'up' or 'down"); + } + _next_token (state); + return result; +} + +static void +_parse_joybinding (parse_state *state, int *target) +{ + int sticknum; + _consume (state, "joystick"); + sticknum = _consume_num (state); + if (!state->error) + { + if (!stricmp (state->token, "axis")) + { + int axisnum; + _consume (state, "axis"); + axisnum = _consume_num (state); + if (!state->error) + { + int polarity = _consume_polarity (state); + if (!state->error) + { + VControl_AddJoyAxisBinding (sticknum, axisnum, polarity, target); + } + } + } + else if (!stricmp (state->token, "button")) + { + int buttonnum; + _consume (state, "button"); + buttonnum = _consume_num (state); + if (!state->error) + { + VControl_AddJoyButtonBinding (sticknum, buttonnum, target); + } + } + else if (!stricmp (state->token, "hat")) + { + int hatnum; + _consume (state, "hat"); + hatnum = _consume_num (state); + if (!state->error) + { + Uint8 dir = _consume_dir (state); + if (!state->error) + { + VControl_AddJoyHatBinding (sticknum, hatnum, dir, target); + } + } + } + else + { + _expected_error (state, "axis', 'button', or 'hat"); + } + } +} + +static void +_parse_binding (parse_state *state) +{ + int *target = _consume_idname (state); + if (!state->error) + { + if (!stricmp (state->token, "key")) + { + /* Parse key binding */ + int keysym; + _consume (state, "key"); + keysym = _consume_keyname (state); + if (!state->error) + { + VControl_AddKeyBinding (keysym, target); + } + } + else if (!stricmp (state->token, "joystick")) + { + _parse_joybinding (state, target); + } + else + { + _expected_error (state, "key' or 'joystick"); + } + } +} + +static void +_parse_config_line (parse_state *state) +{ + state->error = 0; + _next_token (state); + if (!state->token[0]) + { + /* Blank line, skip it */ + return; + } + if (!stricmp (state->token, "joystick")) + { + int sticknum, threshold = 0; + _consume (state, "joystick"); + sticknum = _consume_num (state); + if (!state->error) _consume (state, "threshold"); + if (!state->error) threshold = _consume_num (state); + if (!state->error) + { + VControl_SetJoyThreshold (sticknum, threshold); + } + return; + } + /* Otherwise, it must be a binding */ + _parse_binding (state); +} + +int +VControl_ReadConfiguration (FILE *in) +{ + parse_state ps; + int errors; + if (!in) + { + fprintf (stderr, "VControl: Invalid configuration file stream\n"); + return 1; + } + ps.linenum = 0; + errors = 0; + while (1) + { + _next_line (&ps, in); + if (!ps.line[0]) + break; + _parse_config_line (&ps); + if (ps.error) + { + errors++; + } + } + return errors; +} + +#if 0 +/* This was kinda handy for proving (lack of) buffer overrun + * vulnerabilities, but there's no real need for it otherwise. */ +void +VControl_TokenizeFile (FILE *in) +{ + parse_state ps; + if (!in) + { + fprintf (stderr, "VControl: Invalid configuration file stream\n"); + return; + } + ps.linenum = 0; + while (1) + { + _next_line (&ps, in); + if (!ps.line[0]) + break; + printf ("%3d:", ps.linenum); + while (1) + { + _next_token (&ps); + if (!ps.token[0]) + break; + printf (" \"%s\"", ps.token); + } + printf ("\n"); + } +} +#endif diff --git a/sc2/src/sc2code/libs/input/sdl/vcontrol.h b/sc2/src/sc2code/libs/input/sdl/vcontrol.h new file mode 100644 index 000000000..1b9362318 --- /dev/null +++ b/sc2/src/sc2code/libs/input/sdl/vcontrol.h @@ -0,0 +1,56 @@ +#include + +#ifndef _VCONTROL_H_ +#define _VCONTROL_H_ + + +/* Initialization routines */ +void VControl_Init (void); +void VControl_Uninit (void); + +/* Control of bindings */ +void VControl_AddKeyBinding (int symbol, int *target); +void VControl_RemoveKeyBinding (int symbol, int *target); +void VControl_AddJoyAxisBinding (int port, int axis, int polarity, int *target); +void VControl_RemoveJoyAxisBinding (int port, int axis, int polarity, int *target); +void VControl_SetJoyThreshold (int port, int threshold); +void VControl_AddJoyButtonBinding (int port, int button, int *target); +void VControl_RemoveJoyButtonBinding (int port, int button, int *target); +void VControl_AddJoyHatBinding (int port, int which, Uint8 dir, int *target); +void VControl_RemoveJoyHatBinding (int port, int which, Uint8 dir, int *target); + +void VControl_RemoveAllBindings (void); + +/* The listener. Routines besides HandleEvent may be used to 'fake' inputs without + * fabricating an SDL_Event. + */ +void VControl_HandleEvent (const SDL_Event *e); +void VControl_ProcessKeyDown (int symbol); +void VControl_ProcessKeyUp (int symbol); +void VControl_ProcessJoyButtonDown (int port, int button); +void VControl_ProcessJoyButtonUp (int port, int button); +void VControl_ProcessJoyAxis (int port, int axis, int value); +void VControl_ProcessJoyHat (int port, int which, Uint8 value); + +/* Force the input into the blank state. For preventing "sticky" keys. */ +void VControl_ResetInput (void); + +/* Name control. To provide a table of names and bindings, declare + * a persistent, unchanging array of VControl_NameBinding and end it + * with a {0, 0} entry. Pass this array to VControl_RegisterNameTable. + * Only one name table may be registered at a time; subsequent calls + * replace the previous values. */ + +typedef struct _vcontrol_namebinding { + char *name; + int *target; +} VControl_NameBinding; + +void VControl_RegisterNameTable (VControl_NameBinding *table); + +/* Dump a configuration file corresponding to the current bindings and names. */ +void VControl_Dump (FILE *out); +/* Read a configuration file. Returns number of errors encountered. */ +int VControl_ReadConfiguration (FILE *in); + +#endif diff --git a/sc2/src/sc2code/libs/input/sdl/vcontrol_malloc.h b/sc2/src/sc2code/libs/input/sdl/vcontrol_malloc.h new file mode 100644 index 000000000..f323fd548 --- /dev/null +++ b/sc2/src/sc2code/libs/input/sdl/vcontrol_malloc.h @@ -0,0 +1,5 @@ +/* re-#define these to use your own allocators. */ +#include "misc.h" + +#define vctrl_malloc HMalloc +#define vctrl_free HFree diff --git a/sc2/src/sc2code/melee.c b/sc2/src/sc2code/melee.c index 970fc52b3..2b885ace1 100644 --- a/sc2/src/sc2code/melee.c +++ b/sc2/src/sc2code/melee.c @@ -23,6 +23,7 @@ #include "melee.h" #include "options.h" #include "file.h" +#include "controls.h" //Added by Chris @@ -103,11 +104,11 @@ extern QUEUE master_q; extern DWORD InTime; PMELEE_STATE volatile pMeleeState; -static BOOLEAN DoMelee (INPUT_STATE InputState, PMELEE_STATE pMS); -static BOOLEAN DoEdit (INPUT_STATE InputState, PMELEE_STATE pMS); -static BOOLEAN DoPickShip (INPUT_STATE InputState, PMELEE_STATE pMS); +static BOOLEAN DoMelee (PMELEE_STATE pMS); +static BOOLEAN DoEdit (PMELEE_STATE pMS); +static BOOLEAN DoPickShip (PMELEE_STATE pMS); static void DrawTeamString (PMELEE_STATE pMS, COUNT HiLiteState); -static BOOLEAN DoLoadTeam (INPUT_STATE InputState, PMELEE_STATE pMS); +static BOOLEAN DoLoadTeam (PMELEE_STATE pMS); static void DrawFileStrings (PMELEE_STATE pMS, int HiLiteState); static void @@ -355,12 +356,11 @@ DrawTeamString (PMELEE_STATE pMS, COUNT HiLiteState) pchar_deltas = char_deltas; for (i = pMS->CurIndex; i > 0; --i) text_r.corner.x += (SIZE)*pchar_deltas++; - if (SerialInput) - { - if (pMS->CurIndex < lfText.CharCount) /* end of line */ - --text_r.corner.x; - text_r.extent.width = 1; - } + if (pMS->CurIndex < lfText.CharCount) /* end of line */ + --text_r.corner.x; + text_r.extent.width = 1; +#if 0 + /* Code for keyboardless systems */ else { if (pMS->CurIndex == lfText.CharCount) /* end of line */ @@ -368,6 +368,7 @@ DrawTeamString (PMELEE_STATE pMS, COUNT HiLiteState) else text_r.extent.width = (SIZE)*pchar_deltas; } +#endif ++text_r.corner.x; ++text_r.corner.y; text_r.extent.height -= 2; @@ -842,11 +843,11 @@ DrawFileStrings (PMELEE_STATE pMS, int HiLiteState) } static BOOLEAN -DoLoadTeam (INPUT_STATE InputState, PMELEE_STATE pMS) +DoLoadTeam (PMELEE_STATE pMS) { SIZE index; - if (InputState & DEVICE_EXIT) + if (GameExiting) return (FALSE); if (!pMS->Initialized) @@ -865,9 +866,9 @@ DoLoadTeam (INPUT_STATE InputState, PMELEE_STATE pMS) pMS->InputFunc = DoLoadTeam; ClearSemaphore (GraphicsSem); } - else if (InputState & (DEVICE_BUTTON1 | DEVICE_BUTTON2)) + else if (CurrentMenuState.select | CurrentMenuState.cancel) { - if (!(InputState & DEVICE_BUTTON2)) + if (!CurrentMenuState.cancel) { pMS->TeamImage[pMS->side] = pMS->FileList[ pMS->CurIndex - pMS->TopTeamIndex @@ -893,7 +894,7 @@ DoLoadTeam (INPUT_STATE InputState, PMELEE_STATE pMS) NewTop = pMS->TopTeamIndex; index = old_index = pMS->CurIndex; - if (GetInputYComponent (InputState) < 0) + if (CurrentMenuState.up) { if (index-- == 0) index = 0; @@ -901,7 +902,7 @@ DoLoadTeam (INPUT_STATE InputState, PMELEE_STATE pMS) if (index < NewTop && (NewTop -= MAX_VIS_TEAMS) < 0) NewTop = 0; } - else if (GetInputYComponent (InputState) > 0) + else if (CurrentMenuState.down) { if ((int)index < (int)GetDirEntryTableCount (pMS->TeamDE) + NUM_PREBUILT - 1) ++index; @@ -909,7 +910,7 @@ DoLoadTeam (INPUT_STATE InputState, PMELEE_STATE pMS) if ((int)index > (int)pMS->BotTeamIndex) NewTop = index; } - else if (InputState & DEVICE_LEFTSHIFT) + else if (CurrentMenuState.page_up) { if ((index -= MAX_VIS_TEAMS) < 0) index = NewTop = 0; @@ -919,7 +920,7 @@ DoLoadTeam (INPUT_STATE InputState, PMELEE_STATE pMS) NewTop = 0; } } - else if (InputState & DEVICE_RIGHTSHIFT) + else if (CurrentMenuState.page_down) { if ((int)(index += MAX_VIS_TEAMS) < (int)(GetDirEntryTableCount (pMS->TeamDE) + NUM_PREBUILT)) @@ -954,11 +955,12 @@ DoLoadTeam (INPUT_STATE InputState, PMELEE_STATE pMS) } static UWORD -DoTextEntry (PMELEE_STATE pMS, INPUT_STATE InputState) +DoTextEntry (PMELEE_STATE pMS) { UWORD ch; UNICODE *pStr, *pBaseStr; COUNT len, max_chars; + BOOLEAN left = FALSE, right = FALSE; if (pMS->MeleeOption == EDIT_MELEE) { @@ -966,61 +968,52 @@ DoTextEntry (PMELEE_STATE pMS, INPUT_STATE InputState) max_chars = MAX_TEAM_CHARS; } - if (SerialInput) - { - ch = GetInputUNICODE (GetInputState (SerialInput)); - } - else - { - extern UWORD GetJoystickChar (INPUT_STATE InputState); - - ch = GetJoystickChar (InputState); - } + ch = GetCharacter (); pStr = &pBaseStr[pMS->CurIndex]; len = wstrlen (pStr); switch (ch) { - case 0x7F: - if (len) - { - memmove (pStr, pStr + 1, len * sizeof (*pStr)); - len = (COUNT)~0; - } - break; - case '\b': - if (pMS->CurIndex) - { - memmove (pStr - 1, pStr, (len + 1) * sizeof (*pStr)); - --pMS->CurIndex; - - len = (COUNT)~0; - } - break; - default: - if (isprint (ch) && len + pStr - pBaseStr < (int)(max_chars)) - { - if (SerialInput) - { - memmove (pStr + 1, pStr, (len + 1) * sizeof (*pStr)); - *pStr++ = ch; - ++pMS->CurIndex; - } - else - { - *pStr = ch; - if (len == 0) - *(pStr + 1) = '\0'; - } - - len = (COUNT)~0; - } - break; + case SK_DELETE: + if (len) + { + memmove (pStr, pStr + 1, len * sizeof (*pStr)); + len = (COUNT)~0; + } + break; + case '\b': + if (pMS->CurIndex) + { + memmove (pStr - 1, pStr, (len + 1) * sizeof (*pStr)); + --pMS->CurIndex; + + len = (COUNT)~0; + } + break; + case SK_LF_ARROW: + left = TRUE; + break; + case SK_RT_ARROW: + right = TRUE; + break; + default: + /* This really should use isprint, but for some + * ungodly reason some machines refuse to accept + * anything as printable */ + if ((ch >= 32) && (ch < 127) && (len + pStr - pBaseStr < (int)(max_chars))) + { + memmove (pStr + 1, pStr, (len + 1) * sizeof (*pStr)); + *pStr++ = ch; + ++pMS->CurIndex; + + len = (COUNT)~0; + } + break; } if (len == (COUNT)~0) DrawTeamString (pMS, 1); - else if (GetInputXComponent (InputState) < 0) + else if (left) { if (pMS->CurIndex) { @@ -1028,7 +1021,7 @@ DoTextEntry (PMELEE_STATE pMS, INPUT_STATE InputState) DrawTeamString (pMS, 1); } } - else if (GetInputXComponent (InputState) > 0) + else if (right) { if (len) { @@ -1142,11 +1135,10 @@ RetrySave: } static BOOLEAN -DoEdit (INPUT_STATE InputState, PMELEE_STATE pMS) +DoEdit (PMELEE_STATE pMS) { - if (InputState & DEVICE_EXIT) + if (GameExiting) return (FALSE); - if (!pMS->Initialized) { pMS->CurIndex = pMS->TeamImage[pMS->side].ShipList[pMS->row][pMS->col]; @@ -1156,8 +1148,8 @@ DoEdit (INPUT_STATE InputState, PMELEE_STATE pMS) pMS->InputFunc = DoEdit; } else if ((pMS->row < NUM_MELEE_ROWS || pMS->CurIndex == (BYTE)~0) - && ((InputState & DEVICE_BUTTON2) - || (GetInputXComponent (InputState) > 0 + && (CurrentMenuState.cancel + || (CurrentMenuState.right && (pMS->col == NUM_MELEE_COLUMNS - 1 || pMS->row == NUM_MELEE_ROWS)))) { SetSemaphore (GraphicsSem); @@ -1169,13 +1161,14 @@ DoEdit (INPUT_STATE InputState, PMELEE_STATE pMS) InTime = GetTimeCounter (); } else if (pMS->row < NUM_MELEE_ROWS - && (InputState & (DEVICE_BUTTON1 | DEVICE_BUTTON3))) + && (CurrentMenuState.select || CurrentMenuState.special)) { - if (InputState & DEVICE_BUTTON1) + if (CurrentMenuState.select) pMS->Initialized = 0; else pMS->Initialized = -1; - DoPickShip (0, pMS); + TFB_ResetControls (); + DoPickShip (pMS); } else { @@ -1189,45 +1182,47 @@ DoEdit (INPUT_STATE InputState, PMELEE_STATE pMS) { if (pMS->CurIndex != (BYTE)~0) { + UNICODE ch; SetSemaphore (GraphicsSem); - if (pMS->Initialized == 1 && SerialInput) + if (pMS->Initialized == 1) { FlushInput (); pMS->Initialized = 2; } - else if ((SerialInput == 0 && (InputState & DEVICE_BUTTON2)) - || DoTextEntry (pMS, InputState) == '\n') + else if (((ch = DoTextEntry (pMS)) == '\n') || (ch == '\r')) { pMS->CurIndex = (BYTE)~0; DrawTeamString (pMS, 4); pMS->Initialized = 1; + DisableCharacterMode (); } ClearSemaphore (GraphicsSem); return (TRUE); } - else if (InputState & DEVICE_BUTTON1) + else if (CurrentMenuState.select) { pMS->CurIndex = 0; SetSemaphore (GraphicsSem); DrawTeamString (pMS, 1); ClearSemaphore (GraphicsSem); + EnableCharacterMode (); return (TRUE); } } { - if (GetInputXComponent (InputState) < 0) + if (CurrentMenuState.left) { if (col-- == 0) col = 0; } - else if (GetInputXComponent (InputState) > 0) + else if (CurrentMenuState.right) { if (++col == NUM_MELEE_COLUMNS) col = NUM_MELEE_COLUMNS - 1; } - if (GetInputYComponent (InputState) < 0) + if (CurrentMenuState.up) { if (row-- == 0) { @@ -1240,7 +1235,7 @@ DoEdit (INPUT_STATE InputState, PMELEE_STATE pMS) } } } - else if (GetInputYComponent (InputState) > 0) + else if (CurrentMenuState.down) { if (row++ == NUM_MELEE_ROWS) { @@ -1276,11 +1271,11 @@ DoEdit (INPUT_STATE InputState, PMELEE_STATE pMS) } static BOOLEAN -DoPickShip (INPUT_STATE InputState, PMELEE_STATE pMS) +DoPickShip (PMELEE_STATE pMS) { STARSHIPPTR StarShipPtr; - if (InputState & DEVICE_EXIT) + if (GameExiting) return (FALSE); if (pMS->Initialized <= 0) @@ -1338,11 +1333,11 @@ DoPickShip (INPUT_STATE InputState, PMELEE_STATE pMS) DrawMeleeShipStrings (pMS, (BYTE)(pMS->CurIndex)); } } - else if (InputState & (DEVICE_BUTTON1 | DEVICE_BUTTON2)) + else if (CurrentMenuState.select || CurrentMenuState.cancel) { pMS->InputFunc = 0; /* disable ship flashing */ - if (!(InputState & DEVICE_BUTTON2)) + if (!CurrentMenuState.cancel) { HSTARSHIP hStarShip; @@ -1385,7 +1380,7 @@ DoPickShip (INPUT_STATE InputState, PMELEE_STATE pMS) return (TRUE); } - else if (InputState & DEVICE_BUTTON3) + else if (CurrentMenuState.special) { DoShipSpin (pMS->CurIndex, (MUSIC_REF)0); @@ -1397,25 +1392,25 @@ DoPickShip (INPUT_STATE InputState, PMELEE_STATE pMS) NewStarShip = pMS->CurIndex; - if (GetInputXComponent (InputState) < 0) + if (CurrentMenuState.left) { if (NewStarShip-- % NUM_PICK_COLS == 0) NewStarShip += NUM_PICK_COLS; } - else if (GetInputXComponent (InputState) > 0) + else if (CurrentMenuState.right) { if (++NewStarShip % NUM_PICK_COLS == 0) NewStarShip -= NUM_PICK_COLS; } - if (GetInputYComponent (InputState) < 0) + if (CurrentMenuState.up) { if (NewStarShip >= NUM_PICK_COLS) NewStarShip -= NUM_PICK_COLS; else NewStarShip += NUM_PICK_COLS * (NUM_PICK_ROWS - 1); } - else if (GetInputYComponent (InputState) > 0) + else if (CurrentMenuState.down) { if (NewStarShip < NUM_PICK_COLS * (NUM_PICK_ROWS - 1)) NewStarShip += NUM_PICK_COLS; @@ -1590,14 +1585,11 @@ BuildAndDrawShipList (PMELEE_STATE pMS) } static BOOLEAN -DoMelee (INPUT_STATE InputState, PMELEE_STATE pMS) +DoMelee (PMELEE_STATE pMS) { - if (InputState) - { - if (InputState & DEVICE_EXIT) - return (FALSE); - InTime = GetTimeCounter (); - } + BOOLEAN force_select = FALSE; + if (GameExiting) + return (FALSE); if (!pMS->Initialized) { @@ -1613,34 +1605,36 @@ DoMelee (INPUT_STATE InputState, PMELEE_STATE pMS) } InTime = GetTimeCounter (); } - else if ((InputState & DEVICE_BUTTON2) - || GetInputXComponent (InputState) < 0) + else if (CurrentMenuState.cancel || CurrentMenuState.left) { SetSemaphore (GraphicsSem); + InTime = GetTimeCounter (); Deselect (pMS->MeleeOption); ClearSemaphore (GraphicsSem); pMS->MeleeOption = EDIT_MELEE; pMS->Initialized = FALSE; - if (InputState & DEVICE_BUTTON2) + if (CurrentMenuState.cancel) pMS->side = pMS->row = pMS->col = 0; else pMS->side = 0, pMS->row = NUM_MELEE_ROWS - 1, pMS->col = NUM_MELEE_COLUMNS - 1; - DoEdit (InputState, pMS); + DoEdit (pMS); } else { MELEE_OPTIONS NewMeleeOption; NewMeleeOption = pMS->MeleeOption; - if (GetInputYComponent (InputState) < 0) + if (CurrentMenuState.up) { + InTime = GetTimeCounter (); if (NewMeleeOption-- == CONTROLS_TOP) NewMeleeOption = CONTROLS_TOP; } - else if (GetInputYComponent (InputState) > 0) + else if (CurrentMenuState.down) { + InTime = GetTimeCounter (); if (NewMeleeOption++ == CONTROLS_BOT) NewMeleeOption = CONTROLS_BOT; } @@ -1648,7 +1642,7 @@ DoMelee (INPUT_STATE InputState, PMELEE_STATE pMS) if ((PlayerControl[0] & PlayerControl[1] & PSYTRON_CONTROL) && GetTimeCounter () - InTime > ONE_SECOND * 10) { - InputState = DEVICE_BUTTON1; + force_select = TRUE; NewMeleeOption = START_MELEE; } @@ -1661,7 +1655,7 @@ DoMelee (INPUT_STATE InputState, PMELEE_STATE pMS) ClearSemaphore (GraphicsSem); } - if (InputState & DEVICE_BUTTON1) + if (CurrentMenuState.select || force_select) { switch (pMS->MeleeOption) { @@ -1721,7 +1715,7 @@ DoMelee (INPUT_STATE InputState, PMELEE_STATE pMS) case LOAD_BOT: pMS->Initialized = FALSE; pMS->side = pMS->MeleeOption == LOAD_TOP ? 0 : 1; - DoLoadTeam (InputState, pMS); + DoLoadTeam (pMS); break; case SAVE_TOP: case SAVE_BOT: diff --git a/sc2/src/sc2code/melee.h b/sc2/src/sc2code/melee.h index 7220e66ad..67c19f589 100644 --- a/sc2/src/sc2code/melee.h +++ b/sc2/src/sc2code/melee.h @@ -79,8 +79,7 @@ typedef struct typedef struct melee_state { - BOOLEAN (*InputFunc) (INPUT_STATE InputState, struct melee_state * - pInputState); + BOOLEAN (*InputFunc) (struct melee_state *pInputState); COUNT MenuRepeatDelay; BOOLEAN Initialized; diff --git a/sc2/src/sc2code/menu.c b/sc2/src/sc2code/menu.c index 9a497a761..1e5abc8a6 100644 --- a/sc2/src/sc2code/menu.c +++ b/sc2/src/sc2code/menu.c @@ -21,6 +21,7 @@ #include "libs/graphics/gfx_common.h" #include "libs/tasklib.h" #include "options.h" +#include "controls.h" extern Task flash_task; extern RECT flash_rect; @@ -434,7 +435,7 @@ ConvertAlternateMenu (BYTE BaseState, BYTE NewState) } BOOLEAN -DoMenuChooser (INPUT_STATE InputState, PMENU_STATE pMS, BYTE BaseState) +DoMenuChooser (PMENU_STATE pMS, BYTE BaseState) { { @@ -443,13 +444,11 @@ DoMenuChooser (INPUT_STATE InputState, PMENU_STATE pMS, BYTE BaseState) BOOLEAN useAltMenu = FALSE; if (optWhichMenu == OPT_PC) useAltMenu = GetAlternateMenu (&BaseState, &NewState); - if (GetInputXComponent (InputState) < 0 - || GetInputYComponent (InputState) < 0) + if (CurrentMenuState.left || CurrentMenuState.up) NewState = PreviousMenuState (BaseState, NewState); - else if (GetInputXComponent (InputState) > 0 - || GetInputYComponent (InputState) > 0) + else if (CurrentMenuState.right || CurrentMenuState.down) NewState = NextMenuState (BaseState, NewState); - else if (useAltMenu && InputState & DEVICE_BUTTON1) + else if (useAltMenu && CurrentMenuState.select) { NewState = ConvertAlternateMenu (BaseState, NewState); if (NewState == ALT_MANIFEST) diff --git a/sc2/src/sc2code/outfit.c b/sc2/src/sc2code/outfit.c index f79985c52..4fa284932 100644 --- a/sc2/src/sc2code/outfit.c +++ b/sc2/src/sc2code/outfit.c @@ -19,6 +19,7 @@ #include "starcon.h" #include "libs/graphics/gfx_common.h" #include "options.h" +#include "controls.h" //Added by Chris @@ -162,13 +163,13 @@ DisplayLanders (PMENU_STATE pMS) } static BOOLEAN -DoInstallModule (INPUT_STATE InputState, PMENU_STATE pMS) +DoInstallModule (PMENU_STATE pMS) { extern void DrawFlagshipStats (void); BYTE NewState, new_slot_piece, old_slot_piece; SIZE FirstItem, LastItem; - //STAMP s; + BOOLEAN select, cancel, motion; if (GLOBAL (CurrentActivity) & CHECK_ABORT) { @@ -176,6 +177,10 @@ DoInstallModule (INPUT_STATE InputState, PMENU_STATE pMS) return (TRUE); } + select = CurrentMenuState.select; + cancel = CurrentMenuState.cancel; + motion = CurrentMenuState.left || CurrentMenuState.right || CurrentMenuState.up || CurrentMenuState.down; + FirstItem = 0; switch (NewState = pMS->CurState) { @@ -187,19 +192,16 @@ DoInstallModule (INPUT_STATE InputState, PMENU_STATE pMS) break; case FUSION_THRUSTER: case EMPTY_SLOT + 0: - old_slot_piece = - GLOBAL_SIS (DriveSlots[pMS->delta_item]); + old_slot_piece = GLOBAL_SIS (DriveSlots[pMS->delta_item]); LastItem = NUM_DRIVE_SLOTS - 1; break; case TURNING_JETS: case EMPTY_SLOT + 1: - old_slot_piece = - GLOBAL_SIS (JetSlots[pMS->delta_item]); + old_slot_piece = GLOBAL_SIS (JetSlots[pMS->delta_item]); LastItem = NUM_JET_SLOTS - 1; break; default: - old_slot_piece = - GLOBAL_SIS (ModuleSlots[pMS->delta_item]); + old_slot_piece = GLOBAL_SIS (ModuleSlots[pMS->delta_item]); if (GET_GAME_STATE (CHMMR_BOMB_STATE) == 3) FirstItem = NUM_BOMB_MODULES; LastItem = NUM_MODULE_SLOTS - 1; @@ -225,10 +227,10 @@ DoInstallModule (INPUT_STATE InputState, PMENU_STATE pMS) SetFlashRect (NULL_PTR, (FRAME)0); goto InitFlash; } - else if (InputState & (DEVICE_BUTTON1 | DEVICE_BUTTON2)) + else if (select || cancel) { new_slot_piece = pMS->CurState; - if (InputState & DEVICE_BUTTON1) + if (select) { if (new_slot_piece < EMPTY_SLOT) { @@ -273,7 +275,7 @@ DoInstallModule (INPUT_STATE InputState, PMENU_STATE pMS) SetFlashRect (NULL_PTR, (FRAME)0); - if (InputState & DEVICE_BUTTON1) + if (select) { if (new_slot_piece >= EMPTY_SLOT && old_slot_piece >= EMPTY_SLOT) { @@ -330,7 +332,7 @@ DoInstallModule (INPUT_STATE InputState, PMENU_STATE pMS) } } - InputState &= ~DEVICE_BUTTON2; + cancel = FALSE; } if (pMS->CurState < EMPTY_SLOT) @@ -340,11 +342,11 @@ DoInstallModule (INPUT_STATE InputState, PMENU_STATE pMS) pMS->CurState = EMPTY_SLOT + 3; else if (pMS->CurState > EMPTY_SLOT + 2) pMS->CurState = EMPTY_SLOT + 2; - if (InputState & DEVICE_BUTTON2) + if (cancel) new_slot_piece = pMS->CurState; goto InitFlash; } - else if (!(InputState & DEVICE_BUTTON2)) + else if (!cancel) { pMS->CurState = new_slot_piece; goto InitFlash; @@ -362,19 +364,16 @@ DoInstallModule (INPUT_STATE InputState, PMENU_STATE pMS) } ClearSemaphore (GraphicsSem); } - else if (InputState) + else if (motion) { SIZE NewItem; NewItem = NewState < EMPTY_SLOT ? pMS->CurState : pMS->delta_item; do { - SBYTE dy; - - dy = GetInputYComponent (InputState); - if (NewState >= EMPTY_SLOT && dy) + if (NewState >= EMPTY_SLOT && (CurrentMenuState.up || CurrentMenuState.down)) { - if (dy < 0) + if (CurrentMenuState.up) { if (NewState-- == EMPTY_SLOT) NewState = EMPTY_SLOT + 3; @@ -388,18 +387,18 @@ DoInstallModule (INPUT_STATE InputState, PMENU_STATE pMS) if (GET_GAME_STATE (CHMMR_BOMB_STATE) == 3) { if (NewState == EMPTY_SLOT + 3) - NewState = dy < 0 ? EMPTY_SLOT + 2 : EMPTY_SLOT; + NewState = CurrentMenuState.up ? EMPTY_SLOT + 2 : EMPTY_SLOT; if (NewState == EMPTY_SLOT + 2) NewItem = NUM_BOMB_MODULES; } pMS->delta_item = NewItem; } - else if (GetInputXComponent (InputState) < 0 || dy < 0) + else if (CurrentMenuState.left || CurrentMenuState.up) { if (NewItem-- == FirstItem) NewItem = LastItem; } - else if (GetInputXComponent (InputState) > 0 || dy > 0) + else if (CurrentMenuState.right || CurrentMenuState.down) { if (NewItem++ == LastItem) NewItem = FirstItem; @@ -512,14 +511,13 @@ InitFlash: return (TRUE); } void -ChangeFuelQuantity (INPUT_STATE InputState) +ChangeFuelQuantity () { RECT r; r.extent.height = 1; - if (GetInputXComponent (InputState) < 0 - || GetInputYComponent (InputState) < 0) + if (CurrentMenuState.left || CurrentMenuState.up) { SetSemaphore (GraphicsSem); SetContext (SpaceContext); @@ -545,8 +543,7 @@ ChangeFuelQuantity (INPUT_STATE InputState) } ClearSemaphore (GraphicsSem); } - else if (GetInputXComponent (InputState) > 0 - || GetInputYComponent (InputState) > 0) + else if (CurrentMenuState.right || CurrentMenuState.down) { SetSemaphore (GraphicsSem); SetContext (SpaceContext); @@ -571,7 +568,7 @@ ChangeFuelQuantity (INPUT_STATE InputState) } BOOLEAN -DoOutfit (INPUT_STATE InputState, PMENU_STATE pMS) +DoOutfit (PMENU_STATE pMS) { if (GLOBAL (CurrentActivity) & CHECK_ABORT) goto ExitOutfit; @@ -691,8 +688,8 @@ DoOutfit (INPUT_STATE InputState, PMENU_STATE pMS) SetContext (StatusContext); } - else if ((InputState & DEVICE_BUTTON2) - || ((InputState & DEVICE_BUTTON1) + else if (CurrentMenuState.cancel + || (CurrentMenuState.select && pMS->CurState == OUTFIT_EXIT)) { if (pMS->CurState == OUTFIT_DOFUEL) @@ -713,7 +710,7 @@ ExitOutfit: return (FALSE); } } - else if (InputState & DEVICE_BUTTON1) + else if (CurrentMenuState.select) { switch (pMS->CurState) { @@ -743,7 +740,7 @@ ExitOutfit: pMS->delta_item = NUM_BOMB_MODULES; pMS->first_item.y = 0; pMS->Initialized = 0; - DoInstallModule (InputState, pMS); + DoInstallModule (pMS); break; case OUTFIT_SAVELOAD: if (GameOptions () == 0) @@ -758,9 +755,9 @@ ExitOutfit: else { if (pMS->CurState == OUTFIT_DOFUEL) - ChangeFuelQuantity(InputState); + ChangeFuelQuantity (); else - DoMenuChooser (InputState, pMS, PM_FUEL); + DoMenuChooser (pMS, PM_FUEL); } return (TRUE); diff --git a/sc2/src/sc2code/pickmele.c b/sc2/src/sc2code/pickmele.c index 201321c24..60c5d1975 100644 --- a/sc2/src/sc2code/pickmele.c +++ b/sc2/src/sc2code/pickmele.c @@ -30,14 +30,14 @@ GetMeleeStarShip (STARSHIPPTR LastStarShipPtr, COUNT which_player) { COUNT ships_left, row, col; DWORD NewTime, OldTime, LastTime; - INPUT_STATE OldInputState; + BATTLE_INPUT_STATE OldInputState; HSTARSHIP hBattleShip, hNextShip; STARSHIPPTR StarShipPtr; RECT flash_rect; - TEXT t; - UNICODE buf[10]; - STAMP s; - CONTEXT OldContext; + TEXT t; + UNICODE buf[10]; + STAMP s; + CONTEXT OldContext; if (!(GLOBAL (CurrentActivity) & IN_BATTLE)) return (0); @@ -52,7 +52,7 @@ GetMeleeStarShip (STARSHIPPTR LastStarShipPtr, COUNT which_player) cur_bucks = 0; for (hBattleShip = GetHeadLink (&race_q[which_player]); - hBattleShip != 0; hBattleShip = hNextShip) + hBattleShip != 0; hBattleShip = hNextShip) { StarShipPtr = LockStarShip (&race_q[which_player], hBattleShip); if (StarShipPtr == LastStarShipPtr) @@ -110,7 +110,7 @@ GetMeleeStarShip (STARSHIPPTR LastStarShipPtr, COUNT which_player) if (LOBYTE (battle_counter) == 0 || HIBYTE (battle_counter) == 0) { DWORD TimeOut; - INPUT_STATE PressState, ButtonState; + BOOLEAN PressState, ButtonState; s.origin.y = PICK_Y_OFFS - 9 + (which_player * PICK_SIDE_OFFS); s.frame = SetAbsFrameIndex (PickMeleeFrame, @@ -121,6 +121,7 @@ GetMeleeStarShip (STARSHIPPTR LastStarShipPtr, COUNT which_player) SetContext (OldContext); ClearSemaphore (GraphicsSem); + UpdateInputState (); PressState = AnyButtonPress (TRUE); do { @@ -128,16 +129,18 @@ GetMeleeStarShip (STARSHIPPTR LastStarShipPtr, COUNT which_player) if (PressState) { PressState = ButtonState; - ButtonState = 0; + ButtonState = FALSE; } } while (!ButtonState && (!(PlayerControl[0] & PlayerControl[1] & PSYTRON_CONTROL) || (TaskSwitch (), GetTimeCounter ()) < TimeOut)); + /* if (ButtonState) ButtonState = GetInputState (NormalInput); if (ButtonState & DEVICE_EXIT) ConfirmExit (); + */ SetSemaphore (GraphicsSem); @@ -169,25 +172,23 @@ GetMeleeStarShip (STARSHIPPTR LastStarShipPtr, COUNT which_player) goto ChangeSelection; for (;;) { - INPUT_STATE InputState; + BATTLE_INPUT_STATE InputState; SleepThread (ONE_SECOND / 120); NewTime = GetTimeCounter (); - InputState = GetInputState (PlayerInput[which_player]); + UpdateInputState (); + InputState = (*(PlayerInput[which_player])) (); if (InputState) LastTime = NewTime; else if (!(PlayerControl[1 - which_player] & PSYTRON_CONTROL) && NewTime - LastTime >= ONE_SECOND * 3) - InputState = GetInputState (PlayerInput[1 - which_player]); - if (InputState & DEVICE_EXIT) + InputState = (*(PlayerInput[1 - which_player])) (); + if (GameExiting) { - if (ConfirmExit ()) - { - hBattleShip = 0; - break; - } - continue; + hBattleShip = 0; + GameExiting = FALSE; + break; } if (InputState == OldInputState @@ -199,11 +200,12 @@ GetMeleeStarShip (STARSHIPPTR LastStarShipPtr, COUNT which_player) OldTime = NewTime; } - if (InputState & DEVICE_BUTTON1) + if (InputState & BATTLE_WEAPON || CurrentMenuState.select) { if (hBattleShip || (col == NUM_MELEE_COLS_ORIG && ConfirmExit ())) { GLOBAL (CurrentActivity) &= ~CHECK_ABORT; + GameExiting = FALSE; break; } } @@ -213,22 +215,22 @@ GetMeleeStarShip (STARSHIPPTR LastStarShipPtr, COUNT which_player) new_row = row; new_col = col; - if (GetInputXComponent (InputState) < 0) + if ((InputState & BATTLE_LEFT) || CurrentMenuState.left) { if (new_col-- == 0) new_col = NUM_MELEE_COLS_ORIG; } - else if (GetInputXComponent (InputState) > 0) + else if ((InputState & BATTLE_RIGHT) || CurrentMenuState.right) { if (new_col++ == NUM_MELEE_COLS_ORIG) new_col = 0; } - if (GetInputYComponent (InputState) < 0) + if ((InputState & BATTLE_THRUST) || CurrentMenuState.up) { if (new_row-- == 0) new_row = NUM_MELEE_ROWS - 1; } - else if (GetInputYComponent (InputState) > 0) + else if (CurrentMenuState.down) { if (++new_row == NUM_MELEE_ROWS) new_row = 0; diff --git a/sc2/src/sc2code/pickship.c b/sc2/src/sc2code/pickship.c index f3d368d7a..8e0a48656 100644 --- a/sc2/src/sc2code/pickship.c +++ b/sc2/src/sc2code/pickship.c @@ -17,6 +17,7 @@ */ #include "starcon.h" +#include "controls.h" #define NUM_PICK_SHIP_ROWS 2 #define NUM_PICK_SHIP_COLUMNS 6 @@ -30,7 +31,7 @@ #define FLAGSHIP_HEIGHT 48 static BOOLEAN -DoPickBattleShip (INPUT_STATE InputState, PMENU_STATE pMS) +DoPickBattleShip (PMENU_STATE pMS) { if (GLOBAL (CurrentActivity) & CHECK_ABORT) { @@ -47,7 +48,7 @@ DoPickBattleShip (INPUT_STATE InputState, PMENU_STATE pMS) goto ChangeSelection; } - else if (InputState & DEVICE_BUTTON1) + else if (CurrentMenuState.select) { if ((HSTARSHIP)pMS->CurFrame) return (FALSE); @@ -55,9 +56,14 @@ DoPickBattleShip (INPUT_STATE InputState, PMENU_STATE pMS) else { COORD new_row, new_col; + int dx = 0, dy = 0; + if (CurrentMenuState.right) dx = 1; + if (CurrentMenuState.left) dx = -1; + if (CurrentMenuState.up) dy = -1; + if (CurrentMenuState.down) dy = 1; - new_col = pMS->first_item.x + GetInputXComponent (InputState); - new_row = pMS->first_item.y + GetInputYComponent (InputState); + new_col = pMS->first_item.x + dx; + new_row = pMS->first_item.y + dy; if (new_row != pMS->first_item.y || new_col != pMS->first_item.x) { diff --git a/sc2/src/sc2code/planets/cargo.c b/sc2/src/sc2code/planets/cargo.c index f1443de12..597ea17bc 100644 --- a/sc2/src/sc2code/planets/cargo.c +++ b/sc2/src/sc2code/planets/cargo.c @@ -17,6 +17,7 @@ */ #include "starcon.h" +#include "controls.h" //Added by Chris @@ -275,9 +276,14 @@ DrawCargoStrings (BYTE OldElement, BYTE NewElement) } static BOOLEAN -DoDiscardCargo (INPUT_STATE InputState, PMENU_STATE pMS) +DoDiscardCargo (PMENU_STATE pMS) { BYTE NewState; + BOOLEAN select, cancel, back, forward; + select = CurrentMenuState.select; + cancel = CurrentMenuState.cancel; + back = CurrentMenuState.up || CurrentMenuState.left; + forward = CurrentMenuState.down || CurrentMenuState.right; if (GLOBAL (CurrentActivity) & CHECK_ABORT) return (FALSE); @@ -291,7 +297,7 @@ DoDiscardCargo (INPUT_STATE InputState, PMENU_STATE pMS) pMS->CurState = (BYTE)~0; goto SelectCargo; } - else if (InputState & DEVICE_BUTTON2) + else if (cancel) { SetSemaphore (GraphicsSem); ClearSISRect (DRAW_SIS_DISPLAY); @@ -299,7 +305,7 @@ DoDiscardCargo (INPUT_STATE InputState, PMENU_STATE pMS) return (FALSE); } - else if (InputState & DEVICE_BUTTON1) + else if (select) { if (GLOBAL_SIS (ElementAmounts[pMS->CurState - 1])) { @@ -315,14 +321,12 @@ DoDiscardCargo (INPUT_STATE InputState, PMENU_STATE pMS) else { NewState = pMS->CurState - 1; - if (GetInputXComponent (InputState) < 0 - || GetInputYComponent (InputState) < 0) + if (back) { if (NewState-- == 0) NewState = NUM_ELEMENT_CATEGORIES - 1; } - else if (GetInputXComponent (InputState) > 0 - || GetInputYComponent (InputState) > 0) + else if (forward) { if (++NewState == NUM_ELEMENT_CATEGORIES) NewState = 0; diff --git a/sc2/src/sc2code/planets/devices.c b/sc2/src/sc2code/planets/devices.c index 9053ac91a..66c993c10 100644 --- a/sc2/src/sc2code/planets/devices.c +++ b/sc2/src/sc2code/planets/devices.c @@ -17,6 +17,7 @@ */ #include "starcon.h" +#include "controls.h" static COUNT lpstrchr (UNICODE *pStr, UNICODE ch) @@ -420,9 +421,14 @@ DeviceFailed (BYTE which_device) } static BOOLEAN -DoManipulateDevices (INPUT_STATE InputState, PMENU_STATE pMS) +DoManipulateDevices (PMENU_STATE pMS) { BYTE NewState; + BOOLEAN select, cancel, back, forward; + select = CurrentMenuState.select; + cancel = CurrentMenuState.cancel; + back = CurrentMenuState.up || CurrentMenuState.left; + forward = CurrentMenuState.down || CurrentMenuState.right; if (GLOBAL (CurrentActivity) & CHECK_ABORT) return (FALSE); @@ -436,11 +442,11 @@ DoManipulateDevices (INPUT_STATE InputState, PMENU_STATE pMS) NewState = pMS->CurState; goto SelectDevice; } - else if (InputState & DEVICE_BUTTON2) + else if (cancel) { return (FALSE); } - else if (InputState & DEVICE_BUTTON1) + else if (select) { UWORD status; @@ -465,8 +471,7 @@ DoManipulateDevices (INPUT_STATE InputState, PMENU_STATE pMS) NewTop = pMS->first_item.y; NewState = pMS->CurState - 1; - if (GetInputXComponent (InputState) < 0 - || GetInputYComponent (InputState) < 0) + if (back) { if (NewState-- == 0) NewState = 0; @@ -474,8 +479,7 @@ DoManipulateDevices (INPUT_STATE InputState, PMENU_STATE pMS) if ((SIZE)NewState < NewTop && (NewTop -= MAX_VIS_DEVICES) < 0) NewTop = 0; } - else if (GetInputXComponent (InputState) > 0 - || GetInputYComponent (InputState) > 0) + else if (forward) { if (++NewState == (BYTE)pMS->first_item.x) NewState = (BYTE)(pMS->first_item.x - 1); @@ -619,7 +623,8 @@ Devices (PMENU_STATE pMS) pMS->first_item.y = 0; pMS->CurFrame = (FRAME)DeviceMap; - DoManipulateDevices (0, pMS); /* to make sure it's initialized */ + TFB_ResetControls (); + DoManipulateDevices (pMS); /* to make sure it's initialized */ DoInput ((PVOID)pMS); pMS->CurFrame = 0; diff --git a/sc2/src/sc2code/planets/lander.c b/sc2/src/sc2code/planets/lander.c index b28b20dde..1d9b671c7 100644 --- a/sc2/src/sc2code/planets/lander.c +++ b/sc2/src/sc2code/planets/lander.c @@ -20,6 +20,7 @@ #include "lander.h" #include "lifeform.h" #include "libs/graphics/gfx_common.h" +#include "controls.h" //define SPIN_ON_LAUNCH to let the planet spin while // the lander animation is playing @@ -1549,7 +1550,7 @@ InitPlanetSide (void) } static BOOLEAN -DoPlanetSide (INPUT_STATE InputState, PMENU_STATE pMS) +DoPlanetSide (PMENU_STATE pMS) { #define NUM_LANDING_DELTAS 10 #define SHUTTLE_TURN_WAIT 2 @@ -1588,10 +1589,8 @@ SetVelocityComponents ( } else if (pMS->delta_item == 0 || (HIBYTE (pMS->delta_item) - && ((InputState & (DEVICE_BUTTON3 | DEVICE_LEFTSHIFT | DEVICE_BUTTON4)) - || ( - (PPLANETSIDE_DESC)pMenuState->ModuleFrame - )->InTransit))) + && (CurrentInputState.lander_escape + || ((PPLANETSIDE_DESC)pMenuState->ModuleFrame)->InTransit))) { if (pMS->delta_item || pMS->CurState > EXPLOSION_LIFE + 60) return (FALSE); @@ -1651,16 +1650,21 @@ SetVelocityComponents ( index = GetFrameIndex (LanderFrame[0]); if (LONIBBLE (pMS->CurState)) pMS->CurState -= MAKE_BYTE (1, 0); - else if ((dx = GetInputXComponent (InputState))) + else if (CurrentInputState.lander_left || CurrentInputState.lander_right) { - if (dx < 0) + if (CurrentInputState.lander_left) + { + dx = -1; --index; + } else + { + dx = +1; ++index; + } index = NORMALIZE_FACING (index); - LanderFrame[0] = - SetAbsFrameIndex (LanderFrame[0], index); + LanderFrame[0] = SetAbsFrameIndex (LanderFrame[0], index); dx = FACING_TO_ANGLE (index); if (!GET_GAME_STATE (IMPROVED_LANDER_SPEED)) @@ -1688,8 +1692,7 @@ SetVelocityComponents ( ); } - if (!(InputState & DEVICE_BUTTON1) - && GetInputYComponent (InputState) >= 0) + if (!CurrentInputState.lander_thrust) dx = dy = 0; else GetNextVelocityComponents ( @@ -1698,7 +1701,7 @@ SetVelocityComponents ( if (HINIBBLE (pMS->CurState)) pMS->CurState -= MAKE_BYTE (0, 1); - else if (InputState & (DEVICE_BUTTON2 | DEVICE_RIGHTSHIFT)) + else if (CurrentInputState.lander_weapon) { HELEMENT hWeaponElement; @@ -1727,8 +1730,7 @@ SetVelocityComponents ( index + ANGLE_TO_FACING (FULL_CIRCLE) ); - if (!(InputState & DEVICE_BUTTON1) - && GetInputYComponent (InputState) >= 0) + if (!CurrentInputState.lander_thrust) wdx = wdy = 0; else GetCurrentVelocityComponents ( diff --git a/sc2/src/sc2code/planets/planets.h b/sc2/src/sc2code/planets/planets.h index eab87c2e2..bce15d474 100644 --- a/sc2/src/sc2code/planets/planets.h +++ b/sc2/src/sc2code/planets/planets.h @@ -155,9 +155,7 @@ typedef struct solarsys_state MENU_STATE MenuState; COUNT WaitIntersect; - PLANET_DESC SunDesc[MAX_SUNS], - PlanetDesc[MAX_PLANETS], - MoonDesc[MAX_MOONS]; + PLANET_DESC SunDesc[MAX_SUNS], PlanetDesc[MAX_PLANETS], MoonDesc[MAX_MOONS]; PPLANET_DESC pBaseDesc, pOrbitalDesc; SIZE FirstPlanetIndex, LastPlanetIndex; @@ -200,8 +198,7 @@ extern void FillOrbits (BYTE NumPlanets, PPLANET_DESC pBaseDesc, BOOLEAN TypesDefined); extern void ScanSystem (void); extern void ChangeSolarSys (void); -extern BOOLEAN DoFlagshipCommands (INPUT_STATE InputState, PMENU_STATE - pMS); +extern BOOLEAN DoFlagshipCommands (PMENU_STATE pMS); extern void ZoomSystem (void); extern void LoadSolarSys (void); extern void InitLander (BYTE LanderFlags); diff --git a/sc2/src/sc2code/planets/pstarmap.c b/sc2/src/sc2code/planets/pstarmap.c index 0d5b12ae9..41503bd4b 100644 --- a/sc2/src/sc2code/planets/pstarmap.c +++ b/sc2/src/sc2code/planets/pstarmap.c @@ -19,6 +19,8 @@ #include "starcon.h" #include "libs/graphics/gfx_common.h" #include "options.h" +#include "controls.h" +#include "libs/inplib.h" //Added by Chris @@ -597,7 +599,7 @@ ZoomStarMap (SIZE dir) } static BOOLEAN -DoMoveCursor (INPUT_STATE InputState, PMENU_STATE pMS) +DoMoveCursor (PMENU_STATE pMS) { #define MIN_ACCEL_DELAY (ONE_SECOND / 60) #define MAX_ACCEL_DELAY (ONE_SECOND / 8) @@ -615,15 +617,18 @@ DoMoveCursor (INPUT_STATE InputState, PMENU_STATE pMS) ); pMS->InputFunc = DoMoveCursor; + SetMenuRepeatDelay (MIN_ACCEL_DELAY, MAX_ACCEL_DELAY, STEP_ACCEL_DELAY); + pMS->flash_task = AssignTask (flash_cursor_func, 2048, "flash location on star map"); s.origin.x = UNIVERSE_TO_DISPX (pMS->first_item.x); s.origin.y = UNIVERSE_TO_DISPY (pMS->first_item.y); + last_buf = ~0; buf[0] = '\0'; goto UpdateCursorInfo; } - else if (InputState & DEVICE_BUTTON2) + else if (CurrentMenuState.cancel) { if (pMS->flash_task) { @@ -633,7 +638,7 @@ DoMoveCursor (INPUT_STATE InputState, PMENU_STATE pMS) return (FALSE); } - else if (InputState & DEVICE_BUTTON1) + else if (CurrentMenuState.select) { GLOBAL (autopilot) = pMS->first_item; @@ -646,27 +651,24 @@ DoMoveCursor (INPUT_STATE InputState, PMENU_STATE pMS) SIZE ZoomIn, ZoomOut; ZoomIn = ZoomOut = 0; - if (InputState & DEVICE_LEFTSHIFT) + if (CurrentMenuState.zoom_in) ZoomIn = 1; - else if (InputState & DEVICE_RIGHTSHIFT) + else if (CurrentMenuState.zoom_out) ZoomOut = 1; ZoomStarMap (ZoomOut - ZoomIn); - sx = GetInputXComponent (InputState); - sy = GetInputYComponent (InputState); + sx = sy = 0; + if (CurrentMenuState.left) sx = -1; + if (CurrentMenuState.right) sx = 1; + if (CurrentMenuState.up) sy = -1; + if (CurrentMenuState.down) sy = 1; + if (sx == 0 && sy == 0) { - extern INPUT_STATE OldInputState; - - if (OldInputState == 0) - pMS->CurState = MAX_ACCEL_DELAY; } else { - if (pMS->CurState > MIN_ACCEL_DELAY) - pMS->CurState -= STEP_ACCEL_DELAY; - pt.x = UNIVERSE_TO_DISPX (pMS->first_item.x); pt.y = UNIVERSE_TO_DISPY (pMS->first_item.y); @@ -1098,7 +1100,7 @@ DoStarMap (void) MenuState.InputFunc = DoMoveCursor; MenuState.Initialized = FALSE; - MenuState.CurState = MAX_ACCEL_DELAY; + SetMenuRepeatDelay (MIN_ACCEL_DELAY, MAX_ACCEL_DELAY, STEP_ACCEL_DELAY); transition_pending = TRUE; if (GET_GAME_STATE (ARILOU_SPACE_SIDE) <= 1) @@ -1123,6 +1125,7 @@ DoStarMap (void) OldMenuSounds = MenuSounds; MenuSounds = 0; + DoInput ((PVOID)&MenuState); MenuSounds = OldMenuSounds; @@ -1143,7 +1146,7 @@ DoStarMap (void) } BOOLEAN -DoFlagshipCommands (INPUT_STATE InputState, PMENU_STATE pMS) +DoFlagshipCommands (PMENU_STATE pMS) { if (!(pMS->Initialized & 1)) { @@ -1151,6 +1154,7 @@ DoFlagshipCommands (INPUT_STATE InputState, PMENU_STATE pMS) } else { + BOOLEAN select = CurrentMenuState.select; SetSemaphore (GraphicsSem); while (((PMENU_STATE volatile)pMS)->CurState == 0 && (((PMENU_STATE volatile)pMS)->Initialized & 1) @@ -1171,14 +1175,14 @@ DoFlagshipCommands (INPUT_STATE InputState, PMENU_STATE pMS) BYTE NewState; // For some reason, DoFlagshipCommands uses CurState a bit differently pMS->CurState --; - DoMenu = DoMenuChooser (InputState, pMS, + DoMenu = DoMenuChooser (pMS, (BYTE)(pMS->Initialized <= 1 ? PM_STARMAP : PM_SCAN)); pMS->CurState ++; if (!DoMenu) { NewState = pMS->CurState; - if ((InputState & DEVICE_BUTTON1) || LastActivity == CHECK_LOAD) + if (select || LastActivity == CHECK_LOAD) { CONTEXT OldContext; if (NewState != SCAN + 1 && NewState != (GAME_MENU) + 1) @@ -1199,7 +1203,7 @@ DoFlagshipCommands (INPUT_STATE InputState, PMENU_STATE pMS) pMenuState = pMS; if (!Devices (pMS)) - InputState &= ~DEVICE_BUTTON1; + select = FALSE; pMenuState = 0; if (GET_GAME_STATE (PORTAL_COUNTER)) return (FALSE); @@ -1217,7 +1221,7 @@ DoFlagshipCommands (INPUT_STATE InputState, PMENU_STATE pMS) extern BOOLEAN Roster (void); if (!Roster ()) - InputState &= ~DEVICE_BUTTON1; + select = FALSE; break; } case GAME_MENU: @@ -1312,7 +1316,7 @@ DoFlagshipCommands (INPUT_STATE InputState, PMENU_STATE pMS) SetSemaphore (GraphicsSem); SetFlashRect ((PRECT)~0L, (FRAME)0); ClearSemaphore (GraphicsSem); - if (InputState & DEVICE_BUTTON1) + if (select) { if (optWhichMenu != OPT_PC) pMS->CurState = (NAVIGATION) + 1; diff --git a/sc2/src/sc2code/planets/roster.c b/sc2/src/sc2code/planets/roster.c index 49e2c35e1..4ac7d180e 100644 --- a/sc2/src/sc2code/planets/roster.c +++ b/sc2/src/sc2code/planets/roster.c @@ -17,6 +17,7 @@ */ #include "starcon.h" +#include "controls.h" int flash_ship_task(void *data) @@ -199,13 +200,14 @@ RosterCleanup (PMENU_STATE pMS) } static BOOLEAN -DoModifyRoster (INPUT_STATE InputState, PMENU_STATE pMS) +DoModifyRoster (PMENU_STATE pMS) { BYTE NewState; SBYTE sx, sy; RECT r; STAMP s; SHIP_FRAGMENTPTR StarShipPtr; + BOOLEAN select, cancel, up, down, horiz; if (GLOBAL (CurrentActivity) & CHECK_ABORT) { @@ -217,6 +219,12 @@ DoModifyRoster (INPUT_STATE InputState, PMENU_STATE pMS) return (FALSE); } + select = CurrentMenuState.select; + cancel = CurrentMenuState.cancel; + up = CurrentMenuState.up; + down = CurrentMenuState.down; + horiz = CurrentMenuState.left || CurrentMenuState.right; + if (!pMS->Initialized) { pMS->InputFunc = DoModifyRoster; @@ -227,8 +235,7 @@ DoModifyRoster (INPUT_STATE InputState, PMENU_STATE pMS) SetContext (StatusContext); goto SelectSupport; } - else if ((InputState & DEVICE_BUTTON2) - && !(pMS->CurState & SHIP_TOGGLE)) + else if (cancel && !(pMS->CurState & SHIP_TOGGLE)) { SetSemaphore (GraphicsSem); SetFlashRect (NULL_PTR, (FRAME)0); @@ -239,7 +246,7 @@ DoModifyRoster (INPUT_STATE InputState, PMENU_STATE pMS) return (FALSE); } - else if (InputState & (DEVICE_BUTTON1 | DEVICE_BUTTON2)) + else if (select || cancel) { SetSemaphore (GraphicsSem); pMS->CurState ^= SHIP_TOGGLE; @@ -260,8 +267,9 @@ DoModifyRoster (INPUT_STATE InputState, PMENU_STATE pMS) } else if (pMS->CurState & SHIP_TOGGLE) { - if ((sy = GetInputYComponent (InputState)) < 0) + if (up) { + sy = -1; if (GLOBAL_SIS (CrewEnlisted)) { SetSemaphore (GraphicsSem); @@ -269,8 +277,9 @@ DoModifyRoster (INPUT_STATE InputState, PMENU_STATE pMS) ClearSemaphore (GraphicsSem); } } - else if (sy > 0) + else if (down) { + sy = 1; if (GLOBAL_SIS (CrewEnlisted) < GetCPodCapacity (NULL_PTR)) { @@ -286,7 +295,7 @@ DoModifyRoster (INPUT_STATE InputState, PMENU_STATE pMS) NewState = pMS->CurState; sx = (SBYTE)((pMS->delta_item + 1) >> 1); - if (GetInputXComponent (InputState)) + if (horiz) { pship_pos = (PPOINT)pMS->flash_frame1; if (NewState == (BYTE)(sx - 1)) @@ -305,15 +314,17 @@ DoModifyRoster (INPUT_STATE InputState, PMENU_STATE pMS) --NewState; } } - else if ((sy = GetInputYComponent (InputState)) > 0) + else if (down) { + sy = 1; if (++NewState == (BYTE)pMS->delta_item) NewState = (BYTE)(sx - 1); else if (NewState == (BYTE)sx) NewState = 0; } - else if (sy < 0) + else if (up) { + sy = -1; if (NewState == 0) NewState += sx - 1; else if (NewState == (BYTE)sx) diff --git a/sc2/src/sc2code/planets/scan.c b/sc2/src/sc2code/planets/scan.c index 83a15f51d..06f87d2a7 100644 --- a/sc2/src/sc2code/planets/scan.c +++ b/sc2/src/sc2code/planets/scan.c @@ -20,6 +20,7 @@ #include "lifeform.h" #include "libs/graphics/gfx_common.h" #include "options.h" +#include "controls.h" //Added by Chris void @@ -646,11 +647,14 @@ flash_planet_loc_func(void *data) return(0); } -static BOOLEAN DoScan (INPUT_STATE InputState, PMENU_STATE pMS); +static BOOLEAN DoScan (PMENU_STATE pMS); static BOOLEAN -PickPlanetSide (INPUT_STATE InputState, PMENU_STATE pMS) +PickPlanetSide (PMENU_STATE pMS) { + BOOLEAN select, cancel; + select = CurrentMenuState.select; + cancel = CurrentMenuState.cancel; if (GLOBAL (CurrentActivity) & CHECK_ABORT) { if (pMenuState->flash_task) @@ -661,16 +665,16 @@ PickPlanetSide (INPUT_STATE InputState, PMENU_STATE pMS) goto ExitPlanetSide; } - pMS->MenuRepeatDelay = 0; if (!pMS->Initialized) { pMS->InputFunc = PickPlanetSide; + SetMenuRepeatDelay (0, 0, 0); if (pMS->CurFrame == 0) { pMS->CurFrame = (FRAME)MenuSounds; MenuSounds = 0; } - if (!(InputState & DEVICE_BUTTON1)) + if (!select) { RECT r; @@ -698,7 +702,7 @@ PickPlanetSide (INPUT_STATE InputState, PMENU_STATE pMS) 2048, "flash planet location"); } } - else if (InputState & (DEVICE_BUTTON1 | DEVICE_BUTTON2)) + else if (select || cancel) { STAMP s; @@ -714,7 +718,7 @@ PickPlanetSide (INPUT_STATE InputState, PMENU_STATE pMS) pMenuState->flash_task = 0; } - if (!(InputState & DEVICE_BUTTON1)) + if (!select) SetPlanetLoc (pSolarSysState->MenuState.first_item); else { @@ -803,16 +807,21 @@ ExitPlanetSide: pMS->InputFunc = DoScan; pMS->CurState = DISPATCH_SHUTTLE; - pMS->MenuRepeatDelay = MENU_REPEAT_DELAY; + SetDefaultMenuRepeatDelay (); } else { - SIZE dx, dy; + SIZE dx = 0, dy = 0; POINT new_pt; new_pt = pSolarSysState->MenuState.first_item; - dx = GetInputXComponent (InputState) << MAG_SHIFT; + if (CurrentMenuState.left) dx = -1; + if (CurrentMenuState.right) dx = 1; + if (CurrentMenuState.up) dy = -1; + if (CurrentMenuState.down) dy = 1; + + dx = dx << MAG_SHIFT; if (dx) { new_pt.x += dx; @@ -821,7 +830,7 @@ ExitPlanetSide: else if (new_pt.x >= (MAP_WIDTH << MAG_SHIFT)) new_pt.x -= (MAP_WIDTH << MAG_SHIFT); } - dy = GetInputYComponent (InputState) << MAG_SHIFT; + dy = dy << MAG_SHIFT; if (dy) { new_pt.y += dy; @@ -935,11 +944,12 @@ DrawScannedStuff (COUNT y, BYTE CurState) } static BOOLEAN -DoScan (INPUT_STATE InputState, PMENU_STATE - pMS) +DoScan (PMENU_STATE pMS) { - //STAMP s; DWORD TimeIn, WaitTime; + BOOLEAN select, cancel; + select = CurrentMenuState.select; + cancel = CurrentMenuState.cancel; if (GLOBAL (CurrentActivity) & CHECK_ABORT) return (FALSE); @@ -948,9 +958,7 @@ DoScan (INPUT_STATE InputState, PMENU_STATE pMS->Initialized = TRUE; pMS->InputFunc = DoScan; } - else if ((InputState & DEVICE_BUTTON2) - || ((InputState & DEVICE_BUTTON1) - && pMS->CurState == EXIT_SCAN)) + else if (cancel || (select && pMS->CurState == EXIT_SCAN)) { SetSemaphore (GraphicsSem); SetContext (SpaceContext); @@ -964,11 +972,11 @@ DoScan (INPUT_STATE InputState, PMENU_STATE return (FALSE); } - else if (InputState & DEVICE_BUTTON1) + else if (select) { BYTE min_scan, max_scan; RECT r; - INPUT_STATE PressState, ButtonState; + BOOLEAN PressState, ButtonState; if (pMS->CurState == DISPATCH_SHUTTLE) { @@ -1009,7 +1017,7 @@ DoScan (INPUT_STATE InputState, PMENU_STATE pMS->Initialized = FALSE; pMS->CurFrame = 0; - return (PickPlanetSide (InputState, pMS)); + return (PickPlanetSide (pMS)); } pSolarSysState->MenuState.Initialized += 4; @@ -1102,7 +1110,7 @@ DoScan (INPUT_STATE InputState, PMENU_STATE if (PressState) { PressState = ButtonState; - ButtonState = 0; + ButtonState = FALSE; } if (ButtonState) i = -i; @@ -1153,7 +1161,7 @@ DoScan (INPUT_STATE InputState, PMENU_STATE else if (!(pSolarSysState->pOrbitalDesc->data_index & PLANET_SHIELDED) && pSolarSysState->SysInfo.PlanetInfo.AtmoDensity != GAS_GIANT_ATMOSPHERE) - DoMenuChooser (InputState, pMS, PM_MIN_SCAN); + DoMenuChooser (pMS, PM_MIN_SCAN); return (TRUE); } diff --git a/sc2/src/sc2code/planets/solarsys.c b/sc2/src/sc2code/planets/solarsys.c index 95eec3928..79ab89d67 100644 --- a/sc2/src/sc2code/planets/solarsys.c +++ b/sc2/src/sc2code/planets/solarsys.c @@ -18,6 +18,7 @@ #include "starcon.h" #include "libs/graphics/gfx_common.h" +#include "controls.h" //Added by Chris @@ -764,7 +765,7 @@ flagship_inertial_thrust (register COUNT CurrentAngle) extern void DrawIPRadar (BOOLEAN FirstTime); static void -UndrawShip (INPUT_STATE InputState) +UndrawShip (void) { COUNT index; SIZE radius, delta_x, delta_y; @@ -776,13 +777,17 @@ UndrawShip (INPUT_STATE InputState) DrawIPRadar (FALSE); #endif /* SHOW_RADAR */ - delta_x = GetInputXComponent (InputState); -// delta_y = GetInputYComponent (InputState); - if (InputState & DEVICE_BUTTON1) + if (CurrentInputState.p1_thrust) delta_y = -1; else - delta_y = GetInputYComponent (InputState); + delta_y = 0; + delta_x = 0; + if (CurrentInputState.p1_left) + delta_x -= 1; + if (CurrentInputState.p1_right) + delta_x += 1; + if (delta_x || delta_y < 0) { GLOBAL (autopilot.x) = @@ -995,15 +1000,20 @@ int IPtask_func(void* data) #define DEBOUNCE_DELAY ((ONE_SECOND >> 1) / IP_FRAME_RATE) BYTE MenuTransition; DWORD NextTime; - INPUT_STATE InputState; Task task = (Task) data; + BOOLEAN cancel, select; TaskSwitch (); if (LastActivity != CHECK_LOAD) - InputState = 0; + { + cancel = select = FALSE; + } else - InputState = DEVICE_BUTTON2; + { + cancel = TRUE; + select = FALSE; + } MenuTransition = 0; NextTime = GetTimeCounter (); @@ -1022,7 +1032,7 @@ int IPtask_func(void* data) || GLOBAL_SIS (CrewEnlisted) == (COUNT)~0) && !Task_ReadState (task, TASK_EXIT)) { - InputState = 0; + select = cancel = FALSE; ClearSemaphore (GraphicsSem); TaskSwitch (); SetSemaphore (GraphicsSem); @@ -1039,7 +1049,7 @@ int IPtask_func(void* data) if (pSolarSysState->MenuState.CurState || pSolarSysState->MenuState.Initialized == 0) { - InputState = 0; + select = cancel = FALSE; if (draw_sys_flags & DRAW_REFRESH) goto TheMess; } @@ -1048,12 +1058,12 @@ int IPtask_func(void* data) if (MenuTransition) { if (MenuTransition < DEBOUNCE_DELAY - && !(InputState & (DEVICE_BUTTON1 | DEVICE_BUTTON2))) + && !(cancel || select)) MenuTransition = 0; else { --MenuTransition; - InputState &= ~(DEVICE_BUTTON1 | DEVICE_BUTTON2); + cancel = select = FALSE; } } @@ -1082,9 +1092,9 @@ TheMess: } if (MenuTransition < DEBOUNCE_DELAY) - UndrawShip (InputState); + UndrawShip (); if (pSolarSysState->MenuState.Initialized != 1) - InputState = 0; + select = cancel = FALSE; } if (old_radius) @@ -1160,19 +1170,20 @@ TheMess: break; } - if (!(InputState & DEVICE_BUTTON2)) + if (!cancel) { SleepThreadUntil (NextTime + IP_FRAME_RATE); NextTime = GetTimeCounter (); if (pSolarSysState->MenuState.CurState || pSolarSysState->MenuState.Initialized != 1) - InputState = 0; + cancel = select = 0; else - InputState = GetInputState (NormalInput); - JournalInput (InputState); - - if (InputState & DEVICE_EXIT) - InputState = ConfirmExit (); + { + UpdateInputState (); + cancel = ImmediateMenuState.cancel; + select = ImmediateMenuState.select; + } + // JournalInput (InputState); } else { diff --git a/sc2/src/sc2code/restart.c b/sc2/src/sc2code/restart.c index dbc5ec0e4..214b7b58b 100644 --- a/sc2/src/sc2code/restart.c +++ b/sc2/src/sc2code/restart.c @@ -18,6 +18,7 @@ #include "starcon.h" #include "uqmversion.h" +#include "controls.h" //Added by Chris @@ -81,7 +82,7 @@ DrawRestartMenu (BYTE OldState, BYTE NewState, FRAME f) DWORD InTime; static BOOLEAN -DoRestart (INPUT_STATE InputState, PMENU_STATE pMS) +DoRestart (PMENU_STATE pMS) { if (!pMS->Initialized) { @@ -97,7 +98,10 @@ DoRestart (INPUT_STATE InputState, PMENU_STATE pMS) #ifdef TESTING else if (InputState & DEVICE_EXIT) return (FALSE); #endif /* TESTING */ - else if (InputState == 0) + else if (!(CurrentMenuState.up || CurrentMenuState.down || + CurrentMenuState.left || CurrentMenuState.right || + CurrentMenuState.select)) + { if (GetTimeCounter () - InTime < ONE_SECOND * 15) return (TRUE); @@ -105,7 +109,7 @@ else if (InputState & DEVICE_EXIT) return (FALSE); GLOBAL (CurrentActivity) = (ACTIVITY)~0; return (FALSE); } - else if (InputState & DEVICE_BUTTON1) + else if (CurrentMenuState.select) { switch (pMS->CurState) { @@ -133,14 +137,12 @@ else if (InputState & DEVICE_EXIT) return (FALSE); BYTE NewState; NewState = pMS->CurState; - if (GetInputXComponent (InputState) < 0 - || GetInputYComponent (InputState) < 0) + if (CurrentMenuState.left || CurrentMenuState.up) { if (NewState-- == START_NEW_GAME) NewState = PLAY_SUPER_MELEE; } - else if (GetInputXComponent (InputState) > 0 - || GetInputYComponent (InputState) > 0) + else if (CurrentMenuState.right || CurrentMenuState.down) { if (NewState++ == PLAY_SUPER_MELEE) NewState = START_NEW_GAME; diff --git a/sc2/src/sc2code/save.c b/sc2/src/sc2code/save.c index b7a028025..8e8dec062 100644 --- a/sc2/src/sc2code/save.c +++ b/sc2/src/sc2code/save.c @@ -20,6 +20,7 @@ #include "declib.h" #include "file.h" #include "options.h" +#include "controls.h" void FreeSC2Data (void); @@ -207,8 +208,8 @@ SaveProblem (void) { BOOLEAN manage; STAMP s; - INPUT_STATE InputState; CONTEXT OldContext; + BOOLEAN cont; SetSemaphore (GraphicsSem); OldContext = SetContext (SpaceContext); @@ -216,20 +217,23 @@ SaveProblem (void) SaveProblemMessage (&s); GLOBAL (CurrentActivity) |= CHECK_ABORT; + GameExiting = TRUE; while (AnyButtonPress (FALSE)); do { - InputState = GetInputState (NormalInput); - if (InputState & DEVICE_BUTTON1) + cont = FALSE; + UpdateInputState (); + if (CurrentMenuState.select) manage = TRUE; - else if (InputState & DEVICE_BUTTON3) + else if (CurrentMenuState.special) manage = FALSE; else - InputState = 0; - } while (!InputState); + cont = TRUE; + } while (cont); GLOBAL (CurrentActivity) &= ~CHECK_ABORT; + GameExiting = FALSE; BatchGraphics (); DrawStamp (&s); diff --git a/sc2/src/sc2code/setup.c b/sc2/src/sc2code/setup.c index 499103a27..6f8dc73a6 100644 --- a/sc2/src/sc2code/setup.c +++ b/sc2/src/sc2code/setup.c @@ -25,6 +25,7 @@ #include "libs/graphics/gfx_common.h" #include "libs/file.h" #include "options.h" +#include "controls.h" //Added by Chris @@ -43,9 +44,6 @@ CONTEXT ScreenContext, SpaceContext, StatusContext, OffScreenContext, SIZE screen_width, screen_height; FRAME Screen; FONT StarConFont, MicroFont, TinyFont; -INPUT_REF ArrowInput, ComputerInput, NormalInput, SerialInput, - JoystickInput[NUM_PLAYERS], KeyboardInput[NUM_PLAYERS], - CombinedInput[NUM_PLAYERS], PlayerInput[NUM_PLAYERS]; QUEUE race_q[NUM_PLAYERS]; SOUND MenuSounds, GameSounds; FRAME ActivityFrame, status, flagship_status, misc_data; @@ -53,297 +51,20 @@ Semaphore GraphicsSem; CondVar RenderingCond; STRING GameStrings; -static UWORD ParseKeyString(char* line) -{ - char key[16]; - char* index = strchr(line+1, '"'); - if (index == NULL) - return 0; - memset(key, 0, sizeof(key)); - strncpy(key, line+1, index - (line + 1)); - if (strchr(key, ',') != NULL && strlen(key) != 1) - { - // We have a chorded key! - UWORD k1, k2; - char l[16]; - char* comma = line; - memset(l, 0, sizeof(l)); - while (strchr(comma + 1, ',') != NULL) - comma = strchr(comma + 1, ','); - strncpy(l, line, comma - line); - strcat(l, "\""); - k1 = ParseKeyString(l); - memset(l, 0, sizeof(l)); - l[0] = '"'; - strncpy(l + 1, comma + 1, index - (comma + 1)); - strcat(l, "\""); - k2 = ParseKeyString(l); - return KEYCHORD(k1, k2); - } - - if (!strcmp(key, "Left")) - return SK_LF_ARROW; - else if (!strcmp(key, "Right")) - return SK_RT_ARROW; - else if (!strcmp(key, "Up")) - return SK_UP_ARROW; - else if (!strcmp(key, "Down")) - return SK_DN_ARROW; - else if (!strcmp(key, "RCtrl")) - return SK_RT_CTL; - else if (!strcmp(key, "LCtrl")) - return SK_LF_CTL; - else if (!strcmp(key, "RAlt")) - return SK_RT_ALT; - else if (!strcmp(key, "LAlt")) - return SK_LF_ALT; - else if (!strcmp(key, "LShift")) - return SK_LF_SHIFT; - else if (!strcmp(key, "RShift")) - return SK_RT_SHIFT; - else if (!strcmp(key, "Enter")) - return '\n'; - else if (!strcmp(key, "F1")) - return SK_F1; - else if (!strcmp(key, "F2")) - return SK_F2; - else if (!strcmp(key, "F3")) - return SK_F3; - else if (!strcmp(key, "F4")) - return SK_F4; - else if (!strcmp(key, "F5")) - return SK_F5; - else if (!strcmp(key, "F6")) - return SK_F6; - else if (!strcmp(key, "F7")) - return SK_F7; - else if (!strcmp(key, "F8")) - return SK_F8; - else if (!strcmp(key, "F9")) - return SK_F9; - else if (!strcmp(key, "F10")) - return SK_F10; - else if (!strcmp(key, "F11")) - return SK_F11; - else if (!strcmp(key, "F12")) - return SK_F12; - else if (!strcmp(key, "KP+")) - return SK_KEYPAD_PLUS; - else if (!strcmp(key, "KP-")) - return SK_KEYPAD_MINUS; - else if (!strcmp(key, "Esc")) - return 27; //Escape is stadard ASCII 27 - else - return key[0]; -} - -static MEM_HANDLE -LoadKeyConfig (FILE *fp, DWORD length) -{ - UWORD buf[20]; - int p; - int i; - char line[256]; - extern BOOLEAN PauseGame (void); - - UNICODE specialKeys[3]; - - // Look for pause, exit, abort keys - for (i = 0; i < 3; ++i) - { - for (;;) - { - if (feof(fp) || ferror(fp)) - break; - fgets(line, 256, fp); - if (line[0] != '#') - break; - } - if (line[0] == '"') - { - specialKeys[i] = (UNICODE)(ParseKeyString(line) & 0xFF); -#ifdef DEBUG - fprintf(stderr, "Special %i = %i\n", i, specialKeys[i]); -#endif - } - } - - // For each of two players - for (p = 0; p < 2; ++p) - { - int joyN = -1; - int joyThresh = 0; - memset(buf, 0xFF, sizeof(buf)); - // Read in 9 inputs - for (i = 0; i < 10; ++i) - { - // Look for valid lines - for (;;) - { - if (feof(fp) || ferror(fp)) - break; - fgets(line, 256, fp); - - if (line[0] != '#') - break; - } - // line now contains what should be a valid line - if (strstr(line, "'); - if (index2 != NULL) - strncpy(joy, index+1, index2 - (index + 1)); - } - else - { - joy[0] = 0; - } - buf[i] = ParseKeyString (line); -#ifdef DEBUG - fprintf(stderr, "Player %i, key %i = %i\n", p, i, buf[i]); -#endif - if (joy[0] != 0) - { - char type; - if (strchr(joy, '-') != NULL) - type = *(strchr(joy, '-') + 1); - else - type = 0; - - if (type == 'A') - { - int axis = atoi(strchr(joy, '-') + 2); - char sign = joy[strlen(joy)-1]; - int s; - if (sign == '+') - s = 1; - else if (sign == '-') - s = -1; - else - s = 1; - buf[9 + i] = JOYAXIS(axis, s); - } - else if (type == 'B') - { - int button = atoi(strchr(joy, '-') + 2); - buf[9 + i] = JOYBUTTON(button); - } - else if (type == 'C') - { - int b1 = atoi(strchr(joy, '-') + 2); - int b2 = atoi(strchr(joy, ',') + 1); - buf[9 + i] = JOYCHORD(b1, b2); - } - } - } - } - KeyboardInput[p] = CaptureInputDevice ( - CreateJoystickKeyboardDevice(buf[0], buf[1], buf[2], buf[3], buf[4], - buf[5], buf[6], buf[7], buf[8], buf[9]) - ); - if (joyN != -1) - { - JoystickInput[p] = CaptureInputDevice ( - CreateJoystickDevice(joyN, joyThresh, buf[10], buf[11], buf[12], - buf[13], buf[14], buf[15], buf[16], buf[17], buf[18], buf[19]) - ); - } - else - { - JoystickInput[p] = 0; - } - } - ArrowInput = KeyboardInput[0]; - (void) length; /* Satisfying compiler (unused parameter) */ - InitInput(PauseGame, specialKeys[0], specialKeys[1], specialKeys[2]); - return (NULL_HANDLE); -} - -static void -initKeyConfig(void) { - char userFile[PATH_MAX]; /* System-wide key config */ - FILE *fp; - int cb; - - cb = snprintf (userFile, PATH_MAX, "%skeys.cfg", configDir); - assert (cb != -1); - // Verified before: strlen (configDir) <= PATH_MAX - 13 - - if (fileExists (userFile)) { - fp = res_OpenResFile (userFile, "rt"); - } else { - if (copyFile ("starcon.key", userFile) == -1) { - fprintf(stderr, "Warning: Could not copy default key config " - "to %s: %s.\n", userFile, strerror (errno)); - } else - fprintf(stderr, "Copying default key config file to %s.\n", - userFile); - fp = res_OpenResFile ("starcon.key", "rt"); - } - LoadKeyConfig (fp, 0); - // second arg is file length, but is unused. - // It should be temporary anyhow. - res_CloseResFile (fp); -} - static void InitPlayerInput (void) { - INPUT_DEVICE InputDevice; - - SerialInput = CaptureInputDevice (CreateSerialKeyboardDevice ()); - - InputDevice = CreateInternalDevice (game_input); - NormalInput = CaptureInputDevice (InputDevice); - InputDevice = CreateInternalDevice (computer_intelligence); - ComputerInput = CaptureInputDevice (InputDevice); - InputDevice = CreateInternalDevice (combined_input0); - CombinedInput[0] = CaptureInputDevice (InputDevice); - InputDevice = CreateInternalDevice (combined_input1); - CombinedInput[1] = CaptureInputDevice (InputDevice); - -#if DEMO_MODE - InputDevice = CreateInternalDevice (demo_input); - DemoInput = CaptureInputDevice (InputDevice); -#endif /* DEMO_MODE */ + HumanInput[0] = p1_combat_summary; + HumanInput[1] = p2_combat_summary; + ComputerInput = computer_intelligence; } void UninitPlayerInput (void) { - COUNT which_player; - #if DEMO_MODE DestroyInputDevice (ReleaseInputDevice (DemoInput)); #endif /* DEMO_MODE */ - DestroyInputDevice (ReleaseInputDevice (ComputerInput)); - DestroyInputDevice (ReleaseInputDevice (NormalInput)); - - DestroyInputDevice (ReleaseInputDevice (ArrowInput)); - DestroyInputDevice (ReleaseInputDevice (SerialInput)); - for (which_player = 0; which_player < NUM_PLAYERS; ++which_player) - { - DestroyInputDevice (ReleaseInputDevice (JoystickInput[which_player])); - DestroyInputDevice (ReleaseInputDevice (KeyboardInput[which_player])); - DestroyInputDevice (ReleaseInputDevice (CombinedInput[which_player])); - } - - UninitInput (); } BOOLEAN @@ -370,10 +91,6 @@ LoadKernel (int argc, char *argv[]) return (FALSE); INIT_INSTANCES (); - InstallResTypeVectors (KEY_CONFIG, LoadKeyConfig, NULL_PTR); -// res_GetResource (JOYSTICK_KEYS); - initKeyConfig(); - { COLORMAP ColorMapTab; @@ -493,7 +210,7 @@ SetPlayerInput (void) else if (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE) { if (which_player == 0) - PlayerInput[which_player] = NormalInput; + PlayerInput[which_player] = HumanInput[0]; else { PlayerInput[which_player] = ComputerInput; @@ -501,7 +218,7 @@ SetPlayerInput (void) } } else - PlayerInput[which_player] = CombinedInput[which_player]; + PlayerInput[which_player] = HumanInput[which_player]; } } diff --git a/sc2/src/sc2code/ships/sis_ship/sis_ship.c b/sc2/src/sc2code/ships/sis_ship/sis_ship.c index e0534f1a8..78208b675 100644 --- a/sc2/src/sc2code/ships/sis_ship/sis_ship.c +++ b/sc2/src/sc2code/ships/sis_ship/sis_ship.c @@ -19,6 +19,7 @@ #include "reslib.h" #include "ships/sis_ship/resinst.h" #include "starcon.h" +#include "controls.h" #define MAX_TRACKING 3 #define MAX_DEFENSE 8 @@ -275,7 +276,7 @@ sis_hyper_postprocess (PELEMENT ElementPtr) GLOBAL (velocity) = ElementPtr->velocity; GetElementStarShip (ElementPtr, &StarShipPtr); - if ((StarShipPtr->cur_status_flags & WEAPON) + if (((StarShipPtr->cur_status_flags & WEAPON) || CurrentMenuState.cancel) && StarShipPtr->special_counter == 0) { #define MENU_DELAY 10 diff --git a/sc2/src/sc2code/shipyard.c b/sc2/src/sc2code/shipyard.c index 7d8049fe2..30e686a85 100644 --- a/sc2/src/sc2code/shipyard.c +++ b/sc2/src/sc2code/shipyard.c @@ -18,6 +18,7 @@ #include "starcon.h" #include "melee.h" +#include "controls.h" #include "libs/graphics/gfx_common.h" //Added by Chris @@ -600,12 +601,20 @@ CrewTransaction (SIZE crew_delta) * ships per row number must divide 0xf0 without remainder */ static BOOLEAN -DoModifyShips (INPUT_STATE InputState, PMENU_STATE pMS) +DoModifyShips (PMENU_STATE pMS) { #define MODIFY_CREW_FLAG (1 << 8) RECT r; HSTARSHIP hStarShip, hNextShip; SHIP_FRAGMENTPTR StarShipPtr; + BOOLEAN select, cancel; +#ifdef WANT_SHIP_SPINS + BOOLEAN special; + + special = CurrentMenuState.special; +#endif /* WANT_SHIP_SPINS */ + select = CurrentMenuState.select; + cancel = CurrentMenuState.cancel; if (GLOBAL (CurrentActivity) & CHECK_ABORT) { @@ -626,11 +635,13 @@ DoModifyShips (INPUT_STATE InputState, PMENU_STATE pMS) } else { - SBYTE dx, dy; + SBYTE dx = 0, dy = 0; BYTE NewState; - dx = GetInputXComponent (InputState); - dy = GetInputYComponent (InputState); + if (CurrentMenuState.right) dx = 1; + if (CurrentMenuState.left) dx = -1; + if (CurrentMenuState.up) dy = -1; + if (CurrentMenuState.down) dy = 1; NewState = pMS->CurState; if (pMS->delta_item & MODIFY_CREW_FLAG) { @@ -666,9 +677,9 @@ DoModifyShips (INPUT_STATE InputState, PMENU_STATE pMS) } #ifdef WANT_SHIP_SPINS - if ((InputState & (DEVICE_BUTTON1 | DEVICE_BUTTON2 | DEVICE_BUTTON3)) + if (select || cancel || special #else - if ((InputState & (DEVICE_BUTTON1 | DEVICE_BUTTON2)) + if (select || cancel #endif || NewState != pMS->CurState || ((pMS->delta_item & MODIFY_CREW_FLAG) && (dx || dy))) @@ -697,7 +708,7 @@ DoModifyShips (INPUT_STATE InputState, PMENU_STATE pMS) SetSemaphore (GraphicsSem); #ifdef WANT_SHIP_SPINS - if (InputState & DEVICE_BUTTON3) + if (special) { HSTARSHIP hSpinShip; @@ -716,9 +727,8 @@ DoModifyShips (INPUT_STATE InputState, PMENU_STATE pMS) } else #endif - if ((InputState & DEVICE_BUTTON1) - || ((pMS->delta_item & MODIFY_CREW_FLAG) - && (dx || dy || (InputState & DEVICE_BUTTON2)))) + if (select || ((pMS->delta_item & MODIFY_CREW_FLAG) + && (dx || dy || cancel))) { COUNT ShipCost[] = { @@ -737,13 +747,13 @@ DoModifyShips (INPUT_STATE InputState, PMENU_STATE pMS) DrawRaceStrings (0); return (TRUE); } - else if (InputState & DEVICE_BUTTON2) + else if (cancel) { pMS->delta_item ^= MODIFY_CREW_FLAG; SetFlashRect ((PRECT)~0L, (FRAME)0); DrawMenuStateStrings (PM_CREW, SHIPYARD_CREW); } - else if (InputState & DEVICE_BUTTON1) + else if (select) { Index = GetIndexFromStarShip ( &GLOBAL (avail_race_q), @@ -803,7 +813,7 @@ DoModifyShips (INPUT_STATE InputState, PMENU_STATE pMS) SetSemaphore (GraphicsSem); goto ChangeFlashRect; } - else if (InputState & (DEVICE_BUTTON1 | DEVICE_BUTTON2)) + else if (select || cancel) { if (!(pMS->delta_item ^= MODIFY_CREW_FLAG)) goto ChangeFlashRect; @@ -989,7 +999,7 @@ DoModifyShips (INPUT_STATE InputState, PMENU_STATE pMS) CrewTransaction (crew_delta); } } - else if (InputState & DEVICE_BUTTON2) + else if (cancel) { ClearSemaphore (GraphicsSem); @@ -1183,11 +1193,15 @@ EndHangarAnim (PMENU_STATE pMS) } BOOLEAN -DoShipyard (INPUT_STATE InputState, PMENU_STATE pMS) +DoShipyard (PMENU_STATE pMS) { + BOOLEAN select, cancel; if (GLOBAL (CurrentActivity) & CHECK_ABORT) goto ExitShipyard; + select = CurrentMenuState.select; + cancel = CurrentMenuState.cancel; + if (!pMS->Initialized) { pMS->InputFunc = DoShipyard; @@ -1260,9 +1274,7 @@ DoShipyard (INPUT_STATE InputState, PMENU_STATE pMS) pMS->Initialized = TRUE; } - else if ((InputState & DEVICE_BUTTON2) - || ((InputState & DEVICE_BUTTON1) - && pMS->CurState == SHIPYARD_EXIT)) + else if (cancel || (select && pMS->CurState == SHIPYARD_EXIT)) { ExitShipyard: SetSemaphore (GraphicsSem); @@ -1276,12 +1288,12 @@ ExitShipyard: return (FALSE); } - else if (InputState & DEVICE_BUTTON1) + else if (select) { if (pMS->CurState != SHIPYARD_SAVELOAD) { pMS->Initialized = FALSE; - DoModifyShips (InputState, pMS); + DoModifyShips (pMS); } else { @@ -1296,7 +1308,7 @@ ExitShipyard: } } else - DoMenuChooser (InputState, pMS, PM_CREW); + DoMenuChooser (pMS, PM_CREW); return (TRUE); } diff --git a/sc2/src/sc2code/sis.h b/sc2/src/sc2code/sis.h index cd34fd6d5..2bf48d88f 100644 --- a/sc2/src/sc2code/sis.h +++ b/sc2/src/sc2code/sis.h @@ -262,8 +262,7 @@ extern COUNT GetSBayCapacity (PPOINT ppt); extern DWORD GetFTankCapacity (PPOINT ppt); extern COUNT CountSISPieces (BYTE piece_type); -extern BOOLEAN DoMenuChooser (INPUT_STATE InputState, PMENU_STATE pMS, - BYTE BaseState); +extern BOOLEAN DoMenuChooser (PMENU_STATE pMS, BYTE BaseState); extern void DrawMenuStateStrings (BYTE beg_index, SWORD NewState); extern void DoMenuOptions (void); extern void DrawFlagshipName (BOOLEAN InStatusArea); diff --git a/sc2/src/sc2code/starbase.c b/sc2/src/sc2code/starbase.c index 052097760..7edb528b9 100644 --- a/sc2/src/sc2code/starbase.c +++ b/sc2/src/sc2code/starbase.c @@ -19,6 +19,7 @@ #include "starcon.h" #include "libs/graphics/gfx_common.h" #include "libs/tasklib.h" +#include "controls.h" PMENU_STATE pMenuState; @@ -271,7 +272,7 @@ s.origin.x = SAFE_X, s.origin.y = SAFE_Y + 4; } BOOLEAN -DoStarBase (INPUT_STATE InputState, PMENU_STATE pMS) +DoStarBase (PMENU_STATE pMS) { if (GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD)) { @@ -335,7 +336,7 @@ s.origin.x = SAFE_X, s.origin.y = SAFE_Y + 4; "rotate starbase"); ClearSemaphore (GraphicsSem); } - else if ((InputState & DEVICE_BUTTON1) + else if (CurrentMenuState.select || GET_GAME_STATE (MOONBASE_ON_SHIP) || GET_GAME_STATE (CHMMR_BOMB_STATE) == 2) { @@ -395,14 +396,12 @@ ExitStarBase: STARBASE_STATE NewState; NewState = pMS->CurState; - if (GetInputXComponent (InputState) < 0 - || GetInputYComponent (InputState) < 0) + if (CurrentMenuState.left || CurrentMenuState.up) { if (NewState-- == TALK_COMMANDER) NewState = DEPART_BASE; } - else if (GetInputXComponent (InputState) > 0 - || GetInputYComponent (InputState) > 0) + else if (CurrentMenuState.right || CurrentMenuState.down) { if (NewState++ == DEPART_BASE) NewState = TALK_COMMANDER; diff --git a/sc2/src/sc2code/starbase.h b/sc2/src/sc2code/starbase.h index 761c92d5c..5e7219134 100644 --- a/sc2/src/sc2code/starbase.h +++ b/sc2/src/sc2code/starbase.h @@ -34,8 +34,7 @@ typedef BYTE STARBASE_STATE; typedef struct menu_state { - BOOLEAN (*InputFunc) (INPUT_STATE InputState, struct menu_state - *pMS); + BOOLEAN (*InputFunc) (struct menu_state *pMS); COUNT MenuRepeatDelay; SIZE Initialized; @@ -48,10 +47,8 @@ typedef struct menu_state FRAME ModuleFrame; Task flash_task; - RECT flash_rect0, - flash_rect1; - FRAME flash_frame0, - flash_frame1; + RECT flash_rect0, flash_rect1; + FRAME flash_frame0, flash_frame1; MUSIC_REF hMusic; } MENU_STATE; @@ -60,9 +57,9 @@ typedef MENU_STATE *PMENU_STATE; extern PMENU_STATE pMenuState; extern void VisitStarBase (void); -extern BOOLEAN DoStarBase (INPUT_STATE InputState, PMENU_STATE pMS); -extern BOOLEAN DoOutfit (INPUT_STATE InputState, PMENU_STATE pMS); -extern BOOLEAN DoShipyard (INPUT_STATE InputState, PMENU_STATE pMS); +extern BOOLEAN DoStarBase (PMENU_STATE pMS); +extern BOOLEAN DoOutfit (PMENU_STATE pMS); +extern BOOLEAN DoShipyard (PMENU_STATE pMS); extern void DrawShipPiece (PMENU_STATE pMS, COUNT which_piece, COUNT which_slot, BOOLEAN DrawBluePrint); diff --git a/sc2/src/sc2code/starcon.h b/sc2/src/sc2code/starcon.h index 3a3abd3bc..90ef19b57 100644 --- a/sc2/src/sc2code/starcon.h +++ b/sc2/src/sc2code/starcon.h @@ -159,9 +159,6 @@ extern SIZE screen_width, screen_height; extern FRAME Screen, RadarFrame; extern FONT StarConFont, MicroFont, TinyFont; extern BOOLEAN PagingEnabled; -extern INPUT_REF ArrowInput, ComputerInput, NormalInput, SerialInput, - JoystickInput[NUM_PLAYERS], KeyboardInput[NUM_PLAYERS], - CombinedInput[NUM_PLAYERS], PlayerInput[NUM_PLAYERS]; extern FRAME ActivityFrame; extern SOUND MenuSounds, GameSounds; extern QUEUE race_q[NUM_PLAYERS]; @@ -184,17 +181,11 @@ extern void SetFlashRect (PRECT pRect, FRAME f); extern void DrawStarConBox (PRECT pRect, SIZE BorderWidth, COLOR TopLeftColor, COLOR BottomRightColor, BOOLEAN FillInterior, COLOR InteriorColor); -extern INPUT_STATE ConfirmExit (void); +extern BOOLEAN ConfirmExit (void); extern DWORD SeedRandomNumbers (void); extern BOOLEAN StarConDiskError (PSTR pFileName); extern void ReportDiskError (PSTR pFileName, DISK_ERROR ErrorCondition); extern void DoInput (PVOID pInputState); -extern INPUT_STATE game_input (INPUT_REF InputRef, INPUT_STATE - InputState); -extern INPUT_STATE combined_input0 (INPUT_REF InputRef, INPUT_STATE - InputState); -extern INPUT_STATE combined_input1 (INPUT_REF InputRef, INPUT_STATE - InputState); extern BOOLEAN Battle (void); extern void EncounterBattle (void); extern void SetPlayerInput (void); @@ -230,6 +221,7 @@ extern DRAWABLE CreatePixmapRegion (FRAME Frame, PPOINT pOrg, SIZE width, extern void SetPrimNextLink (PPRIMITIVE pPrim, COUNT Link); extern COUNT GetPrimNextLink (PPRIMITIVE pPrim); +extern volatile BOOLEAN GamePaused, GameExiting, ExitRequested; //Added by Chris diff --git a/sc2/src/sc2code/utils.c b/sc2/src/sc2code/utils.c index fdad6ee12..f0f1705c6 100644 --- a/sc2/src/sc2code/utils.c +++ b/sc2/src/sc2code/utils.c @@ -20,6 +20,7 @@ #include "commglue.h" #include "comm.h" #include "libs/sound/trackplayer.h" +#include "controls.h" void DrawStarConBox (PRECT pRect, SIZE BorderWidth, COLOR TopLeftColor, COLOR @@ -107,7 +108,7 @@ SeedRandomNumbers (void) void WaitForNoInput (SIZE Duration) { - INPUT_STATE PressState; + BOOLEAN PressState; PressState = AnyButtonPress (FALSE); if (Duration < 0) @@ -121,7 +122,7 @@ WaitForNoInput (SIZE Duration) { DWORD TimeOut; - INPUT_STATE ButtonState; + BOOLEAN ButtonState; TimeOut = GetTimeCounter () + Duration; do @@ -177,15 +178,17 @@ PauseGame (void) FlushGraphics (); //SetSemaphore (GraphicsSem); - while (KeyDown (PauseKey)) + while (ImmediateInputState.pause) TaskSwitch (); - FlushInput (); - - // Wait for the pause key to be pressed again - while (!KeyDown (PauseKey)) + while (!ImmediateInputState.pause) TaskSwitch (); + while (ImmediateInputState.pause) + TaskSwitch (); + + GamePaused = FALSE; + s.frame = F; DrawStamp (&s); DestroyDrawable (ReleaseDrawable (s.frame));