#include <string.h>
#include <errno.h>
#include <unistd.h>
+#include <math.h>
#include <time.h>
#include <SDL.h>
#include "level.h"
#include "scene.h"
#include "collision.h"
+#include "tile.h"
+#include "particlesystem.h"
/* extern variables */
void activate_bad_guys(void)
{
- int x,y;
-
- /* Activate bad guys: */
-
- for (y = 0; y < 15; y++)
+ for (std::vector<BadGuyData>::iterator i = current_level.badguy_data.begin();
+ i != current_level.badguy_data.end();
+ ++i)
{
- 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, static_cast<BadGuyKind>(current_level.tiles[y][x] - '0'));
- current_level.tiles[y][x] = '.';
- }
- }
+ add_bad_guy(i->x, i->y, i->kind);
}
+}
+void activate_particle_systems(void)
+{
+ if(current_level.particle_system == "clouds")
+ {
+ particle_systems.push_back(new CloudParticleSystem);
+ }
+ else if(current_level.particle_system == "snow")
+ {
+ particle_systems.push_back(new SnowParticleSystem);
+ }
+ else if(current_level.particle_system != "")
+ {
+ st_abort("unknown particle system specified in level", "");
+ }
}
/* --- GAME EVENT! --- */
case SDLK_f:
if(debug_fps)
debug_fps = false;
- else
+ else
debug_fps = true;
- break;
+ break;
default:
break;
}
case JOY_X:
if (event.jaxis.value < -JOYSTICK_DEAD_ZONE)
{
- tux.input_.left = DOWN;
- tux.input_.right = UP;
+ tux.input.left = DOWN;
+ tux.input.right = UP;
}
else if (event.jaxis.value > JOYSTICK_DEAD_ZONE)
{
- tux.input_.left = UP;
- tux.input_.right = DOWN;
+ tux.input.left = UP;
+ tux.input.right = DOWN;
}
else
{
- tux.input_.left = DOWN;
- tux.input_.right = DOWN;
+ tux.input.left = DOWN;
+ tux.input.right = DOWN;
}
break;
case JOY_Y:
if (event.jaxis.value > JOYSTICK_DEAD_ZONE)
- tux.input_.down = DOWN;
+ tux.input.down = DOWN;
else if (event.jaxis.value < -JOYSTICK_DEAD_ZONE)
- tux.input_.down = UP;
+ tux.input.down = UP;
else
- tux.input_.down = UP;
+ tux.input.down = UP;
/* Handle joystick for the menu */
if(show_menu)
{
- if(tux.input_.down == DOWN)
+ if(tux.input.down == DOWN)
menuaction = MENU_ACTION_DOWN;
else
menuaction = MENU_ACTION_UP;
break;
case SDL_JOYBUTTONDOWN:
if (event.jbutton.button == JOY_A)
- tux.input_.up = DOWN;
+ tux.input.up = DOWN;
else if (event.jbutton.button == JOY_B)
- tux.input_.fire = DOWN;
+ tux.input.fire = DOWN;
break;
case SDL_JOYBUTTONUP:
if (event.jbutton.button == JOY_A)
- tux.input_.up = UP;
+ tux.input.up = UP;
else if (event.jbutton.button == JOY_B)
- tux.input_.fire = UP;
+ tux.input.fire = UP;
if(show_menu)
menuaction = MENU_ACTION_HIT;
arrays_free();
arrays_init();
activate_bad_guys();
+ activate_particle_systems();
level_free_gfx();
level_load_gfx(¤t_level);
level_free_song();
bad_guys[i].action();
}
+ /* update particle systems */
+ std::vector<ParticleSystem*>::iterator p;
+ for(p = particle_systems.begin(); p != particle_systems.end(); ++p)
+ {
+ (*p)->simulate(frame_ratio);
+ }
+
/* Handle all possible collisions. */
collision_handler();
void game_draw(void)
{
+int y,x;
+
/* Draw screen: */
if (tux.dying && (global_frame_counter % 4) == 0)
clearscreen(255, 255, 255);
}
}
- // Draw background:
- for (int y = 0; y < 15; ++y)
- for (int x = 0; x < 21; ++x)
- drawshape(32*x - fmodf(scroll_x, 32), y * 32,
- current_level.tiles[y][x + (int)(scroll_x / 32)]);
+ /* Draw particle systems (background) */
+ std::vector<ParticleSystem*>::iterator p;
+ for(p = particle_systems.begin(); p != particle_systems.end(); ++p)
+ {
+ (*p)->draw(scroll_x, 0, 0);
+ }
+
+ /* Draw background: */
+
+ for (y = 0; y < 15; ++y)
+ {
+ for (x = 0; x < 21; ++x)
+ {
+ drawshape(32*x - fmodf(scroll_x, 32), y * 32,
+ current_level.bg_tiles[(int)y][(int)x + (int)(scroll_x / 32)]);
+ }
+ }
+
+ /* Draw interactive tiles: */
+
+ for (y = 0; y < 15; ++y)
+ {
+ for (x = 0; x < 21; ++x)
+ {
+ drawshape(32*x - fmodf(scroll_x, 32), y * 32,
+ current_level.ia_tiles[(int)y][(int)x + (int)(scroll_x / 32)]);
+ }
+ }
+
+ /* (Bouncy bricks): */
for (unsigned int i = 0; i < bouncy_bricks.size(); ++i)
bouncy_brick_draw(&bouncy_bricks[i]);
for (unsigned int i = 0; i < broken_bricks.size(); ++i)
broken_brick_draw(&broken_bricks[i]);
+ /* Draw foreground: */
+
+ for (y = 0; y < 15; ++y)
+ {
+ for (x = 0; x < 21; ++x)
+ {
+ drawshape(32*x - fmodf(scroll_x, 32), y * 32,
+ current_level.fg_tiles[(int)y][(int)x + (int)(scroll_x / 32)]);
+ }
+ }
+
+ /* Draw particle systems (foreground) */
+ for(p = particle_systems.begin(); p != particle_systems.end(); ++p)
+ {
+ (*p)->draw(scroll_x, 0, 1);
+ }
+
drawstatus();
if(game_pause)
menu_process_current();
/* (Update it all!) */
-
updatescreen();
-
-
}
/* --- GAME LOOP! --- */
level_load_gfx(¤t_level);
activate_bad_guys();
+ activate_particle_systems();
level_load_song(¤t_level);
tux.init();
if(st_gl_mode == ST_GL_LOAD_GAME)
loadgame(levelnb);
-
/* --- MAIN GAME LOOP!!! --- */
jump = false;
while (SDL_PollEvent(&event))
- {}
+ {}
game_draw();
do
frame_ratio = ((double)(update_time-last_update_time))/((double)FRAME_RATE);
if(frame_ratio > 1.5) /* Quick hack to correct the unprecise CPU clocks a little bit. */
frame_ratio = 1.5 + (frame_ratio - 1.5) * 0.85;
-
+
if(!timer_check(&frame_timer))
{
timer_start(&frame_timer,25);
/* Handle events: */
- tux.input_.old_fire = tux.input_.fire;
+ tux.input.old_fire = tux.input.fire;
game_event();
/* == -1: continues */
return 0;
}
- /* --z;
- }*/
+ /* --z;
+ }*/
}
else
{
last_update_time = update_time;
update_time = st_get_ticks();
-
/* Pause till next frame, if the machine running the game is too fast: */
/* FIXME: Works great for in OpenGl mode, where the CPU doesn't have to do that much. But
the results in SDL mode aren't perfect (thought the 100 FPS are reached), even on an AMD2500+. */
"/images/shared/bag-right-1.png",
USE_ALPHA);
+ /* Mr. Bomb */
+ for(int i=0; i<4; ++i) {
+ char num[4];
+ snprintf(num, 4, "%d", i);
+ texture_load(&img_mrbomb_left[i],
+ datadir + "/images/shared/mrbomb-left-" + num + ".png", USE_ALPHA);
+ texture_load(&img_mrbomb_right[i],
+ datadir + "/images/shared/mrbomb-right-" + num + ".png", USE_ALPHA);
+ }
+ /* stalactite */
+ texture_load(&img_stalactite,
+ datadir + "/images/shared/stalactite.png", USE_ALPHA);
+ texture_load(&img_stalactite_broken,
+ datadir + "/images/shared/stalactite-broken.png", USE_ALPHA);
/* Upgrades: */
texture_free(&img_money_right[i]);
}
+ for(i = 0; i < 4; i++) {
+ texture_free(&img_mrbomb_left[i]);
+ texture_free(&img_mrbomb_right[i]);
+ }
+
+ texture_free(&img_stalactite);
+ texture_free(&img_stalactite_broken);
+
texture_free(&img_box_full);
texture_free(&img_box_empty);
/* Draw a tile on the screen: */
-void drawshape(float x, float y, unsigned char c)
+void drawshape(float x, float y, unsigned int c)
{
- int z;
+ if (c != 0)
+ {
+ Tile* ptile = TileManager::instance()->get(c);
+ if(ptile)
+ {
+ if(ptile->images.size() > 1)
+ {
+ texture_draw(&ptile->images[( ((global_frame_counter*25) / ptile->anim_speed) % (ptile->images.size()))],x,y);
+ }
+ else if (ptile->images.size() == 1)
+ {
+ texture_draw(&ptile->images[0],x,y);
+ }
+ else
+ {
+ printf("Tile not dravable %u\n", c);
+ }
+ }
+ }
+ /*
if (c == 'X' || c == 'x')
texture_draw(&img_brick[0], x, y);
else if (c == 'Y' || c == 'y')
texture_draw(&img_flag[z], x + 16, y);
}
else if (c == '&')
- texture_draw(&img_water, x, y);
+ texture_draw(&img_water, x, y);*/
+
}
/* What shape is at some position? */
-
-unsigned char shape(float x, float y)
+unsigned int shape(float x, float y)
{
int xx, yy;
- unsigned char c;
+ unsigned int c;
yy = ((int)y / 32);
xx = ((int)x / 32);
if (yy >= 0 && yy < 15 && xx >= 0 && xx <= current_level.width)
{
- c = current_level.tiles[yy][xx];
+ c = current_level.ia_tiles[yy][xx];
}
else
- c = '.';
+ c = 0;
return(c);
}
-/* Is is ground? */
-
+Tile* gettile(float x, float y)
+{
+ return TileManager::instance()->get(shape(x, y));
+}
bool issolid(float x, float y)
{
- return (isbrick(x, y) ||
- isice(x, y) ||
- (shape(x, y) == '[') ||
- (shape(x, y) == '=') ||
- (shape(x, y) == ']') ||
- (shape(x, y) == 'A') ||
- (shape(x, y) == 'B') ||
- (shape(x, y) == '!') ||
- (shape(x, y) == 'a'));
+ Tile* tile = TileManager::instance()->get
+ (shape(x,y));
+ if(tile)
+ {
+ if(tile->solid == true)
+ return true;
+ else
+ return false;
+ }
+ else
+ {
+ return false;
+ }
}
/* Is it a brick? */
bool isbrick(float x, float y)
{
- return (shape(x, y) == 'X' ||
- shape(x, y) == 'x' ||
- shape(x, y) == 'Y' ||
- shape(x, y) == 'y');
+ Tile* tile = TileManager::instance()->get
+ (shape(x,y));
+ if(tile)
+ {
+ if(tile->brick == true)
+ return true;
+ else
+ return false;
+ }
+ else
+ {
+ return false;
+ }
}
bool isice(float x, float y)
{
- return (shape(x, y) == '#');
+ Tile* tile = TileManager::instance()->get
+ (shape(x,y));
+ if(tile)
+ {
+ if(tile->ice == true)
+ return true;
+ else
+ return false;
+ }
+ else
+ {
+ return false;
+ }
}
/* Is it a full box? */
bool isfullbox(float x, float y)
{
- return (shape(x, y) == 'A' ||
- shape(x, y) == 'B' ||
- shape(x, y) == '!');
+ Tile* tile = TileManager::instance()->get
+ (shape(x,y));
+ if(tile)
+ {
+ if(tile->fullbox == true)
+ return true;
+ else
+ return false;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool isdistro(float x, float y)
+{
+ Tile* tile = TileManager::instance()->get(shape(x,y));
+ return tile && tile->distro;
}
/* Break a brick: */
void trybreakbrick(float x, float y)
{
- if (isbrick(x, y))
+ Tile* tile = gettile(x, y);
+ if (tile->brick)
{
- if (shape(x, y) == 'x' || shape(x, y) == 'y')
+ if (tile->data > 0)
{
/* Get a distro from it: */
-
add_bouncy_distro(((int)(x + 1) / 32) * 32,
(int)(y / 32) * 32);
}
if (distro_counter <= 0)
- level_change(¤t_level,x, y, 'a');
+ level_change(¤t_level,x, y, TM_IA, tile->next_tile2);
play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
score = score + SCORE_DISTRO;
else
{
/* Get rid of it: */
-
- level_change(¤t_level,x, y,'.');
+ level_change(¤t_level,x, y, TM_IA, tile->next_tile);
}
/* Empty a box: */
-
void tryemptybox(float x, float y, int col_side)
{
- if (!isfullbox(x, y))
+ Tile* tile = gettile(x,y);
+ if (!tile->fullbox)
return;
// according to the collision side, set the upgrade direction
-
if(col_side == LEFT)
col_side = RIGHT;
else
col_side = LEFT;
- switch(shape(x,y))
+ switch(tile->data)
{
- case 'A': /* Box with a distro! */
+ case 1: //'A': /* Box with a distro! */
add_bouncy_distro(((int)(x + 1) / 32) * 32, (int)(y / 32) * 32 - 32);
play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
score = score + SCORE_DISTRO;
distros++;
break;
- case 'B': /* Add an upgrade! */
+
+ case 2: // 'B': /* Add an upgrade! */
if (tux.size == SMALL) /* Tux is small, add mints! */
add_upgrade((int)((x + 1) / 32) * 32, (int)(y / 32) * 32 - 32, col_side, UPGRADE_MINTS);
else /* Tux is big, add coffee: */
add_upgrade((int)((x + 1) / 32) * 32, (int)(y / 32) * 32 - 32, col_side, UPGRADE_COFFEE);
play_sound(sounds[SND_UPGRADE], SOUND_CENTER_SPEAKER);
break;
- case '!': /* Add a golden herring */
+
+ case 3:// '!': /* Add a golden herring */
add_upgrade((int)((x + 1) / 32) * 32, (int)(y / 32) * 32 - 32, col_side, UPGRADE_HERRING);
break;
default:
}
/* Empty the box: */
- level_change(¤t_level,x, y, 'a');
+ level_change(¤t_level,x, y, TM_IA, tile->next_tile);
}
-
/* Try to grab a distro: */
-
void trygrabdistro(float x, float y, int bounciness)
{
- if (shape(x, y) == '$')
+ Tile* tile = gettile(x, y);
+ if (tile && tile->distro)
{
- level_change(¤t_level,x, y, '.');
+ level_change(¤t_level,x, y, TM_IA, tile->next_tile);
play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
if (bounciness == BOUNCE)
}
/* Try to bump a bad guy from below: */
-
void trybumpbadguy(float x, float y)
{
- unsigned int i;
-
/* Bad guys: */
- for (i = 0; i < bad_guys.size(); i++)
+ for (unsigned int i = 0; i < bad_guys.size(); i++)
{
if (bad_guys[i].base.x >= x - 32 && bad_guys[i].base.x <= x + 32 &&
bad_guys[i].base.y >= y - 16 && bad_guys[i].base.y <= y + 16)
{
- if (bad_guys[i].kind == BAD_BSOD ||
- bad_guys[i].kind == BAD_LAPTOP)
- {
- bad_guys[i].dying = DYING_FALLING;
- bad_guys[i].base.ym = -8;
- play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
- }
+ bad_guys[i].collision(&tux, CO_PLAYER, COLLISION_BUMP);
}
}
/* Upgrades: */
- for (i = 0; i < upgrades.size(); i++)
+ for (unsigned int i = 0; i < upgrades.size(); i++)
{
if (upgrades[i].base.height == 32 &&
upgrades[i].base.x >= x - 32 && upgrades[i].base.x <= x + 32 &&
if (fi == NULL)
{
fprintf(stderr, "Warning: I could not open the slot file ");
-
}
else
{
arrays_free();
arrays_init();
activate_bad_guys();
+ activate_particle_systems();
level_free_gfx();
level_load_gfx(¤t_level);
level_free_song();