#include "def.h" #include "main.h" #include "sound.h" #include "hardware.h" #include "record.h" #include "digger.h" #ifdef _WINDOWS #include "win_dig.h" #endif #ifdef _SDL #include #endif bool escape=FALSE,firepflag=FALSE,aleftpressed=FALSE,arightpressed=FALSE, auppressed=FALSE,adownpressed=FALSE,start=FALSE,af1pressed=FALSE; bool fire2pflag=FALSE,aleft2pressed=FALSE,aright2pressed=FALSE, aup2pressed=FALSE,adown2pressed=FALSE,af12pressed=FALSE; Sint4 akeypressed; Sint4 dynamicdir=-1,dynamicdir2=-1,staticdir=-1,staticdir2=-1,joyx=0,joyy=0; bool joybut1=FALSE,joybut2=FALSE; Sint4 keydir=0,keydir2=0,jleftthresh=0,jupthresh=0,jrightthresh=0, jdownthresh=0,joyanax=0,joyanay=0; bool joyflag=FALSE,pausef=FALSE; bool krdf[17]={FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE}; #ifdef ARM #include "C:kernel.h" #define rightpressed (_kernel_osbyte(129,keycodes[0][0],255)&0xff==0xff) #define uppressed (_kernel_osbyte(129,keycodes[1][0],255)&0xff==0xff) #define leftpressed (_kernel_osbyte(129,keycodes[2][0],255)&0xff==0xff) #define downpressed (_kernel_osbyte(129,keycodes[3][0],255)&0xff==0xff) #define f1pressed (_kernel_osbyte(129,keycodes[4][0],255)&0xff==0xff) #define right2pressed (_kernel_osbyte(129,keycodes[5][0],255)&0xff==0xff) #define up2pressed (_kernel_osbyte(129,keycodes[6][0],255)&0xff==0xff) #define left2pressed (_kernel_osbyte(129,keycodes[7][0],255)&0xff==0xff) #define down2pressed (_kernel_osbyte(129,keycodes[8][0],255)&0xff==0xff) #define f12pressed (_kernel_osbyte(129,keycodes[9][0],255)&0xff==0xff) /* Default key codes for ARM */ int keycodes[17][5]={{134,0,-2,-2,-2}, /* 1 Right */ {198,0,-2,-2,-2}, /* 1 Up */ {230,0,-2,-2,-2}, /* 1 Left */ {214,0,-2,-2,-2}, /* 1 Down */ {142,0,-2,-2,-2}, /* 1 Fire */ {134,0,-2,-2,-2}, /* 2 Right */ {198,0,-2,-2,-2}, /* 2 Up */ {230,0,-2,-2,-2}, /* 2 Left */ {214,0,-2,-2,-2}, /* 2 Down */ {142,0,-2,-2,-2}, /* 2 Fire */ {20,-2,-2,-2,-2}, /* Cheat */ {43,-2,-2,-2,-2}, /* Accelerate */ {45,-2,-2,-2,-2}, /* Brake */ {137,-2,-2,-2,-2}, /* Music */ {139,-2,-2,-2,-2}, /* Sound */ {140,-2,-2,-2,-2}, /* Exit */ {32,-2,-2,-2,-2}}; /* Pause */ #define ASCIIF8 138 /* This function exclusively used in keyboard redefinition */ void findkey(int kn) { int k=0,i,j; bool f=FALSE; do { for (i=130;i<256 && !f;i++) if (_kernel_osbyte(129,i,255)&0xff==0xff) f=TRUE; gretrace(); if (kbhit()) k=getkey(); } while (k==0 && !f); j=i-1; if (k==0) k=-2; if (k>='a' && k<='z') k-='a'-'A'; for (i=0;i<5;i++) keycodes[kn][i]=-2; if (kn>9) i=0; else { i=2; keycodes[kn][0]=j; keycodes[kn][1]=0; } keycodes[kn][i++]=k; if (k>='A' && k<='Z') { keycodes[kn][i++]=k-('A'-'a'); /* lower case */ keycodes[kn][i++]=k-'@'; /* ctrl code */ } krdf[kn]=TRUE; } #else #ifdef _WINDOWS #define rightpressed (GetAsyncKeyState(keycodes[0][0]) & 0x8000) #define uppressed (GetAsyncKeyState(keycodes[1][0]) & 0x8000) #define leftpressed (GetAsyncKeyState(keycodes[2][0]) & 0x8000) #define downpressed (GetAsyncKeyState(keycodes[3][0]) & 0x8000) #define f1pressed (GetAsyncKeyState(keycodes[4][0])) #define right2pressed (GetAsyncKeyState(keycodes[5][0]) & 0x8000) #define up2pressed (GetAsyncKeyState(keycodes[6][0]) & 0x8000) #define left2pressed (GetAsyncKeyState(keycodes[7][0]) & 0x8000) #define down2pressed (GetAsyncKeyState(keycodes[8][0]) & 0x8000) #define f12pressed (GetAsyncKeyState(keycodes[9][0])) int keycodes[17][5]={{VK_RIGHT,VK_RIGHT+0x80,0x14d,-2,-2}, /* 1 Right */ {VK_UP,VK_UP+0x80,-2,-2}, /* 1 Up */ {VK_LEFT,VK_LEFT+0x80,0x14b,-2,-2}, /* 1 Left */ {VK_DOWN,VK_DOWN+0x80,0x150,-2,-2}, /* 1 Down */ {VK_F1,VK_F1+0x80,0x13b,-2,-2}, /* 1 Fire */ {'S','S'+0x80,83,115,19}, /* 2 Right */ {'W','W'+0x80,87,119,23}, /* 2 Up */ {'A','A'+0x80,65,97,1}, /* 2 Left */ {'Z','Z'+0x80,90,122,26}, /* 2 Down */ {15,143,9,-2,-2}, /* 2 Fire */ {'T',-2,-2,-2,-2}, /* Cheat */ {VK_ADD,-2,-2,-2,-2}, /* Accelerate */ {VK_SUBTRACT,-2,-2,-2,-2}, /* Brake */ {VK_F7,-2,-2,-2,-2}, /* Music */ {VK_F9,-2,-2,-2,-2}, /* Sound */ {VK_F10,-2,-2,-2,-2}, /* Exit */ {VK_SPACE,-2,-2,-2,-2}}; /* Pause */ #define ASCIIF8 VK_F8 #else #ifdef _VGL bool GetAsyncKeyState(int); #define RIGHTKEY 98+128 #define UPKEY 95+128 #define LEFTKEY 97+128 #define DOWNKEY 100+128 #define F1KEY 59+128 #define TABKEY 15+128 #define ADDKEY 78+128 #define SUBKEY 74+128 #define F7KEY 65+128 #define F8KEY 66+128 #define F9KEY 67+128 #define F10KEY 68+128 int keycodes[17][5]={{RIGHTKEY,-2,-2,-2,-2}, /* 1 Right */ {UPKEY,-2,-2,-2,-2}, /* 1 Up */ {LEFTKEY,-2,-2,-2,-2}, /* 1 Left */ {DOWNKEY,-2,-2,-2,-2}, /* 1 Down */ {F1KEY,-2,-2,-2,-2}, /* 1 Fire */ {'s',-2,-2,-2,-2}, /* 2 Right */ {'w',-2,-2,-2,-2}, /* 2 Up */ {'a',-2,-2,-2,-2}, /* 2 Left */ {'z',-2,-2,-2,-2}, /* 2 Down */ {TABKEY,-2,-2,-2,-2}, /* 2 Fire */ {'t',-2,-2,-2,-2}, /* Cheat */ {ADDKEY,-2,-2,-2,-2}, /* Accelerate */ {SUBKEY,-2,-2,-2,-2}, /* Brake */ {F7KEY,-2,-2,-2,-2}, /* Music */ {F9KEY,-2,-2,-2,-2}, /* Sound */ {F10KEY,-2,-2,-2,-2}, /* Exit */ {' ',-2,-2,-2,-2}}; /* Pause */ #define rightpressed (GetAsyncKeyState(keycodes[0][0])) #define uppressed (GetAsyncKeyState(keycodes[1][0])) #define leftpressed (GetAsyncKeyState(keycodes[2][0])) #define downpressed (GetAsyncKeyState(keycodes[3][0])) #define f1pressed (GetAsyncKeyState(keycodes[4][0])) #define right2pressed (GetAsyncKeyState(keycodes[5][0])) #define up2pressed (GetAsyncKeyState(keycodes[6][0])) #define left2pressed (GetAsyncKeyState(keycodes[7][0])) #define down2pressed (GetAsyncKeyState(keycodes[8][0])) #define f12pressed (GetAsyncKeyState(keycodes[9][0])) #define ASCIIF8 F8KEY #else #ifdef _SDL bool GetAsyncKeyState(int); int keycodes[17][5]={{SDLK_RIGHT,-2,-2,-2,-2}, /* 1 Right */ {SDLK_UP,-2,-2,-2,-2}, /* 1 Up */ {SDLK_LEFT,-2,-2,-2,-2}, /* 1 Left */ {SDLK_DOWN,-2,-2,-2,-2}, /* 1 Down */ {SDLK_F1,-2,-2,-2,-2}, /* 1 Fire */ {SDLK_s,-2,-2,-2,-2}, /* 2 Right */ {SDLK_w,-2,-2,-2,-2}, /* 2 Up */ {SDLK_a,-2,-2,-2,-2}, /* 2 Left */ {SDLK_z,-2,-2,-2,-2}, /* 2 Down */ {SDLK_TAB,-2,-2,-2,-2}, /* 2 Fire */ {SDLK_t,-2,-2,-2,-2}, /* Cheat */ {SDLK_KP_PLUS,-2,-2,-2,-2}, /* Accelerate */ {SDLK_KP_MINUS,-2,-2,-2,-2}, /* Brake */ {SDLK_F7,-2,-2,-2,-2}, /* Music */ {SDLK_F9,-2,-2,-2,-2}, /* Sound */ {SDLK_F10,-2,-2,-2,-2}, /* Exit */ {SDLK_SPACE,-2,-2,-2,-2}}; /* Pause */ #define ASCIIF8 SDLK_F8 #define rightpressed (GetAsyncKeyState(keycodes[0][0])) #define uppressed (GetAsyncKeyState(keycodes[1][0])) #define leftpressed (GetAsyncKeyState(keycodes[2][0])) #define downpressed (GetAsyncKeyState(keycodes[3][0])) #define f1pressed (GetAsyncKeyState(keycodes[4][0])) #define right2pressed (GetAsyncKeyState(keycodes[5][0])) #define up2pressed (GetAsyncKeyState(keycodes[6][0])) #define left2pressed (GetAsyncKeyState(keycodes[7][0])) #define down2pressed (GetAsyncKeyState(keycodes[8][0])) #define f12pressed (GetAsyncKeyState(keycodes[9][0])) #else bool leftpressed=FALSE,rightpressed=FALSE,uppressed=FALSE,downpressed=FALSE, f1pressed=FALSE,left2pressed=FALSE,right2pressed=FALSE,up2pressed=FALSE, down2pressed=FALSE,f12pressed=FALSE; /* Default key codes */ int keycodes[17][5]={{0x4d,0xcd,0x14d,-2,-2}, /* 1 Right */ {0x48,0xc8,0x148,-2,-2}, /* 1 Up */ {0x4b,0xcb,0x14b,-2,-2}, /* 1 Left */ {0x50,0xd0,0x150,-2,-2}, /* 1 Down */ {0x3b,0xbb,0x13b,-2,-2}, /* 1 Fire */ {31,159,83,115,19}, /* 2 Right */ {17,145,87,119,23}, /* 2 Up */ {30,158,65,97,1}, /* 2 Left */ {44,172,90,122,26}, /* 2 Down */ {15,143,9,-2,-2}, /* 2 Fire */ {20,-2,-2,-2,-2}, /* Cheat */ {43,-2,-2,-2,-2}, /* Accelerate */ {45,-2,-2,-2,-2}, /* Brake */ {321,-2,-2,-2,-2}, /* Music */ {323,-2,-2,-2,-2}, /* Sound */ {324,-2,-2,-2,-2}, /* Exit */ {32,-2,-2,-2,-2}}; /* Pause */ #define ASCIIF8 322 #endif #endif #endif Uint4 scancode; int pki; #if !defined(_WINDOWS) && !defined(_SDL) && !defined(_VGL) bool *flagp[10]={ &rightpressed,&uppressed,&leftpressed,&downpressed,&f1pressed, &right2pressed,&up2pressed,&left2pressed,&down2pressed,&f12pressed}; /* We need to know when keys are released so we know when to stop. This routine is only called on platforms where keyboard makes and breaks cause interrupts (this being the handler). On platforms where makes and breaks set and release flags, these "variables" are actually macros linking to these flags (they are each only read once). */ void processkey(Uint4 key) { for (pki=0;pki<10;pki++) { if (key==keycodes[pki][0]) /* Make */ *flagp[pki]=TRUE; if (key==keycodes[pki][1]) /* Break */ *flagp[pki]=FALSE; } scancode=key; } #endif #if !defined(_SDL) && !defined(_VGL) /* This function exclusively used in keyboard redefinition */ void findkey(int kn) { int k=0,i; scancode=0; do if (kbhit()) k=getkey(); while (k==0 && (scancode==0 || scancode&0x80)); if (kbhit()) k=getkey(); if (k==0) k=-2; if (k>='a' && k<='z') k-='a'-'A'; for (i=0;i<5;i++) keycodes[kn][i]=-2; if (kn>9) i=0; else { i=2; keycodes[kn][0]=scancode&0x7f; keycodes[kn][1]=scancode|0x80; } keycodes[kn][i++]=k; if (k>='A' && k<='Z') { keycodes[kn][i++]=k-('A'-'a'); /* lower case */ keycodes[kn][i]=k-'@'; /* ctrl code */ } krdf[kn]=TRUE; } #else /* SDL & FBSD */ void findkey(int kn) { keycodes[kn][0] = getkey(); } #endif #endif void readjoy(void); /* The standard ASCII keyboard is also checked so that very short keypresses are not overlooked. The functions kbhit() (returns bool denoting whether or not there is a key in the buffer) and getkey() (wait until a key is in the buffer, then return it) are used. These functions are emulated on platforms which only provide an inkey() function (return the key in the buffer, unless there is none, in which case return -1. It is done this way around for historical reasons, there is no fundamental reason why it shouldn't be the other way around. */ void checkkeyb(void) { int i,j,k=0; bool *aflagp[10]={&arightpressed,&auppressed,&aleftpressed,&adownpressed, &af1pressed,&aright2pressed,&aup2pressed,&aleft2pressed, &adown2pressed,&af12pressed}; if (leftpressed) aleftpressed=TRUE; if (rightpressed) arightpressed=TRUE; if (uppressed) auppressed=TRUE; if (downpressed) adownpressed=TRUE; if (f1pressed) af1pressed=TRUE; if (left2pressed) aleft2pressed=TRUE; if (right2pressed) aright2pressed=TRUE; if (up2pressed) aup2pressed=TRUE; if (down2pressed) adown2pressed=TRUE; if (f12pressed) af12pressed=TRUE; while (kbhit()) { akeypressed=getkey(); for (i=0;i<10;i++) for (j=2;j<5;j++) if (akeypressed==keycodes[i][j]) *aflagp[i]=TRUE; for (i=10;i<17;i++) for (j=0;j<5;j++) if (akeypressed==keycodes[i][j]) k=i; switch (k) { case 10: /* Cheat! */ if (!gauntlet) { playing=FALSE; drfvalid=FALSE; } break; case 11: /* Increase speed */ if (ftime>10000l) ftime-=10000l; break; case 12: /* Decrease speed */ ftime+=10000l; break; case 13: /* Toggle music */ musicflag=!musicflag; break; case 14: /* Toggle sound */ soundflag=!soundflag; break; case 15: /* Exit */ escape=TRUE; break; case 16: /* Pause */ pausef=TRUE; } if (akeypressed==ASCIIF8) /* Save DRF */ savedrf=TRUE; if (akeypressed!=27 && akeypressed!='n' && akeypressed!='N') start=TRUE; /* Change number of players */ } } /* Joystick not yet implemented. It will be, though, using gethrt on platform DOSPC. */ void readjoy(void) { } void detectjoy(void) { joyflag=FALSE; staticdir=dynamicdir=DIR_NONE; } /* Contrary to some beliefs, you don't need a separate OS call to flush the keyboard buffer. */ void flushkeybuf(void) { while (kbhit()) getkey(); aleftpressed=arightpressed=auppressed=adownpressed=af1pressed=FALSE; aleft2pressed=aright2pressed=aup2pressed=adown2pressed=af12pressed=FALSE; } void clearfire(int n) { if (n==0) af1pressed=FALSE; else af12pressed=FALSE; } bool oupressed=FALSE,odpressed=FALSE,olpressed=FALSE,orpressed=FALSE; bool ou2pressed=FALSE,od2pressed=FALSE,ol2pressed=FALSE,or2pressed=FALSE; void readdir(int n) { Sint4 j; bool u=FALSE,d=FALSE,l=FALSE,r=FALSE; bool u2=FALSE,d2=FALSE,l2=FALSE,r2=FALSE; if (n==0) { if (auppressed || uppressed) { u=TRUE; auppressed=FALSE; } if (adownpressed || downpressed) { d=TRUE; adownpressed=FALSE; } if (aleftpressed || leftpressed) { l=TRUE; aleftpressed=FALSE; } if (arightpressed || rightpressed) { r=TRUE; arightpressed=FALSE; } if (f1pressed || af1pressed) { firepflag=TRUE; af1pressed=FALSE; } else firepflag=FALSE; if (u && !oupressed) staticdir=dynamicdir=DIR_UP; if (d && !odpressed) staticdir=dynamicdir=DIR_DOWN; if (l && !olpressed) staticdir=dynamicdir=DIR_LEFT; if (r && !orpressed) staticdir=dynamicdir=DIR_RIGHT; if ((oupressed && !u && dynamicdir==DIR_UP) || (odpressed && !d && dynamicdir==DIR_DOWN) || (olpressed && !l && dynamicdir==DIR_LEFT) || (orpressed && !r && dynamicdir==DIR_RIGHT)) { dynamicdir=DIR_NONE; if (u) dynamicdir=staticdir=2; if (d) dynamicdir=staticdir=6; if (l) dynamicdir=staticdir=4; if (r) dynamicdir=staticdir=0; } oupressed=u; odpressed=d; olpressed=l; orpressed=r; keydir=staticdir; if (dynamicdir!=DIR_NONE) keydir=dynamicdir; staticdir=DIR_NONE; } else { if (aup2pressed || up2pressed) { u2=TRUE; aup2pressed=FALSE; } if (adown2pressed || down2pressed) { d2=TRUE; adown2pressed=FALSE; } if (aleft2pressed || left2pressed) { l2=TRUE; aleft2pressed=FALSE; } if (aright2pressed || right2pressed) { r2=TRUE; aright2pressed=FALSE; } if (f12pressed || af12pressed) { fire2pflag=TRUE; af12pressed=FALSE; } else fire2pflag=FALSE; if (u2 && !ou2pressed) staticdir2=dynamicdir2=DIR_UP; if (d2 && !od2pressed) staticdir2=dynamicdir2=DIR_DOWN; if (l2 && !ol2pressed) staticdir2=dynamicdir2=DIR_LEFT; if (r2 && !or2pressed) staticdir2=dynamicdir2=DIR_RIGHT; if ((ou2pressed && !u2 && dynamicdir2==DIR_UP) || (od2pressed && !d2 && dynamicdir2==DIR_DOWN) || (ol2pressed && !l2 && dynamicdir2==DIR_LEFT) || (or2pressed && !r2 && dynamicdir2==DIR_RIGHT)) { dynamicdir2=DIR_NONE; if (u2) dynamicdir2=staticdir2=2; if (d2) dynamicdir2=staticdir2=6; if (l2) dynamicdir2=staticdir2=4; if (r2) dynamicdir2=staticdir2=0; } ou2pressed=u2; od2pressed=d2; ol2pressed=l2; or2pressed=r2; keydir2=staticdir2; if (dynamicdir2!=DIR_NONE) keydir2=dynamicdir2; staticdir2=DIR_NONE; } if (joyflag) { incpenalty(); incpenalty(); joyanay=0; joyanax=0; for (j=0;j<4;j++) { readjoy(); joyanax+=joyx; joyanay+=joyy; } joyx=joyanax>>2; joyy=joyanay>>2; if (joybut1) firepflag=TRUE; else firepflag=FALSE; } } /* Calibrate joystick while waiting at title screen. This works more effectively if the user waggles the joystick in the title screen. */ bool teststart(void) { Sint4 j; bool startf=FALSE; if (joyflag) { readjoy(); if (joybut1) startf=TRUE; } if (start) { start=FALSE; startf=TRUE; joyflag=FALSE; } if (!startf) return FALSE; if (joyflag) { joyanay=0; joyanax=0; for (j=0;j<50;j++) { readjoy(); joyanax+=joyx; joyanay+=joyy; } joyx=joyanax/50; joyy=joyanay/50; jleftthresh=joyx-35; if (jleftthresh<0) jleftthresh=0; jleftthresh+=10; jupthresh=joyy-35; if (jupthresh<0) jupthresh=0; jupthresh+=10; jrightthresh=joyx+35; if (jrightthresh>255) jrightthresh=255; jrightthresh-=10; jdownthresh=joyy+35; if (jdownthresh>255) jdownthresh=255; jdownthresh-=10; joyanax=joyx; joyanay=joyy; } return TRUE; } /* Why the joystick reading is split between readdir and getdir like this is a mystery to me. */ Sint4 getdir(int n) { Sint4 dir=((n==0) ? keydir : keydir2); if (joyflag) { dir=DIR_NONE; if (joyxjrightthresh) dir=DIR_RIGHT; if (joyx>=jleftthresh && joyx<=jrightthresh) { if (joyyjdownthresh) dir=DIR_DOWN; } } if (n==0) { if (playing) playgetdir(&dir,&firepflag); recputdir(dir,firepflag); } else { if (playing) playgetdir(&dir,&fire2pflag); recputdir(dir,fire2pflag); } return dir; }