diff --git a/Makefile b/Makefile index 315e428..06845cc 100644 --- a/Makefile +++ b/Makefile @@ -1,2 +1,2 @@ rc: rc.c rc.h - gcc -mwindows -Wall -orc -g rc.c `sdl-config --cflags --libs` -I/usr/local/include -L/usr/local/lib -lSDLmain -lSDL -lSDL_image -lSDL_gfx + gcc -mwindows -mno-cygwin -Wall -orc.exe -DWINDOWS -g rc.c `sdl-config --cflags --libs` -I/usr/local/include -lmingw32 -L/usr/local/lib -lSDLmain -lSDL -lSDL_image -lSDL_gfx -lSDL_ttf diff --git a/Makefile.posix b/Makefile.posix index 315e428..1afd334 100644 --- a/Makefile.posix +++ b/Makefile.posix @@ -1,2 +1,2 @@ rc: rc.c rc.h - gcc -mwindows -Wall -orc -g rc.c `sdl-config --cflags --libs` -I/usr/local/include -L/usr/local/lib -lSDLmain -lSDL -lSDL_image -lSDL_gfx + gcc -mwindows -Wall -orc -g rc.c `sdl-config --cflags --libs` -I/usr/local/include -L/usr/local/lib -lSDLmain -lSDL -lSDL_image -lSDL_gfx -lSDL_ttf diff --git a/Makefile.windows b/Makefile.windows index 619fd17..06845cc 100644 --- a/Makefile.windows +++ b/Makefile.windows @@ -1,2 +1,2 @@ rc: rc.c rc.h - gcc -mwindows -mno-cygwin -Wall -orc.exe -DWINDOWS -g rc.c `sdl-config --cflags --libs` -I/usr/local/include -lmingw32 -L/usr/local/lib -lSDLmain -lSDL -lSDL_image -lSDL_gfx + gcc -mwindows -mno-cygwin -Wall -orc.exe -DWINDOWS -g rc.c `sdl-config --cflags --libs` -I/usr/local/include -lmingw32 -L/usr/local/lib -lSDLmain -lSDL -lSDL_image -lSDL_gfx -lSDL_ttf diff --git a/level1.dat b/level1.dat index cf2e782..af6b07f 100644 --- a/level1.dat +++ b/level1.dat @@ -8,25 +8,25 @@ bg 0 *000000~~~~~~~~~~~~**000000000000000000* *00000000000000000000000000000000000000* *00000000000000000000000000000000000000* -*00000000000000001000000000000000000000* +*0000000000000000000000r000000000000000* *000000000000~~~~~~~~~~~~~~~00000000000* *00000000000000000000000000000000000000* *00000000000000000000000000000000000000* -*0000000000r000000000000000000000r00000* -*000~~~~~~~~~~~~~~0000~~~~~0000~~~~~000* +*00000000000000000000000000000000000000* +*00000000000000/~~~~~~~~~\0000000000000* +*0000000000000/***********\000000000000* +*000000000000/**000000000**\00000000000* +*00000000000/***0000000r0***\0000000000* +*000~~~~~~~~~~~~~~0000~~~~~~~~~~~~~~000* +*00000000000000000000000000000000000000* +*00000000000000000000000000000000000000* +*00000000000r000000000000000r0000000000* +*000000000~~~~0000000000000~~~~00000000* *00000000000000000000000000000000000000* *00000000000000000000000000000000000000* *000000000000000000000000r0000000000000* *000~~~~~0000~~~~~0000~~~~~~~~~~~~~~000* -*00000000000000000000000000000000000000* -*00000000000000000000000000000000000000* -*00000000000r00000000000000000000000000* -*000~~~~~~~~~~~~~~0000~~~~~0000~~~~~000* -*00000000000000000000000000000000000000* -*00000000000000000000000000000000000000* -*000000000000000000000000r0000000000000* -*000~~~~~0000~~~~~0000~~~~~~~~~~~~~~000* -*00000000000000000000000000000000000000* -*00000000000000000000000000000000000000* -*00000000000000000000000000000000000000* +*0000000000000000*0000*0000000000000000* +*0000000000000000*0000*0000000000000000* +*0010000000000000*^^^^*0000000r00000000* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/rat.bmp b/rat.bmp index dc2a660..0ee5d24 100644 Binary files a/rat.bmp and b/rat.bmp differ diff --git a/rc.c b/rc.c index 213fac0..0860607 100644 --- a/rc.c +++ b/rc.c @@ -12,10 +12,14 @@ #include #include #include +#include #include "rc.h" SDL_Surface *screen; +TTF_Font *font[MAXLETTERHEIGHT]; + +char tempm[BUFLEN]; int curlevelnum = 1; level_t *curlevel; @@ -24,6 +28,8 @@ sprite_t *sprite = NULL; /* main sprite list */ sprite_t *player; sprite_t *lastsprite; +text_t *text, *lasttext; + SDL_Color red = {255, 0, 0, 0}; SDL_Color white = {255, 255, 255, 0}; @@ -33,6 +39,8 @@ int toggletimer = 0; int main (int argc, char **argv) { Uint8 *keys; sprite_t *s,*nextsprite; + char filename[BUFLEN]; + int i; if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE)==-1) { printf("SDL_Init: %s\n", SDL_GetError()); @@ -43,14 +51,26 @@ int main (int argc, char **argv) { screen = SDL_SetVideoMode(640,480,16,SDL_HWSURFACE|SDL_DOUBLEBUF); - if (loadimagesets()) { return 1; } + + /* load fonts */ + TTF_Init(); + sprintf(filename, "verdana.ttf"); + for (i = 1; i < MAXLETTERHEIGHT; i++) { + font[i] = TTF_OpenFont(filename,i); + if (!font[i]) { + printf("Error opening font: %s\n", TTF_GetError()); + return 1; + } + } + if (loadlevel(curlevelnum)) { return 1; } + drawlevel(); SDL_Flip(screen); @@ -59,6 +79,7 @@ int main (int argc, char **argv) { printf("player y is %0.1f\n",player->y); fflush(stdout); while (1) { + removetext(); /* remove player */ for (s = sprite ; s ; s = s->next) { removesprite(s); @@ -85,6 +106,11 @@ fflush(stdout); toggletimer = 50; } } + if (keys[SDLK_q]) { + if (text == NULL) { + addtext(100,100,32,"Test"); + } + } if (keys[SDLK_ESCAPE]) { return 1; } @@ -137,11 +163,13 @@ fflush(stdout); player->netystart = player->y; } } else { - /* shoot net */ - player->netting = 1; - player->netspeed = NETSPEED; - player->netlen = 0; - player->netdir = player->dir; + if (player->netcaught < player->netmax) { + /* shoot net */ + player->netting = 1; + player->netspeed = NETSPEED; + player->netlen = 0; + player->netdir = player->dir; + } } } } @@ -149,6 +177,7 @@ fflush(stdout); for (s = sprite; s ; s = s->next) { movesprite(s); } + movetext(); /* gravity */ @@ -166,6 +195,9 @@ fflush(stdout); checkcollide(s); } + /* draw text */ + drawtext(); + drawnetting(player); /* draw player */ @@ -182,8 +214,12 @@ fflush(stdout); } - void cleanup(void) { + int i; + for (i = 1; i < MAXLETTERHEIGHT; i++) { + TTF_CloseFont(font[i]); + } + TTF_Quit(); SDL_Quit(); } @@ -200,14 +236,19 @@ void checkcollide(sprite_t *s) { if (collide) { /* check for colission with our net */ if ((s->netting) && (!s2->caughtby)) { - xdiff = (s->x + s->netlen*s->netdir) - s2->x; - if (xdiff < 0) xdiff = -xdiff; - ydiff = s->netystart - s2->y; - if (ydiff < 0) ydiff = -ydiff; + if (s->netcaught < s->netmax) { + xdiff = (s->x + s->netlen*s->netdir) - s2->x; + if (xdiff < 0) xdiff = -xdiff; + ydiff = s->netystart - s2->y; + if (ydiff < 0) ydiff = -ydiff; - if ((xdiff <= s2->img->w) && (ydiff <= s2->img->h)) { - s2->caughtby = s; - s2->caughtstate = 1; + if ((xdiff <= s2->img->w) && (ydiff <= s2->img->h)) { + s2->caughtby = s; + s2->jumping = 0; + s2->falling = 0; + s2->caughtstate = 1; + s->netcaught++; + } } } else { /* check for collision with us */ @@ -223,7 +264,10 @@ void checkcollide(sprite_t *s) { if (s == player) { /* kill the fruit */ s2->dead = 4; + /* draw text */ + addtext(s2->x,s2->y - s2->img->h/2, 16, "100"); /* give points to the player */ + } } if (ismonster(s2->id)) { @@ -313,12 +357,12 @@ void movesprite(sprite_t *s) { } else if (s->dead == 3) { /* final fall */ s->x += s->xs; s->y += s->ys; - if (s->x >= (640-(s->img->w/2))) { + if (s->x >= (640-TILEW)) { if (s->xs > 0) { s->xs = -s->xs; s->bounces++; } - } else if (s->x <= s->img->w/2) { + } else if (s->x <= TILEW) { if (s->xs < 0) { s->xs = -s->xs; s->bounces++; @@ -338,7 +382,6 @@ void movesprite(sprite_t *s) { } - if ((s->ys > 0) && (s->y >= TILEH)) { if (isonground(s)) { int x,y,ty; @@ -347,6 +390,10 @@ void movesprite(sprite_t *s) { x = s->x; gettileat(s->x,s->y-1,NULL,&ty); y = ty*TILEH + TILEH - 2; + + /* make sure it's within the screen */ + if (x > (640-TILEW)) x = 640-TILEW; + if (x < (TILEW)) x = TILEW; addsprite(P_CHEESE, x, y, "Cheese"); } } @@ -362,16 +409,82 @@ void movesprite(sprite_t *s) { if (s->id == P_RAT) { if (!s->falling) { tiletype_t *tt; - /* if there's not a hole in front of us, move */ - + int move = B_FALSE; + int xdiff, absxdiff; + + + /* distance to player */ + xdiff = player->x - s->x; + if (xdiff < 0) absxdiff = -xdiff; + else absxdiff = xdiff; + tt = gettileat(s->x + s->dir+s->speed,s->y,NULL,NULL); if (tt->solid == S_NOTSOLID) { - s->dir = -s->dir; + /* if there's a hole in front of us */ + if (player->y > s->y) { + /* if player is below, fall off */ + if (xdiff <= (TILEW*8)) { + move = B_TRUE; + } + } else if (player->y == s->y) { + /* if player is at same level and close, jump */ + if ((s->dir == 1) && (xdiff > 0) && (xdiff <= (TILEW*7))) { + s->jumping = 1; + s->jumpdir = 1; + s->jumpspeed = 5; + } else if ((s->dir == -1) && (xdiff < 0) && (xdiff >= -(TILEW*7))) { + s->jumping = 1; + s->jumpdir = -1; + s->jumpspeed = 5; + } + } } else { + move = B_TRUE; + } + + /* either move or turn around */ + if (move) { rv = movex(s, s->dir*s->speed); if (rv) { + /* if we couldn't move (hit a wall), turn */ s->dir = -s->dir; } + } else { + s->dir = -s->dir; + } + + if ((player->dead == 0) && (!s->jumping)) { + /* if player is above us, jump */ + if (player->y < s->y) { + if ((xdiff >= (TILEW*2)) && (xdiff <= (TILEW*3))) { + /* jump right */ + s->jumpdir = 1; + s->jumping = 1; + s->jumpspeed = 5; + } else if ((xdiff <= -(TILEW*2)) && (xdiff >= -(TILEW*3))) { + /* jump left */ + s->jumpdir = -1; + s->jumping = 1; + s->jumpspeed = 5; + } else if (s->y - player->y <= (TILEH*6)) { + if ((xdiff >= 0) && (xdiff < (TILEW*2))) { + /* jump up */ + s->jumpdir = 0; + s->jumping = 1; + s->jumpspeed = 5; + } else if ((xdiff <= 0) && (xdiff > -(TILEW*2))) { + /* jump up */ + s->jumpdir = 0; + s->jumping = 1; + s->jumpspeed = 5; + } + } else { + /* jump whichever way we're facing */ + s->jumpdir = s->dir; + s->jumping = 1; + s->jumpspeed = 5; + } + } } } } @@ -691,6 +804,8 @@ int loadtiletypes(char *filename) { int loadimagesets(void) { int p,i; + SDL_Surface *tempimg; + imageset[P_PLAYER].img[F_WALK1] = IMG_Load("pdwarf.png"); imageset[P_PLAYER].img[F_JUMP] = IMG_Load("pdwarfjump.png"); imageset[P_PLAYER].img[F_FALL] = IMG_Load("pdwarffall.png"); @@ -700,7 +815,7 @@ int loadimagesets(void) { imageset[P_PLAYER].numimages = 8; imageset[P_RAT].img[F_WALK1] = IMG_Load("rat.bmp"); - imageset[P_RAT].img[F_JUMP] = IMG_Load("rat.bmp"); + imageset[P_RAT].img[F_JUMP] = IMG_Load("ratjump.bmp"); imageset[P_RAT].img[F_FALL] = IMG_Load("rat.bmp"); imageset[P_RAT].img[F_CAUGHT] = IMG_Load("ratcaught.bmp"); imageset[P_RAT].img[F_DEAD] = IMG_Load("ratdead.bmp"); @@ -708,18 +823,25 @@ int loadimagesets(void) { imageset[P_RAT].numimages = 8; imageset[P_CHEESE].img[F_WALK1] = IMG_Load("cheese.bmp"); + imageset[P_CHEESE].img[F_DEAD] = IMG_Load("cheese.bmp"); imageset[P_CHEESE].numimages = 1; /* generate rotated/flipped images */ for (p = 0; p < MAXPTYPES; p++) { - imageset[p].img[F_DEAD2] = rotozoomSurface(imageset[p].img[F_DEAD],90,1,0); - imageset[p].img[F_DEAD3] = rotozoomSurface(imageset[p].img[F_DEAD],180,1,0); - imageset[p].img[F_DEAD4] = rotozoomSurface(imageset[p].img[F_DEAD],270,1,0); + 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_SetColorKey(imageset[p].img[i], SDL_SRCCOLORKEY, SDL_MapRGB(screen->format, 0, 0, 0)); + imageset[p].img[MAXFRAMES+i] = rotozoomSurfaceXY(imageset[p].img[i], 0, -1,1,0); } @@ -735,6 +857,141 @@ double getspeed(int id) { return 1; } +int addtext(int x, int y, int size, char *string) { + text_t *t; + + if (text == NULL) { + text = malloc(sizeof(text_t)); + t = text; + t->prev = NULL; + } else { + t = lasttext; + t->next = malloc(sizeof(text_t)); + t->next->prev = t; + + t = t->next; + } + + t->bg = SDL_CreateRGBSurface(SDL_HWSURFACE, + 300, 110, + screen->format->BitsPerPixel, screen->format->Rmask, + screen->format->Gmask,screen->format->Bmask, + screen->format->Amask); + + t->x = x; + t->y = y; + t->maxsize = size; + t->size = 3; + strcpy(t->txt, string); + t->state = 0; + + t->img = TTF_RenderText_Solid(font[t->size], t->txt, white); + + + t->next = NULL; + lasttext = t; + + return B_FALSE; +} + +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 movetext(void) { + text_t *t,*nextt; + for (t = text ; t ; t = nextt) { + nextt = t->next; + if (t->state == 0) { + t->size += TEXTSPEED; + if (t->size >= t->maxsize) { + t->state = 1; + } + } else if (t->state == TEXTDELAY) { + t->size -= TEXTSPEED; + if (t->size <= 3) { + killtext(t); + } + + } else { + t->state++; + } + } +} + +void drawtext(void) { + text_t *t; + SDL_Rect area; + + for (t = text ; t ; t = t->next) { + + /* create text */ + if (t->img) { + SDL_FreeSurface(t->img); + t->img = NULL; + } + t->img = TTF_RenderText_Solid(font[t->size], t->txt, white); + + /* get bg */ + t->bgarea.x = t->x - t->img->w/2; + t->bgarea.y = t->y - t->img->h/2; + t->bgarea.w = t->img->w; + t->bgarea.h = t->img->h; + SDL_BlitSurface(screen, &t->bgarea, t->bg, NULL); + + /* draw text */ + area.x = t->x - t->img->w/2; + area.y = t->y - t->img->h/2; + area.w = t->img->w; + area.h = t->img->h; + SDL_BlitSurface(t->img,NULL, screen, &area); + } + + +} + +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; + } +} + int addsprite(int id, int x, int y, char *name ) { sprite_t *s; @@ -762,7 +1019,7 @@ int addsprite(int id, int x, int y, char *name ) { if (s == sprite) { s->netbg = SDL_CreateRGBSurface(SDL_HWSURFACE, - 200, 10, + 200, 64, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask,screen->format->Bmask, screen->format->Amask); @@ -774,6 +1031,8 @@ int addsprite(int id, int x, int y, char *name ) { s->jumping = 0; s->jumpdir = 1; s->netting = 0; + s->netmax = 4; + s->netcaught = 0; s->falling = 0; s->fallspeed = 0; s->dir = 1; @@ -818,6 +1077,8 @@ void drawnetting(sprite_t *s) { SDL_Rect area; if (s->netting) { + int y,yy; + int dis; sx = s->x; s->nety = s->y - (s->img->h/2); @@ -830,14 +1091,23 @@ void drawnetting(sprite_t *s) { } else { area.x = s->netxstart - TILEW/2 - s->netlen; } - area.y = s->netystart; + //area.y = s->netystart; + area.y = s->y - s->img->h-2; area.w = s->netlen; - area.h = 7; + area.h = s->img->h+2; SDL_BlitSurface(screen, &area,s->netbg, NULL); - drawline16(screen,sx,s->nety,s->x + s->netdir*s->netlen,s->nety-3,white); - drawline16(screen,sx,s->nety,s->x + s->netdir*s->netlen,s->nety,white); - drawline16(screen,sx,s->nety,s->x + s->netdir*s->netlen,s->nety+3,white); + dis = (int)s->img->h / (int)(s->netmax+1) + 1; + + for (y = dis; y < s->img->h; y += dis) { + yy = s->y - s->img->h; + yy += y; + drawline16(screen,sx,s->nety,s->x + s->netdir*s->netlen,yy,white); + } + + //drawline16(screen,sx,s->nety,s->x + s->netdir*s->netlen,s->nety-3,white); + //drawline16(screen,sx,s->nety,s->x + s->netdir*s->netlen,s->nety,white); + //drawline16(screen,sx,s->nety,s->x + s->netdir*s->netlen,s->nety+3,white); } else if (s->slamming) { double dist; int x,y; @@ -878,7 +1148,7 @@ void drawsprite(sprite_t *s) { frame = F_FALL; } else { if (s->moved) { - if ((timer/6) % 2 == 0) { + if ((timer/12) % 2 == 0) { frame = F_WALK1; } else { frame = F_JUMP; @@ -920,16 +1190,17 @@ void removenetting(sprite_t *s) { sarea.x = 0; sarea.y = 0; sarea.w = s->netlen; - sarea.h = 7; + sarea.h = s->img->h+2; if (s->netdir == 1) { area.x = s->netxstart + TILEW/2; } else { area.x = s->netxstart - TILEW/2 - s->netlen; } - area.y = s->netystart; + //area.y = s->netystart; + area.y = s->y - s->img->h-2; area.w = s->netlen; - area.h = 7; + area.h = s->img->h+2; if (s->netbg != NULL) { SDL_BlitSurface(s->netbg, &sarea, screen, &area); @@ -1116,18 +1387,53 @@ void dogravity(sprite_t *s) { if (s->slamming) { s->slamangle += (10 * (M_PI/180)); if (s->slamangle >= (190 * (M_PI/180))) { + int xdiff,ydiff,xnet = 0,ynet = 0; + int pointsinc = 250; + int psize = 6; + /* if we hit the ground, kill anything we've caught */ s->slamming = 0; for (s2 = sprite; s2 ; s2 = s2->next) { + /* kill anything we have caught */ if (s2->caughtby == s) { if (isongroundpoint(s2,s2->x,s->y)) { s2->dead = 1; + pointsinc *= 2; + psize += 10; } s2->caughtby = NULL; + xnet = s2->x; + ynet = s2->y - s2->img->h/2; + + } else { + /* also kill anything we hit */ + xdiff = s2->x - xnet; + if (xdiff < 0) xdiff =-xdiff; + ydiff = (s2->y - s2->img->h/2) - ynet; + if (ydiff < 0) ydiff =-ydiff; + + if ((xdiff <= s2->img->w) && (ydiff <= s2->img->h)) { + s2->dead = 1; + pointsinc *= 2; + psize += 10; + } } } + + s->netcaught = 0; + + /* show points */ + if (psize >= MAXLETTERHEIGHT) { + psize = MAXLETTERHEIGHT-1; + } + if (pointsinc > 250) { + sprintf(tempm, "%d",pointsinc); + addtext(xnet,ynet-TILEH, psize, tempm); + /* TODO: give points to player */ + } + } } } diff --git a/rc.h b/rc.h index 7747066..cdba05a 100644 --- a/rc.h +++ b/rc.h @@ -1,9 +1,14 @@ #include + +#define TEXTSPEED 2 +#define TEXTDELAY 40 #define NETSPEED 9 #define MAXMONSTERSPERLEVEL 20 +#define MAXLETTERHEIGHT 100 + #define MAXPTYPES 3 #define MAXFRAMES 8 @@ -39,6 +44,19 @@ typedef struct initialmonster_s { int id; } initialmonster_t; +typedef struct text_s { + int x,y; + int size; + int maxsize; + int state; + char txt[BUFLEN]; + SDL_Rect bgarea; + SDL_Surface *bg; + SDL_Surface *img; + struct text_s *next; + struct text_s *prev; +} text_t; + typedef struct level_s { int id; int bgtileid; @@ -72,6 +90,8 @@ typedef struct sprite_s { int slamming; double slamangle; int netting; + int netcaught; + int netmax; int netspeed; int netdir; int netlen; @@ -100,6 +120,11 @@ imageset_t imageset[MAXPTYPES]; void cleanup(void); +int addtext(int x, int y, int size, char *string); +void drawtext(void); +void movetext(void); +void killtext(text_t *t); +void removetext(void); int addsprite(int id,int x, int y, char *name); int loadtiletypes(char *filename); tiletype_t *gettileat(int pixx,int pixy, int *tilex, int *tiley);