From 841f94c4182f8dff0253db9bae4922c3c9039a5f Mon Sep 17 00:00:00 2001 From: Joshua Grams Date: Thu, 7 Jul 2005 23:29:54 +0000 Subject: [PATCH] * mt.c: Added (Mersenne Twister random number generator). * sound.h: moved #defines out to here, used them in main.c. * dust.c: moved space dust functions out to here. --- Makefile | 7 +++- args.c | 5 +-- config.h | 2 - dust.c | 51 +++++++++++++++++++++++ dust.h | 19 +++++++++ gfx.mk | 7 ++-- globals.h | 7 ---- main.c | 85 ++++++++++---------------------------- mt.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mt.h | 11 +++++ povimg.sh | 2 +- rocks.c | 16 +++----- sound.c | 7 ---- sound.h | 8 ++++ 14 files changed, 263 insertions(+), 99 deletions(-) create mode 100644 dust.c create mode 100644 dust.h create mode 100644 mt.c create mode 100644 mt.h diff --git a/Makefile b/Makefile index c2efa12..994cd8b 100644 --- a/Makefile +++ b/Makefile @@ -18,15 +18,18 @@ DATA_PREFIX := /usr/share/vor PROGRAM_PREFIX := /usr/games/bin +CFLAGS := -Wall +LDFLAGS := + debug := $(if $(DEBUG),-DDEBUG=1) paths := -DDATA_PREFIX=\"$(DATA_PREFIX)\" sdl-cflags := $(shell sdl-config --cflags) sdl-ldflags := $(shell sdl-config --libs) -ldflags := $(sdl-ldflags) -lSDL_image -lSDL_mixer +ldflags := $(sdl-ldflags) -lSDL_image -lSDL_mixer $(LDFLAGS) cflags := $(sdl-cflags) $(debug) $(paths) $(CFLAGS) -my_objects := args.o file.o rocks.o score.o shape.o sound.o +my_objects := args.o dust.o file.o mt.o rocks.o score.o shape.o sound.o my_objects += $(if $(DEBUG),debug.o) main.o libs := SFont.o objects := $(libs) $(my_objects) diff --git a/args.c b/args.c index 0131215..94ad057 100644 --- a/args.c +++ b/args.c @@ -79,10 +79,7 @@ parse_opt(int key, char *arg, struct argp_state *state) break; case 'm': opt_music = 1; break; case 's': opt_sound = 0; opt_music = 0; break; - case ARGP_KEY_END: - break; - default: - return ARGP_ERR_UNKNOWN; + default: return ARGP_ERR_UNKNOWN; } return 0; } diff --git a/config.h b/config.h index 99bed8f..641234a 100644 --- a/config.h +++ b/config.h @@ -28,8 +28,6 @@ #define MAXENGINEDOTS 5000 #define MAXBANGDOTS 50000 -#define MAXSPACEDOTS 2000 -#define MAXDUSTDEPTH 2 #define W 100 #define M 255 diff --git a/dust.c b/dust.c new file mode 100644 index 0000000..691649d --- /dev/null +++ b/dust.c @@ -0,0 +1,51 @@ +#include +#include + +#include "config.h" +#include "globals.h" +#include "dust.h" +#include "mt.h" + +struct dust_mote { + float x,y,z; + Uint16 color; +}; + +struct dust_mote motes[N_DUST_MOTES]; + +void +init_dust(void) +{ + int i, b; + for(i=0; iformat, b, b, b); + } +} + +void +move_dust(void) +{ + int i; + for(i=0; i= XSIZE) motes[i].x -= XSIZE; + else if(motes[i].x < 0) motes[i].x += XSIZE; + if(motes[i].y > YSIZE) motes[i].y -= YSIZE; + else if(motes[i].y < 0) motes[i].y += YSIZE; + } +} + +void +draw_dust(SDL_Surface *s) +{ + int i; + uint16_t *pixels = s->pixels; + for(i=0; ipitch/2*(int)motes[i].y + (int)motes[i].x] = motes[i].color; + } +} diff --git a/dust.h b/dust.h new file mode 100644 index 0000000..b8e0de1 --- /dev/null +++ b/dust.h @@ -0,0 +1,19 @@ +#ifndef VOR_DUST_H +#define VOR_DUST_H + +#include + +/* + * Dust motes are harmless background items. They are created when the + * program is initialized, and are simply wrapped whenever they hit the + * edge of the screen. + */ + +#define N_DUST_MOTES 2000 +#define MAX_DUST_DEPTH 2 + +void init_dust(void); +void move_dust(void); +void draw_dust(SDL_Surface *); + +#endif // VOR_DUST_H diff --git a/gfx.mk b/gfx.mk index ad3d932..048b8ef 100644 --- a/gfx.mk +++ b/gfx.mk @@ -1,10 +1,11 @@ +gfx-deps := gfx.mk povimg.sh -data/sprites/ship.png: ship.pov gfx.mk +data/sprites/ship.png: ship.pov $(gfx-deps) ./povimg.sh +W32 +H32 $< > $@ -data/indicators/life.png: ship.pov gfx.mk +data/indicators/life.png: ship.pov $(gfx-deps) ./povimg.sh +W17 +H17 $< > $@ -data/sprites/rock%.png: rocks.pov gfx.mk +data/sprites/rock%.png: rocks.pov $(gfx-deps) ./povimg.sh +H52 +W52 +K$* $< > $@ diff --git a/globals.h b/globals.h index fb68ef6..8d0d962 100644 --- a/globals.h +++ b/globals.h @@ -23,12 +23,6 @@ struct enginedots { // is a number starting at between 0 and 50 and counting backward. float life; // When reduced to 0, set active = 0 }; -struct spacedot { - // Space dots are harmless background items - // All are active. When one falls off the edge, another is created at the start. - float x,y,z; - Uint16 color; -}; // ************************************* VARS // SDL_Surface global variables @@ -51,7 +45,6 @@ extern uint32_t area; // Structure global variables extern struct enginedots edot[MAXENGINEDOTS], *dotptr; extern struct bangdots bdot[MAXBANGDOTS], *bdotptr; -extern struct spacedot sdot[MAXSPACEDOTS]; // Other global variables extern char topline[1024]; diff --git a/main.c b/main.c index 92927b5..58d68d7 100644 --- a/main.c +++ b/main.c @@ -37,8 +37,10 @@ #include "args.h" #include "common.h" #include "config.h" +#include "dust.h" #include "file.h" #include "globals.h" +#include "mt.h" #include "rocks.h" #include "score.h" #include "shape.h" @@ -64,7 +66,6 @@ SFont_Font *g_font; // Structure global variables struct enginedots edot[MAXENGINEDOTS], *dotptr = edot; struct bangdots bdot[MAXBANGDOTS], *bdotptr = bdot; -struct spacedot sdot[MAXSPACEDOTS]; // Other global variables char topline[1024]; @@ -126,11 +127,6 @@ extern int optind, opterr, optopt; // ************************************* FUNCS -float -rnd() { - return (float)random()/(float)RAND_MAX; -} - void init_engine_dots() { int i; @@ -140,23 +136,8 @@ init_engine_dots() { } void -init_space_dots() { - int i,b; - for(i = 0; iformat, b, b, b); - } -} - -void -make_bang_dots(int xbang, int ybang, int dx, int dy, SDL_Surface *s, int power) { - - // TODO - stop generating dots after a certain amount of time has passed, to cope with slower CPUs. - // TODO - generate and display dots in a circular buffer - +new_bang_dots(int xbang, int ybang, int dx, int dy, SDL_Surface *s, int power) +{ int x,y,endcount; Uint16 *rawpixel,c; double theta,r; @@ -176,9 +157,9 @@ make_bang_dots(int xbang, int ybang, int dx, int dy, SDL_Surface *s, int power) c = rawpixel[s->pitch/2*y + x]; if(c && c != s->format->colorkey) { - theta = rnd()*M_PI*2; + theta = frnd()*M_PI*2; - r = 1-(rnd()*rnd()); + r = 1-(frnd()*frnd()); bdot[bd2].dx = (power/50.0)*45.0*cos(theta)*r + dx; bdot[bd2].dy = (power/50.0)*45.0*sin(theta)*r + dy; @@ -188,7 +169,7 @@ make_bang_dots(int xbang, int ybang, int dx, int dy, SDL_Surface *s, int power) // Replace the last few bang dots with the pixels from the exploding object bdot[bd2].c = (endcount>0)?c:0; bdot[bd2].life = 100; - bdot[bd2].decay = rnd()*3 + 1; + bdot[bd2].decay = frnd()*3 + 1; bdot[bd2].active = 1; bd2++; @@ -254,26 +235,6 @@ draw_bang_dots(SDL_Surface *s) { void -draw_space_dots(SDL_Surface *s) { - int i; - Uint16 *rawpixel; - rawpixel = (Uint16 *) s->pixels; - - for(i = 0; ipitch/2*(int)sdot[i].y) + (int)(sdot[i].x)] = sdot[i].color; - sdot[i].x -= xscroll / (1.3 + sdot[i].z); - sdot[i].y -= yscroll / (1.3 + sdot[i].z); - if(sdot[i].y >= XSIZE) sdot[i].x -= XSIZE; - else if(sdot[i].x < 0) sdot[i].x = XSIZE-1; - if(sdot[i].y > YSIZE) sdot[i].y -= YSIZE; - else if(sdot[i].y < 0) sdot[i].y += YSIZE-1; - } -} - -void draw_engine_dots(SDL_Surface *s) { int i; Uint16 *rawpixel; @@ -310,14 +271,14 @@ new_engine_dots(int n, int dir) { for(i = 0; iactive == 0) { - a = rnd()*M_PI + (dir-1)*M_PI_2; - r = sin(rnd()*M_PI); + a = frnd()*M_PI + (dir-1)*M_PI_2; + r = sin(frnd()*M_PI); dx = r * cos(a); dy = r * -sin(a); // screen y is "backwards". dotptr->active = 1; - dotptr->x = shipx + s[dir]*hx + (rnd()-0.5)*3; - dotptr->y = shipy + s[(dir+1)&3]*hy + (rnd()-0.5)*3; + dotptr->x = shipx + s[dir]*hx + (frnd()-0.5)*3; + dotptr->y = shipy + s[(dir+1)&3]*hy + (frnd()-0.5)*3; if(dir&1) { dotptr->dx = shipdx + 2*dx; dotptr->dy = shipdy + 20*dy; @@ -347,8 +308,10 @@ drawdots(SDL_Surface *s) { } } + move_dust(); + SDL_LockSurface(s); - draw_space_dots(s); + draw_dust(s); draw_engine_dots(s); draw_bang_dots(s); SDL_UnlockSurface(s); @@ -382,7 +345,7 @@ init(void) { atexit(SDL_Quit); } - play_tune(0); + play_tune(TUNE_TITLE_PAGE); // Attempt to get the required video size flag = SDL_DOUBLEBUF | SDL_HWSURFACE; @@ -431,7 +394,7 @@ init(void) { NULLERROR(surf_life = SDL_DisplayFormat(temp)); init_engine_dots(); - init_space_dots(); + init_dust(); init_rocks(); @@ -536,7 +499,7 @@ draw() { break; case HIGH_SCORE_ENTRY: - play_tune(2); + play_tune(TUNE_HIGH_SCORE_ENTRY); if(!process_score_input()) { // done inputting name // Change state to briefly show high scores page @@ -546,8 +509,7 @@ draw() { // Write the high score table to the file write_high_score_table(); - // Play the title page tune - play_tune(0); + play_tune(TUNE_TITLE_PAGE); } // FALL THROUGH TO case HIGH_SCORE_DISPLAY: @@ -598,7 +560,7 @@ gameloop() { case DEAD_PAUSE: // Create a new ship and start all over again state = GAMEPLAY; - play_tune(1); + play_tune(TUNE_GAMEPLAY); break; case GAME_OVER: if(new_high_score(score)) { @@ -618,9 +580,6 @@ gameloop() { state_timeout = 500.0; break; case HIGH_SCORE_ENTRY: - // state = TITLE_PAGE; - // play_tune(1); - // state_timeout = 100.0; break; case TITLE_PAGE: state = HIGH_SCORE_DISPLAY; @@ -702,9 +661,9 @@ gameloop() { if(draw() && state == GAMEPLAY) { // Died - play_sound(0); // Play the explosion sound + play_sound(SOUND_BANG); // Play the explosion sound bangx = shipx; bangy = shipy; bangdx = shipdx; bangdy = shipdy; - make_bang_dots(shipx,shipy,shipdx,shipdy,surf_ship,30); + new_bang_dots(shipx,shipy,shipdx,shipdy,surf_ship,30); shipdx *= 0.5; shipdy *= 0.5; if(shipdx < SCREENDXMIN) shipdx = SCREENDXMIN; if(--nships <= 0) { @@ -733,7 +692,7 @@ gameloop() { score = 0; state = GAMEPLAY; - play_tune(1); + play_tune(TUNE_GAMEPLAY); gameover = 0; shipx = XSIZE/2.2; shipy = YSIZE/2; diff --git a/mt.c b/mt.c new file mode 100644 index 0000000..ff3a7c9 --- /dev/null +++ b/mt.c @@ -0,0 +1,135 @@ +/* mt.c - A C program for MT199937, with initialization improved 2002-02-10. + + ----- + 2003-07-01 - Stripped out stuff I didn't need, converted to + stdint.h types, changed source formatting a bit. --Josh + ----- + + A C-program for MT19937, with initialization improved 2002-02-10. + Coded by Takuji Nishimura and Makoto Matsumoto. + This is a faster version by taking Shawn Cokus's optimization, + Matthe Bellew's simplification, Isaku Wada's real version. + + Before using, initialize the state by using init_genrand(seed) + or init_by_array(init_key, key_length). + + Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + Any feedback is very welcome. + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat@math.sci.hiroshima-u.ac.jp +*/ + +#include "mt.h" + +/* Period parameters */ +#define N 624 +#define M 397 +#define MATRIX_A 0x9908b0dfUL /* constant vector a */ +#define UMASK 0x80000000UL /* most significant w-r bits */ +#define LMASK 0x7fffffffUL /* least significant r bits */ +#define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) ) +#define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL)) + +static uint32_t state[N]; /* The array for the state vector */ +static int left = 1; +static int initf = 0; +static uint32_t *next; + +/* Initializes state[N] with a seed. */ +void +init_mt(uint32_t s) +{ + int j; + state[0]= s & 0xffffffffUL; + for (j=1; j> 30)) + j); + /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ + /* In the previous versions, MSBs of the seed affect */ + /* only MSBs of the array state[]. */ + /* 2002/01/09 modified by Makoto Matsumoto */ + state[j] &= 0xffffffffUL; /* for >32 bit machines */ + } + left = 1; initf = 1; +} + +static void +next_state(void) +{ + uint32_t *p=state; + int j; + + /* If mt_init() has not been called, + a default initial seed is used. */ + if (initf==0) init_mt(5489UL); + + left = N; + next = state; + + for (j=N-M+1; --j; p++) + *p = p[M] ^ TWIST(p[0], p[1]); + + for (j=M; --j; p++) + *p = p[M-N] ^ TWIST(p[0], p[1]); + + *p = p[M-N] ^ TWIST(p[0], state[0]); +} + +/* Generates a random number in [0,0xffffffff] */ +uint32_t +urnd(void) +{ + uint32_t y; + + if (--left == 0) next_state(); + y = *next++; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680UL; + y ^= (y << 15) & 0xefc60000UL; + y ^= (y >> 18); + + return y; +} + +float +frnd(void) +{ + return urnd()/(float)0x100000000UL; +} + +float +crnd(void) +{ + return (urnd()-0x80000000)/(float)0x100000000UL; +} diff --git a/mt.h b/mt.h new file mode 100644 index 0000000..f7ac92a --- /dev/null +++ b/mt.h @@ -0,0 +1,11 @@ +#ifndef VOR_MT_H +#define VOR_MT_H + +#include + +void init_mt(uint32_t s); +uint32_t irnd(void); // [0, 0xfffffff] +float frnd(void); // [0, 1) +float crnd(void); // [-0.5, 0.5) + +#endif // VOR_MT_H diff --git a/povimg.sh b/povimg.sh index 686a93f..d2263fa 100755 --- a/povimg.sh +++ b/povimg.sh @@ -1,3 +1,3 @@ #!/bin/sh -povray -D +A -O- +FP $* 2>/dev/null | pnmcrop | pnmtopng -transparent =black +povray -D +A -O- +FP $* 2>/dev/null | pnmcrop | pnmtopng -transparent =black 2>/dev/null diff --git a/rocks.c b/rocks.c index fc18bf3..d2fda29 100644 --- a/rocks.c +++ b/rocks.c @@ -7,6 +7,7 @@ #include "config.h" #include "file.h" #include "globals.h" +#include "mt.h" #include "rocks.h" #include "shape.h" @@ -36,11 +37,6 @@ uint32_t nrocks_inc_ticks = 2*60*1000/(F_ROCKS-I_ROCKS); #define RDX 2.5 // range for rock dx values (+/-) #define RDY 2.5 // range for rock dy values (+/-) -float rnd(void); - -#define crnd() (2*(rnd()-0.5)) - - int init_rocks(void) { @@ -133,7 +129,7 @@ rock_sides(float *ti, float *speed_min, float *speed_max) float weighted_rnd_range(float min, float max) { - return sqrt(min * min + rnd() * (max * max - min * min)); + return sqrt(min * min + frnd() * (max * max - min * min)); } void @@ -172,27 +168,27 @@ new_rocks(void) switch(i) { case RIGHT: rockptr->x = XSIZE; - rockptr->y = rnd()*(YSIZE + rockptr->image->h); + rockptr->y = frnd()*(YSIZE + rockptr->image->h); rockptr->dx = -weighted_rnd_range(rmin[i], rmax[i]) + screendx; rockptr->dy = RDY*crnd(); break; case LEFT: rockptr->x = -rockptr->image->w; - rockptr->y = rnd()*(YSIZE + rockptr->image->h); + rockptr->y = frnd()*(YSIZE + rockptr->image->h); rockptr->dx = weighted_rnd_range(rmin[i], rmax[i]) + screendx; rockptr->dy = RDY*crnd(); break; case BOTTOM: - rockptr->x = rnd()*(XSIZE + rockptr->image->w); + rockptr->x = frnd()*(XSIZE + rockptr->image->w); rockptr->y = YSIZE; rockptr->dx = RDX*crnd(); rockptr->dy = -weighted_rnd_range(rmin[i], rmax[i]) + screendy; break; case TOP: - rockptr->x = rnd()*(XSIZE + rockptr->image->w); + rockptr->x = frnd()*(XSIZE + rockptr->image->w); rockptr->y = -rockptr->image->h; rockptr->dx = RDX*crnd(); diff --git a/sound.c b/sound.c index 480690d..7f369ae 100644 --- a/sound.c +++ b/sound.c @@ -9,13 +9,6 @@ #include "config.h" #include "sound.h" -#define TUNE_TITLE_PAGE 0 -#define TUNE_GAMEPLAY 1 -#define TUNE_HIGH_SCORE_ENTRY 2 -#define NUM_TUNES 3 - -#define SOUND_BANG 0 -#define NUM_SOUNDS 4 static Mix_Music *music[NUM_TUNES]; static int music_volume[NUM_TUNES] = {128,128,128}; diff --git a/sound.h b/sound.h index 5f5a586..a73c1c8 100644 --- a/sound.h +++ b/sound.h @@ -23,4 +23,12 @@ int init_sound(void); void play_sound(int i); void play_tune(int i); +#define TUNE_TITLE_PAGE 0 +#define TUNE_GAMEPLAY 1 +#define TUNE_HIGH_SCORE_ENTRY 2 +#define NUM_TUNES 3 + +#define SOUND_BANG 0 +#define NUM_SOUNDS 4 + #endif // VOR_SOUND_H -- 1.7.10.4