- Made level transition smoother and fixed bug with player movement

- Fixed bug - couldn't climb ladders next to walls
- Now using outlines instead of shadows on text
- Tweaked text colours
- Added KABOOM! to bomb and BIFF POW etc to boxing glove
- Now drawing puffs last to make sure they are on top of things
- Redrew graphics for rat, bee, snake
- Changed to new font (and renamed it to gamefont.ttf)
- OpenGL mode now mostly works (still need to fix angry sprite images, initial level transition and fullscreen mode)
- Replaced all .bmp format graphics with .png format
This commit is contained in:
Rob Pearce 2008-10-01 07:27:44 +00:00
parent 349db8365c
commit 388f50ccfc
61 changed files with 305 additions and 152 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

20
defs.h
View File

@ -4,13 +4,16 @@
#include <SDL_mixer.h>
/* Macros */
//#define OPENGL
#define OPENGL
// sound channel numbers
#define CH_LASTCHANNEL 21
#define CH_HURRYUP 20
#define MAXDEATHTEXT 4
#define MAXBIFFTEXT 4
// size of flower straem when getting last flower
@ -25,9 +28,15 @@
// text sizes
#define TEXTSIZE_HELP 20
#define TEXTSIZE_DEATH 20
#define TEXTSIZE_POINTS 10
#define TEXTSIZE_BONUS 20
#define TEXTSIZE_BIFF 26
#define TEXTSIZE_HURRY 50
#define TEXTSIZE_BOMB 36
#define TEXTSIZE_LEVEL 32
#define TEXTSIZE_LEVEL2 22
#define TEXTSIZE_SCORE 14
// text delays
#define TEXTSPEED 2 // how fast text zooms in
@ -36,7 +45,9 @@
#define POINTSDELAY 40
#define BONUSDELAY 50
#define HURRYDELAY 50
#define LEVELDELAY 80
#define LEVELWINDELAY 80
#define LEVELDELAY 100
#define DIEDELAY 80
#define HELPDELAY 80
@ -295,6 +306,7 @@ typedef struct level_s {
level_t *level;
typedef struct levelentry_s {
int id;
char *filename;
char *desc;
} levelentry_t;
@ -405,6 +417,8 @@ extern text_t *text, *lasttext;
extern int cheat;
extern int nexthurryup;
extern levelentry_t levelentry[];
extern int numlevels;
extern char *deathtext[];
extern char *bifftext[];
#endif

19
edit.c
View File

@ -30,6 +30,8 @@ int modified = B_FALSE; // has the current level been modified since last save?
int curworld = 1;
int curlevelnum;
int skipto = -1;
int layer = 1; // which layer we are editting, either 1 or 2
int main (int argc, char **argv) {
@ -55,8 +57,8 @@ int main (int argc, char **argv) {
usage();
exit(1);
}
curlevelnum = atoi(argv[i]);
printf("Skipping to level %d.\n",curlevelnum);
skipto = atoi(argv[i]);
printf("Skipping to level %d.\n",skipto);
} else {
usage();
exit(1);
@ -69,6 +71,15 @@ int main (int argc, char **argv) {
return 1;
}
// is we're skipping to a level, do so now
if (skipto >= 0) {
for (i = 0; i < numlevels; i++) {
if (levelentry[i].id == skipto) {
curlevelnum = i;
}
}
}
/* initialise */
initglobals();
@ -98,7 +109,7 @@ int main (int argc, char **argv) {
fakeblock.lowness[i] = 0;
}
fakeblock.solid = S_SOLID;
fakeblock.img[0] = IMG_Load("land.bmp");
fakeblock.img[0] = IMG_Load("newtiles/land.png");
fakeblock.numframes = 1;
fakeblock.next = NULL;
fakeblock.prev = NULL;
@ -106,7 +117,7 @@ int main (int argc, char **argv) {
/* load fonts */
TTF_Init();
sprintf(filename, "verdana.ttf");
sprintf(filename, "gamefont.ttf");
for (i = 1; i < MAXLETTERHEIGHT; i++) {
font[i] = TTF_OpenFont(filename,i);
if (!font[i]) {

BIN
gamefont.ttf Normal file

Binary file not shown.

View File

@ -5,6 +5,7 @@
int musicplaying;
levelentry_t levelentry[MAXLEVELS]; // level filenames etc
int numlevels;
SDL_Surface *levelbg; // level background image
SDL_Surface *temps; // temporary surface
@ -39,6 +40,21 @@ int gtime; // game time - time elapsed on current level
int timer; // generic 1-100 timer for repeated events
int toggletimer; // used for toggling between fullscreen mode
char *deathtext[] = {
"Ouch!",
"Ow!",
"Argh!",
"Noooo!"
};
char *bifftext[] = {
"Biff!",
"Pow!",
"Wham!",
"Splat!"
};
/* colours */
SDL_Color red;
SDL_Color black;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

BIN
land.bmp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

BIN
left.bmp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

20
levels.dat Normal file
View File

@ -0,0 +1,20 @@
1,level1.dat,Ratcatching school
2,level2.dat,Powerup school
3,level3.dat,Spike school
4,level4.dat,Bridge school
5,level5.dat,Hole in the hill
7,level6.dat,Roller school
6,level5.5.dat,The Pit
8,level7.dat,Platforms and Ladders
9,level7.5.dat,The Snake Pit
10,level8.dat,Smile!
12,level9.dat,The Garden
14,level10.dat,Planks
15,level11.dat,The Hive
16,level11.5.dat,Underground Lakes
17,level12.dat,Bee Pods
18,level13.dat,Dual Hives
19,level14.dat,The Chimney
11,level8.5.dat,Look out above...
99,level99.dat,TEST LEVEL
13,level9.5.dat,Back and Forth

Binary file not shown.

Before

Width:  |  Height:  |  Size: 707 B

After

Width:  |  Height:  |  Size: 793 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 742 B

After

Width:  |  Height:  |  Size: 860 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 708 B

After

Width:  |  Height:  |  Size: 803 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 729 B

After

Width:  |  Height:  |  Size: 860 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 700 B

After

Width:  |  Height:  |  Size: 795 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 735 B

After

Width:  |  Height:  |  Size: 861 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 706 B

After

Width:  |  Height:  |  Size: 788 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 732 B

After

Width:  |  Height:  |  Size: 858 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 503 B

After

Width:  |  Height:  |  Size: 602 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 490 B

After

Width:  |  Height:  |  Size: 593 B

BIN
newtiles/spikes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

BIN
newtiles/water.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 B

BIN
newtiles/watertop.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

BIN
pfall.bmp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

BIN
pjump.bmp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

212
rc.c
View File

@ -59,6 +59,7 @@ int fpsstart = 0;
int curworld = 1;
int curlevelnum;
int skipto = -1; // which level to skip to
level_t *curlevel;
int levelcompletetime = -1;
@ -71,6 +72,7 @@ sprite_t *lastsprite;
SDL_Color red = {255, 0, 0, 0};
SDL_Color black = {0, 0, 0, 0};
SDL_Color blue = {0, 0, 255, 0};
SDL_Color cyan = {0, 255, 255, 0};
SDL_Color white = {255, 255, 255, 0};
SDL_Color green = {0, 255, 0, 0};
SDL_Color yellow = {255, 255, 0, 0};
@ -107,8 +109,8 @@ int main (int argc, char **argv) {
usage();
exit(1);
}
curlevelnum = atoi(argv[i]);
printf("Skipping to level %d.\n",curlevelnum);
skipto = atoi(argv[i]);
printf("Skipping to level %d.\n",skipto);
} else {
usage();
exit(1);
@ -132,6 +134,12 @@ int main (int argc, char **argv) {
screen = SDL_SetVideoMode(640,480,16,SDL_SWSURFACE|SDL_DOUBLEBUF|vidargs);
#endif
if (!screen) {
printf("Failed to open OpenGL window: %s\n", SDL_GetError());
exit(1);
}
srand(time(NULL));
if (loadimagesets()) {
@ -144,13 +152,22 @@ int main (int argc, char **argv) {
return 1;
}
// is we're skipping to a level, do so now
if (skipto >= 0) {
for (i = 0; i < numlevels; i++) {
if (levelentry[i].id == skipto) {
curlevelnum = i;
}
}
}
fakeblock.id = T_LAND;
strcpy(fakeblock.name,"Fake");
for (i = 0; i < TILEW; i++) {
fakeblock.lowness[i] = 0;
}
fakeblock.solid = S_SOLID;
fakeblock.img[0] = IMG_Load("land.bmp");
fakeblock.img[0] = IMG_Load("newtiles/land.png");
fakeblock.numframes = 1;
fakeblock.next = NULL;
fakeblock.prev = NULL;
@ -158,7 +175,7 @@ int main (int argc, char **argv) {
/* load fonts */
TTF_Init();
sprintf(filename, "verdana.ttf");
sprintf(filename, "gamefont.ttf");
for (i = 1; i < MAXLETTERHEIGHT; i++) {
font[i] = TTF_OpenFont(filename,i);
if (!font[i]) {
@ -222,8 +239,8 @@ int main (int argc, char **argv) {
/* check for end of level */
if (levelcomplete == LV_CLEAR) {
addtext(318,242,32,"Level Complete!",&black,LEVELDELAY);
addtext(320,240,32,"Level Complete!",&yellow,LEVELDELAY);
addoutlinetext(320,240,TEXTSIZE_LEVEL,"Level Complete!",&green,&black,LEVELWINDELAY);
levelcomplete = LV_WAIT;
playfx(FX_WINLEVEL);
} else if (levelcomplete == LV_WAIT) {
@ -507,9 +524,13 @@ int main (int argc, char **argv) {
drawnetting(player);
/* draw player */
/* draw non-puff sprites */
for (s = sprite ; s ; s = s->next) {
drawsprite(s);
if (s->id != P_PUFF) drawsprite(s);
}
/* draw puffs sprites */
for (s = sprite ; s ; s = s->next) {
if (s->id == P_PUFF) drawsprite(s);
}
/* draw text */
drawtext();
@ -574,7 +595,7 @@ void tick(void) {
s->angry = B_TRUE;
}
}
addtext(320,240,TEXTSIZE_HURRY, "Hurry up!", &yellow,HURRYDELAY);
addoutlinetext(320,240,TEXTSIZE_HURRY, "Hurry up!", &yellow,&black,HURRYDELAY);
stopmusic();
Mix_PlayChannel(CH_HURRYUP, sfx[FX_HURRYUP], 0);
@ -582,7 +603,7 @@ void tick(void) {
} else if (gtime == nexthurryup + 10) {
if (!levelcomplete) {
addsprite(P_CLOUD, 320,240,"cloud");
addtext(320,240,TEXTSIZE_HURRY, "Too slow!", &red,HURRYDELAY);
addoutlinetext(320,240,TEXTSIZE_HURRY, "Too slow!", &red,&black,HURRYDELAY);
playfx(FX_TOOSLOW);
}
}
@ -622,8 +643,6 @@ void tick(void) {
void nextlevel(void) {
char msg[SMALLBUFLEN];
SDL_Surface *tempt;
int wid;
// remove the player
removesprite(player);
@ -656,21 +675,11 @@ void nextlevel(void) {
level->gotpowerup = B_FALSE;
sprintf(msg, "Level %d-%d",curworld, curlevelnum);
// calc width
tempt = TTF_RenderText_Solid(font[32], msg, black);
wid = tempt->w;
addtext(318,240-18+2,32,msg,&black,LEVELDELAY);
addtext(320,240-18,32,msg,&red,LEVELDELAY);
SDL_FreeSurface(tempt);
addoutlinetext(320,240-18,TEXTSIZE_LEVEL,msg,&red,&black,LEVELDELAY);
sprintf(msg, "%s", curlevel->name);
// calc width
tempt = TTF_RenderText_Solid(font[22], msg, black);
wid = tempt->w;
addtext(319,240+18+1,22,msg,&black,LEVELDELAY);
addtext(320,240+18,22,msg,&blue,LEVELDELAY);
SDL_FreeSurface(tempt);
addoutlinetext(320,240+18,TEXTSIZE_LEVEL2,msg,&cyan,&black,LEVELDELAY);
/* reset player stats */
player->netting = B_FALSE;
@ -736,8 +745,13 @@ void die(sprite_t *s) {
}
if (s == player) {
int tnum;
/* play sound */
playfx(FX_DIE);
// draw text
tnum = rand() % MAXDEATHTEXT;
addoutlinetext(player->x,player->y,TEXTSIZE_DEATH,deathtext[tnum],&red,&black,DIEDELAY);
}
/* release anything we've caught */
@ -837,6 +851,8 @@ void checkcollide(sprite_t *s) {
s2->willbecome = P_DIAMOND;
playfx(FX_KILL);
sprintf(tempm, bifftext[rand() % MAXBIFFTEXT]);
addoutlinetext(s2->x,s2->y - s->img->h/2, TEXTSIZE_BIFF, tempm,&red,&yellow,POINTSDELAY);
keepchecking = B_FALSE;
} else {
@ -883,7 +899,7 @@ void checkcollide(sprite_t *s) {
if (!dofruiteffect(s2)) {
playfx(FX_FRUIT);
sprintf(tempm, "%d", gotscore);
addtext(s2->x,s2->y - s2->img->h/2, TEXTSIZE_POINTS, tempm, &white,POINTSDELAY);
addoutlinetext(s2->x,s2->y - s2->img->h/2, TEXTSIZE_POINTS, tempm, &white,&black,POINTSDELAY);
}
} else if (ismonster(s2->id) || isbullet(s2->id)) {
if (!s->invuln) {
@ -1666,7 +1682,7 @@ void dotileeffects(sprite_t *s) {
if (!s->teleporting) {
playfx(FX_TELEPORT);
s->teleporting = 1;
}
}
}
}
}
@ -1690,7 +1706,7 @@ void dotileeffects(sprite_t *s) {
}
finished = B_TRUE;
} else if (tt->spikes) {
if (!isfruit(s->id)) {
if (!isfruit(s->id) && !iseffect(s->id) && !isbullet(s->id)) {
if (!s->invuln) {
if (s->id != P_CLOUD) {
die(s);
@ -1743,11 +1759,11 @@ void dotileeffects(sprite_t *s) {
// initial transition to a new level
void drawlevel(void) {
int x,y;
int dstx,dsty,xdis,ydis,dis;
int dstx,dsty,xdis,ydis;
int turns;
int pspeed;
double pxspeed,pyspeed;
SDL_Rect area,dst;
int speed = TILEW;
int speed = 8;
SDL_Surface *playerbg;
/* TODO: chekc for memory leak here with temps -
@ -1788,42 +1804,40 @@ void drawlevel(void) {
// figure out distance to newposition
xdis = player->x - dstx; if (xdis < 0) xdis = -xdis;
ydis = player->y - dsty; if (ydis < 0) ydis = -ydis;
if (xdis > ydis) dis = xdis;
else dis = ydis;
// figure out how many loops it will take to scroll to the next level
switch (oldexitdir) {
case D_LEFT:
case D_RIGHT:
turns = 640 / TILEW;
turns = 640 / speed;
break;
case D_UP:
case D_DOWN:
default:
turns = 480 / TILEH;
turns = 480 / speed;
break;
}
turns -= 4; // just to be safe
turns -= 2; // just to be safe
// figure out how fast player needs to move to get there in time
pspeed = dis / turns;
pxspeed = ceil((double)xdis / (double)turns); if (pxspeed < 1) pxspeed = 1;
pyspeed = ceil((double)ydis / (double)turns); if (pyspeed < 1) pyspeed = 1;
if (oldexitdir == D_LEFT) {
// blit a column at a time to the real screen, shuffling
// the real one along.
for (x = 0; x < 640; x += speed) {
// move player
movetostart(player,dstx,dsty,pspeed);
movetostart(player,dstx,dsty,pxspeed,pyspeed);
// shuffle real screen
area.x = 0;
area.y = 0;
area.w = 640-TILEW;
area.w = 640-speed;
area.h = 480;
dst.x = TILEW;
dst.x = speed;
dst.y = 0;
dst.w = 0;
dst.h = 0;
@ -1832,11 +1846,9 @@ void drawlevel(void) {
// blit next column from temp surface (take last column first)
area.x = 640-x;
area.y = 0;
area.w = TILEW;
area.w = speed;
area.h = 480;
dst.x = 0;
dst.y = 0;
dst.w = 0;
@ -1850,7 +1862,9 @@ void drawlevel(void) {
drawsprite(player);
// update screen
SDL_GL_SwapBuffers();
SDL_UpdateRect(screen, 0,0,640,480);
SDL_framerateDelay(&manager);
// remove player
area.x = player->x - player->img->w/2;
@ -1864,16 +1878,16 @@ void drawlevel(void) {
// the real one along.
for (y = 0; y < 480; y += speed) {
// move player
movetostart(player,dstx,dsty,pspeed);
movetostart(player,dstx,dsty,pxspeed,pyspeed);
// shuffle real screen
area.x = 0;
area.y = 0;
area.w = 640;
area.h = 480-TILEH;
area.h = 480-speed;
dst.x = 0;
dst.y = TILEH;
dst.y = speed;
dst.w = 0;
dst.h = 0;
SDL_BlitSurface(screen, &area, screen, &dst);
@ -1882,7 +1896,7 @@ void drawlevel(void) {
area.x = 0;
area.y = 480-y;
area.w = 640;
area.h = TILEH;
area.h = speed;
dst.x = 0;
dst.y = 0;
@ -1897,7 +1911,9 @@ void drawlevel(void) {
drawsprite(player);
// update screen
SDL_GL_SwapBuffers();
SDL_UpdateRect(screen, 0,0,640,480);
SDL_framerateDelay(&manager);
// remove player
area.x = player->x - player->img->w/2;
@ -1911,13 +1927,13 @@ void drawlevel(void) {
// the real one along.
for (y = 0; y < 480; y += speed) {
// move player
movetostart(player,dstx,dsty,pspeed);
movetostart(player,dstx,dsty,pxspeed,pyspeed);
// shuffle real screen
area.x = 0;
area.y = TILEH;
area.y = speed;
area.w = 640;
area.h = 480-TILEH;
area.h = 480-speed;
dst.x = 0;
dst.y = 0;
@ -1929,10 +1945,10 @@ void drawlevel(void) {
area.x = 0;
area.y = y;
area.w = 640;
area.h = TILEH;
area.h = speed;
dst.x = 0;
dst.y = 480-TILEH;
dst.y = 480-speed;
dst.w = 0;
dst.h = 0;
SDL_BlitSurface(temps, &area, screen, &dst);
@ -1944,7 +1960,9 @@ void drawlevel(void) {
drawsprite(player);
// update screen
SDL_GL_SwapBuffers();
SDL_UpdateRect(screen, 0,0,640,480);
SDL_framerateDelay(&manager);
// remove player
area.x = player->x - player->img->w/2;
@ -1953,18 +1971,17 @@ void drawlevel(void) {
area.h = 0;
SDL_BlitSurface(playerbg, NULL, screen, &area );
}
} else { // right, or default
} else { // RIGHT right, or default
// blit a column at a time to the real screen, shuffling
// the real one along.
for (x = 0; x < 640; x += speed) {
// move player
movetostart(player,dstx,dsty,pspeed);
movetostart(player,dstx,dsty,pxspeed,pyspeed);
// shuffle real screen
area.x = TILEW;
area.x = speed;
area.y = 0;
area.w = 640-TILEW;
area.w = 640-speed;
area.h = 480;
dst.x = 0;
@ -1976,10 +1993,10 @@ void drawlevel(void) {
// blit next column from temp surface (take last column first)
area.x = x;
area.y = 0;
area.w = TILEW;
area.w = speed;
area.h = 480;
dst.x = 640-TILEW;
dst.x = 640-speed;
dst.y = 0;
dst.w = 0;
dst.h = 0;
@ -1992,7 +2009,9 @@ void drawlevel(void) {
drawsprite(player);
// update screen
SDL_GL_SwapBuffers();
SDL_UpdateRect(screen, 0,0,640,480);
SDL_framerateDelay(&manager);
// remove player
area.x = player->x - player->img->w/2;
@ -2111,7 +2130,7 @@ void drawscore(void) {
sprintf(tempm, "%d",player->score);
/* shadow */
score = TTF_RenderText_Solid(font[14], tempm, black);
score = TTF_RenderText_Solid(font[TEXTSIZE_SCORE], tempm, black);
area.x = 18;
area.y = 7;
area.w = 0;
@ -2119,7 +2138,7 @@ void drawscore(void) {
SDL_BlitSurface(score, NULL, screen, &area);
SDL_FreeSurface(score);
/* score */
score = TTF_RenderText_Solid(font[14], tempm, green);
score = TTF_RenderText_Solid(font[TEXTSIZE_SCORE], tempm, red);
area.x = 20;
area.y = 5;
area.w = 0;
@ -2141,6 +2160,21 @@ void drawtext(void) {
}
t->img = TTF_RenderText_Solid(font[t->size], t->txt, *t->c);
// make sure it's on the screen (leave space for border)
if (t->x - (t->img->w / 2) < 2) { // left
t->x = 2 + (t->img->w/2);
}
if (t->x + (t->img->w / 2) > 640-2) { // right
t->x = 640-2 - (t->img->w/2);
}
if (t->y - (t->img->h / 2) < 2) { // top
t->y = 2 + (t->img->h/2);
}
if (t->y + (t->img->h / 2) > 480-2) { // bottom
t->y = 480-2 - (t->img->h/2);
}
/* get bg */
t->bgarea.x = t->x - t->img->w/2;
t->bgarea.y = t->y - t->img->h/2;
@ -2508,8 +2542,10 @@ void dogravity(sprite_t *s) {
attop = B_TRUE;
}
if (isonground(s)) {
//if (isonground(s)) {
if (isongroundpoint(s, s->x, s->y)) {
if (!isongroundpoint(s, s->x, s->y-1)) {
attop = B_TRUE;
attop = B_TRUE;
}
}
@ -2742,7 +2778,7 @@ void dogravity(sprite_t *s) {
}
if (pointsinc > 250) {
sprintf(tempm, "%d",pointsinc);
addtext(xnet,ynet-TILEH, psize, tempm, &white,POINTSDELAY);
addoutlinetext(xnet,ynet-TILEH, psize, tempm, &white,&black,POINTSDELAY);
/* give points to player */
s->score += pointsinc;
}
@ -2846,7 +2882,7 @@ int dofruiteffect(sprite_t *s) {
if (s->id == P_SPEED) {
playfx(FX_POWERUP);
player->speed = 2;
addtext(s->x,s->y - s->img->h/2, TEXTSIZE_POINTS, "Speed up!", &white,POINTSDELAY);
addoutlinetext(s->x,s->y - s->img->h/2, TEXTSIZE_POINTS, "Speed up!", &white,&black,POINTSDELAY);
return B_TRUE;
} else if (s->id == P_NUMNETS) {
playfx(FX_POWERUP);
@ -2854,32 +2890,32 @@ int dofruiteffect(sprite_t *s) {
player->netmax++;
}
sprintf(tempm, "%d nets!",player->netmax);
addtext(s->x,s->y - s->img->h/2, TEXTSIZE_POINTS, tempm,&white,POINTSDELAY);
addoutlinetext(s->x,s->y - s->img->h/2, TEXTSIZE_POINTS, tempm,&white,&black,POINTSDELAY);
return B_TRUE;
} else if (s->id == P_BIGNET) {
playfx(FX_POWERUP);
player->netbig = B_TRUE;
sprintf(tempm, "Big net!");
addtext(s->x,s->y - s->img->h/2, TEXTSIZE_POINTS, tempm,&white,POINTSDELAY);
addoutlinetext(s->x,s->y - s->img->h/2, TEXTSIZE_POINTS, tempm,&white,&black,POINTSDELAY);
return B_TRUE;
} else if (s->id == P_MACEPOWERUP) {
playfx(FX_POWERUP);
player->powerup = PW_MACE;
sprintf(tempm, "Mace Slam!");
addtext(s->x,s->y - s->img->h/2, TEXTSIZE_POINTS, tempm,&white,POINTSDELAY);
addoutlinetext(s->x,s->y - s->img->h/2, TEXTSIZE_POINTS, tempm,&white,&black,POINTSDELAY);
return B_TRUE;
} else if (s->id == P_BOXING) {
playfx(FX_POWERUP);
player->powerup = PW_BOXING;
sprintf(tempm, "Boxing Glove!");
addtext(s->x,s->y - s->img->h/2, TEXTSIZE_POINTS, tempm,&white,POINTSDELAY);
addoutlinetext(s->x,s->y - s->img->h/2, TEXTSIZE_POINTS, tempm,&white,&black,POINTSDELAY);
return B_TRUE;
} else if (s->id == P_FTODIAMOND) {
sprite_t *s2, *nexts;
// convert all flowers to diamonds
playfx(FX_MORPH);
sprintf(tempm, "Make diamonds!");
addtext(s->x,s->y - s->img->h/2, TEXTSIZE_POINTS, tempm,&white,POINTSDELAY);
addoutlinetext(s->x,s->y - s->img->h/2, TEXTSIZE_POINTS, tempm,&white,&black,POINTSDELAY);
for (s2 = sprite; s2 ; s2 = nexts) {
nexts = s2->next;
if (isflower(s2->id)) {
@ -2903,7 +2939,7 @@ int dofruiteffect(sprite_t *s) {
// convert all flowers to gems
playfx(FX_MORPH);
sprintf(tempm, "Make gems!");
addtext(s->x,s->y - s->img->h/2, TEXTSIZE_POINTS, tempm,&white,POINTSDELAY);
addoutlinetext(s->x,s->y - s->img->h/2, TEXTSIZE_POINTS, tempm,&white,&black,POINTSDELAY);
for (s2 = sprite; s2 ; s2 = nexts) {
nexts = s2->next;
if (isflower(s2->id)) {
@ -2962,8 +2998,8 @@ int dofruiteffect(sprite_t *s) {
// kill all monsters
playfx(FX_BOOM);
sprintf(tempm, "BOMB!");
addtext(s->x,s->y - s->img->h/2, TEXTSIZE_POINTS, tempm,&white,POINTSDELAY);
sprintf(tempm, "KABOOM!!");
addoutlinetext(s->x,s->y - s->img->h/2, TEXTSIZE_BOMB, tempm,&red,&yellow,POINTSDELAY);
for (s2 = sprite; s2 ; s2 = nexts) {
nexts = s2->next;
if (isbullet(s2->id)) {
@ -2977,7 +3013,7 @@ int dofruiteffect(sprite_t *s) {
} else if (s->id == P_SHIELD) {
playfx(FX_POWERUP);
sprintf(tempm, "Shield!");
addtext(s->x,s->y - s->img->h/2, TEXTSIZE_POINTS, tempm,&white,POINTSDELAY);
addoutlinetext(s->x,s->y - s->img->h/2, TEXTSIZE_POINTS, tempm,&white,&black,POINTSDELAY);
// temp invincibility
player->invuln = SHIELDTIME;
@ -2985,7 +3021,8 @@ int dofruiteffect(sprite_t *s) {
return B_TRUE;
} else if (s->id == P_HELP) {
playfx(FX_POWERUP);
addtext(320,240,TEXTSIZE_HELP, s->name, &white,HELPDELAY);
// TODO: move other HELP text around if need be!
addoutlinetext(320,240,TEXTSIZE_HELP, s->name, &white,&black,HELPDELAY);
return B_TRUE;
} else if (isflower(s->id)) {
int xx;
@ -3030,7 +3067,7 @@ int dofruiteffect(sprite_t *s) {
}
playfx(FX_BONUS);
sprintf(tempm, "BONUS!");
addtext(s->x,s->y - s->img->h/2, TEXTSIZE_BONUS, tempm,&white,BONUSDELAY);
addoutlinetext(s->x,s->y - s->img->h/2, TEXTSIZE_BONUS, tempm,&white,&black,BONUSDELAY);
return B_TRUE;
}
}
@ -3176,21 +3213,21 @@ void channeldone(int channel) {
// move player towards new position
void movetostart(sprite_t *p, int dstx, int dsty, int speed) {
void movetostart(sprite_t *p, int dstx, int dsty, double xspeed, double yspeed) {
if (p->x < dstx) {
p->x += speed;
p->x += xspeed;
if (p->x > dstx) p->x = dstx;
}
if (p->x > dstx) {
p->x -= speed;
p->x -= xspeed;
if (p->x < dstx) p->x = dstx;
}
if (p->y < dsty) {
p->y += speed;
p->y += yspeed;
if (p->y > dsty) p->y = dsty;
}
if (p->y > dsty) {
p->y -= speed;
p->y -= yspeed;
if (p->y < dsty) p->y = dsty;
}
}
@ -3213,6 +3250,7 @@ SDL_Surface *grabbehind(sprite_t *s, SDL_Surface *surf) {
int randompowerup(void) {
int num;
num = rand() % 9;
return P_BOXING;
switch (num) {
case 0:
@ -3255,3 +3293,15 @@ void dumpsprites(void) {
printf("Total monsters: %d\n",mcount);
printf("\n\n");
}
void addoutlinetext(int x, int y, int size, char *msg, SDL_Color *col, SDL_Color *bgcol, int delay) {
addtext(x-1,y,size,msg,bgcol,delay); // outline
addtext(x-1,y-1,size,msg,bgcol,delay); // outline
addtext(x,y-1,size,msg,bgcol,delay); // outline
addtext(x+1,y-1,size,msg,bgcol,delay); // outline
addtext(x+1,y,size,msg,bgcol,delay); // outline
addtext(x+1,y+1,size,msg,bgcol,delay); // outline
addtext(x,y+1,size,msg,bgcol,delay); // outline
addtext(x-1,y+1,size,msg,bgcol,delay); // outline
addtext(x,y,size,msg,col,delay); // main text
}

3
rc.h
View File

@ -1,5 +1,6 @@
void cleanup(void);
int addtext(int x, int y, int size, char *string, SDL_Color *c, int delay);
void addoutlinetext(int x, int y, int size, char *msg, SDL_Color *col, SDL_Color *bgcol, int delay);
void drawscore(void);
void drawtext(void);
void movetext(void);
@ -39,7 +40,7 @@ void playfx(int num);
void playmusic(Mix_Music *toplay);
void stopmusic(void);
void channeldone(int channel);
void movetostart(sprite_t *p, int dstx, int dsty, int speed);
void movetostart(sprite_t *p, int dstx, int dsty, double xspeed,double yspeed);
SDL_Surface *grabbehind(sprite_t *s, SDL_Surface *surf);
int randompowerup(void);
void dumpsprites(void);

BIN
right.bmp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

130
shared.c
View File

@ -71,7 +71,7 @@ int loadlevel(int wnum, int lnum) {
if (level->animtiles) free(level->animtiles);
level->id = 0;
level->id = levelentry[lnum].id;
//sprintf(level->name, "Level %d-%d",wnum,lnum);
sprintf(level->name, "\"%s\"",levelentry[lnum].desc);
level->prev = NULL;
@ -990,44 +990,44 @@ int loadimagesets(void) {
loadspriteimage(P_PLAYER,F_SLAM5, "sprites/dslam5.png");
imageset[P_PLAYER].numimages = 16;
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");
loadspriteimage(P_SNAKE,F_WALK1, "sprites/snake.png");
loadspriteimage(P_SNAKE,F_JUMP, "sprites/snakejump.png");
loadspriteimage(P_SNAKE,F_FALL, "sprites/snakejump.png");
loadspriteimage(P_SNAKE,F_CAUGHT, "sprites/snakecaught.png");
loadspriteimage(P_SNAKE,F_DEAD, "sprites/snakedead.png");
/* next 3 are auto generated */
imageset[P_SNAKE].numimages = 8;
loadspriteimage(P_RAT,F_WALK1, "sprites/rat.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");
loadspriteimage(P_RAT,F_WALK1, "sprites/rat.png");
loadspriteimage(P_RAT,F_JUMP, "sprites/ratjump.png");
loadspriteimage(P_RAT,F_FALL, "sprites/ratjump.png");
loadspriteimage(P_RAT,F_CAUGHT, "sprites/ratcaught.png");
loadspriteimage(P_RAT,F_DEAD, "sprites/ratdead.png");
/* next 3 are auto generated */
imageset[P_RAT].numimages = 8;
loadspriteimage(P_BEE,F_WALK1, "sprites/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");
loadspriteimage(P_BEE,F_WALK1, "sprites/newbee.png");
loadspriteimage(P_BEE,F_JUMP, "sprites/newbeejump.png");
loadspriteimage(P_BEE,F_FALL, "sprites/newbeejump.png");
loadspriteimage(P_BEE,F_CAUGHT, "sprites/newbeecaught.png");
loadspriteimage(P_BEE,F_DEAD, "sprites/newbeedead.png");
/* next 3 are auto generated */
imageset[P_BEE].numimages = 8;
loadspriteimage(P_SPIDER,F_WALK1, "sprites/spider.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");
loadspriteimage(P_SPIDER,F_WALK1, "sprites/spider.png");
loadspriteimage(P_SPIDER,F_JUMP, "sprites/spiderjump.png");
loadspriteimage(P_SPIDER,F_FALL, "sprites/spiderfall.png");
loadspriteimage(P_SPIDER,F_CAUGHT, "sprites/spidercaught.png");
loadspriteimage(P_SPIDER,F_DEAD, "sprites/spiderdead.png");
/* next 3 are auto generated */
imageset[P_SPIDER].numimages = 8;
loadspriteimage(P_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");
loadspriteimage(P_CLOUD,F_WALK1, "sprites/cloud.png");
loadspriteimage(P_CLOUD,F_JUMP, "sprites/cloud.png");
loadspriteimage(P_CLOUD,F_FALL, "sprites/cloud.png");
loadspriteimage(P_CLOUD,F_CAUGHT, "sprites/cloud.png");
loadspriteimage(P_CLOUD,F_DEAD, "sprites/cloud.png");
imageset[P_CLOUD].numimages = 2;
loadspriteimage(P_COKE,F_WALK1, "sprites/coke.png");
@ -1038,28 +1038,28 @@ int loadimagesets(void) {
imageset[P_COKE].numimages = 8;
/* fruits / powerups */
loadspriteimage(P_CHEESE,F_WALK1, "sprites/cheese.bmp");
loadspriteimage(P_CHEESE,F_WALK1, "sprites/cheese.png");
imageset[P_CHEESE].numimages = 1;
loadspriteimage(P_ICECREAM,F_WALK1, "sprites/icecream.bmp");
loadspriteimage(P_ICECREAM,F_WALK1, "sprites/icecream.png");
imageset[P_ICECREAM].numimages = 1;
loadspriteimage(P_CHIPS,F_WALK1, "sprites/chips.bmp");
loadspriteimage(P_CHIPS,F_WALK1, "sprites/chips.png");
imageset[P_CHIPS].numimages = 1;
loadspriteimage(P_BURGER,F_WALK1, "sprites/burger.bmp");
loadspriteimage(P_BURGER,F_WALK1, "sprites/burger.png");
imageset[P_BURGER].numimages = 1;
loadspriteimage(P_SPEED,F_WALK1, "sprites/speed.bmp");
loadspriteimage(P_SPEED,F_WALK1, "sprites/speed.png");
imageset[P_SPEED].numimages = 1;
loadspriteimage(P_NUMNETS,F_WALK1, "sprites/numnets.bmp");
loadspriteimage(P_NUMNETS,F_WALK1, "sprites/numnets.png");
imageset[P_NUMNETS].numimages = 1;
loadspriteimage(P_BIGNET,F_WALK1, "sprites/bignet.bmp");
loadspriteimage(P_BIGNET,F_WALK1, "sprites/bignet.png");
imageset[P_BIGNET].numimages = 1;
loadspriteimage(P_HELP,F_WALK1, "sprites/help.bmp");
loadspriteimage(P_HELP,F_WALK1, "sprites/help.png");
imageset[P_HELP].numimages = 1;
loadspriteimage(P_FLOWERYELLOW,F_WALK1, "sprites/flower-yellow.png");
@ -1119,7 +1119,7 @@ int loadimagesets(void) {
imageset[P_PUFF].numimages = PUFFFRAMES;
/* bullets */
loadspriteimage(P_SPIT,F_WALK1, "sprites/spit.bmp");
loadspriteimage(P_SPIT,F_WALK1, "sprites/spit.png");
imageset[P_SPIT].numimages = 1;
@ -1127,17 +1127,18 @@ int loadimagesets(void) {
/* generate rotated/flipped images */
for (p = 0; p < MAXPTYPES; p++) {
int fr;
int angle = 90;
/* rotated */
// TODO: need to free tempimg ? */
if (!isfruit(p) && !isbullet(p) && !iseffect(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 (fr = F_DEAD2; fr <= F_DEAD4; fr++) {
if (!imageset[p].img[fr]) {
tempimg = rotozoomSurface(imageset[p].img[F_DEAD],angle,1,0);
imageset[p].img[fr] = SDL_DisplayFormat(tempimg);
}
angle += 90;
}
}
for (i = 0; i < imageset[p].numimages; i++) {
@ -1158,6 +1159,8 @@ int loadimagesets(void) {
/* angry image */
// create semi-transparent red square
reds = SDL_CreateRGBSurface(SDL_SWSURFACE,
origi->w,
origi->h,
@ -1166,21 +1169,29 @@ int loadimagesets(void) {
SDL_FillRect(reds, NULL, SDL_MapRGB(reds->format, 255, 0, 0));
SDL_SetAlpha(reds, SDL_SRCALPHA,100);
// take a copy of the original image
imageset[p].img[MAXFRAMES*2+i] = rotozoomSurfaceXY(origi, 0, 1,1,0);
// paste the transparent one on top of it
SDL_BlitSurface(reds, NULL, imageset[p].img[MAXFRAMES*2+i], NULL);
SDL_FreeSurface(reds);
// Convert the reddened image to the screen format
temps = SDL_DisplayFormat(imageset[p].img[MAXFRAMES*2+i]);
SDL_FreeSurface(imageset[p].img[MAXFRAMES*2+i]);
imageset[p].img[MAXFRAMES*2+i] = temps;
// Make the background red bits completely transparent
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 */
imageset[p].img[MAXFRAMES*3+i] = rotozoomSurfaceXY(imageset[p].img[MAXFRAMES*2+i], 0, -1,1,0);
/* flipped angry image */
/*
reds = SDL_CreateRGBSurface(SDL_SWSURFACE,
origi->w,
origi->h,
@ -1201,6 +1212,7 @@ int loadimagesets(void) {
SDL_SetColorKey(imageset[p].img[MAXFRAMES*3+i],
SDL_SRCCOLORKEY, SDL_MapRGB(imageset[p].img[MAXFRAMES*3+i]->format, 101, 0, 0));
*/
}
}
@ -1487,6 +1499,27 @@ int iseffect(int id) {
return B_FALSE;
}
#ifdef OPENGL
inline void drawpixel16(SDL_Surface *screen, int x, int y, SDL_Color c)
{
Uint8 *bufp;
/* check x/y */
if (x >= screen->w) return;
if (y >= screen->h) return;
if (x < 0) return;
if (y < 0) return;
// bufp = (Uint16 *)screen->pixels + (y*screen->pitch / 2) + x;
bufp = (Uint8 *)screen->pixels + y * screen->pitch + x * 4;
// *bufp = SDL_MapRGB(screen->format, c.r, c.g, c.b);
*(Uint32 *)bufp = SDL_MapRGB(screen->format, c.r, c.g, c.b);
}
#else
inline void drawpixel16(SDL_Surface *screen, int x, int y, SDL_Color c)
{
@ -1502,6 +1535,7 @@ inline void drawpixel16(SDL_Surface *screen, int x, int y, SDL_Color c)
*bufp = SDL_MapRGB(screen->format, c.r, c.g, c.b);
}
#endif
void drawline16(SDL_Surface *screen, int x1, int y1, int x2, int y2, SDL_Color c) {
int deltax, deltay;
@ -1898,11 +1932,16 @@ int loadlevellist(void) {
f = fopen("levels.dat","r");
// format is:
//
// dummy,filename,description,
// id,filename,description,
lev = 1;
fgets(buf, BUFLEN, f);
while (!feof(f)) {
p = strtok(buf, ",");
if (!p) {
printf("invalid level id - line %d\n",lev);
return B_TRUE;
}
levelentry[lev].id = atoi(p);
p = strtok(NULL, ",");
if (!p) {
printf("invalid level filename - line %d\n",lev);
@ -1920,8 +1959,9 @@ int loadlevellist(void) {
fgets(buf, BUFLEN, f);
}
fclose(f);
numlevels = lev;
printf("Read %d levels.\n",lev);
printf("Read %d levels.\n",numlevels);
return B_FALSE;
}

BIN
sky.bmp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

BIN
sprites/bignet.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

BIN
sprites/help.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

BIN
sprites/numnets.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

BIN
sprites/speed.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 278 B

View File

@ -4,7 +4,7 @@ hurryup 30
endmaps
help
Use X to jump, Z to catch the rat.
Once caught, Down+Z will slam and kill a monster!
Then use Down+Z to slam and kill a monster!
endhelp
monsters
1 3 19

View File

@ -5,15 +5,16 @@ endmaps
help
endhelp
monsters
1 15 12
1 31 24
! 3 12
P 25 21
P 24 21
P 23 21
P 26 21
r 37 3
r 20 6
r 9 6
s 10 8
r 36 24
r 37 21
r 37 18
r 36 15
endmonsters
exitdir 1
17,17,17,17,17,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,4,
@ -29,18 +30,18 @@ exitdir 1
4,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
4,1,1,1,1,20,20,20,20,20,20,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
4,15,15,15,15,15,15,15,1,16,16,16,16,16,16,1,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
4,15,15,15,15,15,15,15,1,15,15,15,15,15,15,1,0,7,0,0,20,20,20,20,20,20,20,20,20,20,20,0,0,0,0,0,0,0,0,4,
4,15,15,15,15,15,15,15,1,15,15,15,15,15,15,1,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
4,15,15,15,15,15,15,15,1,15,15,15,15,15,15,1,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
4,1,1,1,1,20,20,20,20,20,20,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,1,1,1,1,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,1,0,0,0,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,1,0,0,0,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,1,1,1,1,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,1,0,0,0,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,1,0,0,0,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,1,1,1,1,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,1,0,0,0,4,
4,15,15,15,15,15,15,15,1,16,16,16,16,16,16,1,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,1,0,0,0,4,
4,15,15,15,15,15,15,15,1,15,15,15,15,15,15,1,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,1,1,1,1,4,
4,15,15,15,15,15,15,15,1,15,15,15,15,15,15,1,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,1,0,0,0,4,
4,15,15,15,15,15,15,15,1,15,15,15,15,15,15,1,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,1,0,0,0,4,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,