ratcatcher/shared.c

5000 lines
130 KiB
C
Raw Permalink Normal View History

#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>
2016-07-24 16:27:15 +10:00
#ifdef OPENGL
#include <SDL_opengl.h>
#endif
#include "defs.h"
#include "globals.h"
#include "shared.h"
#ifndef __EDITOR
extern int fps;
extern int nfadingtiles;
extern SDL_Surface *temptilesurf;
#endif
2016-07-24 16:27:15 +10:00
#ifdef OPENGL
extern SDL_Surface *realscreen;
GLuint tex = -1; // texture which is created based on realscreen.
float texw = 0,texh = 0;
GLint sampleBuffers, samples;
#endif
void blittoscreen(void) {
GLfloat texcoords[8];
GLfloat vertices[8];
// clear screen first
glClearColor( 0, 0, 0, 1.0);
glClear( GL_COLOR_BUFFER_BIT );
// Bind the texture to which subsequent calls refer to
glBindTexture( GL_TEXTURE_2D, tex );
// translate to move to specified spot
//
glLoadIdentity();
glRotatef(0, 1.0, 0, 0);
glTranslatef( texw/2, texh/2, 0);
texcoords[0] = 0; texcoords[1] = 0;
texcoords[2] = 0; texcoords[3] = 1.0;
texcoords[4] = 1.0; texcoords[5] = 1.0;
texcoords[6] = 1.0; texcoords[7] = 0;
vertices[0] = -texw/2; vertices[1] = -texh/2;
vertices[2] = -texw/2; vertices[3] = texh/2;
vertices[4] = texw/2; vertices[5] = texh/2;
vertices[6] = texw/2; vertices[7] = -texh/2;
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glLoadIdentity();
// unbind
glBindTexture( GL_TEXTURE_2D, 0);
// override
//glClearColor( 0, 0, 1.0, 1.0);
//glClear( GL_COLOR_BUFFER_BIT );
SDL_GL_SwapBuffers();
}
void gengl(SDL_Surface *surf) {
int ncol;
GLenum texform;
ncol = surf->format->BytesPerPixel;
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE);
// del old texture
glDeleteTextures( 1, &tex );
// Have OpenGL generate a texture object handle for us
glGenTextures( 1, &tex );
// Bind the texture object
glBindTexture( GL_TEXTURE_2D, tex );
// Set the texture's stretching properties
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
// remember w/h
texw = surf->w;
texh = surf->h;
ncol = 4;
texform = GL_RGBA;
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, texw, texh, 0, texform, GL_UNSIGNED_BYTE, surf->pixels );
}
2008-11-19 09:56:55 +11:00
int loadlevel(int lnum, int wantmonsters) {
FILE *f;
int x,y;
int xx,yy;
char buf[BUFLEN];
char buf2[BUFLEN];
char filename[BUFLEN];
2008-10-10 08:04:41 +11:00
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;
2008-09-27 20:50:19 +10:00
int numenemies = 0;
2008-11-19 09:56:55 +11:00
printf("Loading level %d-%d (seq %d) %s...",getworld(lnum), getlevel(lnum), lnum,levelentry[lnum].filename);
2008-11-21 11:14:26 +11:00
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;
}
2008-10-21 10:17:43 +11:00
if (!level) {
level = malloc(sizeof(level_t));
level->animtiles = NULL;
level->l3tiles = NULL;
2008-10-21 10:17:43 +11:00
}
strncpy(level->filename, levelentry[lnum].filename, BUFLEN);
/* 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;
2008-11-23 18:54:06 +11:00
} 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);
}
}
for (xx = 0; xx < LEVELW; xx++) {
for (yy = 0; yy < LEVELH; yy++) {
level->tilewalkvanish[yy*LEVELW+xx] = -1;
}
}
#ifndef __EDITOR
nfadingtiles = 0;
#endif
/* 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) {
2008-12-21 12:17:30 +11:00
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);
2008-12-21 12:17:30 +11:00
ts = IMG_Load(tempfile);
if (!ts) {
printf("Cannot load background file: %s\n", tempfile);
// default to forest
2008-10-10 08:04:41 +11:00
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 {
2008-12-21 12:17:30 +11:00
SDL_Surface *ts;
// default to forest
if (levelbg) SDL_FreeSurface(levelbg);
2008-10-10 08:04:41 +11:00
sprintf(tempfile, "%s/backgrounds/forest.png",datadir);
2008-12-21 12:17:30 +11:00
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
2008-11-06 20:15:09 +11:00
// 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;
2008-11-06 20:15:09 +11:00
// 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;
2008-09-27 20:50:19 +10:00
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);
}
2008-09-27 20:50:19 +10:00
/* 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 && *p != '\n') {
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 (level->tilewalkvanish[y*LEVELW+x] != -1) {
printf("tilevanish %d,%d = %d\n",x,y,level->tilewalkvanish[y*LEVELW+x]);
}
// 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) {
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
int numframes;
level->map2[yy*LEVELW+xx] = tid;
// animated l2
numframes = gettileframecount(tid);
if (numframes == 1) {
// not animated
// don't clear this, in case l1 is animated
//level->tileframe[y*LEVELW+x] = 0;
} else {
tiletype_t *thistile;
// animated
thistile = gettile(tid);
if (thistile->animsync) {
level->tileframe[yy*LEVELW+xx] = 0;
} else {
level->tileframe[yy*LEVELW+xx] = rand() % numframes;
}
tempanim[numanim] = yy*LEVELW+xx;
numanim++;
}
} 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);
}
2008-10-28 07:22:33 +11:00
}
// 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 */
2008-10-10 10:49:43 +11:00
if (wantmonsters) {
for (i = 0; i < level->nummonsters; i++) {
char name[MIDBUFLEN];
int delay;
2008-10-10 10:49:43 +11:00
if (level->initm[i].id == P_HELP) {
// is help disabled?
#ifndef __EDITOR
if (showhelp == B_FALSE ) continue;
#endif
2008-10-10 10:49:43 +11:00
strncpy(name, level->initm[i].help, MIDBUFLEN);
} else {
sprintf(name, "Monster-%d",i);
}
2008-10-10 10:49:43 +11:00
if (ismonster(level->initm[i].id)) {
delay = 20;
} else {
delay = 0;
}
2008-11-06 20:15:09 +11:00
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;
2008-11-06 20:15:09 +11:00
} else {
int thisid;
thisid = level->initm[i].id;
2008-11-06 20:33:54 +11:00
#ifdef __EDITOR
addsprite(thisid, level->initm[i].startx, level->initm[i].starty, name );
2008-11-06 20:33:54 +11:00
#else
if (forcegold && isfruit(level->initm[i].id)) {
thisid = P_GOLDBAR;
}
puffin(thisid, level->initm[i].startx, level->initm[i].starty, name, delay );
2008-10-10 10:49:43 +11:00
#endif
2008-11-06 20:33:54 +11:00
}
2008-10-10 10:49:43 +11:00
}
}
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 = PLAYERFAST;
} else {
s->speed = PLAYERSLOW;
}
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) {
2008-11-05 08:07:52 +11:00
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;
}
2008-11-25 12:00:57 +11:00
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 = DEFAULTSPEED;
}
s->hasmask = B_FALSE;
s->armour = B_FALSE;
s->netsticky = B_FALSE;
s->doublejump = B_FALSE;
2008-11-25 12:00:57 +11:00
s->umbrella = B_FALSE;
s->netbig = B_FALSE;
s->netmax = 1;
}
2008-10-15 06:36:51 +11:00
s->doublejumpready = B_FALSE;
s->allocimg = B_FALSE;
2008-10-15 06:36:51 +11:00
s->frame = 0;
2008-11-06 20:15:09 +11:00
s->onplatform = NULL;
2008-11-21 11:14:26 +11:00
s->antigrav = B_FALSE;
s->hasbell = B_FALSE;
s->gemboost = 1;
2008-11-25 12:00:57 +11:00
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;
2008-11-06 20:15:09 +11:00
s->swimming = 0;
s->jumping = 0;
s->jumpspeed = 0;
s->jumpdir = 1;
s->useddoublejump = B_FALSE;
2008-11-25 15:05:53 +11:00
s->umbrellaup = B_FALSE;
2008-11-25 12:00:57 +11:00
2008-11-06 13:15:49 +11:00
if (s->id != P_RANDOM) {
// random gets timer1 set during addsprite()
s->timer1 = 0;
}
s->timer2 = 0;
s->timer3 = 0;
s->timer4 = 0;
s->timer5 = 0;
2008-12-22 14:03:48 +11:00
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;
2008-11-03 17:06:37 +11:00
} else if (s->id == P_KINGSNAIL) {
s->timer1 = KSS_WALK1;
s->timer2 = KS_WALKTIME;
s->timer3 = 0;
2008-11-25 12:41:15 +11:00
} else if (s->id == P_KINGFLY) {
s->timer1 = KFS_FLY1;
s->timer2 = KF_FLYTIME;
s->timer3 = 0;
2008-11-25 15:05:53 +11:00
s->xs = -99;
s->ys = -99;
2009-03-05 08:22:28 +11:00
} else if (s->id == P_KINGANT) {
s->timer1 = KAS_WALK1;
s->timer2 = KA_WALKTIME;
s->timer3 = KA_SHOOTTIME;
} else if (s->id == P_KINGCAT) {
s->timer1 = KCS_WALK; // state
s->timer2 = 0; // timer between states
s->timer3 = 0; // selected spell
s->timer4 = 0; // spell timer
s->timer5 = 0; // used to control teleporting every 3 spells
s->newx = -1;
s->newy = -1;
2009-03-22 08:42:38 +11:00
} else if (s->id == P_BAT) {
s->timer1 = BS_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:
2008-11-25 15:05:53 +11:00
case P_KINGFLY:
2009-03-22 08:42:38 +11:00
case P_BAT:
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->caughtdelay = 0;
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;
2008-11-06 13:15:49 +11:00
// special case for random powerup
if (s->id == P_RANDOM) {
s->timer1 = randompowerup();
while (s->timer1 == P_RANDOM) {
// pick again
2008-11-06 13:15:49 +11:00
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);
2008-11-06 13:15:49 +11:00
} 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;
2008-11-06 20:15:09 +11:00
// 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)) {
int ftype;
ftype = isfruit(s->id);
if (ftype == FT_SUPER) {
// super powerups never time out.
s->doomcount = 0;
} else if (ftype) {
// random powerups stay for longer
if (!strcmp(s->name, "random_up")) {
s->doomcount = 900;
2009-03-06 09:40:02 +11:00
} else if (!strcmp(s->name, "goldcoin")) {
//s->doomcount = 1400;
// 30 seconds
s->doomcount = fps*30;
} else {
s->doomcount = 500;
}
}
}
#endif
2008-11-06 13:15:49 +11:00
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 ;
strcpy(imagefile, "");
/* 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->sticky = B_FALSE;
t->slippery = B_FALSE;
t->stopnet = B_FALSE;
t->walkvanish = -1;
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->killframe[i] = B_FALSE;
t->spikeframe[i] = B_FALSE;
}
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, "sticky") == buf) {
p = strtok(buf, " ");
p = strtok(NULL, " ");
t->sticky = atoi(p);
} else if (strstr(buf, "stopnet") == buf) {
p = strtok(buf, " ");
p = strtok(NULL, " ");
t->stopnet = atoi(p);
} else if (strstr(buf, "walkvanish") == buf) {
p = strtok(buf, " ");
p = strtok(NULL, " ");
t->walkvanish = atoi(p);
} else if (strstr(buf, "slippery") == buf) {
p = strtok(buf, " ");
p = strtok(NULL, " ");
t->slippery = 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) { // ! means 'killframe', ^ is 'spikeframe'
int frame;
/* strip newline */
buf[strlen(buf)-1] = '\0';
p = strtok(buf, " ");
// read all images
frame = 0;
p = strtok(NULL, " ");
while (p) {
if (frame >= MAXTILEFRAMES) {
printf("FATAL error - tile %s frame #%d is greater than MAXTILEFRAMES\n",t->name,frame);
}
if (t->img[frame]) {
printf("...already an img for frame #%d - freeing it.\n",frame);
SDL_FreeSurface(t->img[frame]);
t->img[frame] = NULL;
}
if (strstr(p, "x") && !strchr(p, '.')) { // ie. x10, x1, etc
if (frame == 0) {
printf("FATAL ERROR: first frame can't be a repeat.\n");
exit(1);
} else {
int n,repeatcount,baseframe;
// use previous one 'x' times
p++;
repeatcount = atoi(p);
baseframe = frame-1;
for (n = 0; n < repeatcount; n++) {
if (!strlen(imagefile)) {
printf("FATAL ERROR: no previous imagefile to repeat.\n");
exit(1);
}
t->img[frame] = IMG_Load(imagefile);
if (!t->img[frame]) {
printf("cannot load tile image file: '%s'\n",imagefile);
fclose(f);
return B_TRUE;
}
t->killframe[frame] = t->killframe[baseframe];
frame++;
}
}
} else {
// exclamation mark indicates this is a 'killframe' (ie. if you stand
// on this tile when it hits this frame, you die)
if (*p == '!') {
t->killframe[frame] = B_TRUE;
p++;
} else if (*p == '^') {
t->spikeframe[frame] = B_TRUE;
p++;
}
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));
frame++;
}
p = strtok(NULL, " ");
}
t->numframes = frame;
// default animation speed
if ((t->numframes > 1) && (t->animspeed = 0)) {
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;
2008-11-17 13:44:44 +11:00
SDL_Surface *origi;
SDL_Rect redarea,temparea;
int x,y;
SDL_Color tempcol;
2008-10-10 08:04:41 +11:00
char tempfile[BUFLEN];
sprintf(tempfile, "%s/sprites/gravestone.png",datadir);
grave = IMG_Load(tempfile);
2008-10-10 08:04:41 +11:00
sprintf(tempfile, "%s/sprites/dwarfhead.png",datadir);
head = IMG_Load(tempfile);
2008-10-19 08:46:55 +11:00
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);
2008-10-10 08:04:41 +11:00
sprintf(tempfile, "%s/sprites/icecube.png",datadir);
icecube = IMG_Load(tempfile);
2008-10-10 08:04:41 +11:00
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);
2008-10-30 10:00:12 +11:00
// 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");
2008-11-21 20:19:13 +11:00
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");
2008-09-27 20:50:19 +10:00
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");
2008-11-21 20:19:13 +11:00
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;
2008-12-22 14:03:48 +11:00
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;
2009-03-11 10:16:08 +11:00
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;
2009-03-11 10:16:08 +11:00
2009-03-22 08:42:38 +11:00
loadspriteimage(P_BAT,F_WALK1, "sprites/bat.png");
loadspriteimage(P_BAT,F_JUMP, "sprites/bat1.png");
loadspriteimage(P_BAT,F_FALL, "sprites/bat1.png");
loadspriteimage(P_BAT,F_CAUGHT, "sprites/batcaught.png");
loadspriteimage(P_BAT,F_DEAD, "sprites/batdead.png");
/* next 3 are auto generated */
2009-03-22 08:42:38 +11:00
imageset[P_BAT].numimages = 8;
2009-03-11 10:16:08 +11:00
2008-10-13 12:33:41 +11:00
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");
2008-11-03 17:06:37 +11:00
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;
2008-11-25 12:41:15 +11:00
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;
2009-03-05 08:22:28 +11:00
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;
2008-11-25 12:41:15 +11:00
2008-11-03 17:06:37 +11:00
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;
loadspriteimage(P_KINGCAT,F_WALK1, "sprites/kingcat.png");
loadspriteimage(P_KINGCAT,F_JUMP, "sprites/kingcatwalk.png");
loadspriteimage(P_KINGCAT,F_FALL, "sprites/kingcatwalk.png");
loadspriteimage(P_KINGCAT,F_CAUGHT, "sprites/kingcatcaught.png");
loadspriteimage(P_KINGCAT,F_DEAD, "sprites/kingcatdead.png");
/* next 3 are auto generated */
loadspriteimage(P_KINGCAT,F_CLIMB1, "sprites/kingcatshoot.png");
loadspriteimage(P_KINGCAT,F_CLIMB2, "sprites/kingcatshoot2.png");
imageset[P_KINGCAT].numimages = 10;
/* 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;
2008-11-19 12:20:46 +11:00
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;
2008-11-19 12:42:40 +11:00
loadspriteimage(P_CAKE,F_WALK1, "sprites/cake.png");
imageset[P_CAKE].numimages = 1;
2008-11-19 12:20:46 +11:00
loadspriteimage(P_CHOCOLATE,F_WALK1, "sprites/chocolate.png");
imageset[P_CHOCOLATE].numimages = 1;
2008-11-22 22:02:19 +11:00
// 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;
2008-11-06 13:15:49 +11:00
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;
2008-09-28 13:43:03 +10:00
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;
2008-10-10 13:46:56 +11:00
loadspriteimage(P_STARPOWERUP,F_WALK1, "sprites/star.png");
imageset[P_STARPOWERUP].numimages = 1;
// Don't load image for P_MOVINGCARD or P_FIVECARDS
2008-10-10 13:46:56 +11:00
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;
2008-10-10 13:46:56 +11:00
loadspriteimage(P_LIFE,F_WALK1, "sprites/extralife.png");
2008-10-10 11:51:40 +11:00
imageset[P_LIFE].numimages = 1;
2008-10-10 10:49:43 +11:00
loadspriteimage(P_PHONE,F_WALK1, "sprites/phone.png");
imageset[P_PHONE].numimages = 1;
2008-10-10 11:51:40 +11:00
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;
2008-12-19 12:10:11 +11:00
loadspriteimage(P_RAYGUN,F_WALK1, "sprites/raygun.png");
imageset[P_RAYGUN].numimages = 1;
2009-01-30 14:30:38 +11:00
loadspriteimage(P_TOPHAT,F_WALK1, "sprites/tophat.png");
imageset[P_TOPHAT].numimages = 1;
2009-03-06 09:40:02 +11:00
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;
2008-10-30 10:00:12 +11:00
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;
2008-11-17 10:01:10 +11:00
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;
2008-11-17 13:44:44 +11:00
loadspriteimage(P_WHISTLE,F_WALK1, "sprites/whistle.png");
imageset[P_WHISTLE].numimages = 1;
2008-11-22 11:21:22 +11:00
loadspriteimage(P_ANCHOR,F_WALK1, "sprites/anchor.png");
imageset[P_ANCHOR].numimages = 1;
2008-11-25 12:00:57 +11:00
2008-11-22 11:21:22 +11:00
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");
2008-11-25 07:02:39 +11:00
imageset[P_JETPACK].numimages = 1;
2008-11-23 19:15:04 +11:00
2008-11-25 12:00:57 +11:00
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;
2008-11-25 12:00:57 +11:00
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;
2008-11-25 08:35:46 +11:00
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;
loadspriteimage(P_LEAF,F_WALK1, "sprites/leaf.png");
imageset[P_LEAF].numimages = 1;
loadspriteimage(P_FALLINGBRICK,F_WALK1, "sprites/fallingbrick.png");
imageset[P_FALLINGBRICK].numimages = 1;
loadspriteimage(P_BIGCHEST,F_WALK1, "sprites/bigchest.png");
imageset[P_BIGCHEST].numimages = 1;
2008-11-06 20:15:09 +11:00
// 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;
2008-11-05 08:07:52 +11:00
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;
2009-03-05 08:22:28 +11:00
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;
2008-10-15 06:36:51 +11:00
// 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[3];
2008-10-15 06:36:51 +11:00
// HEARTS
loadspriteimage(P_FIRSTHEART+i-1, F_WALK1, "sprites/cardh.png");
//sprintf(str, "%s",getcardletter(i));
strcpy(str, getcardletter(i));
2008-10-15 06:36:51 +11:00
letter = TTF_RenderText_Blended(cardfont, str, red );
2008-10-15 06:36:51 +11:00
area.x = CARDFONTX; area.y = CARDFONTY; area.w = 0; area.h = 0;
if (i == 10) area.x -= 3;
2008-10-15 06:36:51 +11:00
SDL_BlitSurface(letter, NULL, imageset[P_FIRSTHEART + i-1].img[F_WALK1], &area);
imageset[P_FIRSTHEART + i-1].numimages = 1;
SDL_FreeSurface(letter);
2008-10-15 06:36:51 +11:00
// DIAMONDS
loadspriteimage(P_FIRSTDIAMOND+i-1, F_WALK1, "sprites/cardd.png");
//sprintf(str, "%s",getcardletter(i));
strcpy(str, getcardletter(i));
2008-10-15 06:36:51 +11:00
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);
2008-10-15 06:36:51 +11:00
// SPADES
loadspriteimage(P_FIRSTSPADE+i-1, F_WALK1, "sprites/cards.png");
//sprintf(str, "%s",getcardletter(i));
strcpy(str, getcardletter(i));
2008-10-15 06:36:51 +11:00
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;
2008-10-15 06:36:51 +11:00
SDL_BlitSurface(letter, NULL, imageset[P_FIRSTSPADE + i-1].img[F_WALK1], &area);
imageset[P_FIRSTSPADE + i-1].numimages = 1;
SDL_FreeSurface(letter);
2008-10-15 06:36:51 +11:00
// CLUBS
loadspriteimage(P_FIRSTCLUB+i-1, F_WALK1, "sprites/cardc.png");
//sprintf(str, "%s",getcardletter(i));
strcpy(str, getcardletter(i));
2008-10-15 06:36:51 +11:00
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);
2008-10-15 06:36:51 +11:00
}
2008-10-10 13:46:56 +11:00
// sparkles + endgame stars
for (i = 0; i < SPARKLEFRAMES; i++) {
char name[SMALLBUFLEN];
sprintf(name, "sprites/sparkle%d.png",i);
loadspriteimage(P_SPARKLE,i, name);
loadspriteimage(P_UPSTAR, i, name);
}
imageset[P_SPARKLE].numimages = SPARKLEFRAMES;
imageset[P_UPSTAR].numimages = SPARKLEFRAMES;
loadspriteimage(P_BUBBLE,F_WALK1, "sprites/bubble.png");
imageset[P_BUBBLE].numimages = 1;
2008-12-19 12:10:11 +11:00
/* ray gun bullet */
loadspriteimage(P_RAYGUNBULLET,F_WALK1, "sprites/raygunbullet.png");
imageset[P_RAYGUNBULLET].numimages = 1;
/* water drip */
loadspriteimage(P_DRIP,F_WALK1, "sprites/drip.png");
imageset[P_DRIP].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;
2013-08-14 20:19:34 +10:00
loadspriteimage(P_FIREUP,0, "sprites/fireup1.png");
loadspriteimage(P_FIREUP,1, "sprites/fireup2.png");
loadspriteimage(P_FIREUP,2, "sprites/fireup3.png");
loadspriteimage(P_FIREUP,3, "sprites/fireup4.png");
imageset[P_FIREUP].numimages = 4;
2009-03-22 08:42:38 +11:00
loadspriteimage(P_SONAR,0, "sprites/sonar0.png");
loadspriteimage(P_SONAR,1, "sprites/sonar1.png");
loadspriteimage(P_SONAR,2, "sprites/sonar2.png");
loadspriteimage(P_SONAR,3, "sprites/sonar3.png");
loadspriteimage(P_SONAR,4, "sprites/sonar4.png");
loadspriteimage(P_SONAR,5, "sprites/sonar5.png");
loadspriteimage(P_SONAR,6, "sprites/sonar4.png");
loadspriteimage(P_SONAR,7, "sprites/sonar3.png");
loadspriteimage(P_SONAR,8, "sprites/sonar2.png");
loadspriteimage(P_SONAR,9, "sprites/sonar1.png");
imageset[P_SONAR].numimages = 10;
loadspriteimage(P_NET,0, "sprites/net.png");
// manually do flipped one
imageset[P_NET].img[1] = rotozoomSurfaceXY(imageset[P_NET].img[0], 0, -1,1,0);
imageset[P_NET].numimages = 2;
2008-11-17 13:44:44 +11:00
// manual angry image for black cloud
origi = imageset[P_BLACKCLOUD].img[0];
reds = SDL_CreateRGBSurface(SDL_SWSURFACE,2,2,
2008-11-17 13:44:44 +11:00
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);
redarea.x = 0; redarea.y = 0;
redarea.w = 1; redarea.h = 1;
temparea.w = 1; temparea.h = 1;
2008-11-17 13:44:44 +11:00
for (y = 0; y < imageset[P_BLACKCLOUD].img[MAXFRAMES*2]->h; y++) {
for (x = 0; x < imageset[P_BLACKCLOUD].img[MAXFRAMES*2]->w; x++) {
2008-11-17 13:44:44 +11:00
getpixelrgb(imageset[P_BLACKCLOUD].img[MAXFRAMES*2] , 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, imageset[P_BLACKCLOUD].img[MAXFRAMES*2], &temparea);
}
2008-11-17 13:44:44 +11:00
}
}
/* 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);
2008-10-15 06:36:51 +11:00
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);
2008-10-23 17:10:35 +11:00
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],
2008-12-21 11:14:16 +11:00
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);
2008-12-21 11:14:16 +11:00
SDL_SetColorKey(imageset[p].img[MAXFRAMES*3+i],SDL_RLEACCEL, 0);
}
}
}
return B_FALSE;
}
void drawsprite(sprite_t *s) {
SDL_Rect area;
2008-10-15 06:36:51 +11:00
int frame = 0;
2008-12-22 14:03:48 +11:00
#ifndef __EDITOR
if (isplayer(s) && s->lives < 0) {
// permenantly dead - don't draw
return;
}
2008-12-22 14:03:48 +11:00
#endif
2008-10-30 10:00:12 +11:00
// 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;
}
2008-10-30 10:00:12 +11:00
}
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)) {
2009-03-22 08:42:38 +11:00
if (s->id == P_SONAR) {
frame = s->timer1;
} else if (s->id == P_FALLINGBRICK) {
// only 1 frame
frame = F_WALK1;
} else if (s->id == P_FIREUP) {
if (s->ys < 0) {
// going up
if ((timer/6) % 2 == 0) {
frame = F_WALK1;
} else {
frame = F_JUMP;
}
} else {
// going down
if ((timer/6) % 2 == 0) {
frame = F_FALL;
} else {
frame = F_CAUGHT;
}
}
} else {
if ((timer/6) % 2 == 0) {
frame = F_WALK1;
} else {
frame = F_JUMP;
}
}
} else if (iseffect(s->id)) {
2009-03-05 08:22:28 +11:00
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;
2008-11-03 17:06:37 +11:00
} 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_UPSTAR) {
// frame based on speed
frame = (s->ys - 1);
2008-10-10 13:46:56 +11:00
} 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;
}
2008-10-10 13:46:56 +11:00
} 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);
}
}
2008-11-03 17:06:37 +11:00
} 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->id == P_KINGCAT) {
// frame based on state
switch (s->timer1) {
case KCS_WALK:
default:
if ((timer/12) % 2 == 0) {
frame = F_WALK1;
} else {
frame = F_JUMP;
}
break;
case KCS_SPELLPAUSE:
frame = F_CLIMB1;
break;
case KCS_SPELLCAST:
frame = F_CLIMB2;
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;
}
2009-03-11 10:16:08 +11:00
} 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;
2008-11-09 16:31:24 +11:00
} 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->id == P_PLANT) && s->bullet) { //shooting plant
frame = F_JUMP; // ie. mouth open
} 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;
2008-11-25 15:05:53 +11:00
} 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;
}
2008-11-03 17:06:37 +11:00
} 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) {
2008-11-22 13:06:33 +11:00
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!
2008-11-06 13:15:49 +11:00
} 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;
}
2008-10-15 06:36:51 +11:00
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);
2008-11-03 17:06:37 +11:00
// 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;
}
2008-11-03 17:06:37 +11:00
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);
}
2008-11-22 11:21:22 +11:00
// anchor
if (globpowerup == PW_ANCHOR) {
if (ismonster(s->id) && (s->id != P_BLACKCLOUD) && !s->caughtby && !s->dead) {
2008-11-22 11:21:22 +11:00
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)) {
SDL_Color *col1 = &white,*col2 = &white2;
if (s->caughtby->netsticky) {
col1 = &orange;
col2 = &yellow;
}
drawdotline16(screen, s->x,s->y - s->img->h,
s->caughtby->x,s->caughtby->y-(s->caughtby->img->h/2), *col1, *col2);
drawdotline16(screen, s->x,s->y - (s->img->h/2),
s->caughtby->x,s->caughtby->y-(s->caughtby->img->h/2), *col1,*col2);
drawdotline16(screen, s->x,s->y,
s->caughtby->x,s->caughtby->y-(s->caughtby->img->h/2), *col1,*col2);
}
}
}
void killsprite(sprite_t *s) {
sprite_t *nextone, *lastone;
#ifndef __EDITOR
sprite_t *s2;
// remove boss pointer
if (boss == s) {
boss = NULL;
}
2008-10-19 09:00:31 +11:00
// 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);
}
2008-10-23 17:10:35 +11:00
// 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;
}
}
2016-07-24 16:27:15 +10:00
void flip(int wantclear) {
#ifdef OPENGL
2016-07-24 16:27:15 +10:00
gengl(screen);
blittoscreen();
if (wantclear) {
// clear screen buffer afterwards
2016-07-24 16:27:15 +10:00
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, black.r, black.g, black.b));
}
#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;
}
2008-10-15 06:36:51 +11:00
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_LIFE:
2009-01-30 14:30:38 +11:00
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:
2009-03-06 09:40:02 +11:00
case P_LAMP:
return B_TRUE;
}
return B_FALSE;
}
int getwalkvanish(int tileid) {
tiletype_t *tt;
tt = gettile(tileid);
if (tt) {
return tt->walkvanish;
}
return -1;
}
int isfruit(int id) {
switch (id) {
/* fruits */
case P_CHEESE:
case P_ICECREAM:
case P_CHIPS:
case P_BURGER:
2008-11-19 12:20:46 +11:00
case P_PIZZA:
case P_SUNDAE:
2008-11-19 12:42:40 +11:00
case P_CAKE:
2008-11-19 12:20:46 +11:00
case P_CHOCOLATE:
case P_DIAMOND:
2009-03-06 09:40:02 +11:00
case P_GOLDCOIN:
case P_GOLDBAR:
return FT_FRUIT;
/* super powerups */
case P_BIGSPEED:
case P_BIGSCUBA:
case P_SUPERUMBRELLA:
case P_BIGHELMET:
case P_BIGCHEST:
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:
2008-10-10 11:51:40 +11:00
case P_HONEY:
case P_HELMET:
case P_MASKPOWERUP:
case P_WINGBOOTS:
2008-11-25 12:00:57 +11:00
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:
2008-10-10 13:46:56 +11:00
case P_STARPOWERUP:
case P_UFO:
2008-10-10 11:51:40 +11:00
case P_LIFE:
2008-10-10 10:49:43 +11:00
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:
2008-10-30 10:00:12 +11:00
case P_GUN:
case P_ZAPPOWERUP:
case P_SKULL:
case P_GNOME:
2008-11-17 10:01:10 +11:00
case P_WAND:
2008-11-22 11:21:22 +11:00
case P_ANCHOR:
case P_CANDLE:
2008-11-17 13:44:44 +11:00
case P_WHISTLE:
2008-11-06 13:15:49 +11:00
case P_RANDOM:
case P_MAGNET:
case P_BADMAGNET:
2008-11-25 07:02:39 +11:00
case P_JETPACK:
2008-11-25 08:35:46 +11:00
case P_CAMERA:
case P_PILL:
2008-12-19 12:10:11 +11:00
case P_RAYGUN:
2009-01-30 14:30:38 +11:00
case P_TOPHAT:
2009-03-06 09:40:02 +11:00
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;
2008-10-15 06:36:51 +11:00
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;
2013-08-14 20:19:34 +10:00
if (id == P_FIREUP) return B_TRUE;
2009-03-22 08:42:38 +11:00
if (id == P_SONAR) return B_TRUE;
if (id == P_FALLINGBRICK) return B_TRUE;
return B_FALSE;
}
2008-11-06 20:15:09 +11:00
int isplatform(int id) {
switch (id) {
case P_PLATFORM:
return B_TRUE;
}
return B_FALSE;
}
int iseffect(int id) {
switch (id) {
case P_UPSTAR:
case P_PUFF:
case P_SPARKLE:
case P_SMASH:
2009-03-05 08:22:28 +11:00
case P_FLAME:
2008-11-03 17:06:37 +11:00
case P_KSSHELL:
case P_POWERUPPOS:
case P_GLOVE:
case P_MACE:
case P_PINKCLOUD:
case P_CANNON:
case P_ZAPPER:
case P_BUBBLE:
2008-10-10 13:46:56 +11:00
case P_STAR:
case P_METEOR:
case P_MASK:
case P_MOVINGCARD:
case P_FIVECARDS:
2008-11-22 11:21:22 +11:00
case P_PLATFORM:
2008-12-19 12:10:11 +11:00
case P_RAYGUNBULLET:
case P_LEAF:
2008-11-22 11:21:22 +11:00
// these last ones aren't REALLY effects since they never have a sprite allocated
case P_WINGLEFT:
case P_WINGRIGHT:
2008-11-25 12:00:57 +11:00
case P_BIGUMBRELLA:
2008-11-22 11:21:22 +11:00
case P_SMALLANCHOR:
case P_NET:
case P_DRIP:
return B_TRUE;
}
return B_FALSE;
}
int needscollisions(int id) {
if (id == P_SMASH) return B_TRUE;
2008-10-10 13:46:56 +11:00
if (id == P_STAR) return B_TRUE;
if (id == P_METEOR) return B_TRUE;
if (id == P_ZAPPER) return B_TRUE;
2008-12-19 12:10:11 +11:00
if (id == P_RAYGUNBULLET) return B_TRUE;
2008-11-06 20:15:09 +11:00
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);
2008-10-10 11:51:40 +11:00
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);
2008-10-10 11:51:40 +11:00
} else {
drawpixel(screen,x,y,c2);
2008-10-10 11:51:40 +11:00
}
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;
int fadeint = 0;
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);
// use level background
SDL_BlitSurface(levelbg, &area, where, &area);
/* now draw layer 1 tile */
offset = y*LEVELW+x;
tt = gettile(curlevel->map[offset]);
if (tt->numframes > 1) {
frame = curlevel->tileframe[offset];
} else {
frame = 0;
}
// tiles which vanish when walking on them will slowly fade out
if (curlevel->tilewalkvanish[offset] >= 0) {
int this, max;
double fadeamt;
// set alpha
this = curlevel->tilewalkvanish[offset];
max = tt->walkvanish;
fadeamt = ((double)this / (double)max) * 255.0;
fadeamt = 255 - fadeamt;
fadeint = (int)fadeamt;
} else {
fadeint = 0;
}
if (tt->id != curlevel->bgtileid) {
SDL_BlitSurface(tt->img[frame], NULL, where, &area);
#ifndef __EDITOR
if (fadeint != 0) {
// copy background area to temp surface
SDL_BlitSurface(levelbg, &area, temptilesurf, NULL);
// make it tranparent
SDL_SetAlpha(temptilesurf, SDL_SRCALPHA, fadeint);
// blit to screen over top of tile
SDL_BlitSurface(temptilesurf, NULL, where, &area);
}
#endif
}
/* now draw layer2 if it exists */
if (curlevel->map2[offset] != T_BLANK) {
tt = gettile(curlevel->map2[offset]);
if (tt->numframes > 1) {
frame = curlevel->tileframe[offset];
} else {
frame = 0;
}
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;
2008-11-13 07:39:03 +11:00
purple.r = 255; purple.g = 0; purple.b = 255;
}
SDL_Surface *loadspriteimage(int spriteid, int frame, char *filename) {
char fullfile[BUFLEN];
2008-12-21 11:14:16 +11:00
SDL_Surface *temps;
sprintf(fullfile,"%s/%s",datadir,filename);
2008-12-21 11:14:16 +11:00
//imageset[spriteid].img[frame] = IMG_Load(fullfile);
temps = IMG_Load(fullfile);
imageset[spriteid].img[frame] = SDL_DisplayFormatAlpha(temps);
if (imageset[spriteid].img[frame] == NULL) {
2008-10-10 08:04:41 +11:00
printf("Error loading image file: %s\n",fullfile);
exit(1);
}
2008-12-21 11:14:16 +11:00
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;
}
2008-09-27 20:50:19 +10:00
int ismonster(int id) {
switch (id) {
case P_RAT:
case P_BEE:
case P_FLY:
case P_SPIDER:
2009-03-11 10:16:08 +11:00
case P_WSPIDER:
case P_SNAKE:
case P_TICK:
case P_PLANT:
case P_SNAIL:
case P_SLUG:
case P_FISH:
2008-12-22 14:03:48 +11:00
case P_FROG:
case P_ANT1:
case P_ANT2:
case P_ANT3:
2009-03-22 08:42:38 +11:00
case P_BAT:
return MT_MONSTER;
case P_BLACKCLOUD:
case P_KINGRAT:
case P_KINGSNAIL:
2008-11-25 12:41:15 +11:00
case P_KINGFLY:
2009-03-05 08:22:28 +11:00
case P_KINGANT:
case P_KINGCAT:
return MT_BOSS;
}
2008-09-27 20:50:19 +10:00
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) {
2009-03-06 09:40:02 +11:00
case P_GOLDCOIN:
points = 250;
break;
case P_CHEESE:
2008-11-19 12:20:46 +11:00
points = 500;
break;
case P_ICECREAM:
2008-11-19 12:20:46 +11:00
points = 1000;
break;
case P_CHIPS:
2008-11-19 12:20:46 +11:00
points = 1500;
break;
case P_BURGER:
2008-11-19 12:20:46 +11:00
points = 2000;
break;
case P_PIZZA:
points = 2500;
break;
2008-11-19 12:20:46 +11:00
case P_SUNDAE:
points = 3000;
break;
2008-11-19 12:42:40 +11:00
case P_CAKE:
2008-11-19 12:20:46 +11:00
points = 3500;
break;
case P_CHOCOLATE: // LOTS
points = 8000;
2008-11-19 12:20:46 +11:00
break;
2009-03-06 09:40:02 +11:00
case P_GOLDBAR:
points = 10000;
break;
2008-11-19 12:20:46 +11:00
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;
2008-11-19 09:30:43 +11:00
sprintf(filename, "%s/%s",datadir,FILE_LEVELMAP);
f = fopen(filename,"w");
if (!f) {
2008-11-19 09:30:43 +11:00
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;
2008-11-19 09:30:43 +11:00
sprintf(filename, "%s/%s",datadir, FILE_LEVELMAP);
f = fopen(filename,"r");
if (!f) {
2008-11-19 09:30:43 +11:00
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) {
if ((levelentry[lev].id != INTRO_LEVELNUM) &&
(levelentry[lev].id != TEST_LEVELNUM)) {
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;
2009-03-06 09:40:02 +11:00
num = rand() % 48;
2009-02-04 11:54:54 +11:00
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;
2008-10-10 10:49:43 +11:00
case 19:
return P_PHONE;
2008-10-10 11:51:40 +11:00
case 20:
return P_HONEY;
case 21:
return P_LIFE;
2008-10-10 13:46:56 +11:00
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;
2008-10-30 10:00:12 +11:00
case 31:
return P_GUN;
case 32:
return P_ZAPPOWERUP;
2008-11-06 13:15:49 +11:00
case 33:
return P_RANDOM;
case 34:
return P_GNOME;
2008-11-17 10:01:10 +11:00
case 35:
return P_WAND;
2008-11-17 13:44:44 +11:00
case 36:
return P_WHISTLE;
case 37:
return P_CANDLE;
2008-11-22 11:21:22 +11:00
case 38:
return P_ANCHOR;
case 39:
return P_MAGNET;
case 40:
return P_BADMAGNET;
2008-11-23 19:15:04 +11:00
case 41:
2008-11-25 07:02:39 +11:00
return P_JETPACK;
2008-11-25 08:35:46 +11:00
case 42:
return P_CAMERA;
2008-11-25 12:00:57 +11:00
case 43:
return P_UMBRELLA;
case 44:
return P_PILL;
2008-12-19 12:10:11 +11:00
case 45:
return P_RAYGUN;
2009-01-30 14:30:38 +11:00
case 46:
return P_TOPHAT;
2009-03-06 09:40:02 +11:00
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_KINGCAT:
case P_KINGRAT:
case P_KINGSNAIL:
2008-11-25 12:41:15 +11:00
case P_KINGFLY:
2009-03-05 08:22:28 +11:00
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:
2008-11-25 12:41:15 +11:00
case P_KINGFLY:
case P_KINGCAT:
2009-03-05 08:22:28 +11:00
case P_KINGANT:
return B_FALSE;
default:
return B_TRUE;
}
}
}
2008-11-21 20:19:13 +11:00
if (isplayer(s)) return B_TRUE;
return B_FALSE;
}
// return starting health for a given boss type
int getbosshealth(int mid) {
/* if (cheat) {
return 1;
} */
switch (mid) {
case P_KINGRAT:
2008-10-10 19:59:03 +11:00
return 8;
case P_KINGSNAIL:
2008-11-21 18:13:17 +11:00
return 8;
2008-11-25 12:41:15 +11:00
case P_KINGFLY:
return 8;
2009-03-05 08:22:28 +11:00
case P_KINGANT:
return 8;
case P_KINGCAT:
return 10;
}
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");
2008-11-19 12:20:46 +11:00
setinfo(P_PIZZA, "Pizza", "", "pizza.png");
setinfo(P_SUNDAE, "Sundae", "", "sundae.png");
2008-11-19 12:42:40 +11:00
setinfo(P_CAKE, "Cake", "", "cake.png");
2008-11-19 12:20:46 +11:00
setinfo(P_CHOCOLATE, "Chocolate", "", "chocolate.png");
2008-11-19 11:10:57 +11:00
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");
2009-03-06 09:42:32 +11:00
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");
2008-10-10 19:59:03 +11:00
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");
2008-12-23 12:19:16 +11:00
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");
2009-03-06 08:04:07 +11:00
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");
2008-12-19 12:10:11 +11:00
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 is now a power-up!", "tophat.png");
2009-03-06 09:40:02 +11:00
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");
2008-10-10 19:59:03 +11:00
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");
2008-11-17 08:52:11 +11:00
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");
2008-10-20 11:42:16 +11:00
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");
2008-10-10 11:51:40 +11:00
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, "Leaky 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 deadly 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");
2008-11-17 13:44:44 +11:00
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");
2008-11-22 11:21:22 +11:00
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 tasty treats!", "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");
2008-11-25 08:35:46 +11:00
setinfo(P_CAMERA, "Camera", "Creates a bright flash of light, blinding all enemies.", "camera.png");
setinfo(P_ZAPPOWERUP, "Bug Zapper", "Floats around your head and zaps nearby enemies with miniature bolts of lightning.", "zapper.png");
2008-11-25 08:47:52 +11:00
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");
2008-10-15 06:36:51 +11:00
2008-11-06 13:15:49 +11:00
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.", "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 feminine armour is also slightly more visually appealing due to its convenient openings for lipstick and hair.", "p2dwarf.png");
2008-11-14 13:47:37 +11:00
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");
2008-11-17 08:52:11 +11:00
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 deadly fish are at home in the water and unhampered by slowness while swimming.", "fish.png");
setinfo(P_SPIDER, "Redback", "Redback spiders lurk quietly on the ceiling, crawling back and forth. If they notice a player nearby, they will swiftly pounce down onto their prey.", "spider.png");
2009-03-11 10:18:33 +11:00
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_BAT, "Bat", "The bat moves in a straight line until it hits a wall. Although simplistic in their movement, bats have the ability to emit a burst of sonar towards unwary players.", "bat.png");
setinfo(P_FROG, "Frog", "Green frogs continually bounce around, making them quite difficult to catch. Unlike their other video game counterparts, they are also excellent swimmers.", "frog.png");
2008-12-22 14:03:48 +11:00
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, it becomes a Queen. Queens are just as fast as soldiers and can also breath fire. If that wasn't enough, they are also only one meal away from spawning an additional ant!", "ant3.png");
setinfo(P_SNAKE, "Snake", "The snake moves in a similar fashion to the rat with one important exception - upon seeing a player it will spit a glob of deadly venom in their direction.", "snake.png");
setinfo(P_FLY, "Fly", "Annoying pests at the best of times, flies pose additional danger to dwarves. They move 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 lie in wait and devour any player foolish enough to wander into their clutches. They also belch red-hot balls of fire at anything above them.", "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 one 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. 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");
2013-08-14 20:19:34 +10:00
setinfo(P_KINGCAT, "King Cat", "The elusive King Cat masterminded the great food heist, and is rumoured to weild powerful arcane magic...", "kingcat.png");
2008-11-25 12:41:15 +11:00
setinfo(P_SNAIL, "Snail", "Snails are slow moving but tough. Normal attacks will not harm them, instead simply destroying their shell and turning them into a slug. The safest way to take out a snail is to slam it with another monster, killing it instantly.", "snail.png");
setinfo(P_SLUG, "Slug", "Without the burden of a heavy shell, slugs move much faster than snails, and are capable of launching themselves through the air at nearby players.", "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;
2008-11-19 11:10:57 +11:00
int count;
// header
2008-10-30 13:46:39 +11:00
//printf("<html>\n");
//printf("<body bgcolor=\"#AAAAAA\">\n");
2008-11-14 13:27:14 +11:00
printf("<center><h2>Creatures</h2></center>\n");
printf("<table border=1>\n");
// players
2008-12-23 11:13:27 +11:00
printf("<tr bgcolor=\"#ffff00\"><th colspan=4>Players</th></tr>\n");
2008-11-14 13:27:14 +11:00
for (i = 0; i < MAXPTYPES; i++) {
switch (i) {
case P_PLAYER:
2008-12-23 11:13:27 +11:00
printf("<tr><td align=center><img src=\"img/%s\"><img src=\"img/%s\"><br>%s</td><td colspan=3>%s</td></tr>\n",
2008-11-14 13:41:31 +11:00
spriteinfo[i].file, spriteinfo[P_ARMOUR].file, spriteinfo[i].name,spriteinfo[i].desc);
2008-11-14 13:39:41 +11:00
break;
2008-11-14 13:41:31 +11:00
case P_PLAYER2:
2008-12-23 11:13:27 +11:00
printf("<tr><td align=center><img src=\"img/%s\"><img src=\"img/%s\"><br>%s</td><td colspan=3>%s</td></tr>\n",
2008-11-14 13:39:41 +11:00
spriteinfo[i].file, spriteinfo[P_ARMOUR2].file, spriteinfo[i].name,spriteinfo[i].desc);
2008-11-14 13:27:14 +11:00
break;
}
}
// monsters
2008-12-23 11:13:27 +11:00
printf("<tr bgcolor=\"#ffff00\"><th colspan=4>Monsters</th></tr>\n");
/*
2008-11-14 13:27:14 +11:00
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);
}
}
2008-12-23 11:13:27 +11:00
*/
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\">");
2009-03-22 08:42:38 +11:00
} else if (i == P_BAT) {
printf("<img src=\"img/sonar.png\">");
2008-12-23 11:13:27 +11:00
}
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>&nbsp;</td></tr>");
}
2008-11-14 13:27:14 +11:00
// bosses
2008-12-23 11:13:27 +11:00
printf("<tr bgcolor=\"#ffff00\"><th colspan=4>Bosses</th></tr>\n");
/*
2008-11-14 13:27:14 +11:00
for (i = 0; i < MAXPTYPES; i++) {
if (ismonster(i) == MT_BOSS) {
2008-12-23 11:13:27 +11:00
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",
2008-11-14 13:27:14 +11:00
spriteinfo[i].file, spriteinfo[i].name,spriteinfo[i].desc);
2008-12-23 11:13:27 +11:00
if (count % 2 == 1) {
printf("</tr>");
}
count++;
2008-11-14 13:27:14 +11:00
}
2008-12-23 11:13:27 +11:00
}
if (count % 2 == 0) {
printf("</tr>");
} else {
printf("<td colspan=2>&nbsp;</td></tr>");
2008-11-14 13:27:14 +11:00
}
2008-12-23 11:13:27 +11:00
2008-11-14 13:27:14 +11:00
printf("</table>\n");
2008-10-10 19:59:03 +11:00
printf("<center><h2>Power-Ups</h2>\n");
printf("<table border=1>\n");
// fruits
2008-11-19 11:10:57 +11:00
printf("<tr bgcolor=\"#ffff00\"><th colspan=4>Fruits</th></tr>\n");
count = 0;
for (i = 0; i < MAXPTYPES; i++) {
2008-11-19 12:49:28 +11:00
if ((isfruit(i) == FT_FRUIT) && (i != P_DIAMOND)) {
2008-11-19 11:10:57 +11:00
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.",
spriteinfo[i].file, spriteinfo[i].name,getpoints(i));
if (i == P_FLOWERRED) {
printf(" Collect them all for a set of rubies.");
} else if (i == P_FLOWERYELLOW) {
printf(" Collect them all for a set of topaz stones.");
} else if (i == P_FLOWERPURPLE) {
printf(" Collect them all for a set of amethysts.");
}
printf("</td>\n");
2008-11-19 11:10:57 +11:00
if (count % 2 == 1) {
printf("</tr>");
}
count++;
}
2008-11-19 11:10:57 +11:00
}
2008-11-19 11:10:57 +11:00
2008-11-19 12:49:28 +11:00
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));
2008-11-19 11:10:57 +11:00
if (count % 2 == 1) {
2008-11-19 12:49:28 +11:00
printf("</tr>");
} else {
2008-11-19 11:10:57 +11:00
printf("<td colspan=2>&nbsp;</td></tr>");
}
2008-11-19 12:49:28 +11:00
// perm powerup
2008-11-19 11:10:57 +11:00
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) {
2008-11-19 11:10:57 +11:00
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);
2008-11-19 11:10:57 +11:00
if (count % 2 == 1) {
printf("</tr>");
}
count++;
}
}
2008-11-19 11:10:57 +11:00
if (count % 2 == 0) {
printf("<tr>");
}
// card
2008-11-19 11:10:57 +11:00
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);
2008-11-19 11:10:57 +11:00
if (count % 2 == 1) {
printf("</tr>");
} else {
printf("<td colspan=2>&nbsp;</td></tr>");
}
// temp powerup
2008-11-19 11:10:57 +11:00
printf("<tr bgcolor=\"#ffff00\"><th colspan=4>Temporary Powerups</th></tr>\n");
count = 0;
for (i = 0; i < MAXPTYPES; i++) {
2008-11-17 08:52:11 +11:00
if ((isfruit(i) == FT_TEMP) && (i != P_RANDOM)) {
2008-11-19 11:10:57 +11:00
if (count % 2 == 0) {
printf("<tr>");
}
printf("<td align=center><img src=\"img/%s\"><br>%s</td><td>%s</td>\n",
2008-11-17 08:52:11 +11:00
spriteinfo[i].file, spriteinfo[i].name,spriteinfo[i].desc);
2008-11-19 11:10:57 +11:00
if (count % 2 == 1) {
printf("</tr>");
}
count++;
}
}
2008-11-19 11:10:57 +11:00
if (count % 2 == 0) {
printf("<tr>");
}
2008-11-17 08:52:11 +11:00
// random comes last
2008-11-19 11:10:57 +11:00
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>&nbsp;</td></tr>");
}
2008-11-17 08:52:11 +11:00
// super powerup
2008-11-19 11:10:57 +11:00
printf("<tr bgcolor=\"#ffff00\"><th colspan=4>Super Powerups</th></tr>\n");
count = 0;
for (i = 0; i < MAXPTYPES; i++) {
2013-08-14 20:19:34 +10:00
if ((isfruit(i) == FT_SUPER) && (i != P_BIGCHEST)) {
2008-11-19 11:10:57 +11:00
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);
2008-11-19 11:10:57 +11:00
if (count % 2 == 1) {
printf("</tr>");
}
count++;
}
}
2008-11-19 11:10:57 +11:00
if (count % 2 == 1) {
printf("<td colspan=2>&nbsp;</td></tr>");
}
printf("</table>\n");
2008-10-10 19:59:03 +11:00
printf("</center>\n");
2008-10-30 13:46:39 +11:00
//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);
}
}
}
2008-10-15 06:36:51 +11:00
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;
2008-10-15 06:36:51 +11:00
int cardid;
int ok = B_FALSE;
//cardid = P_FIRSTCARD + (rand() % 52);
// TODO: possible infinite loop?
while (!ok) {
// 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!
ok = B_TRUE;
if (player) {
for (i = 0; i < player->numcards; i++) {
if (player->card[i] == cardid) {
ok = B_FALSE;
}
}
}
if (player2) {
for (i = 0; i < player2->numcards; i++) {
if (player2->card[i] == cardid) {
ok = B_FALSE;
}
}
}
// 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) {
ok = B_FALSE;
}
}
}
} // end while !ok
2008-10-15 06:36:51 +11:00
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;
2008-10-28 07:22:33 +11:00
int drawwings;
#endif
#ifndef __EDITOR
2008-10-28 07:22:33 +11:00
if (s->powerup == PW_GUNNER) {
2008-11-13 07:39:03 +11:00
SDL_Color *ccol;
SDL_Color purple;
purple.r = 255;
purple.g = 0;
purple.b = 255;
2008-10-30 10:00:12 +11:00
// just draw crosshairs
2008-11-13 07:39:03 +11:00
if (s == player) {
ccol = &red;
} else {
ccol = &purple;
}
2008-10-30 10:00:12 +11:00
// box
2008-11-13 07:39:03 +11:00
drawbox16(screen, s->x-(TILEW/2),s->y-(TILEH/2),s->x+(TILEW/2),s->y+(TILEH/2), ccol, NULL);
2008-10-30 10:00:12 +11:00
// littlebox
2008-11-13 07:39:03 +11:00
drawbox16(screen, s->x-1,s->y-1,s->x+1,s->y+1, ccol, NULL);
2008-10-30 10:00:12 +11:00
// 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
2008-10-30 10:00:12 +11:00
return;
}
// only draw wings in certain states
2008-10-28 07:22:33 +11:00
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;
}
2008-11-25 12:00:57 +11:00
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
2008-11-25 12:00:57 +11:00
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);
}
}
2008-11-25 12:00:57 +11:00
// draw umbrella
if ((s->umbrella && s->umbrellaup) || (isplayer(s) && endgame)) {
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;
2008-11-25 12:00:57 +11:00
} else {
umarea.x = s->x - 11;
umarea.y = s->y - s->img->h - 2;
2008-11-25 12:00:57 +11:00
}
doblit(imageset[P_BIGUMBRELLA].img[F_WALK1], screen, &umarea);
2008-11-25 12:00:57 +11:00
}
}
}
#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;
}
2008-11-23 18:54:06 +11:00
int getnumplayers(void) {
int num = 0;
if (player) num++;
if (player2) num++;
return num;
}