summaryrefslogtreecommitdiffstats
path: root/apps/plugins/sdl/progs/wolf3d/id_us_1.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/sdl/progs/wolf3d/id_us_1.c')
-rw-r--r--apps/plugins/sdl/progs/wolf3d/id_us_1.c789
1 files changed, 789 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/wolf3d/id_us_1.c b/apps/plugins/sdl/progs/wolf3d/id_us_1.c
new file mode 100644
index 0000000000..76b53f30f0
--- /dev/null
+++ b/apps/plugins/sdl/progs/wolf3d/id_us_1.c
@@ -0,0 +1,789 @@
+//
+// ID Engine
+// ID_US_1.c - User Manager - General routines
+// v1.1d1
+// By Jason Blochowiak
+// Hacked up for Catacomb 3D
+//
+
+//
+// This module handles dealing with user input & feedback
+//
+// Depends on: Input Mgr, View Mgr, some variables from the Sound, Caching,
+// and Refresh Mgrs, Memory Mgr for background save/restore
+//
+// Globals:
+// ingame - Flag set by game indicating if a game is in progress
+// loadedgame - Flag set if a game was loaded
+// PrintX, PrintY - Where the User Mgr will print (global coords)
+// WindowX,WindowY,WindowW,WindowH - The dimensions of the current
+// window
+//
+
+#include "wl_def.h"
+
+#pragma hdrstop
+
+#if _MSC_VER == 1200 // Visual C++ 6
+ #define vsnprintf _vsnprintf
+#endif
+
+// Global variables
+ word PrintX,PrintY;
+ word WindowX,WindowY,WindowW,WindowH;
+
+// Internal variables
+#define ConfigVersion 1
+
+static boolean US_Started;
+
+ void (*USL_MeasureString)(const char *,word *,word *) = VW_MeasurePropString;
+ void (*USL_DrawString)(const char *) = VWB_DrawPropString;
+
+ SaveGame Games[MaxSaveGames];
+ HighScore Scores[MaxScores] =
+ {
+ {"id software-'92",10000,1},
+ {"Adrian Carmack",10000,1},
+ {"John Carmack",10000,1},
+ {"Kevin Cloud",10000,1},
+ {"Tom Hall",10000,1},
+ {"John Romero",10000,1},
+ {"Jay Wilbur",10000,1},
+ };
+
+int rndindex = 0;
+
+static byte rndtable[] = {
+ 0, 8, 109, 220, 222, 241, 149, 107, 75, 248, 254, 140, 16, 66,
+ 74, 21, 211, 47, 80, 242, 154, 27, 205, 128, 161, 89, 77, 36,
+ 95, 110, 85, 48, 212, 140, 211, 249, 22, 79, 200, 50, 28, 188,
+ 52, 140, 202, 120, 68, 145, 62, 70, 184, 190, 91, 197, 152, 224,
+ 149, 104, 25, 178, 252, 182, 202, 182, 141, 197, 4, 81, 181, 242,
+ 145, 42, 39, 227, 156, 198, 225, 193, 219, 93, 122, 175, 249, 0,
+ 175, 143, 70, 239, 46, 246, 163, 53, 163, 109, 168, 135, 2, 235,
+ 25, 92, 20, 145, 138, 77, 69, 166, 78, 176, 173, 212, 166, 113,
+ 94, 161, 41, 50, 239, 49, 111, 164, 70, 60, 2, 37, 171, 75,
+ 136, 156, 11, 56, 42, 146, 138, 229, 73, 146, 77, 61, 98, 196,
+ 135, 106, 63, 197, 195, 86, 96, 203, 113, 101, 170, 247, 181, 113,
+ 80, 250, 108, 7, 255, 237, 129, 226, 79, 107, 112, 166, 103, 241,
+ 24, 223, 239, 120, 198, 58, 60, 82, 128, 3, 184, 66, 143, 224,
+ 145, 224, 81, 206, 163, 45, 63, 90, 168, 114, 59, 33, 159, 95,
+ 28, 139, 123, 98, 125, 196, 15, 70, 194, 253, 54, 14, 109, 226,
+ 71, 17, 161, 93, 186, 87, 244, 138, 20, 52, 123, 251, 26, 36,
+ 17, 46, 52, 231, 232, 76, 31, 221, 84, 37, 216, 165, 212, 106,
+ 197, 242, 98, 43, 39, 175, 254, 145, 190, 84, 118, 222, 187, 136,
+ 120, 163, 236, 249 };
+
+// Internal routines
+
+// Public routines
+
+///////////////////////////////////////////////////////////////////////////
+//
+// US_Startup() - Starts the User Mgr
+//
+///////////////////////////////////////////////////////////////////////////
+void US_Startup()
+{
+ if (US_Started)
+ return;
+
+ US_InitRndT(true); // Initialize the random number generator
+
+ US_Started = true;
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// US_Shutdown() - Shuts down the User Mgr
+//
+///////////////////////////////////////////////////////////////////////////
+void
+US_Shutdown(void)
+{
+ if (!US_Started)
+ return;
+
+ US_Started = false;
+}
+
+// Window/Printing routines
+
+///////////////////////////////////////////////////////////////////////////
+//
+// US_SetPrintRoutines() - Sets the routines used to measure and print
+// from within the User Mgr. Primarily provided to allow switching
+// between masked and non-masked fonts
+//
+///////////////////////////////////////////////////////////////////////////
+void
+US_SetPrintRoutines(void (*measure)(const char *,word *,word *),
+ void (*print)(const char *))
+{
+ USL_MeasureString = measure;
+ USL_DrawString = print;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// US_Print() - Prints a string in the current window. Newlines are
+// supported.
+//
+///////////////////////////////////////////////////////////////////////////
+void
+US_Print(const char *sorg)
+{
+ char c;
+ char *sstart = strdup(sorg);
+ char *s = sstart;
+ char *se;
+ word w,h;
+
+ while (*s)
+ {
+ se = s;
+ while ((c = *se)!=0 && (c != '\n'))
+ se++;
+ *se = '\0';
+
+ USL_MeasureString(s,&w,&h);
+ px = PrintX;
+ py = PrintY;
+ USL_DrawString(s);
+
+ s = se;
+ if (c)
+ {
+ *se = c;
+ s++;
+
+ PrintX = WindowX;
+ PrintY += h;
+ }
+ else
+ PrintX += w;
+ }
+ free(sstart);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// US_PrintUnsigned() - Prints an unsigned long
+//
+///////////////////////////////////////////////////////////////////////////
+void
+US_PrintUnsigned(longword n)
+{
+ char buffer[32];
+ sprintf(buffer, "%lu", n);
+
+ US_Print(buffer);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// US_PrintSigned() - Prints a signed long
+//
+///////////////////////////////////////////////////////////////////////////
+void
+US_PrintSigned(int32_t n)
+{
+ char buffer[32];
+
+ US_Print(ltoa(n,buffer,10));
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// USL_PrintInCenter() - Prints a string in the center of the given rect
+//
+///////////////////////////////////////////////////////////////////////////
+void
+USL_PrintInCenter(const char *s,Rect r)
+{
+ word w,h,
+ rw,rh;
+
+ USL_MeasureString(s,&w,&h);
+ rw = r.lr.x - r.ul.x;
+ rh = r.lr.y - r.ul.y;
+
+ px = r.ul.x + ((rw - w) / 2);
+ py = r.ul.y + ((rh - h) / 2);
+ USL_DrawString(s);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// US_PrintCentered() - Prints a string centered in the current window.
+//
+///////////////////////////////////////////////////////////////////////////
+void
+US_PrintCentered(const char *s)
+{
+ Rect r;
+
+ r.ul.x = WindowX;
+ r.ul.y = WindowY;
+ r.lr.x = r.ul.x + WindowW;
+ r.lr.y = r.ul.y + WindowH;
+
+ USL_PrintInCenter(s,r);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// US_CPrintLine() - Prints a string centered on the current line and
+// advances to the next line. Newlines are not supported.
+//
+///////////////////////////////////////////////////////////////////////////
+void
+US_CPrintLine(const char *s)
+{
+ word w,h;
+
+ USL_MeasureString(s,&w,&h);
+
+ if (w > WindowW)
+ Quit("US_CPrintLine() - String exceeds width");
+ px = WindowX + ((WindowW - w) / 2);
+ py = PrintY;
+ USL_DrawString(s);
+ PrintY += h;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// US_CPrint() - Prints a string centered in the current window.
+// Newlines are supported.
+//
+///////////////////////////////////////////////////////////////////////////
+void
+US_CPrint(const char *sorg)
+{
+ char c;
+ char *sstart = strdup(sorg);
+ char *s = sstart;
+ char *se;
+
+ while (*s)
+ {
+ se = s;
+ while ((c = *se)!=0 && (c != '\n'))
+ se++;
+ *se = '\0';
+
+ US_CPrintLine(s);
+
+ s = se;
+ if (c)
+ {
+ *se = c;
+ s++;
+ }
+ }
+ free(sstart);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// US_Printf() - Prints a formatted string in the current window.
+// Newlines are supported.
+//
+///////////////////////////////////////////////////////////////////////////
+
+void US_Printf(const char *formatStr, ...)
+{
+ char strbuf[256];
+ va_list vlist;
+ va_start(vlist, formatStr);
+ int len = vsnprintf(strbuf, sizeof(strbuf), formatStr, vlist);
+ va_end(vlist);
+ if(len <= -1 || len >= sizeof(strbuf))
+ strbuf[sizeof(strbuf) - 1] = 0;
+ US_Print(strbuf);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// US_CPrintf() - Prints a formatted string centered in the current window.
+// Newlines are supported.
+//
+///////////////////////////////////////////////////////////////////////////
+
+void US_CPrintf(const char *formatStr, ...)
+{
+ char strbuf[256];
+ va_list vlist;
+ va_start(vlist, formatStr);
+ int len = vsnprintf(strbuf, sizeof(strbuf), formatStr, vlist);
+ va_end(vlist);
+ if(len <= -1 || len >= sizeof(strbuf))
+ strbuf[sizeof(strbuf) - 1] = 0;
+ US_CPrint(strbuf);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// US_ClearWindow() - Clears the current window to white and homes the
+// cursor
+//
+///////////////////////////////////////////////////////////////////////////
+void
+US_ClearWindow(void)
+{
+ VWB_Bar(WindowX,WindowY,WindowW,WindowH,WHITE);
+ PrintX = WindowX;
+ PrintY = WindowY;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// US_DrawWindow() - Draws a frame and sets the current window parms
+//
+///////////////////////////////////////////////////////////////////////////
+void
+US_DrawWindow(word x,word y,word w,word h)
+{
+ word i,
+ sx,sy,sw,sh;
+
+ WindowX = x * 8;
+ WindowY = y * 8;
+ WindowW = w * 8;
+ WindowH = h * 8;
+
+ PrintX = WindowX;
+ PrintY = WindowY;
+
+ sx = (x - 1) * 8;
+ sy = (y - 1) * 8;
+ sw = (w + 1) * 8;
+ sh = (h + 1) * 8;
+
+ US_ClearWindow();
+
+ VWB_DrawTile8(sx,sy,0),VWB_DrawTile8(sx,sy + sh,5);
+ for (i = sx + 8;i <= sx + sw - 8;i += 8)
+ VWB_DrawTile8(i,sy,1),VWB_DrawTile8(i,sy + sh,6);
+ VWB_DrawTile8(i,sy,2),VWB_DrawTile8(i,sy + sh,7);
+
+ for (i = sy + 8;i <= sy + sh - 8;i += 8)
+ VWB_DrawTile8(sx,i,3),VWB_DrawTile8(sx + sw,i,4);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// US_CenterWindow() - Generates a window of a given width & height in the
+// middle of the screen
+//
+///////////////////////////////////////////////////////////////////////////
+void
+US_CenterWindow(word w,word h)
+{
+ US_DrawWindow(((MaxX / 8) - w) / 2,((MaxY / 8) - h) / 2,w,h);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// US_SaveWindow() - Saves the current window parms into a record for
+// later restoration
+//
+///////////////////////////////////////////////////////////////////////////
+void
+US_SaveWindow(WindowRec *win)
+{
+ win->x = WindowX;
+ win->y = WindowY;
+ win->w = WindowW;
+ win->h = WindowH;
+
+ win->px = PrintX;
+ win->py = PrintY;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// US_RestoreWindow() - Sets the current window parms to those held in the
+// record
+//
+///////////////////////////////////////////////////////////////////////////
+void
+US_RestoreWindow(WindowRec *win)
+{
+ WindowX = win->x;
+ WindowY = win->y;
+ WindowW = win->w;
+ WindowH = win->h;
+
+ PrintX = win->px;
+ PrintY = win->py;
+}
+
+// Input routines
+
+///////////////////////////////////////////////////////////////////////////
+//
+// USL_XORICursor() - XORs the I-bar text cursor. Used by US_LineInput()
+//
+///////////////////////////////////////////////////////////////////////////
+static void
+USL_XORICursor(int x,int y,const char *s,word cursor)
+{
+ static boolean status; // VGA doesn't XOR...
+ char buf[MaxString];
+ int temp;
+ word w,h;
+
+ strcpy(buf,s);
+ buf[cursor] = '\0';
+ USL_MeasureString(buf,&w,&h);
+
+ px = x + w - 1;
+ py = y;
+ if (status^=1)
+ USL_DrawString("\x80");
+ else
+ {
+ temp = fontcolor;
+ fontcolor = backcolor;
+ USL_DrawString("\x80");
+ fontcolor = temp;
+ }
+}
+
+char USL_RotateChar(char ch, int dir)
+{
+ static const char charSet[] = " ABCDEFGHIJKLMNOPQRSTUVWXYZ.,-!?0123456789";
+ const int numChars = sizeof(charSet) / sizeof(char) - 1;
+ int i;
+ for(i = 0; i < numChars; i++)
+ {
+ if(ch == charSet[i]) break;
+ }
+
+ if(i == numChars) i = 0;
+
+ i += dir;
+ if(i < 0) i = numChars - 1;
+ else if(i >= numChars) i = 0;
+ return charSet[i];
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// US_LineInput() - Gets a line of user input at (x,y), the string defaults
+// to whatever is pointed at by def. Input is restricted to maxchars
+// chars or maxwidth pixels wide. If the user hits escape (and escok is
+// true), nothing is copied into buf, and false is returned. If the
+// user hits return, the current string is copied into buf, and true is
+// returned
+//
+///////////////////////////////////////////////////////////////////////////
+boolean
+US_LineInput(int x,int y,char *buf,const char *def,boolean escok,
+ int maxchars,int maxwidth)
+{
+ boolean redraw,
+ cursorvis,cursormoved,
+ done,result, checkkey;
+ ScanCode sc;
+ char c;
+ char s[MaxString],olds[MaxString];
+ int cursor,len;
+ word i,
+ w,h,
+ temp;
+ longword curtime, lasttime, lastdirtime, lastbuttontime, lastdirmovetime;
+ ControlInfo ci;
+ Direction lastdir = dir_None;
+
+ if (def)
+ strcpy(s,def);
+ else
+ *s = '\0';
+ *olds = '\0';
+ cursor = (int) strlen(s);
+ cursormoved = redraw = true;
+
+ cursorvis = done = false;
+ lasttime = lastdirtime = lastdirmovetime = GetTimeCount();
+ lastbuttontime = lasttime + TickBase / 4; // 250 ms => first button press accepted after 500 ms
+ LastASCII = key_None;
+ LastScan = sc_None;
+
+ while (!done)
+ {
+ ReadAnyControl(&ci);
+
+ if (cursorvis)
+ USL_XORICursor(x,y,s,cursor);
+
+ sc = LastScan;
+ LastScan = sc_None;
+ c = LastASCII;
+ LastASCII = key_None;
+
+ checkkey = true;
+ curtime = GetTimeCount();
+
+ // After each direction change accept the next change after 250 ms and then everz 125 ms
+ if(ci.dir != lastdir || curtime - lastdirtime > TickBase / 4 && curtime - lastdirmovetime > TickBase / 8)
+ {
+ if(ci.dir != lastdir)
+ {
+ lastdir = ci.dir;
+ lastdirtime = curtime;
+ }
+ lastdirmovetime = curtime;
+
+ switch(ci.dir)
+ {
+ case dir_West:
+ if(cursor)
+ {
+ // Remove trailing whitespace if cursor is at end of string
+ if(s[cursor] == ' ' && s[cursor + 1] == 0)
+ s[cursor] = 0;
+ cursor--;
+ }
+ cursormoved = true;
+ checkkey = false;
+ break;
+ case dir_East:
+ if(cursor >= MaxString - 1) break;
+
+ if(!s[cursor])
+ {
+ USL_MeasureString(s,&w,&h);
+ if(len >= maxchars || maxwidth && w >= maxwidth) break;
+
+ s[cursor] = ' ';
+ s[cursor + 1] = 0;
+ }
+ cursor++;
+ cursormoved = true;
+ checkkey = false;
+ break;
+
+ case dir_North:
+ if(!s[cursor])
+ {
+ USL_MeasureString(s,&w,&h);
+ if(len >= maxchars || maxwidth && w >= maxwidth) break;
+ s[cursor + 1] = 0;
+ }
+ s[cursor] = USL_RotateChar(s[cursor], 1);
+ redraw = true;
+ checkkey = false;
+ break;
+
+ case dir_South:
+ if(!s[cursor])
+ {
+ USL_MeasureString(s,&w,&h);
+ if(len >= maxchars || maxwidth && w >= maxwidth) break;
+ s[cursor + 1] = 0;
+ }
+ s[cursor] = USL_RotateChar(s[cursor], -1);
+ redraw = true;
+ checkkey = false;
+ break;
+ }
+ }
+
+ if((int)(curtime - lastbuttontime) > TickBase / 4) // 250 ms
+ {
+ if(ci.button0) // acts as return
+ {
+ strcpy(buf,s);
+ done = true;
+ result = true;
+ checkkey = false;
+ }
+ if(ci.button1 && escok) // acts as escape
+ {
+ done = true;
+ result = false;
+ checkkey = false;
+ }
+ if(ci.button2) // acts as backspace
+ {
+ lastbuttontime = curtime;
+ if(cursor)
+ {
+ strcpy(s + cursor - 1,s + cursor);
+ cursor--;
+ redraw = true;
+ }
+ cursormoved = true;
+ checkkey = false;
+ }
+ }
+
+ if(checkkey)
+ {
+ switch (sc)
+ {
+ case sc_LeftArrow:
+ if (cursor)
+ cursor--;
+ c = key_None;
+ cursormoved = true;
+ break;
+ case sc_RightArrow:
+ if (s[cursor])
+ cursor++;
+ c = key_None;
+ cursormoved = true;
+ break;
+ case sc_Home:
+ cursor = 0;
+ c = key_None;
+ cursormoved = true;
+ break;
+ case sc_End:
+ cursor = (int) strlen(s);
+ c = key_None;
+ cursormoved = true;
+ break;
+
+ case sc_Return:
+ strcpy(buf,s);
+ done = true;
+ result = true;
+ c = key_None;
+ break;
+ case sc_Escape:
+ if (escok)
+ {
+ done = true;
+ result = false;
+ }
+ c = key_None;
+ break;
+
+ case sc_BackSpace:
+ if (cursor)
+ {
+ strcpy(s + cursor - 1,s + cursor);
+ cursor--;
+ redraw = true;
+ }
+ c = key_None;
+ cursormoved = true;
+ break;
+ case sc_Delete:
+ if (s[cursor])
+ {
+ strcpy(s + cursor,s + cursor + 1);
+ redraw = true;
+ }
+ c = key_None;
+ cursormoved = true;
+ break;
+
+ case SDLK_KP5: //0x4c: // Keypad 5 // TODO: hmmm...
+ case sc_UpArrow:
+ case sc_DownArrow:
+ case sc_PgUp:
+ case sc_PgDn:
+ case sc_Insert:
+ c = key_None;
+ break;
+ }
+
+ if (c)
+ {
+ len = (int) strlen(s);
+ USL_MeasureString(s,&w,&h);
+
+ if(isprint(c) && (len < MaxString - 1) && ((!maxchars) || (len < maxchars))
+ && ((!maxwidth) || (w < maxwidth)))
+ {
+ for (i = len + 1;i > cursor;i--)
+ s[i] = s[i - 1];
+ s[cursor++] = c;
+ redraw = true;
+ }
+ }
+ }
+
+ if (redraw)
+ {
+ px = x;
+ py = y;
+ temp = fontcolor;
+ fontcolor = backcolor;
+ USL_DrawString(olds);
+ fontcolor = (byte) temp;
+ strcpy(olds,s);
+
+ px = x;
+ py = y;
+ USL_DrawString(s);
+
+ redraw = false;
+ }
+
+ if (cursormoved)
+ {
+ cursorvis = false;
+ lasttime = curtime - TickBase;
+
+ cursormoved = false;
+ }
+ if (curtime - lasttime > TickBase / 2) // 500 ms
+ {
+ lasttime = curtime;
+
+ cursorvis ^= true;
+ }
+ else SDL_Delay(5);
+ if (cursorvis)
+ USL_XORICursor(x,y,s,cursor);
+
+ VW_UpdateScreen();
+ }
+
+ if (cursorvis)
+ USL_XORICursor(x,y,s,cursor);
+ if (!result)
+ {
+ px = x;
+ py = y;
+ USL_DrawString(olds);
+ }
+ VW_UpdateScreen();
+
+ IN_ClearKeysDown();
+ return(result);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// US_InitRndT - Initializes the pseudo random number generator.
+// If randomize is true, the seed will be initialized depending on the
+// current time
+//
+///////////////////////////////////////////////////////////////////////////
+void US_InitRndT(int randomize)
+{
+ if(randomize)
+ rndindex = (SDL_GetTicks() >> 4) & 0xff;
+ else
+ rndindex = 0;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// US_RndT - Returns the next 8-bit pseudo random number
+//
+///////////////////////////////////////////////////////////////////////////
+int US_RndT()
+{
+ rndindex = (rndindex+1)&0xff;
+ return rndtable[rndindex];
+}