2008-09-17 12:34:39 +10:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
#include <SDL.h>
|
|
|
|
#include <SDL_keysym.h>
|
|
|
|
#include <SDL_rotozoom.h>
|
|
|
|
#include <SDL_ttf.h>
|
|
|
|
#include <SDL_framerate.h>
|
|
|
|
|
|
|
|
#include "defs.h"
|
|
|
|
#include "globals.h"
|
|
|
|
#include "shared.h"
|
|
|
|
|
|
|
|
|
|
|
|
int loadlevel(int wnum, int lnum) {
|
|
|
|
FILE *f;
|
|
|
|
int x,y;
|
|
|
|
char buf[BUFLEN];
|
|
|
|
char buf2[BUFLEN];
|
|
|
|
char filename[BUFLEN];
|
|
|
|
char *help[MAXHELP];
|
|
|
|
int numhelp = 0;
|
|
|
|
int curhelp;
|
|
|
|
char *p;
|
|
|
|
int tileid;
|
|
|
|
int i;
|
2008-09-26 19:51:17 +10:00
|
|
|
//int *ii;
|
2008-09-17 12:34:39 +10:00
|
|
|
mapping_t mapping[MAXMAPPINGS];
|
|
|
|
int nmappings = 0;
|
|
|
|
tiletype_t *lasttile;
|
|
|
|
int newversion;
|
2008-09-17 21:16:19 +10:00
|
|
|
int numanim = 0;
|
|
|
|
int tempanim[LEVELW*LEVELH];
|
2008-09-17 12:34:39 +10:00
|
|
|
|
2008-09-27 20:50:19 +10:00
|
|
|
int numenemies = 0;
|
|
|
|
|
2008-09-17 12:34:39 +10:00
|
|
|
|
2008-09-28 13:18:36 +10:00
|
|
|
|
2008-09-26 19:51:17 +10:00
|
|
|
printf("Loading level %d-%d...",wnum,lnum);
|
|
|
|
|
2008-09-28 13:18:36 +10:00
|
|
|
// remember exit direction for current level
|
|
|
|
// before loading the new one.
|
|
|
|
if (level) {
|
|
|
|
oldexitdir = level->exitdir;
|
|
|
|
} else {
|
|
|
|
oldexitdir = D_RIGHT;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-09-17 21:16:19 +10:00
|
|
|
if (!level) level = malloc(sizeof(level_t));
|
|
|
|
|
|
|
|
if (level->animtiles) free(level->animtiles);
|
2008-09-17 12:34:39 +10:00
|
|
|
|
|
|
|
level->id = 0;
|
|
|
|
sprintf(level->name, "Level %d-%d",wnum,lnum);
|
|
|
|
level->prev = NULL;
|
|
|
|
level->next = NULL;
|
|
|
|
|
|
|
|
/* default */
|
|
|
|
level->hurryuptime = 30;
|
2008-09-28 13:18:36 +10:00
|
|
|
level->poweruptime = 5;
|
2008-09-17 12:34:39 +10:00
|
|
|
level->p1x = 0;
|
|
|
|
level->p1y = 0;
|
2008-09-28 13:18:36 +10:00
|
|
|
level->powerupx = -1;
|
|
|
|
level->powerupy = -1;
|
|
|
|
|
2008-09-17 12:34:39 +10:00
|
|
|
|
|
|
|
sprintf(filename, "world%d/level%d.dat",wnum,lnum);
|
|
|
|
f = fopen(filename,"rt");
|
|
|
|
if (!f) {
|
|
|
|
printf("can't open level file\n");
|
|
|
|
return B_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* clear tiletype linked list */
|
|
|
|
while (tiletype != NULL) {
|
2008-09-17 21:16:19 +10:00
|
|
|
int i;
|
2008-09-17 12:34:39 +10:00
|
|
|
tiletype_t *tt;
|
|
|
|
|
|
|
|
/* kill first tile */
|
2008-09-17 21:16:19 +10:00
|
|
|
for (i = 0; i < tiletype->numframes; i++) {
|
|
|
|
if (tiletype->img[i]) {
|
|
|
|
SDL_FreeSurface(tiletype->img[i]);
|
|
|
|
tiletype->img[i] = NULL;
|
|
|
|
}
|
2008-09-17 12:34:39 +10:00
|
|
|
}
|
2008-09-17 21:16:19 +10:00
|
|
|
tt = tiletype->next;
|
|
|
|
free(tiletype);
|
|
|
|
tiletype = tt;
|
2008-09-17 12:34:39 +10:00
|
|
|
}
|
|
|
|
|
2008-09-28 13:18:36 +10:00
|
|
|
/* remove all onscreen text */
|
|
|
|
while (text) {
|
|
|
|
killtext(text);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* clear sprite linked list (leave player) */
|
2008-09-17 12:34:39 +10:00
|
|
|
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';
|
|
|
|
|
2008-09-17 21:16:19 +10:00
|
|
|
|
|
|
|
|
|
|
|
if ( level->tileset) free(level->tileset);
|
|
|
|
level->tileset = strdup(p);
|
|
|
|
|
2008-09-17 12:34:39 +10:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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 */
|
|
|
|
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);
|
|
|
|
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;
|
2008-09-28 13:18:36 +10:00
|
|
|
} else if (monid == P_POWERUPPOS) {
|
|
|
|
level->powerupx = x;
|
|
|
|
level->powerupy = y;
|
2008-09-17 12:34:39 +10:00
|
|
|
} else {
|
|
|
|
/* place the monster */
|
|
|
|
level->initm[level->nummonsters].startx = x*TILEW+(TILEW/2);
|
2008-09-26 19:51:17 +10:00
|
|
|
level->initm[level->nummonsters].starty = y*TILEH+(TILEH-2)+2;
|
2008-09-17 12:34:39 +10:00
|
|
|
level->initm[level->nummonsters].id = monid;
|
|
|
|
|
2008-09-27 20:50:19 +10:00
|
|
|
if (ismonster(monid)) numenemies++;
|
|
|
|
|
2008-09-17 12:34:39 +10:00
|
|
|
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++;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fgets(buf, BUFLEN, f);
|
|
|
|
}
|
|
|
|
|
2008-09-28 13:18:36 +10:00
|
|
|
/* this reads the next line after monster defs */
|
2008-09-17 12:34:39 +10:00
|
|
|
fgets(buf, BUFLEN, f);
|
|
|
|
}
|
|
|
|
|
2008-09-27 20:50:19 +10:00
|
|
|
printf("got %d monsters\n", numenemies);
|
|
|
|
|
2008-09-28 13:18:36 +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");
|
|
|
|
}
|
|
|
|
|
2008-09-17 12:34:39 +10:00
|
|
|
/* 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;
|
|
|
|
while (!feof(f)) {
|
|
|
|
/* process a line of level data */
|
|
|
|
if (newversion) {
|
|
|
|
strncpy(buf2, buf, BUFLEN);
|
|
|
|
p = strtok(buf2, ",");
|
|
|
|
while (p) {
|
2008-09-17 21:16:19 +10:00
|
|
|
int numframes;
|
2008-09-17 12:34:39 +10:00
|
|
|
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;
|
|
|
|
|
2008-09-17 21:16:19 +10:00
|
|
|
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++;
|
|
|
|
}
|
|
|
|
|
2008-09-17 12:34:39 +10:00
|
|
|
x++;
|
|
|
|
p = strtok(NULL, ",");
|
|
|
|
}
|
|
|
|
|
|
|
|
} else { /* old level data version */
|
|
|
|
for (p = buf; *p; p++) {
|
|
|
|
int n,found = 0;
|
|
|
|
/* search mappings */
|
|
|
|
for (n = 0; n < nmappings; n++) {
|
|
|
|
if (mapping[n].ch == *p) {
|
|
|
|
tileid = mapping[n].tnum;
|
|
|
|
found = B_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!found) {
|
|
|
|
|
|
|
|
if (*p == '~') {
|
|
|
|
tileid = T_LAND;
|
|
|
|
} else if (*p == '=') {
|
|
|
|
tileid = T_LADDER;
|
|
|
|
} else if (*p == '-') {
|
|
|
|
tileid = T_LADDERTOP;
|
|
|
|
} else if (*p == '{') {
|
|
|
|
tileid = T_WATERTOP;
|
|
|
|
} else if (*p == '}') {
|
|
|
|
tileid = T_WATER;
|
|
|
|
} else if (*p == '>') {
|
|
|
|
tileid = T_RIGHT;
|
|
|
|
} else if (*p == '<') {
|
|
|
|
tileid = T_LEFT;
|
|
|
|
} else if (*p == '^') {
|
|
|
|
tileid = T_SPIKES;
|
|
|
|
} else if (*p == '|') {
|
|
|
|
tileid = T_WATERSPIKES;
|
|
|
|
} else if (*p == 'c') {
|
|
|
|
tileid = level->bgtileid;
|
|
|
|
level->initm[level->nummonsters].startx = x*TILEW+(TILEW/2);
|
|
|
|
level->initm[level->nummonsters].starty = y*TILEH+(TILEH-2);
|
|
|
|
level->initm[level->nummonsters].id = P_CLOUD;
|
|
|
|
level->nummonsters++;
|
|
|
|
} else if (*p == 'r') {
|
|
|
|
/* figure out background type */
|
|
|
|
if (lasttile->solid) {
|
|
|
|
tileid = level->map[(y-1)*LEVELW+x];
|
|
|
|
} else {
|
|
|
|
tileid = lasttile->id;
|
|
|
|
}
|
|
|
|
|
|
|
|
// tileid = level->bgtileid;
|
|
|
|
level->initm[level->nummonsters].startx = x*TILEW+(TILEW/2);
|
|
|
|
level->initm[level->nummonsters].starty = y*TILEH+(TILEH-2);
|
|
|
|
level->initm[level->nummonsters].id = P_RAT;
|
|
|
|
level->nummonsters++;
|
|
|
|
|
|
|
|
} else if (*p == 'S') {
|
|
|
|
/* figure out background type */
|
|
|
|
if (lasttile->solid) {
|
|
|
|
tileid = level->map[(y-1)*LEVELW+x];
|
|
|
|
} else {
|
|
|
|
tileid = lasttile->id;
|
|
|
|
}
|
|
|
|
|
|
|
|
// tileid = level->bgtileid;
|
|
|
|
level->initm[level->nummonsters].startx = x*TILEW+(TILEW/2);
|
|
|
|
level->initm[level->nummonsters].starty = y*TILEH+(TILEH-2);
|
|
|
|
level->initm[level->nummonsters].id = P_SNAKE;
|
|
|
|
level->nummonsters++;
|
|
|
|
} else if (*p == 'a') {
|
|
|
|
/* figure out background type */
|
|
|
|
if (lasttile->solid) {
|
|
|
|
tileid = level->map[(y-1)*LEVELW+x];
|
|
|
|
} else {
|
|
|
|
tileid = lasttile->id;
|
|
|
|
}
|
|
|
|
|
|
|
|
level->initm[level->nummonsters].startx = x*TILEW+(TILEW/2);
|
|
|
|
level->initm[level->nummonsters].starty = y*TILEH+(TILEH-2);
|
|
|
|
level->initm[level->nummonsters].id = P_BEE;
|
|
|
|
level->nummonsters++;
|
|
|
|
} else if (*p == 's') {
|
|
|
|
/* figure out background type */
|
|
|
|
if (lasttile->solid) {
|
|
|
|
tileid = level->map[(y-1)*LEVELW+x];
|
|
|
|
} else {
|
|
|
|
tileid = lasttile->id;
|
|
|
|
}
|
|
|
|
|
|
|
|
level->initm[level->nummonsters].startx = x*TILEW+(TILEW/2);
|
|
|
|
level->initm[level->nummonsters].starty = y*TILEH+TILEH;
|
|
|
|
level->initm[level->nummonsters].id = P_SPIDER;
|
|
|
|
level->nummonsters++;
|
|
|
|
} else if (*p == '?') {
|
|
|
|
/* figure out background type */
|
|
|
|
if (lasttile->solid) {
|
|
|
|
tileid = level->map[(y-1)*LEVELW+x];
|
|
|
|
} else {
|
|
|
|
tileid = lasttile->id;
|
|
|
|
}
|
|
|
|
|
|
|
|
// tileid = level->bgtileid;
|
|
|
|
level->initm[level->nummonsters].startx = x*TILEW+(TILEW/2);
|
|
|
|
level->initm[level->nummonsters].starty = y*TILEH+(TILEH-2);
|
|
|
|
level->initm[level->nummonsters].id = 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++;
|
|
|
|
} else if (*p == '*') {
|
|
|
|
tileid = T_FULL;
|
|
|
|
} else if (*p == ';') {
|
|
|
|
tileid = T_TELEPORT;
|
|
|
|
} else if (*p == ':') {
|
|
|
|
tileid = T_TELEPORT2;
|
|
|
|
} else if (*p == '.') {
|
|
|
|
tileid = T_TELEPORTDEST;
|
|
|
|
} else if (*p == '/') {
|
|
|
|
tileid = T_SLOPEUP;
|
|
|
|
} else if (*p == '\\') {
|
|
|
|
tileid = T_SLOPEDOWN;
|
|
|
|
} else if (*p == '1') {
|
|
|
|
/* figure out background type */
|
|
|
|
if (lasttile->solid) {
|
|
|
|
tileid = level->map[(y-1)*LEVELW+x];
|
|
|
|
} else {
|
|
|
|
tileid = lasttile->id;
|
|
|
|
}
|
|
|
|
level->p1x = x;
|
|
|
|
level->p1y = y;
|
|
|
|
} else {
|
|
|
|
tileid = level->bgtileid;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
level->map[y*LEVELW+x] = tileid;
|
|
|
|
|
|
|
|
lasttile = gettile(tileid);
|
|
|
|
x++;
|
|
|
|
}
|
|
|
|
} /* if newversion */
|
|
|
|
|
|
|
|
/* 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);
|
|
|
|
}
|
|
|
|
fclose(f);
|
|
|
|
|
2008-09-17 21:16:19 +10:00
|
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
2008-09-17 12:34:39 +10:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2008-09-26 19:51:17 +10:00
|
|
|
#ifndef __EDITOR
|
2008-09-17 12:34:39 +10:00
|
|
|
if ((level->p1x == 0) || (level->p1y == 0)) {
|
|
|
|
printf("Level is missing player 1 start position.\n");
|
|
|
|
return B_TRUE;
|
|
|
|
}
|
2008-09-26 19:51:17 +10:00
|
|
|
#endif
|
2008-09-17 12:34:39 +10:00
|
|
|
|
|
|
|
/* free help texts */
|
|
|
|
for (i = 0; i < numhelp; i++) {
|
|
|
|
free(help[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set current level pointer */
|
|
|
|
curlevel = level;
|
|
|
|
|
2008-09-28 13:18:36 +10:00
|
|
|
/* add player if required */
|
2008-09-17 12:34:39 +10:00
|
|
|
if (player == NULL) {
|
|
|
|
addsprite(P_PLAYER, (curlevel->p1x * TILEW) + (TILEW/2),
|
2008-09-28 13:18:36 +10:00
|
|
|
(curlevel->p1y * TILEH) + TILEH-2 , "Player" );
|
|
|
|
player = lastsprite;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __EDITOR
|
|
|
|
/* add powerup pos if it exists */
|
|
|
|
if ((level->powerupx != -1) && (level->powerupy != -1)) {
|
|
|
|
addsprite(P_POWERUPPOS, (curlevel->powerupx * TILEW) + (TILEW/2),
|
|
|
|
(curlevel->powerupy * TILEH) + TILEH-2 , "poweruppos" );
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*else {
|
2008-09-17 12:34:39 +10:00
|
|
|
player->x = (curlevel->p1x * TILEW) + (TILEW/2);
|
|
|
|
player->y = (curlevel->p1y * TILEH) + TILEH-2;
|
|
|
|
}
|
2008-09-28 13:18:36 +10:00
|
|
|
*/
|
2008-09-17 12:34:39 +10:00
|
|
|
|
|
|
|
/* add monsters */
|
|
|
|
for (i = 0; i < level->nummonsters; i++) {
|
|
|
|
char name[MIDBUFLEN];
|
2008-09-28 13:18:36 +10:00
|
|
|
int delay;
|
|
|
|
|
2008-09-17 12:34:39 +10:00
|
|
|
if (level->initm[i].id == P_HELP) {
|
|
|
|
strncpy(name, level->initm[i].help, MIDBUFLEN);
|
|
|
|
} else {
|
|
|
|
strcpy(name, "Monster");
|
|
|
|
}
|
2008-09-28 13:18:36 +10:00
|
|
|
|
|
|
|
if (ismonster(level->initm[i].id)) {
|
|
|
|
delay = 20;
|
|
|
|
} else {
|
|
|
|
delay = 0;
|
|
|
|
}
|
|
|
|
#ifdef __EDITOR
|
2008-09-17 12:34:39 +10:00
|
|
|
addsprite(level->initm[i].id,
|
2008-09-28 13:18:36 +10:00
|
|
|
level->initm[i].startx, level->initm[i].starty, name );
|
|
|
|
#else
|
|
|
|
puffin(level->initm[i].id, level->initm[i].startx, level->initm[i].starty, name, delay );
|
|
|
|
#endif
|
2008-09-17 12:34:39 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
gtime = 0;
|
|
|
|
|
2008-09-26 19:51:17 +10:00
|
|
|
printf("Done.\n");
|
|
|
|
/*
|
2008-09-17 21:16:19 +10:00
|
|
|
for (ii = level->animtiles ; ii && *ii != -1; ii++) {
|
|
|
|
printf("%d ",*ii);
|
|
|
|
}
|
|
|
|
printf(".\n");
|
2008-09-26 19:51:17 +10:00
|
|
|
*/
|
2008-09-17 21:16:19 +10:00
|
|
|
|
2008-09-17 12:34:39 +10:00
|
|
|
return B_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void setdefaults(sprite_t *s) {
|
|
|
|
s->speed = 1;
|
|
|
|
s->teleporting = 0;
|
|
|
|
s->climbing = 0;
|
|
|
|
s->jumping = 0;
|
|
|
|
s->jumpspeed = 0;
|
|
|
|
s->jumpdir = 1;
|
2008-09-27 16:02:42 +10:00
|
|
|
s->timer1 = 0;
|
|
|
|
s->timer2 = 0;
|
|
|
|
s->timer3 = 0;
|
2008-09-17 12:34:39 +10:00
|
|
|
s->netting = 0;
|
|
|
|
s->netmax = 1;
|
|
|
|
s->netcaught = 0;
|
|
|
|
s->netbig = 0;
|
2008-09-26 19:51:17 +10:00
|
|
|
s->dropping = 0;
|
|
|
|
s->dropx = -1;
|
2008-09-28 13:18:36 +10:00
|
|
|
s->quickdie = B_FALSE;
|
2008-09-26 19:51:17 +10:00
|
|
|
s->dropy = -1;
|
2008-09-17 12:34:39 +10:00
|
|
|
s->falling = 0;
|
|
|
|
s->fallspeed = 0;
|
|
|
|
s->dir = 1;
|
|
|
|
s->slamming = 0;
|
|
|
|
s->dead = 0;
|
|
|
|
s->angry = 0;
|
|
|
|
s->invuln = 0;
|
|
|
|
s->jumptimer = 0;
|
|
|
|
|
|
|
|
s->bullet = NULL;
|
|
|
|
s->owner = NULL;
|
|
|
|
|
|
|
|
s->willbecome = P_CHEESE;
|
|
|
|
|
|
|
|
switch (s->id) {
|
|
|
|
case P_BEE:
|
|
|
|
case P_CLOUD:
|
|
|
|
s->flies = B_TRUE;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
s->flies = B_FALSE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2008-09-28 14:09:12 +10:00
|
|
|
s->score = getpoints(s->id);
|
2008-09-17 12:34:39 +10:00
|
|
|
|
|
|
|
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 */
|
2008-09-28 13:18:36 +10:00
|
|
|
sprite_t *addsprite(int id, int x, int y, char *name ) {
|
2008-09-17 12:34:39 +10:00
|
|
|
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_CLOUD) {
|
|
|
|
s->img = rotozoomSurfaceXY(imageset[id].img[F_WALK1],0,1,1,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;
|
|
|
|
}
|
|
|
|
|
|
|
|
setdefaults(s);
|
|
|
|
|
2008-09-28 13:18:36 +10:00
|
|
|
// initial fruits don't time out
|
|
|
|
#ifndef __EDITOR
|
|
|
|
if ((levelcomplete != LV_NEXTLEV) && (levelcomplete != LV_INIT)) {
|
2008-09-17 12:34:39 +10:00
|
|
|
if (isfruit(s->id)) {
|
2008-09-28 13:18:36 +10:00
|
|
|
// random powerups stay for longer
|
|
|
|
if (!strcmp(s->name, "random_up")) {
|
|
|
|
s->doomcount = 900;
|
|
|
|
} else {
|
2008-09-17 12:34:39 +10:00
|
|
|
s->doomcount = 500;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-09-28 13:18:36 +10:00
|
|
|
#endif
|
2008-09-17 12:34:39 +10:00
|
|
|
|
|
|
|
s->next = NULL;
|
|
|
|
|
|
|
|
lastsprite = s;
|
|
|
|
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tiletype_t *gettileat(int pixx,int pixy, int *tilex,int *tiley) {
|
|
|
|
int tx,ty;
|
|
|
|
tx = pixx / TILEW;
|
|
|
|
ty = pixy / TILEH;
|
|
|
|
if (tilex != NULL) {
|
|
|
|
*tilex = tx;
|
|
|
|
}
|
|
|
|
if (tiley != NULL) {
|
|
|
|
*tiley = ty;
|
|
|
|
}
|
|
|
|
|
|
|
|
return gettile(curlevel->map[ty*LEVELW+tx]);
|
|
|
|
}
|
|
|
|
|
|
|
|
int loadtiletypes(char *filename) {
|
|
|
|
tiletype_t *t = NULL;
|
|
|
|
int i;
|
|
|
|
int state;
|
|
|
|
FILE *f;
|
|
|
|
char buf[BUFLEN];
|
2008-09-26 19:51:17 +10:00
|
|
|
char dirname[BUFLEN];
|
|
|
|
char imagefile[BUFLEN];
|
2008-09-17 12:34:39 +10:00
|
|
|
char *p,*pp;
|
|
|
|
|
|
|
|
int uniq = 0 ;
|
|
|
|
|
|
|
|
state = 0;
|
|
|
|
f = fopen(filename,"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 */
|
2008-09-26 19:51:17 +10:00
|
|
|
strcpy(dirname, ".");
|
|
|
|
|
2008-09-17 12:34:39 +10:00
|
|
|
t->id = 0;
|
2008-09-17 21:16:19 +10:00
|
|
|
t->animspeed = 0; // not animated
|
|
|
|
t->numframes = 1; // not animated
|
2008-09-17 12:34:39 +10:00
|
|
|
t->water = B_FALSE;
|
|
|
|
t->spikes = B_FALSE;
|
|
|
|
t->solid = B_TRUE;
|
|
|
|
for (i = 0; i < TILEW; i++) {
|
|
|
|
t->lowness[i] = 0;
|
|
|
|
}
|
2008-09-17 21:16:19 +10:00
|
|
|
for (i = 0; i < MAXTILEFRAMES; i++) {
|
|
|
|
t->img[i] = NULL;
|
|
|
|
}
|
2008-09-17 12:34:39 +10:00
|
|
|
t->next = NULL;
|
|
|
|
state = 1;
|
|
|
|
|
|
|
|
/* unique id */
|
|
|
|
t->uniqid = uniq;
|
|
|
|
uniq++;
|
|
|
|
}
|
|
|
|
} else if (state == 1) { /* inside a definition */
|
|
|
|
if (strstr(buf, "end") == buf) {
|
2008-09-17 21:16:19 +10:00
|
|
|
|
2008-09-17 12:34:39 +10:00
|
|
|
//printf("got tile %d: %s (solid=%d)\n",t->id,t->name,t->solid);
|
2008-09-17 21:16:19 +10:00
|
|
|
/* check */
|
2008-09-17 12:34:39 +10:00
|
|
|
state = 0;
|
|
|
|
} else if (strstr(buf, "id") == buf) {
|
|
|
|
p = strtok(buf, " ");
|
|
|
|
p = strtok(NULL, " ");
|
|
|
|
t->id = atoi(p);
|
2008-09-26 19:51:17 +10:00
|
|
|
} else if (strstr(buf, "dir") == buf) { // tile directory
|
|
|
|
/* strip newline */
|
|
|
|
buf[strlen(buf)-1] = '\0';
|
|
|
|
|
|
|
|
p = strtok(buf, " ");
|
|
|
|
p = strtok(NULL, " ");
|
|
|
|
strcpy(dirname, p);
|
2008-09-17 21:16:19 +10:00
|
|
|
} else if (strstr(buf, "animspeed") == buf) {
|
|
|
|
p = strtok(buf, " ");
|
|
|
|
p = strtok(NULL, " ");
|
|
|
|
t->animspeed = atoi(p);
|
2008-09-17 12:34:39 +10:00
|
|
|
} 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) {
|
2008-09-17 21:16:19 +10:00
|
|
|
int frame;
|
|
|
|
|
|
|
|
/* strip newline */
|
|
|
|
buf[strlen(buf)-1] = '\0';
|
|
|
|
|
2008-09-17 12:34:39 +10:00
|
|
|
p = strtok(buf, " ");
|
2008-09-17 21:16:19 +10:00
|
|
|
|
|
|
|
// read all images
|
|
|
|
frame = 0;
|
2008-09-17 12:34:39 +10:00
|
|
|
p = strtok(NULL, " ");
|
2008-09-17 21:16:19 +10:00
|
|
|
while (p) {
|
|
|
|
if (t->img[frame]) {
|
|
|
|
SDL_FreeSurface(t->img[frame]);
|
|
|
|
t->img[frame] = NULL;
|
|
|
|
}
|
2008-09-26 19:51:17 +10:00
|
|
|
strcpy(imagefile, dirname);
|
|
|
|
strcat(imagefile, "/");
|
|
|
|
strcat(imagefile, p);
|
|
|
|
|
|
|
|
t->img[frame] = IMG_Load(imagefile);
|
2008-09-17 21:16:19 +10:00
|
|
|
if (!t->img[frame]) {
|
2008-09-26 19:51:17 +10:00
|
|
|
printf("cannot load tile image file: '%s'\n",imagefile);
|
2008-09-17 21:16:19 +10:00
|
|
|
fclose(f);
|
|
|
|
return B_TRUE;
|
2008-09-26 19:51:17 +10:00
|
|
|
}
|
2008-09-17 21:16:19 +10:00
|
|
|
// black is transparent
|
|
|
|
SDL_SetColorKey(t->img[frame], SDL_SRCCOLORKEY, SDL_MapRGB(screen->format, 0, 0, 0));
|
|
|
|
|
|
|
|
// get next one
|
|
|
|
frame++;
|
|
|
|
p = strtok(NULL, " ");
|
2008-09-17 12:34:39 +10:00
|
|
|
}
|
2008-09-17 21:16:19 +10:00
|
|
|
t->numframes = frame;
|
|
|
|
// default animation speed
|
|
|
|
t->animspeed = 20;
|
2008-09-17 12:34:39 +10:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fgets(buf, BUFLEN, f);
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose(f);
|
|
|
|
return B_FALSE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int loadimagesets(void) {
|
|
|
|
int p,i;
|
|
|
|
SDL_Surface *tempimg;
|
|
|
|
|
|
|
|
SDL_Surface *reds;
|
|
|
|
|
2008-09-17 21:16:19 +10:00
|
|
|
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");
|
2008-09-17 12:34:39 +10:00
|
|
|
/* next 3 are auto generated */
|
2008-09-17 21:16:19 +10:00
|
|
|
loadspriteimage(P_PLAYER,F_CLIMB1, "sprites/dclimb1.png");
|
|
|
|
loadspriteimage(P_PLAYER,F_CLIMB2, "sprites/dclimb2.png");
|
2008-09-26 19:51:17 +10:00
|
|
|
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");
|
|
|
|
imageset[P_PLAYER].numimages = 16;
|
2008-09-17 12:34:39 +10:00
|
|
|
|
2008-09-17 21:16:19 +10:00
|
|
|
loadspriteimage(P_SNAKE,F_WALK1, "sprites/snake.bmp");
|
|
|
|
loadspriteimage(P_SNAKE,F_JUMP, "sprites/snakejump.bmp");
|
|
|
|
loadspriteimage(P_SNAKE,F_FALL, "sprites/snakejump.bmp");
|
|
|
|
loadspriteimage(P_SNAKE,F_CAUGHT, "sprites/snakecaught.bmp");
|
|
|
|
loadspriteimage(P_SNAKE,F_DEAD, "sprites/snakedead.bmp");
|
2008-09-17 12:34:39 +10:00
|
|
|
/* next 3 are auto generated */
|
|
|
|
imageset[P_SNAKE].numimages = 8;
|
|
|
|
|
|
|
|
|
2008-09-17 21:16:19 +10:00
|
|
|
loadspriteimage(P_RAT,F_WALK1, "sprites/rat.bmp");
|
|
|
|
loadspriteimage(P_RAT,F_JUMP, "sprites/ratjump.bmp");
|
|
|
|
loadspriteimage(P_RAT,F_FALL, "sprites/ratjump.bmp");
|
|
|
|
loadspriteimage(P_RAT,F_CAUGHT, "sprites/ratcaught.bmp");
|
|
|
|
loadspriteimage(P_RAT,F_DEAD, "sprites/ratdead.bmp");
|
2008-09-17 12:34:39 +10:00
|
|
|
/* next 3 are auto generated */
|
|
|
|
imageset[P_RAT].numimages = 8;
|
|
|
|
|
2008-09-17 21:16:19 +10:00
|
|
|
loadspriteimage(P_BEE,F_WALK1, "sprites/bee.bmp");
|
|
|
|
loadspriteimage(P_BEE,F_JUMP, "sprites/beejump.bmp");
|
|
|
|
loadspriteimage(P_BEE,F_FALL, "sprites/beejump.bmp");
|
|
|
|
loadspriteimage(P_BEE,F_CAUGHT, "sprites/beecaught.bmp");
|
|
|
|
loadspriteimage(P_BEE,F_DEAD, "sprites/beedead.bmp");
|
2008-09-17 12:34:39 +10:00
|
|
|
/* next 3 are auto generated */
|
|
|
|
imageset[P_BEE].numimages = 8;
|
|
|
|
|
2008-09-17 21:16:19 +10:00
|
|
|
loadspriteimage(P_SPIDER,F_WALK1, "sprites/spider.bmp");
|
|
|
|
loadspriteimage(P_SPIDER,F_JUMP, "sprites/spiderjump.bmp");
|
|
|
|
loadspriteimage(P_SPIDER,F_FALL, "sprites/spiderfall.bmp");
|
|
|
|
loadspriteimage(P_SPIDER,F_CAUGHT, "sprites/spidercaught.bmp");
|
|
|
|
loadspriteimage(P_SPIDER,F_DEAD, "sprites/spiderdead.bmp");
|
2008-09-17 12:34:39 +10:00
|
|
|
/* next 3 are auto generated */
|
|
|
|
imageset[P_SPIDER].numimages = 8;
|
|
|
|
|
2008-09-17 21:16:19 +10:00
|
|
|
loadspriteimage(P_CLOUD,F_WALK1, "sprites/cloud.bmp");
|
|
|
|
loadspriteimage(P_CLOUD,F_JUMP, "sprites/cloud.bmp");
|
|
|
|
loadspriteimage(P_CLOUD,F_FALL, "sprites/cloud.bmp");
|
|
|
|
loadspriteimage(P_CLOUD,F_CAUGHT, "sprites/cloud.bmp");
|
|
|
|
loadspriteimage(P_CLOUD,F_DEAD, "sprites/cloud.bmp");
|
2008-09-17 12:34:39 +10:00
|
|
|
imageset[P_CLOUD].numimages = 2;
|
|
|
|
|
2008-09-26 19:51:17 +10:00
|
|
|
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;
|
|
|
|
|
|
|
|
/* fruits / powerups */
|
2008-09-17 21:16:19 +10:00
|
|
|
loadspriteimage(P_CHEESE,F_WALK1, "sprites/cheese.bmp");
|
2008-09-17 12:34:39 +10:00
|
|
|
imageset[P_CHEESE].numimages = 1;
|
|
|
|
|
2008-09-17 21:16:19 +10:00
|
|
|
loadspriteimage(P_ICECREAM,F_WALK1, "sprites/icecream.bmp");
|
2008-09-17 12:34:39 +10:00
|
|
|
imageset[P_ICECREAM].numimages = 1;
|
|
|
|
|
2008-09-17 21:16:19 +10:00
|
|
|
loadspriteimage(P_CHIPS,F_WALK1, "sprites/chips.bmp");
|
2008-09-17 12:34:39 +10:00
|
|
|
imageset[P_CHIPS].numimages = 1;
|
|
|
|
|
2008-09-17 21:16:19 +10:00
|
|
|
loadspriteimage(P_BURGER,F_WALK1, "sprites/burger.bmp");
|
2008-09-17 12:34:39 +10:00
|
|
|
imageset[P_BURGER].numimages = 1;
|
|
|
|
|
2008-09-17 21:16:19 +10:00
|
|
|
loadspriteimage(P_SPEED,F_WALK1, "sprites/speed.bmp");
|
2008-09-17 12:34:39 +10:00
|
|
|
imageset[P_SPEED].numimages = 1;
|
|
|
|
|
2008-09-17 21:16:19 +10:00
|
|
|
loadspriteimage(P_NUMNETS,F_WALK1, "sprites/numnets.bmp");
|
2008-09-17 12:34:39 +10:00
|
|
|
imageset[P_NUMNETS].numimages = 1;
|
|
|
|
|
2008-09-17 21:16:19 +10:00
|
|
|
loadspriteimage(P_BIGNET,F_WALK1, "sprites/bignet.bmp");
|
2008-09-17 12:34:39 +10:00
|
|
|
imageset[P_BIGNET].numimages = 1;
|
|
|
|
|
2008-09-17 21:16:19 +10:00
|
|
|
loadspriteimage(P_HELP,F_WALK1, "sprites/help.bmp");
|
2008-09-17 12:34:39 +10:00
|
|
|
imageset[P_HELP].numimages = 1;
|
|
|
|
|
2008-09-26 19:51:17 +10:00
|
|
|
loadspriteimage(P_FLOWERYELLOW,F_WALK1, "sprites/flower-yellow.png");
|
|
|
|
imageset[P_FLOWERRED].numimages = 1;
|
|
|
|
|
2008-09-17 21:16:19 +10:00
|
|
|
loadspriteimage(P_FLOWERRED,F_WALK1, "sprites/flower-red.png");
|
|
|
|
imageset[P_FLOWERRED].numimages = 1;
|
|
|
|
|
2008-09-26 19:51:17 +10:00
|
|
|
|
|
|
|
loadspriteimage(P_FLOWERPURPLE,F_WALK1, "sprites/flower-purple.png");
|
|
|
|
imageset[P_FLOWERPURPLE].numimages = 1;
|
|
|
|
|
2008-09-27 16:02:42 +10:00
|
|
|
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;
|
|
|
|
|
2008-09-28 13:18:36 +10:00
|
|
|
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");
|
2008-09-28 13:18:36 +10:00
|
|
|
imageset[P_GLOVE].numimages = 1;
|
|
|
|
|
|
|
|
loadspriteimage(P_DIAMOND,F_WALK1, "sprites/diamond.png");
|
|
|
|
imageset[P_DIAMOND].numimages = 1;
|
|
|
|
|
2008-09-28 14:09:12 +10:00
|
|
|
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;
|
|
|
|
|
2008-09-27 16:02:42 +10:00
|
|
|
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;
|
|
|
|
|
2008-09-17 12:34:39 +10:00
|
|
|
/* bullets */
|
2008-09-17 21:16:19 +10:00
|
|
|
loadspriteimage(P_SPIT,F_WALK1, "sprites/spit.bmp");
|
2008-09-17 12:34:39 +10:00
|
|
|
imageset[P_SPIT].numimages = 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* generate rotated/flipped images */
|
|
|
|
for (p = 0; p < MAXPTYPES; p++) {
|
2008-09-26 19:51:17 +10:00
|
|
|
/* rotated */
|
2008-09-28 13:18:36 +10:00
|
|
|
// TODO: need to free tempimg ? */
|
2008-09-27 16:02:42 +10:00
|
|
|
if (!isfruit(p) && !isbullet(p) && !iseffect(p)) {
|
2008-09-17 12:34:39 +10:00
|
|
|
tempimg = rotozoomSurface(imageset[p].img[F_DEAD],90,1,0);
|
|
|
|
imageset[p].img[F_DEAD2] = SDL_DisplayFormat(tempimg);
|
|
|
|
|
|
|
|
tempimg = rotozoomSurface(imageset[p].img[F_DEAD],180,1,0);
|
|
|
|
imageset[p].img[F_DEAD3] = SDL_DisplayFormat(tempimg);
|
|
|
|
|
|
|
|
tempimg = rotozoomSurface(imageset[p].img[F_DEAD],270,1,0);
|
|
|
|
imageset[p].img[F_DEAD4] = SDL_DisplayFormat(tempimg);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < imageset[p].numimages; i++) {
|
|
|
|
SDL_Surface *origi;
|
|
|
|
|
|
|
|
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 */
|
|
|
|
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*2+i] = rotozoomSurfaceXY(origi, 0, 1,1,0);
|
|
|
|
|
|
|
|
|
|
|
|
SDL_BlitSurface(reds, NULL, imageset[p].img[MAXFRAMES*2+i], NULL);
|
|
|
|
SDL_FreeSurface(reds);
|
|
|
|
|
|
|
|
temps = SDL_DisplayFormat(imageset[p].img[MAXFRAMES*2+i]);
|
|
|
|
SDL_FreeSurface(imageset[p].img[MAXFRAMES*2+i]);
|
|
|
|
imageset[p].img[MAXFRAMES*2+i] = temps;
|
|
|
|
|
|
|
|
SDL_SetColorKey(imageset[p].img[MAXFRAMES*2+i],
|
|
|
|
SDL_SRCCOLORKEY, SDL_MapRGB(imageset[p].img[MAXFRAMES*2+i]->format, 101, 0, 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;
|
|
|
|
|
2008-09-28 13:18:36 +10:00
|
|
|
if ((s == player) && (levelcomplete == LV_NEXTLEV)) {
|
|
|
|
frame = F_SHOOT;
|
|
|
|
} 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) {
|
|
|
|
if (s->timer1 >= PUFFFRAMES) {
|
|
|
|
frame = PUFFFRAMES-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->dead) {
|
|
|
|
if (s == player) {
|
|
|
|
frame = F_DEAD;
|
2008-09-27 16:02:42 +10:00
|
|
|
} else {
|
2008-09-28 13:18:36 +10:00
|
|
|
frame = F_DEAD + ((timer/2) % 4);
|
2008-09-27 16:02:42 +10:00
|
|
|
}
|
2008-09-28 13:18:36 +10:00
|
|
|
} else if (s->caughtby) {
|
|
|
|
frame = F_CAUGHT;
|
|
|
|
} else if (s->climbing) {
|
|
|
|
frame = F_CLIMB1 + ((timer/12) % 2);
|
|
|
|
} else if (s->netting) {
|
|
|
|
frame = F_SHOOT;
|
|
|
|
} else if (s->jumping) {
|
|
|
|
frame = F_JUMP;
|
|
|
|
} else if (s->falling) {
|
2008-09-17 12:34:39 +10:00
|
|
|
frame = F_FALL;
|
2008-09-28 13:18:36 +10:00
|
|
|
} 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 {
|
|
|
|
if (s->moved) {
|
|
|
|
if ((timer/12) % 2 == 0) {
|
|
|
|
frame = F_WALK1;
|
|
|
|
} else {
|
|
|
|
frame = F_JUMP;
|
|
|
|
}
|
2008-09-17 12:34:39 +10:00
|
|
|
} else {
|
2008-09-28 13:18:36 +10:00
|
|
|
frame = F_WALK1;
|
2008-09-17 12:34:39 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-09-28 13:18:36 +10:00
|
|
|
}
|
2008-09-17 12:34:39 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
/* x-flip if required */
|
|
|
|
if (s->dir == -1) {
|
|
|
|
frame += MAXFRAMES;
|
|
|
|
}
|
|
|
|
/* make red if required */
|
|
|
|
if (s->angry) {
|
|
|
|
frame += (MAXFRAMES*2);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((s->id != P_CLOUD) && (!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)) {
|
|
|
|
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);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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->invuln) {
|
|
|
|
if (timer % 2 == 0) {
|
|
|
|
SDL_BlitSurface(s->img, NULL, screen, &area);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
SDL_BlitSurface(s->img, NULL, screen, &area);
|
|
|
|
/* for opengl */
|
|
|
|
//SDL_UpdateRect(screen, area.x, area.y, area.w, area.h);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* caughtby lines */
|
|
|
|
if ((s->caughtby) && (s->caughtstate == 2)){
|
|
|
|
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 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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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_GL_SwapBuffers();
|
|
|
|
SDL_UpdateRect(screen,0,0,screen->w,screen->h);
|
|
|
|
#else
|
|
|
|
SDL_Flip(screen);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2008-09-17 21:16:19 +10:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
2008-09-27 16:02:42 +10:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
2008-09-17 12:34:39 +10:00
|
|
|
int isfruit(int id) {
|
|
|
|
switch (id) {
|
2008-09-28 13:18:36 +10:00
|
|
|
/* fruits */
|
2008-09-17 12:34:39 +10:00
|
|
|
case P_CHEESE:
|
|
|
|
case P_ICECREAM:
|
|
|
|
case P_CHIPS:
|
|
|
|
case P_BURGER:
|
2008-09-28 13:18:36 +10:00
|
|
|
case P_DIAMOND:
|
|
|
|
/* normal powerups */
|
2008-09-17 12:34:39 +10:00
|
|
|
case P_SPEED:
|
|
|
|
case P_NUMNETS:
|
|
|
|
case P_BIGNET:
|
|
|
|
case P_HELP:
|
2008-09-28 13:18:36 +10:00
|
|
|
/* random powerups */
|
|
|
|
case P_BOXING:
|
2008-09-28 14:09:12 +10:00
|
|
|
case P_FTODIAMOND:
|
|
|
|
case P_FTOGEM:
|
2008-09-28 13:18:36 +10:00
|
|
|
/* flowers */
|
2008-09-26 19:51:17 +10:00
|
|
|
case P_FLOWERYELLOW:
|
2008-09-27 16:02:42 +10:00
|
|
|
case P_FLOWERRED:
|
2008-09-26 19:51:17 +10:00
|
|
|
case P_FLOWERPURPLE:
|
2008-09-28 13:18:36 +10:00
|
|
|
/* gems */
|
2008-09-27 16:02:42 +10:00
|
|
|
case P_GEMYELLOW:
|
|
|
|
case P_GEMRED:
|
|
|
|
case P_GEMPURPLE:
|
2008-09-17 12:34:39 +10:00
|
|
|
return B_TRUE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return B_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
int isbullet(int id) {
|
|
|
|
if (id == P_SPIT) return B_TRUE;
|
|
|
|
|
|
|
|
return B_FALSE;
|
|
|
|
}
|
|
|
|
|
2008-09-27 16:02:42 +10:00
|
|
|
int iseffect(int id) {
|
|
|
|
if (id == P_PUFF) return B_TRUE;
|
2008-09-28 13:18:36 +10:00
|
|
|
if (id == P_POWERUPPOS) return B_TRUE;
|
|
|
|
if (id == P_GLOVE) return B_TRUE;
|
2008-09-27 16:02:42 +10:00
|
|
|
|
|
|
|
return B_FALSE;
|
|
|
|
}
|
|
|
|
|
2008-09-17 12:34:39 +10:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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_CLOUD;
|
|
|
|
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;
|
2008-09-17 21:16:19 +10:00
|
|
|
case '@': return P_FLOWERRED;
|
2008-09-26 19:51:17 +10:00
|
|
|
case 'Y': return P_FLOWERYELLOW;
|
|
|
|
case 'P': return P_FLOWERPURPLE;
|
|
|
|
case 'C': return P_COKE;
|
2008-09-27 16:02:42 +10:00
|
|
|
case '*': return P_GEMRED;
|
2008-09-28 13:18:36 +10:00
|
|
|
case '!': return P_POWERUPPOS;
|
2008-09-17 12:34:39 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
char monstertochar(int id ) {
|
|
|
|
switch (id) {
|
|
|
|
case P_CLOUD: 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';
|
2008-09-17 21:16:19 +10:00
|
|
|
case P_FLOWERRED: return '@';
|
2008-09-26 19:51:17 +10:00
|
|
|
case P_FLOWERYELLOW: return 'Y';
|
|
|
|
case P_FLOWERPURPLE: return 'P';
|
|
|
|
case P_COKE: return 'C';
|
2008-09-27 16:02:42 +10:00
|
|
|
case P_GEMRED: return '*';
|
2008-09-28 13:18:36 +10:00
|
|
|
case P_POWERUPPOS: return '!';
|
2008-09-17 12:34:39 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
return '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
tiletype_t *gettile(int tid) {
|
|
|
|
tiletype_t *t;
|
|
|
|
|
|
|
|
for (t = tiletype; t ; t = t->next) {
|
|
|
|
if (t->uniqid == tid) return t;
|
|
|
|
}
|
|
|
|
|
|
|
|
return &fakeblock;
|
|
|
|
}
|
|
|
|
|
|
|
|
void drawtile(SDL_Surface *where, int x, int y) {
|
|
|
|
SDL_Rect area;
|
|
|
|
tiletype_t *tt;
|
2008-09-17 21:16:19 +10:00
|
|
|
int frame;
|
|
|
|
int offset;
|
2008-09-17 12:34:39 +10:00
|
|
|
|
|
|
|
if ((x < 0) || (y < 0) || (x >= LEVELW) || (y >= LEVELH)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
area.x = x * TILEW;
|
|
|
|
area.y = y * TILEH;
|
|
|
|
area.w = 0;
|
|
|
|
area.h = 0;
|
|
|
|
/* draw blank tile first */
|
|
|
|
tt = gettile(curlevel->bgtileid);
|
2008-09-17 21:16:19 +10:00
|
|
|
SDL_BlitSurface(tt->img[0], NULL, where, &area);
|
2008-09-17 12:34:39 +10:00
|
|
|
|
2008-09-17 21:16:19 +10:00
|
|
|
/* now draw real one */
|
|
|
|
offset = y*LEVELW+x;
|
|
|
|
tt = gettile(curlevel->map[offset]);
|
|
|
|
frame = curlevel->tileframe[offset];
|
2008-09-17 12:34:39 +10:00
|
|
|
if (tt->id != curlevel->bgtileid) {
|
2008-09-17 21:16:19 +10:00
|
|
|
SDL_BlitSurface(tt->img[frame], NULL, where, &area);
|
2008-09-17 12:34:39 +10:00
|
|
|
}
|
2008-09-17 21:16:19 +10:00
|
|
|
|
2008-09-17 12:34:39 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
void initglobals(void) {
|
|
|
|
sprite = NULL;
|
|
|
|
|
2008-09-17 21:16:19 +10:00
|
|
|
level = NULL;
|
|
|
|
|
2008-09-17 12:34:39 +10:00
|
|
|
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;
|
|
|
|
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-09-17 21:16:19 +10:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SDL_Surface *loadspriteimage(int spriteid, int frame, char *filename) {
|
|
|
|
imageset[spriteid].img[frame] = IMG_Load(filename);
|
|
|
|
|
|
|
|
if (imageset[spriteid].img[frame] == NULL) {
|
|
|
|
printf("Error loading image file: %s\n",filename);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
return imageset[spriteid].img[frame];
|
|
|
|
}
|
2008-09-27 16:02:42 +10:00
|
|
|
|
|
|
|
int candoslopes(int sid) {
|
|
|
|
switch(sid) {
|
|
|
|
case P_SNAKE:
|
|
|
|
return B_FALSE;
|
|
|
|
}
|
|
|
|
return B_TRUE;
|
|
|
|
}
|
2008-09-27 20:50:19 +10:00
|
|
|
|
|
|
|
int ismonster(int id) {
|
|
|
|
if (id == P_RAT) return B_TRUE;
|
|
|
|
if (id == P_BEE) return B_TRUE;
|
|
|
|
if (id == P_SPIDER) return B_TRUE;
|
|
|
|
if (id == P_SNAKE) return B_TRUE;
|
|
|
|
if (id == P_CLOUD) return B_TRUE;
|
|
|
|
if (id == P_COKE) return B_TRUE;
|
|
|
|
|
|
|
|
return B_FALSE;
|
|
|
|
}
|
2008-09-28 13:18:36 +10:00
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2008-09-28 14:09:12 +10:00
|
|
|
|
|
|
|
// returns score of given fruit type
|
|
|
|
int getpoints(int id) {
|
|
|
|
int points;
|
|
|
|
switch (id) {
|
|
|
|
case P_CHEESE:
|
|
|
|
points = 100;
|
|
|
|
break;
|
|
|
|
case P_ICECREAM:
|
|
|
|
points = 200;
|
|
|
|
break;
|
|
|
|
case P_CHIPS:
|
|
|
|
points = 300;
|
|
|
|
break;
|
|
|
|
case P_BURGER:
|
|
|
|
points = 400;
|
|
|
|
break;
|
|
|
|
case P_DIAMOND:
|
|
|
|
points = 500;
|
|
|
|
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;
|
|
|
|
}
|