ratcatcher/shared.c

2605 lines
62 KiB
C
Raw 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>
#include "defs.h"
#include "globals.h"
#include "shared.h"
2008-10-10 10:49:43 +11:00
int loadlevel(int wnum, 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;
char *p;
int tileid;
int i;
//int *ii;
//mapping_t mapping[MAXMAPPINGS];
//int nmappings = 0;
//tiletype_t *lasttile;
int newversion;
int numanim = 0;
int leveldone;
int tempanim[LEVELW*LEVELH];
2008-09-27 20:50:19 +10:00
int numenemies = 0;
printf("Loading level %d-%d...",wnum,lnum);
sprintf(filename,"%s/world%d/%s",datadir,wnum,levelentry[lnum].filename);
//filename = levelentry[lnum].filename;
//sprintf(filename, "world%d/level%d.dat",wnum,lnum);
f = fopen(filename,"rt");
if (!f) {
printf("can't open level file %s\n",filename);
return B_TRUE;
}
// remember exit direction for current level
// before loading the new one.
if (level) {
oldexitdir = level->exitdir;
} else {
oldexitdir = D_RIGHT;
}
if (!level) level = malloc(sizeof(level_t));
sprintf(level->filename, levelentry[lnum].filename);
/* set current level pointer */
curlevel = level;
if (level->animtiles) free(level->animtiles);
level->id = levelentry[lnum].id;
//sprintf(level->name, "Level %d-%d",wnum,lnum);
sprintf(level->name, "%s",levelentry[lnum].desc);
level->prev = NULL;
level->next = NULL;
/* default */
level->hurryuptime = 30;
if (cheat) {
level->poweruptime = 5;
} 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 player) */
if (sprite != NULL) {
while (sprite->next) {
killsprite(sprite->next);
}
}
/* 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) {
p = strtok(buf, " ");
p = strtok(NULL, " ");
// strip newline
p[strlen(p)-1] = '\0';
if (levelbg) SDL_FreeSurface(levelbg);
2008-10-10 08:04:41 +11:00
sprintf(level->bgfile, "%s/%s",datadir,p);
levelbg = IMG_Load(level->bgfile);
if (!levelbg) {
printf("Cannot load background file: %s\n", level->bgfile);
// default to forest
2008-10-10 08:04:41 +11:00
sprintf(tempfile, "%s/backgrounds/forest.png",datadir);
levelbg = IMG_Load(tempfile);
}
} else {
// default to forest
if (levelbg) SDL_FreeSurface(levelbg);
2008-10-10 08:04:41 +11:00
sprintf(tempfile, "%s/backgrounds/forest.png",datadir);
levelbg = IMG_Load(tempfile);
}
//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;
/* read tile defs */
// TODO: remove all of this, don't need it with new level format
/*
nmappings = 0;
fgets(buf, BUFLEN, f);
while (!strstr(buf, "endmaps")) {
strncpy(buf2,buf,BUFLEN);
p = strtok(buf2, ",");
if (p == NULL) {
printf("invalid char->tile mapping: '%s'\n",buf);
return B_TRUE;
}
mapping[nmappings].ch = p[0];
p = strtok(NULL, ",");
if (p == NULL) {
printf("invalid char->tile mapping: '%s'\n",buf);
return B_TRUE;
}
mapping[nmappings].tnum = atoi(p);
printf("got mapping: '%c' to %d\n",mapping[nmappings].ch,mapping[nmappings].tnum);
nmappings++;
fgets(buf, BUFLEN, f);
}
*/
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
if (monid == P_PLAYER) {
level->p1x = x;
level->p1y = 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;
while (!leveldone) {
/* process a line of level data */
if (newversion) {
strncpy(buf2, buf, BUFLEN);
p = strtok(buf2, ",");
while (p) {
int numframes;
tileid = atoi(p);
/* validate it */
if (!gettile(tileid)) {
printf("invalid tileid: %d\n",tileid);
fclose(f);
return B_TRUE;
}
if (x > LEVELW) {
printf("Too many tiles on line %d: %d,%d\n",y,x,y);
fclose(f);
return B_TRUE;
}
if (y >= LEVELH) {
printf("Too many lines at line %d: %d,%d\n",y,x,y);
fclose(f);
return B_TRUE;
}
/* all okay */
level->map[y*LEVELW+x] = tileid;
numframes = gettileframecount(tileid);
if (numframes == 1) {
// not animated
level->tileframe[y*LEVELW+x] = 0;
} else {
// animated
level->tileframe[y*LEVELW+x] = rand() % numframes;
tempanim[numanim] = y*LEVELW+x;
numanim++;
}
x++;
p = strtok(NULL, ",");
}
} else { // old level data version
printf("ERROR: old level data!\n");
fclose(f);
return B_TRUE;
}
/* make sure enough data was found */
if (x < LEVELW+1) {
printf("Not enough tiles on line: y = %d\n",y);
fclose(f);
return B_TRUE;
}
/* go to next line */
y++;
x = 0;
fgets(buf, BUFLEN, f);
if (feof(f)) {
leveldone = B_TRUE;
} else if (strstr(buf, "layer2")) {
leveldone = B_TRUE;
}
}
// clear out layer2 by default
for (xx = 0; xx < LEVELW; xx++) {
for (yy = 0; yy < LEVELH; yy++) {
level->map2[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);
level->map2[yy*LEVELW+xx] = tid;
fgets(buf, BUFLEN, f);
}
}
fclose(f);
// copy from our temp 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;
}
#endif
/* free help texts */
for (i = 0; i < numhelp; i++) {
free(help[i]);
}
/* add player if required */
if (player == NULL) {
addsprite(P_PLAYER, (curlevel->p1x * TILEW) + (TILEW/2),
(curlevel->p1y * TILEH) + TILEH-2 , "Player" );
player = lastsprite;
}
#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 ;
#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) {
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-10-10 10:49:43 +11:00
#ifdef __EDITOR
addsprite(level->initm[i].id,
level->initm[i].startx, level->initm[i].starty, name );
2008-10-10 10:49:43 +11:00
#else
puffin(level->initm[i].id, level->initm[i].startx, level->initm[i].starty, name, delay );
#endif
}
}
gtime = 0;
nexthurryup = level->hurryuptime;
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) {
// player powerup stats
s->speed = 1;
s->hasbell = B_FALSE;
s->armour = B_FALSE;
s->gemboost = 1;
s->powerup = 0;
s->netbig = 0;
2008-10-10 11:51:40 +11:00
s->netsticky = B_FALSE;
// player-only states
s->netting = 0;
s->netmax = 1;
s->netcaught = 0;
s->slamming = 0;
s->invuln = 0;
// states
s->recoiling = B_FALSE;
s->teleporting = 0;
s->climbing = 0;
s->jumping = 0;
s->jumpspeed = 0;
s->jumpdir = 1;
s->timer1 = 0;
s->timer2 = 0;
s->timer3 = 0;
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
if (s->id == P_KINGRAT) {
s->timer1 = 0;
s->timer2 = KR_WALKTIME;
s->timer3 = 0;
}
if (isboss(s->id)) {
s->lives = getbosshealth(s->id); // health
}
// flying
switch (s->id) {
case P_BEE:
case P_BLACKCLOUD:
case P_SPIDER:
s->flies = B_TRUE;
break;
default:
s->flies = B_FALSE;
break;
}
if (s != player) {
s->score = getpoints(s->id);
}
s->caughtby = NULL;
s->caughtstate = 0;
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;
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;
if (s->id == P_BLACKCLOUD) {
//s->img = rotozoomSurfaceXY(imageset[id].img[F_WALK1],0,1,1,0);
s->img = rotozoomSurfaceXY(imageset[id].img[F_WALK1],0,0.1,0.1,0);
} else if (s->id == P_PINKCLOUD) {
s->img = rotozoomSurfaceXY(imageset[id].img[F_WALK1],0,(double)PCGROWSPEED,(double)PCGROWSPEED,0);
} else {
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;
setdefaults(s);
// initial fruits don't time out
#ifndef __EDITOR
if ((levelcomplete != LV_NEXTLEV) && (levelcomplete != LV_INIT)) {
if (isfruit(s->id)) {
// random powerups stay for longer
if (!strcmp(s->name, "random_up")) {
s->doomcount = 900;
} else {
s->doomcount = 500;
}
}
}
#endif
s->next = NULL;
lastsprite = s;
return s;
}
tiletype_t *gettileat(int pixx,int pixy, int *tilex,int *tiley) {
int tx,ty;
int tid;
tx = pixx / TILEW;
ty = pixy / TILEH;
if (tilex != NULL) {
*tilex = tx;
}
if (tiley != NULL) {
*tiley = ty;
}
if (ty >= LEVELH) {
// if tile is off the bottom of the screen,
// return one from the top row
ty = 0;
}
if (pixy < 0) {
// if tile is off the top of the screen,
// return one from the bottom row
ty = LEVELH-1;
}
// return layer2 if it exists
tid = curlevel->map2[ty*LEVELW+tx];
if (tid == T_BLANK) {
tid = curlevel->map[ty*LEVELW+tx];
}
return gettile(tid);
}
int loadtiletypes(char *filename) {
char fullfile[BUFLEN];
tiletype_t *t = NULL;
int i;
int state;
FILE *f;
char buf[BUFLEN];
char dirname[BUFLEN];
char imagefile[BUFLEN];
char *p,*pp;
int uniq = 0 ;
/* clear tiletype linked list */
while (tiletype != NULL) {
int i;
tiletype_t *tt;
/* kill first tile */
for (i = 0; i < tiletype->numframes; i++) {
if (tiletype->img[i]) {
SDL_FreeSurface(tiletype->img[i]);
tiletype->img[i] = NULL;
}
}
tt = tiletype->next;
free(tiletype);
tiletype = tt;
}
sprintf(fullfile, "%s/%s",datadir,filename);
state = 0;
f = fopen(fullfile,"rt");
if (!f) {
printf("can't open tiles file\n");
return B_TRUE;
}
fgets(buf, BUFLEN, f);
while (!feof(f)) {
if (state == 0) {
if (strstr(buf, "tile") == buf) {
if (t == NULL) {
tiletype = malloc(sizeof(tiletype_t));
t = tiletype;
t->prev = NULL;
} else {
t->next = malloc(sizeof(tiletype_t));
t->next->prev = t;
t = t->next;
}
p = strtok(buf, " ");
p = strtok(NULL, " ");
/* strip newline */
p[strlen(p)-1] = '\0';
strcpy(t->name, p);
/* defaults */
strcpy(dirname, ".");
t->id = 0;
t->animspeed = 0; // not animated
t->numframes = 1; // not animated
t->water = B_FALSE;
t->spikes = B_FALSE;
t->solid = B_TRUE;
for (i = 0; i < TILEW; i++) {
t->lowness[i] = 0;
}
for (i = 0; i < MAXTILEFRAMES; i++) {
t->img[i] = NULL;
}
t->next = NULL;
state = 1;
/* unique id */
t->uniqid = uniq;
uniq++;
}
} else if (state == 1) { /* inside a definition */
if (strstr(buf, "end") == buf) {
//printf("got tile %d: %s (solid=%d)\n",t->id,t->name,t->solid);
/* check */
state = 0;
} else if (strstr(buf, "id") == buf) {
p = strtok(buf, " ");
p = strtok(NULL, " ");
t->id = atoi(p);
} else if (strstr(buf, "dir") == buf) { // tile directory
/* strip newline */
buf[strlen(buf)-1] = '\0';
p = strtok(buf, " ");
p = strtok(NULL, " ");
strcpy(dirname, p);
} else if (strstr(buf, "animspeed") == buf) {
p = strtok(buf, " ");
p = strtok(NULL, " ");
t->animspeed = atoi(p);
} else if (strstr(buf, "lowness") == buf) {
p = strtok(buf, " ");
p = strtok(NULL, " ");
pp = strtok(p, ",");
for (i = 0;i < TILEW; i++) {
t->lowness[i] = atoi(pp);
pp = strtok(NULL, ",");
}
} else if (strstr(buf, "solid") == buf) {
p = strtok(buf, " ");
p = strtok(NULL, " ");
t->solid = atoi(p);
} else if (strstr(buf, "spikes") == buf) {
p = strtok(buf, " ");
p = strtok(NULL, " ");
t->spikes = atoi(p);
} else if (strstr(buf, "water") == buf) {
p = strtok(buf, " ");
p = strtok(NULL, " ");
t->water = atoi(p);
} else if (strstr(buf, "file") == buf) {
int frame;
/* strip newline */
buf[strlen(buf)-1] = '\0';
p = strtok(buf, " ");
// read all images
frame = 0;
p = strtok(NULL, " ");
while (p) {
if (t->img[frame]) {
SDL_FreeSurface(t->img[frame]);
t->img[frame] = NULL;
}
2008-10-10 08:04:41 +11:00
sprintf(imagefile, "%s/%s/%s",datadir,dirname,p);
//strcpy(imagefile, dirname);
//strcat(imagefile, "/");
//strcat(imagefile, p);
t->img[frame] = IMG_Load(imagefile);
if (!t->img[frame]) {
printf("cannot load tile image file: '%s'\n",imagefile);
fclose(f);
return B_TRUE;
}
// black is transparent
SDL_SetColorKey(t->img[frame], SDL_SRCCOLORKEY, SDL_MapRGB(screen->format, 0, 0, 0));
// get next one
frame++;
p = strtok(NULL, " ");
}
t->numframes = frame;
// default animation speed
t->animspeed = 20;
}
}
fgets(buf, BUFLEN, f);
}
fclose(f);
return B_FALSE;
}
int loadimagesets(void) {
int p,i;
SDL_Surface *tempimg;
SDL_Surface *reds;
2008-10-10 08:04:41 +11:00
char tempfile[BUFLEN];
2008-10-10 08:04:41 +11:00
sprintf(tempfile, "%s/sprites/dwarfhead.png",datadir);
head = IMG_Load(tempfile);
sprintf(tempfile, "%s/sprites/dwarfhead-small.png",datadir);
headsmall = IMG_Load(tempfile);
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);
loadspriteimage(P_PLAYER,F_WALK1, "sprites/pdwarf.png");
loadspriteimage(P_PLAYER,F_JUMP, "sprites/pdwarfjump.png");
loadspriteimage(P_PLAYER,F_FALL, "sprites/pdwarffall.png");
loadspriteimage(P_PLAYER,F_CAUGHT, "sprites/pdwarf.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_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/armor.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_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_SPIDER,F_WALK1, "sprites/spider.png");
loadspriteimage(P_SPIDER,F_JUMP, "sprites/spiderjump.png");
loadspriteimage(P_SPIDER,F_FALL, "sprites/spiderfall.png");
loadspriteimage(P_SPIDER,F_CAUGHT, "sprites/spidercaught.png");
loadspriteimage(P_SPIDER,F_DEAD, "sprites/spiderdead.png");
/* next 3 are auto generated */
imageset[P_SPIDER].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_COKE,F_WALK1, "sprites/coke.png");
loadspriteimage(P_COKE,F_JUMP, "sprites/cokejump.png");
loadspriteimage(P_COKE,F_FALL, "sprites/cokejump.png");
loadspriteimage(P_COKE,F_CAUGHT, "sprites/cokecaught.png");
loadspriteimage(P_COKE,F_DEAD, "sprites/cokedead.png");
imageset[P_COKE].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_SNAIL,F_WALK1, "sprites/snail.png");
loadspriteimage(P_SNAIL,F_JUMP, "sprites/snailwalk2.png");
loadspriteimage(P_SNAIL,F_FALL, "sprites/snailwalk2.png");
loadspriteimage(P_SNAIL,F_CAUGHT, "sprites/snailcaught.png");
loadspriteimage(P_SNAIL,F_DEAD, "sprites/snaildead.png");
/* next 3 are auto generated */
imageset[P_SNAIL].numimages = 8;
loadspriteimage(P_SLUG,F_WALK1, "sprites/slug.png");
loadspriteimage(P_SLUG,F_JUMP, "sprites/slugwalk.png");
loadspriteimage(P_SLUG,F_FALL, "sprites/slugjump.png");
loadspriteimage(P_SLUG,F_CAUGHT, "sprites/slugcaught.png");
loadspriteimage(P_SLUG,F_DEAD, "sprites/slugdead.png");
/* next 3 are auto generated */
imageset[P_SLUG].numimages = 8;
/* fruits / powerups */
loadspriteimage(P_CHEESE,F_WALK1, "sprites/cheese.png");
imageset[P_CHEESE].numimages = 1;
loadspriteimage(P_ICECREAM,F_WALK1, "sprites/icecream.png");
imageset[P_ICECREAM].numimages = 1;
loadspriteimage(P_CHIPS,F_WALK1, "sprites/chips.png");
imageset[P_CHIPS].numimages = 1;
loadspriteimage(P_BURGER,F_WALK1, "sprites/burger.png");
imageset[P_BURGER].numimages = 1;
loadspriteimage(P_SPEED,F_WALK1, "sprites/speed.png");
imageset[P_SPEED].numimages = 1;
loadspriteimage(P_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_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;
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 11:51:40 +11:00
loadspriteimage(P_LIFE,F_WALK1, "sprites/dwarfhead-small.png");
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_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;
// 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);
sprintf(name, "sprites/puff%d.png",i);
loadspriteimage(P_SMASH,i, name);
}
imageset[P_PUFF].numimages = PUFFFRAMES;
imageset[P_SMASH].numimages = PUFFFRAMES;
// sparkles
for (i = 0; i < SPARKLEFRAMES; i++) {
char name[SMALLBUFLEN];
sprintf(name, "sprites/sparkle%d.png",i);
loadspriteimage(P_SPARKLE,i, name);
}
imageset[P_SPARKLE].numimages = SPARKLEFRAMES;
loadspriteimage(P_BUBBLE,F_WALK1, "sprites/bubble.png");
imageset[P_BUBBLE].numimages = 1;
/* bullets */
loadspriteimage(P_SPIT,F_WALK1, "sprites/spit.png");
imageset[P_SPIT].numimages = 1;
/* generate rotated/flipped images */
for (p = 0; p < MAXPTYPES; p++) {
int fr;
int angle = 90;
/* rotated death images */
// TODO: need to free tempimg ? */
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);
imageset[p].img[fr] = SDL_DisplayFormat(tempimg);
}
angle += 90;
}
}
for (i = 0; i < imageset[p].numimages; i++) {
SDL_Surface *origi;
if (!isfruit(p) && !iseffect(p) && p != P_BLACKCLOUD) {
SDL_SetColorKey(imageset[p].img[i],
SDL_SRCCOLORKEY, SDL_MapRGB(screen->format, 0, 0, 0));
origi = imageset[p].img[i];
/* flipped image */
imageset[p].img[MAXFRAMES+i] =
rotozoomSurfaceXY(imageset[p].img[i], 0, -1,1,0);
SDL_SetColorKey(imageset[p].img[MAXFRAMES+i],
SDL_SRCCOLORKEY, SDL_MapRGB(screen->format, 0, 0, 0));
/* angry image */
// create semi-transparent red square (white for bosses)
if (isboss(p)) {
reds = SDL_CreateRGBSurface(SDL_SWSURFACE,
origi->w,
origi->h,
origi->format->BitsPerPixel, origi->format->Rmask,
origi->format->Gmask,origi->format->Bmask, 0);
SDL_FillRect(reds, NULL, SDL_MapRGB(reds->format, 255, 255, 255));
SDL_SetAlpha(reds, SDL_SRCALPHA,100);
} else {
reds = SDL_CreateRGBSurface(SDL_SWSURFACE,
origi->w,
origi->h,
origi->format->BitsPerPixel, origi->format->Rmask,
origi->format->Gmask,origi->format->Bmask, 0);
SDL_FillRect(reds, NULL, SDL_MapRGB(reds->format, 255, 0, 0));
SDL_SetAlpha(reds, SDL_SRCALPHA,100);
}
// take a copy of the original image
imageset[p].img[MAXFRAMES*2+i] = rotozoomSurfaceXY(origi, 0, 1,1,0);
// paste the transparent one on top of it
SDL_BlitSurface(reds, NULL, imageset[p].img[MAXFRAMES*2+i], NULL);
SDL_FreeSurface(reds);
// Convert the reddened image to the screen format
temps = SDL_DisplayFormat(imageset[p].img[MAXFRAMES*2+i]);
SDL_FreeSurface(imageset[p].img[MAXFRAMES*2+i]);
imageset[p].img[MAXFRAMES*2+i] = temps;
// Make the background red bits completely transparent
if (isboss(p)) {
SDL_SetColorKey(imageset[p].img[MAXFRAMES*2+i],
SDL_SRCCOLORKEY, SDL_MapRGB(imageset[p].img[MAXFRAMES*2+i]->format, 99, 97, 99));
} else {
///SDL_Color tempcol;
///getpixelrgb(imageset[p].img[MAXFRAMES*2+i], 0, 0, &tempcol);
//printf("for spriteid %d, rgb is %d,%d,%d\n",p,tempcol.r,tempcol.g,tempcol.b);
SDL_SetColorKey(imageset[p].img[MAXFRAMES*2+i],
SDL_SRCCOLORKEY, SDL_MapRGB(imageset[p].img[MAXFRAMES*2+i]->format, 99, 0, 0));
}
/* flipped angry image */
imageset[p].img[MAXFRAMES*3+i] = rotozoomSurfaceXY(imageset[p].img[MAXFRAMES*2+i], 0, -1,1,0);
/* flipped angry image */
/*
reds = SDL_CreateRGBSurface(SDL_SWSURFACE,
origi->w,
origi->h,
origi->format->BitsPerPixel, origi->format->Rmask,
origi->format->Gmask,origi->format->Bmask, 0);
SDL_FillRect(reds, NULL, SDL_MapRGB(reds->format, 255, 0, 0));
SDL_SetAlpha(reds, SDL_SRCALPHA,100);
imageset[p].img[MAXFRAMES*3+i] = rotozoomSurfaceXY(origi, 0, -1,1,0);
SDL_BlitSurface(reds, NULL, imageset[p].img[MAXFRAMES*3+i], NULL);
SDL_FreeSurface(reds);
temps = SDL_DisplayFormat(imageset[p].img[MAXFRAMES*3+i]);
SDL_FreeSurface(imageset[p].img[MAXFRAMES*3+i]);
imageset[p].img[MAXFRAMES*3+i] = temps;
SDL_SetColorKey(imageset[p].img[MAXFRAMES*3+i],
SDL_SRCCOLORKEY, SDL_MapRGB(imageset[p].img[MAXFRAMES*3+i]->format, 101, 0, 0));
*/
}
}
}
return B_FALSE;
}
void drawsprite(sprite_t *s) {
SDL_Rect area;
int frame;
if ((s == player) && (levelcomplete == LV_NEXTLEV)) {
frame = F_SHOOT;
if (curlevel->exitdir == D_RIGHT) {
player->dir = 1;
} else if (curlevel->exitdir == D_LEFT) {
player->dir = -1;
}
} else {
/* select frame */
if (isfruit(s->id)) {
frame = F_WALK1;
} else if (isbullet(s->id)) {
frame = F_WALK1;
} else if (iseffect(s->id)) {
if ((s->id == P_PUFF) || (s->id == P_SMASH) || (s->id == P_SPARKLE)) {
if (s->timer1 >= imageset[s->id].numimages) {
frame = imageset[s->id].numimages - 1;
} else if (s->timer1 < 0) {
// don't draw
return;
} else {
frame = s->timer1;
}
} else if (s->id == P_GLOVE) {
frame = F_WALK1;
} else if (s->id == P_MACE) {
frame = F_WALK1;
} else if (s->id == P_CANNON) {
frame = F_WALK1;
} else if (s->id == P_BUBBLE) {
frame = F_WALK1;
}
} else if (s->dead) {
if (s == player) {
frame = F_DEAD;
} else if (s == boss) {
frame = F_DEAD;
} else if (s->id == P_SNAIL) {
frame = F_DEAD;
} else {
frame = F_DEAD + ((timer/2) % 4);
}
} 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) && (s == player) && !s->slamming) {
if ((timer/12) % 2 == 0) {
frame = F_SWIM1;
} else {
frame = F_SWIM2;
}
} else if (s->netting) {
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 {
frame = F_JUMP;
}
} else if (s->falling) {
if ((s->id == P_SNAIL) && (s->recoiling)) {
frame = F_DEAD;
} else {
frame = F_FALL;
}
} else if (s->slamming) {
double slamdegs = s->slamangle / (M_PI/180);
if (slamdegs < 36) {
frame = F_SLAM1;
} else if (slamdegs < 72) {
frame = F_SLAM2;
} else if (slamdegs < 108) {
frame = F_SLAM3;
} else if (slamdegs < 144) {
frame = F_SLAM4;
} else {
frame = F_SLAM5;
}
} else if (!s->teleporting) {
if ((s->id == P_SPIDER) && (s->ys != -99)) {
frame = F_FALL;
} else {
// walking / sliding
if (s->moved == MV_WALK) {
if ((timer/12) % 2 == 0) {
frame = F_WALK1;
} else {
frame = F_JUMP;
}
} else if (s->moved == MV_ICE) {
frame = F_FALL;
} 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;
}
}
/* make red if required */
if (s->angry && s->id != P_BLACKCLOUD) {
frame += (MAXFRAMES*2);
}
if ((s->id != P_BLACKCLOUD) && (s->id != P_PINKCLOUD) && (!s->teleporting)) {
s->img = imageset[s->id].img[frame];
}
/* 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;
}
}
drawline16(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;
}
area.x = s->x - (s->img->w/2);
area.y = s->y - (s->img->h);
area.w = 0;
area.h = 0;
//if (area.y < (480-s->img->h)) {
/*
if (s == player) {
printf("player at %0.1f,%0.1f\n",player->x,player->y);
}
*/
if (s->invuln) {
if (timer % 2 == 0) {
//SDL_BlitSurface(s->img, NULL, screen, &area);
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 {
// draw the sprite
//SDL_BlitSurface(s->img, NULL, screen, &area);
doblit(s->img, screen, &area);
/* for opengl */
//SDL_UpdateRect(screen, area.x, area.y, area.w, area.h);
}
// 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);
}
//}
/* caughtby lines */
if ((s->caughtby) && (s->caughtstate == 2)){
// only if we're on the screen
if ((s->y >= 0) && (s->y <= 480)) {
drawline16(screen, s->x,s->y - s->img->h,
s->caughtby->x,s->caughtby->y-(s->caughtby->img->h/2), white);
drawline16(screen, s->x,s->y - (s->img->h/2),
s->caughtby->x,s->caughtby->y-(s->caughtby->img->h/2), white);
drawline16(screen, s->x,s->y,
s->caughtby->x,s->caughtby->y-(s->caughtby->img->h/2), white);
}
}
}
void killsprite(sprite_t *s) {
sprite_t *nextone, *lastone;
sprite_t *s2;
// remove boss pointer
if (boss == s) {
boss = 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;
}
}
// free ice image
if (s->iceimg) {
SDL_FreeSurface(s->iceimg);
}
nextone = s->next;
if (nextone != NULL) {
nextone->prev = s->prev;
} else { /*last sprite */
lastsprite = s->prev;
}
if (s->prev == NULL) {
/* first sprite */
nextone = sprite->next;
free(sprite);
sprite = nextone;
} else {
lastone = s->prev;
free (lastone->next );
lastone->next = nextone;
}
}
void flip(void) {
#ifdef OPENGL
SDL_UpdateRect(screen,0,0,screen->w,screen->h);
SDL_GL_SwapBuffers();
#else
SDL_Flip(screen);
#endif
}
// returns 0 if tile isn't animated, else the number of frames
int gettileframecount(int tid) {
tiletype_t *tt;
tt = gettile(tid);
return tt->numframes;
}
// returns gem type for a given flower
int flowertogem(int id) {
switch (id) {
case P_FLOWERRED:
return P_GEMRED;
case P_FLOWERYELLOW:
return P_GEMYELLOW;
case P_FLOWERPURPLE:
return P_GEMPURPLE;
}
return P_GEMRED;
}
int isflower(int id) {
switch (id) {
case P_FLOWERRED:
case P_FLOWERYELLOW:
case P_FLOWERPURPLE:
return B_TRUE;
}
return B_FALSE;
}
int isfruit(int id) {
switch (id) {
/* fruits */
case P_CHEESE:
case P_ICECREAM:
case P_CHIPS:
case P_BURGER:
case P_DIAMOND:
return FT_FRUIT;
/* 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:
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 11:51:40 +11:00
case P_LIFE:
2008-10-10 10:49:43 +11:00
case P_PHONE:
case P_HELMET:
case P_SHIELD:
case P_RINGSILVER:
case P_RINGGOLD:
case P_CLOCK:
case P_SNOWMAN:
case P_SPRAY:
case P_CANNONPOWERUP:
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_FRUIT;
/* misc */
case P_POWERUPPOS:
return FT_OTHER;
}
return B_FALSE;
}
int isbullet(int id) {
if (id == P_SPIT) return B_TRUE;
return B_FALSE;
}
int iseffect(int id) {
switch (id) {
case P_PUFF:
case P_SPARKLE:
case P_SMASH:
case P_POWERUPPOS:
case P_GLOVE:
case P_MACE:
case P_PINKCLOUD:
case P_CANNON:
case P_BUBBLE:
return B_TRUE;
}
return B_FALSE;
}
int needscollisions(int id) {
if (id == P_SMASH) return B_TRUE;
return B_FALSE;
}
#ifdef OPENGL
inline 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
inline void drawpixel16(SDL_Surface *screen, int x, int y, SDL_Color c)
{
Uint16 *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 = SDL_MapRGB(screen->format, c.r, c.g, c.b);
}
#endif
void drawline16(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++) {
drawpixel16(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) {
drawpixel16(screen,x,y,c);
} else {
drawpixel16(screen,x,y,c2);
}
if (d < 0) {
d += dinc1;
x += xinc1;
y += yinc1;
} else {
d += dinc2;
x += xinc2;
y += yinc2;
}
}
}
void drawbox16(SDL_Surface *screen, int x1, int y1, int x2, int y2, SDL_Color *c, SDL_Color *fc) {
if (fc != NULL) {
/* fill */
if (((x2 - x1) >= 2) && ((y2 - y1) >= 2)) {
int y;
for (y = (y1+1) ; y <= (y2-1); y++) {
drawline16(screen, x1+1, y, x2-1,y,*fc);
}
}
}
drawline16(screen,x1,y1,x2,y1,*c);
drawline16(screen,x1,y1,x1,y2,*c);
drawline16(screen,x1,y2,x2,y2,*c);
drawline16(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;
}
/*
int chartomonster(char ch) {
switch (ch) {
case 'c': return P_BLACKCLOUD;
case 'r': return P_RAT;
case 'S': return P_SNAKE;
case 'a': return P_BEE;
case 's': return P_SPIDER;
case '?': return P_HELP;
case '1': return P_PLAYER;
case '@': return P_FLOWERRED;
case 'Y': return P_FLOWERYELLOW;
case 'P': return P_FLOWERPURPLE;
case 'C': return P_COKE;
case '*': return P_GEMRED;
case '!': return P_POWERUPPOS;
}
return -1;
}
char monstertochar(int id ) {
switch (id) {
case P_BLACKCLOUD: return 'c';
case P_RAT: return 'r';
case P_SNAKE: return 'S';
case P_BEE: return 'a';
case P_SPIDER: return 's';
case P_HELP: return '?';
case P_PLAYER: return '1';
case P_FLOWERRED: return '@';
case P_FLOWERYELLOW: return 'Y';
case P_FLOWERPURPLE: return 'P';
case P_COKE: return 'C';
case P_GEMRED: return '*';
case P_POWERUPPOS: return '!';
}
return '\0';
}
*/
tiletype_t *gettile(int uniqid) {
tiletype_t *t;
for (t = tiletype; t ; t = t->next) {
if (t->uniqid == uniqid) return t;
}
return &fakeblock;
}
int getuniq(int tileid) {
tiletype_t *t;
for (t = tiletype; t ; t = t->next) {
if (t->id == tileid) return t->uniqid;
}
return 0;
}
void drawtile(SDL_Surface *where, int x, int y) {
SDL_Rect area;
tiletype_t *tt;
int frame;
int offset;
if ((x < 0) || (y < 0) || (x >= LEVELW) || (y >= LEVELH)) {
return;
}
area.x = x * TILEW;
area.y = y * TILEH;
area.w = TILEW;
area.h = TILEH;
/* draw blank tile first */
tt = gettile(curlevel->bgtileid);
SDL_BlitSurface(levelbg, &area, where, &area);
/* now draw real one */
offset = y*LEVELW+x;
tt = gettile(curlevel->map[offset]);
frame = curlevel->tileframe[offset];
if (tt->id != curlevel->bgtileid) {
SDL_BlitSurface(tt->img[frame], NULL, where, &area);
}
/* now draw layer2 if it exists */
if (curlevel->map2[offset] != T_BLANK) {
tt = gettile(curlevel->map2[offset]);
if (tt->id != curlevel->bgtileid) {
SDL_BlitSurface(tt->img[frame], NULL, where, &area);
}
}
}
void 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;
}
SDL_Surface *loadspriteimage(int spriteid, int frame, char *filename) {
char fullfile[BUFLEN];
sprintf(fullfile,"%s/%s",datadir,filename);
2008-10-10 08:04:41 +11:00
imageset[spriteid].img[frame] = IMG_Load(fullfile);
if (imageset[spriteid].img[frame] == NULL) {
2008-10-10 08:04:41 +11:00
printf("Error loading image file: %s\n",fullfile);
exit(1);
}
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_SPIDER:
case P_SNAKE:
case P_COKE:
case P_SNAIL:
case P_SLUG:
return MT_MONSTER;
case P_BLACKCLOUD:
case P_KINGRAT:
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) {
case P_CHEESE:
points = 1000;
break;
case P_ICECREAM:
points = 1500;
break;
case P_CHIPS:
points = 2000;
break;
case P_BURGER:
points = 2500;
break;
case P_DIAMOND:
points = 3000;
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;
default:
points = 0;
break;
}
return points;
}
int savelevellist(void) {
char filename[BUFLEN];
FILE *f;
int i;
sprintf(filename, "%s/levels.dat",datadir);
f = fopen(filename,"w");
if (!f) {
printf("error writing to levels.dat\n");
return B_FALSE;
}
for (i = 1; i < numlevels; i++) {
fprintf(f, "%d,%s,%s\n",levelentry[i].id, levelentry[i].filename, levelentry[i].desc);
}
fclose(f);
return B_FALSE;
}
int loadlevellist(void) {
int lev;
char filename[BUFLEN];
FILE *f;
char buf[BUFLEN];
char *p;
sprintf(filename, "%s/levels.dat",datadir);
f = fopen(filename,"r");
if (!f) {
printf("Error opening levels data file\n");
exit(1);
}
// format is:
//
// id,filename,description,
lev = 1;
maxlevid = -99;
fgets(buf, BUFLEN, f);
while (!feof(f)) {
p = strtok(buf, ",");
if (!p) {
printf("invalid level id - line %d\n",lev);
return B_TRUE;
}
levelentry[lev].id = atoi(p);
// track max levelid
if (levelentry[lev].id > maxlevid) {
maxlevid = levelentry[lev].id;
}
p = strtok(NULL, ",");
if (!p) {
printf("invalid level filename - line %d\n",lev);
return B_TRUE;
}
strncpy(levelentry[lev].filename, p, MIDBUFLEN);
p = strtok(NULL, ",");
if (!p) {
printf("invalid level description - line %d\n",lev);
return B_TRUE;
}
p[strlen(p)-1] = '\0'; // strip newline
//LEVELENTry[lev].desc = strdup(p);
strncpy(levelentry[lev].desc, p, MIDBUFLEN);
lev++;
fgets(buf, BUFLEN, f);
}
fclose(f);
numlevels = lev;
printf("Read %d levels.\n",numlevels);
return B_FALSE;
}
int randompowerup(void) {
int num;
2008-10-10 11:51:40 +11:00
num = rand() % 22;
2008-10-09 20:36:13 +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;
}
}
// 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_HELP:
case P_TROPHY:
case P_HELMET:
case P_BELL:
case P_GEMBOOST:
return B_TRUE;
}
return B_FALSE;
}
int isbosslevel(int lev) {
if (lev % 20 == 0) {
return B_TRUE;
}
return B_FALSE;
}
int isboss(int monid) {
switch (monid) {
case P_KINGRAT:
return B_TRUE;
default:
return B_FALSE;
}
}
int isnettable(int monid) {
if (ismonster(monid)) {
switch (monid) {
case P_BLACKCLOUD:
case P_KINGRAT:
return B_FALSE;
default:
return B_TRUE;
}
}
return B_FALSE;
}
// return starting health for a given boss type
int getbosshealth(int mid) {
switch (mid) {
case P_KINGRAT:
return 8;
}
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_GetRGB ( col , where->format , &clr->r , &clr->g , &clr->b ) ;
//*r = color.r;
//*g = color.g;
//*b = color.b;
}
void setfruitinfo(void) {
setinfo(P_CHEESE, "Cheese", "", "cheese.png");
setinfo(P_ICECREAM, "Ice Cream","", "icecream.png");
setinfo(P_CHIPS, "Chips", "", "chips.png");
setinfo(P_BURGER, "Burger", "", "burger.png");
setinfo(P_DIAMOND, "Diamond", "", "diamond.png");
setinfo(P_FLOWERYELLOW, "Yellow Flower", "", "flower-yellow.png");
setinfo(P_FLOWERRED, "Red Flower", "", "flower-red.png");
setinfo(P_FLOWERPURPLE, "Purple Flower", "", "flower-purple.png");
setinfo(P_GEMYELLOW, "Yellow Gem", "", "gem-yellow.png");
setinfo(P_GEMRED, "Red Gem", "", "gem-red.png");
setinfo(P_GEMPURPLE, "Purple Gem", "", "gem-purple.png");
setinfo(P_SPEED, "Speed Up", "Makes you walk faster.", "speed.png");
setinfo(P_NUMNETS, "More Nets", "Increases the number of monsters you can catchsimultaneously.", "numnets.png");
setinfo(P_BIGNET, "Big Net", "Makes your nets reach further.", "bignet.png");
setinfo(P_HELP, "Help", "Gives useful game information or hints.", "help.png");
setinfo(P_GEMBOOST, "Gem Boost", "Increases the length of gem streams.", "gemboost.png");
setinfo(P_BELL, "Powerup Bell", "Rings if a permenant powerup is 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_BOXING, "Boxing Glove", "Your net will punch monsters, killing them instantly.", "glove.png");
setinfo(P_MACEPOWERUP, "Mace", "Slamming your net will cause a lethal explosion!", "macepowerup.png");
setinfo(P_FTODIAMOND, "Flowers-to-diamonds","Transforms all flowers on the level into diamonds.", "flowertodiamond.png");
setinfo(P_FTOGEM, "Flowers-to-gems", "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-10 10:49:43 +11:00
setinfo(P_PHONE, "Phone", "Calls in your helper cloud and immediately skips two levels.", "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_RAT, "Rat", "The weakest of the monsters, the rat will simply walk back and forth waiting to be caught. Beward an angry rat though, as it will try to fall or jump in order to catch you!", "rat.png");
setinfo(P_BEE, "Bee", "Bees, while still relatively weak, gain an advantage over bats 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_SPIDER, "Spider", "Spiders will lurk quietly on the ceiling, crawling back and forth. If they notice a player nearby however they will swiftly pounce down onto their prey!", "spider.png");
setinfo(P_SNAKE, "Snake", "The snake moves in a similar fashion to the rat with one important exception - upon seeing a player they will spit a glob of deadly venom at them!", "snake.png");
setinfo(P_COKE, "Coke Can", "The coke can 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 arget with a slam!", "coke.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 locating them will charge at high speed.", "kingrat.png");
setinfo(P_SNAIL, "Snail", "Snails are slow moving but tough - when slammed they will not die, but simply lose their shell and become a slug.", "snail.png");
setinfo(P_SLUG, "Slug", "Slugs are faster moving than snails and capable of launching themselves through the air at their prey!", "slug.png");
}
void setinfo(int id, char *name, char *desc, char *file) {
spriteinfo[id].name = strdup(name);
spriteinfo[id].desc = strdup(desc);
spriteinfo[id].file = strdup(file);
}
// dump html doco
void dumpinfo(void) {
int i;
// header
printf("<center><h2>Power-Ups</h2></center>\n");
printf("<table border=1>\n");
// fruits
printf("<tr><th colspan=2>Fruits</th></tr>\n");
for (i = 0; i < MAXPTYPES; i++) {
if (isfruit(i) == FT_FRUIT) {
printf("<tr><td align=center><img src=\"%s\"><br>%s</td><td>Worth %d points.</td></tr>\n",
spriteinfo[i].file, spriteinfo[i].name,getpoints(i));
}
}
// perm powerup
printf("<tr><th colspan=2>Permenant Powerups</th></tr>\n");
for (i = 0; i < MAXPTYPES; i++) {
if (isfruit(i) == FT_PERM) {
printf("<tr><td align=center><img src=\"%s\"><br>%s</td><td>%s</td></tr>\n",
spriteinfo[i].file, spriteinfo[i].name,spriteinfo[i].desc);
}
}
// temp powerup
printf("<tr><th colspan=2>Temporary Powerups</th></tr>\n");
for (i = 0; i < MAXPTYPES; i++) {
if (isfruit(i) == FT_TEMP) {
printf("<tr><td align=center><img src=\"%s\"><br>%s</td><td>%s</td></tr>\n",
spriteinfo[i].file, spriteinfo[i].name,spriteinfo[i].desc);
}
}
printf("</table>\n");
printf("<center><h2>Creatures</h2></center>\n");
printf("<table border=1>\n");
// monsters
printf("<tr><th colspan=2>Monsters</th></tr>\n");
for (i = 0; i < MAXPTYPES; i++) {
if (ismonster(i) == MT_MONSTER) {
printf("<tr><td align=center><img src=\"%s\"><br>%s</td><td>%s</td></tr>\n",
spriteinfo[i].file, spriteinfo[i].name,spriteinfo[i].desc);
}
}
// bosses
printf("<tr><th colspan=2>Bosses</th></tr>\n");
for (i = 0; i < MAXPTYPES; i++) {
if (ismonster(i) == MT_BOSS) {
printf("<tr><td align=center><img src=\"%s\"><br>%s</td><td>%s</td></tr>\n",
spriteinfo[i].file, spriteinfo[i].name,spriteinfo[i].desc);
}
}
}
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);
}
}
}