April 11, 2000 - March 15, 2004
*/
+#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/* extern variables */
-Level current_level;
int game_started = false;
/* Local variables: */
static int pause_menu_frame;
static int debug_fps;
-/* Local function prototypes: */
+GameSession* GameSession::current_ = 0;
+/* Local function prototypes: */
void levelintro(void);
void loadshared(void);
void unloadshared(void);
void drawendscreen(void);
void drawresultscreen(void);
-void levelintro(void)
+GameSession::GameSession()
+{
+ current_ = this;
+ assert(0);
+}
+
+GameSession::GameSession(const std::string& filename)
+{
+ current_ = this;
+
+ timer_init(&fps_timer, true);
+ timer_init(&frame_timer, true);
+
+ current_level.load(filename);
+}
+
+GameSession::GameSession(const std::string& subset, int levelnb, int mode)
+{
+ current_ = this;
+
+ timer_init(&fps_timer, true);
+ timer_init(&frame_timer, true);
+
+ game_started = true;
+
+ st_gl_mode = mode;
+ level = levelnb;
+
+ /* Init the game: */
+ arrays_free();
+ set_defaults();
+
+ strcpy(level_subset, subset.c_str());
+
+ if (st_gl_mode == ST_GL_LOAD_LEVEL_FILE)
+ {
+ if (current_level.load(level_subset))
+ exit(1);
+ }
+ else
+ {
+ if(current_level.load(level_subset, level) != 0)
+ exit(1);
+ }
+
+ current_level.load_gfx();
+ loadshared();
+ activate_bad_guys(¤t_level);
+ activate_particle_systems();
+ current_level.load_song();
+
+ tux.init();
+
+ if(st_gl_mode != ST_GL_TEST)
+ load_hs();
+
+ if(st_gl_mode == ST_GL_PLAY || st_gl_mode == ST_GL_LOAD_LEVEL_FILE)
+ levelintro();
+
+ timer_init(&time_left,true);
+ start_timers();
+
+ if(st_gl_mode == ST_GL_LOAD_GAME)
+ loadgame(levelnb);
+}
+
+void
+GameSession::levelintro(void)
{
char str[60];
/* Level Intro: */
}
/* Reset Timers */
-void start_timers(void)
+void
+GameSession::start_timers()
{
timer_start(&time_left,current_level.time_left*1000);
st_pause_ticks_init();
}
}
-void activate_particle_systems(void)
+void
+GameSession::activate_particle_systems()
{
if(current_level.particle_system == "clouds")
{
}
}
-/* --- GAME EVENT! --- */
-
-void game_event(void)
+void
+GameSession::process_events()
{
while (SDL_PollEvent(&event))
{
} /* while */
}
-/* --- GAME ACTION! --- */
-
int
GameSession::action()
{
- unsigned int i;
-
- /* (tux.is_dead() || next_level) */
if (tux.is_dead() || next_level)
{
/* Tux either died, or reached the end of a level! */
tux.action();
/* Handle bouncy distros: */
- for (i = 0; i < bouncy_distros.size(); i++)
- {
- bouncy_distro_action(&bouncy_distros[i]);
- }
-
+ for (unsigned int i = 0; i < bouncy_distros.size(); i++)
+ bouncy_distro_action(&bouncy_distros[i]);
/* Handle broken bricks: */
- for (i = 0; i < broken_bricks.size(); i++)
- {
+ for (unsigned int i = 0; i < broken_bricks.size(); i++)
broken_brick_action(&broken_bricks[i]);
- }
-
/* Handle distro counting: */
-
if (counting_distros)
{
distro_counter--;
counting_distros = -1;
}
+ // Handle all kinds of game objects
+ for (unsigned int i = 0; i < bouncy_bricks.size(); i++)
+ bouncy_brick_action(&bouncy_bricks[i]);
+
+ for (unsigned int i = 0; i < floating_scores.size(); i++)
+ floating_score_action(&floating_scores[i]);
- /* Handle bouncy bricks: */
-
- for (i = 0; i < bouncy_bricks.size(); i++)
- {
- bouncy_brick_action(&bouncy_bricks[i]);
- }
-
-
- /* Handle floating scores: */
-
- for (i = 0; i < floating_scores.size(); i++)
- {
- floating_score_action(&floating_scores[i]);
- }
-
-
- /* Handle bullets: */
-
- for (i = 0; i < bullets.size(); ++i)
- {
- bullet_action(&bullets[i]);
- }
-
- /* Handle upgrades: */
-
- for (i = 0; i < upgrades.size(); i++)
- {
- upgrade_action(&upgrades[i]);
- }
-
-
- /* Handle bad guys: */
+ for (unsigned int i = 0; i < bullets.size(); ++i)
+ bullet_action(&bullets[i]);
+
+ for (unsigned int i = 0; i < upgrades.size(); i++)
+ upgrade_action(&upgrades[i]);
- for (i = 0; i < bad_guys.size(); i++)
- {
- bad_guys[i].action();
- }
+ for (unsigned int i = 0; i < bad_guys.size(); i++)
+ bad_guys[i].action();
/* update particle systems */
std::vector<ParticleSystem*>::iterator p;
updatescreen();
}
-/* --- GAME LOOP! --- */
-
-GameSession::GameSession(const char * subset, int levelnb, int mode)
-{
- timer_init(&fps_timer, true);
- timer_init(&frame_timer, true);
-
- game_started = true;
-
- st_gl_mode = mode;
- level = levelnb;
-
- /* Init the game: */
- arrays_free();
- set_defaults();
-
- strcpy(level_subset,subset);
-
- if (st_gl_mode == ST_GL_LOAD_LEVEL_FILE)
- {
- if (current_level.load(level_subset))
- exit(1);
- }
- else
- {
- if(current_level.load(level_subset, level) != 0)
- exit(1);
- }
-
- current_level.load_gfx();
- loadshared();
- activate_bad_guys(¤t_level);
- activate_particle_systems();
- current_level.load_song();
-
- tux.init();
-
- if(st_gl_mode != ST_GL_TEST)
- load_hs();
-
- if(st_gl_mode == ST_GL_PLAY || st_gl_mode == ST_GL_LOAD_LEVEL_FILE)
- levelintro();
-
- timer_init(&time_left,true);
- start_timers();
-
- if(st_gl_mode == ST_GL_LOAD_GAME)
- loadgame(levelnb);
-}
int
GameSession::run()
{
+ current_ = this;
+
int fps_cnt;
bool jump;
bool done;
tux.input.old_fire = tux.input.fire;
- game_event();
+ process_events();
if(show_menu)
{
}
}
-/* Break a brick: */
-void trybreakbrick(float x, float y, bool small)
-{
- Tile* tile = gettile(x, y);
- if (tile->brick)
- {
- if (tile->data > 0)
- {
- /* Get a distro from it: */
- add_bouncy_distro(((int)(x + 1) / 32) * 32,
- (int)(y / 32) * 32);
-
- if (!counting_distros)
- {
- counting_distros = true;
- distro_counter = 50;
- }
-
- if (distro_counter <= 0)
- current_level.change(x, y, TM_IA, tile->next_tile);
-
- play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
- score = score + SCORE_DISTRO;
- distros++;
- }
- else if (!small)
- {
- /* Get rid of it: */
- current_level.change(x, y, TM_IA, tile->next_tile);
-
- /* Replace it with broken bits: */
- add_broken_brick(((int)(x + 1) / 32) * 32,
- (int)(y / 32) * 32);
-
- /* Get some score: */
- play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER);
- score = score + SCORE_BRICK;
- }
- }
-}
-
-
/* Bounce a brick: */
-
void bumpbrick(float x, float y)
{
add_bouncy_brick(((int)(x + 1) / 32) * 32,
play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER);
}
-/* Empty a box: */
-void tryemptybox(float x, float y, int col_side)
-{
- 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(tile->data)
- {
- 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 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 3:// '!': /* Add a golden herring */
- add_upgrade((int)((x + 1) / 32) * 32, (int)(y / 32) * 32 - 32, col_side, UPGRADE_HERRING);
- break;
- default:
- break;
- }
-
- /* Empty the box: */
- current_level.change(x, y, TM_IA, tile->next_tile);
-}
-
-/* Try to grab a distro: */
-void trygrabdistro(float x, float y, int bounciness)
-{
- Tile* tile = gettile(x, y);
- if (tile && tile->distro)
- {
- current_level.change(x, y, TM_IA, tile->next_tile);
- play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
-
- if (bounciness == BOUNCE)
- {
- add_bouncy_distro(((int)(x + 1) / 32) * 32,
- (int)(y / 32) * 32);
- }
-
- score = score + SCORE_DISTRO;
- distros++;
- }
-}
-
-/* Try to bump a bad guy from below: */
-void trybumpbadguy(float x, float y)
-{
- /* Bad guys: */
- 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)
- {
- bad_guys[i].collision(&tux, CO_PLAYER, COLLISION_BUMP);
- }
- }
-
-
- /* Upgrades: */
- 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 &&
- upgrades[i].base.y >= y - 16 && upgrades[i].base.y <= y + 16)
- {
- upgrades[i].base.xm = -upgrades[i].base.xm;
- upgrades[i].base.ym = -8;
- play_sound(sounds[SND_BUMP_UPGRADE], SOUND_CENTER_SPEAKER);
- }
- }
-}
-
/* (Status): */
void drawstatus(void)
{
wait_for_event(event,2000,5000,true);
}
-void savegame(int slot)
+void
+GameSession::savegame(int slot)
{
char savefile[1024];
FILE* fi;
}
-void loadgame(int slot)
+void
+GameSession::loadgame(int slot)
{
char savefile[1024];
char str[100];
levelintro();
update_time = st_get_ticks();
- fread(&score,sizeof(int),1,fi);
- fread(&distros,sizeof(int),1,fi);
+ fread(&score, sizeof(int),1,fi);
+ fread(&distros, sizeof(int),1,fi);
fread(&scroll_x,sizeof(float),1,fi);
- fread(&tux, sizeof(Player), 1, fi);
+ fread(&tux, sizeof(Player), 1, fi);
timer_fread(&tux.invincible_timer,fi);
timer_fread(&tux.skidding_timer,fi);
timer_fread(&tux.safe_timer,fi);
#define ST_GL_LOAD_GAME 2
#define ST_GL_LOAD_LEVEL_FILE 3
-// FIXME: Make this local to the gamesession
-extern Level current_level;
-
extern int game_started;
class GameSession
{
private:
timer_type fps_timer, frame_timer;
+ Level current_level;
public:
- GameSession(const char * subset, int levelnb, int mode);
+ GameSession();
+ GameSession(const std::string& filename);
+ GameSession(const std::string& subset, int levelnb, int mode);
int run();
void draw();
int action();
+ void process_events();
+
+ Level* get_level() { return ¤t_level; }
+
+ void savegame(int slot);
+ void loadgame(int slot);
+
+ static GameSession* current() { return current_; }
+ private:
+ static GameSession* current_;
+
+ void levelintro();
+ void start_timers();
+ void activate_particle_systems();
};
void activate_bad_guys(Level* plevel);
-void savegame(int slot);
-void loadgame(int slot);
+
std::string slotinfo(int slot);
bool rectcollision(base_type* one, base_type* two);
void drawshape(float x, float y, unsigned int c, Uint8 alpha = 255);
void bumpbrick(float x, float y);
-/** Try to grab the coin at the given coordinates */
-void trygrabdistro(float x, float y, int bounciness);
-
-/** Try to break the brick at the given coordinates */
-void trybreakbrick(float x, float y, bool small);
-
-/** Try to get the content out of a bonus box, thus emptying it */
-void tryemptybox(float x, float y, int col_side);
-
-/** Try to bumb a badguy that might we walking above Tux, thus shaking
- the tile which the badguy is walking on an killing him this way */
-void trybumpbadguy(float x, float y);
-
#endif /*SUPERTUX_GAMELOOP_H*/
}
int
-Level::load(const char* filename)
+Level::load(const std::string& filename)
{
FILE * fi;
lisp_object_t* root_obj = 0;
- fi = fopen(filename, "r");
+ fi = fopen(filename.c_str(), "r");
if (fi == NULL)
{
- perror(filename);
+ perror(filename.c_str());
return -1;
}
if (root_obj->type == LISP_TYPE_EOF || root_obj->type == LISP_TYPE_PARSE_ERROR)
{
- printf("World: Parse Error in file %s", filename);
+ printf("World: Parse Error in file %s", filename.c_str());
}
vector<int> ia_tm;
}
-unsigned int gettileid(float x, float y)
+unsigned int
+Level::gettileid(float x, float y)
{
int xx, yy;
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.ia_tiles[yy][xx];
+ if (yy >= 0 && yy < 15 && xx >= 0 && xx <= width)
+ c = ia_tiles[yy][xx];
else
c = 0;
Tile* gettile(float x, float y)
{
- return TileManager::instance()->get(gettileid(x, y));
+ return TileManager::instance()->get(GameSession::current()->get_level()->gettileid(x, y));
}
bool issolid(float x, float y)
{
- Tile* tile = TileManager::instance()->get(gettileid(x,y));
+ Tile* tile = gettile(x,y);
return tile && tile->solid;
}
bool isbrick(float x, float y)
{
- Tile* tile = TileManager::instance()->get(gettileid(x,y));
+ Tile* tile = gettile(x,y);
return tile && tile->brick;
}
bool isice(float x, float y)
{
- Tile* tile = TileManager::instance()->get(gettileid(x,y));
+ Tile* tile = gettile(x,y);
return tile && tile->ice;
}
bool isfullbox(float x, float y)
{
- Tile* tile = TileManager::instance()->get(gettileid(x,y));
+ Tile* tile = gettile(x,y);
return tile && tile->fullbox;
}
bool isdistro(float x, float y)
{
- Tile* tile = TileManager::instance()->get(gettileid(x,y));
+ Tile* tile = gettile(x,y);
return tile && tile->distro;
}
void cleanup();
int load(const char* subset, int level);
- int load(const char* filename);
+ int load(const std::string& filename);
void load_gfx();
void load_song();
/** Resize the level to a new width */
void change_size (int new_width);
+
+ /** Return the id of the tile at position x/y */
+ unsigned int gettileid(float x, float y);
};
void level_load_image(texture_type* ptexture, std::string theme, const char * file, int use_alpha);
void level_free_song();
void level_free_gfx();
-/** Return the id of the tile at the given x/y coordinates */
-unsigned int gettileid(float x, float y);
-
/** Return a pointer to the tile at the given x/y coordinates */
Tile* gettile(float x, float y);
void
Player::keep_in_bounds()
{
+ Level* plevel = GameSession::current()->get_level();
+
/* Keep tux in bounds: */
if (base.x< 0)
base.x= 0;
scroll_x = 0;
}
- else if (base.x> screen->w / 2 + scroll_x && scroll_x < ((current_level.width * 32) - screen->w))
+ else if (base.x > screen->w / 2 + scroll_x
+ && scroll_x < ((GameSession::current()->get_level()->width * 32) - screen->w))
{
- // Scroll the screen in past center:
+ // FIXME: Scrolling needs to be handled by a seperate View
+ // class, doing it as a player huck is ugly
+ // Scroll the screen in past center:
scroll_x = base.x - screen->w / 2;
- if (scroll_x > ((current_level.width * 32) - screen->w))
- scroll_x = ((current_level.width * 32) - screen->w);
+ if (scroll_x > ((plevel->width * 32) - screen->w))
+ scroll_x = ((plevel->width * 32) - screen->w);
}
else if (base.x> 608 + scroll_x)
{
{
int slot = save_game_menu->check();
if (slot != -1)
- savegame(slot - 1);
+ GameSession::current()->savegame(slot - 1);
}
bool process_load_game_menu()
}
else
{
- loadgame(slot - 1);
+ //loadgame(slot - 1);
+ puts("Warning: Loading games isn't supported at the moment");
}
}
st_pause_ticks_stop();
void bullet_action(bullet_type* pbullet)
{
- pbullet->base.x = pbullet->base.x + pbullet->base.xm * frame_ratio;
- pbullet->base.y = pbullet->base.y + pbullet->base.ym * frame_ratio;
+ pbullet->base.x = pbullet->base.x + pbullet->base.xm * frame_ratio;
+ pbullet->base.y = pbullet->base.y + pbullet->base.ym * frame_ratio;
- collision_swept_object_map(&pbullet->old_base,&pbullet->base);
+ collision_swept_object_map(&pbullet->old_base,&pbullet->base);
- if (issolid(pbullet->base.x, pbullet->base.y + 4) || issolid(pbullet->base.x, pbullet->base.y))
- {
- pbullet->base.ym = -pbullet->base.ym;
- pbullet->base.y = (int)(pbullet->base.y / 32) * 32;
- }
+ if (issolid(pbullet->base.x, pbullet->base.y + 4) || issolid(pbullet->base.x, pbullet->base.y))
+ {
+ pbullet->base.ym = -pbullet->base.ym;
+ pbullet->base.y = (int)(pbullet->base.y / 32) * 32;
+ }
- pbullet->base.ym = pbullet->base.ym + GRAVITY;
+ pbullet->base.ym = pbullet->base.ym + GRAVITY;
- if (pbullet->base.x < scroll_x ||
- pbullet->base.x > scroll_x + screen->w ||
- pbullet->base.y < 0 ||
- pbullet->base.y > screen->h ||
- issolid(pbullet->base.x + 4, pbullet->base.y + 2) ||
- issolid(pbullet->base.x, pbullet->base.y + 2))
- {
- bullets.erase(static_cast<std::vector<bullet_type>::iterator>(pbullet));
- }
+ if (pbullet->base.x < scroll_x ||
+ pbullet->base.x > scroll_x + screen->w ||
+ pbullet->base.y < 0 ||
+ pbullet->base.y > screen->h ||
+ issolid(pbullet->base.x + 4, pbullet->base.y + 2) ||
+ issolid(pbullet->base.x, pbullet->base.y + 2))
+ {
+ bullets.erase(static_cast<std::vector<bullet_type>::iterator>(pbullet));
+ }
}
if(c_object == CO_BADGUY) {
std::vector<bullet_type>::iterator i;
for(i = bullets.begin(); i != bullets.end(); ++i) {
- if(& (*i) == pbullet) {
- bullets.erase(i);
- return;
- }
+ if(& (*i) == pbullet) {
+ bullets.erase(i);
+ return;
+ }
}
}
}
{
- if (pupgrade->base.height < 32)
- {
- /* Rise up! */
+ if (pupgrade->base.height < 32)
+ {
+ /* Rise up! */
- pupgrade->base.height = pupgrade->base.height + 0.7 * frame_ratio;
- if(pupgrade->base.height > 32)
- pupgrade->base.height = 32;
- }
- else
- {
- /* Move around? */
+ pupgrade->base.height = pupgrade->base.height + 0.7 * frame_ratio;
+ if(pupgrade->base.height > 32)
+ pupgrade->base.height = 32;
+ }
+ else
+ {
+ /* Move around? */
- if (pupgrade->kind == UPGRADE_MINTS ||
- pupgrade->kind == UPGRADE_HERRING)
- {
- pupgrade->base.x = pupgrade->base.x + pupgrade->base.xm * frame_ratio;
- pupgrade->base.y = pupgrade->base.y + pupgrade->base.ym * frame_ratio;
+ if (pupgrade->kind == UPGRADE_MINTS ||
+ pupgrade->kind == UPGRADE_HERRING)
+ {
+ pupgrade->base.x = pupgrade->base.x + pupgrade->base.xm * frame_ratio;
+ pupgrade->base.y = pupgrade->base.y + pupgrade->base.ym * frame_ratio;
- collision_swept_object_map(&pupgrade->old_base,&pupgrade->base);
+ collision_swept_object_map(&pupgrade->old_base,&pupgrade->base);
- /* Off the screen? Kill it! */
+ /* Off the screen? Kill it! */
- if (pupgrade->base.x < scroll_x - pupgrade->base.width)
- upgrades.erase(static_cast<std::vector<upgrade_type>::iterator>(pupgrade));
- if (pupgrade->base.y > screen->h)
- upgrades.erase(static_cast<std::vector<upgrade_type>::iterator>(pupgrade));
+ if (pupgrade->base.x < scroll_x - pupgrade->base.width)
+ upgrades.erase(static_cast<std::vector<upgrade_type>::iterator>(pupgrade));
+ if (pupgrade->base.y > screen->h)
+ upgrades.erase(static_cast<std::vector<upgrade_type>::iterator>(pupgrade));
- if (issolid(pupgrade->base.x + 1, pupgrade->base.y + 32.) ||
- issolid(pupgrade->base.x + 31., pupgrade->base.y + 32.))
+ if (issolid(pupgrade->base.x + 1, pupgrade->base.y + 32.) ||
+ issolid(pupgrade->base.x + 31., pupgrade->base.y + 32.))
+ {
+ if (pupgrade->base.ym > 0)
{
- if (pupgrade->base.ym > 0)
+ if (pupgrade->kind == UPGRADE_MINTS)
{
- if (pupgrade->kind == UPGRADE_MINTS)
- {
- pupgrade->base.ym = 0;
- }
- else if (pupgrade->kind == UPGRADE_HERRING)
- {
- pupgrade->base.ym = -8;
- }
-
- pupgrade->base.y = (int)(pupgrade->base.y / 32) * 32;
+ pupgrade->base.ym = 0;
+ }
+ else if (pupgrade->kind == UPGRADE_HERRING)
+ {
+ pupgrade->base.ym = -8;
}
- }
- else
- pupgrade->base.ym = pupgrade->base.ym + GRAVITY * frame_ratio;
- if (issolid(pupgrade->base.x - 1, (int) pupgrade->base.y))
- {
- if(pupgrade->base.xm < 0)
- pupgrade->base.xm = -pupgrade->base.xm;
- }
- else if (issolid(pupgrade->base.x + pupgrade->base.width, (int) pupgrade->base.y))
- {
- if(pupgrade->base.xm > 0)
- pupgrade->base.xm = -pupgrade->base.xm;
+ pupgrade->base.y = (int)(pupgrade->base.y / 32) * 32;
}
}
+ else
+ pupgrade->base.ym = pupgrade->base.ym + GRAVITY * frame_ratio;
+ if (issolid(pupgrade->base.x - 1, (int) pupgrade->base.y))
+ {
+ if(pupgrade->base.xm < 0)
+ pupgrade->base.xm = -pupgrade->base.xm;
+ }
+ else if (issolid(pupgrade->base.x + pupgrade->base.width, (int) pupgrade->base.y))
+ {
+ if(pupgrade->base.xm > 0)
+ pupgrade->base.xm = -pupgrade->base.xm;
+ }
}
+
+ }
}
void upgrade_draw(upgrade_type* pupgrade)
{
SDL_Rect dest;
- if (pupgrade->base.height < 32)
+ if (pupgrade->base.height < 32)
+ {
+ /* Rising up... */
+
+ dest.x = (int)(pupgrade->base.x - scroll_x);
+ dest.y = (int)(pupgrade->base.y + 32 - pupgrade->base.height);
+ dest.w = 32;
+ dest.h = (int)pupgrade->base.height;
+
+ if (pupgrade->kind == UPGRADE_MINTS)
+ texture_draw_part(&img_mints,0,0,dest.x,dest.y,dest.w,dest.h);
+ else if (pupgrade->kind == UPGRADE_COFFEE)
+ texture_draw_part(&img_coffee,0,0,dest.x,dest.y,dest.w,dest.h);
+ else if (pupgrade->kind == UPGRADE_HERRING)
+ texture_draw_part(&img_golden_herring,0,0,dest.x,dest.y,dest.w,dest.h);
+ }
+ else
+ {
+ if (pupgrade->kind == UPGRADE_MINTS)
{
- /* Rising up... */
-
- dest.x = (int)(pupgrade->base.x - scroll_x);
- dest.y = (int)(pupgrade->base.y + 32 - pupgrade->base.height);
- dest.w = 32;
- dest.h = (int)pupgrade->base.height;
-
- if (pupgrade->kind == UPGRADE_MINTS)
- texture_draw_part(&img_mints,0,0,dest.x,dest.y,dest.w,dest.h);
- else if (pupgrade->kind == UPGRADE_COFFEE)
- texture_draw_part(&img_coffee,0,0,dest.x,dest.y,dest.w,dest.h);
- else if (pupgrade->kind == UPGRADE_HERRING)
- texture_draw_part(&img_golden_herring,0,0,dest.x,dest.y,dest.w,dest.h);
+ texture_draw(&img_mints,
+ pupgrade->base.x - scroll_x, pupgrade->base.y);
}
- else
+ else if (pupgrade->kind == UPGRADE_COFFEE)
{
- if (pupgrade->kind == UPGRADE_MINTS)
- {
- texture_draw(&img_mints,
- pupgrade->base.x - scroll_x, pupgrade->base.y);
- }
- else if (pupgrade->kind == UPGRADE_COFFEE)
- {
- texture_draw(&img_coffee,
- pupgrade->base.x - scroll_x, pupgrade->base.y);
- }
- else if (pupgrade->kind == UPGRADE_HERRING)
- {
- texture_draw(&img_golden_herring,
- pupgrade->base.x - scroll_x, pupgrade->base.y);
- }
+ texture_draw(&img_coffee,
+ pupgrade->base.x - scroll_x, pupgrade->base.y);
}
+ else if (pupgrade->kind == UPGRADE_HERRING)
+ {
+ texture_draw(&img_golden_herring,
+ pupgrade->base.x - scroll_x, pupgrade->base.y);
+ }
+ }
}
void upgrade_collision(upgrade_type* pupgrade, void* p_c_object, int c_object)
pplayer->base.height = 64;
pplayer->base.y -= 32;
if(collision_object_map(&pplayer->base))
- {
- pplayer->base.height = 32;
- pplayer->base.y += 32;
- pplayer->duck = true;
- }
+ {
+ pplayer->base.height = 32;
+ pplayer->base.y += 32;
+ pplayer->duck = true;
+ }
timer_start(&super_bkgd_timer, 350);
}
else if (pupgrade->kind == UPGRADE_COFFEE)
#include "math.h"
void loadshared(void);
-void activate_particle_systems(void);
static texture_type bkg_title;
static texture_type logo;
texture_draw_bg(&bkg_title);
}
-void draw_demo()
+void draw_demo(Level* plevel)
{
- /* DEMO begin */
- /* update particle systems */
+ /* FIXME:
+ // update particle systems
std::vector<ParticleSystem*>::iterator p;
for(p = particle_systems.begin(); p != particle_systems.end(); ++p)
{
{
(*p)->draw(scroll_x, 0, 0);
}
+ */
// Draw interactive tiles:
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.ia_tiles[(int)y][(int)x + (int)(scroll_x / 32)]);
+ plevel->ia_tiles[(int)y][(int)x + (int)(scroll_x / 32)]);
}
}
}
// Wrap around at the end of the level back to the beginnig
- if(current_level.width * 32 - 320 < titletux.base.x)
+ if(plevel->width * 32 - 320 < titletux.base.x)
{
- titletux.base.x = titletux.base.x - (current_level.width * 32 - 640);
+ titletux.base.x = titletux.base.x - (plevel->width * 32 - 640);
scroll_x = titletux.base.x - 320;
}
st_pause_ticks_init();
- current_level.load((datadir + "/levels/misc/menu.stl").c_str());
+ GameSession session(datadir + "/levels/misc/menu.stl");
loadshared();
- activate_particle_systems();
+ //FIXME:activate_particle_systems();
/* Lower the gravity that tux doesn't jump to hectically through the demo */
//gravity = 5;
/* Draw the background: */
draw_background();
- draw_demo();
-
+ draw_demo(session.get_level());
+
if (current_menu == main_menu)
texture_draw(&logo, 160, 30);
#include "screen.h"
#include "defines.h"
#include "world.h"
+#include "tile.h"
texture_type img_distro[4];
void bouncy_brick_init(bouncy_brick_type* pbouncy_brick, float x, float y)
{
- pbouncy_brick->base.x = x;
- pbouncy_brick->base.y = y;
- pbouncy_brick->offset = 0;
+ pbouncy_brick->base.x = x;
+ pbouncy_brick->base.y = y;
+ pbouncy_brick->offset = 0;
pbouncy_brick->offset_m = -BOUNCY_BRICK_SPEED;
- pbouncy_brick->shape = gettileid(x, y);
+ pbouncy_brick->shape = GameSession::current()->get_level()->gettileid(x, y);
}
void bouncy_brick_action(bouncy_brick_type* pbouncy_brick)
dest.w = 32;
dest.h = 32;
+ Level* plevel = GameSession::current()->get_level();
+
// FIXME: overdrawing hack to clean the tile from the screen to
// paint it later at on offseted position
- if(current_level.bkgd_image[0] == '\0')
+ if(plevel->bkgd_image[0] == '\0')
{
fillrect(pbouncy_brick->base.x - scroll_x, pbouncy_brick->base.y,
- 32,32,current_level.bkgd_red,current_level.bkgd_green,
- current_level.bkgd_blue,0);
+ 32,32,
+ plevel->bkgd_red, plevel->bkgd_green, plevel->bkgd_blue, 0);
}
else
{
text_draw(&gold_text, str, (int)pfloating_score->base.x + 16 - strlen(str) * 8, (int)pfloating_score->base.y, 1);
}
+/* Break a brick: */
+void trybreakbrick(float x, float y, bool small)
+{
+ Level* plevel = GameSession::current()->get_level();
+
+ Tile* tile = gettile(x, y);
+ if (tile->brick)
+ {
+ if (tile->data > 0)
+ {
+ /* Get a distro from it: */
+ add_bouncy_distro(((int)(x + 1) / 32) * 32,
+ (int)(y / 32) * 32);
+
+ if (!counting_distros)
+ {
+ counting_distros = true;
+ distro_counter = 50;
+ }
+
+ if (distro_counter <= 0)
+ plevel->change(x, y, TM_IA, tile->next_tile);
+
+ play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
+ score = score + SCORE_DISTRO;
+ distros++;
+ }
+ else if (!small)
+ {
+ /* Get rid of it: */
+ plevel->change(x, y, TM_IA, tile->next_tile);
+
+ /* Replace it with broken bits: */
+ add_broken_brick(((int)(x + 1) / 32) * 32,
+ (int)(y / 32) * 32);
+
+ /* Get some score: */
+ play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER);
+ score = score + SCORE_BRICK;
+ }
+ }
+}
+
+/* Empty a box: */
+void tryemptybox(float x, float y, int col_side)
+{
+ Level* plevel = GameSession::current()->get_level();
+
+ 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(tile->data)
+ {
+ 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 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 3:// '!': /* Add a golden herring */
+ add_upgrade((int)((x + 1) / 32) * 32, (int)(y / 32) * 32 - 32, col_side, UPGRADE_HERRING);
+ break;
+ default:
+ break;
+ }
+
+ /* Empty the box: */
+ plevel->change(x, y, TM_IA, tile->next_tile);
+}
+
+/* Try to grab a distro: */
+void trygrabdistro(float x, float y, int bounciness)
+{
+ Level* plevel = GameSession::current()->get_level();
+ Tile* tile = gettile(x, y);
+ if (tile && tile->distro)
+ {
+ plevel->change(x, y, TM_IA, tile->next_tile);
+ play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
+
+ if (bounciness == BOUNCE)
+ {
+ add_bouncy_distro(((int)(x + 1) / 32) * 32,
+ (int)(y / 32) * 32);
+ }
+
+ score = score + SCORE_DISTRO;
+ distros++;
+ }
+}
+
+/* Try to bump a bad guy from below: */
+void trybumpbadguy(float x, float y)
+{
+ /* Bad guys: */
+ 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)
+ {
+ bad_guys[i].collision(&tux, CO_PLAYER, COLLISION_BUMP);
+ }
+ }
+
+
+ /* Upgrades: */
+ 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 &&
+ upgrades[i].base.y >= y - 16 && upgrades[i].base.y <= y + 16)
+ {
+ upgrades[i].base.xm = -upgrades[i].base.xm;
+ upgrades[i].base.ym = -8;
+ play_sound(sounds[SND_BUMP_UPGRADE], SOUND_CENTER_SPEAKER);
+ }
+ }
+}
+
/* EOF */
void floating_score_action(floating_score_type* pfloating_score);
void floating_score_draw(floating_score_type* pfloating_score);
+
+/** Try to grab the coin at the given coordinates */
+void trygrabdistro(float x, float y, int bounciness);
+
+/** Try to break the brick at the given coordinates */
+void trybreakbrick(float x, float y, bool small);
+
+/** Try to get the content out of a bonus box, thus emptying it */
+void tryemptybox(float x, float y, int col_side);
+
+/** Try to bumb a badguy that might we walking above Tux, thus shaking
+ the tile which the badguy is walking on an killing him this way */
+void trybumpbadguy(float x, float y);
+
#endif /*SUPERTUX_WORLD_H*/