#include "badguy.h"
#include "world.h"
#include "player.h"
+#include "level.h"
/* extern variables */
done, quit, tux_dir, tux_size, tux_duck, tux_x, tux_xm, tux_y, tux_ym,
tux_dying, tux_safe, jumping, jump_counter, frame, score_multiplier,
tux_frame_main, tux_frame, tux_got_coffee, tux_skidding,
-super_bkgd_time, time_left, tux_invincible_time, endpos,
+super_bkgd_time, tux_invincible_time, endpos,
counting_distros, distro_counter;
-int bkgd_red, bkgd_green, bkgd_blue, level_width;
int left, right, up, down, fire, old_fire;
SDL_Surface * img_brick[2], * img_solid[4], * img_distro[4],
* img_waves[3], * img_water, * img_pole, * img_poletop, * img_flag[2];
SDL_Event event;
SDL_Rect src, dest;
SDLKey key;
-unsigned char * tiles[15];
bouncy_distro_type bouncy_distros[NUM_BOUNCY_DISTROS];
broken_brick_type broken_bricks[NUM_BROKEN_BRICKS];
bouncy_brick_type bouncy_bricks[NUM_BOUNCY_BRICKS];
floating_score_type floating_scores[NUM_FLOATING_SCORES];
upgrade_type upgrades[NUM_UPGRADES];
bullet_type bullets[NUM_BULLETS];
-char song_title[60];
-char levelname[60];
-char leveltheme[60];
+st_level current_level;
+char level_subset[100];
char str[60];
/* Local function prototypes: */
+void levelintro(void);
+void set_default(void);
void initgame(void);
-void loadlevel(void);
void loadlevelgfx(void);
void loadlevelsong(void);
void unloadlevelgfx(void);
void trybumpbadguy(int x, int y, int sx);
void add_upgrade(int x, int y, int kind);
void killtux(int mode);
+void remove_powerups(void);
void add_bullet(int x, int y, int dir, int xm);
void drawendscreen(void);
void drawresultscreen(void);
+void levelintro(void)
+{
+ /* Level Intro: */
+
+ clearscreen(0, 0, 0);
+
+ sprintf(str, "LEVEL %d", level);
+ drawcenteredtext(str, 200, letters_red, NO_UPDATE, 1);
+
+ sprintf(str, "%s", current_level.name);
+ drawcenteredtext(str, 224, letters_gold, NO_UPDATE, 1);
+
+ sprintf(str, "TUX x %d", lives);
+ drawcenteredtext(str, 256, letters_blue, NO_UPDATE, 1);
+
+ SDL_Flip(screen);
+
+ SDL_Delay(1000);
+}
+
+void set_defaults(void)
+{
+ int i;
+
+ /* Reset arrays: */
+
+ for (i = 0; i < NUM_BOUNCY_DISTROS; i++)
+ bouncy_distros[i].alive = NO;
+
+ for (i = 0; i < NUM_BROKEN_BRICKS; i++)
+ broken_bricks[i].alive = NO;
+
+ for (i = 0; i < NUM_BOUNCY_BRICKS; i++)
+ bouncy_bricks[i].alive = NO;
+
+ for (i = 0; i < NUM_BAD_GUYS; i++)
+ bad_guys[i].alive = NO;
+
+ for (i = 0; i < NUM_FLOATING_SCORES; i++)
+ floating_scores[i].alive = NO;
+
+ for (i = 0; i < NUM_UPGRADES; i++)
+ upgrades[i].alive = NO;
+
+ for (i = 0; i < NUM_BULLETS; i++)
+ bullets[i].alive = NO;
+
+
+ /* Set defaults: */
+
+ tux_x = 0;
+ tux_xm = 0;
+ tux_y = 240;
+ tux_ym = 0;
+ tux_dir = RIGHT;
+ tux_invincible_time = 0;
+ tux_duck = NO;
+
+ tux_dying = NO;
+ tux_safe = TUX_SAFE_TIME;
+
+ jumping = NO;
+ jump_counter = 0;
+
+ tux_skidding = 0;
+
+ scroll_x = 0;
+
+ right = UP;
+ left = UP;
+ up = UP;
+ down = UP;
+ fire = UP;
+ old_fire = UP;
+
+ score_multiplier = 1;
+ super_bkgd_time = 0;
+
+ counting_distros = NO;
+ distro_counter = 0;
+
+ endpos = 0;
+
+ /* set current song/music */
+ current_music = LEVEL_MUSIC;
+}
+
+void activate_bad_guys(void)
+{
+int x,y;
+
+ /* Activate bad guys: */
+
+ for (y = 0; y < 15; y++)
+ {
+ for (x = 0; x < current_level.width; x++)
+ {
+ if (current_level.tiles[y][x] >= '0' && current_level.tiles[y][x] <= '9')
+ {
+ add_bad_guy(x * 32, y * 32, current_level.tiles[y][x] - '0');
+ current_level.tiles[y][x] = '.';
+ }
+ }
+ }
+
+}
+
/* --- GAME EVENT! --- */
void game_event(void)
/* He died :^( */
- lives--;
+ --lives;
+ remove_powerups();
/* No more lives!? */
/* Either way, (re-)load the (next) level... */
- loadlevel();
+ set_defaults();
+ loadlevel(¤t_level,"default",level);
+ activate_bad_guys();
unloadlevelgfx();
loadlevelgfx();
unloadlevelsong();
loadlevelsong();
+ levelintro();
}
/* Move tux: */
scroll_x = 0;
}
- else if (tux_x > 320 && scroll_x < ((level_width * 32) - 640))
+ else if (tux_x > 320 && scroll_x < ((current_level.width * 32) - 640))
{
/* Scroll the screen in past center: */
scroll_x = scroll_x + (tux_x - 320);
tux_x = 320;
- if (scroll_x > ((level_width * 32) - 640))
- scroll_x = ((level_width * 32) - 640);
+ if (scroll_x > ((current_level.width * 32) - 640))
+ scroll_x = ((current_level.width * 32) - 640);
}
else if (tux_x > 608)
{
if (!playing_music())
{
- if (time_left <= TIME_WARNING)
+ if (current_level.time_left <= TIME_WARNING)
play_music( level_song_fast, 1 );
else
play_music( level_song, 1 );
else
{
if (super_bkgd_time == 0)
- clearscreen(bkgd_red, bkgd_green, bkgd_blue);
+ clearscreen(current_level.bkgd_red, current_level.bkgd_green, current_level.bkgd_blue);
else
drawimage(img_super_bkgd, 0, 0, NO_UPDATE);
}
for (x = 0; x < 21; x++)
{
drawshape(x * 32 - (scroll_x % 32), y * 32,
- tiles[y][x + (scroll_x / 32)]);
+ current_level.tiles[y][x + (scroll_x / 32)]);
}
}
dest.h = 32;
SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format,
- bkgd_red,
- bkgd_green,
- bkgd_blue));
+ current_level.bkgd_red,
+ current_level.bkgd_green,
+ current_level.bkgd_blue));
drawshape(bouncy_bricks[i].x - scroll_x,
bouncy_bricks[i].y + bouncy_bricks[i].offset,
drawtext("HIGH", 0, 20, letters_blue, NO_UPDATE, 1);
drawtext(str, 96, 20, letters_gold, NO_UPDATE, 1);
- if (time_left >= TIME_WARNING || (frame % 10) < 5)
+ if (current_level.time_left >= TIME_WARNING || (frame % 10) < 5)
{
- sprintf(str, "%d", time_left);
+ sprintf(str, "%d", current_level.time_left);
drawtext("TIME", 224, 0, letters_blue, NO_UPDATE, 1);
drawtext(str, 304, 0, letters_gold, NO_UPDATE, 1);
}
tux_size = SMALL;
tux_got_coffee = NO;
- loadlevel();
+ set_defaults();
+ loadlevel(¤t_level,"default",level);
loadlevelgfx();
+ activate_bad_guys();
loadlevelsong();
highscore = load_hs();
-
+ levelintro();
+
/* --- MAIN GAME LOOP!!! --- */
done = 0;
switch (current_music)
{
case LEVEL_MUSIC:
- if (time_left <= TIME_WARNING)
+ if (current_level.time_left <= TIME_WARNING)
play_music(level_song_fast, 1);
else
play_music(level_song, 1);
/* Handle time: */
- if ((frame % 10) == 0 && time_left > 0)
+ if ((frame % 10) == 0 && current_level.time_left > 0)
{
- time_left--;
+ current_level.time_left--;
/* Stop the music; it will start again, faster! */
- if (time_left == TIME_WARNING)
+ if (current_level.time_left == TIME_WARNING)
halt_music();
- if (time_left <= 0)
+ if (current_level.time_left <= 0)
killtux(KILL);
}
}
lives = 3;
}
+/* Load graphics: */
-
-/* Load data for this level: */
-
-void loadlevel(void)
-{
- int i, x, y;
- FILE * fi;
- char * filename;
- char str[80];
- char * line;
-
-
- /* Reset arrays: */
-
- for (i = 0; i < NUM_BOUNCY_DISTROS; i++)
- bouncy_distros[i].alive = NO;
-
- for (i = 0; i < NUM_BROKEN_BRICKS; i++)
- broken_bricks[i].alive = NO;
-
- for (i = 0; i < NUM_BOUNCY_BRICKS; i++)
- bouncy_bricks[i].alive = NO;
-
- for (i = 0; i < NUM_BAD_GUYS; i++)
- bad_guys[i].alive = NO;
-
- for (i = 0; i < NUM_FLOATING_SCORES; i++)
- floating_scores[i].alive = NO;
-
- for (i = 0; i < NUM_UPGRADES; i++)
- upgrades[i].alive = NO;
-
- for (i = 0; i < NUM_BULLETS; i++)
- bullets[i].alive = NO;
-
-
- /* Load data file: */
-
- filename = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) + 20));
- sprintf(filename, "%s/levels/level%d.dat", DATA_PREFIX, level);
- fi = fopen(filename, "r");
- if (fi == NULL)
- {
- perror(filename);
- st_shutdown();
- free(filename);
- exit(-1);
- }
- free(filename);
-
-
- /* Load header info: */
-
-
- /* (Level title) */
- fgets(str, 20, fi);
- strcpy(levelname, str);
- levelname[strlen(levelname)-1] = '\0';
-
- /* (Level theme) */
- fgets(str, 20, fi);
- strcpy(leveltheme, str);
- leveltheme[strlen(leveltheme)-1] = '\0';
-
-
-
- /* (Time to beat level) */
- fgets(str, 10, fi);
- time_left = atoi(str);
-
- /* (Song file for this level) */
- fgets(str, sizeof(song_title), fi);
- strcpy(song_title, str);
- song_title[strlen(song_title)-1] = '\0';
-
-
-
- /* (Level background color) */
- fgets(str, 10, fi);
- bkgd_red = atoi(str);
- fgets(str, 10, fi);
- bkgd_green= atoi(str);
- fgets(str, 10, fi);
- bkgd_blue = atoi(str);
-
- /* (Level width) */
- fgets(str, 10, fi);
- level_width = atoi(str);
-
-
- /* Allocate some space for the line-reading! */
-
- line = (char *) malloc(sizeof(char) * (level_width + 5));
- if (line == NULL)
- {
- fprintf(stderr, "Couldn't allocate space to load level data!");
- exit(1);
- }
-
-
- /* Load the level lines: */
-
- for (y = 0; y < 15; y++)
- {
- if(fgets(line, level_width + 5, fi) == NULL)
- {
- fprintf(stderr, "Level %s isn't complete!\n",levelname);
- exit(1);
- }
- line[strlen(line) - 1] = '\0';
- tiles[y] = strdup(line);
- }
-
- fclose(fi);
-
-
- /* Activate bad guys: */
-
- for (y = 0; y < 15; y++)
- {
- for (x = 0; x < level_width; x++)
- {
- if (tiles[y][x] >= '0' && tiles[y][x] <= '9')
- {
- add_bad_guy(x * 32, y * 32, tiles[y][x] - '0');
- tiles[y][x] = '.';
- }
- }
- }
-
-
- /* Set defaults: */
-
- tux_x = 0;
- tux_xm = 0;
- tux_y = 240;
- tux_ym = 0;
- tux_dir = RIGHT;
- tux_invincible_time = 0;
- tux_duck = NO;
-
- tux_dying = NO;
- tux_safe = TUX_SAFE_TIME;
-
- jumping = NO;
- jump_counter = 0;
-
- tux_skidding = 0;
-
- scroll_x = 0;
-
- right = UP;
- left = UP;
- up = UP;
- down = UP;
- fire = UP;
- old_fire = UP;
-
- score_multiplier = 1;
- super_bkgd_time = 0;
-
- counting_distros = NO;
- distro_counter = 0;
-
- endpos = 0;
-
- /* set current song/music */
- current_music = LEVEL_MUSIC;
-
- /* Level Intro: */
-
- clearscreen(0, 0, 0);
-
- sprintf(str, "LEVEL %d", level);
- drawcenteredtext(str, 200, letters_red, NO_UPDATE, 1);
-
- sprintf(str, "%s", levelname);
- drawcenteredtext(str, 224, letters_gold, NO_UPDATE, 1);
-
- sprintf(str, "TUX x %d", lives);
- drawcenteredtext(str, 256, letters_blue, NO_UPDATE, 1);
-
- SDL_Flip(screen);
-
- SDL_Delay(1000);
-
-
-}
-
-
-/* Load a level-specific graphic... */
-
-SDL_Surface * load_level_image(char * file, int use_alpha)
+void loadlevelgfx(void)
{
- char fname[1024];
-
- snprintf(fname, 1024, "%s/images/themes/%s/%s", DATA_PREFIX, leveltheme, file);
- return(load_image(fname, use_alpha));
-}
+ img_brick[0] = load_level_image(current_level.theme,"brick0.png", IGNORE_ALPHA);
+ img_brick[1] = load_level_image(current_level.theme,"brick1.png", IGNORE_ALPHA);
+ img_solid[0] = load_level_image(current_level.theme,"solid0.png", USE_ALPHA);
+ img_solid[1] = load_level_image(current_level.theme,"solid1.png", USE_ALPHA);
+ img_solid[2] = load_level_image(current_level.theme,"solid2.png", USE_ALPHA);
+ img_solid[3] = load_level_image(current_level.theme,"solid3.png", USE_ALPHA);
-/* Load graphics: */
+ img_bkgd[0][0] = load_level_image(current_level.theme,"bkgd-00.png", USE_ALPHA);
+ img_bkgd[0][1] = load_level_image(current_level.theme,"bkgd-01.png", USE_ALPHA);
+ img_bkgd[0][2] = load_level_image(current_level.theme,"bkgd-02.png", USE_ALPHA);
+ img_bkgd[0][3] = load_level_image(current_level.theme,"bkgd-03.png", USE_ALPHA);
-void loadlevelgfx(void)
-{
- img_brick[0] = load_level_image("brick0.png", IGNORE_ALPHA);
- img_brick[1] = load_level_image("brick1.png", IGNORE_ALPHA);
-
- img_solid[0] = load_level_image("solid0.png", USE_ALPHA);
- img_solid[1] = load_level_image("solid1.png", USE_ALPHA);
- img_solid[2] = load_level_image("solid2.png", USE_ALPHA);
- img_solid[3] = load_level_image("solid3.png", USE_ALPHA);
-
- img_bkgd[0][0] = load_level_image("bkgd-00.png", USE_ALPHA);
- img_bkgd[0][1] = load_level_image("bkgd-01.png", USE_ALPHA);
- img_bkgd[0][2] = load_level_image("bkgd-02.png", USE_ALPHA);
- img_bkgd[0][3] = load_level_image("bkgd-03.png", USE_ALPHA);
-
- img_bkgd[1][0] = load_level_image("bkgd-10.png", USE_ALPHA);
- img_bkgd[1][1] = load_level_image("bkgd-11.png", USE_ALPHA);
- img_bkgd[1][2] = load_level_image("bkgd-12.png", USE_ALPHA);
- img_bkgd[1][3] = load_level_image("bkgd-13.png", USE_ALPHA);
+ img_bkgd[1][0] = load_level_image(current_level.theme,"bkgd-10.png", USE_ALPHA);
+ img_bkgd[1][1] = load_level_image(current_level.theme,"bkgd-11.png", USE_ALPHA);
+ img_bkgd[1][2] = load_level_image(current_level.theme,"bkgd-12.png", USE_ALPHA);
+ img_bkgd[1][3] = load_level_image(current_level.theme,"bkgd-13.png", USE_ALPHA);
}
char * song_subtitle;
song_path = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) +
- strlen(song_title) + 8));
- sprintf(song_path, "%s/music/%s", DATA_PREFIX, song_title);
+ strlen(current_level.song_title) + 8));
+ sprintf(song_path, "%s/music/%s", DATA_PREFIX, current_level.song_title);
level_song = load_song(song_path);
free(song_path);
song_path = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) +
- strlen(song_title) + 8 + 5));
- song_subtitle = strdup(song_title);
+ strlen(current_level.song_title) + 8 + 5));
+ song_subtitle = strdup(current_level.song_title);
strcpy(strstr(song_subtitle, "."), "\0");
- sprintf(song_path, "%s/music/%s-fast%s", DATA_PREFIX, song_subtitle, strstr(song_title, "."));
+ sprintf(song_path, "%s/music/%s-fast%s", DATA_PREFIX, song_subtitle, strstr(current_level.song_title, "."));
level_song_fast = load_song(song_path);
free(song_subtitle);
free(song_path);
unsigned char shape(int x, int y, int sx)
{
+
int xx, yy;
unsigned char c;
-
+
yy = (y / 32);
xx = ((x + sx) / 32);
+
- if (yy >= 0 && yy <= 15 && xx >= 0 && xx <= level_width)
- c = tiles[yy][xx];
+ if (yy >= 0 && yy < 15 && xx >= 0 && xx <= current_level.width)
+ c = current_level.tiles[yy][xx];
else
c = '.';
-
+
return(c);
}
yy = (y / 32);
xx = ((x + sx) / 32);
- if (yy >= 0 && yy <= 15 && xx >= 0 && xx <= level_width)
- tiles[yy][xx] = c;
+ if (yy >= 0 && yy < 15 && xx >= 0 && xx <= current_level.width)
+ current_level.tiles[yy][xx] = c;
}
}
}
+/* Remove Tux's power ups */
+void remove_powerups(void)
+{
+ tux_got_coffee = NO;
+ tux_size = SMALL;
+}
+
/* Kill tux! */
drawcenteredtext(str, 256, letters_blue, NO_UPDATE, 1);
SDL_Flip(screen);
- /*SDL_Delay(2000);*/
- sleep(2);
+ SDL_Delay(2000);
}
void savegame(void)
fwrite(&tux_x,4,1,fi);
fwrite(&tux_y,4,1,fi);
fwrite(&scroll_x,4,1,fi);
+ fwrite(¤t_level.time_left,4,1,fi);
}
fclose(fi);
}
else
- {
+ {
+ set_defaults();
+ loadlevel(¤t_level,"default",level);
+ activate_bad_guys();
+ unloadlevelgfx();
+ loadlevelgfx();
+ unloadlevelsong();
+ loadlevelsong();
+ levelintro();
+
fread(&level,4,1,fi);
fread(&score,4,1,fi);
fread(&distros,4,1,fi);
fread(&tux_x,4,1,fi);
fread(&tux_y,4,1,fi);
fread(&scroll_x,4,1,fi);
+ fread(¤t_level.time_left,4,1,fi);
fclose(fi);
}
--- /dev/null
+//
+// C Implementation: level
+//
+// Description:
+//
+//
+// Author: Tobias Glaesser <tobi.web@gmx.de>, (C) 2003
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "setup.h"
+#include "screen.h"
+#include "level.h"
+
+/* Load data for this level: */
+
+void loadlevel(st_level* plevel, char *subset, int level)
+{
+ int y;
+ FILE * fi;
+ char str[80];
+ char * filename;
+ char * line;
+
+ /* Load data file: */
+
+ filename = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) + 20) + strlen(subset));
+ sprintf(filename, "%s/levels/%s/level%d.dat", DATA_PREFIX, subset, level);
+ fi = fopen(filename, "r");
+ if (fi == NULL)
+ {
+ perror(filename);
+ st_shutdown();
+ free(filename);
+ exit(-1);
+ }
+ free(filename);
+
+
+ /* Load header info: */
+
+
+ /* (Level title) */
+ fgets(str, 20, fi);
+ strcpy(plevel->name, str);
+ plevel->name[strlen(plevel->name)-1] = '\0';
+
+ /* (Level theme) */
+ fgets(str, 20, fi);
+ strcpy(plevel->theme, str);
+ plevel->theme[strlen(plevel->theme)-1] = '\0';
+
+
+
+ /* (Time to beat level) */
+ fgets(str, 10, fi);
+ plevel->time_left = atoi(str);
+
+ /* (Song file for this level) */
+ fgets(str, sizeof(plevel->song_title), fi);
+ strcpy(plevel->song_title, str);
+ plevel->song_title[strlen(plevel->song_title)-1] = '\0';
+
+
+
+ /* (Level background color) */
+ fgets(str, 10, fi);
+ plevel->bkgd_red = atoi(str);
+ fgets(str, 10, fi);
+ plevel->bkgd_green= atoi(str);
+ fgets(str, 10, fi);
+ plevel->bkgd_blue = atoi(str);
+
+ /* (Level width) */
+ fgets(str, 10, fi);
+ plevel->width = atoi(str);
+
+
+ /* Allocate some space for the line-reading! */
+
+ line = (char *) malloc(sizeof(char) * (plevel->width + 5));
+ if (line == NULL)
+ {
+ fprintf(stderr, "Couldn't allocate space to load level data!");
+ exit(1);
+ }
+
+
+ /* Load the level lines: */
+
+ for (y = 0; y < 15; y++)
+ {
+ if(fgets(line, plevel->width + 5, fi) == NULL)
+ {
+ fprintf(stderr, "Level %s isn't complete!\n",plevel->name);
+ exit(1);
+ }
+ line[strlen(line) - 1] = '\0';
+ plevel->tiles[y] = strdup(line);
+ }
+
+ fclose(fi);
+
+}
+
+/* Load a level-specific graphic... */
+
+SDL_Surface * load_level_image(char* theme, char * file, int use_alpha)
+{
+ char fname[2024];
+
+ snprintf(fname, 21024, "%simages/themes/%s/%s", DATA_PREFIX, theme, file);
+
+ return(load_image(fname, use_alpha));
+}
--- /dev/null
+//
+// C Interface: level
+//
+// Description:
+//
+//
+// Author: Tobias Glaesser <tobi.web@gmx.de>, (C) 2003
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+typedef struct st_level /*It is easier to read the sources IMHO, if we don't write something like int a,b,c; */
+ {
+ char name[100];
+ char theme[100];
+ char song_title[100];
+ unsigned char* tiles[15];
+ int time_left;
+ int bkgd_red;
+ int bkgd_green;
+ int bkgd_blue;
+ int width;
+ } st_level;
+
+void loadlevel(st_level* plevel, char * subset, int level);
+SDL_Surface * load_level_image(char* theme, char * file, int use_alpha);
+
+
#include "globals.h"
#include "setup.h"
#include "menu.h"
-
+#include "level.h"
#include "badguy.h"
-char levelname[60];
-char leveltheme[60];
-bad_guy_type bad_guys[NUM_BAD_GUYS];
-SDL_Surface *img_bsod_left[4], *img_laptop_left[3], *img_money_left[2];
-char song_title[60];
-char levelfilename[100];
-
-int time_left;
-unsigned char* tiles[15];
-int bkgd_red, bkgd_green, bkgd_blue, level_width;
-
-SDL_Surface *selection;
-
/* definitions to aid development */
#define DONE_LEVELEDITOR 1
#define DONE_QUIT 2
#define MOUSE_RIGHT_MARGIN 608
#define MOUSE_POS_SPEED 32
+ /* Level Intro: */
+/*
+ clearscreen(0, 0, 0);
+
+ sprintf(str, "Editing Level %s", levelfilename);
+ drawcenteredtext(str, 200, letters_red, NO_UPDATE, 1);
+
+ sprintf(str, "%s", levelname);
+ drawcenteredtext(str, 224, letters_gold, NO_UPDATE, 1);
+
+ SDL_Flip(screen);
+
+ SDL_Delay(1000);
+*/
+
+/* global variables (based on the gameloop ones) */
+
+bad_guy_type bad_guys[NUM_BAD_GUYS];
+SDL_Surface *img_bsod_left[4], *img_laptop_left[3], *img_money_left[2];
+int level;
+st_level current_level;
+char level_subset[100];
+
+int frame;
+SDL_Surface *selection;
+
/* gameloop funcs declerations */
void loadlevelgfx(void);
void le_loadlevel(void);
void le_change(int x, int y, int sx, unsigned char c);
void showhelp();
+void le_set_defaults(void);
+void le_activate_bad_guys(void);
+
+void le_activate_bad_guys(void)
+{
+int x,y;
+
+ /* Activate bad guys: */
+
+ /* as oposed to the gameloop.c func, this one doesn't remove
+ the badguys from tiles */
+
+ for (y = 0; y < 15; ++y)
+ for (x = 0; x < current_level.width; ++x)
+ if (current_level.tiles[y][x] >= '0' && current_level.tiles[y][x] <= '9')
+ add_bad_guy(x * 32, y * 32, current_level.tiles[y][x] - '0');
+}
+
+void le_set_defaults()
+{
+ /* Set defaults: */
+
+ if(current_level.time_left == 0)
+ current_level.time_left = 255;
+}
/* FIXME: Needs to be implemented. It should ask the user for the level(file)name and then let him create a new level based on this. */
void newlevel()
SDL_Event event;
SDLKey key;
SDLMod keymod;
+
+ strcpy(level_subset,"default");
-
- strcpy(levelfilename,"level1");
+ level = 1;
initmenu();
menumenu = MENU_LEVELEDITOR;
show_menu = YES;
+ int last_time, now_time;
+ frame = 0; /* support for frames in some tiles, like waves and bad guys */
+
loadshared();
- le_loadlevel();
+ loadlevel(¤t_level,"default",level);
loadlevelgfx();
+ le_activate_bad_guys();
+ le_set_defaults();
+
selection = load_image(DATA_PREFIX "/images/leveleditor/select.png", USE_ALPHA);
done = 0;
while(1)
{
- SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, bkgd_red, bkgd_green, bkgd_blue));
+ SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, current_level.bkgd_red, current_level.bkgd_green, current_level.bkgd_blue));
+ last_time = SDL_GetTicks();
+ frame++;
+
keymod = SDL_GetModState();
while(SDL_PollEvent(&event))
else
cursor_x += KEY_CURSOR_FASTSPEED;
- if(cursor_x > (level_width*32) - 1)
- cursor_x = (level_width*32) - 1;
+ if(cursor_x > (current_level.width*32) - 1)
+ cursor_x = (current_level.width*32) - 1;
break;
case SDLK_UP:
if(fire == DOWN)
cursor_x = 0;
break;
case SDLK_END:
- cursor_x = (level_width * 32) - 32;
+ cursor_x = (current_level.width * 32) - 32;
break;
case SDLK_PERIOD:
le_change(cursor_x, cursor_y, 0, '.');
if(pos_x < 0)
pos_x = 0;
- if(pos_x > (level_width * 32) - 640)
- pos_x = (level_width * 32) - 640;
+ if(pos_x > (current_level.width * 32) - 640)
+ pos_x = (current_level.width * 32) - 640;
old_cursor_x = cursor_x;
for (y = 0; y < 15; ++y)
for (x = 0; x < 21; ++x)
- drawshape(x * 32, y * 32, tiles[y][x + (pos_x / 32)]);
+ drawshape(x * 32, y * 32, current_level.tiles[y][x + (pos_x / 32)]);
/* Draw the Bad guys: */
for (i = 0; i < NUM_BAD_GUYS; ++i)
continue;
/* to support frames: img_bsod_left[(frame / 5) % 4] */
if(bad_guys[i].kind == BAD_BSOD)
- drawimage(img_bsod_left[0], ((int)(bad_guys[i].x - pos_x)/32)*32, bad_guys[i].y, NO_UPDATE);
+ drawimage(img_bsod_left[(frame / 5) % 4], ((int)(bad_guys[i].x - pos_x)/32)*32, bad_guys[i].y, NO_UPDATE);
else if(bad_guys[i].kind == BAD_LAPTOP)
- drawimage(img_laptop_left[0], ((int)(bad_guys[i].x - pos_x)/32)*32, bad_guys[i].y, NO_UPDATE);
+ drawimage(img_laptop_left[(frame / 5) % 3], ((int)(bad_guys[i].x - pos_x)/32)*32, bad_guys[i].y, NO_UPDATE);
else if (bad_guys[i].kind == BAD_MONEY)
- drawimage(img_money_left[0], ((int)(bad_guys[i].x - pos_x)/32)*32, bad_guys[i].y, NO_UPDATE);
+ drawimage(img_money_left[(frame / 5) % 2], ((int)(bad_guys[i].x - pos_x)/32)*32, bad_guys[i].y, NO_UPDATE);
}
drawimage(selection, ((int)(cursor_x - pos_x)/32)*32, cursor_y, NO_UPDATE);
- sprintf(str, "%d", time_left);
+ sprintf(str, "%d", current_level.time_left);
drawtext("TIME", 324, 0, letters_blue, NO_UPDATE, 1);
drawtext(str, 404, 0, letters_gold, NO_UPDATE, 1);
- sprintf(str, "%s", levelname);
+ sprintf(str, "%s", current_level.name);
drawtext("NAME", 0, 0, letters_blue, NO_UPDATE, 1);
drawtext(str, 80, 0, letters_gold, NO_UPDATE, 1);
return 1;
SDL_Delay(50);
+ now_time = SDL_GetTicks();
+ if (now_time < last_time + FPS)
+ SDL_Delay(last_time + FPS - now_time); /* delay some time */
+
SDL_Flip(screen);
}
SDL_FreeSurface(selection);
- /*if(done == DONE_SAVE)*/ /* let's save the changes */
- /* savelevel();*/
- /*
- if(done == DONE_CHANGELEVEL) change level
- return leveleditor(level);
- */
return done;
}
bad_guys[i].alive = NO;
- if (yy >= 0 && yy <= 15 && xx >= 0 && xx <= level_width)
- tiles[yy][xx] = c;
+ if (yy >= 0 && yy < 15 && xx >= 0 && xx <= current_level.width)
+ current_level.tiles[yy][xx] = c;
}
/* Save data for this level: */
/* Save data file: */
- filename = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) + 20));
- sprintf(filename, "%s/levels/%s.dat", DATA_PREFIX, levelfilename);
+ filename = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) + 20) + strlen(level_subset));
+ sprintf(filename, "%s/levels/%s/level%d.dat", DATA_PREFIX, level_subset, level);
fi = fopen(filename, "w");
if (fi == NULL)
{
/* sptrinf("# Level created by SuperTux built-in editor", fi); */
- fputs(levelname, fi);
+ fputs(current_level.name, fi);
fputs("\n", fi);
- fputs(leveltheme, fi);
+ fputs(current_level.theme, fi);
fputs("\n", fi);
- sprintf(str, "%d\n", time_left); /* time */
+ sprintf(str, "%d\n", current_level.time_left); /* time */
fputs(str, fi);
- fputs(song_title, fi); /* song filename */
- sprintf(str, "%d\n", bkgd_red); /* red background color */
+ fputs(current_level.song_title, fi); /* song filename */
+ sprintf(str, "\n%d\n", current_level.bkgd_red); /* red background color */
fputs(str, fi);
- sprintf(str, "%d\n", bkgd_green); /* green background color */
+ sprintf(str, "%d\n", current_level.bkgd_green); /* green background color */
fputs(str, fi);
- sprintf(str, "%d\n", bkgd_blue); /* blue background color */
+ sprintf(str, "%d\n", current_level.bkgd_blue); /* blue background color */
fputs(str, fi);
- sprintf(str, "%d\n", level_width); /* level width */
+ sprintf(str, "%d\n", current_level.width); /* level width */
fputs(str, fi);
for(y = 0; y < 15; ++y)
{
- fputs(tiles[y], fi);
+ fputs(current_level.tiles[y], fi);
fputs("\n", fi);
}
SDL_Delay(1000);
}
-
-/* I had to copy loadlevel, because loadlevel changes the tiles.
- For intance, badguys are removed from the tiles and we have to
- keep them there. */
-
-/* Load data for this level: */
-
-void le_loadlevel(void)
-{
- FILE * fi;
- char * filename;
- int x, y;
- char str[80];
- char* line = malloc(sizeof(char)*10);/*[LEVEL_WIDTH + 5];*/
-
- /* Load data file: */
-
- filename = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) + 20));
- sprintf(filename, "%s/levels/%s.dat", DATA_PREFIX, levelfilename);
- fi = fopen(filename, "r");
- if (fi == NULL)
- {
- perror(filename);
- st_shutdown();
- free(filename);
- exit(-1);
- }
- free(filename);
-
- /* (Level title) */
- fgets(str, 20, fi);
- strcpy(levelname, str);
- levelname[strlen(levelname)-1] = '\0';
-
- /* (Level theme) */
- fgets(str, 20, fi);
- strcpy(leveltheme, str);
- leveltheme[strlen(leveltheme)-1] = '\0';
-
- fgets(line, 10, fi);
- time_left = atoi(line);
- fgets(str, 60, fi);
- song_title[0]='\0';
- strcpy(song_title,str);
- fgets(line, 10, fi);
- bkgd_red = atoi(line);
- fgets(line, 10, fi);
- bkgd_green= atoi(line);
- fgets(line, 10, fi);
- bkgd_blue = atoi(line);
- fgets(line, 10, fi);
- level_width = atoi(line);
-
- free(line);
- line = malloc(level_width*sizeof(char)+5);
-
- for (y = 0; y < 15; ++y)
- {
- fgets(line, level_width + 5, fi);
- line[strlen(line) - 1] = '\0';
- free(tiles[y]);
- tiles[y] = malloc((strlen(line)+5)*sizeof(char));
- strcpy(tiles[y], line);
- }
-
- fclose(fi);
-
- /* Activate bad guys: */
-
- /* as oposed to the gameloop.c func, this one doesn't remove
- the badguys from tiles */
-
- for (y = 0; y < 15; ++y)
- for (x = 0; x < level_width; ++x)
- if (tiles[y][x] >= '0' && tiles[y][x] <= '9')
- add_bad_guy(x * 32, y * 32, tiles[y][x] - '0');
-
-
- /* Set defaults: */
-
- if(time_left == 0)
- time_left = 255;
-
-
- /* Level Intro: */
-
- clearscreen(0, 0, 0);
-
- sprintf(str, "Editing Level %s", levelfilename);
- drawcenteredtext(str, 200, letters_red, NO_UPDATE, 1);
-
- sprintf(str, "%s", levelname);
- drawcenteredtext(str, 224, letters_gold, NO_UPDATE, 1);
-
- SDL_Flip(screen);
-
- SDL_Delay(1000);
-}
-
void showhelp()
{
SDL_Event event;
#include "setup.h"
#include "sound.h"
#include "leveleditor.h"
+#include "gameloop.h"
/* Set defaults */
void initmenu(void)
}
else
drawcenteredtext("Return To Game", 192, letters_blue, NO_UPDATE, 2);
-
+
if(menuitem == 1)
{
- drawcenteredtext("Options", 224, letters_red, NO_UPDATE, 2);
+ drawcenteredtext("Save Game", 224, letters_red, NO_UPDATE, 2);
+ if(menuaction == MN_HIT) /* Don't show the menu anymore, if this item got hit */
+ {
+ show_menu = 0;
+ savegame();
+ }
+ }
+ else
+ drawcenteredtext("Save Game", 224, letters_blue, NO_UPDATE, 2);
+
+ if(menuitem == 2)
+ {
+ drawcenteredtext("Load Game", 256, letters_red, NO_UPDATE, 2);
+ if(menuaction == MN_HIT) /* Don't show the menu anymore, if this item got hit */
+ {
+ show_menu = 0;
+ char *x = NULL;
+ loadgame(x);
+ }
+ }
+ else
+ drawcenteredtext("Load Game", 256, letters_blue, NO_UPDATE, 2);
+
+ if(menuitem == 3)
+ {
+ drawcenteredtext("Options", 288, letters_red, NO_UPDATE, 2);
if(menuaction == MN_HIT) /* Switch to the 'Options' menu */
{
menumenu = MENU_OPTIONS;
}
}
else
- drawcenteredtext("Options", 224, letters_blue, NO_UPDATE, 2);
+ drawcenteredtext("Options", 288, letters_blue, NO_UPDATE, 2);
- if(menuitem == 2)
+ if(menuitem == 4)
{
- drawcenteredtext("Quit Game", 256, letters_red, NO_UPDATE, 2);
+ drawcenteredtext("Quit Game", 320, letters_red, NO_UPDATE, 2);
if(menuaction == MN_HIT) /* Quit a running game */
return 1;
}
else
{
- drawcenteredtext("Quit Game", 256, letters_blue, NO_UPDATE, 2);
+ drawcenteredtext("Quit Game", 320, letters_blue, NO_UPDATE, 2);
}
return 0;
int menu_change;
#define MENU_MAIN_ITEM_MAX 3
-#define MENU_GAME_ITEM_MAX 2
+#define MENU_GAME_ITEM_MAX 4
#define MENU_OPTIONS_ITEM_MAX 3
#define MENU_LEVELEDITOR_ITEM_MAX 4
SDL_Surface * load_image(char * file, int use_alpha)
{
+
SDL_Surface * temp, * surf;
temp = IMG_Load(file);
+
if (temp == NULL)
st_abort("Can't load", file);
-
+
surf = SDL_DisplayFormatAlpha(temp);
if (surf == NULL)
st_abort("Can't covert to display format", file);
-
+
if (use_alpha == IGNORE_ALPHA)
SDL_SetAlpha(surf, 0, 0);
void drawtext(char * text, int x, int y, SDL_Surface * surf, int update, int shadowsize)
{
- int i;
+ /* i - helps to keep tracking of the all string length
+ j - helps to keep track of the length of the current line */
+ int i, j;
char c;
SDL_Rect src, dest;
src.x = 400;
src.y = 24;
}
+ else if (c == '\n') /* support for multi-lines */
+ {
+ j = i + 1;
+ y += 18;
+ continue;
+ }
else
src.x = -1;