4624 lines
120 KiB
C
4624 lines
120 KiB
C
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include <sys/time.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
|
|
#include <math.h>
|
|
|
|
#include <SDL.h>
|
|
#include <SDL_keysym.h>
|
|
#include <SDL_rotozoom.h>
|
|
#include <SDL_ttf.h>
|
|
#include <SDL_framerate.h>
|
|
|
|
#include "defs.h"
|
|
#include "globals.h"
|
|
#include "shared.h"
|
|
|
|
|
|
int loadlevel(int lnum, int wantmonsters) {
|
|
FILE *f;
|
|
int x,y;
|
|
int xx,yy;
|
|
char buf[BUFLEN];
|
|
char buf2[BUFLEN];
|
|
char filename[BUFLEN];
|
|
char tempfile[BUFLEN];
|
|
char *help[MAXHELP];
|
|
int numhelp = 0;
|
|
int curhelp = 0;
|
|
char *p;
|
|
int tileid;
|
|
int i;
|
|
//int *ii;
|
|
//mapping_t mapping[MAXMAPPINGS];
|
|
//int nmappings = 0;
|
|
//tiletype_t *lasttile;
|
|
int newversion;
|
|
int leveldone;
|
|
int numanim = 0;
|
|
int tempanim[LEVELW*LEVELH];
|
|
int numl3 = 0;
|
|
int templ3[LEVELW*LEVELH];
|
|
|
|
sprite_t *ss, *nextss;
|
|
|
|
int numenemies = 0;
|
|
|
|
|
|
|
|
printf("Loading level %d-%d (seq %d) %s...",getworld(lnum), getlevel(lnum), lnum,levelentry[lnum].filename);
|
|
|
|
if (lnum == 101) {
|
|
// special case for intro
|
|
sprintf(filename,"%s/%s/intro.dat",datadir,DIR_LEVELS);
|
|
} else {
|
|
sprintf(filename,"%s/%s/%s",datadir,DIR_LEVELS,levelentry[lnum].filename);
|
|
}
|
|
//filename = levelentry[lnum].filename;
|
|
|
|
f = fopen(filename,"rt");
|
|
if (!f) {
|
|
printf("can't open level file %s\n",filename);
|
|
return B_TRUE;
|
|
}
|
|
|
|
// remember exit direction for current level
|
|
// before loading the new one.
|
|
if (level) {
|
|
oldexitdir = level->exitdir;
|
|
} else {
|
|
oldexitdir = D_RIGHT;
|
|
}
|
|
|
|
|
|
if (!level) {
|
|
level = malloc(sizeof(level_t));
|
|
level->animtiles = NULL;
|
|
level->l3tiles = NULL;
|
|
}
|
|
|
|
sprintf(level->filename, levelentry[lnum].filename);
|
|
|
|
/* set current level pointer */
|
|
curlevel = level;
|
|
|
|
if (level->animtiles) free(level->animtiles);
|
|
if (level->l3tiles) free(level->l3tiles);
|
|
|
|
level->id = levelentry[lnum].id;
|
|
sprintf(level->name, "%s",levelentry[lnum].desc);
|
|
level->prev = NULL;
|
|
level->next = NULL;
|
|
|
|
|
|
/* default */
|
|
level->hurryuptime = 30;
|
|
if (cheat) {
|
|
level->poweruptime = 5;
|
|
} else if (getnumplayers() >= 2) {
|
|
level->poweruptime = POWERUPTIME2;
|
|
} else {
|
|
level->poweruptime = POWERUPTIME;
|
|
}
|
|
level->p1x = 0;
|
|
level->p1y = 0;
|
|
level->powerupx = -1;
|
|
level->powerupy = -1;
|
|
|
|
|
|
|
|
|
|
/* remove all onscreen text */
|
|
while (text) {
|
|
killtext(text);
|
|
}
|
|
|
|
/* clear sprite linked list (leave players) */
|
|
for (ss = sprite ; ss ; ss = nextss) {
|
|
nextss = ss->next;
|
|
if (!isplayer(ss)) {
|
|
killsprite(ss);
|
|
}
|
|
}
|
|
|
|
|
|
/* read tileset */
|
|
/*
|
|
fgets(buf, BUFLEN, f);
|
|
if (strstr(buf, "tileset") == buf) {
|
|
p = strtok(buf, " ");
|
|
p = strtok(NULL, " ");
|
|
|
|
// strip newline
|
|
p[strlen(p)-1] = '\0';
|
|
|
|
|
|
|
|
if ( level->tileset) free(level->tileset);
|
|
level->tileset = strdup(p);
|
|
|
|
strcat(p, ".tiles");
|
|
|
|
if (loadtiletypes(p)) {
|
|
printf("Cannot load tileset file: %s\n", p);
|
|
return B_TRUE;
|
|
}
|
|
|
|
} else {
|
|
printf("invalid tileset file in line: '%s'\n",buf);
|
|
return B_TRUE;
|
|
}
|
|
*/
|
|
/* load background image */
|
|
fgets(buf, BUFLEN, f);
|
|
if (strstr(buf, "bgfile") == buf) {
|
|
SDL_Surface *ts;
|
|
p = strtok(buf, " ");
|
|
p = strtok(NULL, " ");
|
|
|
|
// strip newline
|
|
p[strlen(p)-1] = '\0';
|
|
|
|
|
|
if (levelbg) SDL_FreeSurface(levelbg);
|
|
sprintf(level->bgfile, "%s",p);
|
|
sprintf(tempfile, "%s/backgrounds/%s",datadir,level->bgfile);
|
|
ts = IMG_Load(tempfile);
|
|
if (!ts) {
|
|
printf("Cannot load background file: %s\n", tempfile);
|
|
// default to forest
|
|
sprintf(tempfile, "%s/backgrounds/forest.png",datadir);
|
|
ts = IMG_Load(tempfile);
|
|
SDL_SetColorKey(ts, SDL_RLEACCEL, 0);
|
|
levelbg = SDL_DisplayFormat(ts);
|
|
SDL_FreeSurface(ts);
|
|
} else {
|
|
SDL_SetColorKey(ts, SDL_RLEACCEL, 0);
|
|
levelbg = SDL_DisplayFormat(ts);
|
|
SDL_FreeSurface(ts);
|
|
}
|
|
|
|
} else {
|
|
SDL_Surface *ts;
|
|
// default to forest
|
|
if (levelbg) SDL_FreeSurface(levelbg);
|
|
sprintf(tempfile, "%s/backgrounds/forest.png",datadir);
|
|
ts = IMG_Load(tempfile);
|
|
SDL_SetColorKey(ts, SDL_RLEACCEL, 0);
|
|
levelbg = SDL_DisplayFormat(ts);
|
|
SDL_FreeSurface(ts);
|
|
}
|
|
|
|
|
|
//if (levelbg) SDL_FreeSurface(levelbg);
|
|
//levelbg = IMG_Load("backgrounds/forest.png");
|
|
|
|
/* read background tile */
|
|
fgets(buf, BUFLEN, f);
|
|
if (strstr(buf, "bg") == buf) {
|
|
p = strtok(buf, " ");
|
|
p = strtok(NULL, " ");
|
|
level->bgtileid = atoi(p);
|
|
if (!gettile(level->bgtileid)) {
|
|
printf("invalid background tile id: %d\n",level->bgtileid);
|
|
return B_TRUE;
|
|
}
|
|
//printf("Background tile id is %d (%s)\n",level->bgtileid,(gettile(level->bgtileid)->name));
|
|
} else {
|
|
printf("invalid background tile id line: '%s'\n",buf);
|
|
return B_TRUE;
|
|
}
|
|
|
|
/* read hurryup time tile */
|
|
fgets(buf, BUFLEN, f);
|
|
if (strstr(buf, "hurryup") == buf) {
|
|
p = strtok(buf, " ");
|
|
p = strtok(NULL, " ");
|
|
level->hurryuptime = atoi(p);
|
|
//printf("Hurryup time is %d\n",level->hurryuptime);
|
|
} else {
|
|
printf("invalid hurryup time line: '%s'\n",buf);
|
|
return B_TRUE;
|
|
}
|
|
|
|
level->nummonsters = 0;
|
|
|
|
fgets(buf, BUFLEN, f);
|
|
/* read help messages if present */
|
|
if (strstr(buf, "help")) {
|
|
curhelp = 0; // used later
|
|
numhelp = 0;
|
|
fgets(buf, BUFLEN, f);
|
|
while (!strstr(buf, "endhelp")) {
|
|
// strip newline
|
|
buf[strlen(buf)-1] = '\0';
|
|
help[numhelp] = strdup(buf);
|
|
numhelp++;
|
|
fgets(buf, BUFLEN, f);
|
|
}
|
|
|
|
/* this reads the first line of the level */
|
|
fgets(buf, BUFLEN, f);
|
|
}
|
|
/* read monster definitions if present */
|
|
if (strstr(buf, "monsters")) {
|
|
fgets(buf, BUFLEN, f);
|
|
while (!strstr(buf, "endmonsters")) {
|
|
//char ch;
|
|
int monid;
|
|
int x,y;
|
|
// strip newline
|
|
buf[strlen(buf)-1] = '\0';
|
|
|
|
strncpy(buf2,buf,BUFLEN);
|
|
p = strtok(buf2, " ");
|
|
if (p == NULL) {
|
|
printf("invalid monster definition (missing type): '%s'\n",buf);
|
|
return B_TRUE;
|
|
}
|
|
//ch = p[0]; // type of monster
|
|
//monid = chartomonster(ch);
|
|
// type of monster
|
|
monid = atoi(p);
|
|
if (monid < 0) {
|
|
printf("invalid monster definition (invalid type): '%s'\n",buf);
|
|
return B_TRUE;
|
|
}
|
|
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) {
|
|
printf("invalid monster definition (missing x): '%s'\n",buf);
|
|
return B_TRUE;
|
|
}
|
|
x = atoi(p); // monster x pos
|
|
|
|
p = strtok(NULL, " ");
|
|
if (p == NULL) {
|
|
printf("invalid monster definition (missing y): '%s'\n",buf);
|
|
return B_TRUE;
|
|
}
|
|
y = atoi(p); // monster y pos
|
|
|
|
// waypoints
|
|
if (isplatform(monid)) {
|
|
|
|
// initial waypoint is start position
|
|
level->initm[level->nummonsters].wayx[0] = x*TILEW+(TILEW/2);
|
|
level->initm[level->nummonsters].wayy[0] = y*TILEH+(TILEH-2)+2;
|
|
level->initm[level->nummonsters].numwaypoints = 1;
|
|
|
|
|
|
|
|
// read waypoints
|
|
p = strtok(NULL, " ");
|
|
while (p) {
|
|
level->initm[level->nummonsters].wayx[level->initm[level->nummonsters].numwaypoints] = atoi(p);
|
|
p = strtok(NULL, " ");
|
|
level->initm[level->nummonsters].wayy[level->initm[level->nummonsters].numwaypoints] = atoi(p);
|
|
level->initm[level->nummonsters].numwaypoints++;
|
|
|
|
// go to next one
|
|
p = strtok(NULL, " ");
|
|
}
|
|
|
|
if ( level->initm[level->nummonsters].numwaypoints <= 0 ){
|
|
printf("missing waypoint data for platform!\n");
|
|
}
|
|
}
|
|
|
|
|
|
if (monid == P_PLAYER) {
|
|
level->p1x = x;
|
|
level->p1y = y;
|
|
} else if (monid == P_PLAYER2) {
|
|
level->p2x = x;
|
|
level->p2y = y;
|
|
} else if (monid == P_POWERUPPOS) {
|
|
level->powerupx = x;
|
|
level->powerupy = y;
|
|
level->poweruptype = randompowerup();
|
|
} else {
|
|
/* place the monster */
|
|
level->initm[level->nummonsters].startx = x*TILEW+(TILEW/2);
|
|
level->initm[level->nummonsters].starty = y*TILEH+(TILEH-2)+2;
|
|
level->initm[level->nummonsters].id = monid;
|
|
|
|
|
|
if (ismonster(monid)) numenemies++;
|
|
|
|
if (monid == P_HELP) {
|
|
if (curhelp >= numhelp) {
|
|
printf("Error in level - more help icons than help texts.\n");
|
|
exit(1);
|
|
} else {
|
|
level->initm[level->nummonsters].help = strdup(help[curhelp]);
|
|
curhelp++;
|
|
}
|
|
}
|
|
|
|
level->nummonsters++;
|
|
if (level->nummonsters >= MAXMONSTERSPERLEVEL) {
|
|
printf("ERROR: too many sprites !\n");
|
|
fclose(f);
|
|
return B_TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
fgets(buf, BUFLEN, f);
|
|
}
|
|
|
|
/* this reads the next line after monster defs */
|
|
fgets(buf, BUFLEN, f);
|
|
}
|
|
|
|
|
|
/* exitdir ? */
|
|
if (strstr(buf, "exitdir")) {
|
|
p = strtok(buf, " "); // "exitdir"
|
|
p = strtok(NULL, " ");
|
|
level->exitdir = atoi(p);
|
|
/*
|
|
printf("Exit direction is ");
|
|
switch (level->exitdir) {
|
|
case D_RIGHT:
|
|
printf("RIGHT"); break;
|
|
case D_LEFT:
|
|
printf("lEFT"); break;
|
|
case D_UP:
|
|
printf("UP"); break;
|
|
case D_DOWN:
|
|
printf("DOWN"); break;
|
|
default:
|
|
level->exitdir = D_RIGHT;
|
|
printf("*INVALID*");
|
|
break;
|
|
}
|
|
*/
|
|
printf("\n");
|
|
fgets(buf, BUFLEN, f);
|
|
} else {
|
|
level->exitdir = D_RIGHT;
|
|
printf("Defaulting to exitdir of RIGHT.\n");
|
|
}
|
|
|
|
/* check whether we've got a new or old level version */
|
|
if (strstr(buf, ",")) {
|
|
/* new version */
|
|
newversion = B_TRUE;
|
|
printf("Level data is new version.\n");
|
|
} else {
|
|
/* old version */
|
|
newversion = B_FALSE;
|
|
printf("Level data is old version.\n");
|
|
}
|
|
|
|
x = 0;
|
|
y = 0;
|
|
leveldone = B_FALSE;
|
|
level->bottomopen = B_FALSE; // default, could get chnaged in the next block of code
|
|
while (!leveldone) {
|
|
/* process a line of level data */
|
|
if (newversion) {
|
|
strncpy(buf2, buf, BUFLEN);
|
|
p = strtok(buf2, ",");
|
|
while (p) {
|
|
int numframes;
|
|
tileid = atoi(p);
|
|
/* validate it */
|
|
if (!gettile(tileid)) {
|
|
printf("invalid tileid: %d\n",tileid);
|
|
fclose(f);
|
|
return B_TRUE;
|
|
}
|
|
if (x > LEVELW) {
|
|
printf("Too many tiles on line %d: %d,%d\n",y,x,y);
|
|
fclose(f);
|
|
return B_TRUE;
|
|
}
|
|
if (y >= LEVELH) {
|
|
printf("Too many lines at line %d: %d,%d\n",y,x,y);
|
|
fclose(f);
|
|
return B_TRUE;
|
|
}
|
|
/* all okay */
|
|
level->map[y*LEVELW+x] = tileid;
|
|
|
|
numframes = gettileframecount(tileid);
|
|
if (numframes == 1) {
|
|
// not animated
|
|
level->tileframe[y*LEVELW+x] = 0;
|
|
} else {
|
|
tiletype_t *thistile;
|
|
// animated
|
|
thistile = gettile(tileid);
|
|
if (thistile->animsync) {
|
|
level->tileframe[y*LEVELW+x] = 0;
|
|
} else {
|
|
level->tileframe[y*LEVELW+x] = rand() % numframes;
|
|
}
|
|
tempanim[numanim] = y*LEVELW+x;
|
|
numanim++;
|
|
}
|
|
|
|
// if this is the last line, update level->bottomopen
|
|
if (y == LEVELH-1) {
|
|
tiletype_t *thistile;
|
|
thistile = gettile(tileid);
|
|
if (!thistile->solid) {
|
|
level->bottomopen = B_TRUE;
|
|
}
|
|
}
|
|
|
|
x++;
|
|
p = strtok(NULL, ",");
|
|
}
|
|
|
|
} else { // old level data version
|
|
printf("ERROR: old level data!\n");
|
|
fclose(f);
|
|
return B_TRUE;
|
|
}
|
|
|
|
/* make sure enough data was found */
|
|
if (x < LEVELW+1) {
|
|
printf("Not enough tiles on line: y = %d\n",y);
|
|
fclose(f);
|
|
return B_TRUE;
|
|
}
|
|
|
|
/* go to next line */
|
|
y++;
|
|
x = 0;
|
|
fgets(buf, BUFLEN, f);
|
|
if (feof(f)) {
|
|
leveldone = B_TRUE;
|
|
} else if (strstr(buf, "layer2")) {
|
|
leveldone = B_TRUE;
|
|
}
|
|
}
|
|
|
|
// clear out layer2 and layer3 by default
|
|
for (xx = 0; xx < LEVELW; xx++) {
|
|
for (yy = 0; yy < LEVELH; yy++) {
|
|
level->map2[yy*LEVELW+xx] = T_BLANK;
|
|
level->map3[yy*LEVELW+xx] = T_BLANK;
|
|
}
|
|
}
|
|
|
|
if (!feof(f)) {
|
|
int tid,xx,yy;
|
|
//printf("found second layer\n");
|
|
// second layer exists - read it
|
|
fgets(buf, BUFLEN, f);
|
|
while (!feof(f)) {
|
|
// format is x,y,tileid
|
|
p = strtok(buf, ","); xx = atoi(p);
|
|
p = strtok(NULL, ","); yy = atoi(p);
|
|
p = strtok(NULL, ","); tid = atoi(p);
|
|
p = strtok(NULL, ",");
|
|
if (p == NULL) { // no more data
|
|
level->map2[yy*LEVELW+xx] = tid;
|
|
} else { // more data! this means use layer 3
|
|
level->map3[yy*LEVELW+xx] = tid;
|
|
}
|
|
|
|
fgets(buf, BUFLEN, f);
|
|
|
|
}
|
|
}
|
|
fclose(f);
|
|
|
|
|
|
/// fill in array of l3 tiles for speed
|
|
numl3 = 0;
|
|
for (xx = 0; xx < LEVELW; xx++) {
|
|
for (yy = 0; yy < LEVELH; yy++) {
|
|
if (level->map3[yy*LEVELW+xx] != T_BLANK) {
|
|
templ3[numl3] = yy*LEVELW+xx;
|
|
numl3++;
|
|
}
|
|
}
|
|
}
|
|
|
|
// copy from our temp layer 3 buffer into the real one
|
|
level->l3tiles = malloc(sizeof(int) * (numl3+1));
|
|
memcpy(level->l3tiles,templ3,numl3*sizeof(int));
|
|
level->l3tiles[numl3] = -1;
|
|
|
|
|
|
// copy from our temp animation buffer into the real one
|
|
level->animtiles = malloc(sizeof(int) * (numanim+1));
|
|
memcpy(level->animtiles,tempanim,numanim*sizeof(int));
|
|
level->animtiles[numanim] = -1;
|
|
//level->animtiles = realloc(level->animtiles, (numanim+2) * sizeof(int)); // leave space for terminator
|
|
|
|
if ((numhelp > 0) && (curhelp != numhelp)) {
|
|
printf("WARNING: Unused help text. First unused is '%s'\n",help[curhelp]);
|
|
}
|
|
|
|
if (y < LEVELH) {
|
|
printf("Not enough lines in level: last y=%d, should be %d.\n",
|
|
y,LEVELH);
|
|
return B_TRUE;
|
|
}
|
|
|
|
#ifndef __EDITOR
|
|
if ((level->p1x == 0) || (level->p1y == 0)) {
|
|
printf("Level is missing player 1 start position.\n");
|
|
return B_TRUE;
|
|
}
|
|
if ((level->p2x == 0) || (level->p2y == 0)) {
|
|
printf("Level is missing player 2 start position.\n");
|
|
return B_TRUE;
|
|
}
|
|
#endif
|
|
|
|
/* free help texts */
|
|
for (i = 0; i < numhelp; i++) {
|
|
free(help[i]);
|
|
}
|
|
|
|
|
|
/* add player if required */
|
|
if (want1up) {
|
|
if (player == NULL) {
|
|
player = addsprite(P_PLAYER, (curlevel->p1x * TILEW) + (TILEW/2),
|
|
(curlevel->p1y * TILEH) + TILEH-2 , "Player 1" );
|
|
// call this again to make sure player gets
|
|
// level-based powerups when starting on other
|
|
// levels
|
|
setdefaults(player);
|
|
}
|
|
}
|
|
if (want2up) {
|
|
if (player2 == NULL) {
|
|
player2 = addsprite(P_PLAYER2, (curlevel->p2x * TILEW) + (TILEW/2),
|
|
(curlevel->p2y * TILEH) + TILEH-2 , "Player 2" );
|
|
// call this again to make sure player gets
|
|
// level-based powerups when starting on other
|
|
// levels
|
|
setdefaults(player2);
|
|
}
|
|
}
|
|
|
|
// don't move player to start of the level if they already exist, becuase they're
|
|
// currently on a cloud - we move them after the level transition animation.
|
|
|
|
#ifdef __EDITOR
|
|
/* add powerup and player pos if they exists */
|
|
if ((level->powerupx != -1) && (level->powerupy != -1)) {
|
|
addsprite(P_POWERUPPOS, (curlevel->powerupx * TILEW) + (TILEW/2),
|
|
(curlevel->powerupy * TILEH) + TILEH-2 , "poweruppos" );
|
|
}
|
|
|
|
player->x = (curlevel->p1x * TILEW) + (TILEW/2);
|
|
player->y = (curlevel->p1y * TILEH) + TILEH-2 ;
|
|
player2->x = (curlevel->p2x * TILEW) + (TILEW/2);
|
|
player2->y = (curlevel->p2y * TILEH) + TILEH-2 ;
|
|
#endif
|
|
|
|
/*else {
|
|
player->x = (curlevel->p1x * TILEW) + (TILEW/2);
|
|
player->y = (curlevel->p1y * TILEH) + TILEH-2;
|
|
}
|
|
*/
|
|
|
|
|
|
|
|
/* add monsters */
|
|
if (wantmonsters) {
|
|
for (i = 0; i < level->nummonsters; i++) {
|
|
char name[MIDBUFLEN];
|
|
int delay;
|
|
|
|
if (level->initm[i].id == P_HELP) {
|
|
// is help disabled?
|
|
#ifndef __EDITOR
|
|
if (showhelp == B_FALSE ) continue;
|
|
#endif
|
|
strncpy(name, level->initm[i].help, MIDBUFLEN);
|
|
} else {
|
|
sprintf(name, "Monster-%d",i);
|
|
}
|
|
|
|
if (ismonster(level->initm[i].id)) {
|
|
delay = 20;
|
|
} else {
|
|
delay = 0;
|
|
}
|
|
|
|
|
|
if (isplatform(level->initm[i].id)) {
|
|
sprite_t *newsp;
|
|
int w;
|
|
|
|
newsp = addsprite(level->initm[i].id, level->initm[i].startx, level->initm[i].starty, name );
|
|
newsp->numwaypoints = level->initm[i].numwaypoints;
|
|
for (w = 0; w < newsp->numwaypoints; w++) {
|
|
newsp->wayx[w] = level->initm[i].wayx[w];
|
|
newsp->wayy[w] = level->initm[i].wayy[w];
|
|
}
|
|
newsp->curwaypoint = 1;
|
|
} else {
|
|
#ifdef __EDITOR
|
|
addsprite(level->initm[i].id, level->initm[i].startx, level->initm[i].starty, name );
|
|
#else
|
|
puffin(level->initm[i].id, level->initm[i].startx, level->initm[i].starty, name, delay );
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
gtime = 0;
|
|
resethurryup(level);
|
|
|
|
boss = NULL;
|
|
|
|
printf("Done.\n");
|
|
/*
|
|
for (ii = level->animtiles ; ii && *ii != -1; ii++) {
|
|
printf("%d ",*ii);
|
|
}
|
|
printf(".\n");
|
|
*/
|
|
|
|
return B_FALSE;
|
|
}
|
|
|
|
|
|
|
|
void setdefaults(sprite_t *s) {
|
|
if (isplayer(s)) {
|
|
// set permenant powerups based on level
|
|
if (curlevelnum != INTRO_LEVELNUM) {
|
|
if (curlevelnum > 20) {
|
|
s->permspeed = B_TRUE;
|
|
} else {
|
|
s->permspeed = B_FALSE;
|
|
}
|
|
if (curlevelnum > 40) {
|
|
s->permmask = B_TRUE;
|
|
} else {
|
|
s->permmask = B_FALSE;
|
|
}
|
|
if (curlevelnum > 60) {
|
|
s->permumbrella = B_TRUE;
|
|
} else {
|
|
s->permumbrella = B_FALSE;
|
|
}
|
|
}
|
|
|
|
// player powerup stats
|
|
if (s->permspeed) {
|
|
s->speed = 2;
|
|
} else {
|
|
s->speed = 1;
|
|
}
|
|
if (s->permbignet) {
|
|
s->netbig = B_TRUE;
|
|
} else {
|
|
s->netbig = B_FALSE;
|
|
}
|
|
|
|
if (s->permmask) {
|
|
s->hasmask = B_TRUE;
|
|
} else {
|
|
s->hasmask = B_FALSE;
|
|
}
|
|
|
|
if (s->permnumnets) {
|
|
s->netmax = s->permnumnets;
|
|
} else {
|
|
s->netmax = 1;
|
|
}
|
|
if (s->permsticky) {
|
|
s->netsticky = B_TRUE;
|
|
} else {
|
|
s->netsticky = B_FALSE;
|
|
}
|
|
if (s->permdoublejump) {
|
|
s->doublejump = B_TRUE;
|
|
} else {
|
|
s->doublejump = B_FALSE;
|
|
}
|
|
|
|
if (s->permarmour) {
|
|
s->armour = B_TRUE;
|
|
if (s == player) {
|
|
s->id = P_ARMOUR;
|
|
} else {
|
|
s->id = P_ARMOUR2;
|
|
}
|
|
} else {
|
|
s->armour = B_FALSE;
|
|
}
|
|
|
|
if (s->permumbrella) {
|
|
s->umbrella = B_TRUE;
|
|
} else {
|
|
s->umbrella = B_FALSE;
|
|
}
|
|
|
|
|
|
} else {
|
|
if (s->id == P_PLATFORM) {
|
|
s->speed = PLATFORM_MAXSPEED;
|
|
} else {
|
|
s->speed = 1;
|
|
}
|
|
|
|
s->hasmask = B_FALSE;
|
|
s->armour = B_FALSE;
|
|
s->netsticky = B_FALSE;
|
|
s->doublejump = B_FALSE;
|
|
s->umbrella = B_FALSE;
|
|
s->netbig = B_FALSE;
|
|
s->netmax = 1;
|
|
}
|
|
|
|
s->doublejumpready = B_FALSE;
|
|
|
|
|
|
s->allocimg = B_FALSE;
|
|
|
|
s->frame = 0;
|
|
|
|
s->onplatform = NULL;
|
|
|
|
s->antigrav = B_FALSE;
|
|
|
|
s->hasbell = B_FALSE;
|
|
s->gemboost = 1;
|
|
s->powerup = PW_NONE;
|
|
// player-only states
|
|
s->netting = 0;
|
|
s->netcaught = 0;
|
|
s->slamming = 0;
|
|
s->invuln = 0;
|
|
// states
|
|
s->recoiling = B_FALSE;
|
|
s->teleporting = 0;
|
|
s->climbing = 0;
|
|
s->swimming = 0;
|
|
s->jumping = 0;
|
|
s->jumpspeed = 0;
|
|
s->jumpdir = 1;
|
|
s->useddoublejump = B_FALSE;
|
|
s->umbrellaup = B_FALSE;
|
|
|
|
if (s->id != P_RANDOM) {
|
|
// random gets timer1 set during addsprite()
|
|
s->timer1 = 0;
|
|
}
|
|
s->timer2 = 0;
|
|
s->timer3 = 0;
|
|
s->timer4 = 0;
|
|
|
|
s->dbltimer = -1;
|
|
s->dropping = 0;
|
|
s->dropx = -1;
|
|
s->dropy = -1;
|
|
s->ontramp = B_FALSE;
|
|
s->trampx = -1;
|
|
s->trampy = -1;
|
|
s->quickdie = B_FALSE;
|
|
s->falling = 0;
|
|
s->fallspeed = 0;
|
|
s->dir = 1;
|
|
s->dead = 0;
|
|
s->angry = 0;
|
|
s->jumptimer = 0;
|
|
s->willjumpspeed = 0;
|
|
s->iced = B_FALSE;
|
|
if (s->iceimg) {
|
|
SDL_FreeSurface(s->iceimg);
|
|
s->iceimg = NULL;
|
|
}
|
|
|
|
s->watertimer = 0;
|
|
|
|
s->bullet = NULL;
|
|
s->owner = NULL;
|
|
|
|
s->willbecome = P_CHEESE;
|
|
|
|
// special
|
|
if (s->id == P_PINKCLOUD) {
|
|
s->size = 0.1;
|
|
} else if (s->id == P_BLACKCLOUD) {
|
|
s->size = 0.1;
|
|
} else {
|
|
// not used
|
|
s->size = -1;
|
|
}
|
|
|
|
// special
|
|
if (s->id == P_SNAIL) {
|
|
s->lives = 1;
|
|
}
|
|
|
|
// special for bosses/other monsters
|
|
if (s->id == P_KINGRAT) {
|
|
s->timer1 = 0;
|
|
s->timer2 = KR_WALKTIME;
|
|
s->timer3 = 0;
|
|
} else if (s->id == P_KINGSNAIL) {
|
|
s->timer1 = KSS_WALK1;
|
|
s->timer2 = KS_WALKTIME;
|
|
s->timer3 = 0;
|
|
} else if (s->id == P_KINGFLY) {
|
|
s->timer1 = KFS_FLY1;
|
|
s->timer2 = KF_FLYTIME;
|
|
s->timer3 = 0;
|
|
s->xs = -99;
|
|
s->ys = -99;
|
|
} else if (s->id == P_KINGANT) {
|
|
s->timer1 = KAS_WALK1;
|
|
s->timer2 = KA_WALKTIME;
|
|
s->timer3 = KA_SHOOTTIME;
|
|
} else if (s->id == P_MOTH) {
|
|
s->timer1 = MS_FLY;
|
|
s->timer2 = D_NONE;
|
|
s->timer3 = D_NONE;
|
|
}
|
|
if (isboss(s->id)) {
|
|
s->lives = getbosshealth(s->id); // health
|
|
}
|
|
|
|
|
|
// flying
|
|
switch (s->id) {
|
|
case P_BEE:
|
|
case P_FISH:
|
|
case P_BLACKCLOUD:
|
|
case P_SPIDER:
|
|
case P_KINGFLY:
|
|
case P_MOTH:
|
|
s->flies = B_TRUE;
|
|
break;
|
|
case P_FLY:
|
|
s->flies = F_FLYVERT;
|
|
break;
|
|
default:
|
|
s->flies = B_FALSE;
|
|
break;
|
|
|
|
}
|
|
|
|
if (!isplayer(s)) {
|
|
s->score = getpoints(s->id);
|
|
}
|
|
|
|
s->caughtby = NULL;
|
|
s->caughtstate = B_FALSE;
|
|
|
|
s->zapping = NULL;
|
|
|
|
s->xs = -99;
|
|
s->ys = -99;
|
|
|
|
s->doomcount = 0;
|
|
}
|
|
|
|
/* initial is TRUE if we are populating the level for the first time */
|
|
sprite_t *addsprite(int id, int x, int y, char *name ) {
|
|
sprite_t *s;
|
|
int c;
|
|
|
|
if (sprite == NULL) {
|
|
sprite = malloc(sizeof(sprite_t));
|
|
s = sprite;
|
|
s->prev = NULL;
|
|
} else {
|
|
s = lastsprite;
|
|
s->next = malloc(sizeof(sprite_t));
|
|
s->next->prev = s;
|
|
|
|
s = s->next;
|
|
}
|
|
|
|
|
|
|
|
s->id = id;
|
|
s->x = x;
|
|
s->y = y;
|
|
|
|
// special case for random powerup
|
|
if (s->id == P_RANDOM) {
|
|
s->timer1 = randompowerup();
|
|
while (s->timer1 == P_RANDOM) {
|
|
// pick again
|
|
s->timer1 = randompowerup();
|
|
}
|
|
}
|
|
|
|
|
|
if (s->id == P_BLACKCLOUD) {
|
|
s->img = rotozoomSurfaceXY(imageset[id].img[F_WALK1],0,0.1,0.1,0);
|
|
} else if (s->id == P_PINKCLOUD) {
|
|
s->img = rotozoomSurfaceXY(imageset[id].img[F_WALK1],0,(double)PCGROWSPEED,(double)PCGROWSPEED,0);
|
|
} else if (s->id == P_RANDOM) {
|
|
s->img = imageset[s->timer1].img[F_WALK1];
|
|
} else {
|
|
s->img = imageset[id].img[F_WALK1];
|
|
}
|
|
if (s->y > (480 - TILEH-1)) {
|
|
s->y = 480 - TILEH-1;
|
|
}
|
|
strcpy(s->name, name);
|
|
|
|
if (s == sprite) {
|
|
s->netbg = SDL_CreateRGBSurface(SDL_SWSURFACE,
|
|
200, 64,
|
|
screen->format->BitsPerPixel, screen->format->Rmask,
|
|
screen->format->Gmask,screen->format->Bmask,
|
|
screen->format->Amask);
|
|
} else {
|
|
s->netbg = NULL;
|
|
}
|
|
s->iceimg = NULL;
|
|
|
|
// waypoints for moving platforms
|
|
s->numwaypoints = 0;
|
|
s->curwaypoint = 0;
|
|
|
|
// don't set these in setdefaults() as setdefaults() is called after each player death
|
|
s->permspeed = B_FALSE;
|
|
s->permmask = B_FALSE;
|
|
s->permumbrella = B_FALSE;
|
|
s->permbignet = B_FALSE;
|
|
s->permnumnets = B_FALSE;
|
|
s->permsticky = B_FALSE;
|
|
s->permdoublejump = B_FALSE;
|
|
s->permarmour = B_FALSE;
|
|
|
|
s->lostlife = B_FALSE;
|
|
|
|
// don't set this in setdefaults() as setdefaults() is called after each player death
|
|
s->numcards = 0;
|
|
for (c = 0; c < MAXCARDS; c++) {
|
|
s->card[c] = -1;
|
|
s->usedcard[c] = 0;
|
|
}
|
|
|
|
|
|
setdefaults(s);
|
|
|
|
|
|
// initial fruits don't time out
|
|
#ifndef __EDITOR
|
|
if ((levelcomplete != LV_NEXTLEV) && (levelcomplete != LV_INIT)) {
|
|
if (isfruit(s->id)) {
|
|
// random powerups stay for longer
|
|
if (!strcmp(s->name, "random_up")) {
|
|
s->doomcount = 900;
|
|
} else if (!strcmp(s->name, "goldcoin")) {
|
|
s->doomcount = 1400;
|
|
} else {
|
|
s->doomcount = 500;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
s->next = NULL;
|
|
|
|
lastsprite = s;
|
|
|
|
return s;
|
|
}
|
|
|
|
|
|
|
|
tiletype_t *gettileat(int pixx,int pixy, int *tilex,int *tiley) {
|
|
int tx,ty;
|
|
int tid;
|
|
|
|
tx = pixx / TILEW;
|
|
ty = pixy / TILEH;
|
|
if (tilex != NULL) {
|
|
*tilex = tx;
|
|
}
|
|
if (tiley != NULL) {
|
|
*tiley = ty;
|
|
}
|
|
|
|
if (ty >= LEVELH) {
|
|
// if tile is off the bottom of the screen,
|
|
// return one from the top row
|
|
ty = 0;
|
|
}
|
|
|
|
if (pixy < 0) {
|
|
// if tile is off the top of the screen,
|
|
// return one from the bottom row
|
|
ty = LEVELH-1;
|
|
}
|
|
|
|
// return layer2 if it exists
|
|
tid = curlevel->map2[ty*LEVELW+tx];
|
|
if (tid == T_BLANK) {
|
|
tid = curlevel->map[ty*LEVELW+tx];
|
|
}
|
|
return gettile(tid);
|
|
}
|
|
|
|
int oppositedir(int dir) {
|
|
if (dir == D_RIGHT) return D_LEFT;
|
|
if (dir == D_LEFT) return D_RIGHT;
|
|
if (dir == D_UP) return D_DOWN;
|
|
if (dir == D_DOWN) return D_UP;
|
|
|
|
return D_NONE;
|
|
}
|
|
|
|
tiletype_t *gettilexy(int tilex,int tiley) {
|
|
int tx,ty;
|
|
int tid;
|
|
|
|
tx = tilex;
|
|
ty = tiley;
|
|
|
|
if (tx >= LEVELW) tx = LEVELW-1;
|
|
if (ty >= LEVELH) ty = LEVELH-1;
|
|
|
|
if (ty < 0) ty = 0;
|
|
if (tx < 0) tx = 0;
|
|
|
|
// return layer2 if it exists
|
|
tid = curlevel->map2[ty*LEVELW+tx];
|
|
if (tid == T_BLANK) {
|
|
tid = curlevel->map[ty*LEVELW+tx];
|
|
}
|
|
return gettile(tid);
|
|
}
|
|
|
|
int loadtiletypes(char *filename) {
|
|
char fullfile[BUFLEN];
|
|
tiletype_t *t = NULL;
|
|
int i;
|
|
int state;
|
|
FILE *f;
|
|
char buf[BUFLEN];
|
|
char dirname[BUFLEN];
|
|
char imagefile[BUFLEN];
|
|
char *p,*pp;
|
|
|
|
int uniq = 0 ;
|
|
|
|
/* clear tiletype linked list */
|
|
while (tiletype != NULL) {
|
|
int i;
|
|
tiletype_t *tt;
|
|
|
|
/* kill first tile */
|
|
for (i = 0; i < tiletype->numframes; i++) {
|
|
if (tiletype->img[i]) {
|
|
SDL_FreeSurface(tiletype->img[i]);
|
|
tiletype->img[i] = NULL;
|
|
}
|
|
}
|
|
tt = tiletype->next;
|
|
free(tiletype);
|
|
tiletype = tt;
|
|
}
|
|
|
|
sprintf(fullfile, "%s/%s",datadir,filename);
|
|
|
|
state = 0;
|
|
f = fopen(fullfile,"rt");
|
|
if (!f) {
|
|
printf("can't open tiles file\n");
|
|
return B_TRUE;
|
|
}
|
|
|
|
fgets(buf, BUFLEN, f);
|
|
while (!feof(f)) {
|
|
if (state == 0) {
|
|
if (strstr(buf, "tile") == buf) {
|
|
if (t == NULL) {
|
|
tiletype = malloc(sizeof(tiletype_t));
|
|
t = tiletype;
|
|
t->prev = NULL;
|
|
} else {
|
|
t->next = malloc(sizeof(tiletype_t));
|
|
t->next->prev = t;
|
|
|
|
t = t->next;
|
|
}
|
|
p = strtok(buf, " ");
|
|
p = strtok(NULL, " ");
|
|
/* strip newline */
|
|
p[strlen(p)-1] = '\0';
|
|
strcpy(t->name, p);
|
|
|
|
/* defaults */
|
|
strcpy(dirname, ".");
|
|
|
|
t->id = 0;
|
|
t->animspeed = 0; // not animated
|
|
t->numframes = 1; // not animated
|
|
t->animsync = B_FALSE;
|
|
t->water = B_FALSE;
|
|
t->spikes = B_FALSE;
|
|
t->solid = B_TRUE;
|
|
for (i = 0; i < TILEW; i++) {
|
|
t->lowness[i] = 0;
|
|
}
|
|
for (i = 0; i < MAXTILEFRAMES; i++) {
|
|
t->img[i] = NULL;
|
|
}
|
|
t->next = NULL;
|
|
state = 1;
|
|
|
|
/* unique id */
|
|
t->uniqid = uniq;
|
|
uniq++;
|
|
}
|
|
} else if (state == 1) { /* inside a definition */
|
|
if (strstr(buf, "end") == buf) {
|
|
|
|
//printf("got tile %d: %s (solid=%d)\n",t->id,t->name,t->solid);
|
|
/* check */
|
|
state = 0;
|
|
} else if (strstr(buf, "id") == buf) {
|
|
p = strtok(buf, " ");
|
|
p = strtok(NULL, " ");
|
|
t->id = atoi(p);
|
|
} else if (strstr(buf, "dir") == buf) { // tile directory
|
|
/* strip newline */
|
|
buf[strlen(buf)-1] = '\0';
|
|
|
|
p = strtok(buf, " ");
|
|
p = strtok(NULL, " ");
|
|
strcpy(dirname, p);
|
|
} else if (strstr(buf, "animspeed") == buf) {
|
|
p = strtok(buf, " ");
|
|
p = strtok(NULL, " ");
|
|
t->animspeed = atoi(p);
|
|
} else if (strstr(buf, "animsync") == buf) {
|
|
t->animsync = B_TRUE;
|
|
} else if (strstr(buf, "lowness") == buf) {
|
|
p = strtok(buf, " ");
|
|
p = strtok(NULL, " ");
|
|
pp = strtok(p, ",");
|
|
for (i = 0;i < TILEW; i++) {
|
|
t->lowness[i] = atoi(pp);
|
|
pp = strtok(NULL, ",");
|
|
}
|
|
} else if (strstr(buf, "solid") == buf) {
|
|
p = strtok(buf, " ");
|
|
p = strtok(NULL, " ");
|
|
t->solid = atoi(p);
|
|
} else if (strstr(buf, "spikes") == buf) {
|
|
p = strtok(buf, " ");
|
|
p = strtok(NULL, " ");
|
|
t->spikes = atoi(p);
|
|
} else if (strstr(buf, "water") == buf) {
|
|
p = strtok(buf, " ");
|
|
p = strtok(NULL, " ");
|
|
t->water = atoi(p);
|
|
} else if (strstr(buf, "file") == buf) {
|
|
int frame;
|
|
|
|
/* strip newline */
|
|
buf[strlen(buf)-1] = '\0';
|
|
|
|
p = strtok(buf, " ");
|
|
|
|
// read all images
|
|
frame = 0;
|
|
p = strtok(NULL, " ");
|
|
while (p) {
|
|
if (t->img[frame]) {
|
|
SDL_FreeSurface(t->img[frame]);
|
|
t->img[frame] = NULL;
|
|
}
|
|
sprintf(imagefile, "%s/%s/%s",datadir,dirname,p);
|
|
//strcpy(imagefile, dirname);
|
|
//strcat(imagefile, "/");
|
|
//strcat(imagefile, p);
|
|
|
|
//t->img[frame] = IMG_Load(imagefile);
|
|
t->img[frame] = IMG_Load(imagefile);
|
|
if (!t->img[frame]) {
|
|
printf("cannot load tile image file: '%s'\n",imagefile);
|
|
fclose(f);
|
|
return B_TRUE;
|
|
}
|
|
// black is transparent
|
|
SDL_SetColorKey(t->img[frame], SDL_SRCCOLORKEY, SDL_MapRGB(screen->format, 0, 0, 0));
|
|
|
|
// get next one
|
|
frame++;
|
|
p = strtok(NULL, " ");
|
|
}
|
|
t->numframes = frame;
|
|
// default animation speed
|
|
t->animspeed = 20;
|
|
|
|
}
|
|
}
|
|
fgets(buf, BUFLEN, f);
|
|
}
|
|
|
|
fclose(f);
|
|
return B_FALSE;
|
|
|
|
}
|
|
|
|
int loadimagesets(void) {
|
|
int p,i;
|
|
SDL_Surface *tempsurf;
|
|
SDL_Surface *tempimg;
|
|
SDL_Surface *reds;
|
|
SDL_Surface *origi;
|
|
char tempfile[BUFLEN];
|
|
|
|
sprintf(tempfile, "%s/sprites/gravestone.png",datadir);
|
|
grave = IMG_Load(tempfile);
|
|
|
|
sprintf(tempfile, "%s/sprites/dwarfhead.png",datadir);
|
|
head = IMG_Load(tempfile);
|
|
sprintf(tempfile, "%s/sprites/dwarfhead5.png",datadir);
|
|
head5 = IMG_Load(tempfile);
|
|
sprintf(tempfile, "%s/sprites/dwarf2head.png",datadir);
|
|
head2 = IMG_Load(tempfile);
|
|
sprintf(tempfile, "%s/sprites/dwarf2head5.png",datadir);
|
|
head52 = IMG_Load(tempfile);
|
|
sprintf(tempfile, "%s/sprites/icecube.png",datadir);
|
|
icecube = IMG_Load(tempfile);
|
|
|
|
sprintf(tempfile, "%s/sprites/health.png",datadir);
|
|
healthbar[HF_GREEN] = IMG_Load(tempfile);
|
|
sprintf(tempfile, "%s/sprites/healthyellow.png",datadir);
|
|
healthbar[HF_YELLOW] = IMG_Load(tempfile);
|
|
sprintf(tempfile, "%s/sprites/healthred.png",datadir);
|
|
healthbar[HF_RED] = IMG_Load(tempfile);
|
|
|
|
// green square for flyspray effect
|
|
greenbox = SDL_CreateRGBSurface(SDL_SWSURFACE,
|
|
screen->w,
|
|
screen->h,
|
|
screen->format->BitsPerPixel, screen->format->Rmask,
|
|
screen->format->Gmask,screen->format->Bmask, 0);
|
|
SDL_FillRect(greenbox, NULL, SDL_MapRGB(greenbox->format, 0, 150, 0));
|
|
SDL_SetAlpha(greenbox, SDL_SRCALPHA,80);
|
|
|
|
// red square for gunner effect
|
|
redbox = SDL_CreateRGBSurface(SDL_SWSURFACE,
|
|
screen->w,
|
|
screen->h,
|
|
screen->format->BitsPerPixel, screen->format->Rmask,
|
|
screen->format->Gmask,screen->format->Bmask, 0);
|
|
SDL_FillRect(redbox, NULL, SDL_MapRGB(greenbox->format, 150, 0, 0));
|
|
SDL_SetAlpha(redbox, SDL_SRCALPHA,80);
|
|
|
|
|
|
loadspriteimage(P_PLAYER,F_WALK1, "sprites/pdwarf.png");
|
|
loadspriteimage(P_PLAYER,F_JUMP, "sprites/pdwarfjump.png");
|
|
loadspriteimage(P_PLAYER,F_FALL, "sprites/pdwarffall.png");
|
|
loadspriteimage(P_PLAYER,F_CAUGHT, "sprites/dwarfdie.png");
|
|
loadspriteimage(P_PLAYER,F_DEAD, "sprites/dwarfdie.png");
|
|
/* next 3 are auto generated */
|
|
loadspriteimage(P_PLAYER,F_CLIMB1, "sprites/dclimb1.png");
|
|
loadspriteimage(P_PLAYER,F_CLIMB2, "sprites/dclimb2.png");
|
|
loadspriteimage(P_PLAYER,F_SHOOT, "sprites/dwarfshoot.png");
|
|
loadspriteimage(P_PLAYER,F_SLAM1, "sprites/dslam1.png");
|
|
loadspriteimage(P_PLAYER,F_SLAM2, "sprites/dslam2.png");
|
|
loadspriteimage(P_PLAYER,F_SLAM3, "sprites/dslam3.png");
|
|
loadspriteimage(P_PLAYER,F_SLAM4, "sprites/dslam4.png");
|
|
loadspriteimage(P_PLAYER,F_SLAM5, "sprites/dslam5.png");
|
|
loadspriteimage(P_PLAYER,F_SWIM1, "sprites/dswim1.png");
|
|
loadspriteimage(P_PLAYER,F_SWIM2, "sprites/dswim2.png");
|
|
imageset[P_PLAYER].numimages = 18;
|
|
|
|
loadspriteimage(P_PLAYER2,F_WALK1, "sprites/p2dwarf.png");
|
|
loadspriteimage(P_PLAYER2,F_JUMP, "sprites/p2dwarfjump.png");
|
|
loadspriteimage(P_PLAYER2,F_FALL, "sprites/p2dwarffall.png");
|
|
loadspriteimage(P_PLAYER2,F_CAUGHT, "sprites/dwarf2die.png");
|
|
loadspriteimage(P_PLAYER2,F_DEAD, "sprites/dwarf2die.png");
|
|
/* next 3 are auto generated */
|
|
loadspriteimage(P_PLAYER2,F_CLIMB1, "sprites/d2climb1.png");
|
|
loadspriteimage(P_PLAYER2,F_CLIMB2, "sprites/d2climb2.png");
|
|
loadspriteimage(P_PLAYER2,F_SHOOT, "sprites/dwarf2shoot.png");
|
|
loadspriteimage(P_PLAYER2,F_SLAM1, "sprites/d2slam1.png");
|
|
loadspriteimage(P_PLAYER2,F_SLAM2, "sprites/d2slam2.png");
|
|
loadspriteimage(P_PLAYER2,F_SLAM3, "sprites/d2slam3.png");
|
|
loadspriteimage(P_PLAYER2,F_SLAM4, "sprites/d2slam4.png");
|
|
loadspriteimage(P_PLAYER2,F_SLAM5, "sprites/d2slam5.png");
|
|
loadspriteimage(P_PLAYER2,F_SWIM1, "sprites/d2swim1.png");
|
|
loadspriteimage(P_PLAYER2,F_SWIM2, "sprites/d2swim2.png");
|
|
imageset[P_PLAYER2].numimages = 18;
|
|
|
|
loadspriteimage(P_ARMOUR,F_WALK1, "sprites/armor.png");
|
|
loadspriteimage(P_ARMOUR,F_JUMP, "sprites/armorjump.png");
|
|
loadspriteimage(P_ARMOUR,F_FALL, "sprites/armorfall.png");
|
|
loadspriteimage(P_ARMOUR,F_CAUGHT, "sprites/armorcaught.png");
|
|
loadspriteimage(P_ARMOUR,F_DEAD, "sprites/dwarfdie.png");
|
|
/* next 3 are auto generated */
|
|
loadspriteimage(P_ARMOUR,F_CLIMB1, "sprites/armorclimb1.png");
|
|
loadspriteimage(P_ARMOUR,F_CLIMB2, "sprites/armorclimb2.png");
|
|
loadspriteimage(P_ARMOUR,F_SHOOT, "sprites/armorshoot.png");
|
|
loadspriteimage(P_ARMOUR,F_SLAM1, "sprites/armorslam1.png");
|
|
loadspriteimage(P_ARMOUR,F_SLAM2, "sprites/armorslam2.png");
|
|
loadspriteimage(P_ARMOUR,F_SLAM3, "sprites/armorslam3.png");
|
|
loadspriteimage(P_ARMOUR,F_SLAM4, "sprites/armorslam4.png");
|
|
loadspriteimage(P_ARMOUR,F_SLAM5, "sprites/armorslam5.png");
|
|
loadspriteimage(P_ARMOUR,F_SWIM1, "sprites/armorswim1.png");
|
|
loadspriteimage(P_ARMOUR,F_SWIM2, "sprites/armorswim2.png");
|
|
imageset[P_ARMOUR].numimages = 18;
|
|
|
|
loadspriteimage(P_ARMOUR2,F_WALK1, "sprites/armor2.png");
|
|
loadspriteimage(P_ARMOUR2,F_JUMP, "sprites/armor2jump.png");
|
|
loadspriteimage(P_ARMOUR2,F_FALL, "sprites/armor2fall.png");
|
|
loadspriteimage(P_ARMOUR2,F_CAUGHT, "sprites/armor2caught.png");
|
|
loadspriteimage(P_ARMOUR2,F_DEAD, "sprites/dwarfdie.png"); // not used
|
|
/* next 3 are auto generated */
|
|
loadspriteimage(P_ARMOUR2,F_CLIMB1, "sprites/armor2climb1.png");
|
|
loadspriteimage(P_ARMOUR2,F_CLIMB2, "sprites/armor2climb2.png");
|
|
loadspriteimage(P_ARMOUR2,F_SHOOT, "sprites/armor2shoot.png");
|
|
loadspriteimage(P_ARMOUR2,F_SLAM1, "sprites/armor2slam1.png");
|
|
loadspriteimage(P_ARMOUR2,F_SLAM2, "sprites/armor2slam2.png");
|
|
loadspriteimage(P_ARMOUR2,F_SLAM3, "sprites/armor2slam3.png");
|
|
loadspriteimage(P_ARMOUR2,F_SLAM4, "sprites/armor2slam4.png");
|
|
loadspriteimage(P_ARMOUR2,F_SLAM5, "sprites/armor2slam5.png");
|
|
loadspriteimage(P_ARMOUR2,F_SWIM1, "sprites/armor2swim1.png");
|
|
loadspriteimage(P_ARMOUR2,F_SWIM2, "sprites/armor2swim2.png");
|
|
imageset[P_ARMOUR2].numimages = 18;
|
|
|
|
|
|
loadspriteimage(P_SNAKE,F_WALK1, "sprites/snake.png");
|
|
loadspriteimage(P_SNAKE,F_JUMP, "sprites/snakejump.png");
|
|
loadspriteimage(P_SNAKE,F_FALL, "sprites/snakejump.png");
|
|
loadspriteimage(P_SNAKE,F_CAUGHT, "sprites/snakecaught.png");
|
|
loadspriteimage(P_SNAKE,F_DEAD, "sprites/snakedead.png");
|
|
/* next 3 are auto generated */
|
|
imageset[P_SNAKE].numimages = 8;
|
|
|
|
|
|
loadspriteimage(P_RAT,F_WALK1, "sprites/rat.png");
|
|
loadspriteimage(P_RAT,F_JUMP, "sprites/ratjump.png");
|
|
loadspriteimage(P_RAT,F_FALL, "sprites/ratjump.png");
|
|
loadspriteimage(P_RAT,F_CAUGHT, "sprites/ratcaught.png");
|
|
loadspriteimage(P_RAT,F_DEAD, "sprites/ratdead.png");
|
|
/* next 3 are auto generated */
|
|
imageset[P_RAT].numimages = 8;
|
|
|
|
loadspriteimage(P_BEE,F_WALK1, "sprites/newbee.png");
|
|
loadspriteimage(P_BEE,F_JUMP, "sprites/newbeejump.png");
|
|
loadspriteimage(P_BEE,F_FALL, "sprites/newbeejump.png");
|
|
loadspriteimage(P_BEE,F_CAUGHT, "sprites/newbeecaught.png");
|
|
loadspriteimage(P_BEE,F_DEAD, "sprites/newbeedead.png");
|
|
/* next 3 are auto generated */
|
|
imageset[P_BEE].numimages = 8;
|
|
|
|
loadspriteimage(P_FLY,F_WALK1, "sprites/fly.png");
|
|
loadspriteimage(P_FLY,F_JUMP, "sprites/flywalk2.png");
|
|
loadspriteimage(P_FLY,F_FALL, "sprites/flyjump.png");
|
|
loadspriteimage(P_FLY,F_CAUGHT, "sprites/flycaught.png");
|
|
loadspriteimage(P_FLY,F_DEAD, "sprites/flydead.png");
|
|
/* next 3 are auto generated */
|
|
imageset[P_FLY].numimages = 8;
|
|
|
|
loadspriteimage(P_FROG,F_WALK1, "sprites/frog.png");
|
|
loadspriteimage(P_FROG,F_JUMP, "sprites/frogjump.png");
|
|
loadspriteimage(P_FROG,F_FALL, "sprites/frogfall.png");
|
|
loadspriteimage(P_FROG,F_CAUGHT, "sprites/frogcaught.png");
|
|
loadspriteimage(P_FROG,F_DEAD, "sprites/frogdead.png");
|
|
/* next 3 are auto generated */
|
|
imageset[P_FROG].numimages = 8;
|
|
|
|
|
|
loadspriteimage(P_ANT1,F_WALK1, "sprites/ant1.png");
|
|
loadspriteimage(P_ANT1,F_JUMP, "sprites/ant1jump.png");
|
|
loadspriteimage(P_ANT1,F_FALL, "sprites/ant1jump.png");
|
|
loadspriteimage(P_ANT1,F_CAUGHT, "sprites/ant1caught.png");
|
|
loadspriteimage(P_ANT1,F_DEAD, "sprites/ant1dead.png");
|
|
/* next 3 are auto generated */
|
|
imageset[P_ANT1].numimages = 8;
|
|
|
|
loadspriteimage(P_ANT2,F_WALK1, "sprites/ant2.png");
|
|
loadspriteimage(P_ANT2,F_JUMP, "sprites/ant2jump.png");
|
|
loadspriteimage(P_ANT2,F_FALL, "sprites/ant2jump.png");
|
|
loadspriteimage(P_ANT2,F_CAUGHT, "sprites/ant2caught.png");
|
|
loadspriteimage(P_ANT2,F_DEAD, "sprites/ant2dead.png");
|
|
/* next 3 are auto generated */
|
|
imageset[P_ANT2].numimages = 8;
|
|
|
|
loadspriteimage(P_ANT3,F_WALK1, "sprites/ant3.png");
|
|
loadspriteimage(P_ANT3,F_JUMP, "sprites/ant3jump.png");
|
|
loadspriteimage(P_ANT3,F_FALL, "sprites/ant3jump.png");
|
|
loadspriteimage(P_ANT3,F_CAUGHT, "sprites/ant3caught.png");
|
|
loadspriteimage(P_ANT3,F_DEAD, "sprites/ant3dead.png");
|
|
/* next 3 are auto generated */
|
|
imageset[P_ANT3].numimages = 8;
|
|
|
|
loadspriteimage(P_WSPIDER,F_WALK1, "sprites/whitespider.png");
|
|
loadspriteimage(P_WSPIDER,F_JUMP, "sprites/whitespider1.png");
|
|
loadspriteimage(P_WSPIDER,F_FALL, "sprites/whitespider1.png");
|
|
loadspriteimage(P_WSPIDER,F_CAUGHT, "sprites/whitespidercaught.png");
|
|
loadspriteimage(P_WSPIDER,F_DEAD, "sprites/whitespiderdead.png");
|
|
/* next 3 are auto generated */
|
|
loadspriteimage(P_WSPIDER,F_CLIMB1, "sprites/whitespiderclimb.png");
|
|
loadspriteimage(P_WSPIDER,F_CLIMB2, "sprites/whitespiderclimb1.png");
|
|
imageset[P_WSPIDER].numimages = 10;
|
|
|
|
loadspriteimage(P_MOTH,F_WALK1, "sprites/moth.png");
|
|
loadspriteimage(P_MOTH,F_JUMP, "sprites/moth1.png");
|
|
loadspriteimage(P_MOTH,F_FALL, "sprites/moth1.png");
|
|
loadspriteimage(P_MOTH,F_CAUGHT, "sprites/mothcaught.png");
|
|
loadspriteimage(P_MOTH,F_DEAD, "sprites/mothdead.png");
|
|
/* next 3 are auto generated */
|
|
imageset[P_MOTH].numimages = 8;
|
|
|
|
|
|
loadspriteimage(P_SPIDER,F_WALK1, "sprites/newspider.png");
|
|
loadspriteimage(P_SPIDER,F_JUMP, "sprites/newspiderjump.png");
|
|
loadspriteimage(P_SPIDER,F_FALL, "sprites/newspiderfall.png");
|
|
loadspriteimage(P_SPIDER,F_CAUGHT, "sprites/newspidercaught.png");
|
|
loadspriteimage(P_SPIDER,F_DEAD, "sprites/newspiderdead.png");
|
|
/* next 3 are auto generated */
|
|
imageset[P_SPIDER].numimages = 8;
|
|
|
|
loadspriteimage(P_FISH,F_WALK1, "sprites/fish.png");
|
|
loadspriteimage(P_FISH,F_JUMP, "sprites/fishjump.png");
|
|
loadspriteimage(P_FISH,F_FALL, "sprites/fishjump.png");
|
|
loadspriteimage(P_FISH,F_CAUGHT, "sprites/fishcaught.png");
|
|
loadspriteimage(P_FISH,F_DEAD, "sprites/fishdead.png");
|
|
/* next 3 are auto generated */
|
|
imageset[P_FISH].numimages = 8;
|
|
|
|
|
|
loadspriteimage(P_BLACKCLOUD,F_WALK1, "sprites/blackcloud.png");
|
|
imageset[P_BLACKCLOUD].numimages = 1;
|
|
|
|
loadspriteimage(P_PINKCLOUD,F_WALK1, "sprites/pinkcloud.png");
|
|
imageset[P_PINKCLOUD].numimages = 1;
|
|
|
|
|
|
loadspriteimage(P_TICK,F_WALK1, "sprites/tick.png");
|
|
loadspriteimage(P_TICK,F_JUMP, "sprites/tickjump.png");
|
|
loadspriteimage(P_TICK,F_FALL, "sprites/tickjump.png");
|
|
loadspriteimage(P_TICK,F_CAUGHT, "sprites/tickcaught.png");
|
|
loadspriteimage(P_TICK,F_DEAD, "sprites/tickdead.png");
|
|
imageset[P_TICK].numimages = 8;
|
|
|
|
loadspriteimage(P_PLANT,F_WALK1, "sprites/plant.png");
|
|
loadspriteimage(P_PLANT,F_JUMP, "sprites/plantjump.png");
|
|
loadspriteimage(P_PLANT,F_FALL, "sprites/plantjump.png");
|
|
loadspriteimage(P_PLANT,F_CAUGHT, "sprites/plant.png");
|
|
loadspriteimage(P_PLANT,F_DEAD, "sprites/plantdead.png");
|
|
imageset[P_PLANT].numimages = 8;
|
|
|
|
loadspriteimage(P_KINGRAT,F_WALK1, "sprites/kingrat.png");
|
|
loadspriteimage(P_KINGRAT,F_JUMP, "sprites/kingratjump.png");
|
|
loadspriteimage(P_KINGRAT,F_FALL, "sprites/kingratjump.png");
|
|
loadspriteimage(P_KINGRAT,F_CAUGHT, "sprites/kingratcaught.png");
|
|
loadspriteimage(P_KINGRAT,F_DEAD, "sprites/kingratdead.png");
|
|
/* next 3 are auto generated */
|
|
imageset[P_KINGRAT].numimages = 8;
|
|
|
|
loadspriteimage(P_KINGSNAIL,F_WALK1, "sprites/kingsnail.png");
|
|
loadspriteimage(P_KINGSNAIL,F_JUMP, "sprites/kingsnailjump.png");
|
|
loadspriteimage(P_KINGSNAIL,F_FALL, "sprites/kingsnailjump.png");
|
|
loadspriteimage(P_KINGSNAIL,F_CAUGHT, "sprites/kingsnail_broken.png");
|
|
loadspriteimage(P_KINGSNAIL,F_DEAD, "sprites/kingsnaildead.png");
|
|
/* next 3 are auto genesnailed */
|
|
imageset[P_KINGSNAIL].numimages = 8;
|
|
|
|
loadspriteimage(P_KINGFLY,F_WALK1, "sprites/kingfly.png");
|
|
loadspriteimage(P_KINGFLY,F_JUMP, "sprites/kingflyjump.png");
|
|
loadspriteimage(P_KINGFLY,F_FALL, "sprites/kingflyjump.png");
|
|
loadspriteimage(P_KINGFLY,F_CAUGHT, "sprites/kingfly.png");
|
|
loadspriteimage(P_KINGFLY,F_DEAD, "sprites/kingflydead.png");
|
|
/* next 3 are auto geneflyed */
|
|
imageset[P_KINGFLY].numimages = 8;
|
|
|
|
|
|
loadspriteimage(P_KINGANT,F_WALK1, "sprites/kingant.png");
|
|
loadspriteimage(P_KINGANT,F_JUMP, "sprites/kingantjump.png");
|
|
loadspriteimage(P_KINGANT,F_FALL, "sprites/kingantjump.png");
|
|
loadspriteimage(P_KINGANT,F_CAUGHT, "sprites/kingant.png");
|
|
loadspriteimage(P_KINGANT,F_DEAD, "sprites/kingantdead.png");
|
|
/* next 3 are auto generated */
|
|
imageset[P_KINGANT].numimages = 8;
|
|
|
|
loadspriteimage(P_KSSHELL,F_WALK1, "sprites/kingsnail_shell.png");
|
|
imageset[P_KSSHELL].numimages = 1;
|
|
// manually do flipped one
|
|
imageset[P_KSSHELL].img[MAXFRAMES] = rotozoomSurfaceXY(imageset[P_KSSHELL].img[0], 0, -1,1,0);
|
|
|
|
|
|
loadspriteimage(P_SNAIL,F_WALK1, "sprites/snail.png");
|
|
loadspriteimage(P_SNAIL,F_JUMP, "sprites/snailwalk2.png");
|
|
loadspriteimage(P_SNAIL,F_FALL, "sprites/snailwalk2.png");
|
|
loadspriteimage(P_SNAIL,F_CAUGHT, "sprites/snailcaught.png");
|
|
loadspriteimage(P_SNAIL,F_DEAD, "sprites/snaildead.png");
|
|
/* next 3 are auto generated */
|
|
imageset[P_SNAIL].numimages = 8;
|
|
|
|
loadspriteimage(P_SLUG,F_WALK1, "sprites/slug.png");
|
|
loadspriteimage(P_SLUG,F_JUMP, "sprites/slugwalk.png");
|
|
loadspriteimage(P_SLUG,F_FALL, "sprites/slugjump.png");
|
|
loadspriteimage(P_SLUG,F_CAUGHT, "sprites/slugcaught.png");
|
|
loadspriteimage(P_SLUG,F_DEAD, "sprites/slugdead.png");
|
|
/* next 3 are auto generated */
|
|
imageset[P_SLUG].numimages = 8;
|
|
|
|
/* fruits / powerups */
|
|
loadspriteimage(P_CHEESE,F_WALK1, "sprites/cheese.png");
|
|
imageset[P_CHEESE].numimages = 1;
|
|
|
|
loadspriteimage(P_ICECREAM,F_WALK1, "sprites/icecream.png");
|
|
imageset[P_ICECREAM].numimages = 1;
|
|
|
|
loadspriteimage(P_CHIPS,F_WALK1, "sprites/chips.png");
|
|
imageset[P_CHIPS].numimages = 1;
|
|
|
|
loadspriteimage(P_BURGER,F_WALK1, "sprites/burger.png");
|
|
imageset[P_BURGER].numimages = 1;
|
|
|
|
loadspriteimage(P_SPEED,F_WALK1, "sprites/speed.png");
|
|
imageset[P_SPEED].numimages = 1;
|
|
|
|
loadspriteimage(P_PIZZA,F_WALK1, "sprites/pizza.png");
|
|
imageset[P_PIZZA].numimages = 1;
|
|
|
|
loadspriteimage(P_SUNDAE,F_WALK1, "sprites/sundae.png");
|
|
imageset[P_SUNDAE].numimages = 1;
|
|
|
|
loadspriteimage(P_CAKE,F_WALK1, "sprites/cake.png");
|
|
imageset[P_CAKE].numimages = 1;
|
|
|
|
loadspriteimage(P_CHOCOLATE,F_WALK1, "sprites/chocolate.png");
|
|
imageset[P_CHOCOLATE].numimages = 1;
|
|
|
|
// we never use it, but load an image for P_RANDOM
|
|
// just in case... otehrwise we'll get crashes due to
|
|
// NULL images.
|
|
loadspriteimage(P_RANDOM,F_WALK1, "sprites/random.png");
|
|
imageset[P_RANDOM].numimages = 1;
|
|
|
|
loadspriteimage(P_NUMNETS,F_WALK1, "sprites/numnets.png");
|
|
imageset[P_NUMNETS].numimages = 1;
|
|
|
|
loadspriteimage(P_BIGNET,F_WALK1, "sprites/bignet.png");
|
|
imageset[P_BIGNET].numimages = 1;
|
|
|
|
loadspriteimage(P_GEMBOOST,F_WALK1, "sprites/gemboost.png");
|
|
imageset[P_GEMBOOST].numimages = 1;
|
|
|
|
loadspriteimage(P_MASK,0, "sprites/mask.png");
|
|
loadspriteimage(P_MASK,1, "sprites/maskleft.png");
|
|
imageset[P_MASK].numimages = 2;
|
|
|
|
|
|
loadspriteimage(P_MASKPOWERUP,F_WALK1, "sprites/maskpowerup.png");
|
|
imageset[P_MASKPOWERUP].numimages = 1;
|
|
|
|
|
|
loadspriteimage(P_HELP,F_WALK1, "sprites/help.png");
|
|
imageset[P_HELP].numimages = 1;
|
|
|
|
loadspriteimage(P_HELMET,F_WALK1, "sprites/helmet.png");
|
|
imageset[P_HELMET].numimages = 1;
|
|
|
|
loadspriteimage(P_FLOWERYELLOW,F_WALK1, "sprites/flower-yellow.png");
|
|
imageset[P_FLOWERRED].numimages = 1;
|
|
|
|
loadspriteimage(P_FLOWERRED,F_WALK1, "sprites/flower-red.png");
|
|
imageset[P_FLOWERRED].numimages = 1;
|
|
|
|
|
|
loadspriteimage(P_FLOWERPURPLE,F_WALK1, "sprites/flower-purple.png");
|
|
imageset[P_FLOWERPURPLE].numimages = 1;
|
|
|
|
loadspriteimage(P_GEMYELLOW,F_WALK1, "sprites/gem-yellow.png");
|
|
imageset[P_GEMYELLOW].numimages = 1;
|
|
|
|
loadspriteimage(P_GEMRED,F_WALK1, "sprites/gem-red.png");
|
|
imageset[P_GEMRED].numimages = 1;
|
|
|
|
loadspriteimage(P_GEMPURPLE,F_WALK1, "sprites/gem-purple.png");
|
|
imageset[P_GEMPURPLE].numimages = 1;
|
|
|
|
loadspriteimage(P_POWERUPPOS,F_WALK1, "sprites/poweruppos.png");
|
|
imageset[P_POWERUPPOS].numimages = 1;
|
|
|
|
loadspriteimage(P_BOXING,F_WALK1, "sprites/boxing.png");
|
|
imageset[P_BOXING].numimages = 1;
|
|
|
|
loadspriteimage(P_GLOVE,F_WALK1, "sprites/glove.png");
|
|
imageset[P_GLOVE].numimages = 1;
|
|
// manually do flipped images
|
|
imageset[P_GLOVE].img[MAXFRAMES] = rotozoomSurfaceXY(imageset[P_GLOVE].img[0], 0, -1,1,0);
|
|
|
|
loadspriteimage(P_DIAMOND,F_WALK1, "sprites/diamond.png");
|
|
imageset[P_DIAMOND].numimages = 1;
|
|
|
|
loadspriteimage(P_FTODIAMOND,F_WALK1, "sprites/flowertodiamond.png");
|
|
imageset[P_FTODIAMOND].numimages = 1;
|
|
|
|
loadspriteimage(P_FTOGEM,F_WALK1, "sprites/flowertogem.png");
|
|
imageset[P_FTOGEM].numimages = 1;
|
|
|
|
loadspriteimage(P_BOMB,F_WALK1, "sprites/bomb.png");
|
|
imageset[P_BOMB].numimages = 1;
|
|
|
|
loadspriteimage(P_STARPOWERUP,F_WALK1, "sprites/star.png");
|
|
imageset[P_STARPOWERUP].numimages = 1;
|
|
|
|
// Don't load image for P_MOVINGCARD or P_FIVECARDS
|
|
|
|
|
|
for (i = 0; i < STARFRAMES; i++) {
|
|
char name[SMALLBUFLEN];
|
|
sprintf(name, "sprites/star%d.png",i);
|
|
loadspriteimage(P_STAR,i, name);
|
|
}
|
|
imageset[P_STAR].numimages = STARFRAMES;
|
|
|
|
loadspriteimage(P_UFO,F_WALK1, "sprites/ufo.png");
|
|
imageset[P_UFO].numimages = 1;
|
|
|
|
loadspriteimage(P_METEOR,F_WALK1, "sprites/meteor.png");
|
|
imageset[P_METEOR].numimages = 1;
|
|
|
|
loadspriteimage(P_LIFE,F_WALK1, "sprites/extralife.png");
|
|
imageset[P_LIFE].numimages = 1;
|
|
|
|
loadspriteimage(P_PHONE,F_WALK1, "sprites/phone.png");
|
|
imageset[P_PHONE].numimages = 1;
|
|
|
|
loadspriteimage(P_HONEY,F_WALK1, "sprites/honey.png");
|
|
imageset[P_HONEY].numimages = 1;
|
|
|
|
loadspriteimage(P_SHIELD,F_WALK1, "sprites/shield.png");
|
|
imageset[P_SHIELD].numimages = 1;
|
|
|
|
loadspriteimage(P_MACEPOWERUP,F_WALK1, "sprites/macepowerup.png");
|
|
imageset[P_MACEPOWERUP].numimages = 1;
|
|
|
|
loadspriteimage(P_MACE,F_WALK1, "sprites/mace.png");
|
|
imageset[P_MACE].numimages = 1;
|
|
|
|
loadspriteimage(P_TROPHY,F_WALK1, "sprites/trophy.png");
|
|
imageset[P_TROPHY].numimages = 1;
|
|
|
|
loadspriteimage(P_RINGSILVER,F_WALK1, "sprites/ring-silver.png");
|
|
imageset[P_RINGSILVER].numimages = 1;
|
|
|
|
loadspriteimage(P_RINGGOLD,F_WALK1, "sprites/ring-gold.png");
|
|
imageset[P_RINGGOLD].numimages = 1;
|
|
|
|
loadspriteimage(P_BELL,F_WALK1, "sprites/bell.png");
|
|
imageset[P_BELL].numimages = 1;
|
|
|
|
loadspriteimage(P_CLOCK,F_WALK1, "sprites/clock.png");
|
|
imageset[P_CLOCK].numimages = 1;
|
|
|
|
loadspriteimage(P_SNOWMAN,F_WALK1, "sprites/snowman.png");
|
|
imageset[P_SNOWMAN].numimages = 1;
|
|
|
|
loadspriteimage(P_TAP,F_WALK1, "sprites/tap.png");
|
|
imageset[P_TAP].numimages = 1;
|
|
|
|
loadspriteimage(P_SPRAY,F_WALK1, "sprites/spray.png");
|
|
imageset[P_SPRAY].numimages = 1;
|
|
|
|
loadspriteimage(P_CANNONPOWERUP,F_WALK1, "sprites/cannonpowerup.png");
|
|
imageset[P_CANNONPOWERUP].numimages = 1;
|
|
|
|
loadspriteimage(P_CANNON,F_WALK1, "sprites/cannon.png");
|
|
imageset[P_CANNON].numimages = 1;
|
|
|
|
loadspriteimage(P_CLOVER,F_WALK1, "sprites/clover.png");
|
|
imageset[P_CLOVER].numimages = 1;
|
|
|
|
loadspriteimage(P_ACCORDION,F_WALK1, "sprites/accordion.png");
|
|
imageset[P_ACCORDION].numimages = 1;
|
|
|
|
loadspriteimage(P_WINGBOOTS,F_WALK1, "sprites/wingboots.png");
|
|
imageset[P_WINGBOOTS].numimages = 1;
|
|
|
|
loadspriteimage(P_PILL,F_WALK1, "sprites/pill.png");
|
|
imageset[P_PILL].numimages = 1;
|
|
|
|
loadspriteimage(P_RAYGUN,F_WALK1, "sprites/raygun.png");
|
|
imageset[P_RAYGUN].numimages = 1;
|
|
|
|
loadspriteimage(P_TOPHAT,F_WALK1, "sprites/tophat.png");
|
|
imageset[P_TOPHAT].numimages = 1;
|
|
|
|
loadspriteimage(P_LAMP,F_WALK1, "sprites/lamp.png");
|
|
imageset[P_LAMP].numimages = 1;
|
|
|
|
loadspriteimage(P_GOLDCOIN,F_WALK1, "sprites/goldcoin.png");
|
|
imageset[P_GOLDCOIN].numimages = 1;
|
|
|
|
loadspriteimage(P_GOLDBAR,F_WALK1, "sprites/goldbar.png");
|
|
imageset[P_GOLDBAR].numimages = 1;
|
|
|
|
loadspriteimage(P_GUN,F_WALK1, "sprites/gunner.png");
|
|
imageset[P_GUN].numimages = 1;
|
|
|
|
loadspriteimage(P_GNOME,F_WALK1, "sprites/gnome.png");
|
|
imageset[P_GNOME].numimages = 1;
|
|
|
|
loadspriteimage(P_WAND,F_WALK1, "sprites/wand.png");
|
|
imageset[P_WAND].numimages = 1;
|
|
|
|
loadspriteimage(P_CANDLE,F_WALK1, "sprites/candle.png");
|
|
imageset[P_CANDLE].numimages = 1;
|
|
|
|
loadspriteimage(P_WHISTLE,F_WALK1, "sprites/whistle.png");
|
|
imageset[P_WHISTLE].numimages = 1;
|
|
|
|
loadspriteimage(P_ANCHOR,F_WALK1, "sprites/anchor.png");
|
|
imageset[P_ANCHOR].numimages = 1;
|
|
|
|
|
|
loadspriteimage(P_SMALLANCHOR,F_WALK1, "sprites/smallanchor.png");
|
|
imageset[P_SMALLANCHOR].numimages = 1;
|
|
|
|
loadspriteimage(P_MAGNET,F_WALK1, "sprites/magnet.png");
|
|
imageset[P_MAGNET].numimages = 1;
|
|
|
|
loadspriteimage(P_BADMAGNET,F_WALK1, "sprites/badmagnet.png");
|
|
imageset[P_BADMAGNET].numimages = 1;
|
|
|
|
loadspriteimage(P_JETPACK,F_WALK1, "sprites/jetpack.png");
|
|
imageset[P_JETPACK].numimages = 1;
|
|
|
|
loadspriteimage(P_UMBRELLA,F_WALK1, "sprites/umbrella.png");
|
|
imageset[P_UMBRELLA].numimages = 1;
|
|
|
|
loadspriteimage(P_EGG,F_WALK1, "sprites/egg.png");
|
|
imageset[P_EGG].numimages = 1;
|
|
|
|
loadspriteimage(P_BIGUMBRELLA,F_WALK1, "sprites/bigumbrella.png");
|
|
imageset[P_BIGUMBRELLA].numimages = 1;
|
|
|
|
loadspriteimage(P_SUPERUMBRELLA,F_WALK1, "sprites/superumbrella.png");
|
|
imageset[P_SUPERUMBRELLA].numimages = 1;
|
|
|
|
loadspriteimage(P_CAMERA,F_WALK1, "sprites/camera.png");
|
|
imageset[P_CAMERA].numimages = 1;
|
|
|
|
loadspriteimage(P_ZAPPOWERUP,F_WALK1, "sprites/zapper.png");
|
|
imageset[P_ZAPPOWERUP].numimages = 1;
|
|
|
|
// moving platforms
|
|
loadspriteimage(P_PLATFORM,F_WALK1, "sprites/platform.png");
|
|
imageset[P_PLATFORM].numimages = 1;
|
|
|
|
|
|
loadspriteimage(P_ZAPPER,0, "sprites/zap1.png");
|
|
loadspriteimage(P_ZAPPER,1, "sprites/zap2.png");
|
|
loadspriteimage(P_ZAPPER,2, "sprites/zap3.png");
|
|
loadspriteimage(P_ZAPPER,3, "sprites/zap2.png");
|
|
loadspriteimage(P_ZAPPER,4, "sprites/zap1.png");
|
|
imageset[P_ZAPPER].numimages = 5;
|
|
|
|
// wings
|
|
loadspriteimage(P_WINGLEFT,0, "sprites/wingleft0.png"); // standing
|
|
loadspriteimage(P_WINGLEFT,1, "sprites/wingleft1.png"); // jumping
|
|
loadspriteimage(P_WINGLEFT,2, "sprites/wingleft2.png"); // jumping
|
|
loadspriteimage(P_WINGLEFT,3, "sprites/wingleft3.png"); // swimming
|
|
imageset[P_WINGLEFT].numimages = 4;
|
|
|
|
loadspriteimage(P_WINGRIGHT,0, "sprites/wingright0.png"); // standing
|
|
loadspriteimage(P_WINGRIGHT,1, "sprites/wingright1.png"); // jumping
|
|
loadspriteimage(P_WINGRIGHT,2, "sprites/wingright2.png"); // jumping
|
|
imageset[P_WINGRIGHT].numimages = 3;
|
|
|
|
// manually do flipped images
|
|
for (i = 0; i < 3; i++) {
|
|
imageset[P_WINGLEFT].img[MAXFRAMES+i] = rotozoomSurfaceXY(imageset[P_WINGLEFT].img[i], 0, -1,1,0);
|
|
imageset[P_WINGRIGHT].img[MAXFRAMES+i] = rotozoomSurfaceXY(imageset[P_WINGRIGHT].img[i], 0, -1,1,0);
|
|
}
|
|
// and one more for WINGLEFT...
|
|
imageset[P_WINGLEFT].img[MAXFRAMES+3] = rotozoomSurfaceXY(imageset[P_WINGLEFT].img[3], 0, -1,1,0);
|
|
|
|
loadspriteimage(P_SKULL,F_WALK1, "sprites/skull.png");
|
|
imageset[P_SKULL].numimages = 1;
|
|
|
|
loadspriteimage(P_BIGSPEED,F_WALK1, "sprites/bigspeed.png");
|
|
imageset[P_BIGSPEED].numimages = 1;
|
|
|
|
loadspriteimage(P_BIGSCUBA,F_WALK1, "sprites/bigscuba.png");
|
|
imageset[P_BIGSCUBA].numimages = 1;
|
|
|
|
loadspriteimage(P_BIGHELMET,F_WALK1, "sprites/bighelmet.png");
|
|
imageset[P_BIGHELMET].numimages = 1;
|
|
|
|
// puffs and mace smashes
|
|
for (i = 0; i < PUFFFRAMES; i++) {
|
|
char name[SMALLBUFLEN];
|
|
sprintf(name, "sprites/puff%d.png",i);
|
|
loadspriteimage(P_PUFF,i, name);
|
|
}
|
|
imageset[P_PUFF].numimages = PUFFFRAMES;
|
|
|
|
for (i = 0; i < EXPFRAMES; i++) {
|
|
char name[SMALLBUFLEN];
|
|
sprintf(name, "sprites/exp%d.png",i);
|
|
loadspriteimage(P_SMASH,i, name);
|
|
}
|
|
|
|
imageset[P_SMASH].numimages = EXPFRAMES;
|
|
|
|
for (i = 0; i < EXPFRAMES; i++) {
|
|
char name[SMALLBUFLEN];
|
|
sprintf(name, "sprites/exp%d.png",i);
|
|
loadspriteimage(P_FLAME,i, name);
|
|
}
|
|
|
|
imageset[P_FLAME].numimages = EXPFRAMES;
|
|
|
|
// playing card bonuses
|
|
//loadspriteimage(P_CARDHK,F_WALK1, "sprites/cardhk.png");
|
|
|
|
// load card font
|
|
sprintf(tempfile, "%s/cardfont.ttf", datadir);
|
|
cardfont = TTF_OpenFont(tempfile, CARDFONTSIZE);
|
|
if (!cardfont) {
|
|
printf("Error opening font '%s': %s\n", tempfile, TTF_GetError());
|
|
exit(1);
|
|
}
|
|
|
|
for (i = 1; i <= 13; i++) {
|
|
SDL_Surface *letter;
|
|
SDL_Rect area;
|
|
char str[2];
|
|
|
|
// HEARTS
|
|
loadspriteimage(P_FIRSTHEART+i-1, F_WALK1, "sprites/cardh.png");
|
|
sprintf(str, "%s",getcardletter(i));
|
|
letter = TTF_RenderText_Blended(cardfont, str, red );
|
|
area.x = CARDFONTX; area.y = CARDFONTY; area.w = 0; area.h = 0;
|
|
if (i == 10) area.x -= 3;
|
|
SDL_BlitSurface(letter, NULL, imageset[P_FIRSTHEART + i-1].img[F_WALK1], &area);
|
|
imageset[P_FIRSTHEART + i-1].numimages = 1;
|
|
SDL_FreeSurface(letter);
|
|
// DIAMONDS
|
|
loadspriteimage(P_FIRSTDIAMOND+i-1, F_WALK1, "sprites/cardd.png");
|
|
sprintf(str, "%s",getcardletter(i));
|
|
letter = TTF_RenderText_Blended(cardfont, str, red );
|
|
area.x = CARDFONTX; area.y = CARDFONTY; area.w = 0; area.h = 0;
|
|
if (i == 10) area.x -= 3;
|
|
SDL_BlitSurface(letter, NULL, imageset[P_FIRSTDIAMOND + i-1].img[F_WALK1], &area);
|
|
imageset[P_FIRSTDIAMOND + i-1].numimages = 1;
|
|
SDL_FreeSurface(letter);
|
|
// SPADES
|
|
loadspriteimage(P_FIRSTSPADE+i-1, F_WALK1, "sprites/cards.png");
|
|
sprintf(str, "%s",getcardletter(i));
|
|
letter = TTF_RenderText_Blended(cardfont, str, black );
|
|
area.x = CARDFONTX; area.y = CARDFONTY; area.w = 0; area.h = 0;
|
|
if (i == 10) area.x -= 3;
|
|
SDL_BlitSurface(letter, NULL, imageset[P_FIRSTSPADE + i-1].img[F_WALK1], &area);
|
|
imageset[P_FIRSTSPADE + i-1].numimages = 1;
|
|
SDL_FreeSurface(letter);
|
|
// CLUBS
|
|
loadspriteimage(P_FIRSTCLUB+i-1, F_WALK1, "sprites/cardc.png");
|
|
sprintf(str, "%s",getcardletter(i));
|
|
letter = TTF_RenderText_Blended(cardfont, str, black );
|
|
area.x = CARDFONTX; area.y = CARDFONTY; area.w = 0; area.h = 0;
|
|
if (i == 10) area.x -= 3;
|
|
SDL_BlitSurface(letter, NULL, imageset[P_FIRSTCLUB + i-1].img[F_WALK1], &area);
|
|
imageset[P_FIRSTCLUB + i-1].numimages = 1;
|
|
SDL_FreeSurface(letter);
|
|
}
|
|
|
|
|
|
// sparkles
|
|
for (i = 0; i < SPARKLEFRAMES; i++) {
|
|
char name[SMALLBUFLEN];
|
|
sprintf(name, "sprites/sparkle%d.png",i);
|
|
loadspriteimage(P_SPARKLE,i, name);
|
|
}
|
|
imageset[P_SPARKLE].numimages = SPARKLEFRAMES;
|
|
|
|
loadspriteimage(P_BUBBLE,F_WALK1, "sprites/bubble.png");
|
|
imageset[P_BUBBLE].numimages = 1;
|
|
|
|
|
|
/* ray gun bullet */
|
|
loadspriteimage(P_RAYGUNBULLET,F_WALK1, "sprites/raygunbullet.png");
|
|
imageset[P_RAYGUNBULLET].numimages = 1;
|
|
|
|
/* bullets */
|
|
loadspriteimage(P_SPIT,0, "sprites/spit.png");
|
|
loadspriteimage(P_SPIT,1, "sprites/spit2.png");
|
|
imageset[P_SPIT].numimages = 2;
|
|
|
|
loadspriteimage(P_FIREBALL,0, "sprites/fire1.png");
|
|
loadspriteimage(P_FIREBALL,1, "sprites/fire2.png");
|
|
imageset[P_FIREBALL].numimages = 2;
|
|
|
|
loadspriteimage(P_BIGFIREBALL,0, "sprites/bigfire1.png");
|
|
loadspriteimage(P_BIGFIREBALL,1, "sprites/bigfire2.png");
|
|
imageset[P_BIGFIREBALL].numimages = 2;
|
|
|
|
loadspriteimage(P_MOTHFIRE,0, "sprites/mothfire0.png");
|
|
loadspriteimage(P_MOTHFIRE,1, "sprites/mothfire1.png");
|
|
loadspriteimage(P_MOTHFIRE,2, "sprites/mothfire2.png");
|
|
loadspriteimage(P_MOTHFIRE,3, "sprites/mothfire3.png");
|
|
loadspriteimage(P_MOTHFIRE,4, "sprites/mothfire4.png");
|
|
loadspriteimage(P_MOTHFIRE,5, "sprites/mothfire5.png");
|
|
loadspriteimage(P_MOTHFIRE,6, "sprites/mothfire4.png");
|
|
loadspriteimage(P_MOTHFIRE,7, "sprites/mothfire3.png");
|
|
loadspriteimage(P_MOTHFIRE,8, "sprites/mothfire2.png");
|
|
loadspriteimage(P_MOTHFIRE,9, "sprites/mothfire1.png");
|
|
imageset[P_MOTHFIRE].numimages = 10;
|
|
|
|
|
|
// manual angry image for black cloud
|
|
|
|
origi = imageset[P_BLACKCLOUD].img[0];
|
|
|
|
reds = SDL_CreateRGBSurface(SDL_SWSURFACE,
|
|
origi->w,
|
|
origi->h,
|
|
origi->format->BitsPerPixel, origi->format->Rmask,
|
|
origi->format->Gmask,origi->format->Bmask, 0);
|
|
SDL_FillRect(reds, NULL, SDL_MapRGB(reds->format, 255, 0, 0));
|
|
SDL_SetAlpha(reds, SDL_SRCALPHA,100);
|
|
|
|
// take a copy of the original image
|
|
imageset[P_BLACKCLOUD].img[MAXFRAMES*2] = rotozoomSurfaceXY(origi, 0, 1,1,0);
|
|
|
|
|
|
// paste the transparent one on top of it
|
|
SDL_BlitSurface(reds, NULL, imageset[P_BLACKCLOUD].img[MAXFRAMES*2], NULL);
|
|
SDL_FreeSurface(reds);
|
|
|
|
// Convert the reddened image to the screen format
|
|
tempsurf = SDL_DisplayFormat(imageset[P_BLACKCLOUD].img[MAXFRAMES*2]);
|
|
SDL_FreeSurface(imageset[P_BLACKCLOUD].img[MAXFRAMES*2]);
|
|
imageset[P_BLACKCLOUD].img[MAXFRAMES*2] = tempsurf;
|
|
|
|
// Make the background red bits completely transparent
|
|
SDL_SetColorKey(imageset[P_BLACKCLOUD].img[MAXFRAMES*2],
|
|
SDL_SRCCOLORKEY, SDL_MapRGB(imageset[P_BLACKCLOUD].img[MAXFRAMES*2]->format, 99, 0, 0));
|
|
|
|
|
|
/* generate rotated/flipped images */
|
|
for (p = 0; p < MAXPTYPES; p++) {
|
|
int fr;
|
|
int angle = 90;
|
|
/* rotated death images */
|
|
if (!isfruit(p) && !isbullet(p) && !iseffect(p) && p != P_BLACKCLOUD) {
|
|
for (fr = F_DEAD2; fr <= F_DEAD4; fr++) {
|
|
if (!imageset[p].img[fr]) {
|
|
tempimg = rotozoomSurface(imageset[p].img[F_DEAD],angle,1,0);
|
|
if (tempimg == NULL) {
|
|
printf("error rotozooming sprite %d, deadimage %d\n",p,fr);
|
|
exit(1);
|
|
}
|
|
SDL_SetColorKey(tempimg, SDL_SRCCOLORKEY|SDL_RLEACCEL, SDL_MapRGB(screen->format, 0, 0, 0));
|
|
imageset[p].img[fr] = SDL_DisplayFormat(tempimg);
|
|
SDL_FreeSurface(tempimg);
|
|
}
|
|
angle += 90;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < imageset[p].numimages; i++) {
|
|
if (!isfruit(p) && !iseffect(p) && p != P_BLACKCLOUD) {
|
|
SDL_Color tempcol;
|
|
int x,y;
|
|
SDL_Rect redarea,temparea;
|
|
|
|
/*
|
|
SDL_SetColorKey(imageset[p].img[i],
|
|
SDL_SRCCOLORKEY, SDL_MapRGB(screen->format, 0, 0, 0));
|
|
*/
|
|
|
|
origi = imageset[p].img[i];
|
|
|
|
|
|
/* flipped image */
|
|
imageset[p].img[MAXFRAMES+i] =
|
|
rotozoomSurfaceXY(imageset[p].img[i], 0, -1,1,0);
|
|
SDL_SetColorKey(imageset[p].img[MAXFRAMES+i],
|
|
SDL_SRCCOLORKEY|SDL_RLEACCEL, SDL_MapRGB(screen->format, 0, 0, 0));
|
|
|
|
|
|
|
|
/* angry image */
|
|
|
|
// create semi-transparent red square (white for bosses)
|
|
if (isboss(p)) {
|
|
reds = SDL_CreateRGBSurface(SDL_SWSURFACE,2,2,
|
|
origi->format->BitsPerPixel, origi->format->Rmask,
|
|
origi->format->Gmask,origi->format->Bmask, 0);
|
|
SDL_FillRect(reds, NULL, SDL_MapRGB(reds->format, 255, 255, 255));
|
|
SDL_SetAlpha(reds, SDL_SRCALPHA,100);
|
|
} else {
|
|
reds = SDL_CreateRGBSurface(SDL_SWSURFACE,2,2,
|
|
origi->format->BitsPerPixel, origi->format->Rmask,
|
|
origi->format->Gmask,origi->format->Bmask, 0);
|
|
SDL_FillRect(reds, NULL, SDL_MapRGB(reds->format, 255, 0, 0));
|
|
SDL_SetAlpha(reds, SDL_SRCALPHA,100);
|
|
}
|
|
|
|
// take a copy of the original image
|
|
tempsurf = rotozoomSurfaceXY(origi, 0, 1,1,0);
|
|
redarea.x = 0; redarea.y = 0;
|
|
redarea.w = 1; redarea.h = 1;
|
|
temparea.w = 1; temparea.h = 1;
|
|
|
|
for (y = 0; y < tempsurf->h; y++) {
|
|
for (x = 0; x < tempsurf->w; x++) {
|
|
|
|
getpixelrgb(tempsurf , x, y, &tempcol);
|
|
// if pixel isn't transparent...
|
|
if (tempcol.unused > 0 ) {
|
|
temparea.x = x;
|
|
temparea.y = y;
|
|
// make this pixel redder
|
|
SDL_BlitSurface(reds, &redarea, tempsurf, &temparea);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
imageset[p].img[MAXFRAMES*2+i] = tempsurf;
|
|
|
|
// free red image surface
|
|
SDL_FreeSurface(reds);
|
|
|
|
/* flipped angry image */
|
|
imageset[p].img[MAXFRAMES*3+i] = rotozoomSurfaceXY(imageset[p].img[MAXFRAMES*2+i], 0, -1,1,0);
|
|
SDL_SetColorKey(imageset[p].img[MAXFRAMES*3+i],SDL_RLEACCEL, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
return B_FALSE;
|
|
}
|
|
|
|
|
|
void drawsprite(sprite_t *s) {
|
|
SDL_Rect area;
|
|
int frame = 0;
|
|
|
|
#ifndef __EDITOR
|
|
if (isplayer(s) && s->lives < 0) {
|
|
// permenantly dead - don't draw
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
// don't show caught mosnters in gunner mode
|
|
if (!isplayer(s) && (s->caughtby) ) {
|
|
if ((player) && (player->powerup == PW_GUNNER)) {
|
|
return;
|
|
}
|
|
if ((player2) && (player2->powerup == PW_GUNNER)) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (isplayer(s) && (levelcomplete == LV_NEXTLEV)) {
|
|
frame = F_SHOOT;
|
|
if (curlevel->exitdir == D_RIGHT) {
|
|
s->dir = 1;
|
|
} else if (curlevel->exitdir == D_LEFT) {
|
|
s->dir = -1;
|
|
}
|
|
} else {
|
|
/* select frame */
|
|
if (isfruit(s->id)) {
|
|
frame = F_WALK1;
|
|
} else if (isbullet(s->id)) {
|
|
if (s->id == P_MOTHFIRE) {
|
|
frame = s->timer1;
|
|
} else {
|
|
if ((timer/6) % 2 == 0) {
|
|
frame = F_WALK1;
|
|
} else {
|
|
frame = F_JUMP;
|
|
}
|
|
}
|
|
} else if (iseffect(s->id)) {
|
|
if ((s->id == P_PUFF) || (s->id == P_SMASH) || (s->id == P_SPARKLE) || (s->id == P_FLAME) ) {
|
|
if (s->timer1 >= imageset[s->id].numimages) {
|
|
frame = imageset[s->id].numimages - 1;
|
|
} else if (s->timer1 < 0) {
|
|
// don't draw
|
|
return;
|
|
} else {
|
|
frame = s->timer1;
|
|
}
|
|
} else if (s->id == P_GLOVE) {
|
|
frame = F_WALK1;
|
|
} else if (s->id == P_KSSHELL) {
|
|
frame = F_WALK1;
|
|
} else if (s->id == P_MACE) {
|
|
frame = F_WALK1;
|
|
} else if (s->id == P_CANNON) {
|
|
frame = F_WALK1;
|
|
} else if (s->id == P_ZAPPER) {
|
|
if (s->timer1 >= imageset[s->id].numimages) {
|
|
// just in case
|
|
frame = 0;
|
|
} else {
|
|
frame = s->timer1;
|
|
}
|
|
} else if (s->id == P_BUBBLE) {
|
|
frame = F_WALK1;
|
|
} else if (s->id == P_METEOR) {
|
|
frame = F_WALK1;
|
|
} else if (s->id == P_STAR) {
|
|
frame = s->timer1;
|
|
} else if (s->id == P_MASK) {
|
|
// only draw this if the player is swimming
|
|
if (s->owner->swimming) {
|
|
if (s->owner->dir > 0) {
|
|
frame = 0;
|
|
} else {
|
|
frame = 1;
|
|
}
|
|
} else {
|
|
return;
|
|
}
|
|
} else if (s->id == P_MOVINGCARD) {
|
|
// not really needed but included here for neatness
|
|
frame = F_WALK1;
|
|
} else if (s->id == P_FIVECARDS) {
|
|
// not really needed but included here for neatness
|
|
frame = F_WALK1;
|
|
}
|
|
|
|
} else if (s->dead) {
|
|
if (isplayer(s)) {
|
|
frame = F_DEAD;
|
|
} else if (s == boss) {
|
|
frame = F_DEAD;
|
|
} else if (s->id == P_SNAIL) {
|
|
frame = F_DEAD;
|
|
} else {
|
|
if (globpowerup == PW_CLOCK) {
|
|
frame = F_DEAD + 2;
|
|
} else {
|
|
frame = F_DEAD + ((timer/2) % 4);
|
|
}
|
|
}
|
|
} else if (s->id == P_KINGSNAIL) {
|
|
// frame based on state
|
|
switch (s->timer1) {
|
|
case KSS_WALK1:
|
|
case KSS_WALK2:
|
|
default:
|
|
if ((timer/12) % 2 == 0) {
|
|
frame = F_WALK1;
|
|
} else {
|
|
frame = F_JUMP;
|
|
}
|
|
break;
|
|
case KSS_PAUSE1:
|
|
case KSS_PAUSE2:
|
|
case KSS_PAUSE3:
|
|
frame = F_WALK1;
|
|
break;
|
|
case KSS_SHOOT:
|
|
case KSS_REGEN:
|
|
if (s->timer3 < 100) {
|
|
frame = F_CAUGHT; // ie. broken shell
|
|
} else {
|
|
frame = F_WALK1;
|
|
}
|
|
break;
|
|
case KSS_JUMPING:
|
|
frame = F_JUMP;
|
|
break;
|
|
}
|
|
} else if (s->caughtby) {
|
|
frame = F_CAUGHT;
|
|
} else if (s->climbing) {
|
|
//frame = F_CLIMB1 + ((timer/12) % 2);
|
|
if (s->moved) {
|
|
if ((timer/12) % 2 == 0) {
|
|
frame = F_CLIMB1;
|
|
} else {
|
|
frame = F_CLIMB2;
|
|
}
|
|
} else {
|
|
frame = F_CLIMB1;
|
|
}
|
|
} else if ((s->swimming) && isplayer(s) && !s->slamming) {
|
|
if ((timer/12) % 2 == 0) {
|
|
frame = F_SWIM1;
|
|
} else {
|
|
frame = F_SWIM2;
|
|
}
|
|
} else if (s->netting && isplayer(s)) {
|
|
frame = F_SHOOT;
|
|
} else if (s->iced) {
|
|
frame = F_WALK1;
|
|
} else if (s->jumping) {
|
|
if ((s->id == P_SNAIL) && (s->recoiling)) {
|
|
// when a snail is "jumping" it is actually recoiling
|
|
// and should look like a shell
|
|
frame = F_DEAD;
|
|
} else if (s->id == P_SLUG) {
|
|
frame = F_FALL;
|
|
} else if (s->powerup == PW_PILL) {
|
|
// toggle between walking frames FAST
|
|
if ((timer/3) % 2 == 0) {
|
|
frame = F_WALK1;
|
|
} else {
|
|
frame = F_JUMP;
|
|
}
|
|
} else {
|
|
frame = F_JUMP;
|
|
}
|
|
} else if (s->falling) {
|
|
if ((s->id == P_SNAIL) && (s->recoiling)) {
|
|
frame = F_DEAD;
|
|
} else if (s->id == P_FLY) {
|
|
// same as flying
|
|
|
|
// toggle between flying frames
|
|
if ((timer/3) % 2 == 0) {
|
|
frame = F_WALK1;
|
|
} else {
|
|
frame = F_FALL;
|
|
}
|
|
} else if (s->powerup == PW_PILL) {
|
|
// toggle between walking frames FAST
|
|
if ((timer/3) % 2 == 0) {
|
|
frame = F_WALK1;
|
|
} else {
|
|
frame = F_JUMP;
|
|
}
|
|
} else {
|
|
frame = F_FALL;
|
|
}
|
|
} else if (s->slamming) {
|
|
double slamdegs = s->slamangle / (M_PI/180);
|
|
if (slamdegs < 36) {
|
|
frame = F_SLAM1;
|
|
} else if (slamdegs < 72) {
|
|
frame = F_SLAM2;
|
|
} else if (slamdegs < 108) {
|
|
frame = F_SLAM3;
|
|
} else if (slamdegs < 144) {
|
|
frame = F_SLAM4;
|
|
} else {
|
|
frame = F_SLAM5;
|
|
}
|
|
} else if (!s->teleporting) {
|
|
if ((s->id == P_SPIDER) && (s->ys != -99)) {
|
|
frame = F_FALL;
|
|
} else {
|
|
// DEFAULT FOR EVERYTHING
|
|
// walking / sliding
|
|
if (s->moved == MV_WALK) {
|
|
if (s->powerup == PW_PILL) {
|
|
// toggle between walking frames FAST
|
|
if ((timer/3) % 2 == 0) {
|
|
frame = F_WALK1;
|
|
} else {
|
|
frame = F_JUMP;
|
|
}
|
|
} else {
|
|
// toggle between walking frames
|
|
if ((timer/12) % 2 == 0) {
|
|
frame = F_WALK1;
|
|
} else {
|
|
frame = F_JUMP;
|
|
}
|
|
}
|
|
} else if (s->moved == MV_FLY) {
|
|
int animspeed;
|
|
// fly animates faster
|
|
if ((s->id == P_FLY) && (s->flies)) {
|
|
animspeed = 3;
|
|
} else if (s->id == P_KINGFLY){
|
|
animspeed = 3;
|
|
} else {
|
|
animspeed = 12;
|
|
}
|
|
|
|
|
|
// toggle between flying frames
|
|
if ((timer/animspeed) % 2 == 0) {
|
|
frame = F_WALK1;
|
|
} else {
|
|
frame = F_FALL;
|
|
}
|
|
|
|
} else if (s->moved == MV_ICE) { // sliding
|
|
frame = F_FALL;
|
|
} else { // standing still
|
|
if (s->powerup == PW_PILL) {
|
|
// toggle between walking frames FAST
|
|
if ((timer/3) % 2 == 0) {
|
|
frame = F_WALK1;
|
|
} else {
|
|
frame = F_JUMP;
|
|
}
|
|
} else {
|
|
frame = F_WALK1;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
/* x-flip if required */
|
|
if (!isfruit(s->id) && !iseffect(s->id) && (s->id != P_BLACKCLOUD)) {
|
|
if (s->dir == -1) {
|
|
frame += MAXFRAMES;
|
|
}
|
|
} else if ((s->id == P_GLOVE) || (s->id == P_KSSHELL)) {
|
|
if (s->dir == -1) {
|
|
frame += MAXFRAMES;
|
|
}
|
|
} else if ((s->id == P_WINGLEFT) || (s->id == P_WINGRIGHT)) {
|
|
if (s->owner->dir == -1) {
|
|
frame += MAXFRAMES;
|
|
}
|
|
}
|
|
/* make red if required */
|
|
if (s->angry && s->id != P_BLACKCLOUD) {
|
|
if (!isplayer(s) && !isfruit(s->id)) {
|
|
frame += (MAXFRAMES*2);
|
|
}
|
|
}
|
|
|
|
if (s->id == P_MOVINGCARD) {
|
|
// image comes from timer1
|
|
s->img = imageset[s->timer1].img[F_WALK1];
|
|
} else if (s->id == P_FIVECARDS) {
|
|
// do nothing - img already there!
|
|
} else if (s->id == P_RANDOM) {
|
|
// image based on timer1
|
|
s->img = imageset[s->timer1].img[F_WALK1];
|
|
} else if ((s->id != P_BLACKCLOUD) && (s->id != P_PINKCLOUD) && (!s->teleporting)) {
|
|
// ALL OTHERS:
|
|
// select image based on sprite id
|
|
s->img = imageset[s->id].img[frame];
|
|
}
|
|
|
|
|
|
// zapper lightning bolt
|
|
if ((s->id == P_ZAPPER) && (s->timer4 > 0)) {
|
|
if (s->zapping) {
|
|
SDL_Color col;
|
|
double zapx,zapy;
|
|
|
|
// initialise
|
|
col.r = 0;
|
|
col.g = 0;
|
|
col.b = 0;
|
|
col.unused = 0;
|
|
|
|
switch (timer % 4) {
|
|
case 0: col.r = 255; col.g = 255; col.b = 255; break;
|
|
case 1: col.r = 0; col.g = 0; col.b = 0; break;
|
|
case 2: col.r = 0; col.g = 255; col.b = 255; break;
|
|
default:
|
|
case 3: col.r = 0; col.g = 0; col.b = 0; break;
|
|
}
|
|
// draw lines to zap position
|
|
zapx = s->zapping->x;
|
|
zapy = s->zapping->y;
|
|
drawline(screen, s->x, s->y - (s->img->h/2),zapx, zapy, col);
|
|
drawline(screen, s->x+1, s->y - (s->img->h/2),zapx, zapy, col);
|
|
drawline(screen, s->x-1, s->y - (s->img->h/2),zapx, zapy, col);
|
|
drawline(screen, s->x, s->y+1 - (s->img->h/2),zapx, zapy, col);
|
|
drawline(screen, s->x, s->y-1 - (s->img->h/2),zapx, zapy, col);
|
|
} else { // the thing we were zapping died!
|
|
s->timer4 = 0;
|
|
}
|
|
}
|
|
|
|
|
|
/* spider's climbing web */
|
|
if ((s->id == P_SPIDER) && ((s->ys != -99) || s->falling) && !s->dead && !s->caughtby && !s->iced) {
|
|
tiletype_t *tt;
|
|
int x = s->x;
|
|
int y = s->y - s->img->h/2;
|
|
int tx=0,ty = 0;
|
|
int done = B_FALSE;
|
|
for (y = s->y ; !done ; y-= TILEH) {
|
|
tt = gettileat(x,y,&tx,&ty);
|
|
if ((tt == NULL) || (tt->solid)) {
|
|
done = B_TRUE;
|
|
}
|
|
if (y < 0) { // nothing above us!
|
|
// die!
|
|
s->dead = D_FINAL;
|
|
puffin(-1, s->x, s->y, "spiderdeath",0);
|
|
return;
|
|
}
|
|
}
|
|
drawline(screen,s->x,s->y - (s->img->h/2),s->x,ty*TILEH+TILEH-1,white);
|
|
|
|
}
|
|
|
|
// override
|
|
if ((s->id == P_SNAIL) && (s->recoiling)) {
|
|
frame = F_DEAD;
|
|
}
|
|
|
|
|
|
s->frame = frame;
|
|
|
|
|
|
// TODO: return if s->img is NULL - but try to bugfix everything
|
|
// before resorting to this.
|
|
area.x = s->x - (s->img->w/2);
|
|
area.y = s->y - (s->img->h);
|
|
area.w = 0;
|
|
area.h = 0;
|
|
|
|
// don't blink invuln things while showing help text
|
|
if ((s->invuln) && (levelcomplete != LV_HELPFREEZE)) {
|
|
if (timer % 2 == 0) {
|
|
//SDL_BlitSurface(s->img, NULL, screen, &area);
|
|
if (isplayer(s)) {
|
|
drawplayer(s, &area);
|
|
} else {
|
|
doblit(s->img, screen, &area);
|
|
}
|
|
}
|
|
} else if ((s->doomcount > 0) && (s->doomcount <= 150) && (levelcomplete != LV_HELPFREEZE)) {
|
|
if ((timer/2) % 2 == 0) {
|
|
if (isplayer(s)) {
|
|
drawplayer(s, &area);
|
|
} else {
|
|
doblit(s->img, screen, &area);
|
|
}
|
|
}
|
|
} else if (s == boss && s->dead) {
|
|
if ((timer / 10) % 2 == 0) {
|
|
//SDL_BlitSurface(s->img, NULL, screen, &area);
|
|
doblit(s->img, screen, &area);
|
|
}
|
|
} else {
|
|
if (isplayer(s)) {
|
|
drawplayer(s, &area);
|
|
} else {
|
|
doblit(s->img, screen, &area);
|
|
// king snail regenerating shell...
|
|
if ((s->id == P_KINGSNAIL) && (s->timer1 == KSS_REGEN)) {
|
|
SDL_Surface *shellimg, *srcimg;
|
|
SDL_Rect newarea;
|
|
double pct;
|
|
// shell image -left or right?
|
|
if (s->dir == 1) {
|
|
srcimg = imageset[P_KSSHELL].img[0];
|
|
} else {
|
|
srcimg = imageset[P_KSSHELL].img[MAXFRAMES];
|
|
}
|
|
// generate new shell at correct size ...
|
|
pct = ((double)s->timer3 / 100);
|
|
if (pct > 1) pct = 1;
|
|
shellimg = rotozoomSurfaceXY(srcimg,0, pct, pct ,0);
|
|
// blit it
|
|
if (s->dir == 1) {
|
|
newarea.x = s->x - (shellimg->w/2) - 21;
|
|
} else {
|
|
newarea.x = s->x - (shellimg->w/2) + 21;
|
|
}
|
|
newarea.y = s->y - (shellimg->h/2) - 28;
|
|
newarea.w = 0;
|
|
newarea.h = 0;
|
|
SDL_BlitSurface(shellimg, NULL, screen, &newarea);
|
|
// free it
|
|
SDL_FreeSurface(shellimg);
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
// ice cube
|
|
if (s->iced) {
|
|
if (!s->iceimg) {
|
|
double xmod,ymod;
|
|
xmod = (double)s->img->w / (double)icecube->w;
|
|
ymod = (double)s->img->h / (double)icecube->h;
|
|
// create image
|
|
s->iceimg = rotozoomSurfaceXY(icecube,0, xmod, ymod ,0);
|
|
}
|
|
// draw it
|
|
doblit(s->iceimg, screen, &area);
|
|
//SDL_BlitSurface(s->iceimg, NULL, screen, &area);
|
|
|
|
}
|
|
|
|
// anchor
|
|
if (globpowerup == PW_ANCHOR) {
|
|
if (ismonster(s->id) && !s->caughtby && !s->dead) {
|
|
SDL_Rect newarea;
|
|
newarea = area;
|
|
newarea.y += (s->img->h / 3);
|
|
SDL_BlitSurface(imageset[P_SMALLANCHOR].img[0], NULL, screen, &newarea);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* caughtby lines */
|
|
if ((s->caughtby) && (s->caughtstate == 2)){
|
|
// only if we're on the screen
|
|
if ((s->y >= 0) && (s->y <= 480)) {
|
|
drawline(screen, s->x,s->y - s->img->h,
|
|
s->caughtby->x,s->caughtby->y-(s->caughtby->img->h/2), white);
|
|
drawline(screen, s->x,s->y - (s->img->h/2),
|
|
s->caughtby->x,s->caughtby->y-(s->caughtby->img->h/2), white);
|
|
drawline(screen, s->x,s->y,
|
|
s->caughtby->x,s->caughtby->y-(s->caughtby->img->h/2), white);
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
void killsprite(sprite_t *s) {
|
|
sprite_t *nextone, *lastone;
|
|
#ifndef __EDITOR
|
|
sprite_t *s2;
|
|
|
|
// remove boss pointer
|
|
if (boss == s) {
|
|
boss = NULL;
|
|
}
|
|
|
|
// remove mask pointer
|
|
/*
|
|
if (mask == s) {
|
|
mask = NULL;
|
|
}
|
|
*/
|
|
|
|
if (s->caughtby) {
|
|
s->caughtby->netcaught--;
|
|
s->caughtby = NULL;
|
|
s->caughtstate = B_FALSE;
|
|
}
|
|
|
|
s->zapping = NULL;
|
|
|
|
/* remove references to this sprite before removing it */
|
|
for (s2 = sprite ; s2 ; s2 = s2->next) {
|
|
if (s2->owner == s) {
|
|
s2->owner = NULL;
|
|
}
|
|
if (s2->bullet == s) {
|
|
s2->bullet = NULL;
|
|
}
|
|
if (s2->zapping == s) {
|
|
s2->zapping = NULL;
|
|
}
|
|
}
|
|
|
|
// free ice image
|
|
if (s->iceimg) {
|
|
SDL_FreeSurface(s->iceimg);
|
|
}
|
|
|
|
// free image for certain types
|
|
switch (s->id) {
|
|
case P_FIVECARDS:
|
|
case P_PINKCLOUD:
|
|
case P_BLACKCLOUD:
|
|
if (s->img) {
|
|
SDL_FreeSurface(s->img);
|
|
}
|
|
break;
|
|
}
|
|
#endif
|
|
|
|
nextone = s->next;
|
|
if (nextone != NULL) {
|
|
nextone->prev = s->prev;
|
|
} else { /*last sprite */
|
|
lastsprite = s->prev;
|
|
}
|
|
|
|
if (s->prev == NULL) {
|
|
/* first sprite */
|
|
nextone = sprite->next;
|
|
free(sprite);
|
|
sprite = nextone;
|
|
} else {
|
|
lastone = s->prev;
|
|
free (lastone->next );
|
|
lastone->next = nextone;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
void flip(void) {
|
|
#ifdef OPENGL
|
|
SDL_UpdateRect(screen,0,0,screen->w,screen->h);
|
|
SDL_GL_SwapBuffers();
|
|
#else
|
|
SDL_Flip(screen);
|
|
#endif
|
|
}
|
|
|
|
// returns 0 if tile isn't animated, else the number of frames
|
|
int gettileframecount(int tid) {
|
|
tiletype_t *tt;
|
|
|
|
tt = gettile(tid);
|
|
return tt->numframes;
|
|
}
|
|
|
|
// returns gem type for a given flower
|
|
int flowertogem(int id) {
|
|
switch (id) {
|
|
case P_FLOWERRED:
|
|
return P_GEMRED;
|
|
case P_FLOWERYELLOW:
|
|
return P_GEMYELLOW;
|
|
case P_FLOWERPURPLE:
|
|
return P_GEMPURPLE;
|
|
|
|
}
|
|
|
|
return P_GEMRED;
|
|
}
|
|
|
|
int iscard(int id) {
|
|
if ((id >= P_FIRSTCARD) && (id <= P_FIRSTCARD+51)) {
|
|
return B_TRUE;
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
int isflower(int id) {
|
|
switch (id) {
|
|
case P_FLOWERRED:
|
|
case P_FLOWERYELLOW:
|
|
case P_FLOWERPURPLE:
|
|
return B_TRUE;
|
|
|
|
}
|
|
|
|
return B_FALSE;
|
|
}
|
|
|
|
/* returns B_TRUE if the given powerup is one which
|
|
gives the player a special ability */
|
|
int isabilitypowerup(int id) {
|
|
switch (id) {
|
|
case P_BOXING:
|
|
case P_MACEPOWERUP:
|
|
case P_SHIELD:
|
|
case P_RINGSILVER:
|
|
case P_RINGGOLD:
|
|
case P_CLOVER:
|
|
case P_ACCORDION:
|
|
case P_ZAPPOWERUP:
|
|
case P_GUN:
|
|
case P_CANNONPOWERUP:
|
|
case P_MAGNET:
|
|
case P_JETPACK:
|
|
case P_PILL:
|
|
case P_RAYGUN:
|
|
case P_TOPHAT:
|
|
return B_TRUE;
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
|
|
|
|
int isbadpowerup(int id) {
|
|
switch (id) {
|
|
case P_SKULL:
|
|
case P_BADMAGNET:
|
|
return B_TRUE;
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
|
|
/* returns B_TRUE if the given powerup is one which
|
|
will or could effectively win the level */
|
|
int iswinpowerup(int id) {
|
|
switch (id) {
|
|
case P_BOMB:
|
|
case P_PHONE:
|
|
case P_WAND:
|
|
case P_LAMP:
|
|
return B_TRUE;
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
int isfruit(int id) {
|
|
switch (id) {
|
|
/* fruits */
|
|
case P_CHEESE:
|
|
case P_ICECREAM:
|
|
case P_CHIPS:
|
|
case P_BURGER:
|
|
case P_PIZZA:
|
|
case P_SUNDAE:
|
|
case P_CAKE:
|
|
case P_CHOCOLATE:
|
|
case P_DIAMOND:
|
|
case P_GOLDCOIN:
|
|
case P_GOLDBAR:
|
|
return FT_FRUIT;
|
|
|
|
/* super powerups */
|
|
case P_BIGSPEED:
|
|
case P_BIGSCUBA:
|
|
case P_SUPERUMBRELLA:
|
|
case P_BIGHELMET:
|
|
return FT_SUPER;
|
|
/* permenant powerups */
|
|
case P_SPEED:
|
|
case P_NUMNETS:
|
|
case P_BIGNET:
|
|
case P_HELP:
|
|
case P_GEMBOOST:
|
|
case P_BELL:
|
|
case P_TROPHY:
|
|
case P_HONEY:
|
|
case P_HELMET:
|
|
case P_MASKPOWERUP:
|
|
case P_WINGBOOTS:
|
|
case P_UMBRELLA:
|
|
return FT_PERM;
|
|
/* one-off level only powerups */
|
|
case P_BOXING:
|
|
case P_MACEPOWERUP:
|
|
case P_FTODIAMOND:
|
|
case P_FTOGEM:
|
|
case P_BOMB:
|
|
case P_STARPOWERUP:
|
|
case P_UFO:
|
|
case P_LIFE:
|
|
case P_PHONE:
|
|
case P_SHIELD:
|
|
case P_RINGSILVER:
|
|
case P_RINGGOLD:
|
|
case P_CLOCK:
|
|
case P_SNOWMAN:
|
|
case P_TAP:
|
|
case P_SPRAY:
|
|
case P_CANNONPOWERUP:
|
|
case P_CLOVER:
|
|
case P_ACCORDION:
|
|
case P_GUN:
|
|
case P_ZAPPOWERUP:
|
|
case P_SKULL:
|
|
case P_GNOME:
|
|
case P_WAND:
|
|
case P_ANCHOR:
|
|
case P_CANDLE:
|
|
case P_WHISTLE:
|
|
case P_RANDOM:
|
|
case P_MAGNET:
|
|
case P_BADMAGNET:
|
|
case P_JETPACK:
|
|
case P_CAMERA:
|
|
case P_PILL:
|
|
case P_RAYGUN:
|
|
case P_TOPHAT:
|
|
case P_LAMP:
|
|
return FT_TEMP;
|
|
/* flowers */
|
|
case P_FLOWERYELLOW:
|
|
case P_FLOWERRED:
|
|
case P_FLOWERPURPLE:
|
|
/* gems */
|
|
case P_GEMYELLOW:
|
|
case P_GEMRED:
|
|
case P_GEMPURPLE:
|
|
return FT_GEM;
|
|
/* misc */
|
|
case P_POWERUPPOS:
|
|
case P_EGG:
|
|
return FT_OTHER;
|
|
|
|
}
|
|
|
|
if (iscard(id)) return FT_CARD;
|
|
|
|
return B_FALSE;
|
|
}
|
|
|
|
int isbullet(int id) {
|
|
if (id == P_SPIT) return B_TRUE;
|
|
if (id == P_FIREBALL) return B_TRUE;
|
|
if (id == P_BIGFIREBALL) return B_TRUE;
|
|
if (id == P_MOTHFIRE) return B_TRUE;
|
|
|
|
return B_FALSE;
|
|
}
|
|
|
|
int isplatform(int id) {
|
|
switch (id) {
|
|
case P_PLATFORM:
|
|
return B_TRUE;
|
|
}
|
|
|
|
return B_FALSE;
|
|
}
|
|
|
|
int iseffect(int id) {
|
|
switch (id) {
|
|
case P_PUFF:
|
|
case P_SPARKLE:
|
|
case P_SMASH:
|
|
case P_FLAME:
|
|
case P_KSSHELL:
|
|
case P_POWERUPPOS:
|
|
case P_GLOVE:
|
|
case P_MACE:
|
|
case P_PINKCLOUD:
|
|
case P_CANNON:
|
|
case P_ZAPPER:
|
|
case P_BUBBLE:
|
|
case P_STAR:
|
|
case P_METEOR:
|
|
case P_MASK:
|
|
case P_MOVINGCARD:
|
|
case P_FIVECARDS:
|
|
case P_PLATFORM:
|
|
case P_RAYGUNBULLET:
|
|
// these last ones aren't REALLY effects since they never have a sprite allocated
|
|
case P_WINGLEFT:
|
|
case P_WINGRIGHT:
|
|
case P_BIGUMBRELLA:
|
|
case P_SMALLANCHOR:
|
|
return B_TRUE;
|
|
}
|
|
|
|
return B_FALSE;
|
|
}
|
|
|
|
int needscollisions(int id) {
|
|
if (id == P_SMASH) return B_TRUE;
|
|
if (id == P_STAR) return B_TRUE;
|
|
if (id == P_METEOR) return B_TRUE;
|
|
if (id == P_ZAPPER) return B_TRUE;
|
|
if (id == P_RAYGUNBULLET) return B_TRUE;
|
|
if (isplatform(id)) return B_TRUE;
|
|
|
|
return B_FALSE;
|
|
}
|
|
|
|
#ifdef OPENGL
|
|
void drawpixel16(SDL_Surface *screen, int x, int y, SDL_Color c)
|
|
{
|
|
Uint8 *bufp;
|
|
|
|
/* check x/y */
|
|
if (x >= screen->w) return;
|
|
if (y >= screen->h) return;
|
|
if (x < 0) return;
|
|
if (y < 0) return;
|
|
|
|
// bufp = (Uint16 *)screen->pixels + (y*screen->pitch / 2) + x;
|
|
|
|
bufp = (Uint8 *)screen->pixels + y * screen->pitch + x * 4;
|
|
|
|
// *bufp = SDL_MapRGB(screen->format, c.r, c.g, c.b);
|
|
*(Uint32 *)bufp = SDL_MapRGB(screen->format, c.r, c.g, c.b);
|
|
}
|
|
|
|
#else
|
|
|
|
|
|
void drawpixel16(SDL_Surface *s, int x, int y, SDL_Color c)
|
|
{
|
|
Uint16 *bufp;
|
|
|
|
// check x/y
|
|
if (x >= s->w) return;
|
|
if (y >= s->h) return;
|
|
if (x < 0) return;
|
|
if (y < 0) return;
|
|
|
|
bufp = (Uint16 *)s->pixels + (y*s->pitch / 2) + x;
|
|
*bufp = SDL_MapRGB(s->format, c.r, c.g, c.b);
|
|
}
|
|
|
|
#endif
|
|
|
|
void drawpixel32(SDL_Surface *s, int x, int y, SDL_Color c)
|
|
{
|
|
Uint32 *bufp;
|
|
|
|
/* check x/y */
|
|
if (x >= s->w) return;
|
|
if (y >= s->h) return;
|
|
if (x < 0) return;
|
|
if (y < 0) return;
|
|
|
|
bufp = (Uint32 *)s->pixels + (y*s->pitch / 4) + x;
|
|
*bufp = SDL_MapRGB(s->format, c.r, c.g, c.b);
|
|
}
|
|
|
|
|
|
void drawline(SDL_Surface *screen, int x1, int y1, int x2, int y2, SDL_Color c) {
|
|
int deltax, deltay;
|
|
int numpixels;
|
|
int d;
|
|
int dinc1,dinc2,xinc1,xinc2,yinc1,yinc2;
|
|
int i;
|
|
int x;
|
|
int y;
|
|
int maskcount = 0;
|
|
int maskindex = 0;
|
|
|
|
deltax = (x2 - x1);
|
|
if (deltax < 0) deltax = -deltax;
|
|
deltay = (y2 - y1);
|
|
if (deltay < 0) deltay = -deltay;
|
|
|
|
if (deltax >= deltay) {
|
|
numpixels = deltax + 1;
|
|
d = (deltay*2) - deltax;
|
|
dinc1 = deltay << 1;
|
|
dinc2 = (deltay-deltax) << 1;
|
|
xinc1 = 1;
|
|
xinc2 = 1;
|
|
yinc1 = 0;
|
|
yinc2 = 1;
|
|
} else {
|
|
numpixels = deltay + 1;
|
|
d = (deltax*2) - deltay;
|
|
dinc1 = deltax << 1;
|
|
dinc2 = (deltax - deltay) << 1;
|
|
xinc1 = 0;
|
|
xinc2 = 1;
|
|
yinc1 = 1;
|
|
yinc2 = 1;
|
|
}
|
|
|
|
if (x1 > x2) {
|
|
xinc1 = - xinc1;
|
|
xinc2 = - xinc2;
|
|
}
|
|
if (y1 > y2) {
|
|
yinc1 = - yinc1;
|
|
yinc2 = - yinc2;
|
|
}
|
|
|
|
x = x1; y = y1;
|
|
|
|
maskcount = 0;
|
|
maskindex = 0;
|
|
for (i = 0; i < numpixels; i++) {
|
|
|
|
drawpixel(screen,x,y,c);
|
|
|
|
|
|
|
|
if (d < 0) {
|
|
d += dinc1;
|
|
x += xinc1;
|
|
y += yinc1;
|
|
} else {
|
|
d += dinc2;
|
|
x += xinc2;
|
|
y += yinc2;
|
|
}
|
|
}
|
|
}
|
|
|
|
// draw line with alternating colours
|
|
void drawdotline16(SDL_Surface *screen, int x1, int y1, int x2, int y2, SDL_Color c, SDL_Color c2) {
|
|
int deltax, deltay;
|
|
int numpixels;
|
|
int d;
|
|
int dinc1,dinc2,xinc1,xinc2,yinc1,yinc2;
|
|
int i;
|
|
int x;
|
|
int y;
|
|
int maskcount = 0;
|
|
int maskindex = 0;
|
|
|
|
|
|
|
|
deltax = (x2 - x1);
|
|
if (deltax < 0) deltax = -deltax;
|
|
deltay = (y2 - y1);
|
|
if (deltay < 0) deltay = -deltay;
|
|
|
|
if (deltax >= deltay) {
|
|
numpixels = deltax + 1;
|
|
d = (deltay*2) - deltax;
|
|
dinc1 = deltay << 1;
|
|
dinc2 = (deltay-deltax) << 1;
|
|
xinc1 = 1;
|
|
xinc2 = 1;
|
|
yinc1 = 0;
|
|
yinc2 = 1;
|
|
} else {
|
|
numpixels = deltay + 1;
|
|
d = (deltax*2) - deltay;
|
|
dinc1 = deltax << 1;
|
|
dinc2 = (deltax - deltay) << 1;
|
|
xinc1 = 0;
|
|
xinc2 = 1;
|
|
yinc1 = 1;
|
|
yinc2 = 1;
|
|
}
|
|
|
|
if (x1 > x2) {
|
|
xinc1 = - xinc1;
|
|
xinc2 = - xinc2;
|
|
}
|
|
if (y1 > y2) {
|
|
yinc1 = - yinc1;
|
|
yinc2 = - yinc2;
|
|
}
|
|
|
|
x = x1; y = y1;
|
|
|
|
maskcount = 0;
|
|
maskindex = 0;
|
|
for (i = 0; i < numpixels; i++) {
|
|
|
|
if (i % 2 == 0) {
|
|
drawpixel(screen,x,y,c);
|
|
} else {
|
|
drawpixel(screen,x,y,c2);
|
|
}
|
|
|
|
|
|
|
|
if (d < 0) {
|
|
d += dinc1;
|
|
x += xinc1;
|
|
y += yinc1;
|
|
} else {
|
|
d += dinc2;
|
|
x += xinc2;
|
|
y += yinc2;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void drawbox16(SDL_Surface *screen, int x1, int y1, int x2, int y2, SDL_Color *c, SDL_Color *fc) {
|
|
if (fc != NULL) {
|
|
/* fill */
|
|
if (((x2 - x1) >= 2) && ((y2 - y1) >= 2)) {
|
|
int y;
|
|
for (y = (y1+1) ; y <= (y2-1); y++) {
|
|
drawline(screen, x1+1, y, x2-1,y,*fc);
|
|
}
|
|
}
|
|
}
|
|
drawline(screen,x1,y1,x2,y1,*c);
|
|
drawline(screen,x1,y1,x1,y2,*c);
|
|
drawline(screen,x1,y2,x2,y2,*c);
|
|
drawline(screen,x2,y1,x2,y2,*c);
|
|
}
|
|
|
|
|
|
|
|
int getcolor(SDL_Surface *dest, int x, int y, SDL_Color *col) {
|
|
Uint32 pixel;
|
|
int bpp = dest->format->BytesPerPixel;
|
|
char *ppos;
|
|
unsigned char r,g,b,a;
|
|
|
|
|
|
ppos = (char *) dest->pixels;
|
|
|
|
/* offset y */
|
|
ppos += (dest->pitch * y);
|
|
/* offset x */
|
|
ppos += (bpp * x);
|
|
|
|
memcpy(&pixel, ppos, bpp);
|
|
|
|
|
|
if (dest->format->BitsPerPixel == 32) {
|
|
SDL_GetRGBA(pixel, dest->format, &r,&g,&b, &a);
|
|
col->r = r;
|
|
col->g = g;
|
|
col->b = b;
|
|
col->unused = a;
|
|
} else if (dest->format->BitsPerPixel == 16) {
|
|
SDL_GetRGB(pixel, dest->format, &r,&g,&b);
|
|
col->r = r;
|
|
col->g = g;
|
|
col->b = b;
|
|
} else if (dest->format->BitsPerPixel == 8) {
|
|
*col = dest->format->palette->colors[(Uint8)pixel];
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
tiletype_t *gettile(int uniqid) {
|
|
tiletype_t *t;
|
|
|
|
for (t = tiletype; t ; t = t->next) {
|
|
if (t->uniqid == uniqid) return t;
|
|
}
|
|
|
|
return &fakeblock;
|
|
}
|
|
|
|
int getuniq(int tileid) {
|
|
tiletype_t *t;
|
|
|
|
for (t = tiletype; t ; t = t->next) {
|
|
if (t->id == tileid) return t->uniqid;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void drawtile(SDL_Surface *where, int x, int y) {
|
|
SDL_Rect area;
|
|
tiletype_t *tt;
|
|
int frame;
|
|
int offset;
|
|
|
|
if ((x < 0) || (y < 0) || (x >= LEVELW) || (y >= LEVELH)) {
|
|
return;
|
|
}
|
|
|
|
area.x = x * TILEW;
|
|
area.y = y * TILEH;
|
|
area.w = TILEW;
|
|
area.h = TILEH;
|
|
/* draw blank tile first */
|
|
tt = gettile(curlevel->bgtileid);
|
|
SDL_BlitSurface(levelbg, &area, where, &area);
|
|
|
|
/* now draw real one */
|
|
offset = y*LEVELW+x;
|
|
tt = gettile(curlevel->map[offset]);
|
|
frame = curlevel->tileframe[offset];
|
|
if (tt->id != curlevel->bgtileid) {
|
|
SDL_BlitSurface(tt->img[frame], NULL, where, &area);
|
|
}
|
|
|
|
/* now draw layer2 if it exists */
|
|
if (curlevel->map2[offset] != T_BLANK) {
|
|
tt = gettile(curlevel->map2[offset]);
|
|
if (tt->id != curlevel->bgtileid) {
|
|
SDL_BlitSurface(tt->img[frame], NULL, where, &area);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void drawl3tile(SDL_Surface *where, int x, int y) {
|
|
SDL_Rect area;
|
|
tiletype_t *tt;
|
|
int offset;
|
|
|
|
if ((x < 0) || (y < 0) || (x >= LEVELW) || (y >= LEVELH)) {
|
|
return;
|
|
}
|
|
|
|
area.x = x * TILEW;
|
|
area.y = y * TILEH;
|
|
area.w = TILEW;
|
|
area.h = TILEH;
|
|
/* draw layer3 if it exists */
|
|
offset = y*LEVELW+x;
|
|
if (curlevel->map3[offset] != T_BLANK) {
|
|
tt = gettile(curlevel->map3[offset]);
|
|
if (tt->id != curlevel->bgtileid) {
|
|
SDL_BlitSurface(tt->img[0], NULL, where, &area);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
void initglobals(void) {
|
|
sprite = NULL;
|
|
|
|
level = NULL;
|
|
|
|
vidargs = 0;
|
|
|
|
/* timers */
|
|
gtime = 0;
|
|
timer = 0;
|
|
toggletimer = 0;
|
|
|
|
/* colours */
|
|
red.r = 255; red.g = 0; red.b = 0;
|
|
black.r = 0; black.g = 0; black.b = 0;
|
|
blue.r = 0; blue.g = 0; blue.b = 255;
|
|
white.r = 255; white.g = 255; white.b = 255;
|
|
green.r = 0; green.g = 255; green.b = 0;
|
|
yellow.r = 255; yellow.g = 255; yellow.b = 0;
|
|
purple.r = 255; purple.g = 0; purple.b = 255;
|
|
}
|
|
|
|
|
|
|
|
SDL_Surface *loadspriteimage(int spriteid, int frame, char *filename) {
|
|
char fullfile[BUFLEN];
|
|
SDL_Surface *temps;
|
|
|
|
sprintf(fullfile,"%s/%s",datadir,filename);
|
|
//imageset[spriteid].img[frame] = IMG_Load(fullfile);
|
|
temps = IMG_Load(fullfile);
|
|
imageset[spriteid].img[frame] = SDL_DisplayFormatAlpha(temps);
|
|
|
|
if (imageset[spriteid].img[frame] == NULL) {
|
|
printf("Error loading image file: %s\n",fullfile);
|
|
exit(1);
|
|
}
|
|
SDL_FreeSurface(temps);
|
|
SDL_SetColorKey(imageset[spriteid].img[frame], SDL_RLEACCEL, 0);
|
|
return imageset[spriteid].img[frame];
|
|
}
|
|
|
|
int candoslopes(int sid) {
|
|
switch(sid) {
|
|
case P_SNAKE:
|
|
case P_SNAIL:
|
|
case P_SLUG:
|
|
return B_FALSE;
|
|
}
|
|
return B_TRUE;
|
|
}
|
|
|
|
int ismonster(int id) {
|
|
switch (id) {
|
|
case P_RAT:
|
|
case P_BEE:
|
|
case P_FLY:
|
|
case P_SPIDER:
|
|
case P_WSPIDER:
|
|
case P_SNAKE:
|
|
case P_TICK:
|
|
case P_PLANT:
|
|
case P_SNAIL:
|
|
case P_SLUG:
|
|
case P_FISH:
|
|
case P_FROG:
|
|
case P_ANT1:
|
|
case P_ANT2:
|
|
case P_ANT3:
|
|
case P_MOTH:
|
|
return MT_MONSTER;
|
|
case P_BLACKCLOUD:
|
|
case P_KINGRAT:
|
|
case P_KINGSNAIL:
|
|
case P_KINGFLY:
|
|
case P_KINGANT:
|
|
return MT_BOSS;
|
|
}
|
|
|
|
return B_FALSE;
|
|
}
|
|
|
|
|
|
void puffin(int willbecome, int x, int y, char *name, int delay) {
|
|
sprite_t *ss;
|
|
ss = addsprite(P_PUFF, x, y, "puff" );
|
|
ss->timer3 = willbecome;
|
|
ss->timer1 = -delay;
|
|
strncpy(ss->name, name, MIDBUFLEN);
|
|
}
|
|
|
|
/*
|
|
void removetext(void) {
|
|
SDL_Rect sarea;
|
|
text_t *t;
|
|
|
|
for (t = text ; t ; t = t->next) {
|
|
sarea.x = 0;
|
|
sarea.y = 0;
|
|
sarea.w = t->bgarea.w;
|
|
sarea.h = t->bgarea.h;
|
|
|
|
SDL_BlitSurface(t->bg, &sarea, screen, &t->bgarea);
|
|
}
|
|
}
|
|
*/
|
|
|
|
void killtext(text_t *t) {
|
|
text_t *nextone, *lastone;
|
|
|
|
|
|
if (t->bg) {
|
|
SDL_FreeSurface(t->bg);
|
|
t->bg = NULL;
|
|
}
|
|
if (t->img) {
|
|
SDL_FreeSurface(t->img);
|
|
t->img = NULL;
|
|
}
|
|
|
|
nextone = t->next;
|
|
if (nextone != NULL) {
|
|
nextone->prev = t->prev;
|
|
} else { /*last text */
|
|
lasttext = t->prev;
|
|
}
|
|
|
|
if (t->prev == NULL) {
|
|
/* first text */
|
|
nextone = text->next;
|
|
free(text);
|
|
text = nextone;
|
|
} else {
|
|
lastone = t->prev;
|
|
free (lastone->next );
|
|
lastone->next = nextone;
|
|
}
|
|
|
|
/* if we're killing text during LV_INIT, it must have been
|
|
the level announcement. That means that we can start
|
|
moving.
|
|
*/
|
|
if (levelcomplete == LV_INIT) {
|
|
levelcomplete = LV_INPROGRESS;
|
|
}
|
|
}
|
|
|
|
// returns score of given fruit type
|
|
int getpoints(int id) {
|
|
int points;
|
|
switch (id) {
|
|
case P_GOLDCOIN:
|
|
points = 250;
|
|
break;
|
|
case P_CHEESE:
|
|
points = 500;
|
|
break;
|
|
case P_ICECREAM:
|
|
points = 1000;
|
|
break;
|
|
case P_CHIPS:
|
|
points = 1500;
|
|
break;
|
|
case P_BURGER:
|
|
points = 2000;
|
|
break;
|
|
case P_PIZZA:
|
|
points = 2500;
|
|
break;
|
|
case P_SUNDAE:
|
|
points = 3000;
|
|
break;
|
|
case P_CAKE:
|
|
points = 3500;
|
|
break;
|
|
case P_CHOCOLATE: // LOTS
|
|
points = 8000;
|
|
break;
|
|
case P_GOLDBAR:
|
|
points = 10000;
|
|
break;
|
|
case P_DIAMOND:
|
|
points = 2500;
|
|
break;
|
|
case P_FLOWERYELLOW:
|
|
points = 5;
|
|
break;
|
|
case P_FLOWERRED:
|
|
points = 10;
|
|
break;
|
|
case P_FLOWERPURPLE:
|
|
points = 30;
|
|
break;
|
|
case P_GEMYELLOW:
|
|
points = 50;
|
|
break;
|
|
case P_GEMRED:
|
|
points = 75;
|
|
break;
|
|
case P_GEMPURPLE:
|
|
points = 100;
|
|
break;
|
|
case P_EGG:
|
|
default:
|
|
points = 0;
|
|
break;
|
|
|
|
}
|
|
|
|
return points;
|
|
}
|
|
|
|
|
|
int savelevellist(void) {
|
|
char filename[BUFLEN];
|
|
FILE *f;
|
|
int i;
|
|
sprintf(filename, "%s/%s",datadir,FILE_LEVELMAP);
|
|
f = fopen(filename,"w");
|
|
if (!f) {
|
|
printf("error writing to %s\n",FILE_LEVELMAP);
|
|
return B_FALSE;
|
|
}
|
|
|
|
for (i = 1; i < numlevels; i++) {
|
|
fprintf(f, "%d,%s,%s\n",levelentry[i].id, levelentry[i].filename, levelentry[i].desc);
|
|
}
|
|
|
|
fclose(f);
|
|
|
|
return B_FALSE;
|
|
}
|
|
|
|
int loadlevellist(void) {
|
|
int lev;
|
|
char filename[BUFLEN];
|
|
FILE *f;
|
|
char buf[BUFLEN];
|
|
char *p;
|
|
|
|
sprintf(filename, "%s/%s",datadir, FILE_LEVELMAP);
|
|
f = fopen(filename,"r");
|
|
if (!f) {
|
|
printf("Error opening %s\n",FILE_LEVELMAP);
|
|
exit(1);
|
|
}
|
|
// format is:
|
|
//
|
|
// id,filename,description,
|
|
lev = 1;
|
|
maxlevid = -99;
|
|
fgets(buf, BUFLEN, f);
|
|
while (!feof(f)) {
|
|
p = strtok(buf, ",");
|
|
if (!p) {
|
|
printf("invalid level id - line %d\n",lev);
|
|
return B_TRUE;
|
|
}
|
|
levelentry[lev].id = atoi(p);
|
|
|
|
// track max levelid
|
|
if (levelentry[lev].id > maxlevid) {
|
|
maxlevid = levelentry[lev].id;
|
|
}
|
|
|
|
|
|
p = strtok(NULL, ",");
|
|
if (!p) {
|
|
printf("invalid level filename - line %d\n",lev);
|
|
return B_TRUE;
|
|
}
|
|
strncpy(levelentry[lev].filename, p, MIDBUFLEN);
|
|
p = strtok(NULL, ",");
|
|
if (!p) {
|
|
printf("invalid level description - line %d\n",lev);
|
|
return B_TRUE;
|
|
}
|
|
p[strlen(p)-1] = '\0'; // strip newline
|
|
//LEVELENTry[lev].desc = strdup(p);
|
|
strncpy(levelentry[lev].desc, p, MIDBUFLEN);
|
|
lev++;
|
|
fgets(buf, BUFLEN, f);
|
|
}
|
|
fclose(f);
|
|
numlevels = lev;
|
|
|
|
printf("Read %d levels.\n",numlevels);
|
|
|
|
return B_FALSE;
|
|
}
|
|
|
|
int randompowerup(void) {
|
|
int num;
|
|
num = rand() % 48;
|
|
|
|
switch (num) {
|
|
case 0:
|
|
default:
|
|
return P_SPEED;
|
|
case 1:
|
|
return P_BIGNET;
|
|
case 2:
|
|
return P_NUMNETS;
|
|
case 3:
|
|
return P_BOXING;
|
|
case 4:
|
|
return P_FTODIAMOND;
|
|
case 5:
|
|
return P_FTOGEM;
|
|
case 6:
|
|
return P_BOMB;
|
|
case 7:
|
|
return P_SHIELD;
|
|
case 8:
|
|
return P_MACEPOWERUP;
|
|
case 9:
|
|
return P_HELMET;
|
|
case 10:
|
|
return P_GEMBOOST;
|
|
case 11:
|
|
return P_TROPHY;
|
|
case 12:
|
|
return P_RINGSILVER;
|
|
case 13:
|
|
return P_RINGGOLD;
|
|
case 14:
|
|
return P_BELL;
|
|
case 15:
|
|
return P_CLOCK;
|
|
case 16:
|
|
return P_SNOWMAN;
|
|
case 17:
|
|
return P_SPRAY;
|
|
case 18:
|
|
return P_CANNONPOWERUP;
|
|
case 19:
|
|
return P_PHONE;
|
|
case 20:
|
|
return P_HONEY;
|
|
case 21:
|
|
return P_LIFE;
|
|
case 22:
|
|
return P_STARPOWERUP;
|
|
case 23:
|
|
return P_UFO;
|
|
case 24:
|
|
return P_TAP;
|
|
case 25:
|
|
return P_MASKPOWERUP;
|
|
case 26:
|
|
if (!gotcard) {
|
|
gotcard = B_TRUE;
|
|
return getrandomcard();
|
|
} else {
|
|
return P_DIAMOND;
|
|
}
|
|
case 27:
|
|
return P_CLOVER;
|
|
case 28:
|
|
return P_ACCORDION;
|
|
case 29:
|
|
return P_WINGBOOTS;
|
|
case 30:
|
|
return P_SKULL;
|
|
case 31:
|
|
return P_GUN;
|
|
case 32:
|
|
return P_ZAPPOWERUP;
|
|
case 33:
|
|
return P_RANDOM;
|
|
case 34:
|
|
return P_GNOME;
|
|
case 35:
|
|
return P_WAND;
|
|
case 36:
|
|
return P_WHISTLE;
|
|
case 37:
|
|
return P_CANDLE;
|
|
case 38:
|
|
return P_ANCHOR;
|
|
case 39:
|
|
return P_MAGNET;
|
|
case 40:
|
|
return P_BADMAGNET;
|
|
case 41:
|
|
return P_JETPACK;
|
|
case 42:
|
|
return P_CAMERA;
|
|
case 43:
|
|
return P_UMBRELLA;
|
|
case 44:
|
|
return P_PILL;
|
|
case 45:
|
|
return P_RAYGUN;
|
|
case 46:
|
|
return P_TOPHAT;
|
|
case 47:
|
|
return P_LAMP;
|
|
}
|
|
}
|
|
|
|
// returns true if the given powerup id is a permenant one
|
|
int ispermenant(int pid) {
|
|
switch (pid) {
|
|
case P_SPEED:
|
|
case P_NUMNETS:
|
|
case P_BIGNET:
|
|
case P_MASKPOWERUP:
|
|
case P_HELP:
|
|
case P_TROPHY:
|
|
case P_HELMET:
|
|
case P_BELL:
|
|
case P_GEMBOOST:
|
|
return B_TRUE;
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
|
|
int isbosslevel(int lev) {
|
|
if (lev % 20 == 0) {
|
|
return B_TRUE;
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
int isboss(int monid) {
|
|
switch (monid) {
|
|
case P_KINGRAT:
|
|
case P_KINGSNAIL:
|
|
case P_KINGFLY:
|
|
case P_KINGANT:
|
|
return B_TRUE;
|
|
default:
|
|
return B_FALSE;
|
|
}
|
|
}
|
|
|
|
int isnettable(sprite_t *s) {
|
|
if (ismonster(s->id)) {
|
|
if (ismonster(s->id)) {
|
|
switch (s->id) {
|
|
case P_BLACKCLOUD:
|
|
case P_KINGRAT:
|
|
case P_KINGSNAIL:
|
|
case P_KINGFLY:
|
|
case P_KINGANT:
|
|
return B_FALSE;
|
|
default:
|
|
return B_TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isplayer(s)) return B_TRUE;
|
|
|
|
return B_FALSE;
|
|
}
|
|
|
|
// return starting health for a given boss type
|
|
int getbosshealth(int mid) {
|
|
switch (mid) {
|
|
case P_KINGRAT:
|
|
return 8;
|
|
case P_KINGSNAIL:
|
|
return 8;
|
|
case P_KINGFLY:
|
|
return 8;
|
|
case P_KINGANT:
|
|
return 8;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void getpixelrgb(SDL_Surface *where, int x, int y, SDL_Color *clr) {
|
|
Uint32 col;
|
|
|
|
//determine position
|
|
char* pPosition = ( char* ) where->pixels ;
|
|
|
|
//offset by y
|
|
pPosition += ( where->pitch * y ) ;
|
|
|
|
//offset by x
|
|
pPosition += ( where->format->BytesPerPixel * x ) ;
|
|
|
|
//copy pixel data
|
|
memcpy ( &col , pPosition , where->format->BytesPerPixel ) ;
|
|
|
|
//convert color
|
|
SDL_GetRGBA ( col , where->format , &clr->r , &clr->g , &clr->b, &clr->unused ) ;
|
|
//*r = color.r;
|
|
//*g = color.g;
|
|
//*b = color.b;
|
|
}
|
|
|
|
void setfruitinfo(void) {
|
|
setinfo(P_CHEESE, "Cheese", "", "cheese.png");
|
|
setinfo(P_ICECREAM, "Ice Cream","", "icecream.png");
|
|
setinfo(P_CHIPS, "Chips", "", "chips.png");
|
|
setinfo(P_BURGER, "Burger", "", "burger.png");
|
|
setinfo(P_DIAMOND, "Diamond", "", "diamond.png");
|
|
setinfo(P_PIZZA, "Pizza", "", "pizza.png");
|
|
setinfo(P_SUNDAE, "Sundae", "", "sundae.png");
|
|
setinfo(P_CAKE, "Cake", "", "cake.png");
|
|
setinfo(P_CHOCOLATE, "Chocolate", "", "chocolate.png");
|
|
setinfo(P_FLOWERYELLOW, "Sunflower", "", "flower-yellow.png");
|
|
setinfo(P_FLOWERRED, "Tulip", "", "flower-red.png");
|
|
setinfo(P_FLOWERPURPLE, "Orchid", "", "flower-purple.png");
|
|
setinfo(P_GEMYELLOW, "Topaz", "", "gem-yellow.png");
|
|
setinfo(P_GEMRED, "Ruby", "", "gem-red.png");
|
|
setinfo(P_GEMPURPLE, "Amethyst", "", "gem-purple.png");
|
|
setinfo(P_GOLDCOIN, "Gold Coin", "", "goldcoin.png");
|
|
setinfo(P_GOLDBAR, "Gold Bar", "", "goldbar.png");
|
|
|
|
setinfo(P_FIRSTCARD, "Card", "Keep a look out for these useful items. Collect a full poker hand for a secret bonus!", "cardh.png");
|
|
|
|
|
|
setinfo(P_SPEED, "Speed Up", "Makes you walk faster.", "speed.png");
|
|
setinfo(P_NUMNETS, "More Nets", "Increases the number of monsters you can catch simultaneously.", "numnets.png");
|
|
setinfo(P_BIGNET, "Big Net", "Makes your nets reach further.", "bignet.png");
|
|
setinfo(P_HELP, "Help", "Gives useful game information or hints.", "help.png");
|
|
setinfo(P_GEMBOOST, "Gem Boost", "Increases the length of gem streams.", "gemboost.png");
|
|
setinfo(P_BELL, "Powerup Bell", "Rings if certain types of powerup are going to appear on the level.", "bell.png");
|
|
setinfo(P_TROPHY, "Trophy", "Gives the player all powerups", "trophy.png");
|
|
setinfo(P_HELMET, "Helmet","Gives you a suit of armour which will protect you from death.", "helmet.png");
|
|
setinfo(P_BIGSPEED, "Big Speed Up", "Makes you walk faster, permenantly!", "bigspeed.png");
|
|
setinfo(P_BIGSCUBA, "Big Scuba Mask", "Permenantly gives you fast underwater movement.", "bigscuba.png");
|
|
setinfo(P_SUPERUMBRELLA, "Big Umbrella", "Bestows you with an umbrella which can survive death!", "superumbrella.png");
|
|
setinfo(P_BIGHELMET, "Big Helmet", "Endows you with a permenant suit of armour!", "bighelmet.png");
|
|
setinfo(P_MASKPOWERUP, "Scuba Mask", "Allows you to move fast underwater.", "maskpowerup.png");
|
|
setinfo(P_WINGBOOTS, "Winged Boots", "These magical boots cause you to grow wings, allowing to you jump again while in mid-air!", "wingboots.png");
|
|
|
|
setinfo(P_PILL, "Pill", "Eating this pill will cause you to enter a hyperactive state, moving at four times your standard speed!", "pill.png");
|
|
setinfo(P_RAYGUN, "Ray Gun", "Alien in origin, the ray gun contains enough charge for five shots of burning plasma.", "raygun.png");
|
|
setinfo(P_TOPHAT, "Top Hat", "Players wearing the top hat will find that every item which appears will now be a power-up!", "tophat.png");
|
|
setinfo(P_LAMP, "Magic Lamp", "The magic lamp shifts you into an alternate dimension filled with gold! Collect it all for a kingly bonus...", "lamp.png");
|
|
|
|
setinfo(P_BOXING, "Boxing Glove", "Your net will punch monsters, killing them instantly.", "boxing.png");
|
|
setinfo(P_MACEPOWERUP, "Mace", "Slamming your net will cause a lethal explosion!", "macepowerup.png");
|
|
setinfo(P_FTODIAMOND, "Diamond Flower","Transforms all flowers on the level into diamonds.", "flowertodiamond.png");
|
|
setinfo(P_FTOGEM, "Rainbow Flower", "Transforms all flowers on the level into gems, and turns itself into an extra-long stream of gems.", "flowertogem.png");
|
|
setinfo(P_BOMB, "Bomb", "Explodes and kills all monsters on the level.", "bomb.png");
|
|
setinfo(P_SHIELD, "Shield", "Temporary invulnerability", "shield.png");
|
|
setinfo(P_RINGSILVER, "Silver Ring", "Until the end of the level, you gain points for jumping.", "ring-silver.png");
|
|
setinfo(P_RINGGOLD, "Gold Ring", "Until the end of the level, you gain points for walking.", "ring-gold.png");
|
|
setinfo(P_CLOCK, "Stopwatch", "Stops time for 10 seconds", "clock.png");
|
|
setinfo(P_SNOWMAN, "Snowman", "Freezes the level, turning everything to ice - touch a monster to shatter it!", "snowman.png");
|
|
setinfo(P_SPRAY, "Fly Spray", "Sickens all monsters, causing them to slow down to half speed.","spray.png");
|
|
setinfo(P_CANNONPOWERUP, "Fusion Cannon", "A powerful weapon which will shoot out laser beams in all directions!", "cannonpowerup.png");
|
|
setinfo(P_PHONE, "Phone", "Calls in your helper cloud and immediately skips two levels (but note that this cannot skip a boss level).", "phone.png");
|
|
setinfo(P_HONEY, "Honey", "Coats your net in a layer of sticky honey, allowing it to pick up fruits from afar.", "honey.png");
|
|
setinfo(P_STARPOWERUP, "Shuriken", "Shoots deadly razor blades in all directions.", "star.png");
|
|
setinfo(P_LIFE, "Life", "Awards the player an extra life.", "extralife.png");
|
|
setinfo(P_UFO, "UFO", "Calls in a powerful meteor strike!", "ufo.png");
|
|
setinfo(P_TAP, "Tap", "The leaky tap will flood the level with water for 20 seconds, allowing you to access hard to reach areas.", "tap.png");
|
|
setinfo(P_ACCORDION, "Accordion", "Makes your nets enormous", "accordion.png");
|
|
setinfo(P_GUN, "Gunner", "Temporarily equips you with a super powerful machine gun!", "gunner.png");
|
|
setinfo(P_GNOME, "Garden Gnome", "This tricky little gnome has rigged explosive devices to all flowers on the level - when collected he will detonate them!", "gnome.png");
|
|
setinfo(P_WAND, "Magic Wand", "A wave of the magic wand will magically polymorph all monsters into weaker ones. Anything which can't become weaker will be instantly destroyed!", "wand.png");
|
|
setinfo(P_WHISTLE, "Whistle", "Produces an extremely loud, shrill whistling noise which wakes the black cloud of doom! In its angered state, the black cloud will slaughter both friend and foe alike.", "whistle.png");
|
|
setinfo(P_CANDLE, "Candle", "Once collected, the candle will cause all enemy corpses to burst into flames, igniting any other enemy which they touch.", "candle.png");
|
|
setinfo(P_ANCHOR, "Anchor", "The extremely heavy anchor will weigh down enemies, preventing them from jumping or flying.", "anchor.png");
|
|
setinfo(P_MAGNET, "Magnet", "Collecting this powerup will align the magnetic forces of the earth in your favour, attracting all nearby fruits towards you.", "magnet.png");
|
|
setinfo(P_BADMAGNET, "Red Skull", "This skull curses you and will repel fruits away from you, denying you access to them!", "badmagnet.png");
|
|
setinfo(P_JETPACK, "Jetpack", "For the remainder of the current level, the jetpack's thrust will add to your jumping ability!", "jetpack.png");
|
|
setinfo(P_UMBRELLA, "Umbrella", "Slows your descent, giving you more time to contemplate your rat eradication quest. Activate this useful item by holding UP while falling.", "umbrella.png");
|
|
setinfo(P_CAMERA, "Camera", "Creates a bright flash of light, blinding all enemies.", "camera.png");
|
|
setinfo(P_ZAPPOWERUP, "Bug Zapper", "Zaps nearby enemies with miniature bolts of lightning", "zapper.png");
|
|
setinfo(P_SKULL, "Green Skull", "Avoid these at all costs! The green skull will shrink your net to miniscule proportions for the remainder of the level.", "skull.png");
|
|
setinfo(P_CLOVER, "4-Leaf Clover", "Increases your luck...", "clover.png");
|
|
|
|
setinfo(P_RANDOM, "Random", "Gives you a random effect...", "random.png");
|
|
|
|
setinfo(P_PLAYER, "Mr. Dwarf", "Mr. Dwarf is currently highly disgruntled due to repeated burglaries of his hard-earned dinner. After one theft too many, he is now out for revenge! When encased in his shining suit of golden armour, Mr. Dwarf is bestowed with incredible powers of endurance, and is able to withstand any earthly threat. Once once, though.", "pdwarf.png");
|
|
setinfo(P_PLAYER2, "Mrs. Dwarf", "Mrs. Dwarf, being the loyal partner that she is, has become equally aggrieved by the constant re-appropriation of culinary treats and has joined Mr. Dwarf on his quest to end the rat menace forever. Her more feminine armour no less effective, just slightly more visually appealing with its convenient openings for lipstick and hair!", "p2dwarf.png");
|
|
setinfo(P_ARMOUR, "Armoured Mr. Dwarf", "", "armor.png");
|
|
setinfo(P_ARMOUR2, "Armoured Mrs. Dwarf", "", "armor2.png");
|
|
|
|
setinfo(P_RAT, "Rat", "The weakest of the monsters, the rat will simply walk back and forth waiting to be caught. Beware an angry rat though, as it will try to fall or jump in order to catch you!", "rat.png");
|
|
setinfo(P_BEE, "Bee", "Bees, while still relatively weak, gain an advantage over rats in that they are able to fly. They move in a simple diagonal pattern, changing direction when they get near a wall or spikes. Bees will speed up when angry.", "newbee.png");
|
|
setinfo(P_FISH, "Pirahna", "These fish at at home in the water and unhampered by slowness while swimming.", "fish.png");
|
|
|
|
setinfo(P_SPIDER, "Redback", "Redback spiders will lurk quietly on the ceiling, crawling back and forth. If they notice a player nearby however they will swiftly pounce down onto their prey!", "spider.png");
|
|
setinfo(P_WSPIDER, "Whitetail", "Whitetail spiders are more intelligent than other monsters - they are aware of nearby players and will use the landscape to track them down!", "whitespider.png");
|
|
setinfo(P_MOTH, "Moth", "The moth moves in straight lines until it hits a wall. Although simplistic in their movement, moths have the ability to fire a burst of hypno-rays to take out an unwary player!", "moth.png");
|
|
|
|
setinfo(P_FROG, "Frog", "Green frogs will continually bounce around, making them more difficult to catch. They are also excellent swimmers.", "frog.png");
|
|
|
|
setinfo(P_ANT1, "Worker Ant", "Worker ants are relatively easy to avoid, but when fed will quickly grow into more dangerous soldier ants.", "ant1.png");
|
|
setinfo(P_ANT2, "Soldier Ant", "Soldiers move faster and are more intelligent than their worker siblings. In addition, with just a little food they will become queens.", "ant2.png");
|
|
setinfo(P_ANT3, "Queen Ant", "After an ant has eaten enough, they become a Queen. Queens are just as fast as soldiers and can also breath fire. Furthermore, they are only one meal away from spawning additional ants!", "ant3.png");
|
|
|
|
setinfo(P_SNAKE, "Snake", "The snake moves in a similar fashion to the rat with one important exception - upon seeing a player they will spit a glob of deadly venom at them!", "snake.png");
|
|
setinfo(P_FLY, "Fly", "Annoying pests at the best of times, flies pose additional danger to dwarves. They fly around more erratically than bees and after landing can scurry quickly back and forth.", "fly.png");
|
|
|
|
|
|
setinfo(P_TICK, "Tick", "The tick is small but intelligent. Even in its regular placid state it will move in the same manner as an angry rat. Because of their small size, they are also difficult to target with a slam!", "tick.png");
|
|
setinfo(P_PLANT, "Plant", "Evil venus fly trap plants will lie in wait and devour any player foolish enough to wander into their clutches.", "plant.png");
|
|
|
|
setinfo(P_BLACKCLOUD, "Cloud of Doom", "This unkillable cloud will appear if you spend too much time on one level. Beware, as the only way to defeat the cloud of doom is to complete the level before it grows too large to handle!", "cloud.png");
|
|
|
|
setinfo(P_KINGRAT, "King Rat", "This mighty creature is the ruler of the rats, and impervious to the player's net. It can only be harmed by slamming another monster into it! King Rat will roam the level searching for a player, and upon spotting them will charge at high speed.", "kingrat.png");
|
|
|
|
setinfo(P_KINGSNAIL, "King Snail", "The absolute ruler of the snail kingdom is far too large and heavy to catch in a net. In addition, its shell provides protection against all attacks, leaving only its head vulnerable. While King Snail is too proud to chase down enemies itself, it can use its snail army to destroy its foes.", "kingsnail.png");
|
|
|
|
setinfo(P_KINGFLY, "King Fly", "King Fly is quite literally the lord of the flies. Far from the timid garden-variety fly, King Fly will roam around with its entourage of underlings in tow, running down anything in its path!", "kingfly.png");
|
|
setinfo(P_KINGANT, "King Ant", "All ants bow down to King Ant, the ultimate ant overlord. King Ant is an enormous fire ant, endlessly covered in flames and able to create ant sustenance from its body. Its flames are so intense that they can instantly melt through solid ice!", "kingant.png");
|
|
|
|
setinfo(P_SNAIL, "Snail", "Snails are slow moving but tough. When attacked normally they will not die, but simply lose their shell and become a slug. The safest way to take them out is to slam another monster into them, thus killing them instantly.", "snail.png");
|
|
setinfo(P_SLUG, "Slug", "Slugs are faster moving than snails and capable of launching themselves through the air at their prey!", "slug.png");
|
|
|
|
}
|
|
|
|
void setinfo(int id, char *name, char *desc, char *file) {
|
|
spriteinfo[id].name = strdup(name);
|
|
spriteinfo[id].desc = strdup(desc);
|
|
spriteinfo[id].file = strdup(file);
|
|
}
|
|
|
|
// dump html doco
|
|
void dumpinfo(void) {
|
|
int i;
|
|
int count;
|
|
// header
|
|
//printf("<html>\n");
|
|
//printf("<body bgcolor=\"#AAAAAA\">\n");
|
|
printf("<center><h2>Creatures</h2></center>\n");
|
|
printf("<table border=1>\n");
|
|
|
|
// players
|
|
printf("<tr bgcolor=\"#ffff00\"><th colspan=4>Players</th></tr>\n");
|
|
for (i = 0; i < MAXPTYPES; i++) {
|
|
switch (i) {
|
|
case P_PLAYER:
|
|
printf("<tr><td align=center><img src=\"img/%s\"><img src=\"img/%s\"><br>%s</td><td colspan=3>%s</td></tr>\n",
|
|
spriteinfo[i].file, spriteinfo[P_ARMOUR].file, spriteinfo[i].name,spriteinfo[i].desc);
|
|
break;
|
|
case P_PLAYER2:
|
|
printf("<tr><td align=center><img src=\"img/%s\"><img src=\"img/%s\"><br>%s</td><td colspan=3>%s</td></tr>\n",
|
|
spriteinfo[i].file, spriteinfo[P_ARMOUR2].file, spriteinfo[i].name,spriteinfo[i].desc);
|
|
break;
|
|
}
|
|
}
|
|
// monsters
|
|
printf("<tr bgcolor=\"#ffff00\"><th colspan=4>Monsters</th></tr>\n");
|
|
/*
|
|
for (i = 0; i < MAXPTYPES; i++) {
|
|
if (ismonster(i) == MT_MONSTER) {
|
|
printf("<tr><td align=center><img src=\"img/%s\"><br>%s</td><td>%s</td></tr>\n",
|
|
spriteinfo[i].file, spriteinfo[i].name,spriteinfo[i].desc);
|
|
}
|
|
}
|
|
*/
|
|
count = 0;
|
|
for (i = 0; i < MAXPTYPES; i++) {
|
|
if (ismonster(i) == MT_MONSTER) {
|
|
if (count % 2 == 0) {
|
|
printf("<tr>");
|
|
}
|
|
|
|
printf("<td width=10%% align=center><img src=\"img/%s\">\n",
|
|
spriteinfo[i].file);
|
|
|
|
if (i == P_SNAKE) {
|
|
printf("<img src=\"img/spit.png\">");
|
|
} else if (i == P_ANT3) {
|
|
printf("<img src=\"img/fire1.png\">");
|
|
} else if (i == P_SPIDER) {
|
|
printf("<img src=\"img/newspiderfall.png\">");
|
|
} else if (i == P_WSPIDER) {
|
|
printf("<img src=\"img/whitespiderclimb.png\">");
|
|
} else if (i == P_MOTH) {
|
|
printf("<img src=\"img/mothfire.png\">");
|
|
}
|
|
|
|
printf("<br>%s</td><td>%s</td>\n",
|
|
spriteinfo[i].name,spriteinfo[i].desc);
|
|
if (count % 2 == 1) {
|
|
printf("</tr>");
|
|
}
|
|
count++;
|
|
}
|
|
|
|
}
|
|
if (count % 2 == 0) {
|
|
printf("</tr>");
|
|
} else {
|
|
printf("<td colspan=2> </td></tr>");
|
|
}
|
|
|
|
|
|
// bosses
|
|
printf("<tr bgcolor=\"#ffff00\"><th colspan=4>Bosses</th></tr>\n");
|
|
/*
|
|
for (i = 0; i < MAXPTYPES; i++) {
|
|
if (ismonster(i) == MT_BOSS) {
|
|
printf("<tr><td align=center><img src=\"img/%s\"><br>%s</td><td colspan=3>%s</td></tr>\n",
|
|
spriteinfo[i].file, spriteinfo[i].name,spriteinfo[i].desc);
|
|
}
|
|
}
|
|
*/
|
|
|
|
count = 0;
|
|
for (i = 0; i < MAXPTYPES; i++) {
|
|
if (ismonster(i) == MT_BOSS) {
|
|
if (count % 2 == 0) {
|
|
printf("<tr>");
|
|
}
|
|
|
|
printf("<td align=center><img src=\"img/%s\"><br>%s</td><td>%s</td>\n",
|
|
spriteinfo[i].file, spriteinfo[i].name,spriteinfo[i].desc);
|
|
|
|
|
|
if (count % 2 == 1) {
|
|
printf("</tr>");
|
|
}
|
|
count++;
|
|
}
|
|
|
|
}
|
|
if (count % 2 == 0) {
|
|
printf("</tr>");
|
|
} else {
|
|
printf("<td colspan=2> </td></tr>");
|
|
}
|
|
|
|
|
|
|
|
|
|
printf("</table>\n");
|
|
|
|
printf("<center><h2>Power-Ups</h2>\n");
|
|
printf("<table border=1>\n");
|
|
// fruits
|
|
printf("<tr bgcolor=\"#ffff00\"><th colspan=4>Fruits</th></tr>\n");
|
|
|
|
count = 0;
|
|
for (i = 0; i < MAXPTYPES; i++) {
|
|
if ((isfruit(i) == FT_FRUIT) && (i != P_DIAMOND)) {
|
|
if (count % 2 == 0) {
|
|
printf("<tr>");
|
|
}
|
|
printf("<td width=10%% align=center><img src=\"img/%s\"><br>%s</td><td width=40%%>Worth %d points.</td>\n",
|
|
spriteinfo[i].file, spriteinfo[i].name,getpoints(i));
|
|
if (count % 2 == 1) {
|
|
printf("</tr>");
|
|
}
|
|
count++;
|
|
}
|
|
|
|
}
|
|
|
|
for (i = 0; i < MAXPTYPES; i++) {
|
|
if ((isfruit(i) == FT_GEM)) {
|
|
if (count % 2 == 0) {
|
|
printf("<tr>");
|
|
}
|
|
printf("<td width=10%% align=center><img src=\"img/%s\"><br>%s</td><td width=40%%>Worth %d points.</td>\n",
|
|
spriteinfo[i].file, spriteinfo[i].name,getpoints(i));
|
|
if (count % 2 == 1) {
|
|
printf("</tr>");
|
|
}
|
|
count++;
|
|
}
|
|
|
|
}
|
|
|
|
printf("<td width=10%% align=center><img src=\"img/%s\"><br>%s</td><td width=40%%>Worth %d points.</td>\n",
|
|
spriteinfo[P_DIAMOND].file, spriteinfo[P_DIAMOND].name,getpoints(P_DIAMOND));
|
|
|
|
if (count % 2 == 1) {
|
|
printf("</tr>");
|
|
} else {
|
|
printf("<td colspan=2> </td></tr>");
|
|
}
|
|
|
|
|
|
|
|
// perm powerup
|
|
printf("<tr bgcolor=\"#ffff00\"><th colspan=4>Permenant Powerups</th></tr>\n");
|
|
count = 0;
|
|
for (i = 0; i < MAXPTYPES; i++) {
|
|
if (isfruit(i) == FT_PERM) {
|
|
if (count % 2 == 0) {
|
|
printf("<tr>");
|
|
}
|
|
printf("<td align=center><img src=\"img/%s\"><br>%s</td><td>%s</td>\n",
|
|
spriteinfo[i].file, spriteinfo[i].name,spriteinfo[i].desc);
|
|
if (count % 2 == 1) {
|
|
printf("</tr>");
|
|
}
|
|
count++;
|
|
}
|
|
}
|
|
if (count % 2 == 0) {
|
|
printf("<tr>");
|
|
}
|
|
// card
|
|
printf("<td align=center><img src=\"img/%s\"><br>%s</td><td>%s</td>\n",
|
|
spriteinfo[P_FIRSTCARD].file, spriteinfo[P_FIRSTCARD].name,spriteinfo[P_FIRSTCARD].desc);
|
|
if (count % 2 == 1) {
|
|
printf("</tr>");
|
|
} else {
|
|
printf("<td colspan=2> </td></tr>");
|
|
}
|
|
|
|
|
|
// temp powerup
|
|
printf("<tr bgcolor=\"#ffff00\"><th colspan=4>Temporary Powerups</th></tr>\n");
|
|
count = 0;
|
|
for (i = 0; i < MAXPTYPES; i++) {
|
|
if ((isfruit(i) == FT_TEMP) && (i != P_RANDOM)) {
|
|
if (count % 2 == 0) {
|
|
printf("<tr>");
|
|
}
|
|
printf("<td align=center><img src=\"img/%s\"><br>%s</td><td>%s</td>\n",
|
|
|
|
spriteinfo[i].file, spriteinfo[i].name,spriteinfo[i].desc);
|
|
if (count % 2 == 1) {
|
|
printf("</tr>");
|
|
}
|
|
count++;
|
|
}
|
|
}
|
|
if (count % 2 == 0) {
|
|
printf("<tr>");
|
|
}
|
|
// random comes last
|
|
printf("<td align=center><font color=\"ff00ff\"><b><big>?</big></b></font><br>%s</td><td>%s</td>\n", spriteinfo[P_RANDOM].name,spriteinfo[P_RANDOM].desc);
|
|
if (count % 2 == 1) {
|
|
printf("</tr>");
|
|
} else {
|
|
printf("<td colspan=2> </td></tr>");
|
|
}
|
|
|
|
// super powerup
|
|
printf("<tr bgcolor=\"#ffff00\"><th colspan=4>Super Powerups</th></tr>\n");
|
|
count = 0;
|
|
for (i = 0; i < MAXPTYPES; i++) {
|
|
if (isfruit(i) == FT_SUPER) {
|
|
if (count % 2 == 0) {
|
|
printf("<tr>");
|
|
}
|
|
printf("<td align=center><img src=\"img/%s\"><br>%s</td><td>%s</td>\n",
|
|
spriteinfo[i].file, spriteinfo[i].name,spriteinfo[i].desc);
|
|
if (count % 2 == 1) {
|
|
printf("</tr>");
|
|
}
|
|
count++;
|
|
}
|
|
}
|
|
if (count % 2 == 1) {
|
|
printf("<td colspan=2> </td></tr>");
|
|
}
|
|
|
|
printf("</table>\n");
|
|
|
|
|
|
|
|
|
|
printf("</center>\n");
|
|
//printf("</body></html>\n");
|
|
}
|
|
|
|
void doblit(SDL_Surface *src, SDL_Surface *dst, SDL_Rect *dstarea) {
|
|
SDL_Rect srcarea;
|
|
if ((dstarea->y > 0) && (dstarea->y <= (480-src->h))) {
|
|
// completely onscreen
|
|
SDL_BlitSurface(src, NULL, dst, dstarea);
|
|
} else if (dstarea->y > (480-src->h)) {
|
|
// off the bottom
|
|
srcarea.x = 0;
|
|
srcarea.y = 0;
|
|
srcarea.w = src->w;
|
|
srcarea.h = 480 - dstarea->y;
|
|
if (srcarea.h > 0) {
|
|
SDL_BlitSurface(src, &srcarea, dst, dstarea);
|
|
}
|
|
} else if (dstarea->y < 0) {
|
|
// off the top
|
|
srcarea.x = 0;
|
|
srcarea.w = src->w;
|
|
|
|
srcarea.y = - dstarea->y;
|
|
srcarea.h = src->h - srcarea.y;
|
|
if (srcarea.y > 0) {
|
|
dstarea->y = 0;
|
|
dstarea->h = srcarea.h;
|
|
dstarea->w = srcarea.w;
|
|
SDL_BlitSurface(src, &srcarea, dst, dstarea);
|
|
}
|
|
}
|
|
}
|
|
|
|
char *getcardletter(int num) {
|
|
switch (num) {
|
|
case 0:
|
|
return "X";
|
|
case 1:
|
|
return "A";
|
|
case 2:
|
|
return "2";
|
|
case 3:
|
|
return "3";
|
|
case 4:
|
|
return "4";
|
|
case 5:
|
|
return "5";
|
|
case 6:
|
|
return "6";
|
|
case 7:
|
|
return "7";
|
|
case 8:
|
|
return "8";
|
|
case 9:
|
|
return "9";
|
|
case 10:
|
|
return "10";
|
|
case 11:
|
|
return "J";
|
|
case 12:
|
|
return "Q";
|
|
case 13:
|
|
return "K";
|
|
}
|
|
return "?";
|
|
}
|
|
|
|
// returns a random card sprite id
|
|
int getrandomcard(void) {
|
|
int i;
|
|
int cardid;
|
|
int gotit;
|
|
//cardid = P_FIRSTCARD + (rand() % 52);
|
|
|
|
|
|
// TODO: possible infinite loop?
|
|
gotit = B_TRUE;
|
|
while (gotit) {
|
|
// give current card
|
|
cardid = deck[curcard];
|
|
// move to next card
|
|
curcard++;
|
|
if (curcard >= DECKSIZE) {
|
|
shufflecards();
|
|
curcard = 0;
|
|
}
|
|
// make sure the player doesn't have it!
|
|
gotit = B_FALSE;
|
|
if (player) {
|
|
for (i = 0; i < player->numcards; i++) {
|
|
if (player->card[i] == cardid) {
|
|
gotit = B_TRUE;
|
|
}
|
|
}
|
|
}
|
|
if (player2) {
|
|
for (i = 0; i < player2->numcards; i++) {
|
|
if (player2->card[i] == cardid) {
|
|
gotit = B_TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
// are we forcing it to be good?
|
|
if (forcegoodcard) {
|
|
if ((player && player->numcards > 0) || (player2 && player2->numcards > 0)) {
|
|
int okay = B_FALSE;
|
|
int csuit,cval;
|
|
if (player) {
|
|
for (i = 0; i < player->numcards; i++) {
|
|
cval = getcardvalue(player->card[i]);
|
|
csuit = getcardsuit(player->card[i]);
|
|
if (csuit == getcardsuit(cardid)) okay = B_TRUE;
|
|
if (cval == (getcardvalue(cardid))) okay = B_TRUE;
|
|
if (cval == (getcardvalue(cardid)+1)) okay = B_TRUE;
|
|
if (cval == (getcardvalue(cardid)-1)) okay = B_TRUE;
|
|
}
|
|
}
|
|
if (player2 && !okay) {
|
|
for (i = 0; i < player2->numcards; i++) {
|
|
cval = getcardvalue(player2->card[i]);
|
|
csuit = getcardsuit(player2->card[i]);
|
|
if (csuit == getcardsuit(cardid)) okay = B_TRUE;
|
|
if (cval == (getcardvalue(cardid))) okay = B_TRUE;
|
|
if (cval == (getcardvalue(cardid)+1)) okay = B_TRUE;
|
|
if (cval == (getcardvalue(cardid)-1)) okay = B_TRUE;
|
|
}
|
|
}
|
|
// if not a good card, go to next one
|
|
if (!okay) {
|
|
gotit = B_TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return cardid;
|
|
}
|
|
|
|
char *getcardname(int id) {
|
|
switch (id) {
|
|
case P_CARDH1:
|
|
return "Ace of Hearts";
|
|
case P_CARDH2:
|
|
return "Two of Hearts";
|
|
case P_CARDH3:
|
|
return "Three of Hearts";
|
|
case P_CARDH4:
|
|
return "Four of Hearts";
|
|
case P_CARDH5:
|
|
return "Five of Hearts";
|
|
case P_CARDH6:
|
|
return "Six of Hearts";
|
|
case P_CARDH7:
|
|
return "Seven of Hearts";
|
|
case P_CARDH8:
|
|
return "Eight of Hearts";
|
|
case P_CARDH9:
|
|
return "Nine of Hearts";
|
|
case P_CARDH10:
|
|
return "Ten of Hearts";
|
|
case P_CARDHJ:
|
|
return "Jack of Hearts";
|
|
case P_CARDHQ:
|
|
return "Queen of Hearts";
|
|
case P_CARDHK:
|
|
return "King of Hearts";
|
|
case P_CARDD1:
|
|
return "Ace of Diamonds";
|
|
case P_CARDD2:
|
|
return "Two of Diamonds";
|
|
case P_CARDD3:
|
|
return "Three of Diamonds";
|
|
case P_CARDD4:
|
|
return "Four of Diamonds";
|
|
case P_CARDD5:
|
|
return "Five of Diamonds";
|
|
case P_CARDD6:
|
|
return "Six of Diamonds";
|
|
case P_CARDD7:
|
|
return "Seven of Diamonds";
|
|
case P_CARDD8:
|
|
return "Eight of Diamonds";
|
|
case P_CARDD9:
|
|
return "Nine of Diamonds";
|
|
case P_CARDD10:
|
|
return "Ten of Diamonds";
|
|
case P_CARDDJ:
|
|
return "Jack of Diamonds";
|
|
case P_CARDDQ:
|
|
return "Queen of Diamonds";
|
|
case P_CARDDK:
|
|
return "King of Diamonds";
|
|
case P_CARDS1:
|
|
return "Ace of Spades";
|
|
case P_CARDS2:
|
|
return "Two of Spades";
|
|
case P_CARDS3:
|
|
return "Three of Spades";
|
|
case P_CARDS4:
|
|
return "Four of Spades";
|
|
case P_CARDS5:
|
|
return "Five of Spades";
|
|
case P_CARDS6:
|
|
return "Six of Spades";
|
|
case P_CARDS7:
|
|
return "Seven of Spades";
|
|
case P_CARDS8:
|
|
return "Eight of Spades";
|
|
case P_CARDS9:
|
|
return "Nine of Spades";
|
|
case P_CARDS10:
|
|
return "Ten of Spades";
|
|
case P_CARDSJ:
|
|
return "Jack of Spades";
|
|
case P_CARDSQ:
|
|
return "Queen of Spades";
|
|
case P_CARDSK:
|
|
return "King of Spades";
|
|
case P_CARDC1:
|
|
return "Ace of Clubs";
|
|
case P_CARDC2:
|
|
return "Two of Clubs";
|
|
case P_CARDC3:
|
|
return "Three of Clubs";
|
|
case P_CARDC4:
|
|
return "Four of Clubs";
|
|
case P_CARDC5:
|
|
return "Five of Clubs";
|
|
case P_CARDC6:
|
|
return "Six of Clubs";
|
|
case P_CARDC7:
|
|
return "Seven of Clubs";
|
|
case P_CARDC8:
|
|
return "Eight of Clubs";
|
|
case P_CARDC9:
|
|
return "Nine of Clubs";
|
|
case P_CARDC10:
|
|
return "Ten of Clubs";
|
|
case P_CARDCJ:
|
|
return "Jack of Clubs";
|
|
case P_CARDCQ:
|
|
return "Queen of Clubs";
|
|
case P_CARDCK:
|
|
return "King of Clubs";
|
|
}
|
|
return "Unknown Card";
|
|
}
|
|
|
|
void shufflecards(void) {
|
|
int ii,i,n,thiscard;
|
|
|
|
// generate initial list of cards
|
|
for (i = 0; i < DECKSIZE; i++) {
|
|
deck[i] = P_FIRSTCARD + i;
|
|
}
|
|
|
|
// shuffle them
|
|
for (ii = 0; ii < SHUFFLEQUALITY; ii++) {
|
|
for (i = 0; i < DECKSIZE; i++) {
|
|
// 50% chance of moving to the end
|
|
if (rand() % 2) {
|
|
thiscard = deck[i];
|
|
for (n = i; n < (DECKSIZE-1); n++) {
|
|
deck[n] = deck[n+1];
|
|
}
|
|
deck[DECKSIZE-1] = thiscard;
|
|
}
|
|
}
|
|
}
|
|
|
|
curcard = 0;
|
|
}
|
|
|
|
int getworld(int lev) {
|
|
int wnum;
|
|
wnum = ((lev-1)/20)+1;
|
|
return wnum;
|
|
}
|
|
|
|
int getlevel(int lev) {
|
|
int wnum;
|
|
wnum = (lev%20);
|
|
if (wnum == 0) return 20;
|
|
return wnum;
|
|
}
|
|
|
|
|
|
int getcardsuit(int cardid) {
|
|
if ((cardid >= P_FIRSTHEART) && (cardid <= (P_FIRSTHEART + 12))) {
|
|
return CS_HEART;
|
|
} else if ((cardid >= P_FIRSTDIAMOND) && (cardid <= (P_FIRSTDIAMOND + 12))) {
|
|
return CS_DIAMOND;
|
|
} else if ((cardid >= P_FIRSTSPADE) && (cardid <= (P_FIRSTSPADE + 12))) {
|
|
return CS_SPADE;
|
|
} else {
|
|
return CS_CLUB;
|
|
}
|
|
}
|
|
int getcardvalue(int cardid) {
|
|
int points;
|
|
points = cardid;
|
|
switch (getcardsuit(cardid)) {
|
|
case CS_HEART:
|
|
points -= P_FIRSTHEART;
|
|
break;
|
|
case CS_DIAMOND:
|
|
points -= P_FIRSTDIAMOND;
|
|
break;
|
|
case CS_SPADE:
|
|
points -= P_FIRSTSPADE;
|
|
break;
|
|
case CS_CLUB:
|
|
default:
|
|
points -= P_FIRSTCLUB;
|
|
break;
|
|
}
|
|
|
|
return (points+1);
|
|
}
|
|
|
|
// draw player, and wings if required
|
|
void drawplayer(sprite_t *s, SDL_Rect *where) {
|
|
#ifndef __EDITOR
|
|
SDL_Rect wingarea;
|
|
int wingframe;
|
|
int drawwings;
|
|
#endif
|
|
|
|
#ifndef __EDITOR
|
|
|
|
if (s->powerup == PW_GUNNER) {
|
|
SDL_Color *ccol;
|
|
SDL_Color purple;
|
|
purple.r = 255;
|
|
purple.g = 0;
|
|
purple.b = 255;
|
|
// just draw crosshairs
|
|
if (s == player) {
|
|
ccol = &red;
|
|
} else {
|
|
ccol = &purple;
|
|
}
|
|
// box
|
|
drawbox16(screen, s->x-(TILEW/2),s->y-(TILEH/2),s->x+(TILEW/2),s->y+(TILEH/2), ccol, NULL);
|
|
// littlebox
|
|
drawbox16(screen, s->x-1,s->y-1,s->x+1,s->y+1, ccol, NULL);
|
|
// lines
|
|
drawline(screen, s->x, 0, s->x, s->y-(TILEH/2), *ccol); // top
|
|
drawline(screen, s->x, s->y+(TILEH/2), s->x, 480-1, *ccol); // bottom
|
|
drawline(screen, 0, s->y, s->x-(TILEW/2), s->y, *ccol); // left
|
|
drawline(screen, s->x+(TILEW/2), s->y, 640-1, s->y, *ccol); // right
|
|
return;
|
|
}
|
|
|
|
// only draw wings in certain states
|
|
switch (levelcomplete) {
|
|
case LV_NEXTLEV:
|
|
case LV_CLOUDLOOP:
|
|
drawwings = B_FALSE;
|
|
break;
|
|
default:
|
|
drawwings = B_TRUE;
|
|
break;
|
|
}
|
|
|
|
|
|
if ((s->doublejump) && (levelcomplete != LV_NEXTLEV)) {
|
|
// draw wings behind the sprite
|
|
if (s->jumping || s->falling) {
|
|
// flapping wings - freeze while showing help text
|
|
if (((timer/12) % 2 == 0) || (levelcomplete == LV_HELPFREEZE)) {
|
|
wingframe = 1;
|
|
} else {
|
|
wingframe = 2;
|
|
}
|
|
} else {
|
|
// still wings
|
|
wingframe = 0;
|
|
}
|
|
|
|
wingarea.x = s->x - (imageset[P_WINGRIGHT].img[wingframe]->w/2);
|
|
wingarea.y = s->y - (imageset[P_WINGRIGHT].img[wingframe]->h);
|
|
if (wingframe == 0) { // still
|
|
wingarea.x += (4*s->dir);
|
|
wingarea.y += 2;
|
|
} else if ((wingframe >= 1) && (wingframe <= 2)) { // flapping
|
|
wingarea.x += (11*s->dir);
|
|
wingarea.y -= 9;
|
|
}
|
|
|
|
if (s == player2) {
|
|
wingarea.x -= (4 * s->dir);
|
|
}
|
|
|
|
// when climbing, show "left" wing twice instead
|
|
// when swimming, only show left wing
|
|
if (!s->climbing && !s->swimming) {
|
|
if (s->dir == -1) wingframe += MAXFRAMES;
|
|
doblit(imageset[P_WINGRIGHT].img[wingframe], screen, &wingarea);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
if ((levelcomplete == LV_CLOUDLOOP) || (levelcomplete == LV_NEXTLEV)) {
|
|
s->img = imageset[s->id].img[F_SHOOT];
|
|
}
|
|
|
|
// draw the sprite
|
|
doblit(s->img, screen, where);
|
|
|
|
#ifndef __EDITOR
|
|
if ((s->doublejump) && (levelcomplete != LV_NEXTLEV)) {
|
|
// draw wings in front of the sprite
|
|
if (s->swimming) {
|
|
wingframe = 3;
|
|
} else if (s->jumping || s->falling) {
|
|
// flapping wings
|
|
if ((timer/12) % 2 == 0) {
|
|
wingframe = 1;
|
|
} else {
|
|
wingframe = 2;
|
|
}
|
|
} else {
|
|
// still wings
|
|
wingframe = 0;
|
|
}
|
|
|
|
wingarea.x = s->x - (imageset[P_WINGLEFT].img[wingframe]->w/2);
|
|
wingarea.y = s->y - (imageset[P_WINGLEFT].img[wingframe]->h);
|
|
if (wingframe == 0) { // still
|
|
if (s->climbing) {
|
|
wingarea.x -= 4;
|
|
wingarea.y += 2;
|
|
} else {
|
|
wingarea.x -= (6*s->dir);
|
|
wingarea.y += 2;
|
|
}
|
|
} else if ((wingframe >= 1) && (wingframe <= 2)) { // flapping
|
|
wingarea.x -= (11*s->dir);
|
|
wingarea.y -= 9;
|
|
} else if (wingframe == 3) {
|
|
wingarea.y -= 9;
|
|
wingarea.x -= (6*s->dir);
|
|
}
|
|
|
|
|
|
if (s->dir == -1) wingframe += MAXFRAMES;
|
|
doblit(imageset[P_WINGLEFT].img[wingframe], screen, &wingarea);
|
|
|
|
if (s->climbing) {
|
|
// draw the other wing
|
|
wingarea.x += 8;
|
|
// reverse it
|
|
if (s->dir == -1) wingframe -= MAXFRAMES;
|
|
else wingframe += MAXFRAMES;
|
|
doblit(imageset[P_WINGLEFT].img[wingframe], screen, &wingarea);
|
|
}
|
|
}
|
|
|
|
|
|
// draw umbrella
|
|
if (s->umbrella && s->umbrellaup) {
|
|
if ((levelcomplete != LV_CLOUD) && (levelcomplete != LV_CLOUDLOOP)) {
|
|
if (!s->swimming && !s->climbing) {
|
|
SDL_Rect umarea;
|
|
if (s->netting) {
|
|
if (s->dir == D_RIGHT) {
|
|
umarea.x = s->x - 11 - 10;
|
|
} else {
|
|
umarea.x = s->x - 11 + 10;
|
|
}
|
|
umarea.y = s->y - s->img->h - 2;
|
|
} else if (s->falling) {
|
|
if (s->dir == D_RIGHT) {
|
|
umarea.x = s->x - 11 - 8;
|
|
} else {
|
|
umarea.x = s->x - 11 + 8;
|
|
}
|
|
umarea.y = s->y - s->img->h - 9;
|
|
} else {
|
|
umarea.x = s->x - 11;
|
|
umarea.y = s->y - s->img->h - 2;
|
|
}
|
|
doblit(imageset[P_BIGUMBRELLA].img[F_WALK1], screen, &umarea);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
void resethurryup(level_t *lev) {
|
|
nexthurryup = gtime + lev->hurryuptime;
|
|
if (gamemode == GM_EASY) {
|
|
nexthurryup += 15;
|
|
}
|
|
}
|
|
|
|
|
|
int isplayer(sprite_t *s) {
|
|
if (player && (s == player)) return B_TRUE;
|
|
if (player2 && (s == player2)) return B_TRUE;
|
|
return B_FALSE;
|
|
}
|
|
|
|
int playersalive(void) {
|
|
// you don't count as a "player" if you are out of lives
|
|
if (player && player->dead && player->lives > 0) return B_FALSE;
|
|
if (player2 && player2->dead && player2->lives > 0) return B_FALSE;
|
|
return B_TRUE;
|
|
}
|
|
|
|
int getnumplayers(void) {
|
|
int num = 0;
|
|
if (player) num++;
|
|
if (player2) num++;
|
|
|
|
return num;
|
|
}
|