// Look and Feel
int opt_fullscreen;
int opt_sound;
+int opt_joystick_enabled;
+int opt_joystick_number;
+int opt_joystick_x_axis;
+int opt_joystick_y_axis;
int opt_autopilot;
puts("Dodge the rocks until you die.");
putchar('\n');
puts(" -f, --full-screen");
- puts(" -s, --silent No explosion sounds or music");
- puts(" -V, --version Print program version");
- puts(" -?, --help Give this help list");
+ puts(" -s, --silent No explosion sounds or music");
+ puts(" -j x,y, --joystick=x,y set the axis numbers. defaults to 0,1");
+ puts(" press a joystick button to activate that joystick");
+ puts(" -V, --version Print program version");
+ puts(" -?, --help Give this help list");
putchar('\n');
puts("Report bugs at http://jasonwoof.com/contact.html");
}
+// Advances buf while reading a positive int, terminated by [^0-9]
+// buf is left pointing at first [^0-9]
+// If digits are found, the parsed number is written to *out and 0 is returned.
+// Otherwise *buf and *out are left unchanged, and non-zero is returned.
+int
+parse_next_int(char **buf, int* out) {
+ int ret = 0, mul = 1;
+ if(!*buf) {
+ return 1;
+ }
+ // make sure *buf starts -?[0-9]
+ if(**buf == '-') {
+ mul = -1;
+ if((*buf)[1] < '0' || (*buf)[1] > '9') {
+ return 2;
+ }
+ *buf += 1;
+ } else {
+ if(**buf < '0' || **buf > '9') {
+ return 2;
+ }
+ }
+ while(**buf >= '0' && **buf <= '9') {
+ ret *= 10;
+ ret += **buf - '0';
+ *buf += 1;
+ }
+ *out = ret * mul;
+
+ return 0;
+}
+
+// returns 1 on success. return 0 causes usage message
+int
+parse_joystick_opts(char *arg) {
+ char *arg_was = arg;
+ static char* bad_arg = "Error: invalid argument to -j/--joystick.";
+
+ // argument is required
+ if(arg == NULL) {
+ puts(bad_arg);
+ return 0;
+ }
+
+ // read x axis
+ if(parse_next_int(&arg, &opt_joystick_x_axis)) {
+ puts(bad_arg);
+ return 0;
+ }
+
+ // skip comma
+ if(*arg != ',') {
+ puts(bad_arg);
+ return 0;
+ }
+ arg += 1;
+
+ // read y axis
+ if(parse_next_int(&arg, &opt_joystick_y_axis)) {
+ puts(bad_arg);
+ return 0;
+ }
+
+ // optionally joystick number
+ if(*arg == ',') {
+ arg += 1; // skip comma
+ if(parse_next_int(&arg, &opt_joystick_number)) {
+ puts(bad_arg);
+ return 0;
+ }
+ opt_joystick_enabled = 1;
+ }
+
+ // end with a comma or end of string
+ if(*arg != 0 && *arg != ',') {
+ puts(bad_arg);
+ return 0;
+ }
+
+ // mark arg as consumed (so it won't be parsed as a commandline switch)
+ arg_was[0] = 0;
+
+ // return success
+ return 1;
+}
int
short_opt(char c, char *arg)
{
switch(c) {
case 'f': opt_fullscreen = 1; break;
case 's': opt_sound = 0; break;
+ case 'j':
+ return parse_joystick_opts(arg);
case 'V':
printf("Variations on Rockdodger %s\n", PACKAGE_VERSION);
exit(0);
return short_opt(*s, arg);
}
-static char *long_opts[] = { "full-screen", "silent", "version", "help", "autopilot" };
+static char *long_opts[] = { "full-screen", "silent", "joystick", "version", "help", "autopilot" };
-static char short_opts[] = { 'f', 's', 'V', 'h', 'a' };
+static char short_opts[] = { 'f', 's', 'j', 'V', 'h', 'a' };
int
parse_long_opt(const char *s, char *arg)
{
opt_fullscreen = 0;
opt_sound = 1;
+ opt_joystick_enabled = 0; // can also be enabled by pressing one of its buttons
+ opt_joystick_number = 0;
+ opt_joystick_x_axis = 0;
+ opt_joystick_y_axis = 1;
opt_autopilot = 0;
}
init_opts();
for(i=1; i<argc; i++) {
char *s, *arg;
+ // args that are consumed as arguments to an option (such as the zero
+ // in: -j 0) have their first byte set to null. So skip them:
s = argv[i]; if(!*s) continue;
if(*s++ != '-') {
fputs("not an option\n\n", stderr);
arg = NULL;
for(r=s; *r; r++) if(*r == '=') { *r = 0; arg = r+1; break; }
- if(!arg && (i+1 < argc)) arg = argv[i+1];
+
+ if(arg == NULL && i + 1 < argc) {
+ arg = argv[i+1];
+ // if this is used, it's first byte will be set to null, and
+ // it'll be skipped. See above.
+ }
if(*s == '-') {
if(!parse_long_opt(s+1, arg)) { show_help(); return 0; }
int paused = 0;
-SDL_Joystick *joy = NULL;
+int num_joysticks = 0;
+SDL_Joystick **joysticks = NULL;
// bangdot start (bd1) and end (bd2) position:
int bd1 = 0, bd2 = 0;
exit(1);
}
- if(SDL_NumJoysticks() > 0)
+ num_joysticks = SDL_NumJoysticks();
+printf("num_joysticks: %i\n", num_joysticks);
+ if(num_joysticks)
{
- NULLERROR(joy = SDL_JoystickOpen(0));
+ joysticks = (SDL_Joystick **)malloc(num_joysticks * sizeof(SDL_Joystick *));
+ for(i = 0; i < num_joysticks; ++i) {
+ NULLERROR(joysticks[i] = SDL_JoystickOpen(i));
+ }
}
init_dots();
SDL_Event e;
Uint8 *keystate;
Sint16 x_move, y_move;
- char button_pressed;
- short i;
+ char button_pressed = 0;
+ short i, j;
float tmp;
for(;;) {
}
}
keystate = SDL_GetKeyState(NULL);
- SDL_JoystickUpdate();
- x_move = SDL_JoystickGetAxis(joy, 4);
- y_move = SDL_JoystickGetAxis(joy, 5);
- button_pressed = 0;
- for(i = 1; i <= SDL_JoystickNumButtons(joy); i++)
- {
- if(SDL_JoystickGetButton(joy, i) == 1)
- {
- button_pressed = 1;
- break;
+ if(num_joysticks) {
+ SDL_JoystickUpdate();
+ if(opt_joystick_enabled) {
+ x_move = SDL_JoystickGetAxis(joysticks[opt_joystick_number], opt_joystick_x_axis);
+ y_move = SDL_JoystickGetAxis(joysticks[opt_joystick_number], opt_joystick_y_axis);
+ button_pressed = 0;
+ for(i = 1; i <= SDL_JoystickNumButtons(joysticks[opt_joystick_number]); i++)
+ {
+ if(SDL_JoystickGetButton(joysticks[opt_joystick_number], i) == 1)
+ {
+ button_pressed = 1;
+ break;
+ }
+ }
+ } else { // there is at least one joystick, but it hasn't been enabled yet
+ // if any joystick has a button down, enable that joystick
+ for(j = 0; j <= num_joysticks; j++) {
+ for(i = 1; i <= SDL_JoystickNumButtons(joysticks[j]); i++)
+ {
+ if(SDL_JoystickGetButton(joysticks[j], i) == 1)
+ {
+ opt_joystick_enabled = 1;
+ opt_joystick_number = j;
+printf("enabled joystick #%i\n", opt_joystick_number);
+ if(state != GAMEPLAY) {
+ // first (enabling) press of the joystick
+ // button should start a game, but should
+ // not pause a running game
+ button_pressed = 1;
+ }
+ break;
+ }
+ }
+ }
}
}
if(keystate[SDLK_UP] || keystate[SDLK_KP8]) {
ship.dy -= THRUSTER_STRENGTH*t_frame; ship.jets |= 1<<3;
}
- if(x_move < -3000) { ship.dx += x_move*THRUSTER_STRENGTH*t_frame/22768; ship.jets |= 1<<0;}
- if(y_move > 3000) { ship.dy += y_move*THRUSTER_STRENGTH*t_frame/22768; ship.jets |= 1<<1;}
- if(x_move > 3000) { ship.dx += x_move*THRUSTER_STRENGTH*t_frame/22768; ship.jets |= 1<<2;}
- if(y_move < -3000) { ship.dy += y_move*THRUSTER_STRENGTH*t_frame/22768; ship.jets |= 1<<3;}
+ if(opt_joystick_enabled) {
+ if(x_move < -3000) { ship.dx += x_move*THRUSTER_STRENGTH*t_frame/22768; ship.jets |= 1<<0;}
+ if(y_move > 3000) { ship.dy += y_move*THRUSTER_STRENGTH*t_frame/22768; ship.jets |= 1<<1;}
+ if(x_move > 3000) { ship.dx += x_move*THRUSTER_STRENGTH*t_frame/22768; ship.jets |= 1<<2;}
+ if(y_move < -3000) { ship.dy += y_move*THRUSTER_STRENGTH*t_frame/22768; ship.jets |= 1<<3;}
+ }
if(ship.jets) {
ship.dx = fconstrain2(ship.dx, -50, 50);
ship.dy = fconstrain2(ship.dy, -50, 50);
frames = 0;
gameloop();
end = SDL_GetTicks();
- // printf("%ld frames in %ld ms, %.2f fps.\n", frames, end-start, frames * 1000.0 / (end-start));
+ printf("%ld frames in %ld ms, %.2f fps.\n", frames, end-start, frames * 1000.0 / (end-start));
return 0;
}