#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <time.h>
#include "font.h"
#include "args.h"
#include "common.h"
-#include "config.h"
+#include <config.h>
+#include "vorconfig.h"
#include "dust.h"
#include "file.h"
#include "float.h"
font *g_font;
+#define ENGINEDOT 0
+#define BANGDOT 1
+
struct dot {
int active;
float x, y;
float mass; // in DOT_MASS_UNITs
float decay; // rate at which to reduce mass.
int heat; // heat multiplier (color).
+ uint8_t type; // BANGDOT or ENGINEDOT
};
+void draw(void);
+
struct dot edot[MAXENGINEDOTS], *dotptr = edot;
struct dot bdot[MAXBANGDOTS];
// Other global variables
char topline[1024];
char *initerror = "";
+int screenshot_number = 0;
struct ship ship = { SHIP, 0, NULL, XSIZE/2, YSIZE/2, BARRIER_SPEED, 0.0 };
int paused = 0;
+int num_joysticks = 0;
+SDL_Joystick **joysticks = NULL;
+
// bangdot start (bd1) and end (bd2) position:
int bd1 = 0, bd2 = 0;
// ************************************* FUNCS
+#ifdef HAVE_NANOSLEEP
+void
+tiny_sleep() {
+ struct timespec t;
+ t.tv_sec = 0;
+ t.tv_nsec = 1;
+ nanosleep(&t, 0);
+}
+#else
+#define tiny_sleep()
+#endif
+
void
-init_engine_dots() {
+init_dots() {
int i;
for(i = 0; i<MAXENGINEDOTS; i++) {
edot[i].active = 0;
+ edot[i].type = ENGINEDOT;
+ }
+ for(i = 0; i<MAXBANGDOTS; i++) {
+ bdot[i].active = 0;
+ bdot[i].type = BANGDOT;
}
}
if(SDL_MUSTLOCK(img)) { SDL_UnlockSurface(img); }
}
+void
+kill_rock(struct rock *r) {
+ r->x = -200;
+}
void
move_dot(struct dot *d)
if(hit) if(hit->type != SHIP) {
d->active = 0;
mass = sprite_mass(hit);
+ if(d->type == BANGDOT) {
+ struct rock *rock = (struct rock*)hit;
+ rock->life -= (d->dx - hit->dx) * (d->dx - hit->dx) + (d->dy - hit->dy) * (d->dy - hit->dy);
+ if(rock->life < 0) {
+ kill_rock(rock);
+ }
+ }
hit->dx += DOT_MASS_UNIT * d->mass * (d->dx - hit->dx) / mass;
hit->dy += DOT_MASS_UNIT * d->mass * (d->dy - hit->dy) / mass;
}
font_free(g_font);
}
+void
+set_video_mode() {
+ Uint32 flag;
+
+ // Attempt to get the required video size
+ flag = SDL_DOUBLEBUF | SDL_HWSURFACE;
+ if(opt_fullscreen) flag |= SDL_FULLSCREEN;
+ surf_screen = SDL_SetVideoMode(XSIZE,YSIZE,16,flag);
+}
+
+void
+toggle_fullscreen() {
+ opt_fullscreen = 1 - opt_fullscreen;
+ set_video_mode();
+ if(paused) {
+ draw();
+ }
+}
+
+
int
init(void) {
int i;
char *s;
- Uint32 flag;
// Where are our data files?
if(!find_files()) exit(1);
if(opt_sound) {
// Initialize SDL with audio and video
- if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) != 0) {
+ if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) != 0) {
opt_sound = 0;
fputs("Can't open sound, starting without it\n", stderr);
atexit(SDL_Quit);
}
} else {
// Initialize with video only
- CONDERROR(SDL_Init(SDL_INIT_VIDEO) != 0);
+ CONDERROR(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) != 0);
atexit(SDL_Quit);
}
play_tune(TUNE_TITLE_PAGE);
+
// Attempt to get the required video size
- flag = SDL_DOUBLEBUF | SDL_HWSURFACE;
- if(opt_fullscreen) flag |= SDL_FULLSCREEN;
- surf_screen = SDL_SetVideoMode(XSIZE,YSIZE,16,flag);
+ set_video_mode();
// Set the title bar text
SDL_WM_SetCaption("Variations on Rockdodger", "VoR");
exit(1);
}
- init_engine_dots();
+ num_joysticks = SDL_NumJoysticks();
+printf("num_joysticks: %i\n", num_joysticks);
+ if(num_joysticks)
+ {
+ joysticks = (SDL_Joystick **)malloc(num_joysticks * sizeof(SDL_Joystick *));
+ for(i = 0; i < num_joysticks; ++i) {
+ NULLERROR(joysticks[i] = SDL_JoystickOpen(i));
+ }
+ }
+
+ init_dots();
init_dust();
init_sprites();
x = (XSIZE-font_width(text))/2 + cos(fadetimer/4.5)*10;
font_write(x,YSIZE-100 + cos(fadetimer/3)*5,text);
- text = "Version " VERSION;
+ text = "Version " PACKAGE_VERSION;
x = (XSIZE-font_width(text))/2 + sin(fadetimer/4.5)*10;
font_write(x,YSIZE-50 + sin(fadetimer/2)*5,text);
}
gameloop() {
SDL_Event e;
Uint8 *keystate;
+ Sint16 x_move, y_move;
+ char button_pressed = 0;
+ short i, j;
float tmp;
for(;;) {
autopilot(t_frame);
}
- while(SDL_PollEvent(&e)) {
+ while(paused ? SDL_WaitEvent(&e) : SDL_PollEvent(&e)) {
switch(e.type) {
case SDL_QUIT: return;
case SDL_KEYDOWN:
return;
case SDLK_3:
case SDLK_PRINT:
- // FIXME make a unique filename like vor-screenshot-<pid>-<count>.bmp
- SDL_SaveBMP(surf_screen, "snapshot.bmp");
+ {
+ FILE *screenshot_fp;
+ char tmp[30];
+ char *screenshot_filename = &(tmp[0]);
+ for(;;) {
+ snprintf(screenshot_filename, 30, "vor-screenshot-%02i.bmp", screenshot_number++);
+ screenshot_fp = fopen(screenshot_filename, "r");
+ if(screenshot_fp) {
+ fclose(screenshot_fp);
+ } else {
+ break;
+ }
+ }
+ SDL_SaveBMP(surf_screen, screenshot_filename);
+ }
break;
+ case SDLK_SPACE:
+ if(state != GAMEPLAY && state != DEAD_PAUSE) {
+ // don't conflict with space key to start a new game
+ break;
+ }
+ // else fall through
case SDLK_p:
case SDLK_PAUSE:
paused = !paused;
ms_end = SDL_GetTicks();
}
break;
+ case SDLK_f:
+ case SDLK_F11:
+ toggle_fullscreen();
+ break;
default:
// other keys are handled by checking keystate each frame
break;
}
}
keystate = SDL_GetKeyState(NULL);
+ 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(opt_autopilot) {
autopilot_fix_keystates(keystate);
}
if(keystate[SDLK_UP] || keystate[SDLK_KP8]) {
ship.dy -= THRUSTER_STRENGTH*t_frame; 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);
draw();
// new game
- if((keystate[SDLK_SPACE] || keystate[SDLK_1] || keystate[SDLK_2])
+ if((keystate[SDLK_SPACE] || keystate[SDLK_1] || keystate[SDLK_2] || button_pressed)
&& (state == HIGH_SCORE_DISPLAY
|| state == TITLE_PAGE
|| state == GAME_OVER)) {
if(state == GAME_OVER && new_high_score(score))
init_score_entry();
else {
- if((keystate[SDLK_SPACE] && !initial_rocks) || keystate[SDLK_2]) {
+ if((keystate[SDLK_SPACE] && !initial_rocks) || keystate[SDLK_2] || button_pressed) {
g_easy = 0;
initial_rocks = NORMAL_I_ROCKS;
final_rocks = NORMAL_F_ROCKS;
state = HIGH_SCORE_DISPLAY;
state_timeout = 400;
}
+
+ tiny_sleep();
}
}
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;
}