applied leveleditor and multiline-drawtext patches from Ricardo Cruz <rick2@aeiou...
authorTobias Gläßer <tobi.web@gmx.de>
Wed, 31 Dec 2003 02:47:08 +0000 (02:47 +0000)
committerTobias Gläßer <tobi.web@gmx.de>
Wed, 31 Dec 2003 02:47:08 +0000 (02:47 +0000)
SVN-Revision: 85

src/gameloop.c
src/level.c [new file with mode: 0644]
src/level.h [new file with mode: 0644]
src/leveleditor.c
src/menu.c
src/menu.h
src/screen.c

index 413d9ea..9c6f3ac 100644 (file)
@@ -34,6 +34,7 @@
 #include "badguy.h"
 #include "world.h"
 #include "player.h"
+#include "level.h"
 
 /* extern variables */
 
@@ -45,9 +46,8 @@ int score, highscore, distros, level, lives, scroll_x, next_level, game_pause,
 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];
@@ -79,7 +79,6 @@ SDL_Surface * tux_life,
 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];
@@ -87,16 +86,16 @@ bad_guy_type bad_guys[NUM_BAD_GUYS];
 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);
@@ -123,10 +122,118 @@ void add_score(int x, int y, int s);
 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)
@@ -515,7 +622,8 @@ int game_action(void)
 
           /* He died :^( */
 
-          lives--;
+          --lives;
+         remove_powerups();
 
           /* No more lives!? */
 
@@ -535,11 +643,14 @@ int game_action(void)
 
       /* Either way, (re-)load the (next) level... */
 
-      loadlevel();
+      set_defaults();
+      loadlevel(&current_level,"default",level);
+      activate_bad_guys();
       unloadlevelgfx();
       loadlevelgfx();
       unloadlevelsong();
       loadlevelsong();
+      levelintro();
     }
 
   /* Move tux: */
@@ -560,15 +671,15 @@ int game_action(void)
         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)
     {
@@ -1093,7 +1204,7 @@ int game_action(void)
 
       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 );
@@ -1639,7 +1750,7 @@ void game_draw()
   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);
     }
@@ -1652,7 +1763,7 @@ void game_draw()
       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)]);
         }
     }
 
@@ -1672,9 +1783,9 @@ void game_draw()
               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,
@@ -2218,9 +2329,9 @@ void game_draw()
   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);
     }
@@ -2272,12 +2383,15 @@ int gameloop(void)
   tux_size = SMALL;
   tux_got_coffee = NO;
 
-  loadlevel();
+  set_defaults();
+  loadlevel(&current_level,"default",level);
   loadlevelgfx();
+  activate_bad_guys();
   loadlevelsong();
   highscore = load_hs();
 
-
+  levelintro();
+  
   /* --- MAIN GAME LOOP!!! --- */
 
   done = 0;
@@ -2325,7 +2439,7 @@ int gameloop(void)
           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);
@@ -2355,15 +2469,15 @@ int gameloop(void)
 
       /* 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);
         }
     }
@@ -2390,230 +2504,28 @@ void initgame(void)
   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);
 }
 
 
@@ -2626,17 +2538,17 @@ void loadlevelsong(void)
   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);
@@ -3264,17 +3176,19 @@ void drawshape(int x, int y, unsigned char c)
 
 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);
 }
 
@@ -3378,8 +3292,8 @@ void change(int x, int y, int sx, unsigned char 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;
 }
 
 
@@ -3739,6 +3653,13 @@ void add_upgrade(int x, int y, int kind)
     }
 }
 
+/* Remove Tux's power ups */
+void remove_powerups(void)
+{
+       tux_got_coffee = NO;
+       tux_size = SMALL;
+}
+
 
 /* Kill tux! */
 
@@ -3839,8 +3760,7 @@ void drawresultscreen(void)
   drawcenteredtext(str, 256, letters_blue, NO_UPDATE, 1);
 
   SDL_Flip(screen);
