1
+ #include <stdio.h>
2
+ #include <stdlib.h>
3
+ #include <string.h>
4
+ #include <ctype.h>
5
+ #include <dir.h>
6
+
7
+ #include "dd.h"
8
+
9
+ #include "config.h"
10
+ #include "command.h"
11
+ #include "message.h"
12
+
13
+
14
+ //----------------------------------------------------
15
+ //defs for system options
16
+
17
+ //forces a res on startup
18
+ int option_res(char *p)
19
+ {
20
+ int xw,yw;
21
+ if (sscanf(p,"%d %d",&xw,&yw)<2) return 0;
22
+ SCREENX=xw;
23
+ SCREENY=yw;
24
+ return 1;
25
+ }
26
+
27
+ int option_help(char *p);
28
+ int option_sb(char *p);
29
+ int option_sb16(char *p);
30
+
31
+ static char *inputtypes[]={"NONE","GRAVIS","KEY1","KEY2","JOY1","JOY2",0};
32
+ int getinputtype(char *s)
33
+ {
34
+ for (int i=0; inputtypes[i]; i++)
35
+ if (!stricmp(s,inputtypes[i])) return i;
36
+
37
+ msg.error("Invalid input type %s. Valid types are: ",s);
38
+ for (i=0; inputtypes[i]; i++) msg.error(inputtypes[i]);
39
+ return 0;
40
+ }
41
+
42
+ int option_setinput(char *p)
43
+ {
44
+ int num;
45
+ char type[32]; type[0]=0;
46
+ if (!sscanf(p,"%d %s",&num,type)) return 0;
47
+ num--;
48
+ if (num<0 || num>3) {msg.error("Input num out of range"); return 1;}
49
+
50
+ cfg->pinput[num]=getinputtype(type); //set input
51
+ return 1;
52
+ }
53
+
54
+ char waitvsync;
55
+ int option_waitvsync(char *p)
56
+ {
57
+ waitvsync=1; return 1;
58
+ }
59
+
60
+ extern int SOUNDRATE;
61
+ int option_sndrate(char *p)
62
+ {
63
+ int num;
64
+ if (!sscanf(p,"%d",&num)) return 0;
65
+ if (num<8000) {msg.error("Sample rate too low, min=8000"); return 1;}
66
+ if (num>44100) {msg.error("Sample rate too high, max=44100"); return 1;}
67
+ SOUNDRATE=num;
68
+ return 1;
69
+ }
70
+
71
+ optiondef optiondefs[]=
72
+ {
73
+ #ifdef DOS
74
+ {"?",option_help,0, 0,"Display this help"},
75
+ {"h",option_help,0, 0, 0},
76
+ #endif
77
+
78
+ {"res", option_res,0, "<X-res> <Y-res>", "Change video resolution to (X-res,Y-res)"},
79
+ {"nosound", 0,0, 0,"Disable sound"},
80
+ {"waitvsync",option_waitvsync,0, 0, "Wait till vertical sync to draw frames"},
81
+ {"sndrate", option_sndrate,0, "<samples/sec>", "Change sound rate [default=22010]"},
82
+
83
+ {"swapbut", option_swapbut,0, 0,"Swaps A/B joystick buttons"},
84
+
85
+ #ifdef DOS
86
+ {"sb" , option_sb,0, "<port> <irq> <dma>", "Manually set SB hardware settings"},
87
+ {"sb16" , option_sb16,0, "<port> <irq> <dma>", "Manually set SB16 hardware settings"},
88
+
89
+ {"novesa" , 0,0,0, "Do not use VESA 2.0 extensions"},
90
+ {"banked" , 0,0,0, "Force banked video mode"},
91
+ {"linear" , 0,0,0, "Force linear video mode"},
92
+ #endif
93
+
94
+ {"setinput",option_setinput,0, "<num> <type>","Set input device <num> to <type>"},
95
+
96
+ // {"definekey",option_definekey,0, "<num> <scancodes...>","Redefine keys for keyboard <num> "},
97
+
98
+ {0,0,0,0,0}
99
+ };
100
+
101
+
102
+ //------------------------------------------------------------
103
+ //defs for commands to be executed after system initialization
104
+
105
+ void disablegui();
106
+ void m_showmessages();
107
+ void m_showfps();
108
+ int cmd_message(char *p) {m_showmessages(); return 1;}
109
+ int cmd_showfps(char *p) {m_showfps(); return 1;}
110
+ int cmd_hidegui(char *p) {disablegui(); return 1;}
111
+ int cmd_maximize(char *p);
112
+ int cmd_loadrom(char *p);
113
+ int cmd_runrom(char *p);
114
+ int cmd_restorerom(char *p);
115
+
116
+ int cmd_chdir(char *p)
117
+ {
118
+ chdir(p);
119
+ return 1;
120
+ }
121
+
122
+
123
+ optiondef commanddefs[]=
124
+ {
125
+ {"message", cmd_message, 0, 0, "Display message box"},
126
+ {"showfps", cmd_showfps, 0, 0, "Show frames/sec"},
127
+ {"hidegui", cmd_hidegui, 0, 0, "Hide GUI on startup"},
128
+ {"chdir", cmd_chdir, 0, "<dirname>", "Changes dir on startup"},
129
+ {"load", cmd_loadrom, 0, "<filename>", "Load ROM <filename>"},
130
+ {"run", cmd_runrom, 0, "<filename>", "Load & run ROM <filename>"},
131
+ {"restore", cmd_restorerom, 0, "<filename>", "Load/run/restore ROM <filename>"},
132
+ {0,0,0,0,0}
133
+ };
134
+
135
+ //----------------
136
+
137
+ //find optiondef with specific name, 0 if not found
138
+ optiondef *findoptiondef(char *name,optiondef *od)
139
+ {
140
+ optiondef *c=od;
141
+ for ( ; c->name; c++)
142
+ if (!stricmp(c->name,name)) return c;
143
+ return 0;
144
+ }
145
+
146
+ int getoption(char *name)
147
+ {
148
+ optiondef *od=findoptiondef(name,optiondefs);
149
+ return od ? od->flag : 0;
150
+ }
151
+
152
+ int getcommand(char *name)
153
+ {
154
+ optiondef *od=findoptiondef(name,commanddefs);
155
+ return od ? od->flag : 0;
156
+ }
157
+
158
+
159
+ void optiondef::printhelp()
160
+ {
161
+ if (!desc) return;
162
+ char s[128];
163
+ sprintf(s," -%s %s",name,syntax ? syntax : "");
164
+ memset(s+strlen(s),' ',32);
165
+ s[26]=0;
166
+ strcat(s,desc);
167
+ printf("%s\n",s);
168
+ }
169
+
170
+ //displays help
171
+ int option_help(char *p)
172
+ {
173
+ optiondef *c;
174
+
175
+ #ifdef DOS
176
+ printf("System options: \n");
177
+ for (c=optiondefs; c->name; c++) c->printhelp();
178
+ printf("\n");
179
+ printf("Commands: \n");
180
+ for (c=commanddefs; c->name; c++) c->printhelp();
181
+ exit(1);
182
+ #endif
183
+ return 1;
184
+ }
185
+
186
+
187
+
188
+ //----------------------------------------
189
+ //individual option on option line
190
+
191
+ void option::free()
192
+ {
193
+ if (name) ::free(name);
194
+ if (parm) ::free(parm);
195
+ }
196
+
197
+ void option::print()
198
+ {
199
+ if (!name) return;
200
+ if (parm) msg.printf(1,"%s: %s",name,parm);
201
+ else msg.printf(1,name);
202
+ }
203
+
204
+ //execute a particular commandline option by finding it's
205
+ //option def, setting the flag and calling the func
206
+ void option::execute(int type)
207
+ {
208
+ if (!name) return;
209
+
210
+ optiondef *od=findoptiondef(name,type ? commanddefs : optiondefs);
211
+ if (!od)
212
+ {
213
+ if (!type && !findoptiondef(name,commanddefs))
214
+ msg.error("unrecognized arg: %s",name);
215
+ return; //no option
216
+ }
217
+
218
+ od->flag=1;
219
+ if (od->func && !od->func(parm ? parm : "")) //error executing option....
220
+ msg.error("syntax error: %s %s",od->name,od->syntax);
221
+ }
222
+
223
+
224
+ //----------------------------------------
225
+ //class for parsing/executing commandline
226
+
227
+ //see if something is a option
228
+ inline int isoption(char *s) {return s[0]=='-';}
229
+ inline int isfile(char *s) {return s[0]=='@';}
230
+ inline int isparm(char *s) {return s[0]!='-' && s[0]!='@';}
231
+
232
+ //add option to end of array
233
+ option *commandline::addoption()
234
+ {
235
+ options=(option *)realloc(options,(numoptions+1)*sizeof(option));
236
+ options[numoptions].clear();
237
+ return &options[numoptions++];
238
+ }
239
+
240
+ //print all commands in commandline
241
+ void commandline::print()
242
+ {
243
+ msg.printf(2,"%d options parsed:",numoptions);
244
+ for (int i=0; i<numoptions; i++)
245
+ options[i].print();
246
+ }
247
+
248
+ //execute all commands on commandline
249
+ void commandline::execute(int type)
250
+ {
251
+ for (int i=0; i<numoptions; i++) options[i].execute(type);
252
+ }
253
+
254
+
255
+ //parse commands from array of strings
256
+ void commandline::parse(int argc,char **argv)
257
+ {
258
+ int i=0;
259
+ while (i<argc)
260
+ if (isoption(argv[i])) //see if it's a option
261
+ {
262
+ option *C=addoption(); //add new option...
263
+ C->name=strdup(argv[i]+1); //add option itself
264
+
265
+ static char p[128];
266
+ p[0]=0; //string containing parms for option
267
+ for (i++; i<argc && isparm(argv[i]); i++)
268
+ {if (p[0]) strcat(p," "); strcat(p,argv[i]);}
269
+ C->parm=strdup(p); //add parms
270
+ } else
271
+ if (isfile(argv[i])) //see if it's a file redirection
272
+ {
273
+ char fname[64];
274
+ strcpy(fname,argv[i++]+1);
275
+ if (!strchr(fname,'.')) strcat(fname,".cfg");
276
+
277
+ msg.printf(1,"Parsing file %s",fname);
278
+ FILE *f=fopen(fname,"rt"); //open file
279
+ if (f) parse(f); //parse filename
280
+ fclose(f);
281
+ } else
282
+ {
283
+ option *C=addoption(); //add new option...
284
+ C->name=strdup("run"); //'run' by default
285
+ C->parm=argv[i++];
286
+
287
+ // msg.error("misplaced argument: %s",argv[i++]); //it's misplaced
288
+ }
289
+ }
290
+
291
+
292
+ //parse commands from a string
293
+ void commandline::parse(char *c)
294
+ {
295
+ int argc=0;
296
+ static char *argv[32];
297
+
298
+ while (*c) //until end of commandline...
299
+ {
300
+ while (*c && isspace(*c)) c++; //scan through all spaces
301
+ if (!*c) break;
302
+ argv[argc++]=c; //store string start
303
+ while(*c && !isspace(*c)) c++; //scan through all non-spaces
304
+ if (!*c) break;
305
+ *c=0; //put end of string
306
+ c++;
307
+ }
308
+ parse(argc,argv);
309
+ }
310
+
311
+ //parse commands from a file
312
+ void commandline::parse(FILE *f)
313
+ {
314
+ static char line[256];
315
+ while (fgets(line,256,f)) parse(line);
316
+ }
317
+
318
+ //constructors....
319
+ commandline::commandline() {numoptions=0; options=0;}
320
+
321
+ //destructor
322
+ commandline::~commandline()
323
+ {
324
+ for (int i=0; i<numoptions;
0 commit comments