From bb42eb45c14ee4b0eba3df68c170aac631666fa6 Mon Sep 17 00:00:00 2001 From: sparky4 Date: Thu, 25 Jun 2015 16:42:29 -0500 Subject: [PATCH] modified: 16.LIB modified: 16.exe modified: 16/cawat/16_in.c modified: 16/cawat/16_in.h new file: 16/cawat/16_us.c new file: 16/cawat/16_us.h modified: 16/cawat/ID_IN.C modified: 16/cawat/cawat.bfproject modified: 16/cawat/lib_head.h modified: 16/cawat/types.h modified: emmtest.exe modified: emsdump.exe modified: fmemtest.exe modified: fonttest.exe modified: maptest.exe modified: maptest0.exe modified: palettec.exe modified: pcxtest.exe modified: scroll.exe modified: test.exe modified: test2.exe --- 16.LIB | Bin 36352 -> 36352 bytes 16.exe | Bin 45885 -> 45725 bytes 16/cawat/16_in.c | 2587 +++++++++++++++++++------------------- 16/cawat/16_in.h | 31 +- 16/cawat/16_us.c | 83 ++ 16/cawat/16_us.h | 36 + 16/cawat/ID_IN.C | 6 +- 16/cawat/cawat.bfproject | 181 ++- 16/cawat/lib_head.h | 20 +- 16/cawat/types.h | 1 + emmtest.exe | Bin 32680 -> 32616 bytes emsdump.exe | Bin 30994 -> 30930 bytes fmemtest.exe | Bin 25482 -> 25450 bytes fonttest.exe | Bin 24118 -> 24122 bytes maptest.exe | Bin 48860 -> 48668 bytes maptest0.exe | Bin 47107 -> 47155 bytes palettec.exe | Bin 33906 -> 33842 bytes pcxtest.exe | Bin 64735 -> 64575 bytes scroll.exe | Bin 59095 -> 58839 bytes test.exe | Bin 40371 -> 40243 bytes test2.exe | Bin 41676 -> 41516 bytes 21 files changed, 1539 insertions(+), 1406 deletions(-) create mode 100644 16/cawat/16_us.c create mode 100644 16/cawat/16_us.h diff --git a/16.LIB b/16.LIB index d37305c399eed33bff6c644b583595db4a77431f..29645ba80bec0b001df87e29b9f5b82c55e76ac7 100644 GIT binary patch delta 11659 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 delta 8344 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 ZKlDeQBX=H5=Tjbk_Tbwl','?',0 ,'*',0 ,' ',0 ,0 ,0 ,0 ,0 ,0 , // 3 - 0 ,0 ,0 ,0 ,0 ,0 ,0 ,'7','8','9','-','4','5','6','+','1', // 4 - '2','3','0',127,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 5 - 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 6 - 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 // 7 - }, - far SpecialNames[] = // ASCII for 0xe0 prefixed codes - { -// 0 1 2 3 4 5 6 7 8 9 A B C D E F - 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 0 - 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,13 ,0 ,0 ,0 , // 1 - 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 2 - 0 ,0 ,0 ,0 ,0 ,'/',0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 3 - 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 4 - 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 5 - 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 6 - 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 // 7 - }, - -#if 0 - *ScanNames[] = // Scan code names with single chars - { - "?","?","1","2","3","4","5","6","7","8","9","0","-","+","?","?", - "Q","W","E","R","T","Y","U","I","O","P","[","]","|","?","A","S", - "D","F","G","H","J","K","L",";","\"","?","?","?","Z","X","C","V", - "B","N","M",",",".","/","?","?","?","?","?","?","?","?","?","?", - "?","?","?","?","?","?","?","?","\xf","?","-","\x15","5","\x11","+","?", - "\x13","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?", - "?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?", - "?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?" - }, // DEBUG - consolidate these -#endif - - far ExtScanCodes[] = // Scan codes with >1 char names - { - 1,0xe,0xf,0x1d,0x2a,0x39,0x3a,0x3b,0x3c,0x3d,0x3e, - 0x3f,0x40,0x41,0x42,0x43,0x44,0x57,0x59,0x46,0x1c,0x36, - 0x37,0x38,0x47,0x49,0x4f,0x51,0x52,0x53,0x45,0x48, - 0x50,0x4b,0x4d,0x00 - }; -#if 0 - *ExtScanNames[] = // Names corresponding to ExtScanCodes - { - "Esc","BkSp","Tab","Ctrl","LShft","Space","CapsLk","F1","F2","F3","F4", - "F5","F6","F7","F8","F9","F10","F11","F12","ScrlLk","Enter","RShft", - "PrtSc","Alt","Home","PgUp","End","PgDn","Ins","Del","NumLk","Up", - "Down","Left","Right","" - }; -#endif -static Direction DirTable[] = // Quick lookup for total direction - { - dir_NorthWest, dir_North, dir_NorthEast, - dir_West, dir_None, dir_East, - dir_SouthWest, dir_South, dir_SouthEast - }; - -static void (*INL_KeyHook)(void); -static void interrupt (*OldKeyVect)(void); - -static char *ParmStrings[] = {"nojoys","nomouse",nil}; - -// Internal routines - -/////////////////////////////////////////////////////////////////////////// -// -// INL_KeyService() - Handles a keyboard interrupt (key up/down) -// -/////////////////////////////////////////////////////////////////////////// -static void interrupt -INL_KeyService(void) -{ -static boolean special; - byte k,c, - temp; - - k = inp(0x60); // Get the scan code - - // Tell the XT keyboard controller to clear the key - outp(0x61,(temp = inp(0x61)) | 0x80); - outp(0x61,temp); - - if (k == 0xe0) // Special key prefix - special = true; - else if (k == 0xe1) // Handle Pause key - Paused = true; - else - { - if (k & 0x80) // Break code - { - k &= 0x7f; - -// DEBUG - handle special keys: ctl-alt-delete, print scrn - - Keyboard[k] = false; - } - else // Make code - { - LastCode = CurCode; - CurCode = LastScan = k; - Keyboard[k] = true; - - if (special) - c = SpecialNames[k]; - else - { - if (k == sc_CapsLock) - { - CapsLock ^= true; - // DEBUG - make caps lock light work - } - - if (Keyboard[sc_LShift] || Keyboard[sc_RShift]) // If shifted - { - c = ShiftNames[k]; - if ((c >= 'A') && (c <= 'Z') && CapsLock) - c += 'a' - 'A'; - } - else - { - c = ASCIINames[k]; - if ((c >= 'a') && (c <= 'z') && CapsLock) - c -= 'a' - 'A'; - } - } - if (c) - LastASCII = c; - } - - special = false; - } - - if (INL_KeyHook && !special) - INL_KeyHook(); - outp(0x20,0x20); -} - -static void -Mouse(int x) -{ - x = CPURegs.x.ax; - int86(MouseInt,&CPURegs,&CPURegs); -} - -/////////////////////////////////////////////////////////////////////////// -// -// INL_GetMouseDelta() - Gets the amount that the mouse has moved from the -// mouse driver -// -/////////////////////////////////////////////////////////////////////////// -static void -INL_GetMouseDelta(int *x,int *y) -{ - Mouse(MDelta); - *x = CPURegs.x.cx; - *y = CPURegs.x.dx; -} - -/////////////////////////////////////////////////////////////////////////// -// -// INL_GetMouseButtons() - Gets the status of the mouse buttons from the -// mouse driver -// -/////////////////////////////////////////////////////////////////////////// -static word -INL_GetMouseButtons(void) -{ - word buttons; - - Mouse(MButtons); - buttons = CPURegs.x.bx; - return(buttons); -} - -/////////////////////////////////////////////////////////////////////////// -// -// IN_GetJoyAbs() - Reads the absolute position of the specified joystick -// -/////////////////////////////////////////////////////////////////////////// -void -IN_GetJoyAbs(word joy,word *xp,word *yp) -{ - byte xb,yb, - xs,ys; - word x,y; - - x = y = 0; - xs = joy? 2 : 0; // Find shift value for x axis - xb = 1 << xs; // Use shift value to get x bit mask - ys = joy? 3 : 1; // Do the same for y axis - yb = 1 << ys; - -// Read the absolute joystick values - __asm - { - pushf // Save some registers - push si - push di - cli // Make sure an interrupt doesn't screw the timings - - - mov dx,0x201 - in al,dx - out dx,al // Clear the resistors - - mov ah,[xb] // Get masks into registers - mov ch,[yb] - - xor si,si // Clear count registers - xor di,di - xor bh,bh // Clear high byte of bx for later - - push bp // Don't mess up stack frame - mov bp,MaxJoyValue - -loop: - in al,dx // Get bits indicating whether all are finished - - dec bp // Check bounding register - jz done // We have a silly value - abort - - mov bl,al // Duplicate the bits - and bl,ah // Mask off useless bits (in [xb]) - add si,bx // Possibly increment count register - mov cl,bl // Save for testing later - - mov bl,al - and bl,ch // [yb] - add di,bx - - add cl,bl - jnz loop // If both bits were 0, drop out - -done: - pop bp - - mov cl,[xs] // Get the number of bits to shift - shr si,cl // and shift the count that many times - - mov cl,[ys] - shr di,cl - - mov [x],si // Store the values into the variables - mov [y],di - - pop di - pop si - popf // Restore the registers - } - - *xp = x; - *yp = y; -} - -/////////////////////////////////////////////////////////////////////////// -// -// INL_GetJoyDelta() - Returns the relative movement of the specified -// joystick (from +/-127, scaled adaptively) -// -/////////////////////////////////////////////////////////////////////////// -static void -INL_GetJoyDelta(word joy,int *dx,int *dy,boolean adaptive) -{ - word x,y; - dword time; - JoystickDef *def; -static dword lasttime; - - IN_GetJoyAbs(joy,&x,&y); - def = JoyDefs + joy; - - if (x < def->threshMinX) - { - if (x < def->joyMinX) - x = def->joyMinX; - - x = -(x - def->threshMinX); - x *= def->joyMultXL; - x >>= JoyScaleShift; - *dx = (x > 127)? -127 : -x; - } - else if (x > def->threshMaxX) - { - if (x > def->joyMaxX) - x = def->joyMaxX; - - x = x - def->threshMaxX; - x *= def->joyMultXH; - x >>= JoyScaleShift; - *dx = (x > 127)? 127 : x; - } - else - *dx = 0; - - if (y < def->threshMinY) - { - if (y < def->joyMinY) - y = def->joyMinY; - - y = -(y - def->threshMinY); - y *= def->joyMultYL; - y >>= JoyScaleShift; - *dy = (y > 127)? -127 : -y; - } - else if (y > def->threshMaxY) - { - if (y > def->joyMaxY) - y = def->joyMaxY; - - y = y - def->threshMaxY; - y *= def->joyMultYH; - y >>= JoyScaleShift; - *dy = (y > 127)? 127 : y; - } - else - *dy = 0; - - if (adaptive) - { - time = (TimeCount - lasttime) / 2; - if (time) - { - if (time > 8) - time = 8; - *dx *= time; - *dy *= time; - } - } - lasttime = TimeCount; -} - -/////////////////////////////////////////////////////////////////////////// -// -// INL_GetJoyButtons() - Returns the button status of the specified -// joystick -// -/////////////////////////////////////////////////////////////////////////// -static word -INL_GetJoyButtons(word joy) -{ -register word result; - - result = inp(0x201); // Get all the joystick buttons - result >>= joy? 6 : 4; // Shift into bits 0-1 - result &= 3; // Mask off the useless bits - result ^= 3; - return(result); -} - -/////////////////////////////////////////////////////////////////////////// -// -// IN_GetJoyButtonsDB() - Returns the de-bounced button status of the -// specified joystick -// -/////////////////////////////////////////////////////////////////////////// -word -IN_GetJoyButtonsDB(word joy) -{ - dword lasttime; - word result1,result2; - - do - { - result1 = INL_GetJoyButtons(joy); - lasttime = TimeCount; - while(TimeCount == lasttime) - ; - result2 = INL_GetJoyButtons(joy); - } while(result1 != result2); - return(result1); -} - -/////////////////////////////////////////////////////////////////////////// -// -// INL_StartKbd() - Sets up my keyboard stuff for use -// -/////////////////////////////////////////////////////////////////////////// -static void -INL_StartKbd(void) -{ - INL_KeyHook = 0; // Clear key hook - - IN_ClearKeysDown(); - - OldKeyVect = _dos_getvect(KeyInt); - _dos_setvect(KeyInt,INL_KeyService); -} - -/////////////////////////////////////////////////////////////////////////// -// -// INL_ShutKbd() - Restores keyboard control to the BIOS -// -/////////////////////////////////////////////////////////////////////////// -static void -INL_ShutKbd(void) -{ - poke(0x40,0x17,peek(0x40,0x17) & 0xfaf0); // Clear ctrl/alt/shift flags - - _dos_setvect(KeyInt,OldKeyVect); -} - -/////////////////////////////////////////////////////////////////////////// -// -// INL_StartMouse() - Detects and sets up the mouse -// -/////////////////////////////////////////////////////////////////////////// -static boolean -INL_StartMouse(void) -{ - if(_dos_getvect(MouseInt)) - { - Mouse(MReset); - if(CPURegs.x.ax == 0xffff) - return(true); - } - return(false); -} - -/////////////////////////////////////////////////////////////////////////// -// -// INL_ShutMouse() - Cleans up after the mouse -// -/////////////////////////////////////////////////////////////////////////// -static void -INL_ShutMouse(void) -{ -} - -// -// INL_SetJoyScale() - Sets up scaling values for the specified joystick -// -static void -INL_SetJoyScale(word joy) -{ - JoystickDef *def; - - def = &JoyDefs[joy]; - def->joyMultXL = JoyScaleMax / (def->threshMinX - def->joyMinX); - def->joyMultXH = JoyScaleMax / (def->joyMaxX - def->threshMaxX); - def->joyMultYL = JoyScaleMax / (def->threshMinY - def->joyMinY); - def->joyMultYH = JoyScaleMax / (def->joyMaxY - def->threshMaxY); -} - -/////////////////////////////////////////////////////////////////////////// -// -// IN_SetupJoy() - Sets up thresholding values and calls INL_SetJoyScale() -// to set up scaling values -// -/////////////////////////////////////////////////////////////////////////// -void -IN_SetupJoy(word joy,word minx,word maxx,word miny,word maxy) -{ - word d,r; - JoystickDef *def; - - def = &JoyDefs[joy]; - - def->joyMinX = minx; - def->joyMaxX = maxx; - r = maxx - minx; - d = r / 5; - def->threshMinX = ((r / 2) - d) + minx; - def->threshMaxX = ((r / 2) + d) + minx; - - def->joyMinY = miny; - def->joyMaxY = maxy; - r = maxy - miny; - d = r / 5; - def->threshMinY = ((r / 2) - d) + miny; - def->threshMaxY = ((r / 2) + d) + miny; - - INL_SetJoyScale(joy); -} - -/////////////////////////////////////////////////////////////////////////// -// -// INL_StartJoy() - Detects & auto-configures the specified joystick -// The auto-config assumes the joystick is centered -// -/////////////////////////////////////////////////////////////////////////// -static boolean -INL_StartJoy(word joy) -{ - word x,y; - - IN_GetJoyAbs(joy,&x,&y); - - if - ( - ((x == 0) || (x > MaxJoyValue - 10)) - || ((y == 0) || (y > MaxJoyValue - 10)) - ) - return(false); - else - { - IN_SetupJoy(joy,0,x * 2,0,y * 2); - return(true); - } -} - -/////////////////////////////////////////////////////////////////////////// -// -// INL_ShutJoy() - Cleans up the joystick stuff -// -/////////////////////////////////////////////////////////////////////////// -static void -INL_ShutJoy(word joy) -{ - JoysPresent[joy] = false; -} - -// Public routines - -/////////////////////////////////////////////////////////////////////////// -// -// IN_Startup() - Starts up the Input Mgr -// -/////////////////////////////////////////////////////////////////////////// -void -IN_Startup(void) -{ - boolean checkjoys,checkmouse; - word i; - - if (IN_Started) - return; - - checkjoys = true; - checkmouse = true; - for (i = 1;i < _argc;i++) - { - switch (US_CheckParm(_argv[i],ParmStrings)) - { - case 0: - checkjoys = false; - break; - case 1: - checkmouse = false; - break; - } - } - - INL_StartKbd(); - MousePresent = checkmouse? INL_StartMouse() : false; - - for (i = 0;i < MaxJoys;i++) - JoysPresent[i] = checkjoys? INL_StartJoy(i) : false; - - IN_Started = true; -} - -/////////////////////////////////////////////////////////////////////////// -// -// IN_Default() - Sets up default conditions for the Input Mgr -// -/////////////////////////////////////////////////////////////////////////// -void -IN_Default(boolean gotit,ControlType in) -{ - if - ( - (!gotit) - || ((in == ctrl_Joystick1) && !JoysPresent[0]) - || ((in == ctrl_Joystick2) && !JoysPresent[1]) - || ((in == ctrl_Mouse) && !MousePresent) - ) - in = ctrl_Keyboard1; - IN_SetControlType(0,in); -} - -/////////////////////////////////////////////////////////////////////////// -// -// IN_Shutdown() - Shuts down the Input Mgr -// -/////////////////////////////////////////////////////////////////////////// -void -IN_Shutdown(void) -{ - word i; - - if (!IN_Started) - return; - - INL_ShutMouse(); - for (i = 0;i < MaxJoys;i++) - INL_ShutJoy(i); - INL_ShutKbd(); - - IN_Started = false; -} - -/////////////////////////////////////////////////////////////////////////// -// -// IN_SetKeyHook() - Sets the routine that gets called by INL_KeyService() -// everytime a real make/break code gets hit -// -/////////////////////////////////////////////////////////////////////////// -void -IN_SetKeyHook(void (*hook)()) -{ - INL_KeyHook = hook; -} - -/////////////////////////////////////////////////////////////////////////// -// -// IN_ClearKeyDown() - Clears the keyboard array -// -/////////////////////////////////////////////////////////////////////////// -void -IN_ClearKeysDown(void) -{ - int i; - - LastScan = sc_None; - LastASCII = key_None; - for (i = 0;i < NumCodes;i++) - Keyboard[i] = false; -} - -/////////////////////////////////////////////////////////////////////////// -// -// INL_AdjustCursor() - Internal routine of common code from IN_ReadCursor() -// -/////////////////////////////////////////////////////////////////////////// -static void -INL_AdjustCursor(CursorInfo *info,word buttons,int dx,int dy) -{ - if (buttons & (1 << 0)) - info->button0 = true; - if (buttons & (1 << 1)) - info->button1 = true; - - info->x += dx; - info->y += dy; -} - -/////////////////////////////////////////////////////////////////////////// -// -// IN_ReadCursor() - Reads the input devices and fills in the cursor info -// struct -// -/////////////////////////////////////////////////////////////////////////// -void -IN_ReadCursor(CursorInfo *info) -{ - word i, - buttons; - int dx,dy; - - info->x = info->y = 0; - info->button0 = info->button1 = false; - - if (MousePresent) - { - buttons = INL_GetMouseButtons(); - INL_GetMouseDelta(&dx,&dy); - INL_AdjustCursor(info,buttons,dx,dy); - } - - for (i = 0;i < MaxJoys;i++) - { - if (!JoysPresent[i]) - continue; - - buttons = INL_GetJoyButtons(i); - INL_GetJoyDelta(i,&dx,&dy,true); - dx /= 64; - dy /= 64; - INL_AdjustCursor(info,buttons,dx,dy); - } -} - -/////////////////////////////////////////////////////////////////////////// -// -// IN_ReadControl() - Reads the device associated with the specified -// player and fills in the control info struct -// -/////////////////////////////////////////////////////////////////////////// -void -IN_ReadControl(int player,ControlInfo *info) -{ - boolean realdelta=false; // MDM (GAMERS EDGE) - byte dbyte; - word buttons; - int dx,dy; - Motion mx,my; - ControlType type; -register KeyboardDef *def; - - dx = dy = 0; - mx = my = motion_None; - buttons = 0; - -#if 0 - if (DemoMode == demo_Playback) - { - dbyte = DemoBuffer[DemoOffset + 1]; - my = (dbyte & 3) - 1; - mx = ((dbyte >> 2) & 3) - 1; - buttons = (dbyte >> 4) & 3; - - if (!(--DemoBuffer[DemoOffset])) - { - DemoOffset += 2; - if (DemoOffset >= DemoSize) - DemoMode = demo_PlayDone; - } - - realdelta = false; - } - else if (DemoMode == demo_PlayDone) - Quit("Demo playback exceeded"); - else -#endif - { - // MDM begin (GAMERS EDGE) - added this block - ControlTypeUsed = ctrl_None; - - // Handle mouse input... - // - if ((MousePresent) && (ControlTypeUsed == ctrl_None)) - { - INL_GetMouseDelta(&dx,&dy); - buttons = INL_GetMouseButtons(); - realdelta = true; - if (dx || dy || buttons) - ControlTypeUsed = ctrl_Mouse; - } - - // Handle joystick input... - // - if ((JoystickCalibrated) && (ControlTypeUsed == ctrl_None)) - { - type = ctrl_Joystick1; - INL_GetJoyDelta(type - ctrl_Joystick,&dx,&dy,false); - buttons = INL_GetJoyButtons(type - ctrl_Joystick); - realdelta = true; - if (dx || dy || buttons) - ControlTypeUsed = ctrl_Joystick; - } - - // Handle keyboard input... - // - if (ControlTypeUsed == ctrl_None) - { - type = ctrl_Keyboard1; - def = &KbdDefs[type - ctrl_Keyboard]; - - if (Keyboard[def->upleft]) - mx = motion_Left,my = motion_Up; - else if (Keyboard[def->upright]) - mx = motion_Right,my = motion_Up; - else if (Keyboard[def->downleft]) - mx = motion_Left,my = motion_Down; - else if (Keyboard[def->downright]) - mx = motion_Right,my = motion_Down; - - if (Keyboard[def->up]) - my = motion_Up; - else if (Keyboard[def->down]) - my = motion_Down; - - if (Keyboard[def->left]) - mx = motion_Left; - else if (Keyboard[def->right]) - mx = motion_Right; - - if (Keyboard[def->button0]) - buttons += 1 << 0; - if (Keyboard[def->button1]) - buttons += 1 << 1; - realdelta = false; - if (mx || my || buttons) - ControlTypeUsed = ctrl_Keyboard; - } // MDM end (GAMERS EDGE) - } - - if (realdelta) - { - mx = (dx < 0)? motion_Left : ((dx > 0)? motion_Right : motion_None); - my = (dy < 0)? motion_Up : ((dy > 0)? motion_Down : motion_None); - } - else - { - dx = mx * 127; - dy = my * 127; - } - - info->x = dx; - info->xaxis = mx; - info->y = dy; - info->yaxis = my; - info->button0 = buttons & (1 << 0); - info->button1 = buttons & (1 << 1); - info->dir = DirTable[((my + 1) * 3) + (mx + 1)]; - -#if 0 - if (DemoMode == demo_Record) - { - // Pack the control info into a byte - dbyte = (buttons << 4) | ((mx + 1) << 2) | (my + 1); - - if - ( - (DemoBuffer[DemoOffset + 1] == dbyte) - && (DemoBuffer[DemoOffset] < 255) - ) - (DemoBuffer[DemoOffset])++; - else - { - if (DemoOffset || DemoBuffer[DemoOffset]) - DemoOffset += 2; - - if (DemoOffset >= DemoSize) - Quit("Demo buffer overflow"); - - DemoBuffer[DemoOffset] = 1; - DemoBuffer[DemoOffset + 1] = dbyte; - } - } -#endif -} - -#if 0 -/////////////////////////////////////////////////////////////////////////// -// -// IN_ReadControl() - Reads the device associated with the specified -// player and fills in the control info struct -// -/////////////////////////////////////////////////////////////////////////// -void -IN_ReadControl(int player,ControlInfo *info) -{ - boolean realdelta; - byte dbyte; - word buttons; - int dx,dy; - Motion mx,my; - ControlType type; -register KeyboardDef *def; - - dx = dy = 0; - mx = my = motion_None; - buttons = 0; - -#if 0 - if (DemoMode == demo_Playback) - { - dbyte = DemoBuffer[DemoOffset + 1]; - my = (dbyte & 3) - 1; - mx = ((dbyte >> 2) & 3) - 1; - buttons = (dbyte >> 4) & 3; - - if (!(--DemoBuffer[DemoOffset])) - { - DemoOffset += 2; - if (DemoOffset >= DemoSize) - DemoMode = demo_PlayDone; - } - - realdelta = false; - } - else if (DemoMode == demo_PlayDone) - Quit("Demo playback exceeded"); - else -#endif - { - switch (type = Controls[player]) - { - case ctrl_Keyboard1: - case ctrl_Keyboard2: - def = &KbdDefs[type - ctrl_Keyboard]; - - if (Keyboard[def->upleft]) - mx = motion_Left,my = motion_Up; - else if (Keyboard[def->upright]) - mx = motion_Right,my = motion_Up; - else if (Keyboard[def->downleft]) - mx = motion_Left,my = motion_Down; - else if (Keyboard[def->downright]) - mx = motion_Right,my = motion_Down; - - if (Keyboard[def->up]) - my = motion_Up; - else if (Keyboard[def->down]) - my = motion_Down; - - if (Keyboard[def->left]) - mx = motion_Left; - else if (Keyboard[def->right]) - mx = motion_Right; - - if (Keyboard[def->button0]) - buttons += 1 << 0; - if (Keyboard[def->button1]) - buttons += 1 << 1; - realdelta = false; - break; - case ctrl_Joystick1: - case ctrl_Joystick2: - INL_GetJoyDelta(type - ctrl_Joystick,&dx,&dy,false); - buttons = INL_GetJoyButtons(type - ctrl_Joystick); - realdelta = true; - break; - case ctrl_Mouse: - INL_GetMouseDelta(&dx,&dy); - buttons = INL_GetMouseButtons(); - realdelta = true; - break; - } - } - - if (realdelta) - { - mx = (dx < 0)? motion_Left : ((dx > 0)? motion_Right : motion_None); - my = (dy < 0)? motion_Up : ((dy > 0)? motion_Down : motion_None); - } - else - { - dx = mx * 127; - dy = my * 127; - } - - info->x = dx; - info->xaxis = mx; - info->y = dy; - info->yaxis = my; - info->button0 = buttons & (1 << 0); - info->button1 = buttons & (1 << 1); - info->dir = DirTable[((my + 1) * 3) + (mx + 1)]; - -#if 0 - if (DemoMode == demo_Record) - { - // Pack the control info into a byte - dbyte = (buttons << 4) | ((mx + 1) << 2) | (my + 1); - - if - ( - (DemoBuffer[DemoOffset + 1] == dbyte) - && (DemoBuffer[DemoOffset] < 255) - ) - (DemoBuffer[DemoOffset])++; - else - { - if (DemoOffset || DemoBuffer[DemoOffset]) - DemoOffset += 2; - - if (DemoOffset >= DemoSize) - Quit("Demo buffer overflow"); - - DemoBuffer[DemoOffset] = 1; - DemoBuffer[DemoOffset + 1] = dbyte; - } - } -#endif -} -#endif - -/////////////////////////////////////////////////////////////////////////// -// -// IN_SetControlType() - Sets the control type to be used by the specified -// player -// -/////////////////////////////////////////////////////////////////////////// -void -IN_SetControlType(int player,ControlType type) -{ - // DEBUG - check that requested type is present? - Controls[player] = type; -} - -#if 0 -/////////////////////////////////////////////////////////////////////////// -// -// IN_StartDemoRecord() - Starts the demo recording, using a buffer the -// size passed. Returns if the buffer allocation was successful -// -/////////////////////////////////////////////////////////////////////////// -boolean -IN_StartDemoRecord(word bufsize) -{ - if (!bufsize) - return(false); - - MM_GetPtr((memptr *)&DemoBuffer,bufsize); - DemoMode = demo_Record; - DemoSize = bufsize & ~1; - DemoOffset = 0; - DemoBuffer[0] = DemoBuffer[1] = 0; - - return(true); -} - -/////////////////////////////////////////////////////////////////////////// -// -// IN_StartDemoPlayback() - Plays back the demo pointed to of the given size -// -/////////////////////////////////////////////////////////////////////////// -void -IN_StartDemoPlayback(byte /*_1seg*/ *buffer,word bufsize) -{ - DemoBuffer = buffer; - DemoMode = demo_Playback; - DemoSize = bufsize & ~1; - DemoOffset = 0; -} - -/////////////////////////////////////////////////////////////////////////// -// -// IN_StopDemo() - Turns off demo mode -// -/////////////////////////////////////////////////////////////////////////// -void -IN_StopDemo(void) -{ - if ((DemoMode == demo_Record) && DemoOffset) - DemoOffset += 2; - - DemoMode = demo_Off; -} - -/////////////////////////////////////////////////////////////////////////// -// -// IN_FreeDemoBuffer() - Frees the demo buffer, if it's been allocated -// -/////////////////////////////////////////////////////////////////////////// -void -IN_FreeDemoBuffer(void) -{ - if (DemoBuffer) - MM_FreePtr((memptr *)&DemoBuffer); -} -#endif - - -#if 0 -/////////////////////////////////////////////////////////////////////////// -// -// IN_GetScanName() - Returns a string containing the name of the -// specified scan code -// -/////////////////////////////////////////////////////////////////////////// -byte * -IN_GetScanName(ScanCode scan) -{ - byte **p; - ScanCode far *s; - - for (s = ExtScanCodes,p = ExtScanNames;*s;p++,s++) - if (*s == scan) - return(*p); - - return(ScanNames[scan]); -} -#endif - - -/////////////////////////////////////////////////////////////////////////// -// -// IN_WaitForKey() - Waits for a scan code, then clears LastScan and -// returns the scan code -// -/////////////////////////////////////////////////////////////////////////// -ScanCode -IN_WaitForKey(void) -{ - ScanCode result; - - while (!(result = LastScan)) - ; - LastScan = 0; - return(result); -} - -/////////////////////////////////////////////////////////////////////////// -// -// IN_WaitForASCII() - Waits for an ASCII char, then clears LastASCII and -// returns the ASCII value -// -/////////////////////////////////////////////////////////////////////////// -char -IN_WaitForASCII(void) -{ - char result; - - while (!(result = LastASCII)) - ; - LastASCII = '\0'; - return(result); -} - -/////////////////////////////////////////////////////////////////////////// -// -// IN_AckBack() - Waits for either an ASCII keypress or a button press -// -/////////////////////////////////////////////////////////////////////////// -void -IN_AckBack(void) -{ - word i; - - while (!LastScan) - { - if (MousePresent) - { - if (INL_GetMouseButtons()) - { - while (INL_GetMouseButtons()) - ; - return; - } - } - - for (i = 0;i < MaxJoys;i++) - { - if (JoysPresent[i]) - { - if (IN_GetJoyButtonsDB(i)) - { - while (IN_GetJoyButtonsDB(i)) - ; - return; - } - } - } - } - - IN_ClearKey(LastScan); - LastScan = sc_None; -} - -/////////////////////////////////////////////////////////////////////////// -// -// IN_Ack() - Clears user input & then calls IN_AckBack() -// -/////////////////////////////////////////////////////////////////////////// -void -IN_Ack(void) -{ - word i; - - IN_ClearKey(LastScan); - LastScan = sc_None; - - if (MousePresent) - while (INL_GetMouseButtons()) - ; - for (i = 0;i < MaxJoys;i++) - if (JoysPresent[i]) - while (IN_GetJoyButtonsDB(i)) - ; - - IN_AckBack(); -} - -/////////////////////////////////////////////////////////////////////////// -// -// IN_IsUserInput() - Returns true if a key has been pressed or a button -// is down -// -/////////////////////////////////////////////////////////////////////////// -boolean -IN_IsUserInput(void) -{ - boolean result; - word i; - - result = LastScan; - - if (MousePresent) - if (INL_GetMouseButtons()) - result = true; - - for (i = 0;i < MaxJoys;i++) - if (JoysPresent[i]) - if (INL_GetJoyButtons(i)) - result = true; - - return(result); -} - -/////////////////////////////////////////////////////////////////////////// -// -// IN_UserInput() - Waits for the specified delay time (in ticks) or the -// user pressing a key or a mouse button. If the clear flag is set, it -// then either clears the key or waits for the user to let the mouse -// button up. -// -/////////////////////////////////////////////////////////////////////////// -boolean -IN_UserInput(dword delay,boolean clear) -{ - dword lasttime; - - lasttime = TimeCount; - do - { - if (IN_IsUserInput()) - { - if (clear) - IN_AckBack(); - return(true); - } - } while (TimeCount - lasttime < delay); - return(false); -} +/* Catacomb Armageddon Source Code + * Copyright (C) 1993-2014 Flat Rock Software + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +// +// ID Engine +// ID_IN.c - Input Manager +// v1.0d1 +// By Jason Blochowiak +// + +// +// This module handles dealing with the various input devices +// +// Depends on: Memory Mgr (for demo recording), Sound Mgr (for timing stuff), +// User Mgr (for command line parms) +// +// Globals: +// LastScan - The keyboard scan code of the last key pressed +// LastASCII - The ASCII value of the last key pressed +// DEBUG - there are more globals +// + +#include "16_in.h" + +// Global variables + boolean JoystickCalibrated=false; // MDM (GAMERS EDGE) - added + ControlType ControlTypeUsed; // MDM (GAMERS EDGE) - added + + boolean Keyboard[NumCodes], + JoysPresent[MaxJoys], + MousePresent; + boolean Paused; + char LastASCII; + ScanCode LastScan; + KeyboardDef KbdDefs[MaxKbds] = {{0x1d,0x38,0x47,0x48,0x49,0x4b,0x4d,0x4f,0x50,0x51}}; + JoystickDef JoyDefs[MaxJoys]; + ControlType Controls[MaxPlayers]; + +#ifdef DEMO0 + Demo DemoMode = demo_Off; + byte __segment *DemoBuffer; + word DemoOffset,DemoSize; +#endif + +// Internal variables +static boolean IN_Started; +static boolean CapsLock; +static ScanCode CurCode,LastCode; +static byte far ASCIINames[] = // Unshifted ASCII for scan codes + { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0 ,27 ,'1','2','3','4','5','6','7','8','9','0','-','=',8 ,9 , // 0 + 'q','w','e','r','t','y','u','i','o','p','[',']',13 ,0 ,'a','s', // 1 + 'd','f','g','h','j','k','l',';',39 ,'`',0 ,92 ,'z','x','c','v', // 2 + 'b','n','m',',','.','/',0 ,'*',0 ,' ',0 ,0 ,0 ,0 ,0 ,0 , // 3 + 0 ,0 ,0 ,0 ,0 ,0 ,0 ,'7','8','9','-','4','5','6','+','1', // 4 + '2','3','0',127,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 5 + 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 6 + 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 // 7 + }, + far ShiftNames[] = // Shifted ASCII for scan codes + { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0 ,27 ,'!','@','#','$','%','^','&','*','(',')','_','+',8 ,9 , // 0 + 'Q','W','E','R','T','Y','U','I','O','P','{','}',13 ,0 ,'A','S', // 1 + 'D','F','G','H','J','K','L',':',34 ,'~',0 ,'|','Z','X','C','V', // 2 + 'B','N','M','<','>','?',0 ,'*',0 ,' ',0 ,0 ,0 ,0 ,0 ,0 , // 3 + 0 ,0 ,0 ,0 ,0 ,0 ,0 ,'7','8','9','-','4','5','6','+','1', // 4 + '2','3','0',127,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 5 + 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 6 + 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 // 7 + }, + far SpecialNames[] = // ASCII for 0xe0 prefixed codes + { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 0 + 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,13 ,0 ,0 ,0 , // 1 + 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 2 + 0 ,0 ,0 ,0 ,0 ,'/',0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 3 + 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 4 + 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 5 + 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 6 + 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 // 7 + }, + +#if 0 + *ScanNames[] = // Scan code names with single chars + { + "?","?","1","2","3","4","5","6","7","8","9","0","-","+","?","?", + "Q","W","E","R","T","Y","U","I","O","P","[","]","|","?","A","S", + "D","F","G","H","J","K","L",";","\"","?","?","?","Z","X","C","V", + "B","N","M",",",".","/","?","?","?","?","?","?","?","?","?","?", + "?","?","?","?","?","?","?","?","\xf","?","-","\x15","5","\x11","+","?", + "\x13","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?", + "?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?", + "?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?" + }, // DEBUG - consolidate these +#endif + + far ExtScanCodes[] = // Scan codes with >1 char names + { + 1,0xe,0xf,0x1d,0x2a,0x39,0x3a,0x3b,0x3c,0x3d,0x3e, + 0x3f,0x40,0x41,0x42,0x43,0x44,0x57,0x59,0x46,0x1c,0x36, + 0x37,0x38,0x47,0x49,0x4f,0x51,0x52,0x53,0x45,0x48, + 0x50,0x4b,0x4d,0x00 + }; +#if 0 + *ExtScanNames[] = // Names corresponding to ExtScanCodes + { + "Esc","BkSp","Tab","Ctrl","LShft","Space","CapsLk","F1","F2","F3","F4", + "F5","F6","F7","F8","F9","F10","F11","F12","ScrlLk","Enter","RShft", + "PrtSc","Alt","Home","PgUp","End","PgDn","Ins","Del","NumLk","Up", + "Down","Left","Right","" + }; +#endif +static Direction DirTable[] = // Quick lookup for total direction + { + dir_NorthWest, dir_North, dir_NorthEast, + dir_West, dir_None, dir_East, + dir_SouthWest, dir_South, dir_SouthEast + }; + +static void (*INL_KeyHook)(void); +static void interrupt (*OldKeyVect)(void); + +static char *ParmStrings[] = {"nojoys","nomouse",nil}; + +// Internal routines + +/////////////////////////////////////////////////////////////////////////// +// +// INL_KeyService() - Handles a keyboard interrupt (key up/down) +// +/////////////////////////////////////////////////////////////////////////// +static void interrupt +INL_KeyService(void) +{ +static boolean special; + byte k,c, + temp; + + k = inp(0x60); // Get the scan code + + // Tell the XT keyboard controller to clear the key + outp(0x61,(temp = inp(0x61)) | 0x80); + outp(0x61,temp); + + if (k == 0xe0) // Special key prefix + special = true; + else if (k == 0xe1) // Handle Pause key + Paused = true; + else + { + if (k & 0x80) // Break code + { + k &= 0x7f; + +// DEBUG - handle special keys: ctl-alt-delete, print scrn + + Keyboard[k] = false; + } + else // Make code + { + LastCode = CurCode; + CurCode = LastScan = k; + Keyboard[k] = true; + + if (special) + c = SpecialNames[k]; + else + { + if (k == sc_CapsLock) + { + CapsLock ^= true; + // DEBUG - make caps lock light work + } + + if (Keyboard[sc_LShift] || Keyboard[sc_RShift]) // If shifted + { + c = ShiftNames[k]; + if ((c >= 'A') && (c <= 'Z') && CapsLock) + c += 'a' - 'A'; + } + else + { + c = ASCIINames[k]; + if ((c >= 'a') && (c <= 'z') && CapsLock) + c -= 'a' - 'A'; + } + } + if (c) + LastASCII = c; + } + + special = false; + } + + if (INL_KeyHook && !special) + INL_KeyHook(); + outp(0x20,0x20); +} + +static void +Mouse(int x) +{ + union REGS CPURegs; + x = CPURegs.x.ax; + int86(MouseInt,&CPURegs,&CPURegs); +} + +/////////////////////////////////////////////////////////////////////////// +// +// INL_GetMouseDelta() - Gets the amount that the mouse has moved from the +// mouse driver +// +/////////////////////////////////////////////////////////////////////////// +static void +INL_GetMouseDelta(int *x,int *y) +{ + union REGS CPURegs; + Mouse(MDelta); + *x = CPURegs.x.cx; + *y = CPURegs.x.dx; +} + +/////////////////////////////////////////////////////////////////////////// +// +// INL_GetMouseButtons() - Gets the status of the mouse buttons from the +// mouse driver +// +/////////////////////////////////////////////////////////////////////////// +static word +INL_GetMouseButtons(void) +{ + union REGS CPURegs; + word buttons; + + Mouse(MButtons); + buttons = CPURegs.x.bx; + return(buttons); +} + +/////////////////////////////////////////////////////////////////////////// +// +// IN_GetJoyAbs() - Reads the absolute position of the specified joystick +// +/////////////////////////////////////////////////////////////////////////// +void +IN_GetJoyAbs(word joy,word *xp,word *yp) +{ + byte xb,yb, + xs,ys; + word x,y; + + x = y = 0; + xs = joy? 2 : 0; // Find shift value for x axis + xb = 1 << xs; // Use shift value to get x bit mask + ys = joy? 3 : 1; // Do the same for y axis + yb = 1 << ys; + +// Read the absolute joystick values + __asm + { + pushf // Save some registers + push si + push di + cli // Make sure an interrupt doesn't screw the timings + + + mov dx,0x201 + in al,dx + out dx,al // Clear the resistors + + mov ah,[xb] // Get masks into registers + mov ch,[yb] + + xor si,si // Clear count registers + xor di,di + xor bh,bh // Clear high byte of bx for later + + push bp // Don't mess up stack frame + mov bp,MaxJoyValue + +loo: + in al,dx // Get bits indicating whether all are finished + + dec bp // Check bounding register + jz done // We have a silly value - abort + + mov bl,al // Duplicate the bits + and bl,ah // Mask off useless bits (in [xb]) + add si,bx // Possibly increment count register + mov cl,bl // Save for testing later + + mov bl,al + and bl,ch // [yb] + add di,bx + + add cl,bl + jnz loo // If both bits were 0, drop out + +done: + pop bp + + mov cl,[xs] // Get the number of bits to shift + shr si,cl // and shift the count that many times + + mov cl,[ys] + shr di,cl + + mov [x],si // Store the values into the variables + mov [y],di + + pop di + pop si + popf // Restore the registers + } + + *xp = x; + *yp = y; +} + +/////////////////////////////////////////////////////////////////////////// +// +// INL_GetJoyDelta() - Returns the relative movement of the specified +// joystick (from +/-127, scaled adaptively) +// +/////////////////////////////////////////////////////////////////////////// +static void +INL_GetJoyDelta(word joy,int *dx,int *dy,boolean adaptive) +{ + word x,y; + dword time; + dword TimeCount = *clockdw; + JoystickDef *def; +static dword lasttime; + + IN_GetJoyAbs(joy,&x,&y); + def = JoyDefs + joy; + + if (x < def->threshMinX) + { + if (x < def->joyMinX) + x = def->joyMinX; + + x = -(x - def->threshMinX); + x *= def->joyMultXL; + x >>= JoyScaleShift; + *dx = (x > 127)? -127 : -x; + } + else if (x > def->threshMaxX) + { + if (x > def->joyMaxX) + x = def->joyMaxX; + + x = x - def->threshMaxX; + x *= def->joyMultXH; + x >>= JoyScaleShift; + *dx = (x > 127)? 127 : x; + } + else + *dx = 0; + + if (y < def->threshMinY) + { + if (y < def->joyMinY) + y = def->joyMinY; + + y = -(y - def->threshMinY); + y *= def->joyMultYL; + y >>= JoyScaleShift; + *dy = (y > 127)? -127 : -y; + } + else if (y > def->threshMaxY) + { + if (y > def->joyMaxY) + y = def->joyMaxY; + + y = y - def->threshMaxY; + y *= def->joyMultYH; + y >>= JoyScaleShift; + *dy = (y > 127)? 127 : y; + } + else + *dy = 0; + + if (adaptive) + { + time = (TimeCount - lasttime) / 2; + if (time) + { + if (time > 8) + time = 8; + *dx *= time; + *dy *= time; + } + } + lasttime = TimeCount; +} + +/////////////////////////////////////////////////////////////////////////// +// +// INL_GetJoyButtons() - Returns the button status of the specified +// joystick +// +/////////////////////////////////////////////////////////////////////////// +static word +INL_GetJoyButtons(word joy) +{ +register word result; + + result = inp(0x201); // Get all the joystick buttons + result >>= joy? 6 : 4; // Shift into bits 0-1 + result &= 3; // Mask off the useless bits + result ^= 3; + return(result); +} + +/////////////////////////////////////////////////////////////////////////// +// +// IN_GetJoyButtonsDB() - Returns the de-bounced button status of the +// specified joystick +// +/////////////////////////////////////////////////////////////////////////// +word +IN_GetJoyButtonsDB(word joy) +{ + dword TimeCount = *clockdw; + dword lasttime; + word result1,result2; + + do + { + result1 = INL_GetJoyButtons(joy); + lasttime = TimeCount; + while(TimeCount == lasttime) + result2 = INL_GetJoyButtons(joy); + } while(result1 != result2); + return(result1); +} + +/////////////////////////////////////////////////////////////////////////// +// +// INL_StartKbd() - Sets up my keyboard stuff for use +// +/////////////////////////////////////////////////////////////////////////// +static void +INL_StartKbd(void) +{ + INL_KeyHook = 0; // Clear key hook + + IN_ClearKeysDown(); + + OldKeyVect = _dos_getvect(KeyInt); + _dos_setvect(KeyInt,INL_KeyService); +} + +/////////////////////////////////////////////////////////////////////////// +// +// INL_ShutKbd() - Restores keyboard control to the BIOS +// +/////////////////////////////////////////////////////////////////////////// +static void +INL_ShutKbd(void) +{ + pokeb(0x40,0x17,peekb(0x40,0x17) & 0xfaf0); // Clear ctrl/alt/shift flags + + _dos_setvect(KeyInt,OldKeyVect); +} + +/////////////////////////////////////////////////////////////////////////// +// +// INL_StartMouse() - Detects and sets up the mouse +// +/////////////////////////////////////////////////////////////////////////// +static boolean +INL_StartMouse(void) +{ + union REGS CPURegs; + if(_dos_getvect(MouseInt)) + { + Mouse(MReset); + if(CPURegs.x.ax == 0xffff) + return(true); + } + return(false); +} + +/////////////////////////////////////////////////////////////////////////// +// +// INL_ShutMouse() - Cleans up after the mouse +// +/////////////////////////////////////////////////////////////////////////// +static void +INL_ShutMouse(void) +{ +} + +// +// INL_SetJoyScale() - Sets up scaling values for the specified joystick +// +static void +INL_SetJoyScale(word joy) +{ + JoystickDef *def; + + def = &JoyDefs[joy]; + def->joyMultXL = JoyScaleMax / (def->threshMinX - def->joyMinX); + def->joyMultXH = JoyScaleMax / (def->joyMaxX - def->threshMaxX); + def->joyMultYL = JoyScaleMax / (def->threshMinY - def->joyMinY); + def->joyMultYH = JoyScaleMax / (def->joyMaxY - def->threshMaxY); +} + +/////////////////////////////////////////////////////////////////////////// +// +// IN_SetupJoy() - Sets up thresholding values and calls INL_SetJoyScale() +// to set up scaling values +// +/////////////////////////////////////////////////////////////////////////// +void +IN_SetupJoy(word joy,word minx,word maxx,word miny,word maxy) +{ + word d,r; + JoystickDef *def; + + def = &JoyDefs[joy]; + + def->joyMinX = minx; + def->joyMaxX = maxx; + r = maxx - minx; + d = r / 5; + def->threshMinX = ((r / 2) - d) + minx; + def->threshMaxX = ((r / 2) + d) + minx; + + def->joyMinY = miny; + def->joyMaxY = maxy; + r = maxy - miny; + d = r / 5; + def->threshMinY = ((r / 2) - d) + miny; + def->threshMaxY = ((r / 2) + d) + miny; + + INL_SetJoyScale(joy); +} + +/////////////////////////////////////////////////////////////////////////// +// +// INL_StartJoy() - Detects & auto-configures the specified joystick +// The auto-config assumes the joystick is centered +// +/////////////////////////////////////////////////////////////////////////// +static boolean +INL_StartJoy(word joy) +{ + word x,y; + + IN_GetJoyAbs(joy,&x,&y); + + if + ( + ((x == 0) || (x > MaxJoyValue - 10)) + || ((y == 0) || (y > MaxJoyValue - 10)) + ) + return(false); + else + { + IN_SetupJoy(joy,0,x * 2,0,y * 2); + return(true); + } +} + +/////////////////////////////////////////////////////////////////////////// +// +// INL_ShutJoy() - Cleans up the joystick stuff +// +/////////////////////////////////////////////////////////////////////////// +static void +INL_ShutJoy(word joy) +{ + JoysPresent[joy] = false; +} + +// Public routines + +/////////////////////////////////////////////////////////////////////////// +// +// IN_Startup() - Starts up the Input Mgr +// +/////////////////////////////////////////////////////////////////////////// +void +IN_Startup(void) +{ + boolean checkjoys,checkmouse; + word i; + + if (IN_Started) + return; + + checkjoys = true; + checkmouse = true; + for (i = 1;i < __argc;i++) + { + switch (US_CheckParm(__argv[i],ParmStrings)) + { + case 0: + checkjoys = false; + break; + case 1: + checkmouse = false; + break; + } + } + + INL_StartKbd(); + MousePresent = checkmouse? INL_StartMouse() : false; + + for (i = 0;i < MaxJoys;i++) + JoysPresent[i] = checkjoys? INL_StartJoy(i) : false; + + IN_Started = true; +} + +/////////////////////////////////////////////////////////////////////////// +// +// IN_Default() - Sets up default conditions for the Input Mgr +// +/////////////////////////////////////////////////////////////////////////// +void +IN_Default(boolean gotit,ControlType in) +{ + if + ( + (!gotit) + || ((in == ctrl_Joystick1) && !JoysPresent[0]) + || ((in == ctrl_Joystick2) && !JoysPresent[1]) + || ((in == ctrl_Mouse) && !MousePresent) + ) + in = ctrl_Keyboard1; + IN_SetControlType(0,in); +} + +/////////////////////////////////////////////////////////////////////////// +// +// IN_Shutdown() - Shuts down the Input Mgr +// +/////////////////////////////////////////////////////////////////////////// +void +IN_Shutdown(void) +{ + word i; + + if (!IN_Started) + return; + + INL_ShutMouse(); + for (i = 0;i < MaxJoys;i++) + INL_ShutJoy(i); + INL_ShutKbd(); + + IN_Started = false; +} + +/////////////////////////////////////////////////////////////////////////// +// +// IN_SetKeyHook() - Sets the routine that gets called by INL_KeyService() +// everytime a real make/break code gets hit +// +/////////////////////////////////////////////////////////////////////////// +void +IN_SetKeyHook(void (*hook)()) +{ + INL_KeyHook = hook; +} + +/////////////////////////////////////////////////////////////////////////// +// +// IN_ClearKeyDown() - Clears the keyboard array +// +/////////////////////////////////////////////////////////////////////////// +void +IN_ClearKeysDown(void) +{ + int i; + + LastScan = sc_None; + LastASCII = key_None; + for (i = 0;i < NumCodes;i++) + Keyboard[i] = false; +} + +/////////////////////////////////////////////////////////////////////////// +// +// INL_AdjustCursor() - Internal routine of common code from IN_ReadCursor() +// +/////////////////////////////////////////////////////////////////////////// +static void +INL_AdjustCursor(CursorInfo *info,word buttons,int dx,int dy) +{ + if (buttons & (1 << 0)) + info->button0 = true; + if (buttons & (1 << 1)) + info->button1 = true; + + info->x += dx; + info->y += dy; +} + +/////////////////////////////////////////////////////////////////////////// +// +// IN_ReadCursor() - Reads the input devices and fills in the cursor info +// struct +// +/////////////////////////////////////////////////////////////////////////// +void +IN_ReadCursor(CursorInfo *info) +{ + word i, + buttons; + int dx,dy; + + info->x = info->y = 0; + info->button0 = info->button1 = false; + + if (MousePresent) + { + buttons = INL_GetMouseButtons(); + INL_GetMouseDelta(&dx,&dy); + INL_AdjustCursor(info,buttons,dx,dy); + } + + for (i = 0;i < MaxJoys;i++) + { + if (!JoysPresent[i]) + continue; + + buttons = INL_GetJoyButtons(i); + INL_GetJoyDelta(i,&dx,&dy,true); + dx /= 64; + dy /= 64; + INL_AdjustCursor(info,buttons,dx,dy); + } +} + +/////////////////////////////////////////////////////////////////////////// +// +// IN_ReadControl() - Reads the device associated with the specified +// player and fills in the control info struct +// +/////////////////////////////////////////////////////////////////////////// +void +IN_ReadControl(int player,ControlInfo *info) +{ + boolean realdelta=false; // MDM (GAMERS EDGE) + byte dbyte; + word buttons; + int dx,dy; + Motion mx,my; + ControlType type; +register KeyboardDef *def; + + dx = dy = 0; + mx = my = motion_None; + buttons = 0; + +#if DEMO0 + if (DemoMode == demo_Playback) + { + dbyte = DemoBuffer[DemoOffset + 1]; + my = (dbyte & 3) - 1; + mx = ((dbyte >> 2) & 3) - 1; + buttons = (dbyte >> 4) & 3; + + if (!(--DemoBuffer[DemoOffset])) + { + DemoOffset += 2; + if (DemoOffset >= DemoSize) + DemoMode = demo_PlayDone; + } + + realdelta = false; + } + else if (DemoMode == demo_PlayDone) + Quit("Demo playback exceeded"); + else +#endif + { + // MDM begin (GAMERS EDGE) - added this block + ControlTypeUsed = ctrl_None; + + // Handle mouse input... + // + if ((MousePresent) && (ControlTypeUsed == ctrl_None)) + { + INL_GetMouseDelta(&dx,&dy); + buttons = INL_GetMouseButtons(); + realdelta = true; + if (dx || dy || buttons) + ControlTypeUsed = ctrl_Mouse; + } + + // Handle joystick input... + // + if ((JoystickCalibrated) && (ControlTypeUsed == ctrl_None)) + { + type = ctrl_Joystick1; + INL_GetJoyDelta(type - ctrl_Joystick,&dx,&dy,false); + buttons = INL_GetJoyButtons(type - ctrl_Joystick); + realdelta = true; + if (dx || dy || buttons) + ControlTypeUsed = ctrl_Joystick; + } + + // Handle keyboard input... + // + if (ControlTypeUsed == ctrl_None) + { + type = ctrl_Keyboard1; + def = &KbdDefs[type - ctrl_Keyboard]; + + if (Keyboard[def->upleft]) + mx = motion_Left,my = motion_Up; + else if (Keyboard[def->upright]) + mx = motion_Right,my = motion_Up; + else if (Keyboard[def->downleft]) + mx = motion_Left,my = motion_Down; + else if (Keyboard[def->downright]) + mx = motion_Right,my = motion_Down; + + if (Keyboard[def->up]) + my = motion_Up; + else if (Keyboard[def->down]) + my = motion_Down; + + if (Keyboard[def->left]) + mx = motion_Left; + else if (Keyboard[def->right]) + mx = motion_Right; + + if (Keyboard[def->button0]) + buttons += 1 << 0; + if (Keyboard[def->button1]) + buttons += 1 << 1; + realdelta = false; + if (mx || my || buttons) + ControlTypeUsed = ctrl_Keyboard; + } // MDM end (GAMERS EDGE) + } + + if (realdelta) + { + mx = (dx < 0)? motion_Left : ((dx > 0)? motion_Right : motion_None); + my = (dy < 0)? motion_Up : ((dy > 0)? motion_Down : motion_None); + } + else + { + dx = mx * 127; + dy = my * 127; + } + + info->x = dx; + info->xaxis = mx; + info->y = dy; + info->yaxis = my; + info->button0 = buttons & (1 << 0); + info->button1 = buttons & (1 << 1); + info->dir = DirTable[((my + 1) * 3) + (mx + 1)]; + +#if DEMO0 + if (DemoMode == demo_Record) + { + // Pack the control info into a byte + dbyte = (buttons << 4) | ((mx + 1) << 2) | (my + 1); + + if + ( + (DemoBuffer[DemoOffset + 1] == dbyte) + && (DemoBuffer[DemoOffset] < 255) + ) + (DemoBuffer[DemoOffset])++; + else + { + if (DemoOffset || DemoBuffer[DemoOffset]) + DemoOffset += 2; + + if (DemoOffset >= DemoSize) + Quit("Demo buffer overflow"); + + DemoBuffer[DemoOffset] = 1; + DemoBuffer[DemoOffset + 1] = dbyte; + } + } +#endif +} + +#if 0 +/////////////////////////////////////////////////////////////////////////// +// +// IN_ReadControl() - Reads the device associated with the specified +// player and fills in the control info struct +// +/////////////////////////////////////////////////////////////////////////// +void +IN_ReadControl(int player,ControlInfo *info) +{ + boolean realdelta; + byte dbyte; + word buttons; + int dx,dy; + Motion mx,my; + ControlType type; +register KeyboardDef *def; + + dx = dy = 0; + mx = my = motion_None; + buttons = 0; + +#if DEMO0 + if (DemoMode == demo_Playback) + { + dbyte = DemoBuffer[DemoOffset + 1]; + my = (dbyte & 3) - 1; + mx = ((dbyte >> 2) & 3) - 1; + buttons = (dbyte >> 4) & 3; + + if (!(--DemoBuffer[DemoOffset])) + { + DemoOffset += 2; + if (DemoOffset >= DemoSize) + DemoMode = demo_PlayDone; + } + + realdelta = false; + } + else if (DemoMode == demo_PlayDone) + Quit("Demo playback exceeded"); + else +#endif + { + switch (type = Controls[player]) + { + case ctrl_Keyboard1: + case ctrl_Keyboard2: + def = &KbdDefs[type - ctrl_Keyboard]; + + if (Keyboard[def->upleft]) + mx = motion_Left,my = motion_Up; + else if (Keyboard[def->upright]) + mx = motion_Right,my = motion_Up; + else if (Keyboard[def->downleft]) + mx = motion_Left,my = motion_Down; + else if (Keyboard[def->downright]) + mx = motion_Right,my = motion_Down; + + if (Keyboard[def->up]) + my = motion_Up; + else if (Keyboard[def->down]) + my = motion_Down; + + if (Keyboard[def->left]) + mx = motion_Left; + else if (Keyboard[def->right]) + mx = motion_Right; + + if (Keyboard[def->button0]) + buttons += 1 << 0; + if (Keyboard[def->button1]) + buttons += 1 << 1; + realdelta = false; + break; + case ctrl_Joystick1: + case ctrl_Joystick2: + INL_GetJoyDelta(type - ctrl_Joystick,&dx,&dy,false); + buttons = INL_GetJoyButtons(type - ctrl_Joystick); + realdelta = true; + break; + case ctrl_Mouse: + INL_GetMouseDelta(&dx,&dy); + buttons = INL_GetMouseButtons(); + realdelta = true; + break; + } + } + + if (realdelta) + { + mx = (dx < 0)? motion_Left : ((dx > 0)? motion_Right : motion_None); + my = (dy < 0)? motion_Up : ((dy > 0)? motion_Down : motion_None); + } + else + { + dx = mx * 127; + dy = my * 127; + } + + info->x = dx; + info->xaxis = mx; + info->y = dy; + info->yaxis = my; + info->button0 = buttons & (1 << 0); + info->button1 = buttons & (1 << 1); + info->dir = DirTable[((my + 1) * 3) + (mx + 1)]; + +#if DEMO0 + if (DemoMode == demo_Record) + { + // Pack the control info into a byte + dbyte = (buttons << 4) | ((mx + 1) << 2) | (my + 1); + + if + ( + (DemoBuffer[DemoOffset + 1] == dbyte) + && (DemoBuffer[DemoOffset] < 255) + ) + (DemoBuffer[DemoOffset])++; + else + { + if (DemoOffset || DemoBuffer[DemoOffset]) + DemoOffset += 2; + + if (DemoOffset >= DemoSize) + Quit("Demo buffer overflow"); + + DemoBuffer[DemoOffset] = 1; + DemoBuffer[DemoOffset + 1] = dbyte; + } + } +#endif +} +#endif + +/////////////////////////////////////////////////////////////////////////// +// +// IN_SetControlType() - Sets the control type to be used by the specified +// player +// +/////////////////////////////////////////////////////////////////////////// +void +IN_SetControlType(int player,ControlType type) +{ + // DEBUG - check that requested type is present? + Controls[player] = type; +} + +#if DEMO0 +/////////////////////////////////////////////////////////////////////////// +// +// IN_StartDemoRecord() - Starts the demo recording, using a buffer the +// size passed. Returns if the buffer allocation was successful +// +/////////////////////////////////////////////////////////////////////////// +boolean +IN_StartDemoRecord(word bufsize) +{ + if (!bufsize) + return(false); + + MM_GetPtr((memptr *)&DemoBuffer,bufsize); + DemoMode = demo_Record; + DemoSize = bufsize & ~1; + DemoOffset = 0; + DemoBuffer[0] = DemoBuffer[1] = 0; + + return(true); +} + +/////////////////////////////////////////////////////////////////////////// +// +// IN_StartDemoPlayback() - Plays back the demo pointed to of the given size +// +/////////////////////////////////////////////////////////////////////////// +void +IN_StartDemoPlayback(byte /*__segment*/ *buffer,word bufsize) +{ + DemoBuffer = buffer; + DemoMode = demo_Playback; + DemoSize = bufsize & ~1; + DemoOffset = 0; +} + +/////////////////////////////////////////////////////////////////////////// +// +// IN_StopDemo() - Turns off demo mode +// +/////////////////////////////////////////////////////////////////////////// +void +IN_StopDemo(void) +{ + if ((DemoMode == demo_Record) && DemoOffset) + DemoOffset += 2; + + DemoMode = demo_Off; +} + +/////////////////////////////////////////////////////////////////////////// +// +// IN_FreeDemoBuffer() - Frees the demo buffer, if it's been allocated +// +/////////////////////////////////////////////////////////////////////////// +void +IN_FreeDemoBuffer(void) +{ + if (DemoBuffer) + MM_FreePtr((memptr *)&DemoBuffer); +} +#endif + + +#if 0 +/////////////////////////////////////////////////////////////////////////// +// +// IN_GetScanName() - Returns a string containing the name of the +// specified scan code +// +/////////////////////////////////////////////////////////////////////////// +byte * +IN_GetScanName(ScanCode scan) +{ + byte **p; + ScanCode far *s; + + for (s = ExtScanCodes,p = ExtScanNames;*s;p++,s++) + if (*s == scan) + return(*p); + + return(ScanNames[scan]); +} +#endif + + +/////////////////////////////////////////////////////////////////////////// +// +// IN_WaitForKey() - Waits for a scan code, then clears LastScan and +// returns the scan code +// +/////////////////////////////////////////////////////////////////////////// +ScanCode +IN_WaitForKey(void) +{ + ScanCode result; + + while (!(result = LastScan)) + ; + LastScan = 0; + return(result); +} + +/////////////////////////////////////////////////////////////////////////// +// +// IN_WaitForASCII() - Waits for an ASCII char, then clears LastASCII and +// returns the ASCII value +// +/////////////////////////////////////////////////////////////////////////// +char +IN_WaitForASCII(void) +{ + char result; + + while (!(result = LastASCII)) + ; + LastASCII = '\0'; + return(result); +} + +/////////////////////////////////////////////////////////////////////////// +// +// IN_AckBack() - Waits for either an ASCII keypress or a button press +// +/////////////////////////////////////////////////////////////////////////// +void +IN_AckBack(void) +{ + word i; + + while (!LastScan) + { + if (MousePresent) + { + if (INL_GetMouseButtons()) + { + while (INL_GetMouseButtons()) + ; + return; + } + } + + for (i = 0;i < MaxJoys;i++) + { + if (JoysPresent[i]) + { + if (IN_GetJoyButtonsDB(i)) + { + while (IN_GetJoyButtonsDB(i)) + ; + return; + } + } + } + } + + IN_ClearKey(LastScan); + LastScan = sc_None; +} + +/////////////////////////////////////////////////////////////////////////// +// +// IN_Ack() - Clears user input & then calls IN_AckBack() +// +/////////////////////////////////////////////////////////////////////////// +void +IN_Ack(void) +{ + word i; + + IN_ClearKey(LastScan); + LastScan = sc_None; + + if (MousePresent) + while (INL_GetMouseButtons()) + ; + for (i = 0;i < MaxJoys;i++) + if (JoysPresent[i]) + while (IN_GetJoyButtonsDB(i)) + ; + + IN_AckBack(); +} + +/////////////////////////////////////////////////////////////////////////// +// +// IN_IsUserInput() - Returns true if a key has been pressed or a button +// is down +// +/////////////////////////////////////////////////////////////////////////// +boolean +IN_IsUserInput(void) +{ + boolean result; + word i; + + result = LastScan; + + if (MousePresent) + if (INL_GetMouseButtons()) + result = true; + + for (i = 0;i < MaxJoys;i++) + if (JoysPresent[i]) + if (INL_GetJoyButtons(i)) + result = true; + + return(result); +} + +/////////////////////////////////////////////////////////////////////////// +// +// IN_UserInput() - Waits for the specified delay time (in ticks) or the +// user pressing a key or a mouse button. If the clear flag is set, it +// then either clears the key or waits for the user to let the mouse +// button up. +// +/////////////////////////////////////////////////////////////////////////// +boolean +IN_UserInput(dword delay,boolean clear) +{ + dword TimeCount = *clockdw; + dword lasttime; + + lasttime = TimeCount; + do + { + if (IN_IsUserInput()) + { + if (clear) + IN_AckBack(); + return(true); + } + } while (TimeCount - lasttime < delay); + return(false); +} diff --git a/16/cawat/16_in.h b/16/cawat/16_in.h index 92c9fdd7..e5adb56d 100644 --- a/16/cawat/16_in.h +++ b/16/cawat/16_in.h @@ -25,8 +25,9 @@ #ifndef __16_IN__ #define __16_IN__ - + #include "lib_head.h" +#include "16_us.h" #ifndef __TYPES__ //#include "ID_Types.h" @@ -35,6 +36,13 @@ #ifdef __DEBUG__ #define __DEBUG_InputMgr__ #endif + +#define KeyInt 9 // The keyboard ISR number + +// Stuff for the joystick +#define JoyScaleMax 32768 +#define JoyScaleShift 8 +#define MaxJoyValue 5000 #define MaxPlayers 4 #define MaxKbds 2 @@ -178,10 +186,12 @@ extern ControlType Controls[MaxPlayers]; extern boolean JoystickCalibrated; // MDM (GAMERS EDGE) - added extern ControlType ControlTypeUsed; // MDM (GAMERS EDGE) - added - + +#ifdef DEMO0 extern Demo DemoMode; -extern byte /*_seg*/ *DemoBuffer; +extern byte __segment *DemoBuffer; extern word DemoOffset,DemoSize; +#endif // Function prototypes #define IN_KeyDown(code) (Keyboard[(code)]) @@ -198,13 +208,18 @@ extern void IN_Startup(void),IN_Shutdown(void), IN_SetControlType(int,ControlType), IN_GetJoyAbs(word joy,word *xp,word *yp), IN_SetupJoy(word joy,word minx,word maxx, - word miny,word maxy), - IN_StartDemoPlayback(byte /*_seg*/ *buffer,word bufsize), - IN_StopDemo(void),IN_FreeDemoBuffer(void), + word miny,word maxy), +#ifdef DEMO0 + IN_StartDemoPlayback(byte __segment *buffer,word bufsize), + IN_StopDemo(void),IN_FreeDemoBuffer(void), +#endif IN_Ack(void),IN_AckBack(void); extern boolean IN_UserInput(dword delay,boolean clear), - IN_IsUserInput(void), - IN_StartDemoRecord(word bufsize); + IN_IsUserInput(void) +#ifdef DEMO0 + , IN_StartDemoRecord(word bufsize) +#endif +; extern byte *IN_GetScanName(ScanCode); extern char IN_WaitForASCII(void); extern ScanCode IN_WaitForKey(void); diff --git a/16/cawat/16_us.c b/16/cawat/16_us.c new file mode 100644 index 00000000..850feb56 --- /dev/null +++ b/16/cawat/16_us.c @@ -0,0 +1,83 @@ +/* Catacomb Armageddon Source Code + * Copyright (C) 1993-2014 Flat Rock Software + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +// +// ID Engine +// ID_US.c - User Manager +// v1.0d1 +// By Jason Blochowiak +// + +// +// 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 +// abortgame - Flag set if the current game should be aborted (if a load +// game fails) +// loadedgame - Flag set if a game was loaded +// abortprogram - Normally nil, this points to a terminal error message +// if the program needs to abort +// restartgame - Normally set to gd_Continue, this is set to one of the +// difficulty levels if a new game should be started +// PrintX, PrintY - Where the User Mgr will print (global coords) +// WindowX,WindowY,WindowW,WindowH - The dimensions of the current +// window +// + +// DEBUG - handle LPT3 for Sound Source + +#include "16_us.h" + +/////////////////////////////////////////////////////////////////////////// +// +// US_CheckParm() - checks to see if a string matches one of a set of +// strings. The check is case insensitive. The routine returns the +// index of the string that matched, or -1 if no matches were found +// +/////////////////////////////////////////////////////////////////////////// +int +US_CheckParm(char *parm,char **strings) +{ + char cp,cs, + *p,*s; + int i; + + while (!isalpha(*parm)) // Skip non-alphas + parm++; + + for (i = 0;*strings && **strings;i++) + { + for (s = *strings++,p = parm,cs = cp = 0;cs == cp;) + { + cs = *s++; + if (!cs) + return(i); + cp = *p++; + + if (isupper(cs)) + cs = tolower(cs); + if (isupper(cp)) + cp = tolower(cp); + } + } + return(-1); +} diff --git a/16/cawat/16_us.h b/16/cawat/16_us.h new file mode 100644 index 00000000..8bcfa006 --- /dev/null +++ b/16/cawat/16_us.h @@ -0,0 +1,36 @@ +/* Catacomb Armageddon Source Code + * Copyright (C) 1993-2014 Flat Rock Software + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +// +// ID Engine +// ID_US.h - Header file for the User Manager +// v1.0d1 +// By Jason Blochowiak +// +#ifndef __ID_US__ +#define __ID_US__ + +#include "lib_head.h" + +#ifdef __DEBUG__ +#define __DEBUG_UserMgr__ +#endif + +extern int US_CheckParm(char *parm,char **strings); + +#endif diff --git a/16/cawat/ID_IN.C b/16/cawat/ID_IN.C index 284a6fe4..7b4421e9 100644 --- a/16/cawat/ID_IN.C +++ b/16/cawat/ID_IN.C @@ -60,9 +60,9 @@ JoystickDef JoyDefs[MaxJoys]; ControlType Controls[MaxPlayers]; -// Demo DemoMode = demo_Off; -// byte /*_1seg*/ *DemoBuffer; -// word DemoOffset,DemoSize; + Demo DemoMode = demo_Off; + byte _seg *DemoBuffer; + word DemoOffset,DemoSize; // Internal variables static boolean IN_Started; diff --git a/16/cawat/cawat.bfproject b/16/cawat/cawat.bfproject index 3b0d54b7..6d630146 100644 --- a/16/cawat/cawat.bfproject +++ b/16/cawat/cawat.bfproject @@ -1,86 +1,12 @@ -c2e.convert_special: 0 -e2c.convert_num: 0 -openfiles: /dos/z/16/src/lib/ems.c:3881:957:0: -openfiles: /dos/z/16/src/lib/ems.h:944:0:0: -openfiles: /dos/z/keen-src/id_mm.c:3423:3343:0: -openfiles: /dos/z/16/16/cawat/16_mm.c:4757:4322:1: -openfiles: /dos/z/16/16/cawat/16_mm.h:0:0:0: -snr_recursion_level: 0 -convertcolumn_horizontally: 0 -adv_open_matchname: 0 -show_mbhl: 1 -view_line_numbers: 1 -fb_show_backup_f: 0 -htmlbar_thumbnailwidth: 300 -view_left_panel: 0 -default_mime_type: text/plain -e2c.convert_xml: 1 -c2e.convert_iso: 0 -opendir: file:///dos/z/16/16/cawat -wrap_text_default: 0 -bookmarks_filename_mode: 1 -ssearch_text: _seg -snr_casesens: 0 -view_blocks: 1 -name: cawatcom -replacelist: /*_1seg*/ -replacelist: /*_1seg*/ -replacelist: \t\t -fb_show_hidden_f: 0 -editor_tab_width: 4 -show_visible_spacing: 0 -view_statusbar: 1 -display_right_margin: 0 -c2e.IE_apos_workaround: 0 -outputb_scroll_mode: 0 -leftpanel_active_tab: 0 -enable_syntax_scan: 1 -ssearch_regex: 0 -e2c.convert_iso: 0 -ssearch_casesens: 0 -charmap_block: 1 -recent_files: file:///dos/z/bakapee.asm -recent_files: file:///dos/z/16/src/lib/ems.c -recent_files: file:///dos/z/16/src/lib/ems.h -recent_files: file:///dos/z/keen-src/id_mm.c -recent_files: file:///dos/z/16/16/cawat/16_mm.err -recent_files: file:///dos/z/16/16/cawat/16_mm.h -recent_files: file:///dos/z/16/16/cawat/16_mm.c -snr_replacetype: 0 -savedir: file:///dos/z/16/16/cawat -spell_check_default: 1 -spell_insert_entities: 0 -last_filefilter: -htmlbar_notebooktab: 0 -view_blockstack: 1 -snr_escape_chars: 1 +view_main_toolbar: 1 +bmarksearchmode: 0 +snr_scope: 0 +snr_type: 0 +view_cline: 0 +editor_indent_wspaces: 0 +c2e.convert_xml: 1 +snr_dotmatchall: 0 htmlbar_view: 0 -spell_lang: en -ssearch_dotmatchall: 0 -searchlist: _seg -searchlist: _1seg -searchlist: p_1seg -searchlist: p1seg -searchlist: pseg -searchlist: peg -searchlist: pg -searchlist: _1 -searchlist: _seg -searchlist: asm\t -searchlist: lo -searchlist: offset -searchlist: emmname -searchlist: seg -searchlist: _seg -autocomplete: 1 -outputb_show_all_output: 0 -bookmarks_show_mode: 0 -snippets_show_as_menu: 0 -adv_open_recursive: 0 -encoding: SHIFT_JIS -e2c.convert_special: 0 -autoindent: 1 -fb_viewmode: 0 filegloblist: *.txt filegloblist: *.shtml filegloblist: *.py @@ -96,16 +22,87 @@ filegloblist: *.cpp filegloblist: *.cgi filegloblist: *.c filegloblist: * -recent_dirs: file:///dos/z/cawat fb_focus_follow: 1 -ssearch_unescape: 0 +adv_open_recursive: 0 +recent_dirs: file:///dos/z/cawat +encoding: UTF-8 +autoindent: 1 +e2c.convert_special: 0 +fb_viewmode: 0 +snippets_show_as_menu: 0 +bookmarks_show_mode: 0 +outputb_show_all_output: 0 +autocomplete: 1 +searchlist: ¥ +searchlist: _seg +searchlist: _1seg +searchlist: p_1seg +searchlist: p1seg +searchlist: pseg +searchlist: peg +searchlist: pg +searchlist: _1 +searchlist: _seg +spell_lang: en c2e.convert_symbol: 0 -snr_dotmatchall: 0 -c2e.convert_xml: 1 -editor_indent_wspaces: 0 -view_cline: 0 -snr_type: 0 -snr_scope: 0 -bmarksearchmode: 0 -view_main_toolbar: 1 +snr_escape_chars: 1 +view_blockstack: 1 +htmlbar_notebooktab: 0 +last_filefilter: +spell_insert_entities: 0 +spell_check_default: 1 +savedir: file:///dos/z/16/16/cawat +files: /dos/z/16/16/cawat/16_in.c +files: /dos/z/16/16/cawat/16_in.h +files: /dos/fdos/watcom/h/PORTABLE.H +files: /dos/fdos/watcom/h/P-WATCOM.H +files: /dos/z/16/16/cawat/lib_head.h +files: /dos/z/16/16/cawat/ID_MM.C +snr_replacetype: 0 +recent_files: file:///dos/z/16/16/cawat/ID_MM.C +recent_files: file:///dos/z/16/16/cawat/lib_head.h +recent_files: file:///dos/z/16/16/cawat/16_in.h +recent_files: file:///dos/fdos/watcom/h/P-WATCOM.H +recent_files: file:///dos/fdos/watcom/h/PORTABLE.H +recent_files: file:///dos/z/16/16/cawat/16_in.c +recent_files: file:///dos/z/bakapee.asm +recent_files: file:///dos/z/16/src/lib/ems.c +recent_files: file:///dos/z/16/src/lib/ems.h +recent_files: file:///dos/z/keen-src/id_mm.c +recent_files: file:///dos/z/16/16/cawat/16_mm.err +recent_files: file:///dos/z/16/16/cawat/16_mm.h +recent_files: file:///dos/z/16/16/cawat/16_mm.c +charmap_block: 1 +e2c.convert_iso: 0 +enable_syntax_scan: 1 +outputb_scroll_mode: 0 +leftpanel_active_tab: 0 +c2e.IE_apos_workaround: 0 +display_right_margin: 0 +replacelist: \\ +replacelist: /*_1seg*/ +replacelist: /*_1seg*/ +replacelist: \t\t +editor_tab_width: 4 +view_statusbar: 1 +fb_show_hidden_f: 0 +name: cawatcom +view_blocks: 1 +snr_casesens: 0 +c2e.convert_iso: 0 +bookmarks_filename_mode: 1 +wrap_text_default: 0 +opendir: file:///dos/z/16/16/cawat +e2c.convert_xml: 1 +default_mime_type: text/plain +view_left_panel: 0 +htmlbar_thumbnailwidth: 300 +fb_show_backup_f: 0 +view_line_numbers: 1 +show_mbhl: 1 +adv_open_matchname: 0 +convertcolumn_horizontally: 0 +snr_recursion_level: 0 e2c.convert_symbol: 0 +e2c.convert_num: 0 +c2e.convert_special: 0 diff --git a/16/cawat/lib_head.h b/16/cawat/lib_head.h index d77af4da..dc676516 100644 --- a/16/cawat/lib_head.h +++ b/16/cawat/lib_head.h @@ -26,17 +26,19 @@ #ifndef _LIB_HEAD_H_ #define _LIB_HEAD_H_ +#include #include +#include +#include +#include #include -#include -//#include "" -//#include "" -//#include "ID_CA.H" -//#include "AUDIOARM.H" #include "types.h" - -#ifndef REGS -struct REGS CPURegs; -#endif + +dword far* clockdw= (dword far*) 0x046C; /* 18.2hz clock */ + +#define peekb(segm,ofs) (*(byte far*)MK_FP((segm),(ofs))) +#define peekw(segm,ofs) (*(word far*)MK_FP((segm),(ofs))) +#define pokeb(segm,ofs,value) (peekb((segm),(ofs)) = (byte)(value)) +#define pokew(segm,ofs,value) (peekw((segm),(ofs)) = (word)(value)) #endif/*_LIB_HEAD_H_*/ diff --git a/16/cawat/types.h b/16/cawat/types.h index 51b7d917..9b0081ac 100644 --- a/16/cawat/types.h +++ b/16/cawat/types.h @@ -2,6 +2,7 @@ #define _TYPE_H_ typedef enum {false,true} boolean; +//typedef __segment pseg; #define nil ((void *)0) typedef unsigned char byte; diff --git a/emmtest.exe b/emmtest.exe index fb51561fba2318cd5e9c911d768dcabbfcce7c56..1afe9df7ab0f53fa981d5d4e8988f04372d9ba45 100644 GIT binary patch delta 2777 zcmai032anV6n*dWX9abzr4_UtDAqDi$CirKq56+HKSELGd^etYNKd+zp@|7M;& zEf1fP11AFV8TunIRhCmuut1hlWw5}0v0sSqB$>fHDQRP{KyNG-f>sAJXkT!=tr?1w zWOW7&20gZ$p_#1Z4@x04!9%m31}-maZ)-2Usy%KlZLbUj8Y>$b{pGZ<_Fa1mSot;O z*ZE`>)z)SCFM{Dc841T=k8D5&qZt;vC=f;yKt3LfetC)m?;@(3)^`^So-tNn$XuR+ zdxW$oY4^bAV=0C7o8d&#j0w4teT~0hFBK2##`^#(@Cf4*pfny~8~_@`BaEMcsLk? zK1Uv*V14$u0Yvu8Rmdp^Xm$OS*=#U6p}(%biyHm%Rp!#Pv)-SL=7jMI^w0G}isN3u z$%dlIiaQDYxIV=uge%qAu}nA+AHX)qK}k0?FaEp|#&z!@ljQc=-Zxaq924J_l?84{*DzldX-43+Qz7FVKp#Ap! zcGaK6tdaYR#-a*Nb~bm6)&Fd?S`mSWOvhq}aTRw87^ZUzcRkU7haaGWlxO)}%By(w^){^Pm=}0r%43`b=7nFN8 zmK^Rsw$8ZGnpjQe^19`){j-@X)+%+>&CEiAUG76FS=>stbm7cVYnyO6;m#V%Q`~F0 zzqzn@RQEk_DI8m&+<7a|>ZG>f8Kcc?8eH1OCX{=E-LYq>wh}x08}XO7waw4!I|AHj zhGKD}(~MSx5+T8NZ8X$@n-ya>{_!H>?=V(8A5>+aI%aeVzKtpa&0$mU-BY_N9K($* zbU2nrI^$th_)@`Vbu69;MIzy4f^QBO$~(<)P1s0?W147Y1K7@`f^P;W^b)JO*6gt%DNHqBU)kl z`c{tQjhb^2B{|29?E2VIn#&1}u^1Xw12M(FbUmB#5)K>I4sW7EYkk@`IdnmHu5^>X+b7pi zYqwWEMO~2l=s{Q((5~(h`6>Mdyo4tAc;(YHx5uX)olGlxa%CRf-Q%t4nZm6GtGLAZ z!|LGc4w@!BkW!r1-9loVahNn__zxyr0%v|0+ImA}wQw3GEbm`o|NEWw@<8t|ntl)` F`ft>pHgNy| delta 2842 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 delta 2429 zcmai04Nz276u$TFuL6o<;Lpga1h|06e`;YVqO7p;vxq}2GTZKZz_5S3x9fysLRh%j zRK~GsaI}e;v~+UHaK?1Rs5I%%CTS+kF)b&xKhwq;qf$HfKAdDseGKP*=R4m$=iK++ zz59+`rd@x~cRnqlKf`AwNwgDwFG;11kYGzSuvvtB14XtZdIB13sVpN4Hri4QnOTIG zVL@>m9JR%=f-E>=i_c$631Ng^%=i@IqIu5cs-&n+M<}33&Y;s1P@UNYPE~O`C7%lpEbPJQgOut<=jjPq;0`sdl8WtRO=^hfbVN6FYqZ#IcSsG$x9j?m zk5IALet5YoFM$(U>ntAcT!bFR9%&DpDa%aYCFDcsTUnlnMWe-7vOQ~>h()1a#9Gjf zS`}#W5EIU?!!lk--iq3Jx(dC#7D0`!R!8Irq7AwYh`JCR)g48&1yQm-8SgmO zABO|wS)+lKXDrfsxLMABTRGayDLEErdGx#V@>m32`b}D{dY%jKno^!IUC34<@u9xb zAlD(tG~^gW$@5&+1Min-)M@1$A(s+DPL#XbVu!1r!vt=_C4+nt!C}K;1Cf73blUKX zR-hUO-bYErtcUMiL3VJt(QTBg5V(vkqv&#gvpuk8+UupD-)$^5@wEH3*kEOr7Tbq@tw|LzGg^H0 zCRaV6Z4VRrou=1BY=stUteT_6YS4ez^tp)b;jtdrTa}x}JN>_v^`hjA=^r6aH4FI! zM|z32u(CiyMFVm-A7*2#aBqKehi_8~CKzwdLmQ#%v}EfYId`nxfszulEacy5^0SWY zJIYU?WQ}=~kk7?a3RgD2Iy?PNE1QFoo#sPA{xp~4GuvF9Yvg))UGHG^-}kj$M(lGn z`EelRBm8HigA#H9?|nXw#de!t4iJ7i729hhh48beJSh3`03#D{n-+NkDxPw7!Vei7 zZGJW6@_Ho?;U@_aMR>}WNpgtX(0mLA+=L$#7_3?(X+Gb$=r2|ziSUhQcLmWUd~+@L z`!t7d1pMjXJb#@XE`Ge)iP;1%HRsa~IMSTN%u(=bb0W=xD6fUOARX;`C`G#yn!QWt zRp|BR($#R@TgalvK#DIh#x{l!JzImzD$=LHIA2`M$74Cu8N=^Ll3?OvIkQ7B>4JGg zFkcJiFV2`w3T8V@55+;dYNF%doG+1Pg28X4dtf%&vry}|(D~4c)&t#WH^M%&FTx45 zdtu0LjkyuWD{aBb9=%cIeP{w_c8a{$eMZ^@?tqoH!1DnMeG7J>{Sv-F#sOCYx%3jG z2Q4%eN`uyz%?W&FR5oA752EW6g85A_wSsA!$Tf>|xTan(U4q#rm{P&)7tAHWToBAf z!5q)!vnFzeStdb2OCntY%Ug1>t!G;-^f>H5Tmh#LN8lRTKA5Ul=s74x|nzBYM9LUt#+9@GI(H4uD&L diff --git a/fmemtest.exe b/fmemtest.exe index 951d244027f6f6ae31868851c8f7a59e8a254534..7904c7d68723ec8cab90dcb366ae7f50c3d64091 100644 GIT binary patch delta 688 zcmZwFUr19?90&0GJ8m}%v)TG1DW1xjyAWX;S(wGWGo8r>ViInF#n8L$w2b?`jns+xUP&3O^oHp*nqol;AsstT3z&>a zszQmi@r}KS^0*`){OluiuyeQ&m*SU-(YT+on2Brj9G`fg;tzWOwFyZ{w6LQv*&E2R z)3}$=#Og*A6LoYLU%Ax>)zm1BMpM!gbg?B|;6BgNHSY`WBoeJ`Ck(3lawqPg~pg~NeBt1r+{eUG_38a=~bE66`4U~BXSrY*^hEawqC<@_27wygQM!#QcZ d+1Xp^upZsHzFpNdW&eLJv!T9|D#kB5s_`Hge#&Xb&lJ0Wc;A+OMZiigtM_tJ8P<@J0y}qD_d#y-@ zwsxE)MG=Y}!WrTGP^WpuO64rGcXTM1GKbA`LzcOx!?bdPW;&b7j;5^9wn5B<7M)>U zPCsz5OWk#k_q(e4)@|eV5+!rzFDZ&M1CfQ;$E|cCq>q@2NZN^cb_6B%K7O$s*k(v7-~hXVupxzW1I7%MCh)+}=mp;Jz=N-B z5SyctvS?+e(alaF!@k5sR1-BDF&Ay7Bly6r9DYVMx{MvBq^Ho?5)!6HCdSPG{l)@! zny||D;xG3Xp~j?e)Z$pIneO01Owt0bv!5`_He!iAj?b)xns|VZ3&y3Wb|DtuOII)% zm-GaA_6v&a7L?f_T>X*;(9TYxhb>~5J&8&78uIKT6xkJ&`=!|AMqNUsQ|L@c8iSG0 zLf_o{vO?c)zhje4CG1Kl_4W3Amh*g7OJ!y!b|sW9yh>>F9N!ZGz8Y^*qh)j_B{d+! sxrw`+-@>z`+`i_qPnzkp_tx4}VgTi2qq@85|9()xJ8+n)AM%g<2c}Tc=Kufz diff --git a/fonttest.exe b/fonttest.exe index 5adb78fc8d8131a2995a95fb049ad455879bc4c2..c0d24493c8841a7632ebb7feaf6028c574323bc0 100644 GIT binary patch delta 569 zcmZ9~Pe@cz6bA5nrje2K>7*zlgcq^WC&)OC!O+7(L}eC}TF-I*yeR`AC`K2WxQSL_ zo0!FCs|=Nh{!mmD!VE%GgsXDXMj~7Y4Jgr~h0FTxEM2@GALrc5y`1|tHl?&FZ+wn4 z;F!~1Ro9|a7sg|aIPU}{hEb=ZYPwyiK2rV3GF4e^{?u9ihSa7W}Ze!5XPgA)^477(F-F+R~RcTr&egx9nQ z+q55lXdLxPEprIdI*ig7X6ZE)lD3plq+#sQE3hWD6wyt0k)Som)8n{Ld-00S<12lL z-}E!Al$J~Arnixx&yi0>r48%MaePeKGJ^x=Rn(-T;>U%wmM&bSF7D75SfxMkfrhY4 zhwv|LS0{pIT0MfbWJvBIp0TABb95e$Xc=1>%@LI87y?-{nhyFBBlJ72(^@Ri0X(HQ zu|=0rrX>VCTZR##C1gF@>TNQI?L^EI1u)TGsHz(^hM<>ApW}x?$6`hAWl5 kO66o_eIBQCW++2Bo41-}zJUVsTNIgpVJDaNKjRPaA2E5O5dZ)H delta 707 zcmY+CPiPZS5QpDvHcf21i6JpILA#JvbQ>F}N&UB0uu@A=TZ2j6#6(3zQ4eiJkRAmu zB0|gWP(@Kh8x#>NVh++O2p*&q)Qg~aumweWsCxC{%mWWD?8orUykXw#zL=%@EIl<` z3c=^L`5O~Tbs)bzirwyN%3;Xe=s(e>R8Cwdqm(lERmwE>?!+CpJ#_Lv_3VSYsfD)S z&tZpdU_&8G-%u*p+Su5p}Car#H)(R>{=>ocoHm#so?6EGhH;r97 zTa&EyQkz9>a+vg@R-{2{;sNP!U1~aaXmekiZ6Wdho^>1;s*f|K@oA0NxSVJn(dMT% znDAnO#-Nn!!$>7z<#hZzF6D$7FG^Kl*r6rNG1K_YEF*HnrswEleny@dz!&+a}=9o68^k!<>yzY=gExP8THk(PQn$Hvyh=rx`AQpxbv$u*|HZsp3#Cx|wwx zXJ&A8)~$q+b7Npz6>Q%yG>kzEn%* I1O7Gt0$4tz=l}o! diff --git a/maptest.exe b/maptest.exe index 36d8c98a74b553d2acbc05b9c2cf40f98efc0d97..9d02cb1c9a3f0788609c2a04b0796e827bce0a41 100644 GIT binary patch delta 8822 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 aq}EXLPqbvkBnzgaOP^n@i+re2QT`A5p9-V^ delta 8953 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 delta 14439 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 diff --git a/pcxtest.exe b/pcxtest.exe index b30c56fa73afedfcd567a26873581b7e2ca624c3..6339890648c3a00c06345d2a5d31c77d88dbb2ed 100644 GIT binary patch delta 7404 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 Wm)rkEQ>=p9J?`Q*gP{ON>Hh$5GbF13 delta 7551 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 delta 12024 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 f8Wl+=#nR)m)fQRn7kI8usMqV4u%_w&8K89>u` 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 A=Kufz diff --git a/test2.exe b/test2.exe index 1b6619aee5911cf1358e5fe8fb291ddc10ea3f3b..c19556ff3c3e5c4c2cbe705feef0b226966b5b07 100644 GIT binary patch delta 7166 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 -- 2.39.5