-  /*SDL_Delay(2000);*/
-  sleep(2);
+  SDL_Delay(2000);
 }
 
 void savegame(void)
@@ -3870,6 +3790,7 @@ void savegame(void)
    fwrite(&tux_x,4,1,fi);
    fwrite(&tux_y,4,1,fi);
    fwrite(&scroll_x,4,1,fi);
+   fwrite(&current_level.time_left,4,1,fi);
   }
   fclose(fi);
 
@@ -3895,13 +3816,23 @@ void loadgame(char* filename)
 
     }
   else
-  {
+  { 
+  set_defaults();
+         loadlevel(&current_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(&current_level.time_left,4,1,fi);
    fclose(fi);
   }
 
diff --git a/src/level.c b/src/level.c
new file mode 100644 (file)
index 0000000..6df811d
--- /dev/null
@@ -0,0 +1,120 @@
+//
+// 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));
+}
diff --git a/src/level.h b/src/level.h
new file mode 100644 (file)
index 0000000..4d9f14b
--- /dev/null
@@ -0,0 +1,29 @@
+//
+// 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);
+
+
index 7c4be0f..5c15090 100644 (file)
 #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
@@ -59,6 +46,32 @@ SDL_Surface *selection;
 #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);
@@ -74,6 +87,31 @@ void savelevel();
 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()
@@ -94,18 +132,25 @@ int leveleditor()
   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(&current_level,"default",level);
   loadlevelgfx();
 
+  le_activate_bad_guys();
+  le_set_defaults();
+  
   selection = load_image(DATA_PREFIX "/images/leveleditor/select.png", USE_ALPHA);
 
   done = 0;
@@ -119,8 +164,11 @@ int leveleditor()
 
   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))
@@ -152,8 +200,8 @@ int leveleditor()
                   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)
@@ -183,7 +231,7 @@ int leveleditor()
                   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, '.');
@@ -401,14 +449,14 @@ int leveleditor()
 
       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)
@@ -418,21 +466,21 @@ int leveleditor()
             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);
 
@@ -448,6 +496,10 @@ int leveleditor()
         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);
     }
 
@@ -456,12 +508,6 @@ int leveleditor()
 
   SDL_FreeSurface(selection);
 
-  /*if(done == DONE_SAVE)*/    /* let's save the changes       */
-  /*   savelevel();*/
-  /*
-  if(done == DONE_CHANGELEVEL)          change level 
-       return leveleditor(level);
-  */
   return done;
 }
 
@@ -480,8 +526,8 @@ void le_change(int x, int y, int sx, unsigned char c)
         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: */
@@ -494,8 +540,8 @@ void savelevel(void)
 
   /* 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)
     {
@@ -509,25 +555,25 @@ void savelevel(void)
 
   /* 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);
     }
 
@@ -538,105 +584,6 @@ void savelevel(void)
   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;
index 09e242a..2ac0fe3 100644 (file)
@@ -23,6 +23,7 @@
 #include "setup.h"
 #include "sound.h"
 #include "leveleditor.h"
+#include "gameloop.h"
 
 /* Set defaults */
 void initmenu(void)
@@ -236,10 +237,35 @@ int menu_game(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;
@@ -247,17 +273,17 @@ int menu_game(void)
         }
     }
   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;
index 0d9dc41..233481e 100644 (file)
@@ -23,7 +23,7 @@ int show_menu;
 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
 
index aa20abd..aebb7aa 100644 (file)
@@ -62,17 +62,19 @@ void updatescreen(void)
 
 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);
   
@@ -126,7 +128,9 @@ void drawpart(SDL_Surface * surf, int x, int y, int w, int h, int update)
 
 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;
   
@@ -166,6 +170,12 @@ void drawtext(char * text, int x, int y, SDL_Surface * surf, int update, int sha
          src.x = 400;
          src.y = 24;
        }
+       else if (c == '\n')             /* support for multi-lines */
+       {
+       j = i + 1;
+       y += 18;
+       continue;
+       }
       else
        src.x = -1;