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-17 21:16:19 +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-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;
|
|
|
|
level->p1x = 0;
|
|
|
|
level->p1y = 0;
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
/* clear player linked list */
|
|
|
|
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;
|
|
|
|
} else {
|
|
|
|
/* place the monster */
|
|
|
|
level->initm[level->nummonsters].startx = x*TILEW+(TILEW/2);
|
|
|
|
level->initm[level->nummonsters].starty = y*TILEH+(TILEH-2);
|
|
|
|
level->initm[level->nummonsters].id = monid;
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* this reads the first line of the level */
|
|
|
|
fgets(buf, BUFLEN, f);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((level->p1x == 0) || (level->p1y == 0)) {
|
|
|
|
printf("Level is missing player 1 start position.\n");
|
|
|
|
return B_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* free help texts */
|
|
|
|
for (i = 0; i < numhelp; i++) {
|
|
|
|
free(help[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set current level pointer */
|
|
|
|
curlevel = level;
|
|
|
|
|
|
|
|
/* add player */
|
|
|
|
if (player == NULL) {
|
|
|
|
addsprite(P_PLAYER, (curlevel->p1x * TILEW) + (TILEW/2),
|
|
|
|
(curlevel->p1y * TILEH) + TILEH-2 , "Player" , B_TRUE);
|
|
|
|
} else {
|
|
|
|
player->x = (curlevel->p1x * TILEW) + (TILEW/2);
|
|
|
|
player->y = (curlevel->p1y * TILEH) + TILEH-2;
|
|
|
|
}
|
|
|
|
player = lastsprite;
|
|
|
|
|
|
|
|
/* add monsters */
|
|
|
|
for (i = 0; i < level->nummonsters; i++) {
|
|
|
|
char name[MIDBUFLEN];
|
|
|
|
if (level->initm[i].id == P_HELP) {
|
|
|
|
strncpy(name, level->initm[i].help, MIDBUFLEN);
|
|
|
|
} else {
|
|
|
|
strcpy(name, "Monster");
|
|
|
|
}
|
|
|
|
addsprite(level->initm[i].id,
|
|
|
|
level->initm[i].startx, level->initm[i].starty, name, B_TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
gtime = 0;
|
|
|
|
|
2008-09-17 21:16:19 +10:00
|
|
|
printf("Loaded level. Animated tiles: ");
|
|
|
|
for (ii = level->animtiles ; ii && *ii != -1; ii++) {
|
|
|
|
printf("%d ",*ii);
|
|
|
|
}
|
|
|
|
printf(".\n");
|
|
|
|
|
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;
|
|
|
|
s->netting = 0;
|
|
|
|
s->netmax = 1;
|
|
|
|
s->netcaught = 0;
|
|
|
|
s->netbig = 0;
|
|
|
|
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;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (s->id) {
|
|
|
|
case P_CHEESE:
|
|
|
|
s->score = 500;
|
|
|
|
break;
|
|
|
|
case P_ICECREAM:
|
|
|
|
s->score = 1000;
|
|
|
|
break;
|
|
|
|
case P_CHIPS:
|
|
|
|
s->score = 2000;
|
|
|
|
break;
|
|
|
|
case P_BURGER:
|
|
|
|
s->score = 4000;
|
|
|
|
break;
|
2008-09-17 21:16:19 +10:00
|
|
|
case P_FLOWERRED:
|
|
|
|
s->score = 5;
|
|
|
|
break;
|
2008-09-17 12:34:39 +10:00
|
|
|
default:
|
|
|
|
s->score = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
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 , int initial) {
|
|
|
|
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);
|
|
|
|
|
|
|
|
if (!initial) {
|
|
|
|
if (isfruit(s->id)) {
|
|
|
|
if (s->id != P_HELP) { // help icons don't time out
|
|
|
|
s->doomcount = 500;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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];
|
|
|
|
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 */
|
|
|
|
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-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;
|
|
|
|
}
|
|
|
|
t->img[frame] = IMG_Load(p);
|
|
|
|
if (!t->img[frame]) {
|
|
|
|
printf("cannot load tile image file: '%s'\n",p);
|
|
|
|
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, " ");
|
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-17 12:34:39 +10:00
|
|
|
imageset[P_PLAYER].numimages = 10;
|
|
|
|
|
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-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-17 21:16:19 +10:00
|
|
|
loadspriteimage(P_FLOWERRED,F_WALK1, "sprites/flower-red.png");
|
|
|
|
imageset[P_FLOWERRED].numimages = 1;
|
|
|
|
|
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++) {
|
|
|
|
if (!isfruit(p) && !isbullet(p)) {
|
|
|
|
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;
|
|
|
|
|
|
|
|
/* select frame */
|
|
|
|
if (isfruit(s->id)) {
|
|
|
|
frame = F_WALK1;
|
|
|
|
} else if (isbullet(s->id)) {
|
|
|
|
frame = F_WALK1;
|
|
|
|
} else if (s->dead) {
|
|
|
|
if (s == player) {
|
|
|
|
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);
|
|
|
|
} else if (s->jumping) {
|
|
|
|
frame = F_JUMP;
|
|
|
|
} else if (s->falling) {
|
|
|
|
frame = F_FALL;
|
|
|
|
} 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;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
frame = F_WALK1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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-17 12:34:39 +10:00
|
|
|
int isfruit(int id) {
|
|
|
|
switch (id) {
|
|
|
|
case P_CHEESE:
|
|
|
|
case P_ICECREAM:
|
|
|
|
case P_CHIPS:
|
|
|
|
case P_BURGER:
|
|
|
|
case P_SPEED:
|
|
|
|
case P_NUMNETS:
|
|
|
|
case P_BIGNET:
|
|
|
|
case P_HELP:
|
2008-09-17 21:16:19 +10:00
|
|
|
case P_FLOWERRED:
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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-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-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];
|
|
|
|
}
|