From 658eba1768f70e0ce6cb01bb817709c1caf91834 Mon Sep 17 00:00:00 2001 From: sparky4 Date: Thu, 8 Dec 2016 13:53:33 -0600 Subject: [PATCH] reverted input and stuff back... walk() is broken badly --- MEMINFO.16W | 0 SCROLL.16L | 2 + src/0.c | 6 +- src/16.c | 2 +- src/inputest.c | 12 +- src/lib/16_in.c | 87 +-- src/lib/16_in.h | 14 +- src/lib/16_tdef.h | 5 +- src/lib/_6_in.c | 1290 -------------------------------------------- src/lib/_6_in.h | 309 ----------- src/lib/doslib | 2 +- src/lib/scroll16.c | 4 + src/scroll.c | 41 +- src/vgmtest.c | 2 +- src/zcroll.c | 96 ++-- test.exe | Bin 144548 -> 147716 bytes 16 files changed, 130 insertions(+), 1742 deletions(-) create mode 100755 MEMINFO.16W create mode 100755 SCROLL.16L delete mode 100755 src/lib/_6_in.c delete mode 100755 src/lib/_6_in.h diff --git a/MEMINFO.16W b/MEMINFO.16W new file mode 100755 index 00000000..e69de29b diff --git a/SCROLL.16L b/SCROLL.16L new file mode 100755 index 00000000..5f541f38 --- /dev/null +++ b/SCROLL.16L @@ -0,0 +1,2 @@ +WARNING: Failed to initialize DEBUG output +chkmap ok pip[0].page->tilesw=22 pip[0].page->tw=20 diff --git a/src/0.c b/src/0.c index 4da93c71..e9dc876e 100755 --- a/src/0.c +++ b/src/0.c @@ -10,7 +10,7 @@ static unsigned char palette[768]; global_game_variables_t gvar; -player_t player[1]; +player_t player[MaxPlayers]; int main(int argc,char **argv) { struct vrl1_vgax_header *vrl_header; @@ -25,7 +25,7 @@ int main(int argc,char **argv) { IN_Startup(); IN_Default(0,&player,ctrl_Joystick); - IN_initplayer(&player);//, 0); + IN_initplayer(&player, 0); if (argc < 3) { fprintf(stderr,"drawvrl \n"); @@ -134,7 +134,7 @@ int main(int argc,char **argv) { while(!IN_KeyDown(sc_Escape)) { - IN_ReadControl(/*0,*/&player); + IN_ReadControl(0,&player); if(IN_KeyDown(2)) modexShowPage(&(gvar.video.page[0])); if(IN_KeyDown(3)) modexShowPage(&(gvar.video.page[1])); if(IN_KeyDown(68)) //f10 diff --git a/src/16.c b/src/16.c index b7850faa..6ad5334f 100755 --- a/src/16.c +++ b/src/16.c @@ -78,7 +78,7 @@ main(int argc, char *argv[]) start_timer(&gvar); while(ENGI_EXIT != engi_stat) { - IN_ReadControl(/*0,*/&player); + IN_ReadControl(0,&player); if(IN_KeyDown(sc_Escape)) engi_stat = ENGI_EXIT; shinku(&gvar); _DEBUGF("Serial debug output printf test %u %u %u\n",1U,2U,3U); diff --git a/src/inputest.c b/src/inputest.c index 52d36283..cd566a34 100755 --- a/src/inputest.c +++ b/src/inputest.c @@ -33,12 +33,14 @@ main(int argc, char *argv[]) //extern struct inconfig inpu; dbg_testkeyin=0; dbg_testcontrolnoisy=1; - dbg_noplayerinpu=1; + dbg_noplayerinpu=0; if(!dbg_noplayerinpu) { IN_Startup(); - IN_Default(0,&player,ctrl_Joystick1); - IN_SetControlType(/*0,*/&player,ctrl_Joystick1); + //IN_Default(0,&player,ctrl_Joystick1); + //IN_SetControlType(0,&player,ctrl_Joystick1); + IN_Default(0,&player,ctrl_Keyboard1); + IN_SetControlType(0,&player,ctrl_Keyboard1); } player[0].q=1; player[0].d=2; @@ -50,11 +52,11 @@ main(int argc, char *argv[]) booleantest(); //printf("nibble size is %u\n", sizeof(nibble)); if(!dbg_noplayerinpu){ - printf("dbg_testkeyin=%u dbg_testcontrolnoisy=%u dbg_noplayerinpu=%u\nloop if this is not responsive then please KILL or reset machine sorry!!\n", dbg_testkeyin, dbg_testcontrolnoisy, dbg_noplayerinpu); + //printf("dbg_testkeyin=%u dbg_testcontrolnoisy=%u dbg_noplayerinpu=%u\nloop if this is not responsive then please KILL or reset machine sorry!!\n", dbg_testkeyin, dbg_testcontrolnoisy, dbg_noplayerinpu); while(!IN_KeyDown(sc_Escape)) { shinkutxt(&gvar); - IN_ReadControl(/*0,*/&player); + IN_ReadControl(0, &player); #define INC_PER_FRAME if(player[0].q&1) player[0].persist_aniframe++; if(player[0].persist_aniframe>4) player[0].persist_aniframe = 1; switch(player[0].d) { diff --git a/src/lib/16_in.c b/src/lib/16_in.c index 69324ee2..e5d2ec1b 100755 --- a/src/lib/16_in.c +++ b/src/lib/16_in.c @@ -506,7 +506,7 @@ INL_StartKbd() IN_ClearKeysDown(); OldKeyVect = _dos_getvect(KeyInt); - //_dos_setvect(KeyInt,INL_KeyService); + _dos_setvect(KeyInt,INL_KeyService); } /////////////////////////////////////////////////////////////////////////// @@ -682,7 +682,7 @@ IN_Startup() void IN_Default(boolean gotit,player_t *player,ControlType nt) { - //int i; + int i; if ( (!gotit) @@ -701,8 +701,9 @@ IN_Default(boolean gotit,player_t *player,ControlType nt) //in.KbdDefs[0].downleft = 0x4f; inpu.KbdDefs[0].down = 0x50; //in.KbdDefs[0].downright = 0x51; - IN_SetControlType(player,nt); - player->d=2; + IN_SetControlType(0,player,nt); + for(i=0; i>MaxPlayers;i++) + player[i].d=2; } /////////////////////////////////////////////////////////////////////////// @@ -813,7 +814,7 @@ IN_ReadCursor(CursorInfo *info) // /////////////////////////////////////////////////////////////////////////// void near -IN_ReadControl(player_t *player) +IN_ReadControl(int pn,player_t *player) { boolean realdelta; #if DEMO0 @@ -853,7 +854,7 @@ register KeyboardDef *def; else { #endif - switch (type = player->Controls) + switch (type = player[pn].Controls) { case ctrl_Keyboard1: case ctrl_Keyboard2: @@ -868,7 +869,7 @@ register KeyboardDef *def; else if (Keyboard[def->downright]) mx = motion_Right,my = motion_Down;*/ //TODO: make this into a function that the joystick AND keyboard can use wwww - if(DIRECTIONIFELSE)//(player->info.dir == 2) + if(DIRECTIONIFELSE)//(player[pn].info.dir == 2) { if(!inpu.Keyboard[def->left] && !inpu.Keyboard[def->right]){ if((inpu.Keyboard[def->up] && !inpu.Keyboard[def->down])) @@ -881,7 +882,7 @@ register KeyboardDef *def; if((inpu.Keyboard[def->right] && !inpu.Keyboard[def->left])) mx = motion_Right; }else{ //2 keys pressed - switch (player->pdir) + switch (player[pn].pdir) { case 0: case 4: @@ -897,7 +898,7 @@ register KeyboardDef *def; break; } #ifdef __DEBUG_InputMgr__ - //if(dbg_testcontrolnoisy > 0){ printf("dir=%c ", dirchar(dir)); printf("pdir=%c ", dirchar(player->pdir)); } + //if(dbg_testcontrolnoisy > 0){ printf("dir=%c ", dirchar(dir)); printf("pdir=%c ", dirchar(player[pn].pdir)); } #endif } } @@ -935,23 +936,23 @@ register KeyboardDef *def; dy = my;// * 127; } - player->info.x = dx; - player->info.xaxis = mx; - player->info.y = dy; - player->info.yaxis = my; - player->info.button0 = buttons & (1 << 0); - player->info.button1 = buttons & (1 << 1); - player->info.button2 = buttons & (1 << 2); - player->info.button3 = buttons & (1 << 3); -// player->info.dir = DirTable[((my + 1) * 3) + (mx + 1)]; + player[pn].info.x = dx; + player[pn].info.xaxis = mx; + player[pn].info.y = dy; + player[pn].info.yaxis = my; + player[pn].info.button0 = buttons & (1 << 0); + player[pn].info.button1 = buttons & (1 << 1); + player[pn].info.button2 = buttons & (1 << 2); + player[pn].info.button3 = buttons & (1 << 3); +// player[pn].info.dir = DirTable[((my + 1) * 3) + (mx + 1)]; conpee=(((my + 1) * 2) + (mx + 1))-1; - player->info.dir = DirTable[conpee]; + player[pn].info.dir = DirTable[conpee]; - if(DirTable[conpee]!=2) player->pdir=DirTable[conpee]; - if(player->q==1 &&( dir!=2 || (mx!=motion_None || my!=motion_None))) + if(DirTable[conpee]!=2) player[pn].pdir=DirTable[conpee]; + if(player[pn].q==1 &&( dir!=2 || (mx!=motion_None || my!=motion_None))) { - if(dir==2) player->d = player->info.dir; - else player->d = DirTable[dir]; + if(dir==2) player[pn].d = player[pn].info.dir; + else player[pn].d = DirTable[dir]; } #if DEMO0 @@ -981,13 +982,13 @@ register KeyboardDef *def; #endif #ifdef __DEBUG_InputMgr__ if(dbg_testcontrolnoisy > 0) -if(player->info.dir!=2/*(inpu.Keyboard[def->up] || inpu.Keyboard[def->down] || inpu.Keyboard[def->left] || inpu.Keyboard[def->right])*/ || player->q>1) +if(player[pn].info.dir!=2/*(inpu.Keyboard[def->up] || inpu.Keyboard[def->down] || inpu.Keyboard[def->left] || inpu.Keyboard[def->right])*/ || player[pn].q>1) { - //printf("b1=%u b2=%u b3=%u b4=%u ", player->info.button0, player->info.button1, player->info.button2, player->info.button3); - //printf("q=%d ", player->q); + //printf("b1=%u b2=%u b3=%u b4=%u ", player[pn].info.button0, player[pn].info.button1, player[pn].info.button2, player[pn].info.button3); + //printf("q=%d ", player[pn].q); //printf("cpee=%c ", dirchar(conpee)); - printf("pdir=%c d=%c dir=%c ", dirchar(player->pdir), dirchar(player->d), dirchar(player->info.dir)); - /*if(realdelta) */printf("dx=%d dy=%d mx=%d my=%d", player->info.x, player->info.y, player->info.xaxis, player->info.yaxis); + printf("pdir=%c d=%c dir=%c ", dirchar(player[pn].pdir), dirchar(player[pn].d), dirchar(player[pn].info.dir)); + /*if(realdelta) */printf("dx=%d dy=%d mx=%d my=%d", player[pn].info.x, player[pn].info.y, player[pn].info.xaxis, player[pn].info.yaxis); //else if(!realdelta) printf("%c%d %c%d %c%d %c%d", dirchar(0), inpu.Keyboard[def->up], dirchar(4), inpu.Keyboard[def->down], dirchar(1), inpu.Keyboard[def->left], dirchar(3), inpu.Keyboard[def->right]); printf("\n"); } @@ -1001,10 +1002,10 @@ if(player->info.dir!=2/*(inpu.Keyboard[def->up] || inpu.Keyboard[def->down] || i // /////////////////////////////////////////////////////////////////////////// void -IN_SetControlType(player_t *player,ControlType type) +IN_SetControlType(word pn,player_t *player,ControlType type) { // DEBUG - check that requested type is present? - player->Controls = type; + player[pn].Controls = type; } #if DEMO0 @@ -1266,16 +1267,20 @@ boolean IN_qb(byte kee) } //init player! -void IN_initplayer(player_t *player) +void IN_initplayer(player_t *player, word pn) { - player->x = player->tx*TILEWH; - player->y = player->ty*TILEWH; - player->triggerx = player->tx; - player->triggery = player->ty+1; - player->q=1; - player->d=2; - player->hp=4; - player->speed=4; - player->persist_aniframe=0; - player->spt=(TILEWH/(player->speed)); //speed per tile wwww + player[pn].x = player[pn].tx*TILEWH; + player[pn].y = player[pn].ty*TILEWH; + player[pn].triggerx = player[pn].tx; + player[pn].triggery = player[pn].ty+1; +/* player[0].info.x = player[0].tx; + player[0].info.xaxis = player[0].tx*TILEWH; + player[0].info.y = player[0].ty; + player[0].info.yaxis = player[0].ty*TILEWH;*/ + player[pn].q=1; + player[pn].d=2; + player[pn].hp=4; + player[pn].speed=4; + player[pn].persist_aniframe=0; + player[pn].spt=(TILEWH/(player[pn].speed)); //speed per tile wwww } diff --git a/src/lib/16_in.h b/src/lib/16_in.h index 4b0030cd..9e4bfc2e 100755 --- a/src/lib/16_in.h +++ b/src/lib/16_in.h @@ -40,8 +40,8 @@ //if else for gfxtesting and direction //player[pn].d == 2 || //player[pn].d != 2 || -#define DIRECTIONIFELSE (player->info.dir == 2)//(player[pn].info.dir == 2) -//#define NDIRECTIONIFELSE (player->info.dir != 2)//(player[pn].info.dir != 2) +#define DIRECTIONIFELSE (player[pn].info.dir == 2) +//#define NDIRECTIONIFELSE (player[pn].info.dir != 2) #define KeyInt 9 // The keyboard ISR number @@ -50,7 +50,7 @@ #define JoyScaleShift 8 #define MaxJoyValue 5000 -#define MaxPlayers 1 +#define MaxPlayers 2//futre plans for multiple playable charaters and being able to alternate #define MaxKbds 2 #define MaxJoys 2 #define MaxPads 2 @@ -232,7 +232,7 @@ typedef struct int persist_aniframe; /* gonna be increased to 1 before being used, so 0 is ok for default */ CursorInfo info; ControlType Controls; - int dx, dy, delta; + int dx, dy, delta; //TODO: what is this? ^^ } player_t; /* @@ -285,8 +285,8 @@ extern void IN_SetKeyHook(void (*hook)()); extern void IN_ClearKeysDown(); //static void INL_AdjustCursor(CursorInfo *info,word buttons,int dx,int dy); extern void IN_ReadCursor(CursorInfo *info); -extern void near IN_ReadControl(player_t *player); -extern void IN_SetControlType(player_t *player,ControlType type); +extern void near IN_ReadControl(int pn,player_t *player); +extern void IN_SetControlType(word pn,player_t *player,ControlType type); #if DEMO0 extern boolean IN_StartDemoRecord(word bufsize); extern void IN_StartDemoPlayback(byte /*__segment*/ *buffer,word bufsize); @@ -303,6 +303,6 @@ extern boolean IN_UserInput(dword delay,boolean clear); extern boolean IN_KeyDown(byte code); extern void IN_ClearKey(byte code); extern boolean IN_qb(byte kee); -void IN_initplayer(player_t *player); +void IN_initplayer(player_t *player, word pn); #endif diff --git a/src/lib/16_tdef.h b/src/lib/16_tdef.h index 137b0bfb..2ea3f9fe 100755 --- a/src/lib/16_tdef.h +++ b/src/lib/16_tdef.h @@ -65,9 +65,10 @@ typedef struct { } planar_buf_t; typedef struct { - int dx, dy; //backwards compait - nibble id; /* the Identification number of the page~ For layering~ */ + /*nibble*/word id; /* the Identification number of the page~ For layering~ */ byte far* data; /* the data for the page */ + word dx; /* col we are viewing on the virtual screen */ + word dy; /* row we are viewing on the virtual screen */ word sw; /* screen width */ word sh; /* screen heigth */ word tw; /* screen width in tiles */ diff --git a/src/lib/_6_in.c b/src/lib/_6_in.c deleted file mode 100755 index 72dcadf5..00000000 --- a/src/lib/_6_in.c +++ /dev/null @@ -1,1290 +0,0 @@ -/* Catacomb Apocalypse 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.0d1w -// By Jason Blochowiak -// Open Watcom port by sparky4 -// - -// -// 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 "src/lib/16_in.h" - -#ifdef __DEBUG_InputMgr__ -boolean dbg_testkeyin=0,dbg_testcontrolnoisy=0; -#endif - -static word far* clockw= (word far*) 0x046C; /* 18.2hz clock */ - -/* -============================================================================= - - GLOBAL VARIABLES - -============================================================================= -*/ -struct inconfig -{ - boolean MousePresent; - boolean JoysPresent[MaxJoys]; - boolean Keyboard[NumCodes]; - boolean Paused; - char LastASCII; - ScanCode LastScan; - - KeyboardDef KbdDefs[MaxKbds]; - JoystickDef JoyDefs[MaxJoys]; -} inpu; - -//extern inconfig inpu; -//inpu.KbdDefs = {0x1d,0x38,/*0x47,*/0x48,/*0x49,*/0x4b,0x4d,/*0x4f,*/0x50/*,0x51*/}; - -/* -============================================================================= - - LOCAL VARIABLES - -============================================================================= -*/ - -#ifdef __cplusplus /* Function must be declared C style */ -extern "C" { -#endif - -static struct instat { - boolean IN_Started; - boolean CapsLock; - ScanCode CurCode,LastCode; -} inst; - -static void (*INL_KeyHook)(void); -static void interrupt (*OldKeyVect)(void); -static char *ParmStringsIN[] = {"nojoys","nomouse",nil}; - -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 - }, - *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 - 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 - }, - *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","" - }; - -static Direction DirTable[] = // Quick lookup for total direction - { - //dir_Nortinest, - dir_North, - dir_West, - dir_None, - dir_East, - dir_South - //dir_NorthEast, - //dir_Soutinest, - //,dir_SouthEast - }; -#ifdef __cplusplus -} -#endif - -// Internal routines - -/////////////////////////////////////////////////////////////////////////// -// -// INL_KeyService() - Handles a keyboard interrupt (key up/down) -// -/////////////////////////////////////////////////////////////////////////// -void interrupt -INL_KeyService() -{ -static boolean special; - byte k,c; - register byte 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 - inpu.Paused = true; - else - { - if (k & 0x80) // Break code - { - k &= 0x7f; - -// DEBUG - handle special keys: ctl-alt-delete, print scrn - - inpu.Keyboard[k] = false; - } - else // Make code - { - inst.LastCode = inst.CurCode; - inst.CurCode = inpu.LastScan = k; - inpu.Keyboard[k] = true; - - if (special) - c = SpecialNames[k]; - else - { - if (k == sc_CapsLock) - { - inst.CapsLock ^= true; - // DEBUG - make caps lock light work - } - - if (inpu.Keyboard[sc_LShift] || inpu.Keyboard[sc_RShift]) // If shifted - { - c = ShiftNames[k]; - if ((c >= 'A') && (c <= 'Z') && inst.CapsLock) - c += 'a' - 'A'; - } - else - { - c = ASCIINames[k]; - if ((c >= 'a') && (c <= 'z') && inst.CapsLock) - c -= 'a' - 'A'; - } - } - if (c) - inpu.LastASCII = c; - } - - special = false; - } - - if (INL_KeyHook && !special) - INL_KeyHook(); -#ifdef __DEBUG_InputMgr__ - if(dbg_testkeyin > 0) printf("%c %u [0x%x %u] %u\n", c, c, k, k, inpu.Keyboard[k]); -#endif - outp(0x20,0x20); -} - -void -Mouse(int x) -{ - //union REGS CPURegs; - //x = CPURegs.x.ax; - __asm { - mov ax,x - int MouseInt - } - //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 -#ifdef __BORLANDC__ - } -#endif -loo: -#ifdef __BORLANDC__ - __asm { -#endif - 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 -#ifdef __BORLANDC__ - } -#endif -done: -#ifdef __BORLANDC__ - __asm { -#endif - 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; - word time; - word TimeCount = *clockw; - JoystickDef *def; -static word lasttime; - - IN_GetJoyAbs(joy,&x,&y); - def = inpu.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) -{ - word TimeCount = *clockw; - word 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() -{ - 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 = &(inpu.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 = &(inpu.JoyDefs[joy]); - - def->joyMinX = minx; - def->joyMaxX = maxx; - r = maxx - minx; - d = r / 3; - def->threshMinX = ((r / 2) - d) + minx; - def->threshMaxX = ((r / 2) + d) + minx; - - def->joyMinY = miny; - def->joyMaxY = maxy; - r = maxy - miny; - d = r / 3; - 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) -{ - inpu.JoysPresent[joy] = false; -} - -// Public routines - -/////////////////////////////////////////////////////////////////////////// -// -// IN_Startup() - Starts up the Input Mgr -// -/////////////////////////////////////////////////////////////////////////// -void -IN_Startup() -{ - boolean checkjoys,checkmouse; - word i; - - if (inst.IN_Started) - return; - - checkjoys = true; - checkmouse = true; - for (i = 1;i < _argc;i++) - { - switch (US_CheckParm(_argv[i],ParmStringsIN)) - { - case 0: - checkjoys = false; - break; - case 1: - checkmouse = false; - break; - } - } - - INL_StartKbd(); - inpu.MousePresent = checkmouse? INL_StartMouse() : false; - - for (i = 0;i < MaxJoys;i++) - inpu.JoysPresent[i] = checkjoys? INL_StartJoy(i) : false; - - inst.IN_Started = true; - -} - -/////////////////////////////////////////////////////////////////////////// -// -// IN_Default() - Sets up default conditions for the Input Mgr -// -/////////////////////////////////////////////////////////////////////////// -void -IN_Default(boolean gotit,player_t *player,ControlType nt) -{ - int i; - if - ( - (!gotit) - || ((nt == ctrl_Joystick1) && !inpu.JoysPresent[0]) - || ((nt == ctrl_Joystick2) && !inpu.JoysPresent[1]) - || ((nt == ctrl_Mouse) && !inpu.MousePresent) - ) - nt = ctrl_Keyboard1; - inpu.KbdDefs[0].button0 = 0x1c; - inpu.KbdDefs[0].button1 = 0x38; - //in.KbdDefs[0].upleft = 0x47; - inpu.KbdDefs[0].up = 0x48; - //in.KbdDefs[0].upright = 0x49; - inpu.KbdDefs[0].left = 0x4b; - inpu.KbdDefs[0].right = 0x4d; - //in.KbdDefs[0].downleft = 0x4f; - inpu.KbdDefs[0].down = 0x50; - //in.KbdDefs[0].downright = 0x51; - IN_SetControlType(0,player,nt); - for(i=0; i>MaxPlayers;i++) - player[i].d=2; -} - -/////////////////////////////////////////////////////////////////////////// -// -// IN_Shutdown() - Shuts down the Input Mgr -// -/////////////////////////////////////////////////////////////////////////// -void -IN_Shutdown() -{ - word i; - - if (!inst.IN_Started) - return; - - INL_ShutMouse(); - for (i = 0;i < MaxJoys;i++) - INL_ShutJoy(i); - INL_ShutKbd(); - - inst.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() -{ - //int i; - - inpu.LastScan = sc_None; - inpu.LastASCII = key_None; - memset (inpu.Keyboard,0,sizeof(inpu.Keyboard)); -} - -/////////////////////////////////////////////////////////////////////////// -// -// 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 (inpu.MousePresent) - { - buttons = INL_GetMouseButtons(); - INL_GetMouseDelta(&dx,&dy); - INL_AdjustCursor(info,buttons,dx,dy); - } - - for (i = 0;i < MaxJoys;i++) - { - if (!inpu.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 near -IN_ReadControl(int pn,player_t *player) -{ - boolean realdelta; -#if DEMO0 - byte dbyte; -#endif - word buttons; - int dx,dy; - Motion mx,my; - ControlType type; - sword conpee; - byte dir=DirTable[2]; -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 = player[pn].Controls) - { - case ctrl_Keyboard1: - case ctrl_Keyboard2: - def = &(inpu.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;*/ -//TODO: make this into a function that the joystick AND keyboard can use wwww - if(DIRECTIONIFELSE)//(player[pn].info.dir == 2) - { - if(!inpu.Keyboard[def->left] && !inpu.Keyboard[def->right]){ - if((inpu.Keyboard[def->up] && !inpu.Keyboard[def->down])) - my = motion_Up; - if((inpu.Keyboard[def->down] && !inpu.Keyboard[def->up])) - my = motion_Down; - }else if(!inpu.Keyboard[def->up] && !inpu.Keyboard[def->down]){ - if((inpu.Keyboard[def->left] && !inpu.Keyboard[def->right])) - mx = motion_Left; - if((inpu.Keyboard[def->right] && !inpu.Keyboard[def->left])) - mx = motion_Right; - }else{ //2 keys pressed - switch (player[pn].pdir) - { - case 0: - case 4: - if((inpu.Keyboard[def->left] && !inpu.Keyboard[def->right])){ dir = DirTable[1]; }//mx = motion_Left; } - else if((inpu.Keyboard[def->right] && !inpu.Keyboard[def->left])){ dir = DirTable[3]; }//mx = motion_Right; } - break; - case 1: - case 3: - if((inpu.Keyboard[def->up] && !inpu.Keyboard[def->down])){ dir = DirTable[0]; }//my = motion_Up; } - else if((inpu.Keyboard[def->down] && !inpu.Keyboard[def->up])){ dir = DirTable[4]; }//my = motion_Down; } - break; - default: - break; - } -#ifdef __DEBUG_InputMgr__ - //if(dbg_testcontrolnoisy > 0){ printf("dir=%c ", dirchar(dir)); printf("pdir=%c ", dirchar(player[pn].pdir)); } -#endif - } - } - //input from player - if (inpu.Keyboard[def->button0]) - buttons += 1 << 0; - if (inpu.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; - } -#ifdef DEMO0 - } -#endif - - 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; - } - - player[pn].info.x = dx; - player[pn].info.xaxis = mx; - player[pn].info.y = dy; - player[pn].info.yaxis = my; - player[pn].info.button0 = buttons & (1 << 0); - player[pn].info.button1 = buttons & (1 << 1); - player[pn].info.button2 = buttons & (1 << 2); - player[pn].info.button3 = buttons & (1 << 3); -// player[pn].info.dir = DirTable[((my + 1) * 3) + (mx + 1)]; - conpee=(((my + 1) * 2) + (mx + 1))-1; - player[pn].info.dir = DirTable[conpee]; - - if(DirTable[conpee]!=2) player[pn].pdir=DirTable[conpee]; - if(player[pn].q==1 &&( dir!=2 || (mx!=motion_None || my!=motion_None))) - { - if(dir==2) player[pn].d = player[pn].info.dir; - else player[pn].d = DirTable[dir]; - } - -#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 -#ifdef __DEBUG_InputMgr__ -if(dbg_testcontrolnoisy > 0) -if(player[pn].info.dir!=2/*(inpu.Keyboard[def->up] || inpu.Keyboard[def->down] || inpu.Keyboard[def->left] || inpu.Keyboard[def->right])*/ || player[pn].q>1) -{ - //printf("b1=%u b2=%u b3=%u b4=%u ", player[pn].info.button0, player[pn].info.button1, player[pn].info.button2, player[pn].info.button3); - //printf("q=%d ", player[pn].q); - //printf("cpee=%c ", dirchar(conpee)); - printf("pdir=%c d=%c dir=%c ", dirchar(player[pn].pdir), dirchar(player[pn].d), dirchar(player[pn].info.dir)); - /*if(realdelta) */printf("dx=%d dy=%d mx=%d my=%d", player[pn].info.x, player[pn].info.y, player[pn].info.xaxis, player[pn].info.yaxis); - //else if(!realdelta) printf("%c%d %c%d %c%d %c%d", dirchar(0), inpu.Keyboard[def->up], dirchar(4), inpu.Keyboard[def->down], dirchar(1), inpu.Keyboard[def->left], dirchar(3), inpu.Keyboard[def->right]); - printf("\n"); -} -#endif -} - -/////////////////////////////////////////////////////////////////////////// -// -// IN_SetControlType() - Sets the control type to be used by the specified -// player -// -/////////////////////////////////////////////////////////////////////////// -void -IN_SetControlType(word pn,player_t *player,ControlType type) -{ - // DEBUG - check that requested type is present? - player[pn].Controls = 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 - - -/////////////////////////////////////////////////////////////////////////// -// -// 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]); -} - -/////////////////////////////////////////////////////////////////////////// -// -// IN_WaitForKey() - Waits for a scan code, then clears LastScan and -// returns the scan code -// -/////////////////////////////////////////////////////////////////////////// -ScanCode -IN_WaitForKey() -{ - ScanCode result; - - while (!(result = inpu.LastScan)) - ; - inpu.LastScan = 0; - return(result); -} - -/////////////////////////////////////////////////////////////////////////// -// -// IN_WaitForASCII() - Waits for an ASCII char, then clears LastASCII and -// returns the ASCII value -// -/////////////////////////////////////////////////////////////////////////// -char -IN_WaitForASCII() -{ - char result; - - while (!(result = inpu.LastASCII)) - ; - inpu.LastASCII = '\0'; - return(result); -} - -/////////////////////////////////////////////////////////////////////////// -// -// IN_AckBack() - Waits for either an ASCII keypress or a button press -// -/////////////////////////////////////////////////////////////////////////// -void -IN_AckBack() -{ - word i; - - while (!inpu.LastScan) - { - if (inpu.MousePresent) - { - if (INL_GetMouseButtons()) - { - while (INL_GetMouseButtons()) - ; - return; - } - } - - for (i = 0;i < MaxJoys;i++) - { - if (inpu.JoysPresent[i]) - { - if (IN_GetJoyButtonsDB(i)) - { - while (IN_GetJoyButtonsDB(i)) - ; - return; - } - } - } - } - - IN_ClearKey(inpu.LastScan); - inpu.LastScan = sc_None; -} - -/////////////////////////////////////////////////////////////////////////// -// -// IN_Ack() - Clears user input & then calls IN_AckBack() -// -/////////////////////////////////////////////////////////////////////////// -void -IN_Ack() -{ - word i; - - if (!inst.IN_Started) - return; - - IN_ClearKey(inpu.LastScan); - inpu.LastScan = sc_None; - - if (inpu.MousePresent) - while (INL_GetMouseButtons()) - ; - for (i = 0;i < MaxJoys;i++) - if (inpu.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() -{ - boolean result; - word i; - - result = inpu.LastScan; - - if (inpu.MousePresent) - if (INL_GetMouseButtons()) - result = true; - - for (i = 0;i < MaxJoys;i++) - if (inpu.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) -{ - word TimeCount = *clockw; - word lasttime; - - lasttime = TimeCount; - do - { - if (IN_IsUserInput()) - { - if (clear) - IN_AckBack(); - return(true); - } - } while (TimeCount - lasttime < delay); - return(false); -} - -boolean IN_KeyDown(byte code) -{ - return inpu.Keyboard[code]; -} - -void IN_ClearKey(byte code) -{ - inpu.Keyboard[code] = false; - if(code == inpu.LastScan) - inpu.LastScan = sc_None; - } - -boolean IN_qb(byte kee) -{ -#ifdef __DEBUG_InputMgr__ -// if(dbg_testkeyin > 0) printf("%u\n", inpu.Keyboard[kee]); -#endif - if(inpu.Keyboard[kee]==true) return 1; - else return 0; -} - -//init player! -void IN_initplayer(player_t *player, word pn) -{ - player[pn].x = player[pn].tx*TILEWH; - player[pn].y = player[pn].ty*TILEWH; - player[pn].triggerx = player[pn].tx; - player[pn].triggery = player[pn].ty+1; -/* player[0].info.x = player[0].tx; - player[0].info.xaxis = player[0].tx*TILEWH; - player[0].info.y = player[0].ty; - player[0].info.yaxis = player[0].ty*TILEWH;*/ - player[pn].q=1; - player[pn].d=2; - player[pn].hp=4; - player[pn].speed=4; - player[pn].persist_aniframe=0; - player[pn].spt=(TILEWH/(player[pn].speed)); //speed per tile wwww -} diff --git a/src/lib/_6_in.h b/src/lib/_6_in.h deleted file mode 100755 index eb1650e4..00000000 --- a/src/lib/_6_in.h +++ /dev/null @@ -1,309 +0,0 @@ -/* Catacomb Apocalypse 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.h - Header file for Input Manager -// v1.0d1w -// By Jason Blochowiak -// Open Watcom port by sparky4 -// - -#ifndef __16_IN__ -#define __16_IN__ - -#include -#include "src/lib/16_head.h" -#include "src/lib/16_timer.h" -#ifdef __WATCOMC__ //borland C BCEXMM.EXE -#include "src/lib/16_dbg.h" -#include "src/lib/16_sprit.h" -//#include "src/lib/bitmap.h" //old format -#endif -#ifdef __DEBUG__ -#define __DEBUG_InputMgr__ -extern boolean dbg_testkeyin,dbg_testcontrolnoisy; -#endif - -//if else for gfxtesting and direction -//player[pn].d == 2 || -//player[pn].d != 2 || -#define DIRECTIONIFELSE (player[pn].info.dir == 2) -//#define NDIRECTIONIFELSE (player[pn].info.dir != 2) - -#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 -#define MaxJoys 2 -#define MaxPads 2 -#define NumCodes 128 - -typedef byte ScanCode; -#define sc_None 0 -#define sc_Bad 0xff -#define sc_Return 0x1c -#define sc_Enter sc_Return -#define sc_Escape 0x01 -#define sc_Space 0x39 -#define sc_BackSpace 0x0e -#define sc_Tab 0x0f -#define sc_Alt 0x38 -#define sc_Control 0x1d -#define sc_CapsLock 0x3a -#define sc_LShift 0x2a -#define sc_RShift 0x36 -#define sc_UpArrow 0x48 -#define sc_DownArrow 0x50 -#define sc_LeftArrow 0x4b -#define sc_RightArrow 0x4d -#define sc_Insert 0x52 -#define sc_Delete 0x53 -#define sc_Home 0x47 -#define sc_End 0x4f -#define sc_PgUp 0x49 -#define sc_PgDn 0x51 -#define sc_F1 0x3b -#define sc_F2 0x3c -#define sc_F3 0x3d -#define sc_F4 0x3e -#define sc_F5 0x3f -#define sc_F6 0x40 -#define sc_F7 0x41 -#define sc_F8 0x42 -#define sc_F9 0x43 -#define sc_F10 0x44 -#define sc_F11 0x57 -#define sc_F12 0x59 - -#define sc_1 0x02 -#define sc_2 0x03 -#define sc_3 0x04 -#define sc_4 0x05 -#define sc_5 0x06 -#define sc_6 0x07 -#define sc_7 0x08 -#define sc_8 0x09 -#define sc_9 0x0a -#define sc_0 0x0b - -#define sc_A 0x1e -#define sc_B 0x30 -#define sc_C 0x2e -#define sc_D 0x20 -#define sc_E 0x12 -#define sc_F 0x21 -#define sc_G 0x22 -#define sc_H 0x23 -#define sc_I 0x17 -#define sc_J 0x24 -#define sc_K 0x25 -#define sc_L 0x26 -#define sc_M 0x32 -#define sc_N 0x31 -#define sc_O 0x18 -#define sc_P 0x19 -#define sc_Q 0x10 -#define sc_R 0x13 -#define sc_S 0x1f -#define sc_T 0x14 -#define sc_U 0x16 -#define sc_V 0x2f -#define sc_W 0x11 -#define sc_X 0x2d -#define sc_Y 0x15 -#define sc_Z 0x2c - -#define key_None 0 -#define key_Return 0x0d -#define key_Enter key_Return -#define key_Escape 0x1b -#define key_Space 0x20 -#define key_BackSpace 0x08 -#define key_Tab 0x09 -#define key_Delete 0x7f - -#define key_LSuper 0x5b -#define key_RSuper 0x5c -#define key_Menu 0x5d - -// Stuff for the mouse -#define MReset 0 -#define MButtons 3 -#define MDelta 11 - -#define MouseInt 0x33 -#ifdef DEMO0 -typedef enum { - demo_Off,demo_Record,demo_Playback,demo_PlayDone - } Demo; -#endif -typedef enum { - //ctrl_None, // MDM (GAMERS EDGE) - added - ctrl_Keyboard, - ctrl_Keyboard1 = ctrl_Keyboard,ctrl_Keyboard2, - ctrl_Joystick, - ctrl_Joystick1 = ctrl_Joystick,ctrl_Joystick2, - ctrl_Mouse, - } ControlType; -typedef enum { - motion_Left = -1,motion_Up = -1, - motion_None = 0, - motion_Right = 1,motion_Down = 1 - } Motion; -typedef enum { - dir_North,//dir_NorthEast, - dir_West,//dir_Nortinest, - dir_None, - dir_East,//,dir_SouthEast, - dir_South,//dir_Soutinest, - } Direction; -typedef struct { - boolean near button0,button1,button2,button3; - int near x,y; - Motion near xaxis,yaxis; - Direction near dir; - } CursorInfo; - -typedef struct { - ScanCode near button0,button1, - //upleft, - up, - down, - left, - right - //upright, - //downleft, - //,downright - ; - } KeyboardDef; -typedef struct { - word near joyMinX,joyMinY, - threshMinX,threshMinY, - threshMaxX,threshMaxY, - joyMaxX,joyMaxY, - joyMultXL,joyMultYL, - joyMultXH,joyMultYH; - } JoystickDef; - -typedef struct -{ - int x; //player exact position on the viewable map - int y; //player exact position on the viewable map - int tx; //player tile position on the viewable map - int ty; //player tile position on the viewable map - int triggerx; //player's trigger box tile position on the viewable map - int triggery; //player's trigger box tile position on the viewable map - int sheetsetx; //NOT USED YET! player sprite sheet set on the image x - int sheetsety; //NOT USED YET! player sprite sheet set on the image y - byte d; //direction to render sprite!! wwww - byte q; //loop variable for anumation and locking the playing to compleate the animation cycle to prevent issues with misalignment www - byte near pdir; //previous direction~ - //byte near kd[2]; //array of arrow key pressed - word speed; //player speed! - word spt; //speed per tile -//0000 planar_buf_t huge *data; //supposively the sprite sheet data -// planar_buf_t data; //supposively the sprite sheet data -////0000---- -#ifdef __WATCOMC__ - struct sprite *spri; //supposively the sprite sheet data - memptr gr; -#endif - bitmap_t *data; //supposively the sprite sheet data//old format - sword hp; //hitpoints of the player - int persist_aniframe; /* gonna be increased to 1 before being used, so 0 is ok for default */ - CursorInfo info; - ControlType Controls; -} player_t; - -/* -============================================================================= - - GLOBAL VARIABLES - -============================================================================= -*/ -/*extern struct inconfig -{ - boolean MousePresent; - boolean JoysPresent[MaxJoys]; - boolean Keyboard[NumCodes]; - boolean Paused; - char LastASCII; - ScanCode LastScan; - - KeyboardDef KbdDefs[MaxKbds]; - JoystickDef JoyDefs[MaxJoys]; -} inpu;*/ - -#ifdef DEMO0 - static Demo DemoMode = demo_Off; - static byte /*_seg*/ *DemoBuffer; - static word DemoOffset,DemoSize; -#endif - -// Internal routines -extern void interrupt INL_KeyService(); -extern void Mouse(int x); -//static void INL_GetMouseDelta(int *x,int *y); -//static word INL_GetMouseButtons(void); -extern void IN_GetJoyAbs(word joy,word *xp,word *yp); -//static void INL_GetJoyDelta(word joy,int *dx,int *dy,boolean adaptive); -//static word INL_GetJoyButtons(word joy); -extern word IN_GetJoyButtonsDB(word joy); -//static void INL_StartKbd(void); -//static void INL_ShutKbd(void); -//static boolean INL_StartMouse(void); -//static void INL_ShutMouse(void); -//static void INL_SetJoyScale(word joy); -extern void IN_SetupJoy(word joy,word minx,word maxx,word miny,word maxy); -//static boolean INL_StartJoy(word joy); -//static void INL_ShutJoy(word joy); -extern void IN_Startup(); -extern void IN_Default(boolean gotit,player_t *player,ControlType nt); -extern void IN_Shutdown(); -extern void IN_SetKeyHook(void (*hook)()); -extern void IN_ClearKeysDown(); -//static void INL_AdjustCursor(CursorInfo *info,word buttons,int dx,int dy); -extern void IN_ReadCursor(CursorInfo *info); -extern void near IN_ReadControl(int pn,player_t *player); -extern void IN_SetControlType(word pn,player_t *player,ControlType type); -#if DEMO0 -extern boolean IN_StartDemoRecord(word bufsize); -extern void IN_StartDemoPlayback(byte /*__segment*/ *buffer,word bufsize); -extern void IN_StopDemo(void); -extern void IN_FreeDemoBuffer(void); -#endif -extern byte *IN_GetScanName(ScanCode scan); -extern ScanCode IN_WaitForKey(); -extern char IN_WaitForASCII(); -extern void IN_AckBack(); -extern void IN_Ack(); -extern boolean IN_IsUserInput(); -extern boolean IN_UserInput(dword delay,boolean clear); -extern boolean IN_KeyDown(byte code); -extern void IN_ClearKey(byte code); -extern boolean IN_qb(byte kee); -void IN_initplayer(player_t *player, word pn); - -#endif diff --git a/src/lib/doslib b/src/lib/doslib index 8037bba4..e3437c72 160000 --- a/src/lib/doslib +++ b/src/lib/doslib @@ -1 +1 @@ -Subproject commit 8037bba4c38f750e1599530d77e41ca1f80a6134 +Subproject commit e3437c7296b618a363f5452ebf90a8c5cf0558fa diff --git a/src/lib/scroll16.c b/src/lib/scroll16.c index cb014fd0..06c7fe95 100755 --- a/src/lib/scroll16.c +++ b/src/lib/scroll16.c @@ -26,6 +26,10 @@ void walk(map_view_t *pip, player_t *player, word pn) { +// modexLeave(); +// IN_Shutdown(); +// exit(-5); + #define INC_PER_FRAME if(player[pn].q&1) player[pn].persist_aniframe++; if(player[pn].persist_aniframe>4) player[pn].persist_aniframe = 1; //printf("player[%d].d=%d\n", pn, player[pn].d); switch(player[pn].d) diff --git a/src/scroll.c b/src/scroll.c index c92469cb..114cad0f 100755 --- a/src/scroll.c +++ b/src/scroll.c @@ -29,7 +29,7 @@ //#define FADE #define MODEX //this is for mode x initiating -boolean dbg_noplayerinpu=1; +//boolean dbg_noplayerinpu=1; //word far *clock= (word far*) 0x046C; /* 18.2hz clock */ //bitmap_t *p; @@ -42,7 +42,7 @@ float t; sword bakapee; pan_t pan; //debugswitches -boolean panswitch=1; +boolean panswitch=0;//1 //extern boolean pageflipflop=1; unsigned int i; const char *cpus; @@ -65,34 +65,7 @@ void main(int argc, char *argv[]) if(argv[1]) bakapee = atoi(argv[1]); else bakapee = 1; - // DOSLIB: check our environment - probe_dos(); - - // DOSLIB: what CPU are we using? - // NTS: I can see from the makefile Sparky4 intends this to run on 8088 by the -0 switch in CFLAGS. - // So this code by itself shouldn't care too much what CPU it's running on. Except that other - // parts of this project (DOSLIB itself) rely on CPU detection to know what is appropriate for - // the CPU to carry out tasks. --J.C. - cpu_probe(); - - // DOSLIB: check for VGA - if (!probe_vga()) { - printf("VGA probe failed\n"); - return; - } - // hardware must be VGA or higher! - if (!(vga_state.vga_flags & VGA_IS_VGA)) { - printf("This program requires VGA or higher graphics hardware\n"); - return; - } - - if (_DEBUG_INIT() == 0) { -#ifdef DEBUGSERIAL - printf("WARNING: Failed to initialize DEBUG output\n"); -#endif - } - _DEBUG("Serial debug output started\n"); // NTS: All serial output must end messages with newline, or DOSBox-X will not emit text to log - _DEBUGF("Serial debug output printf test %u %u %u\n",1U,2U,3U); + Startup16(&gvar); pan.pn=1; @@ -125,7 +98,7 @@ void main(int argc, char *argv[]) if(!dbg_noplayerinpu) { IN_Startup(); - IN_Default(0,&player,ctrl_Joystick); + IN_Default(0,&player,ctrl_Keyboard1); //IN_Default(1,&player,ctrl_Joystick); } @@ -184,7 +157,7 @@ void main(int argc, char *argv[]) //default player position on the viewable map player[0].tx = mv[0].tx + mv[0].page->tilemidposscreenx; player[0].ty = mv[0].ty + mv[0].page->tilemidposscreeny; - IN_initplayer(&player);//, 0); + IN_initplayer(&player, 0); //IN_initplayer(&player, 1); #ifndef SPRITE @@ -228,9 +201,9 @@ void main(int argc, char *argv[]) //when player[0].tx or player[0].ty == 0 or player[0].tx == 20 or player[0].ty == 15 then stop because that is edge of map and you do not want to walk of the map //player movement - IN_ReadControl(/*0,*/&player); + IN_ReadControl(0, &player); if(!panswitch){ - walk(mv, player, 0); + walk(mv, &player, 0); }else{ panpagemanual(mv, player, 0); //printf(" player[0].q: %d", player[0].q); printf(" player[0].d: %d\n", player[0].d); diff --git a/src/vgmtest.c b/src/vgmtest.c index 2760ac0d..6ca69aa1 100755 --- a/src/vgmtest.c +++ b/src/vgmtest.c @@ -64,7 +64,7 @@ main(int argc, char *argv[]) while(!IN_KeyDown(sc_Escape)) //while(!kbhit()) { - IN_ReadControl(/*0,*/&player); + IN_ReadControl(0,&player); UpdateSoundEngine(); } StopMusic(); diff --git a/src/zcroll.c b/src/zcroll.c index 10f87f66..b08fcf7a 100755 --- a/src/zcroll.c +++ b/src/zcroll.c @@ -27,13 +27,13 @@ #include "src/lib/16_dbg.h" #define MODEXZ -boolean dbg_noplayerinpu=1; +//boolean dbg_noplayerinpu=1; //TODO: known issues the array dependent mv stuff and player arrays global_game_variables_t gvar; static map_t map; -player_t *player; -map_view_t *mv; +player_t player[MaxPlayers]; +map_view_t mv[4]; float t; sword bakapee; pan_t pan; @@ -64,10 +64,9 @@ void main(int argc, char *argv[]) pan.pn=0; // OK, this one takes hellova time and needs to be done in farmalloc or MM_... //TODO: USE MM AND CA AND PM WWWWWWWW - player = malloc(sizeof(player_t)); - player->ent = malloc(sizeof(entity_t)); - player->ent->spri = malloc(sizeof(struct sprite)); - player->ent->spri->spritesheet = malloc(sizeof(struct vrs_container)); + player[0].ent = malloc(sizeof(entity_t)); + player[0].ent->spri = malloc(sizeof(struct sprite)); + player[0].ent->spri->spritesheet = malloc(sizeof(struct vrs_container)); // create the map fprintf(stderr, "testing map load~ "); @@ -78,12 +77,12 @@ void main(int argc, char *argv[]) // data printf("loading sprite\n"); - read_vrs(&gvar, "data/spri/chikyuu.vrs", player->ent->spri->spritesheet); printf("sprite loaded\n"); + read_vrs(&gvar, "data/spri/chikyuu.vrs", player[0].ent->spri->spritesheet); printf("sprite loaded\n"); // input! if(!dbg_noplayerinpu) { - IN_Default(0, player,ctrl_Joystick); printf("IN_defaulted\n"); + IN_Default(0, &player,ctrl_Keyboard1); printf("IN_defaulted\n"); } // save the palette @@ -112,29 +111,29 @@ if(dbg_noplayerinpu) { //sprintf(&gvar.pee, "press a key for video setup"); strcpy(global_temp_status_text, "press a key for video setup"); - modexprint(mv->page, 0, 64, 1, 7, 0, global_temp_status_text); + modexprint(mv[0].page, 0, 64, 1, 7, 0, global_temp_status_text); getch(); } modexHiganbanaPageSetup(&gvar.video); - mv->page = &gvar.video.page[0]; - mv->map = ↦ - mv->video = &gvar.video; - mv->pan = &pan; - player->ent->spri->x = player->ent->spri->y = 20; + mv[0].page = &gvar.video.page[0]; + mv[0].map = ↦ + mv[0].video = &gvar.video; + mv[0].pan = &pan; + player[0].ent->spri->x = player[0].ent->spri->y = 20; // set up paging //TODO: LOAD map data and position the map in the middle of the screen if smaller then screen - mapGoTo(mv, 0, 0); + mapGoTo(&mv, 0, 0); #endif //TODO: put player in starting position of spot //default player position on the viewable map - player->tx = mv->tx + mv->page->tilemidposscreenx; - player->ty = mv->ty + mv->page->tilemidposscreeny; - IN_initplayer(player); printf("player inited\n"); + player[0].tx = mv[0].tx + mv[0].page->tilemidposscreenx; + player[0].ty = mv[0].ty + mv[0].page->tilemidposscreeny; + IN_initplayer(&player, 0); printf("player inited\n"); - i = set_anim_by_id(player->ent->spri, 11); - print_anim_ids(player->ent->spri); + i = set_anim_by_id(player[0].ent->spri, 11); + print_anim_ids(player[0].ent->spri); if (i == -1) { #ifdef FADE @@ -148,31 +147,32 @@ if(dbg_noplayerinpu) #endif exit(-4); } - //animate_spri(&(player->ent->spri)); + //animate_spri(&(player[0].ent->spri)); printf("spri ok\n"); - modexShowPage(mv->page);//!(gvar.video.p) + modexShowPage(mv[0].page);//!(gvar.video.p) shinku_fps_indicator_page = 0; // we're on page 1 now, shinku(). follow along please or it will not be visible. #ifdef FADE modexFadeOn(4, gpal); #endif printf("LOOP\n"); if(!dbg_noplayerinpu) - while(!IN_KeyDown(sc_Escape) && player->hp>0) + while(!IN_KeyDown(sc_Escape) && player[0].hp>0) { shinku(&gvar); //top left corner & bottem right corner of map veiw be set as map edge trigger since maps are actually square //to stop scrolling and have the player position data move to the edge of the screen with respect to the direction - //when player->tx or player->ty == 0 or player->tx == 20 or player->ty == 15 then stop because that is edge of map and you do not want to walk of the map + //when player[0].tx or player[0].ty == 0 or player[0].tx == 20 or player[0].ty == 15 then stop because that is edge of map and you do not want to walk of the map //player movement - IN_ReadControl(player); + IN_ReadControl(0, &player); if(!panswitch){ - walk(player->ent, mv); + walk(player[0].ent, mv); + //walk(mv, &player, 0); } //the scripting stuff.... -/* if(((mv->map->data[(player->triggerx-1)+(map.width*(player->triggery-1))] == 0) && IN_KeyDown(0x1C))||(player->tx == 5 && player->ty == 5)) +/* if(((mv[0].map->data[(player[0].triggerx-1)+(map.width*(player[0].triggery-1))] == 0) && IN_KeyDown(0x1C))||(player[0].tx == 5 && player[0].ty == 5)) { short i; for(i=800; i>=400; i--) @@ -181,14 +181,14 @@ if(dbg_noplayerinpu) } nosound(); } - if(player->q == (TILEWH/(player->speed))+1 && player->info.dir != 2 && (player->triggerx == 5 && player->triggery == 5)){ player->hp--; } + if(player[0].q == (TILEWH/(player[0].speed))+1 && player[0].info.dir != 2 && (player[0].triggerx == 5 && player[0].triggery == 5)){ player[0].hp--; } */ //debugging binds! - if(IN_KeyDown(2)){ modexShowPage(mv->page); pan.pn=0; } - if(IN_KeyDown(25)){ modexpdump(mv->page); + if(IN_KeyDown(2)){ modexShowPage(mv[0].page); pan.pn=0; } + if(IN_KeyDown(25)){ modexpdump(mv[0].page); IN_UserInput(1,1); } //p #ifdef FADE - if(IN_KeyDown(24)){ modexPalUpdate0(gpal); paloffset=0; modexpdump(mv->page); IN_UserInput(1,1); } + if(IN_KeyDown(24)){ modexPalUpdate0(gpal); paloffset=0; modexpdump(mv[0].page); IN_UserInput(1,1); } if(IN_KeyDown(22)){ printf("2paloffset = %d\n", paloffset/3); IN_UserInput(1,1); @@ -209,12 +209,12 @@ if(dbg_noplayerinpu) } if(IN_KeyDown(67)) //f9 { - modexClearRegion(mv->page, 0, 0, mv->page->width, mv->page->height, 2); + modexClearRegion(mv[0].page, 0, 0, mv[0].page->width, mv[0].page->height, 2); } if(IN_KeyDown(66)) //f8 { - // modexDrawSprite(mv->page, 16, 16, p); - modexDrawSprite(mv->page, 32+48, 16, (player->data)); + // modexDrawSprite(mv[0].page, 16, 16, p); + modexDrawSprite(mv[0].page, 32+48, 16, (player[0].data)); } //TODO fmemtest into page /*if(IN_KeyDown(4+1)) //4 @@ -229,8 +229,8 @@ if(dbg_noplayerinpu) if(IN_KeyDown(10)){ modexPalOverscan(rand()%56); modexPalUpdate1(dpal); IN_UserInput(1,1); } //if(IN_KeyDown(11)){ modexPalOverscan(15); } #endif - if((player->q==1) && !(player->x%TILEWH==0 && player->y%TILEWH==0)) break; //incase things go out of sync! - player->hp = 0; + if((player[0].q==1) && !(player[0].x%TILEWH==0 && player[0].y%TILEWH==0)) break; //incase things go out of sync! + player[0].hp = 0; } else @@ -250,18 +250,18 @@ if(dbg_noplayerinpu) Shutdown16(&gvar); printf("\nProject 16 zcroll.exe. This is just a test file!\n"); printf("version %s\n", VERSION); - printf("tx: %d ", mv->tx); - printf("ty: %d\n", mv->ty); + printf("tx: %d ", mv[0].tx); + printf("ty: %d\n", mv[0].ty); printf("\n"); printf("player vars:\n"); - printf(" x: %d", player->x); printf(" y: %d\n", player->y); - //if(player->hp==0) printf("%d wwww\n", player->y+8); - //else printf("\nplayer->y: %d\n", player->y); - printf(" tx: %d", player->tx); printf(" ty: %d\n", player->ty); - printf(" triggx: %d", player->triggerx); printf(" triggy: %d\n", player->triggery); - printf(" hp: %d", (player->hp)); printf(" q: %d", player->q); printf(" player.info.dir: %d", player->info.dir); printf(" player.d: %d ", player->d); - printf(" pdir=%d\n", player->pdir); - printf(" tile data value at player trigger position: %d\n\n", mv->map->data[(player->triggerx-1)+(map.width*(player->triggery-1))]); + printf(" x: %d", player[0].x); printf(" y: %d\n", player[0].y); + //if(player[0].hp==0) printf("%d wwww\n", player[0].y+8); + //else printf("\nplayer[0].y: %d\n", player[0].y); + printf(" tx: %d", player[0].tx); printf(" ty: %d\n", player[0].ty); + printf(" triggx: %d", player[0].triggerx); printf(" triggy: %d\n", player[0].triggery); + printf(" hp: %d", (player[0].hp)); printf(" q: %d", player[0].q); printf(" player.info.dir: %d", player[0].info.dir); printf(" player.d: %d ", player[0].d); + printf(" pdir=%d\n", player[0].pdir); + printf(" tile data value at player trigger position: %d\n\n", mv[0].map->data[(player[0].triggerx-1)+(map.width*(player[0].triggery-1))]); printf("Virtual Screen: %dx", gvar.video.page[0].width); printf("%d ", gvar.video.page[0].height); printf("Screen: %dx", gvar.video.page[0].sw); printf("%d\n", gvar.video.page[0].sh); printf("virtual tile resolution: %dx", gvar.video.page[0].tilesw); printf("%d ", gvar.video.page[0].tilesh); @@ -274,7 +274,7 @@ if(dbg_noplayerinpu) //0000printf("\ngvar.video.tickclk=%f\n", gvar.video.tickclk); //0000printf("gvar.video.clk=%f", gvar.video.clk); printf("\n"); - //printf("map.width=%d map.height=%d map.data[0]=%d\n", mv->map->width, mv->map->height, mv->map->data[0]); + //printf("map.width=%d map.height=%d map.data[0]=%d\n", mv[0].map->width, mv[0].map->height, mv[0].map->data[0]); printf("\n"); switch(detectcpu()) diff --git a/test.exe b/test.exe index fc489c2c5f4537dd2ef1aeda66015b68eb8b02a2..434bf1a81eaecb8f725b55ee6e474c72a0a7aa27 100755 GIT binary patch delta 59201 zcmb@v30xIb|M)-ma#_R?al;J}H{2K0GzHPju2wFjg{DZGnWd2_V3~SR)Eowhnujp;o8d z8MeYRQEKqla1|O1RfA{1X1D<1!_;7DlvDPKamug5H*mf|cBnZZJJdGGX_L=RBA|zz z^8K(V)+wjKTd)%@!q4C})hRcGF7Oy6z!FFYI~0Hv$8T8uC<%R>dsqjb!$r6amM5I@ zU^oqBPdVkH88)X}E@y{U!ml%&@?}!C?`fxe@)@W63v`_6ls|)9_z%1=iv+^Qun*3_ zbr}9E&*59J5QZOAJjeZPryK+w;SJab#n9(@r~EX$W8>0t4!MU{APe4ulkn&=QVPE= zcgovecFKztr~CuVP@QrfY+UJ-D_(KR9WtEq7U#KNag01J7(8n!|GJJjGVa4#%?0{8{q>8}QV4yT}XKQ;JHco@>)BA9rd z-peV!54Xdq{~!7~<)7d>`1fuKRInAIqMULP zyfqZ}!<=%{yPR@=m;^K7Jvak5VB~P891pLM)Z+(-C3<;Jp8J_;8>4M6Z9p&{-X(Q;s1W2Za^hBl?8z^Z0W**nN7 z_l8Mu9ip2%<=7UKC|FxM{?AsVK^ z99RIE@E+`f6L16kk)0MoexN@@!Bj|qgTEq>H=XjtGN+sh=|7{^f2RI-T&2mB&~pv=rzJgW}@-AHdX54ekba!f<#8Hp16%9&R?I{^dY5xD|AP0Wb_6hK2AtdjMFg?%49thsa0tGF@8QnokM zm<3B93pT+{I0(n#C#YW!D+&g|NSFvO+PJKP&)@)j2}Mv2KK|%+xC_R?RG0~g@H%`5 z2jEBe1x)pc0IaYO(qJom4oQPCu zgAezP!;(}4Gmc2oWf;Ko@epx9lE%S$_yVRJl%$v8Rk#QZ4oOmT7z9({6?prQWRv!C z^E+7cB_F9));V20!nYBrhUv1v}7!0g_W54<8?M z%3p%7lko*y1M`z>*2^}{KZiqJd*8{Q(!+F+=?Fm1pN*TKgIyvOeX__w~#p40GFZThfeukco>$R zpbt6DbGQYK`K?egIbe&TH)=*Z?+?Ra<5o%947*?-ctyZ-?3AR5kOp?R4mZKPOOj-01ViCTI0{~NN$Lwvfd)t61bh!a*=>?k%1x`?c=%9~ z7DEo4gp1(+5jli7_-PA~@Jxo5&;k0uV0ejl3Z%muuo1Sw7?=!C!qFT_I<`-ezJoGo zfWWr0aTx>;!8}NXt?(=k7Q%AKgj>0I;BOFghP&Zoo_zr)Vdh>E4slt0}ZIZN|n}bjWfjDRfkuU}# za*$Sd8WzCI@F9Hug(Q{3EojE?5aNmxUnC6vc7Pu9ssF*;jDS_V*a!|d2t8jw;9xvF3X5PZ*dfc39l8eA z!~3uWw!${p340(1_Cp>Vh2wAv&cInX50@;q?9eORT!m|J1InQis=(}>9qI%A5CCV1 z{5p7(z}C|h?m81aZ1ihdijD?3_2Bg3%@Fr}BosbVl;T)8L3v6bjzBw!; zP!+P_3pfRzCZi4E8z=%7ge{h&fiM}K1RJEmyRZpPz;T6S z>i--!SK%hKNI|S^jE3>j@(4RSeOAXLI!MrFW@-*3o4*7 z0d{~Xuh8Vc21{Wjya6A;1@I<6{(qdC>F^B1!yHJ0`LGC{uLvS2^grA`&kO? z0)B#WxCNHi2@^WNP>6+8cpq#Bxm*O_HxL$h1eU;B*abhrZTMy`HUj(vzrZbMoq&Ks zUxU20MHS-@y0q6C|0D z16TsfAr;c$HFy)UU=6H?_hAccg>A4C_COBohdek6$Ke#5fwML)=iw4ufva#0Za_Iy zLKT>42|nNt0niwNpcRBbdkBMW&9bI3u9(r-AqSdq0Lj&J3ItW!b;cx zyTJ(;pu-I6zX6WBKqRbs5_1~tkPjE&D*QYRwF?&R>q9Vfg?r%egm0@K`@50|~GQRzMc)gk1P??)Iy}=S}U$ zBaksL86qMuQeY;s@FFaNW%1juhLoH92aKj$hmY^uem-=O$u^}i0}_aMjB11|_zo^Z zF)WNDE;tRPaQqQ61FarK$G~Wq4#|)OJK#$Qz;A0A7z!T<`TG(RixZRui|2pz3F3nvO^vIlHp8N z4y2zg_YLIT6;nV_{I6de#%G;DRsLI12_ zOhzerN`YcMt;C$kdX1mBQ+~|~-N*WQ)_Ufo0*Vf+8R4fKfdRX-L&J0N`ev#^XdCN5A&_Q6;y>Ni|Jjv+)XkMC?qEy9PS!COy!7-CB%p&)lIsS@*ZCuD`=d%*j9a%hvtLy93Fv z5_2^DtWi>~{>rf|0@6Bl5Aza#$9501iGb7N^3*t|YhZfZaW(FgYhZY8Gzp9*d5)8& z>LjXhW$M@)qL|NQW$Yt4z4heyn`>u7FHWN($$+2P$Xwm0w~ge59|=E~rN?jYsfRS+ zzl7BPFGK2LJk>)I8Byc*t78u$vsvRs0x9H;6jpj62}(Pg?=vZuH@bLTLA-7%G3DXy zh18{;HJ)DP=~X4>nqCEIXO*NQyC0f9=1f2R4dwOAb?uJRRv^k!R6;JEyPmPq=Ei}nH^>Aw*n+{K(tYElIWBRAb8Z zg38K1$Yk*IRsX={FxyA8W|I_tN+}E|>M}Q@WLh-IwCtU;eK)-ZHf_EV(4n2UB zgFZF+rfxj})KRo}r=`$>e-XkP?Fb|@dXjw5hk7yT<=)-5&t*f?qHWc&XFQJ7xYGee z^HVZ(&FGfc?Qisc#KE$ul_#M+M?SY7a=EV(p&_~-75omtCf!1zF z53M3%f_Zr({r1JkhNh+3FOj{>dAdKjWMIj(;tZ+yb15f~=V|7%!cR~0YT>@8c5X;- z^QZv*NxuNC(Xd{oM%u7pJ+;iJ-lhlR59FM69F6)Oa$S(VMsu%&z`=xdjJ!%FS=(^omE~9-cCF%rTq8PQH}N zzbcq$`)6)1ddph3B(~3Gnp?+)(Q8v;qwNPNy?l3r94H%MCEwz4l!HYMHPabNQE?K33M0{Vl<2&bP^r^`sS~qdaM@p&L(SMBF zTG~3|mA`x*ea}k+s@*qL@|Bn?4!J?C%+rol-`&_5cd?1V5!=Y#t+8@6>xD*6&1CIN zm36hg*PyInv@7YVE2$`}tg%x&XKfXL?h%I6gAI&Sd5s(_%s3&ni%W9@qsP}IY{JM6 ztq+gMNLf@aCALXfbW=)ft}Y*NU466vb+m7?_Ug#i#PadTdH&r3(hJj0uFSdfx^{hO zh&FoEfL6k+C{w;ttv8mPv-u`I7GW)$7fZ}JU9{DsdYVpZM@Oal%xIwdc{L)qzET)| z#1SoJHLmB>7T??16s&E&x0m^j##+yN!!*~uGl*%%eNU5mJswwjVS4V$I4%6HHs+iV zt?IrZypO!Uv*`|P+Wlj=-*$gTuHW3>-G5-?=$tY2g|un%=qLX&fKJ+)(UH7AH`*F& z^gn3@$_>?b<(fNPS^Z=>kI|KG%lMv$lz&CrL)}_Vlv+w@K=gP+=pK(%gC335JKpc5 zWv3E{fRwN_o#3&->&n(Q$XMp9vsV-#dwSb)Njr>*Q)N0`;7VaiA|VTLKq(+k&4 zC)jBOoA?M}PN``Ru8>Ey`^FXqPm8U2#&l|~k;Y&>jat;Wc0~E;IFbLw<3xqMGp<*? zw*qtvd(pkx>2V`@791^HMMc-RdMWx2^V(6`w&?qLQ5D^sYtRE7xDI}xZA-Sg^-s4} zs&O~ev1MWE2){7(LI14teok%90~2v`^nq}$w;$-wHGF&r1k5pv+$u4bMRtAE7(cx! zJu`k{Ft7TLQLLr99b>%9x88Ic&)<)qNeK5&n8NkF2{Fy;l$s})?ST)6~Q=z;ltEg)JX!q8h5q75kOBW2iKuB%(v_hTf(;p1*> zTIxd`M6ac5_I%}x!|Zvn@1f8x?kIiLiP(ciQYKII*QwQuX-@|9 zP*O^p($K1d85Ywz+;A$2=aL$8A>Y>|(LGiNQRjL8F?#8x#RQ82>EA%fH^fMI)Zcs& zGl25A86&Ez#l*Jkr^>t-XlkO3p4i-76(|$EDyqG_IB_73Kb>ghS~0P0Tg;qn3ndYA z0iB~*FK7LmUyAh#$O;Mp_V*}R+NWyK+jB>3Z3YwN*x|Ixy(THWFd}MJ{K9cc#oGvWLBW-R z0$zwe>4nO#>!!!6K{Mh-R%J)DSu}LaMb)A{XbvbE5tlK}9HI||u3-(-N|1Qb(fz{y#~1bOM+fUId;J|+_7lRSI`+gccA@H0 zN7nYZJ!oyFHK!F9Tyqa7t>tRWO=X~Cg{;@k7~}1gKfKK_-Y%ThymgJZmNOKU@U0GX zeCMzG{$yG+x2Yh+)*bR0{heo!sy`JT9cT0~|M1-9avc1d=S6=G=g>gMh3cpK!(Cx1 zL$$k~99+}b`jGR>?n>2Od$KDzcYKFP-Vj47l9@%D?&eRqV>LVf8{i4tl$>`~=MGr{hPZ?@j*#3{N7f)~3*La=p z>n)WWbiXh1giC%9G%=rGya{(1iJLx{8g2MgFxMVWwH2-ZyuYUtxvIvL>aHGrs)cy- zoxevfRKHpIR2%W;?4SMYeM(o-g%rwhLzz^2s(5OAb37H1BF~IP^}EMrB%0^<(F$h_ zB}FZszFTM)LPxt`q^Z_wch5iFOoSnV7gIHL-o5km9ifYQ7bm%jbEFiTk1O%VLve)> z1LxGYU(rQ5s_4<)+Ks29f@c&3AR?R-Ww^{Qur+|{C5D4WyRlD8xn%OtFtY=2a=hf3-EVb$# zK2t0VYqSM3Tapi5r(18}zrKCXK)t!W-&6Z&W+oTOJdhJ5inJRy-wY08-C!P~YO?@uRwzg{q)|}&p|J$g2YmpK|^%6|M^rC{8t0FMw zGm6x)#;qtL^r1RXu~uNYG+b7mSl>QL?93pkFcc-ljnt)BPmW%+F5hB*mr|I9 zY2+|VRy|~b(|XVD(2blHwU9E3k5t)TGD^O*OGa^il~G|vT?M)8YPPU}H_jdrJfll` zTxH4ve^+9olm)Vjgxu2oGRe_JvpgRgSk}3?kIUZQ{qRy}ZT9n`)Y6|9HL&UVwpb#Vrq}KF34M4NkSJs)DzO{arxQg7`d(r;26#-^y2bu%;)Aul-I;U` zjus_#6Qb@8%W$nGUDgBMo758*KPPp)Z*cqK2VHvM*KQ}CJe$!3XVCDT-b=TIhPYe_ z-dR2(|E0AX-=p(71ZIa$3_li7^!_)f-Ez^mwRs}hIrCc4p%Bn`24*T#y^o8e2c>rsc~mTKd-xEin*4v?{KCj8FO;D)Tes;D~vo3|DILo(QHKv}m_vepo z5gU?G?Em{;v@7|gj*o?gs8&BU#=maeD!-||Oq~6i6^Pgms!X&DDq{w*ty_ziws9r- z<0m}VmE?y<=4)L^RG>Z-Fm&qJ3Q-c30Yy35t1q<-e7{Zc9G5+GfT1+rYNPFWsROm+ zZcv!^=pyD)jlS{bOTzjKT_6;l+eKqsEOFPN_UHm(4ZXBL3=7vT5KTIFfv^<6T_8-} z(1k%<2QKWw_0ff*EiGKwVvG>7^t1UElTt%_CZ90gHv_9*dvlnzcB1Wxn=`=SqoQ^JH23DkW;Pkt|W=SCoNj%w@%9#>O`SrkKPFdfCegbLm$c z%w>6WrFe0z`h{J8p-o*H!ZAE|?`6J9M13#*Lz3e#NHZB*P$%*A+ zlA~;S^E)WK{Pg{*^#Z;b`Gg+{Q@mAcmQhIho6F+O@;Yy{$d_A+(U1O~iJP|^uh)G) z`(sB zNY`wLN4at%&)ZnIt57j6%wn_~gJ~>Ah84!}NYD0drR;5EJ(HoGKFgs! zk=h08NS7S+)i(t1PWHR0LGBqf!(=+yn|IYxSkanIUy-s$n6M^p^BKWjU1V$YM)Dk@1V7crrbhj2GE5ce)Za5a14XfGx zLVvt+`h%YN>6*DW!vys-C5Hbj2R!n)Xa|D{$=*(^Qc8}?ax_mdX_zV3EgEY%CXIU* zzEW)~j2yiYi;U&_GALf4mz~xpttl0CPg+<{qtKNDc1Z+jHdbynJWk(QZ6o=y(6Y$z z_f}f4Z=g{Enj=k^5a-ic(O$R1lzw}KH zVNPXku;@_AJX%Z}klqlPylDn{~pEA~_g?WllG$1j5cvA!;<__h#Ud7{G zYTPyE6qSm!{aKq@G9#5foJen`i;+^uD}^>=R#ToN=3N_$zOh32K^a@AS}`qTM}?Om zcbI!DjAGPOh@LX(8Yx1DDT~UPj_|VjFbYapkV#WnGfltn&eb01dMTy?2CuesEm za##BDo38XVH(cuSGFNI3>!+rr#fkL>sLfAm_h*Fo36~KSiKnz@GlH9mAD^23;8DxU z=-p4eNpS_v@lD%5JbiyZSISl&$u#$KSGu3{;?9!AMsxK@xO>o2l_3T#VXunOSeRlF zn<^?qA-k+M^;&uQRWXcR^{S|q&tDaartCGL5r28L<=~BbF{~KrU{zrcx{@mB=99|R zHUULfO=4lG36doQIXu_XQxdxVNE`85S20NxlastSCa0Y_W_+{|AI+ap-54B%0A^Q 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�iS{Ms&8wgyUap(;~8wOr~()3$2%Ow$Yi5m9R>d zpkL(Z3Pc5^<8Eu){IZdVyBC0iPH{2?F$U`c3gae#Fo-+}pH%Q9;3u1*3yo(Njk~mt z&Hu`Hu+CZJpK~I&rL3v~-qebk40ET8WB#*Vfz=mvUSw-q_)$(v&WXQO&3*{$wK$hL zzbo8vh+SS}Yq2jhxsoS|WEe52GI`-}CgRc7Nk;%yRylBP)2y0i85>^G~`d(G=WDsLbN4 z8zFsHH@1GQdF^N>uN^de?w_pm!ki6GR{D;9k3zh|W}>>Wy3ui#;lSAeQ@S>QTb~d@ zI&xl+1w%5j)G&hyyF&_N!knfoSQ}YS^PS1c+{l~VzEyO5kTK@@xD+Y1WGjgN$BR>x ze)!neO^NxXeO~)3_IX39a(~!(tqfEOG&~)LpnM#k;aWKj8enxSF@CxjG$v) zlcn4R{OX&n%*My+Y{A0zXDf7UbVj0}Z+9ivp5wu+Qpt9`9?o*cNdp0$1jM%3X{%># zqzwcexK)O@Jp~gPq6>eQOFGyDIc-7k3_(oD+-~h4>LCs$t;(%tB)3}yFS28*;D-k` z`2&4t85@Q(48>_GKIMbk@nn?^TiJS)1X+?N3|SGKh2eHD@i_EWdr2HoyZj*PmwgxJ zwnl3J3~Ph~4B$gumh~{atsCI@1MWZV&Z3i7K7zmtE(@jyo(PzNDXwD&>vB#AjtFkx zV_4F9SzN8E9cVoZT~86%(Ro)i28@zqKpM0bUKwM;WiOFI9GGeEi3iR-iV+JRH;(Go z>GoRq``R_Pg;nnKVQ>d<*ijod=^rIWUH<#yOA2v61~>fMt+fp1=vL8#zoOd!4wxt0 z!2>i1Dop%xu!~=s=`45q6__SY_iNZFuQ_Sno)YAY3m5XCwb*(Ja+odv34+8ecKC3bFxX(4Hy$9Ra+HpoE<{5XqhWUE!MHNr zRWzf(?`o3xW^6R)ZWC?Iw`_zL=O>qHE);I&bdXCnU+ znZMzJL3DXYjuHv+agp`ZAU4})Q2U(DvWP-O_`^9uQvOGd5^CQVV9axbZ3t-eZw$%v z?7^E}Js2$0=JY}J(-8H>w=8F=A%I{tILLQa{9wE9yeQEfAJLtya02WCVxylZ>@z1U zZ+X|iJZD%C!lno}+P-m!?>=P;IU)xz`q>N zbUvn!l5QV5+hFK}hyEGo$R`}1p?HGvbivaZPavL7csk-S;fcl54Nn>#z1$b5=My{^ z@O+Nv2%bH7KEv}Jp0DtHiDws{9e6g*HrPesAMxWDo>n~P@O+Qw44y_j4S2rA zp*z0+lKPDHUs~W-&TqfEx61&!$MFota}s`6>hMJ3dj_6&@T|kL2G5&#-oW!Jo)_?x z;o*3u;JFjeBs^pB1mkH&9o_I5iO!F}=LdM&@wEKe5N|kuFY$Qh;hBIZ2Tvmkl;g9{ z9B%HX#BIvyr%dyO5^1HMVG|#$G%%mPARq#NB43$>-QSmgFa!|#+PhwuX$Zi>I}TA+ zL0!(+5roWU{RWxvH{m&KNLa#K$@KT}yYSa{%H8z+n+NEx&;9u8^J5wQvi>*Gn>s80 Qh77|Q5{rL$h9Tg804>O+)Bpeg -- 2.39.2