/****************************************************************** Joystick configuration utility for David Firth's Atari800 emulator 22.5.1998 Robert Golias (golias@fi.muni.cz) ******************************************************************/ #include "config.h" #include #include #include #include #include #include #include #include #include #include "pcjoy.h" /*color attributes*/ #define BACKGROUND 0x10 #define MENUHEADER 0xe #define MENUITEM 0xb #define MENUSELECT 0x0f #define TITLE 0xf char joysticks[JOYSTICKTYPES][21]={"Off","PC Analog joystick", "LPT1 joystick","LPT2 joystick","LPT3 joystick", "Keyset 0","Keyset 1","Keyset 2","Keyset 3"}; int joytypes[4]={joy_keyset0,joy_keyset1,0,0}; /*note: keyset order: fire, downleft, down, downright, left, right, upleft, up, upright*/ int keysets[4][9]={ {82,79,80,81,75,77,71,72,73}, {15,44,45,46,30,32,16,17,18}, {255,255,255,255,255,255,255,255,255}, {255,255,255,255,255,255,255,255,255}}; char keynames[256][11]={ /*keys 0-127 = normal scancodes*/ "none","ESC","1","2","3","4","5","6", "7","8","9","0","-","+","Backspace","Tab", "Q","W","E","R","T","Y","U","I", "O","P","[","]","Enter","L Ctrl","A","S", "D","F","G","H","J","K","L",";", "\"","`","L Shift","\\","Z","X","C","V", "B","N","M",",",".","/","R Shift","Num *", "L Alt","Space","CapsLock","F1","F2","F3","F4","F5", "F6","F7","F8","F9","F10","NumLock","ScrLock","Num Home", "Num Up","Num PgDn","Num -","Num Left","Num 5","Num Right","Num +","Num End", "Num Down","Num PgDn","Num Ins","Num Del","Alt+PrScr","?","?","F11", "F12","?","?","?","?","?","?","?", "?","?","?","?","?","?","?","?", "?","?","?","?","?","?","?","?", "?","?","?","?","?","?","?","?", "?","?","?","?","?","?","?","?", /*keys 127 - 255 = extended scancodes (preceded with 0xe0) */ "?","?","?","?","?","?","?","?", "?","?","?","?","?","?","?","?", "?","?","?","?","?","?","?","?", "?","?","?","?","Num Enter","R Ctrl","?","?", "?","?","?","?","?","?","?","PrScr", "?","?","#","?","?","?","?","?", "?","?","?","?","?","Num /","?","PrScr", "R Alt","?","?","?","?","?","?","?", "?","?","?","?","?","Pause","?","Gray Home", "Gray Up","Gray PgUp","?","Gray Left","?","Gray Right","?","Gray End", "Gray Down","Gray PgDn","Gray Ins","Gray Del","?","?","?","?", "?","?","?","?","?","?","?","?", "#","#","?","?","?","?","?","?", "?","?","?","?","?","?","?","?", "?","?","?","?","?","?","?","?", "?","?","?","?","?","?","?","none" }; /* Note: "?" = unknown combination "#" = special prefix, ignore (like 0xe0 0xaa with Shift+Insert) "@" = known, but unusable */ /*-----------------------------------------------------------------------*/ void Screen(char *title,int attr) { int i; window(1,1,80,25); textattr(attr); clrscr(); gotoxy(1,1); cputs("ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿"); for (i=2;i<24;i++) { gotoxy(1,i);cputs("³"); gotoxy(80,i);cputs("³"); } gotoxy(1,3); cputs("ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´"); gotoxy(1,24); cputs("ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ"); gotoxy((80-strlen(title))/2,2); cputs(title); window(2,4,79,23); } int SelectItem(char *title,int *selection,int background,...) { va_list params; int y; int i,pos; char *text[20]; int lines; int key; lines=0; va_start(params,background); while (lines<20 && (text[lines]=va_arg(params,char*))!=NULL) lines++; va_end(params); clrscr(); y=(20-lines)/2+2; gotoxy((78-strlen(title))/2,y-1); textattr(background+MENUHEADER); cputs(title); textattr(background+MENUITEM); for (i=0;i1) pos-=2; while (pos>0 && *text[pos]!='-') pos--; if (pos!=0) pos++; while (*text[pos]=='-') pos++; break; case 0x151: /*PgDn*/ while (pos=59 && lastkey<=68) || lastkey==87 || lastkey==88 || lastkey==167 || lastkey==183 || lastkey==70 || lastkey==197; }while ((lastkey&0xff00) || *keynames[lastkey&0xff]=='?' || *keynames[lastkey&0xff]=='#' || bad); newval=lastkey&0xff; if (newval==1) newval=255; sprintf(msg,"Current setting: %s",keynames[newval]); gotoxy(1,11); clreol(); gotoxy((78-strlen(msg))/2,11); cputs(msg); /*wait until key is depressed*/ do{ while (hi==lo); lastkey=buffer[lo++]; if (lo==100) lo=0; }while(!(lastkey&0xff00)); key_done(); return newval; } /*------------------------------------------------------------------------*/ void setupkeyset(int no) { int select,key,i; int keyset[9]; char tUL[80],tU[80],tUR[80],tL[80],tR[80],tDL[80],tDR[80],tD[80],tF[80]; for (i=0;i<9;i++) keyset[i]=keysets[no][i]; select=0; do{ sprintf(tF,"Fire: %s",keynames[keyset[0]]); sprintf(tDL,"Down+left: %s",keynames[keyset[1]]); sprintf(tD,"Down: %s",keynames[keyset[2]]); sprintf(tDR,"Down+right: %s",keynames[keyset[3]]); sprintf(tL,"Left: %s",keynames[keyset[4]]); sprintf(tR,"Right: %s",keynames[keyset[5]]); sprintf(tUL,"Up+left: %s",keynames[keyset[6]]); sprintf(tU,"Up: %s",keynames[keyset[7]]); sprintf(tUR,"Up+right: %s",keynames[keyset[8]]); key=SelectItem("Change settings:",&select,BACKGROUND, tUL,tU,tUR,tL,tR,tDL,tD,tDR,tF,"-","Clear all","-", "Accept changes", "Discard changes",NULL); if (key==13) switch(select) { case 0:keyset[6]=choosekey("up+left",keyset[6]);select++;break; case 1:keyset[7]=choosekey("up",keyset[7]);select++;break; case 2:keyset[8]=choosekey("up+right",keyset[8]);select++;break; case 3:keyset[4]=choosekey("left",keyset[4]);select++;break; case 4:keyset[5]=choosekey("right",keyset[5]);select++;break; case 5:keyset[1]=choosekey("down+left",keyset[1]);select++;break; case 6:keyset[2]=choosekey("down",keyset[2]);select++;break; case 7:keyset[3]=choosekey("down+right",keyset[3]);select++;break; case 8:keyset[0]=choosekey("fire",keyset[0]);break; case 10:for (i=0;i<9;i++) keyset[i]=255;break; } }while (key!=27 && !(key==13 && select>11)); if (key==13 && select==12) for (i=0;i<9;i++) keysets[no][i]=keyset[i]; } /*------------------------------------------------------------------------*/ int mainmenu(void) { char joytext[4][80]; int i,select,key; select=0; do{ for (i=0;i<4;i++) sprintf(joytext[i],"Joystick %i: %s",i,joysticks[joytypes[i]]); key=SelectItem("Select function",&select,BACKGROUND,joytext[0],joytext[1], joytext[2],joytext[3],"-", "Configure keyset 0","Configure keyset 1", "Configure keyset 2","Configure keyset 3","-","Test keyboard collisions", "-","Save and exit","Exit without saving",NULL); switch(key) { case 0x14d: /*right*/ if (select<4) { joytypes[select]++; if (joytypes[select]==JOYSTICKTYPES) joytypes[select]=0; } break; case 0x14b: /*left*/ if (select<4) { joytypes[select]--; if (joytypes[select]==-1) joytypes[select]=JOYSTICKTYPES-1; } break; case 13: /*enter*/ if (select<4) { joytypes[select]++; if (joytypes[select]==JOYSTICKTYPES) joytypes[select]=0; }else if (select<9) { setupkeyset(select-5); }else if (select==10) { testcollisions(); } break; } }while(key!=27 && !(key==13 && select>=12)); return (key==13 && select==12); /*Save only when user pressed ENTER on 'Save&Exit' */ } /*------------------------------------------------------------------------*/ void read_config() { FILE *fr; char string[256]; char *ptr; int i,no; int bad=0; if ((fr=fopen("atari800.cfg","r"))==NULL) { printf("Error opening configuration file.\n" "Execute this utility from atari800 dir after configuring it!\n"); exit(1); } while (fgets(string,sizeof(string),fr)) { i=strlen(string); if (i >= 2 && string[i-2]=='\r' && string[i-1]=='\n') string[i-2]='\0'; else if (i >= 1 && (string[i-1]=='\n' || string[i-1]=='\r')) string[i-1]='\0'; ptr=strchr(string,'='); if (ptr) { *ptr++='\0'; if (strncmp(string,"JOYSTICK_",9)==0) { no=string[9]-'0'; if (no<0 || no>3) {printf("Error in config lines: %s\n",string);bad=1;} else{ for (i=0;i4) {printf("Error in config line: %s\n",string);bad=1;} else { i=sscanf(ptr,"%d %d %d %d %d %d %d %d %d",keysets[no]+0,keysets[no]+1, keysets[no]+2,keysets[no]+3,keysets[no]+4,keysets[no]+5, keysets[no]+6,keysets[no]+7,keysets[no]+8); if (i!=9) {printf("Not enough parametres for KEYSET_x: %s\n",ptr);bad=1;} for (i=0;i<9;i++) if (keysets[no][i]<0 || keysets[no][i]>255) { keysets[no][i]=255; printf("Invalid %i. scancode in KEYSET parameter: %s\n",i+1,ptr); bad=1; } } }/*other commands are ignored*/ } } /*while*/ fclose(fr); if (bad) exit(1); } void save_config() { FILE *fr; FILE *fw; char string[256]; int i; if ((fr=fopen("atari800.cfg","r"))==NULL) { printf("Error opening atari800.cfg!\n"); return; } if ((fw=fopen("atari800.tmp","w"))==NULL) { printf("Error creating temporary file atari800.tmp!\n"); fclose(fr); return; } while (fgets(string,sizeof(string),fr)) { if (strncmp(string,"JOYSTICK_",9)!=0 && strncmp(string,"KEYSET_",7)!=0) fputs(string,fw); /*copy all lines except those with JOYSTICK_ and KEYSET_ parameters*/ } fclose(fr); i=strlen(string)-1; if (i>=0 && string[i]!='\n') fprintf(fw,"\n"); for (i=0;i<4;i++) fprintf(fw,"KEYSET_%i=%i %i %i %i %i %i %i %i %i\n",i, keysets[i][0],keysets[i][1],keysets[i][2],keysets[i][3], keysets[i][4],keysets[i][5],keysets[i][6],keysets[i][7], keysets[i][8]); for (i=0;i<4;i++) fprintf(fw,"JOYSTICK_%i=%s\n",i,joyparams[joytypes[i]]); fclose(fw); if (rename("atari800.tmp","atari800.cfg")==0) printf("Configuration successfully saved.\n"); else printf("Error when renaming atari800.tmp to atari800.cfg!\n"); } /*------------------------------------------------------------------------*/ int main() { int ok; read_config(); _set_screen_lines(25); _setcursortype(_NOCURSOR); Screen("Joystick configuration utility for Atari 800 emulator",BACKGROUND+TITLE); ok=mainmenu(); window(1,1,80,25); textattr(0xf); clrscr(); _setcursortype(_NORMALCURSOR); if (ok) save_config(); return 0; }