JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
joysticks: configurable, working, buttons enable
[vor.git] / main.c
diff --git a/main.c b/main.c
index 794ff8d..9227c91 100644 (file)
--- a/main.c
+++ b/main.c
 #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 "vorconfig.h"
 #include "dust.h"
 #include "file.h"
@@ -59,6 +61,9 @@ SDL_Surface
 
 font *g_font;
 
+#define ENGINEDOT 0
+#define BANGDOT 1
+
 struct dot {
        int active;
        float x, y;
@@ -66,6 +71,7 @@ struct dot {
        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);
@@ -97,6 +103,9 @@ float fadetimer = 0;
 
 int paused = 0;
 
+int num_joysticks = 0;
+SDL_Joystick **joysticks = NULL;
+
 // bangdot start (bd1) and end (bd2) position:
 int bd1 = 0, bd2 = 0;
 
@@ -136,11 +145,28 @@ extern int optind, opterr, optopt;
 
 // ************************************* FUNCS
 
+#ifdef HAVE_NANOSLEEP
 void
-init_engine_dots() {
+tiny_sleep() {
+       struct timespec t;
+       t.tv_sec = 0;
+       t.tv_nsec = 1;
+       nanosleep(&t, 0);
+}
+#else
+#define tiny_sleep()
+#endif
+
+void
+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;
        }
 }
 
@@ -264,6 +290,10 @@ new_bang_dots(struct sprite *s)
        if(SDL_MUSTLOCK(img)) { SDL_UnlockSurface(img); }
 }
 
+void
+kill_rock(struct rock *r) {
+       r->x = -200;
+}
 
 void
 move_dot(struct dot *d)
@@ -282,6 +312,13 @@ 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;
                        }
@@ -382,7 +419,7 @@ init(void) {
 
        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);
@@ -393,7 +430,7 @@ init(void) {
                }
        } 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);
        }
 
@@ -437,7 +474,17 @@ init(void) {
                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();
@@ -521,7 +568,7 @@ draw_title_page(void)
        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);
 }
@@ -644,6 +691,9 @@ void
 gameloop() {
        SDL_Event e;
        Uint8 *keystate;
+       Sint16 x_move, y_move;
+       char button_pressed = 0;
+       short i, j;
        float tmp;
 
        for(;;) {
@@ -698,6 +748,12 @@ gameloop() {
                                                                        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;
@@ -721,6 +777,43 @@ gameloop() {
                        }
                }
                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);
                }
@@ -741,6 +834,12 @@ gameloop() {
                                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);
@@ -792,14 +891,14 @@ gameloop() {
                        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;
@@ -835,6 +934,8 @@ gameloop() {
                        state = HIGH_SCORE_DISPLAY;
                        state_timeout = 400;
                }
+
+               tiny_sleep();
        }
 }
 
@@ -851,7 +952,7 @@ main(int argc, char **argv) {
        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;
 }