diff --git a/sc2/src/sc2code/controls.h b/sc2/src/sc2code/controls.h index 13350c18c..f4df34bfd 100644 --- a/sc2/src/sc2code/controls.h +++ b/sc2/src/sc2code/controls.h @@ -20,6 +20,7 @@ #define _CONTROLS_H_ #include "libs/compiler.h" +#include "libs/strlib.h" // Enumerated type for controls @@ -115,6 +116,10 @@ typedef struct textentry_state BOOLEAN Initialized; BOOLEAN Success; // edit confirmed or canceled UNICODE *CacheStr; // cached copy to revert immediate changes + STRING JoyAlphaString; // joystick alphabet definition + BOOLEAN JoystickMode; // TRUE when doing joystick input + BOOLEAN UpperRegister; // TRUE when entering Caps + UNICODE *JoyAlphaStr; // joystick alphabet // 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 diff --git a/sc2/src/sc2code/gameopt.c b/sc2/src/sc2code/gameopt.c index 1900db196..e2d49c062 100644 --- a/sc2/src/sc2code/gameopt.c +++ b/sc2/src/sc2code/gameopt.c @@ -205,8 +205,12 @@ FeedbackQuit (BYTE which_setting) UnlockMutex (GraphicsLock); } +#define DDSHS_NORMAL 0 +#define DDSHS_EDIT 1 +#define DDSHS_BLOCKCUR 2 + static BOOLEAN -DrawDescriptionString (PMENU_STATE pMS, COUNT which_string, SIZE state) +DrawDescriptionString (PMENU_STATE pMS, COUNT which_string, COUNT state) { COUNT rel_index; RECT r; @@ -255,8 +259,10 @@ DrawDescriptionString (PMENU_STATE pMS, COUNT which_string, SIZE state) lf.pStr = ((GAME_DESC *)pMS->CurString)[rel_index]; lf.CharCount = (COUNT)~0; - if (state <= 0) + if (!(state & DDSHS_EDIT)) { // normal state + SetFlashRect ((PRECT)~0L, (FRAME)0); + if (pMS->InputFunc == DoNaming) { if (pMS->CurState == CHANGE_CAPTAIN_SETTING) @@ -269,7 +275,9 @@ DrawDescriptionString (PMENU_STATE pMS, COUNT which_string, SIZE state) } } else - { + { // XXX: remnants of DOS? this function is never actually + // called outside DoNaming nowadays, which makes this + // code utterly dead if (state == 0) { COLOR OldColor; @@ -280,8 +288,6 @@ DrawDescriptionString (PMENU_STATE pMS, COUNT which_string, SIZE state) } font_DrawText (&lf); } - SetFlashRect (&r, (FRAME)0); - SetFlashRect ((PRECT)~0L, (FRAME)0); } else { // editing state @@ -307,17 +313,27 @@ DrawDescriptionString (PMENU_STATE pMS, COUNT which_string, SIZE state) text_r.corner.x += (SIZE)*pchar_deltas++; 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 */ + + if (state & DDSHS_BLOCKCUR) + { // Use block cursor for keyboardless systems + if ((COUNT)pMS->first_item.x == lf.CharCount) + { // cursor at end-line -- use insertion point text_r.extent.width = 1; + } + else if ((COUNT)pMS->first_item.x + 1 == lf.CharCount) + { // extra pixel for last char margin + text_r.extent.width = (SIZE)*pchar_deltas + 2; + } else - text_r.extent.width = (SIZE)*pchar_deltas; + { // normal mid-line char + text_r.extent.width = (SIZE)*pchar_deltas + 1; + } } -#endif + else + { // Insertion point cursor + text_r.extent.width = 1; + } + text_r.corner.y = r.corner.y; text_r.extent.height = r.extent.height; SetContextForeGroundColor (BLACK_COLOR); @@ -337,8 +353,13 @@ static BOOLEAN OnNameChange (PTEXTENTRY_STATE pTES) { PMENU_STATE pMS = (PMENU_STATE) pTES->CbParam; + COUNT hl = DDSHS_EDIT; + pMS->first_item.x = pTES->InsPt - pTES->BaseStr; - return DrawDescriptionString (pMS, 0, 1); + if (pTES->JoystickMode) + hl |= DDSHS_BLOCKCUR; + + return DrawDescriptionString (pMS, 0, hl); } static BOOLEAN @@ -363,7 +384,7 @@ DoNaming (PMENU_STATE pMS) // XXX: nasty hack; CurString may not be large enough to // contain a pointer on some platforms pMS->CurString = (STRING)buf; - DrawDescriptionString (pMS, 0, 1); + DrawDescriptionString (pMS, 0, DDSHS_EDIT); LockMutex (GraphicsLock); DrawStatusMessage (GAME_STRING (NAMING_STRING_BASE + 0)); @@ -391,7 +412,7 @@ DoNaming (PMENU_STATE pMS) wstrcpy (Setting, buf); else wstrcpy (buf, Setting); - DrawDescriptionString (pMS, 0, 0); + DrawDescriptionString (pMS, 0, DDSHS_NORMAL); SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT); diff --git a/sc2/src/sc2code/getchar.c b/sc2/src/sc2code/getchar.c index 02c3cf494..92b90b96f 100644 --- a/sc2/src/sc2code/getchar.c +++ b/sc2/src/sc2code/getchar.c @@ -23,72 +23,10 @@ #include "globdata.h" #include "sounds.h" #include "settings.h" +#include "resinst.h" +#include "nameref.h" -static UWORD cur_char = ' '; - -void -SetJoystickChar (UWORD which_char) -{ - if (!isalnum (cur_char = which_char)) - cur_char = ' '; -} - -UWORD -GetJoystickChar (void) -{ - int dy; - UWORD old_char; - - if (PulsedInputState.key[KEY_MENU_SELECT]) - return ('\n'); - else if (PulsedInputState.key[KEY_MENU_CANCEL]) - return (0x1B); - else if (PulsedInputState.key[KEY_MENU_SPECIAL]) - return (0x7F); - - old_char = cur_char; - dy = 0; - if (PulsedInputState.key[KEY_MENU_UP]) dy = -1; - else if (PulsedInputState.key[KEY_MENU_DOWN]) dy = 1; - if (dy) - { - if (cur_char == ' ') - { - if (dy > 0) - cur_char = 'a'; - else /* if (dy < 0) */ - cur_char = '9'; - } - else if (isdigit (cur_char)) - { - cur_char += dy; - if (cur_char < '0') - cur_char = 'z'; - else if (cur_char > '9') - cur_char = ' '; - } - else if (!isalpha (cur_char += dy)) - { - cur_char -= dy; - if (cur_char == 'a' || cur_char == 'A') - cur_char = ' '; - else - cur_char = '0'; - } - } - - if ((PulsedInputState.key[KEY_MENU_PAGE_UP] || PulsedInputState.key[KEY_MENU_PAGE_DOWN]) && isalpha (cur_char)) - { - if (islower (cur_char)) - cur_char = toupper (cur_char); - else - cur_char = tolower (cur_char); - } - - return (cur_char == old_char ? 0 : cur_char); -} - BOOLEAN DoTextEntry (PTEXTENTRY_STATE pTES) { @@ -108,11 +46,18 @@ DoTextEntry (PTEXTENTRY_STATE pTES) pTES->CacheStr = HMalloc (pTES->MaxSize); pTES->Success = FALSE; pTES->Initialized = TRUE; + pTES->JoystickMode = FALSE; + pTES->UpperRegister = TRUE; + pTES->JoyAlphaString = CaptureStringTable ( + LoadStringTable (JOYSTICK_ALPHA_STRTAB)); + pTES->JoyAlphaStr = GetStringAddress ( + SetAbsStringTableIndex (pTES->JoyAlphaString, 0)); DoInput (pTES, TRUE); if (pTES->CacheStr) HFree (pTES->CacheStr); + DestroyStringTable ( ReleaseStringTable (pTES->JoyAlphaString)); return pTES->Success; } @@ -125,8 +70,15 @@ DoTextEntry (PTEXTENTRY_STATE pTES) pTES->CacheStr[pTES->MaxSize - 1] = '\0'; // process the pending character buffer - while (ch = GetNextCharacter ()) + ch = GetNextCharacter (); + if (!ch && PulsedInputState.key[KEY_CHARACTER]) + { // keyboard repeat, but only when buffer empty + ch = GetLastCharacter (); + } + while (ch) { + pTES->JoystickMode = FALSE; + if (isprint (ch) && (pStr + len - pTES->BaseStr + 1 < pTES->MaxSize)) { memmove (pStr + 1, pStr, (len + 1) * sizeof (*pStr)); @@ -135,22 +87,9 @@ DoTextEntry (PTEXTENTRY_STATE pTES) ++len; changed = TRUE; } + ch = GetNextCharacter (); } - 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) @@ -202,13 +141,86 @@ DoTextEntry (PTEXTENTRY_STATE pTES) changed = TRUE; } } - else if (PulsedInputState.key[KEY_MENU_UP]) - { - // do joystick text - } - else if (PulsedInputState.key[KEY_MENU_DOWN]) - { - // do joystick text + + if (pTES->JoyAlphaStr && ( + PulsedInputState.key[KEY_MENU_UP] || + PulsedInputState.key[KEY_MENU_DOWN] || + PulsedInputState.key[KEY_MENU_PAGE_UP] || + PulsedInputState.key[KEY_MENU_PAGE_DOWN]) ) + { // do joystick text + UNICODE newch; + UNICODE cmpch; + int i; + + pTES->JoystickMode = TRUE; + + if (len) + ch = *pStr; + else + ch = pTES->JoyAlphaStr[0]; + + newch = ch; + cmpch = toupper (ch); + + // find current char in the alphabet + for (i = 0; pTES->JoyAlphaStr[i] != cmpch + && pTES->JoyAlphaStr[i] != '\0'; ++i) + ; + + if (PulsedInputState.key[KEY_MENU_UP]) + { + --i; + if (i < 0) + i = wstrlen (pTES->JoyAlphaStr) - 1; + newch = pTES->JoyAlphaStr[i]; + } + else if (PulsedInputState.key[KEY_MENU_DOWN]) + { + ++i; + if (i >= (int)wstrlen(pTES->JoyAlphaStr)) + newch = pTES->JoyAlphaStr[0]; + else + newch = pTES->JoyAlphaStr[i]; + } + + if (PulsedInputState.key[KEY_MENU_PAGE_UP] || + PulsedInputState.key[KEY_MENU_PAGE_DOWN]) + { + if (len) + { // single char change + if (islower (newch)) + newch = toupper (newch); + else + newch = tolower (newch); + } + else + { // register change + pTES->UpperRegister = !pTES->UpperRegister; + } + } + else + { // check register + if (pTES->UpperRegister) + newch = toupper (newch); + else + newch = tolower (newch); + } + + if (newch != ch) + { + if (len) + { // change current + pStr[0] = newch; + changed = TRUE; + } + else if (pStr + len - pTES->BaseStr + 1 < pTES->MaxSize) + { // append + pStr[0] = newch; + pStr[1] = '\0'; + ++len; + changed = TRUE; + } + } } if (PulsedInputState.key[KEY_MENU_SELECT]) diff --git a/sc2/src/sc2code/istrtab.h b/sc2/src/sc2code/istrtab.h index bd4fae813..ff6e3b4f2 100644 --- a/sc2/src/sc2code/istrtab.h +++ b/sc2/src/sc2code/istrtab.h @@ -100,4 +100,5 @@ #define INTROPRES_STRTAB 0x23c06204L #define FINALPRES_STRTAB 0x23e06304L #define CREDITS_STRTAB 0x24206404L +#define JOYSTICK_ALPHA_STRTAB 0x24406504L diff --git a/sc2/src/sc2code/melee.c b/sc2/src/sc2code/melee.c index 15c2bace7..82df6f001 100644 --- a/sc2/src/sc2code/melee.c +++ b/sc2/src/sc2code/melee.c @@ -138,10 +138,19 @@ PMELEE_STATE volatile pMeleeState; static BOOLEAN DoMelee (PMELEE_STATE pMS); static BOOLEAN DoEdit (PMELEE_STATE pMS); static BOOLEAN DoPickShip (PMELEE_STATE pMS); + +#define DTSHS_NORMAL 0 +#define DTSHS_EDIT 1 +#define DTSHS_SELECTED 2 +#define DTSHS_REPAIR 4 +#define DTSHS_BLOCKCUR 8 + static BOOLEAN DrawTeamString (PMELEE_STATE pMS, COUNT HiLiteState); + static BOOLEAN DoLoadTeam (PMELEE_STATE pMS); static void DrawFileStrings (PMELEE_STATE pMS, int HiLiteState); + static void DrawMeleeIcon (COUNT which_icon) { @@ -310,7 +319,7 @@ RepairMeleeFrame (PRECT pRect) DrawShipBox (pMeleeState, FALSE); } - DrawTeamString (pMeleeState, 0); + DrawTeamString (pMeleeState, DTSHS_NORMAL); } pMeleeState->side = old_side; pMeleeState->row = old_row; @@ -337,15 +346,12 @@ DrawTeamString (PMELEE_STATE pMS, COUNT HiLiteState) + ((MELEE_BOX_HEIGHT + MELEE_BOX_SPACE) * NUM_MELEE_ROWS + 2)); r.extent.width = NUM_MELEE_COLUMNS * (MELEE_BOX_WIDTH + MELEE_BOX_SPACE); r.extent.height = 13; - if (HiLiteState == 4) + if (HiLiteState == DTSHS_REPAIR) { RepairMeleeFrame (&r); return (TRUE); } - if (HiLiteState & 1) - r.extent.width -= 29; - SetContextFont (MicroFont); lfText.pStr = pMS->TeamImage[pMS->side].TeamName; @@ -356,7 +362,7 @@ DrawTeamString (PMELEE_STATE pMS, COUNT HiLiteState) lfText.CharCount = wstrlen (lfText.pStr); // (COUNT)~0; BatchGraphics (); - if (!(HiLiteState & 1)) + if (!(HiLiteState & DTSHS_EDIT)) { // normal or selected state TEXT rtText; UNICODE buf[10]; @@ -368,7 +374,7 @@ DrawTeamString (PMELEE_STATE pMS, COUNT HiLiteState) rtText.baseline.y = lfText.baseline.y; rtText.baseline.x = lfText.baseline.x + r.extent.width - 1; - SetContextForeGroundColor (HiLiteState == 0 + SetContextForeGroundColor (!(HiLiteState & DTSHS_SELECTED) ? TEAM_NAME_TEXT_COLOR : TEAM_NAME_EDIT_TEXT_COLOR); font_DrawText (&lfText); font_DrawText (&rtText); @@ -380,6 +386,9 @@ DrawTeamString (PMELEE_STATE pMS, COUNT HiLiteState) BYTE char_deltas[MAX_TEAM_CHARS]; PBYTE pchar_deltas; + // not drawing team bucks + r.extent.width -= 29; + 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 @@ -397,19 +406,28 @@ 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 (pMS->CurIndex < lfText.CharCount) /* end of line */ + if (pMS->CurIndex < lfText.CharCount) /* cursor mid-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 */ + if (HiLiteState & DTSHS_BLOCKCUR) + { // Use block cursor for keyboardless systems + if (pMS->CurIndex == lfText.CharCount) + { // cursor at end-line -- use insertion point text_r.extent.width = 1; + } + else if (pMS->CurIndex + 1 == lfText.CharCount) + { // extra pixel for last char margin + text_r.extent.width = (SIZE)*pchar_deltas + 2; + } else - text_r.extent.width = (SIZE)*pchar_deltas; + { // normal mid-line char + text_r.extent.width = (SIZE)*pchar_deltas + 1; + } } -#endif + else + { // Insertion point cursor + text_r.extent.width = 1; + } + // position cursor within input field rect ++text_r.corner.x; ++text_r.corner.y; text_r.extent.height -= 2; @@ -490,7 +508,7 @@ Deselect (BYTE opt) if (pMeleeState->row < NUM_MELEE_ROWS) DrawShipBox (pMeleeState, FALSE); else if (pMeleeState->CurIndex == (BYTE)~0) - DrawTeamString (pMeleeState, 0); + DrawTeamString (pMeleeState, DTSHS_NORMAL); } else if (pMeleeState->InputFunc == DoPickShip) { @@ -536,7 +554,7 @@ Select (BYTE opt) if (pMeleeState->row < NUM_MELEE_ROWS) DrawShipBox (pMeleeState, TRUE); else if (pMeleeState->CurIndex == (BYTE)~0) - DrawTeamString (pMeleeState, 2); + DrawTeamString (pMeleeState, DTSHS_SELECTED); } else if (pMeleeState->InputFunc == DoPickShip) { @@ -1113,7 +1131,7 @@ DeleteCurrentShip (PMELEE_STATE pMS) GetShipBox (&r, pMS->side, pMS->row, pMS->col); RepairMeleeFrame (&r); - DrawTeamString (pMS, 4); + DrawTeamString (pMS, DTSHS_REPAIR); UnlockMutex (GraphicsLock); } @@ -1138,11 +1156,14 @@ OnTeamNameChange (PTEXTENTRY_STATE pTES) { PMELEE_STATE pMS = (PMELEE_STATE) pTES->CbParam; BOOLEAN ret; + COUNT hl = DTSHS_EDIT; pMS->CurIndex = pTES->InsPt - pTES->BaseStr; + if (pTES->JoystickMode) + hl |= DTSHS_BLOCKCUR; LockMutex (GraphicsLock); - ret = DrawTeamString (pMS, 1); + ret = DrawTeamString (pMS, hl); UnlockMutex (GraphicsLock); return ret; @@ -1209,7 +1230,7 @@ DoEdit (PMELEE_STATE pMS) // CurIndex to contain the current cursor position pMS->CurIndex = 0; LockMutex (GraphicsLock); - DrawTeamString (pMS, 1); /* draw input state */ + DrawTeamString (pMS, DTSHS_EDIT); UnlockMutex (GraphicsLock); tes.Initialized = FALSE; @@ -1223,7 +1244,7 @@ DoEdit (PMELEE_STATE pMS) // done entering pMS->CurIndex = (BYTE)~0; LockMutex (GraphicsLock); - DrawTeamString (pMS, 4); /* draw normal state */ + DrawTeamString (pMS, DTSHS_REPAIR); UnlockMutex (GraphicsLock); return (TRUE); @@ -1346,7 +1367,7 @@ DoPickShip (PMELEE_STATE pMS) pMS->TeamImage[pMS->side].ShipList[pMS->row][pMS->col] = pMS->CurIndex; LockMutex (GraphicsLock); - DrawTeamString (pMS, 4); + DrawTeamString (pMS, DTSHS_REPAIR); DrawShipBox (pMS, FALSE); UnlockMutex (GraphicsLock); AdvanceCursor (pMS); diff --git a/sc2/src/sc2code/respkg.h b/sc2/src/sc2code/respkg.h index 7c13adf9b..5f00c580f 100644 --- a/sc2/src/sc2code/respkg.h +++ b/sc2/src/sc2code/respkg.h @@ -307,5 +307,6 @@ enum FINAL_PACKAGE, CREDIT_FONTS_PACKAGE, CREDITS_PACKAGE, + JOYSTICK_ALPHA_PACKAGE, };