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:
avolkov
2005-12-31 17:21:05 +00:00
parent 00e32acfa2
commit 6fffcf9366
8 changed files with 377 additions and 489 deletions
+29
View File
@@ -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
+4 -1
View File
@@ -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
View File
@@ -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);
}
+157
View File
@@ -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;
}
+3 -39
View File
@@ -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 */
+63 -159
View File
@@ -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
@@ -256,37 +279,54 @@ 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
View File
@@ -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);
}
}
+1 -4
View File
@@ -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);