Universal text input, stage 1; universal DoTextEntry() with key-repeat, folded into DoInput() domain; removed old serial keyboard code; removed some hacks
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@2143 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -55,9 +55,14 @@ enum {
|
||||
KEY_MENU_SPECIAL,
|
||||
KEY_MENU_PAGE_UP,
|
||||
KEY_MENU_PAGE_DOWN,
|
||||
KEY_MENU_HOME,
|
||||
KEY_MENU_END,
|
||||
KEY_MENU_ZOOM_IN,
|
||||
KEY_MENU_ZOOM_OUT,
|
||||
KEY_MENU_DELETE,
|
||||
KEY_MENU_BACKSPACE,
|
||||
KEY_MENU_EDIT_CANCEL,
|
||||
KEY_CHARACTER, /* abstract char key */
|
||||
NUM_KEYS
|
||||
};
|
||||
|
||||
@@ -100,6 +105,30 @@ BATTLE_INPUT_STATE p2_combat_summary (void);
|
||||
|
||||
extern volatile BOOLEAN GamePaused, ExitRequested;
|
||||
|
||||
typedef struct textentry_state
|
||||
{
|
||||
// standard state required by DoInput
|
||||
BOOLEAN (*InputFunc) (struct textentry_state *pTES);
|
||||
COUNT MenuRepeatDelay;
|
||||
|
||||
// these are semi-private read-only
|
||||
BOOLEAN Initialized;
|
||||
BOOLEAN Success; // edit confirmed or canceled
|
||||
UNICODE *CacheStr; // cached copy to revert immediate changes
|
||||
// these are public and must be set before calling DoTextEntry
|
||||
UNICODE *BaseStr; // set to string to edit
|
||||
UNICODE *InsPt; // set to curremt pos of insertion point
|
||||
int MaxSize; // set to max size of edited string
|
||||
|
||||
BOOLEAN (*ChangeCallback) (struct textentry_state *pTES);
|
||||
// returns TRUE if last change is OK
|
||||
void *CbParam; // callback parameter, use as you like
|
||||
|
||||
} TEXTENTRY_STATE;
|
||||
typedef TEXTENTRY_STATE *PTEXTENTRY_STATE;
|
||||
|
||||
BOOLEAN DoTextEntry (PTEXTENTRY_STATE pTES);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -192,7 +192,9 @@ UpdateInputState (void)
|
||||
int i;
|
||||
for (i = 0; i < NUM_KEYS; i++)
|
||||
{
|
||||
_check_for_pulse(&PulsedInputState.key[i], &CachedInputState.key[i], &OldInputState.key[i], &RepeatDelays.key[i], &NewTime, &Times.key[i]);
|
||||
_check_for_pulse (&PulsedInputState.key[i],
|
||||
&CachedInputState.key[i], &OldInputState.key[i],
|
||||
&RepeatDelays.key[i], &NewTime, &Times.key[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,6 +272,7 @@ DoInput (PVOID pInputState, BOOLEAN resetInput)
|
||||
if (PulsedInputState.key[KEY_MENU_PAGE_UP]) input |= MENU_SOUND_PAGEUP;
|
||||
if (PulsedInputState.key[KEY_MENU_PAGE_DOWN]) input |= MENU_SOUND_PAGEDOWN;
|
||||
if (PulsedInputState.key[KEY_MENU_DELETE]) input |= MENU_SOUND_DELETE;
|
||||
if (PulsedInputState.key[KEY_MENU_BACKSPACE]) input |= MENU_SOUND_DELETE;
|
||||
|
||||
if (MenuSounds
|
||||
&& (pSolarSysState == 0
|
||||
|
||||
+54
-163
@@ -43,7 +43,6 @@
|
||||
#define MAX_SAVED_GAMES 50
|
||||
#define SUMMARY_X_OFFS 14
|
||||
#define SUMMARY_SIDE_OFFS 7
|
||||
#define MAX_NAME_CHARS 15
|
||||
#define SAVES_PER_PAGE 5
|
||||
|
||||
static BOOLEAN DoSettings (PMENU_STATE pMS);
|
||||
@@ -225,7 +224,7 @@ DrawDescriptionString (PMENU_STATE pMS, COUNT which_string, SIZE state)
|
||||
r.extent.height = SHIP_NAME_HEIGHT;
|
||||
|
||||
SetContext (StatusContext);
|
||||
if (pMS->delta_item == CHANGE_CAPTAIN_SETTING)
|
||||
if (pMS->CurState == CHANGE_CAPTAIN_SETTING)
|
||||
{
|
||||
Font = TinyFont;
|
||||
r.corner.y = 10;
|
||||
@@ -251,14 +250,16 @@ DrawDescriptionString (PMENU_STATE pMS, COUNT which_string, SIZE state)
|
||||
}
|
||||
|
||||
SetContextFont (Font);
|
||||
// XXX: nasty hack; CurString may not be large enough to
|
||||
// contain a pointer on some platforms
|
||||
lf.pStr = ((GAME_DESC *)pMS->CurString)[rel_index];
|
||||
lf.CharCount = (COUNT)~0;
|
||||
|
||||
if (state <= 0)
|
||||
{
|
||||
{ // normal state
|
||||
if (pMS->InputFunc == DoNaming)
|
||||
{
|
||||
if (pMS->delta_item == CHANGE_CAPTAIN_SETTING)
|
||||
if (pMS->CurState == CHANGE_CAPTAIN_SETTING)
|
||||
DrawCaptainsName ();
|
||||
else
|
||||
{
|
||||
@@ -283,7 +284,7 @@ DrawDescriptionString (PMENU_STATE pMS, COUNT which_string, SIZE state)
|
||||
SetFlashRect ((PRECT)~0L, (FRAME)0);
|
||||
}
|
||||
else
|
||||
{
|
||||
{ // editing state
|
||||
COUNT i;
|
||||
RECT text_r;
|
||||
BYTE char_deltas[MAX_DESC_CHARS];
|
||||
@@ -291,8 +292,10 @@ DrawDescriptionString (PMENU_STATE pMS, COUNT which_string, SIZE state)
|
||||
|
||||
TextRect (&lf, &text_r, char_deltas);
|
||||
if ((text_r.extent.width + 2) >= r.extent.width)
|
||||
{
|
||||
{ // the text does not fit the input box size and so
|
||||
// will not fit when displayed later
|
||||
UnlockMutex (GraphicsLock);
|
||||
// disallow the change
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
@@ -330,183 +333,71 @@ DrawDescriptionString (PMENU_STATE pMS, COUNT which_string, SIZE state)
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static UWORD
|
||||
DoTextEntry (PMENU_STATE pMS)
|
||||
static BOOLEAN
|
||||
OnNameChange (PTEXTENTRY_STATE pTES)
|
||||
{
|
||||
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));
|
||||
}
|
||||
else
|
||||
{
|
||||
extern UWORD GetJoystickChar (INPUT_STATE InputState);
|
||||
|
||||
ch = GetJoystickChar ();
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
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:
|
||||
if (isprint (ch) && (len + (pStr - pBaseStr) < MAX_NAME_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)
|
||||
{
|
||||
if (!DrawDescriptionString (pMS, pMS->CurState, 1))
|
||||
{
|
||||
len = wstrlen (pStr);
|
||||
memmove (pStr - 1, pStr, (len + 1) * sizeof (*pStr));
|
||||
--pMS->first_item.x;
|
||||
}
|
||||
}
|
||||
else if (left)
|
||||
{
|
||||
if (pMS->first_item.x)
|
||||
{
|
||||
--pMS->first_item.x;
|
||||
DrawDescriptionString (pMS, pMS->CurState, 1);
|
||||
}
|
||||
}
|
||||
else if (right)
|
||||
{
|
||||
if (len)
|
||||
{
|
||||
++pMS->first_item.x;
|
||||
DrawDescriptionString (pMS, pMS->CurState, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return (ch);
|
||||
PMENU_STATE pMS = (PMENU_STATE) pTES->CbParam;
|
||||
pMS->first_item.x = pTES->InsPt - pTES->BaseStr;
|
||||
return DrawDescriptionString (pMS, 0, 1);
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
DoNaming (PMENU_STATE pMS)
|
||||
{
|
||||
if (GLOBAL (CurrentActivity) & CHECK_ABORT)
|
||||
return (FALSE);
|
||||
GAME_DESC buf;
|
||||
TEXTENTRY_STATE tes;
|
||||
UNICODE *Setting;
|
||||
|
||||
if (!pMS->Initialized)
|
||||
{
|
||||
GAME_DESC GD[1];
|
||||
|
||||
pMS->Initialized = 1;
|
||||
pMS->Initialized = TRUE;
|
||||
pMS->InputFunc = DoNaming;
|
||||
|
||||
GD[0][0] = '\0';
|
||||
pMS->delta_item = pMS->CurState;
|
||||
pMS->first_item.x = pMS->first_item.y = 0;
|
||||
pMS->CurState = 0;
|
||||
pMS->CurString = (STRING)&GD[0];
|
||||
DrawDescriptionString (pMS, pMS->CurState, 1);
|
||||
buf[0] = '\0';
|
||||
// XXX: this code abuses MENU_STATE struct members to store
|
||||
// some values:
|
||||
// first_item.x - current cursor position
|
||||
// first_item.y - must be set to 0; DrawDescriptionString()
|
||||
// treats it as base index into array of strings
|
||||
// supplied in CurString
|
||||
pMS->first_item.x = 0;
|
||||
pMS->first_item.y = 0;
|
||||
// XXX: nasty hack; CurString may not be large enough to
|
||||
// contain a pointer on some platforms
|
||||
pMS->CurString = (STRING)buf;
|
||||
DrawDescriptionString (pMS, 0, 1);
|
||||
|
||||
LockMutex (GraphicsLock);
|
||||
DrawStatusMessage (GAME_STRING (NAMING_STRING_BASE + 0));
|
||||
UnlockMutex (GraphicsLock);
|
||||
|
||||
EnableCharacterMode ();
|
||||
DoInput (pMS, TRUE);
|
||||
DisableCharacterMode ();
|
||||
if (pMS->CurState == CHANGE_CAPTAIN_SETTING)
|
||||
{
|
||||
Setting = GLOBAL_SIS (CommanderName);
|
||||
tes.MaxSize = sizeof (GLOBAL_SIS (CommanderName));
|
||||
}
|
||||
else
|
||||
{
|
||||
Setting = GLOBAL_SIS (ShipName);
|
||||
tes.MaxSize = sizeof (GLOBAL_SIS (ShipName));
|
||||
}
|
||||
|
||||
// text entry setup
|
||||
tes.Initialized = FALSE;
|
||||
tes.MenuRepeatDelay = 0;
|
||||
tes.BaseStr = buf;
|
||||
tes.CbParam = pMS;
|
||||
tes.ChangeCallback = OnNameChange;
|
||||
|
||||
if (DoTextEntry (&tes))
|
||||
wstrcpy (Setting, buf);
|
||||
else
|
||||
wstrcpy (buf, Setting);
|
||||
DrawDescriptionString (pMS, 0, 0);
|
||||
|
||||
SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT);
|
||||
|
||||
pMS->InputFunc = DoSettings;
|
||||
pMS->CurState = (BYTE)pMS->delta_item;
|
||||
pMS->delta_item = 0;
|
||||
if (!(GLOBAL (CurrentActivity) & CHECK_ABORT))
|
||||
FeedbackSetting (pMS->CurState);
|
||||
}
|
||||
else
|
||||
{
|
||||
UWORD ch;
|
||||
|
||||
if (pMS->Initialized == 1)
|
||||
{
|
||||
FlushInput ();
|
||||
pMS->Initialized = 2;
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
ch = DoTextEntry (pMS);
|
||||
|
||||
if (ch == '\n' || ch == '\r' || ch == 0x1B)
|
||||
{
|
||||
if (ch == '\n' || ch == '\r')
|
||||
{
|
||||
if (pMS->delta_item == CHANGE_CAPTAIN_SETTING)
|
||||
wstrcpy (GLOBAL_SIS (CommanderName),
|
||||
(const UNICODE *)((GAME_DESC *)pMS->CurString)[0]);
|
||||
else
|
||||
wstrcpy (GLOBAL_SIS (ShipName),
|
||||
(const UNICODE *)((GAME_DESC *)pMS->CurString)[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pMS->delta_item == CHANGE_CAPTAIN_SETTING)
|
||||
wstrcpy ((UNICODE *)((GAME_DESC *)pMS->CurString)[0],
|
||||
GLOBAL_SIS (CommanderName));
|
||||
else
|
||||
wstrcpy ((UNICODE *)((GAME_DESC *)pMS->CurString)[0],
|
||||
GLOBAL_SIS (ShipName));
|
||||
}
|
||||
|
||||
DrawDescriptionString (pMS, pMS->CurState, 0);
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,11 @@
|
||||
|
||||
#include <ctype.h>
|
||||
#include "controls.h"
|
||||
#include "libs/inplib.h"
|
||||
#include "libs/misc.h"
|
||||
#include "globdata.h"
|
||||
#include "sounds.h"
|
||||
#include "settings.h"
|
||||
|
||||
|
||||
static UWORD cur_char = ' ';
|
||||
@@ -83,3 +88,155 @@ GetJoystickChar (void)
|
||||
|
||||
return (cur_char == old_char ? 0 : cur_char);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
DoTextEntry (PTEXTENTRY_STATE pTES)
|
||||
{
|
||||
UNICODE ch;
|
||||
UNICODE *pStr;
|
||||
UNICODE *CacheInsPt;
|
||||
int len;
|
||||
BOOLEAN changed = FALSE;
|
||||
|
||||
if (GLOBAL (CurrentActivity) & CHECK_ABORT)
|
||||
return (FALSE);
|
||||
|
||||
if (!pTES->Initialized)
|
||||
{ // init basic vars
|
||||
pTES->InputFunc = DoTextEntry;
|
||||
pTES->InsPt = pTES->BaseStr;
|
||||
pTES->CacheStr = HMalloc (pTES->MaxSize);
|
||||
pTES->Success = FALSE;
|
||||
pTES->Initialized = TRUE;
|
||||
|
||||
DoInput (pTES, TRUE);
|
||||
|
||||
if (pTES->CacheStr)
|
||||
HFree (pTES->CacheStr);
|
||||
|
||||
return pTES->Success;
|
||||
}
|
||||
|
||||
pStr = pTES->InsPt;
|
||||
len = wstrlen (pStr);
|
||||
// save a copy of string
|
||||
CacheInsPt = pTES->InsPt;
|
||||
wstrncpy (pTES->CacheStr, pTES->BaseStr, pTES->MaxSize - 1);
|
||||
pTES->CacheStr[pTES->MaxSize - 1] = '\0';
|
||||
|
||||
// process the pending character buffer
|
||||
while (ch = GetNextCharacter ())
|
||||
{
|
||||
if (isprint (ch) && (pStr + len - pTES->BaseStr + 1 < pTES->MaxSize))
|
||||
{
|
||||
memmove (pStr + 1, pStr, (len + 1) * sizeof (*pStr));
|
||||
*pStr = ch;
|
||||
++pStr;
|
||||
++len;
|
||||
changed = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!changed && PulsedInputState.key[KEY_CHARACTER])
|
||||
{ // keyboard repeat, but only when buffer empty
|
||||
ch = GetLastCharacter ();
|
||||
if (ch && isprint (ch) &&
|
||||
(pStr + len - pTES->BaseStr + 1 < pTES->MaxSize))
|
||||
{
|
||||
memmove (pStr + 1, pStr, (len + 1) * sizeof (*pStr));
|
||||
*pStr = ch;
|
||||
++pStr;
|
||||
++len;
|
||||
changed = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (PulsedInputState.key[KEY_MENU_DELETE])
|
||||
{
|
||||
if (len)
|
||||
{
|
||||
memmove (pStr, pStr + 1, len * sizeof (*pStr));
|
||||
--len;
|
||||
changed = TRUE;
|
||||
}
|
||||
}
|
||||
else if (PulsedInputState.key[KEY_MENU_BACKSPACE])
|
||||
{
|
||||
if (pStr > pTES->BaseStr)
|
||||
{
|
||||
memmove (pStr - 1, pStr, (len + 1) * sizeof (*pStr));
|
||||
--pStr;
|
||||
--len;
|
||||
changed = TRUE;
|
||||
}
|
||||
}
|
||||
else if (PulsedInputState.key[KEY_MENU_LEFT])
|
||||
{
|
||||
if (pStr > pTES->BaseStr)
|
||||
{
|
||||
--pStr;
|
||||
changed = TRUE;
|
||||
}
|
||||
}
|
||||
else if (PulsedInputState.key[KEY_MENU_RIGHT])
|
||||
{
|
||||
if (len > 0)
|
||||
{
|
||||
++pStr;
|
||||
changed = TRUE;
|
||||
}
|
||||
}
|
||||
else if (PulsedInputState.key[KEY_MENU_HOME])
|
||||
{
|
||||
if (pStr > pTES->BaseStr)
|
||||
{
|
||||
pStr = pTES->BaseStr;
|
||||
changed = TRUE;
|
||||
}
|
||||
}
|
||||
else if (PulsedInputState.key[KEY_MENU_END])
|
||||
{
|
||||
if (len > 0)
|
||||
{
|
||||
pStr += len;
|
||||
changed = TRUE;
|
||||
}
|
||||
}
|
||||
else if (PulsedInputState.key[KEY_MENU_UP])
|
||||
{
|
||||
// do joystick text
|
||||
}
|
||||
else if (PulsedInputState.key[KEY_MENU_DOWN])
|
||||
{
|
||||
// do joystick text
|
||||
}
|
||||
|
||||
if (PulsedInputState.key[KEY_MENU_SELECT])
|
||||
{ // done entering
|
||||
pTES->Success = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
else if (PulsedInputState.key[KEY_MENU_EDIT_CANCEL])
|
||||
{ // canceled entering
|
||||
pTES->Success = FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pTES->InsPt = pStr;
|
||||
|
||||
if (changed && pTES->ChangeCallback)
|
||||
{
|
||||
if (!pTES->ChangeCallback (pTES))
|
||||
{ // changes not accepted - revert
|
||||
wstrncpy (pTES->BaseStr, pTES->CacheStr, pTES->MaxSize - 1);
|
||||
pTES->BaseStr[pTES->MaxSize - 1] = '\0';
|
||||
pTES->InsPt = CacheInsPt;
|
||||
|
||||
PlaySoundEffect (SetAbsSoundIndex (MenuSounds, 2),
|
||||
0, NotPositional (), NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,48 +23,11 @@
|
||||
|
||||
typedef DWORD INPUT_STATE;
|
||||
|
||||
/* Serial Keyboard Pseudo UNICODE Equivalents */
|
||||
#define SK_DELETE ((UNICODE)127)
|
||||
#define SK_LF_ARROW ((UNICODE)128)
|
||||
#define SK_RT_ARROW ((UNICODE)129)
|
||||
#define SK_UP_ARROW ((UNICODE)130)
|
||||
#define SK_DN_ARROW ((UNICODE)131)
|
||||
#define SK_HOME ((UNICODE)132)
|
||||
#define SK_PAGE_UP ((UNICODE)133)
|
||||
#define SK_END ((UNICODE)134)
|
||||
#define SK_PAGE_DOWN ((UNICODE)135)
|
||||
#define SK_INSERT ((UNICODE)136)
|
||||
#define SK_KEYPAD_PLUS ((UNICODE)137)
|
||||
#define SK_KEYPAD_MINUS ((UNICODE)138)
|
||||
|
||||
#define SK_LF_SHIFT ((UNICODE)139)
|
||||
#define SK_RT_SHIFT ((UNICODE)140)
|
||||
#define SK_LF_CTL ((UNICODE)141)
|
||||
#define SK_RT_CTL ((UNICODE)142)
|
||||
#define SK_LF_ALT ((UNICODE)143)
|
||||
#define SK_RT_ALT ((UNICODE)144)
|
||||
|
||||
#define SK_F1 ((UNICODE)145)
|
||||
#define SK_F2 ((UNICODE)146)
|
||||
#define SK_F3 ((UNICODE)147)
|
||||
#define SK_F4 ((UNICODE)148)
|
||||
#define SK_F5 ((UNICODE)149)
|
||||
#define SK_F6 ((UNICODE)150)
|
||||
#define SK_F7 ((UNICODE)151)
|
||||
#define SK_F8 ((UNICODE)152)
|
||||
#define SK_F9 ((UNICODE)153)
|
||||
#define SK_F10 ((UNICODE)154)
|
||||
#define SK_F11 ((UNICODE)155)
|
||||
#define SK_F12 ((UNICODE)156)
|
||||
|
||||
extern BOOLEAN InitInput (void);
|
||||
extern BOOLEAN UninitInput (void);
|
||||
extern BOOLEAN AnyButtonPress (BOOLEAN DetectSpecial);
|
||||
|
||||
extern void FlushInput (void);
|
||||
extern BOOLEAN KeyDown (UNICODE which_scan);
|
||||
extern UNICODE GetUnicodeKey (void);
|
||||
extern UNICODE KBDToUNICODE (UWORD which_key);
|
||||
|
||||
/*
|
||||
* Not used right now
|
||||
@@ -79,8 +42,9 @@ extern volatile int MouseButtonDown;
|
||||
|
||||
void EnableCharacterMode (void);
|
||||
void DisableCharacterMode (void);
|
||||
UNICODE GetCharacter (void);
|
||||
UNICODE GetNextCharacter (void);
|
||||
UNICODE GetLastCharacter (void);
|
||||
|
||||
|
||||
#endif /* _INPLIB_H */
|
||||
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#define KBDBUFSIZE (1 << 8)
|
||||
static int kbdhead=0, kbdtail=0;
|
||||
static UNICODE kbdbuf[KBDBUFSIZE];
|
||||
static UNICODE lastchar;
|
||||
static int kbdstate[SDLK_LAST];
|
||||
|
||||
static BOOLEAN InputInitialized = FALSE;
|
||||
UWORD UNICODEToKBD (UNICODE which_key);
|
||||
@@ -49,9 +51,13 @@ static VControl_NameBinding control_names[] = {
|
||||
{ "Menu-Special", (int *)&ImmediateInputState.key[KEY_MENU_SPECIAL] },
|
||||
{ "Menu-Page-Up", (int *)&ImmediateInputState.key[KEY_MENU_PAGE_UP] },
|
||||
{ "Menu-Page-Down", (int *)&ImmediateInputState.key[KEY_MENU_PAGE_DOWN] },
|
||||
{ "Menu-Home", (int *)&ImmediateInputState.key[KEY_MENU_HOME] },
|
||||
{ "Menu-End", (int *)&ImmediateInputState.key[KEY_MENU_END] },
|
||||
{ "Menu-Zoom-In", (int *)&ImmediateInputState.key[KEY_MENU_ZOOM_IN] },
|
||||
{ "Menu-Zoom-Out", (int *)&ImmediateInputState.key[KEY_MENU_ZOOM_OUT] },
|
||||
{ "Menu-Delete", (int *)&ImmediateInputState.key[KEY_MENU_DELETE] },
|
||||
{ "Menu-Backspace", (int *)&ImmediateInputState.key[KEY_MENU_BACKSPACE] },
|
||||
{ "Menu-Edit-Cancel", (int *)&ImmediateInputState.key[KEY_MENU_EDIT_CANCEL] },
|
||||
{ "Player-1-Thrust", (int *)&ImmediateInputState.key[KEY_P1_THRUST] },
|
||||
{ "Player-1-Left", (int *)&ImmediateInputState.key[KEY_P1_LEFT] },
|
||||
{ "Player-1-Right", (int *)&ImmediateInputState.key[KEY_P1_RIGHT] },
|
||||
@@ -152,6 +158,13 @@ initKeyConfig(void) {
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static void
|
||||
resetKeyboardState (void)
|
||||
{
|
||||
memset (kbdstate, 0, sizeof (kbdstate));
|
||||
ImmediateInputState.key[KEY_CHARACTER] = 0;
|
||||
}
|
||||
|
||||
int
|
||||
TFB_InitInput (int driver, int flags)
|
||||
{
|
||||
@@ -184,6 +197,7 @@ TFB_InitInput (int driver, int flags)
|
||||
}
|
||||
|
||||
_in_character_mode = FALSE;
|
||||
resetKeyboardState ();
|
||||
|
||||
/* Prepare the Virtual Controller system. */
|
||||
VControl_Init ();
|
||||
@@ -204,34 +218,43 @@ TFB_UninitInput (void)
|
||||
VControl_Uninit ();
|
||||
}
|
||||
|
||||
// XXX: not currently used -- character mode is always on
|
||||
void
|
||||
EnableCharacterMode (void)
|
||||
{
|
||||
kbdhead = kbdtail = 0;
|
||||
lastchar = 0;
|
||||
_in_character_mode = TRUE;
|
||||
VControl_ResetInput ();
|
||||
|
||||
}
|
||||
|
||||
// XXX: not currently used -- character mode is always on
|
||||
void
|
||||
DisableCharacterMode (void)
|
||||
{
|
||||
VControl_ResetInput ();
|
||||
_in_character_mode = FALSE;
|
||||
kbdhead = kbdtail = 0;
|
||||
lastchar = 0;
|
||||
}
|
||||
|
||||
UNICODE
|
||||
GetCharacter (void)
|
||||
GetNextCharacter (void)
|
||||
{
|
||||
UNICODE result;
|
||||
while (kbdhead == kbdtail)
|
||||
TaskSwitch ();
|
||||
if (kbdhead == kbdtail)
|
||||
return 0;
|
||||
result = kbdbuf[kbdhead];
|
||||
kbdhead = (kbdhead + 1) & (KBDBUFSIZE - 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
UNICODE
|
||||
GetLastCharacter (void)
|
||||
{
|
||||
return lastchar;
|
||||
}
|
||||
|
||||
volatile int MouseButtonDown = 0;
|
||||
|
||||
void
|
||||
@@ -252,41 +275,58 @@ ProcessMouseEvent (const SDL_Event *e)
|
||||
|
||||
|
||||
void
|
||||
ProcessInputEvent(const SDL_Event *Event)
|
||||
ProcessInputEvent (const SDL_Event *Event)
|
||||
{
|
||||
if (!InputInitialized)
|
||||
return;
|
||||
ProcessMouseEvent (Event);
|
||||
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);
|
||||
|
||||
ProcessMouseEvent (Event);
|
||||
VControl_HandleEvent (Event);
|
||||
|
||||
{ // process character input event, if any
|
||||
SDLKey k = Event->key.keysym.sym;
|
||||
UNICODE map_key = (UNICODE) Event->key.keysym.unicode;
|
||||
|
||||
if (Event->type == SDL_KEYDOWN)
|
||||
{
|
||||
// dont care about the non-printable, non-char
|
||||
if (!map_key)
|
||||
return;
|
||||
|
||||
kbdstate[k]++;
|
||||
ImmediateInputState.key[KEY_CHARACTER]++;
|
||||
|
||||
lastchar = map_key;
|
||||
kbdbuf[kbdtail] = map_key;
|
||||
kbdtail = (kbdtail + 1) & (KBDBUFSIZE - 1);
|
||||
if (kbdtail == kbdhead)
|
||||
kbdhead = (kbdhead + 1) & (KBDBUFSIZE - 1);
|
||||
}
|
||||
else if (Event->type == SDL_KEYUP)
|
||||
{
|
||||
if (kbdstate[k] == 0)
|
||||
{ // something is fishy -- better to reset the
|
||||
// repeatable state to avoid big problems
|
||||
ImmediateInputState.key[KEY_CHARACTER] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
kbdstate[k]--;
|
||||
if (ImmediateInputState.key[KEY_CHARACTER] > 0)
|
||||
ImmediateInputState.key[KEY_CHARACTER]--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TFB_ResetControls (void)
|
||||
{
|
||||
VControl_ResetInput ();
|
||||
resetKeyboardState ();
|
||||
// flush character buffer
|
||||
kbdhead = kbdtail = 0;
|
||||
lastchar = 0;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -296,140 +336,4 @@ FlushInput (void)
|
||||
FlushInputState ();
|
||||
}
|
||||
|
||||
// Translates from SDLKeys to values defined in inplib.h
|
||||
UNICODE
|
||||
KBDToUNICODE (UWORD SK_in)
|
||||
{
|
||||
switch (SK_in)
|
||||
{
|
||||
case SDLK_KP_ENTER:
|
||||
case SDLK_RETURN:
|
||||
return '\n';
|
||||
case SDLK_KP4:
|
||||
case SDLK_LEFT:
|
||||
return (SK_LF_ARROW);
|
||||
case SDLK_KP6:
|
||||
case SDLK_RIGHT:
|
||||
return (SK_RT_ARROW);
|
||||
case SDLK_KP8:
|
||||
case SDLK_UP:
|
||||
return (SK_UP_ARROW);
|
||||
case SDLK_KP2:
|
||||
case SDLK_DOWN:
|
||||
return (SK_DN_ARROW);
|
||||
case SDLK_KP7:
|
||||
case SDLK_HOME:
|
||||
return (SK_HOME);
|
||||
case SDLK_KP9:
|
||||
case SDLK_PAGEUP:
|
||||
return (SK_PAGE_UP);
|
||||
case SDLK_KP1:
|
||||
case SDLK_END:
|
||||
return (SK_END);
|
||||
case SDLK_KP3:
|
||||
case SDLK_PAGEDOWN:
|
||||
return (SK_PAGE_DOWN);
|
||||
case SDLK_KP0:
|
||||
case SDLK_INSERT:
|
||||
return (SK_INSERT);
|
||||
case SDLK_KP_PERIOD:
|
||||
case SDLK_DELETE:
|
||||
return (SK_DELETE);
|
||||
case SDLK_KP_PLUS:
|
||||
return (SK_KEYPAD_PLUS);
|
||||
case SDLK_KP_MINUS:
|
||||
return (SK_KEYPAD_MINUS);
|
||||
case SDLK_LSHIFT:
|
||||
return (SK_LF_SHIFT);
|
||||
case SDLK_RSHIFT:
|
||||
return (SK_RT_SHIFT);
|
||||
case SDLK_LCTRL:
|
||||
return (SK_LF_CTL);
|
||||
case SDLK_RCTRL:
|
||||
return (SK_RT_CTL);
|
||||
case SDLK_LALT:
|
||||
return (SK_LF_ALT);
|
||||
case SDLK_RALT:
|
||||
return (SK_RT_ALT);
|
||||
case SDLK_F1:
|
||||
case SDLK_F2:
|
||||
case SDLK_F3:
|
||||
case SDLK_F4:
|
||||
case SDLK_F5:
|
||||
case SDLK_F6:
|
||||
case SDLK_F7:
|
||||
case SDLK_F8:
|
||||
case SDLK_F9:
|
||||
case SDLK_F10:
|
||||
case SDLK_F11:
|
||||
case SDLK_F12:
|
||||
return ((UNICODE) ((SK_in - SDLK_F1) + SK_F1));
|
||||
default:
|
||||
return (UNICODE)SK_in;
|
||||
}
|
||||
}
|
||||
|
||||
// Translates from values defined in inplib.h to SDLKey values
|
||||
UWORD
|
||||
UNICODEToKBD (UNICODE which_key)
|
||||
{
|
||||
switch (which_key)
|
||||
{
|
||||
case '\r':
|
||||
case '\n':
|
||||
return SDLK_RETURN;
|
||||
case SK_LF_ARROW:
|
||||
return SDLK_LEFT;
|
||||
case SK_RT_ARROW:
|
||||
return SDLK_RIGHT;
|
||||
case SK_UP_ARROW:
|
||||
return SDLK_UP;
|
||||
case SK_DN_ARROW:
|
||||
return SDLK_DOWN;
|
||||
case SK_HOME:
|
||||
return SDLK_HOME;
|
||||
case SK_PAGE_UP:
|
||||
return SDLK_PAGEUP;
|
||||
case SK_END:
|
||||
return SDLK_END;
|
||||
case SK_PAGE_DOWN:
|
||||
return SDLK_PAGEDOWN;
|
||||
case SK_INSERT:
|
||||
return SDLK_INSERT;
|
||||
case SK_DELETE:
|
||||
return SDLK_DELETE;
|
||||
case SK_KEYPAD_PLUS:
|
||||
return SDLK_KP_PLUS;
|
||||
case SK_KEYPAD_MINUS:
|
||||
return SDLK_KP_MINUS;
|
||||
case SK_LF_SHIFT:
|
||||
return SDLK_LSHIFT;
|
||||
case SK_RT_SHIFT:
|
||||
return SDLK_RSHIFT;
|
||||
case SK_LF_CTL:
|
||||
return SDLK_LCTRL;
|
||||
case SK_RT_CTL:
|
||||
return SDLK_RCTRL;
|
||||
case SK_LF_ALT:
|
||||
return SDLK_LALT;
|
||||
case SK_RT_ALT:
|
||||
return SDLK_RALT;
|
||||
case SK_F1:
|
||||
case SK_F2:
|
||||
case SK_F3:
|
||||
case SK_F4:
|
||||
case SK_F5:
|
||||
case SK_F6:
|
||||
case SK_F7:
|
||||
case SK_F8:
|
||||
case SK_F9:
|
||||
case SK_F10:
|
||||
case SK_F11:
|
||||
case SK_F12:
|
||||
return (which_key - SK_F1) + SDLK_F1;
|
||||
default:
|
||||
return which_key;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+52
-109
@@ -138,7 +138,7 @@ PMELEE_STATE volatile pMeleeState;
|
||||
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 DrawTeamString (PMELEE_STATE pMS, COUNT HiLiteState);
|
||||
static BOOLEAN DoLoadTeam (PMELEE_STATE pMS);
|
||||
static void DrawFileStrings (PMELEE_STATE pMS, int HiLiteState);
|
||||
|
||||
@@ -326,7 +326,7 @@ RepairMeleeFrame (PRECT pRect)
|
||||
SetContext (OldContext);
|
||||
}
|
||||
|
||||
static void
|
||||
static BOOLEAN
|
||||
DrawTeamString (PMELEE_STATE pMS, COUNT HiLiteState)
|
||||
{
|
||||
RECT r;
|
||||
@@ -340,7 +340,7 @@ DrawTeamString (PMELEE_STATE pMS, COUNT HiLiteState)
|
||||
if (HiLiteState == 4)
|
||||
{
|
||||
RepairMeleeFrame (&r);
|
||||
return;
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
if (HiLiteState & 1)
|
||||
@@ -357,7 +357,7 @@ DrawTeamString (PMELEE_STATE pMS, COUNT HiLiteState)
|
||||
|
||||
BatchGraphics ();
|
||||
if (!(HiLiteState & 1))
|
||||
{
|
||||
{ // normal or selected state
|
||||
TEXT rtText;
|
||||
UNICODE buf[10];
|
||||
|
||||
@@ -374,18 +374,26 @@ DrawTeamString (PMELEE_STATE pMS, COUNT HiLiteState)
|
||||
font_DrawText (&rtText);
|
||||
}
|
||||
else
|
||||
{
|
||||
{ // editing state
|
||||
COUNT i;
|
||||
RECT text_r;
|
||||
BYTE char_deltas[MAX_TEAM_CHARS];
|
||||
PBYTE pchar_deltas;
|
||||
|
||||
TextRect (&lfText, &text_r, char_deltas);
|
||||
if ((text_r.extent.width + 2) >= r.extent.width)
|
||||
{ // the text does not fit the input box size and so
|
||||
// will not fit when displayed later
|
||||
UnbatchGraphics ();
|
||||
// disallow the change
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
text_r = r;
|
||||
SetContextForeGroundColor (TEAM_NAME_EDIT_RECT_COLOR);
|
||||
DrawFilledRectangle (&text_r);
|
||||
|
||||
// calculate the cursor position and draw it
|
||||
pchar_deltas = char_deltas;
|
||||
for (i = pMS->CurIndex; i > 0; --i)
|
||||
text_r.corner.x += (SIZE)*pchar_deltas++;
|
||||
@@ -412,6 +420,8 @@ DrawTeamString (PMELEE_STATE pMS, COUNT HiLiteState)
|
||||
font_DrawText (&lfText);
|
||||
}
|
||||
UnbatchGraphics ();
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -988,88 +998,6 @@ DoLoadTeam (PMELEE_STATE pMS)
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
// XXX: TODO: to be merged with DoTextEntry in gameopt.c
|
||||
static UWORD
|
||||
DoTextEntry (PMELEE_STATE pMS)
|
||||
{
|
||||
UWORD ch;
|
||||
UNICODE *pStr, *pBaseStr;
|
||||
COUNT len, max_chars;
|
||||
BOOLEAN left = FALSE, right = FALSE;
|
||||
|
||||
if (pMS->MeleeOption == EDIT_MELEE)
|
||||
{
|
||||
pBaseStr = pMS->TeamImage[pMS->side].TeamName;
|
||||
max_chars = MAX_TEAM_CHARS;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Should not happen. Satisfying compiler.
|
||||
return 0;
|
||||
}
|
||||
|
||||
ch = GetCharacter ();
|
||||
|
||||
pStr = &pBaseStr[pMS->CurIndex];
|
||||
len = wstrlen (pStr);
|
||||
switch (ch)
|
||||
{
|
||||
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:
|
||||
if (isprint (ch) && (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 (left)
|
||||
{
|
||||
if (pMS->CurIndex)
|
||||
{
|
||||
--pMS->CurIndex;
|
||||
DrawTeamString (pMS, 1);
|
||||
}
|
||||
}
|
||||
else if (right)
|
||||
{
|
||||
if (len)
|
||||
{
|
||||
++pMS->CurIndex;
|
||||
DrawTeamString (pMS, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return (ch);
|
||||
}
|
||||
|
||||
static int
|
||||
WriteTeamImage (TEAM_IMAGE *pTI, uio_Stream *save_fp)
|
||||
{
|
||||
@@ -1205,6 +1133,21 @@ AdvanceCursor (PMELEE_STATE pMS)
|
||||
}
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
OnTeamNameChange (PTEXTENTRY_STATE pTES)
|
||||
{
|
||||
PMELEE_STATE pMS = (PMELEE_STATE) pTES->CbParam;
|
||||
BOOLEAN ret;
|
||||
|
||||
pMS->CurIndex = pTES->InsPt - pTES->BaseStr;
|
||||
|
||||
LockMutex (GraphicsLock);
|
||||
ret = DrawTeamString (pMS, 1);
|
||||
UnlockMutex (GraphicsLock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
DoEdit (PMELEE_STATE pMS)
|
||||
{
|
||||
@@ -1257,32 +1200,32 @@ DoEdit (PMELEE_STATE pMS)
|
||||
|
||||
if (row == NUM_MELEE_ROWS)
|
||||
{
|
||||
if (pMS->CurIndex != (BYTE)~0)
|
||||
{
|
||||
UNICODE ch;
|
||||
LockMutex (GraphicsLock);
|
||||
if (pMS->Initialized == 1)
|
||||
{
|
||||
FlushInput ();
|
||||
pMS->Initialized = 2;
|
||||
}
|
||||
else if (((ch = DoTextEntry (pMS)) == '\n') || (ch == '\r'))
|
||||
{
|
||||
pMS->CurIndex = (BYTE)~0;
|
||||
DrawTeamString (pMS, 4);
|
||||
pMS->Initialized = 1;
|
||||
DisableCharacterMode ();
|
||||
}
|
||||
UnlockMutex (GraphicsLock);
|
||||
return (TRUE);
|
||||
}
|
||||
else if (PulsedInputState.key[KEY_MENU_SELECT])
|
||||
if (PulsedInputState.key[KEY_MENU_SELECT])
|
||||
{
|
||||
TEXTENTRY_STATE tes;
|
||||
|
||||
// going to enter text
|
||||
// XXX: CurIndex is abused here; DrawTeamString expects
|
||||
// CurIndex to contain the current cursor position
|
||||
pMS->CurIndex = 0;
|
||||
LockMutex (GraphicsLock);
|
||||
DrawTeamString (pMS, 1);
|
||||
DrawTeamString (pMS, 1); /* draw input state */
|
||||
UnlockMutex (GraphicsLock);
|
||||
EnableCharacterMode ();
|
||||
|
||||
tes.Initialized = FALSE;
|
||||
tes.MenuRepeatDelay = 0;
|
||||
tes.BaseStr = pMS->TeamImage[pMS->side].TeamName;
|
||||
tes.MaxSize = MAX_TEAM_CHARS + 1;
|
||||
tes.CbParam = pMS;
|
||||
tes.ChangeCallback = OnTeamNameChange;
|
||||
DoTextEntry (&tes);
|
||||
|
||||
// done entering
|
||||
pMS->CurIndex = (BYTE)~0;
|
||||
LockMutex (GraphicsLock);
|
||||
DrawTeamString (pMS, 4); /* draw normal state */
|
||||
UnlockMutex (GraphicsLock);
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -619,10 +619,7 @@ DoMoveCursor (PMENU_STATE pMS)
|
||||
pMS->MenuRepeatDelay = (COUNT)pMS->CurState;
|
||||
if (!pMS->Initialized)
|
||||
{
|
||||
pMS->Initialized = MAKE_WORD (
|
||||
KBDToUNICODE (SK_INSERT),
|
||||
KBDToUNICODE (SK_DELETE)
|
||||
);
|
||||
pMS->Initialized = TRUE;
|
||||
pMS->InputFunc = DoMoveCursor;
|
||||
|
||||
SetMenuRepeatDelay (MIN_ACCEL_DELAY, MAX_ACCEL_DELAY, STEP_ACCEL_DELAY, TRUE);
|
||||
|
||||
Reference in New Issue
Block a user