From: Matthias Braun Date: Sat, 20 Nov 2004 22:38:35 +0000 (+0000) Subject: forgot to update makefiles X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=fcae2511a70217bb8ca6e7fb13e0dab639a062f1;p=supertux.git forgot to update makefiles SVN-Revision: 2118 --- diff --git a/src/Makefile.am b/src/Makefile.am index 96d4ff34d..35bd69769 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,12 +5,13 @@ supertux_CXXFLAGS = -DLOCALEDIR=\"$(localedir)\" supertux_LDADD = $(top_builddir)/lib/libsupertux.la @LIBINTL@ -supertux_SOURCES = badguy.cpp badguy.h bitmask.cpp bitmask.h camera.cpp \ +supertux_SOURCES = camera.cpp \ camera.h collision.cpp collision.h intro.cpp intro.h \ - gameloop.cpp gameloop.h high_scores.cpp high_scores.h interactive_object.cpp \ - interactive_object.h level.cpp level.h level_subset.cpp level_subset.h leveleditor.cpp \ - leveleditor.h particlesystem.cpp particlesystem.h player.cpp player.h scene.cpp \ - scene.h special.cpp special.h supertux.cpp title.cpp title.h worldmap.cpp \ + gameloop.cpp gameloop.h high_scores.cpp high_scores.h \ + level.cpp level.h level_subset.cpp level_subset.h \ + leveleditor.cpp leveleditor.h particlesystem.cpp \ + particlesystem.h player.cpp player.h scene.cpp \ + scene.h supertux.cpp title.cpp title.h worldmap.cpp \ worldmap.h tile.h tile.cpp tile_manager.h tile_manager.cpp resources.h \ resources.cpp gameobjs.h gameobjs.cpp background.h background.cpp tilemap.h \ tilemap.cpp serializable.h sector.cpp sector.h misc.h misc.cpp defines.h \ @@ -19,10 +20,24 @@ supertux_SOURCES = badguy.cpp badguy.h bitmask.cpp bitmask.h camera.cpp \ object/coin.h object/coin.cpp \ object/block.h object/block.cpp \ object/platform.h object/platform.cpp \ - object/door.h object/door.cpp \ object/fireworks.h object/fireworks.cpp \ - object/bullet.h object/bullet.cpp + object/bullet.h object/bullet.cpp \ + object/specialriser.h object/specialriser.cpp \ + object/star.h object/star.cpp \ + object/oneup.h object/oneup.cpp \ + object/flower.h object/flower.cpp \ + object/growup.h object/growup.cpp \ + badguy/badguy.h badguy/badguy.cpp \ + badguy/bomb.h badguy/bomb.cpp \ + badguy/bouncing_snowball.h badguy/bouncing_snowball.cpp\ + badguy/flame.h badguy/flame.cpp \ + badguy/jumpy.h badguy/jumpy.cpp \ + badguy/mrbomb.h badguy/mrbomb.cpp \ + badguy/mriceblock.h badguy/mriceblock.cpp \ + badguy/snowball.h badguy/snowball.cpp \ + badguy/spiky.h badguy/spiky.cpp \ + trigger/trigger_base.h trigger/trigger_base.cpp \ + trigger/door.h trigger/door.cpp \ + trigger/sequence_trigger.h trigger/sequence_trigger.cpp -# EOF # INCLUDES = -I$(top_srcdir)/lib -noinst_HEADERS = misc.h diff --git a/src/badguy.cpp b/src/badguy.cpp deleted file mode 100644 index 1fe2e2372..000000000 --- a/src/badguy.cpp +++ /dev/null @@ -1,1382 +0,0 @@ -// $Id$ -// -// SuperTux -// Copyright (C) 2000 Bill Kendrick -// Copyright (C) 2004 Tobias Glaesser -// Copyright (C) 2004 Matthias Braun -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -// 02111-1307, USA. - -#include - -#include -#include - -#include "app/globals.h" -#include "defines.h" -#include "special/sprite_manager.h" -#include "utils/lispwriter.h" -#include "badguy.h" -#include "tile.h" -#include "resources.h" -#include "camera.h" -#include "level.h" -#include "sector.h" -#include "tilemap.h" -#include "statistics.h" -#include "badguy_specs.h" - -#define BADGUY_WALK_SPEED .8f -#define WINGLING_FLY_SPEED 1.6f - -BadGuyKind badguykind_from_string(const std::string& str) -{ - if (str == "jumpy" || str == "money") // was "money" in ancient versions - return BAD_JUMPY; - else if (str == "mriceblock" || str == "laptop") // was "laptop" in ancient versions - return BAD_MRICEBLOCK; - else if (str == "mrbomb") - return BAD_MRBOMB; - else if (str == "stalactite") - return BAD_STALACTITE; - else if (str == "flame") - return BAD_FLAME; - else if (str == "fish") - return BAD_FISH; - else if (str == "flamefish") - return BAD_FLAMEFISH; - else if (str == "bouncingsnowball") - return BAD_BOUNCINGSNOWBALL; - else if (str == "flyingsnowball") - return BAD_FLYINGSNOWBALL; - else if (str == "spiky") - return BAD_SPIKY; - else if (str == "snowball" || str == "bsod") // was "bsod" in ancient versions - return BAD_SNOWBALL; - else if (str == "wingling") - return BAD_WINGLING; - else if (str == "walkingtree") - return BAD_WALKINGTREE; - else if(str == "bomb") // not to be used as a real bad guys - return BAD_BOMB; - else - { - return BAD_INVALID; - } -} - -std::string badguykind_to_string(BadGuyKind kind) -{ - switch(kind) - { - case BAD_JUMPY: - return "jumpy"; - break; - case BAD_MRICEBLOCK: - return "mriceblock"; - break; - case BAD_MRBOMB: - return "mrbomb"; - break; - case BAD_STALACTITE: - return "stalactite"; - break; - case BAD_FLAME: - return "flame"; - break; - case BAD_FISH: - return "fish"; - break; - case BAD_FLAMEFISH: - return "flamefish"; - break; - case BAD_BOUNCINGSNOWBALL: - return "bouncingsnowball"; - break; - case BAD_FLYINGSNOWBALL: - return "flyingsnowball"; - break; - case BAD_SPIKY: - return "spiky"; - break; - case BAD_SNOWBALL: - return "snowball"; - break; - case BAD_WINGLING: - return "wingling"; - break; - case BAD_WALKINGTREE: - return "walkingtree"; - case BAD_BOMB: // not to be used as a real bad guys - return "bomb"; - break; - default: - return "snowball"; - } -} - -#if 0 -BadGuy::BadGuy(BadGuyKind kind_, LispReader& lispreader) - : squishcount(0) -{ - lispreader.read_float("x", start_position.x); - lispreader.read_float("y", start_position.y); - - kind = kind_; - - stay_on_platform = false; - lispreader.read_bool("stay-on-platform", stay_on_platform); - - init(); -} - -BadGuy::BadGuy(BadGuyKind kind_, float x, float y) - : squishcount(0) -{ - start_position.x = x; - start_position.y = y; - stay_on_platform = false; - - kind = kind_; - - init(); -} - -BadGuy::~BadGuy() -{ -} - -void -BadGuy::init() -{ - bbox.set_pos(start_position); - bbox.set_size(32, 32); - - state = NORMAL; - old_base = base; - dir = LEFT; - seen = false; - animation_offset = 0; - target.x = target.y = -1; - physic.reset(); - frozen_timer.init(true); - timer.init(true); - - specs = badguyspecs_manager->load(badguykind_to_string(kind)); -} - -void -BadGuy::write(LispWriter& writer) -{ - writer.start_list(badguykind_to_string(kind)); - - writer.write_float("x", base.x); - writer.write_float("y", base.y); - writer.write_bool("stay-on-platform", stay_on_platform); - - writer.end_list(badguykind_to_string(kind)); -} - -void -BadGuy::activate(Direction activation_dir) -{ - state = NORMAL; - animation_offset = 0; - target.x = target.y = -1; - physic.reset(); - frozen_timer.start(0); - timer.start(0); - - dying = DYING_NOT; - seen = true; - - dir = activation_dir; - float dirsign = activation_dir == LEFT ? -1 : 1; - - set_action("left", "right"); - if(kind == BAD_MRBOMB) { - physic.set_velocity(dirsign * BADGUY_WALK_SPEED, 0); - } else if (kind == BAD_MRICEBLOCK) { - physic.set_velocity(dirsign * BADGUY_WALK_SPEED, 0); - } else if(kind == BAD_JUMPY) { - set_action("left-up", "right-up"); - } else if(kind == BAD_BOMB) { - set_action("ticking-left", "ticking-right"); - // hack so that the bomb doesn't hurt until it explodes... - dying = DYING_SQUISHED; - } else if(kind == BAD_FLAME) { - angle = 0; - physic.enable_gravity(false); - set_action("normal", "normal"); - } else if(kind == BAD_BOUNCINGSNOWBALL) { - physic.set_velocity(dirsign * 1.3, 0); - } else if(kind == BAD_STALACTITE) { - physic.enable_gravity(false); - set_action("normal", "normal"); - } else if(kind == BAD_FISH) { - set_action("normal", "normal"); - physic.enable_gravity(true); - } else if(kind == BAD_FLAMEFISH) { - set_action("normal", "normal"); - physic.enable_gravity(true); - } else if(kind == BAD_FLYINGSNOWBALL) { - physic.enable_gravity(false); - } else if(kind == BAD_SPIKY) { - physic.set_velocity(dirsign * BADGUY_WALK_SPEED, 0); - } else if(kind == BAD_SNOWBALL) { - physic.set_velocity(dirsign * BADGUY_WALK_SPEED, 0); - } else if(kind == BAD_WINGLING) { - physic.set_velocity(dirsign * WINGLING_FLY_SPEED, 0); - physic.enable_gravity(false); - set_action("left", "left"); - } else if (kind == BAD_WALKINGTREE) { - // TODO: why isn't the height/width being set properly in set_action? - physic.set_velocity(dirsign * BADGUY_WALK_SPEED, 0); - state = BGM_BIG; - set_action("left", "left"); - bbox.set_size(66, 66); - } -} - -Surface* -BadGuy::get_image() -{ - // Set action as the "default" one. - specs->sprite->set_action("left"); - if(BAD_JUMPY) - specs->sprite->set_action("left-up"); - else if(kind == BAD_BOMB) - specs->sprite->set_action("ticking-left"); - else if(kind == BAD_FLAME) - specs->sprite->set_action("normal"); - else if(kind == BAD_STALACTITE) - specs->sprite->set_action("normal"); - else if(kind == BAD_FISH) - specs->sprite->set_action("normal"); - else if(kind == BAD_FLAMEFISH) - specs->sprite->set_action("normal"); - - return specs->sprite->get_frame(0); -} - -#if 0 -void -BadGuy::action_mriceblock(double elapsed_time) -{ - Player& tux = *Sector::current()->player; - - if(state != HELD) - fall(); - - /* Move left/right: */ - if (state != HELD) - { - // move - physic.apply(elapsed_time, base.x, base.y, Sector::current()->gravity); - if (dying != DYING_FALLING) - collision_swept_object_map(&old_base,&base); - } - else if (state == HELD) - { /* FIXME: The pbad object shouldn't know about pplayer objects. */ - /* If we're holding the iceblock */ - dir = tux.dir; - if(tux.size == SMALL) - { - if(dir == RIGHT) - base.x = tux.base.x + 24; - else // dir == LEFT - base.x = tux.base.x - 12; - base.y = tux.base.y + tux.base.height/1.5 - base.height; - } - else // TUX == BIG - { - if(dir == RIGHT) - base.x = tux.base.x + 24; - else // dir == LEFT - base.x = tux.base.x - 4; - base.y = tux.base.y + tux.base.height/1.5 - base.height; - } - - if(collision_object_map(base)) - { - base.x = tux.base.x; - base.y = tux.base.y + tux.base.height/1.5 - base.height; - } - - if(tux.input.fire != DOWN) /* SHOOT! */ - { - if(dir == LEFT) - base.x = tux.base.x - base.width; - else - base.x = tux.base.x + tux.base.width; - old_base = base; - - state=KICK; - tux.kick_timer.start(KICKING_TIME); - set_action("flat-left", "flat-right"); - physic.set_velocity_x((dir == LEFT) ? -3.5 : 3.5); - SoundManager::get()->play_sound(IDToSound(SND_KICK), this, Sector::current()->player->get_pos()); - } - } - - if (!dying) - { - int changed = dir; - check_horizontal_bump(); - if(state == KICK && changed != dir) - { - SoundManager::get()->play_sound(IDToSound(SND_RICOCHET), get_pos(), Sector::current()->player->get_pos()); - } - } - - /* Handle state timer: */ - if (state == FLAT) - { - if(!timer.check()) - { - state = NORMAL; - set_action("left", "right"); - physic.set_velocity( (dir == LEFT) ? -.8 : .8, 0); - } - } -} - -void -BadGuy::check_horizontal_bump(bool checkcliff) -{ - float halfheight = base.height / 2; - if (dir == LEFT && issolid( base.x, base.y + halfheight)) - { - if (kind == BAD_MRICEBLOCK && state == KICK) - { - Sector::current()->trybreakbrick(Vector(base.x, base.y + halfheight), false); - Sector::current()->tryemptybox(Vector(base.x, base.y + halfheight), dir); - } - - dir = RIGHT; - physic.set_velocity(-physic.get_velocity_x(), physic.get_velocity_y()); - return; - } - if (dir == RIGHT && issolid( base.x + base.width, base.y + halfheight)) - { - if (kind == BAD_MRICEBLOCK && state == KICK) - { - Sector::current()->trybreakbrick( - Vector(base.x + base.width, base.y + halfheight), false); - Sector::current()->tryemptybox( - Vector(base.x + base.width, base.y + halfheight), dir); - } - - dir = LEFT; - physic.set_velocity(-physic.get_velocity_x(), physic.get_velocity_y()); - return; - } - - // don't check for cliffs when we're falling - if(!checkcliff) - return; - if(!issolid(base.x + base.width/2, base.y + base.height)) - return; - - if(dir == LEFT && !issolid(base.x, (int) base.y + base.height + halfheight)) - { - dir = RIGHT; - physic.set_velocity(-physic.get_velocity_x(), physic.get_velocity_y()); - return; - } - if(dir == RIGHT && !issolid(base.x + base.width, - (int) base.y + base.height + halfheight)) - { - dir = LEFT; - physic.set_velocity(-physic.get_velocity_x(), physic.get_velocity_y()); - return; - } -} - -void -BadGuy::fall() -{ - /* Fall if we get off the ground: */ - if (dying != DYING_FALLING) - { - if (!issolid(base.x+base.width/2, base.y + base.height)) - { - // not solid below us? enable gravity - physic.enable_gravity(true); - } - else - { - /* Land: */ - if (physic.get_velocity_y() < 0) - { - base.y = int((base.y + base.height)/32) * 32 - base.height; - physic.set_velocity_y(0); - } - // no gravity anymore please - physic.enable_gravity(false); - - if (stay_on_platform && state == NORMAL) - { - if (!issolid(base.x + ((dir == LEFT) ? 0 : base.width), - base.y + base.height)) - { - if (dir == LEFT) - { - dir = RIGHT; - physic.set_velocity_x(fabsf(physic.get_velocity_x())); - } - else - { - dir = LEFT; - physic.set_velocity_x(-fabsf(physic.get_velocity_x())); - } - } - } - } - } - else - { - physic.enable_gravity(true); - } -} -#endif - -void -BadGuy::action_jumpy(double elapsed_time) -{ - if(frozen_timer.check()) { - set_action("left-iced", "right-iced"); - return; - } - - const float vy = physic.get_velocity_y(); - - // XXX: These tests *should* use location from ground, not velocity - if (fabsf(vy) > 560) - set_action("left-down", "right-down"); - else if (fabsf(vy) > 530) - set_action("left-middle", "right-middle"); - else - set_action("left-up", "right-up"); - - Player& tux = *Sector::current()->player; - - static const float JUMPV = 6; - - fall(); - // jump when on ground - if(dying == DYING_NOT && issolid(base.x, base.y+32)) - { - physic.set_velocity_y(JUMPV); - physic.enable_gravity(true); - - state = JUMPY_JUMP; - } - else if(state == JUMPY_JUMP) - { - state = NORMAL; - } - - // set direction based on tux - if(dying == DYING_NOT) { - if(tux.base.x > base.x) - dir = RIGHT; - else - dir = LEFT; - } - - // move - physic.apply(elapsed_time, base.x, base.y, Sector::current()->gravity); - if(dying == DYING_NOT) - collision_swept_object_map(&old_base, &base); -} - -void -BadGuy::action_mrbomb(double elapsed_time) -{ - if(frozen_timer.check()) - { - set_action("iced-left", "iced-right"); - return; - } - - if (dying == DYING_NOT) - check_horizontal_bump(true); - - fall(); - - physic.apply(elapsed_time, base.x, base.y, Sector::current()->gravity); - if (dying != DYING_FALLING) - collision_swept_object_map(&old_base,&base); -} - -void -BadGuy::action_bomb(double elapsed_time) -{ - static const int TICKINGTIME = 1000; - static const int EXPLODETIME = 1000; - - fall(); - - if(state == NORMAL) { - state = BOMB_TICKING; - timer.start(TICKINGTIME); - } else if(!timer.check()) { - if(state == BOMB_TICKING) { - state = BOMB_EXPLODE; - set_action("explosion", "explosion"); - dying = DYING_NOT; // now the bomb hurts - timer.start(EXPLODETIME); - - SoundManager::get()->play_sound(IDToSound(SND_EXPLODE), this, Sector::current()->player->get_pos()); - } else if(state == BOMB_EXPLODE) { - remove_me(); - return; - } - } - - // move - physic.apply(elapsed_time, base.x, base.y, Sector::current()->gravity); - collision_swept_object_map(&old_base,&base); -} - -void -BadGuy::action_stalactite(double elapsed_time) -{ - Player& tux = *Sector::current()->player; - - static const int SHAKETIME = 800; - static const int RANGE = 40; - - if(state == NORMAL) { - // start shaking when tux is below the stalactite and at least 40 pixels - // near - if(tux.base.x + 32 > base.x - RANGE && tux.base.x < base.x + 32 + RANGE - && tux.base.y + tux.base.height > base.y - && tux.dying == DYING_NOT) { - timer.start(SHAKETIME); - state = STALACTITE_SHAKING; - } - } if(state == STALACTITE_SHAKING) { - base.x = old_base.x + (rand() % 6) - 3; // TODO this could be done nicer... - if(!timer.check()) { - state = STALACTITE_FALL; - } - } else if(state == STALACTITE_FALL) { - fall(); - /* Destroy if we collides with land */ - if(issolid(base.x+base.width/2, base.y+base.height)) - { - timer.start(2000); - dying = DYING_SQUISHED; - state = FLAT; - set_action("broken", "broken"); - } - } else if(state == FLAT) { - fall(); - } - - // move - physic.apply(elapsed_time, base.x, base.y, Sector::current()->gravity); - - if(dying == DYING_SQUISHED && !timer.check()) - remove_me(); -} - -void -BadGuy::action_flame(double elapsed_time) -{ - static const float radius = 100; - static const float speed = 0.02; - base.x = old_base.x + cos(angle) * radius; - base.y = old_base.y + sin(angle) * radius; - - angle = fmodf(angle + elapsed_time * speed, 2*M_PI); -} - -void -BadGuy::action_fish(double elapsed_time) -{ - if(frozen_timer.check()) - { - if(physic.get_velocity_y() < 0) - set_action("iced-down", "iced-down"); - else - set_action("iced", "iced"); - - return; - } - - static const float JUMPV = 6; - static const int WAITTIME = 1000; - - // go in wait state when back in water - if(dying == DYING_NOT - && gettile(base.x, base.y + base.height) - && gettile(base.x, base.y + base.height)->attributes & Tile::WATER - && physic.get_velocity_y() <= 0 && state == NORMAL) - { - state = FISH_WAIT; - set_action("hide", "hide"); - physic.set_velocity(0, 0); - physic.enable_gravity(false); - timer.start(WAITTIME); - } - else if(state == FISH_WAIT && !timer.check()) - { - // jump again - set_action("normal", "normal"); - state = NORMAL; - physic.set_velocity(0, JUMPV); - physic.enable_gravity(true); - } - - physic.apply(elapsed_time, base.x, base.y, Sector::current()->gravity); - if(dying == DYING_NOT) - collision_swept_object_map(&old_base, &base); - - if(physic.get_velocity_y() < 0) - { - set_action("down", "down"); - } -} - -void -BadGuy::action_bouncingsnowball(double elapsed_time) -{ - static const float JUMPV = 4.5; - - fall(); - - // jump when on ground - if(dying == DYING_NOT && issolid(base.x, base.y+32)) - { - physic.set_velocity_y(JUMPV); - physic.enable_gravity(true); - } - else - { - state = NORMAL; - } - - // check for right/left collisions - check_horizontal_bump(); - - physic.apply(elapsed_time, base.x, base.y, Sector::current()->gravity); - if(dying == DYING_NOT) - collision_swept_object_map(&old_base, &base); - - // Handle dying timer: - if (dying == DYING_SQUISHED && !timer.check()) - remove_me(); -} - -void -BadGuy::action_flyingsnowball(double elapsed_time) -{ - static const float FLYINGSPEED = 1; - static const int DIRCHANGETIME = 1000; - - // go into flyup state if none specified yet - if(dying == DYING_NOT && state == NORMAL) { - state = FLY_UP; - physic.set_velocity_y(FLYINGSPEED); - timer.start(DIRCHANGETIME/2); - } - - if(dying == DYING_NOT && !timer.check()) { - if(state == FLY_UP) { - state = FLY_DOWN; - physic.set_velocity_y(-FLYINGSPEED); - } else if(state == FLY_DOWN) { - state = FLY_UP; - physic.set_velocity_y(FLYINGSPEED); - } - timer.start(DIRCHANGETIME); - } - - if(dying != DYING_NOT) - physic.enable_gravity(true); - - physic.apply(elapsed_time, base.x, base.y, Sector::current()->gravity); - if(dying == DYING_NOT || dying == DYING_SQUISHED) - collision_swept_object_map(&old_base, &base); - - if(dying == DYING_NOT) - { - // set direction based on tux - if(Sector::current()->player->base.x > base.x) - dir = RIGHT; - else - dir = LEFT; - } - - // Handle dying timer: - if (dying == DYING_SQUISHED && !timer.check()) - remove_me(); -} - -void -BadGuy::action_spiky(double elapsed_time) -{ - if(frozen_timer.check()) - { - set_action("iced-left", "iced-right"); - return; - } - - if (dying == DYING_NOT) - check_horizontal_bump(); - - fall(); - - physic.apply(elapsed_time, base.x, base.y, Sector::current()->gravity); - if (dying != DYING_FALLING) - collision_swept_object_map(&old_base,&base); -} - -void -BadGuy::action_snowball(double elapsed_time) -{ - if (dying == DYING_NOT) - check_horizontal_bump(); - - fall(); - - // jump when we're about to fall - if (physic.get_velocity_y() == 0 && - !issolid(base.x+base.width/2, base.y + base.height)) { - physic.enable_gravity(true); - physic.set_velocity_y(2); - } - - physic.apply(elapsed_time, base.x, base.y, Sector::current()->gravity); - if (dying != DYING_FALLING) - collision_swept_object_map(&old_base,&base); - - // Handle dying timer: - if (dying == DYING_SQUISHED && !timer.check()) - remove_me(); -} - -void -BadGuy::action_wingling(double elapsed_time) -{ - if (dying != DYING_NOT) - physic.enable_gravity(true); - else - { - Player& tux = *Sector::current()->player; - int dirsign = physic.get_velocity_x() < 0 ? -1 : 1; - - if (fabsf(tux.base.x - base.x) < 150 && base.y < tux.base.y && tux.dying == DYING_NOT) - { - if (target.x < 0 && target.y < 0) - { - target.x = tux.base.x; - target.y = tux.base.y; - physic.set_velocity(dirsign * 1.5f, -2.25f); - } - } - else if (base.y >= target.y - 16) - physic.set_velocity(dirsign * WINGLING_FLY_SPEED, 0); - } - - physic.apply(elapsed_time, base.x, base.y, Sector::current()->gravity); - - - // Handle dying timer: - if (dying == DYING_SQUISHED && !timer.check()) - remove_me(); - - // TODO: Winglings should be removed after flying off the screen -} - -void -BadGuy::action_walkingtree(double elapsed_time) -{ - if (dying == DYING_NOT) - check_horizontal_bump(); - - fall(); - - physic.apply(elapsed_time, base.x, base.y, Sector::current()->gravity); - if (dying != DYING_FALLING) - collision_swept_object_map(&old_base,&base); - - // Handle dying timer: - if (dying == DYING_SQUISHED && !timer.check()) - remove_me(); -} - -void -BadGuy::action(float elapsed_time) -{ - float scroll_x = Sector::current()->camera->get_translation().x; - float scroll_y = Sector::current()->camera->get_translation().y; - - // BadGuy fall below the ground - if (base.y > Sector::current()->solids->get_height() * 32) { - remove_me(); - return; - } - - // Kill us if we landed on spikes - if (dying == DYING_NOT - && (kind != BAD_STALACTITE && kind != BAD_FLAME && kind != BAD_BOMB) - && (isspike(base.x, base.y) || isspike(base.x + base.width, base.y) - || isspike(base.x, base.y + base.height) - || isspike(base.x + base.width, base.y + base.height))) - { - physic.set_velocity_y(3); - kill_me(0); - } - - if(!seen) - { - /* Activate badguys if they're just around the screen to avoid - * the effect of having badguys suddenly popping up from nowhere. - */ - if (start_position.x > scroll_x - X_OFFSCREEN_DISTANCE && - start_position.x < scroll_x - base.width && - start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE && - start_position.y < scroll_y + screen->h + Y_OFFSCREEN_DISTANCE) - activate(RIGHT); - else if (start_position.x > scroll_x + screen->w && - start_position.x < scroll_x + screen->w + X_OFFSCREEN_DISTANCE && - start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE && - start_position.y < scroll_y + screen->h + Y_OFFSCREEN_DISTANCE) - activate(LEFT); - else if (start_position.x > scroll_x - X_OFFSCREEN_DISTANCE && - start_position.x < scroll_x + screen->w + X_OFFSCREEN_DISTANCE && - ((start_position.y > scroll_y + screen->h && - start_position.y < scroll_y + screen->h + Y_OFFSCREEN_DISTANCE) || - (start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE && - start_position.y < scroll_y))) - { - if(start_position.x < scroll_x - screen->w/2) - activate(RIGHT); - else - activate(LEFT); - } - /* Special case for badguys on start of the level. - * If in the future, it's possible to set Tux start pos, this case - * should contemplate that. */ - else if (start_position.x > 0 && start_position.x < screen->w && - start_position.y > 0 && start_position.y < screen->h) - activate(LEFT); - } - else - { - if(base.x + base.width < scroll_x - X_OFFSCREEN_DISTANCE*4 - || base.x > scroll_x + screen->w + X_OFFSCREEN_DISTANCE*4 - || base.y + base.height < scroll_y - Y_OFFSCREEN_DISTANCE*4 - || base.y > scroll_y + screen->h + Y_OFFSCREEN_DISTANCE*4) - { - seen = false; - if(dying != DYING_NOT) - remove_me(); - } - } - - if(!seen) - return; - - switch (kind) - { - case BAD_MRICEBLOCK: - action_mriceblock(elapsed_time); - break; - - case BAD_JUMPY: - action_jumpy(elapsed_time); - break; - - case BAD_MRBOMB: - action_mrbomb(elapsed_time); - break; - - case BAD_BOMB: - action_bomb(elapsed_time); - break; - - case BAD_STALACTITE: - action_stalactite(elapsed_time); - break; - - case BAD_FLAME: - action_flame(elapsed_time); - break; - - case BAD_FISH: - case BAD_FLAMEFISH: - action_fish(elapsed_time); - break; - - case BAD_BOUNCINGSNOWBALL: - action_bouncingsnowball(elapsed_time); - break; - - case BAD_FLYINGSNOWBALL: - action_flyingsnowball(elapsed_time); - break; - - case BAD_SPIKY: - action_spiky(elapsed_time); - break; - - case BAD_SNOWBALL: - action_snowball(elapsed_time); - break; - - case BAD_WINGLING: - action_wingling(elapsed_time); - break; - - case BAD_WALKINGTREE: - action_walkingtree(elapsed_time); - break; - - default: - break; - } -} - -void -BadGuy::draw(DrawingContext& context) -{ - if(!seen) - return; - - if((dir == LEFT && action_left == "hide") || - (dir == RIGHT && action_right == "hide")) - return; - - if(dir == LEFT) - specs->sprite->set_action(action_left); - else // if(dir == RIGHT) - specs->sprite->set_action(action_right); - - if(dying == DYING_FALLING && physic.get_velocity_y() < 0) - specs->sprite->draw(context, Vector(base.x, base.y), LAYER_FOREGROUNDTILES+1, VERTICAL_FLIP); - else - specs->sprite->draw(context, Vector(base.x, base.y), LAYER_OBJECTS); - - if(debug_state) - context.draw_filled_rect(Vector(base.x, base.y), - Vector(base.width, base.height), Color(75,0,75, 150), LAYER_OBJECTS+1); -} - -void -BadGuy::set_action(std::string left, std::string right) -{ - base.width = 32; - base.height = 32; - - action_left = left; - action_right = right; - -#if 0 - if (1) - { - base.width = 32; - base.height = 32; - } - else - { - // FIXME: Using the image size for the physics and collision is - // a bad idea, since images should always overlap their physical - // representation - if(left != 0) { - if(base.width == 0 && base.height == 0) { - base.width = left->get_width(); - base.height = left->get_height(); - } else if(base.width != left->get_width() || base.height != left->get_height()) { - base.x -= (left->get_width() - base.width) / 2; - base.y -= left->get_height() - base.height; - base.width = left->get_width(); - base.height = left->get_height(); - old_base = base; - } - } else { - base.width = base.height = 0; - } - } - - animation_offset = 0; - sprite_left = left; - sprite_right = right; -#endif -} - -void -BadGuy::bump() -{ - // these can't be bumped - if(kind == BAD_FLAME || kind == BAD_BOMB || kind == BAD_FISH - || kind == BAD_FLAMEFISH || kind == BAD_FLYINGSNOWBALL) - return; - - physic.set_velocity_y(3); - kill_me(25); -} - -void -BadGuy::squish_me(Player* player) -{ - player->bounce(this); - - Sector::current()->add_score(Vector(base.x, base.y), - 25 * player_status.score_multiplier); - - SoundManager::get()->play_sound(IDToSound(SND_SQUISH), get_pos(), Sector::current()->player->get_pos()); - player_status.score_multiplier++; - - dying = DYING_SQUISHED; - timer.start(2000); - physic.set_velocity(0, 0); -} - -void -BadGuy::squish(Player* player) -{ - static const int MAX_ICEBLOCK_SQUICHES = 10; - - if(kind == BAD_MRBOMB) { - // mrbomb transforms into a bomb now - explode(false); - - player->bounce(this); - Sector::current()->add_score(Vector(base.x, base.y), - 25 * player_status.score_multiplier); - SoundManager::get()->play_sound(IDToSound(SND_SQUISH), get_pos(), Sector::current()->player->get_pos()); - - player_status.score_multiplier++; - return; - - } else if (kind == BAD_MRICEBLOCK) { - if (state == NORMAL || state == KICK) - { - /* Flatten! */ - SoundManager::get()->play_sound(IDToSound(SND_STOMP), get_pos(), Sector::current()->player->get_pos()); - state = FLAT; - set_action("flat-left", "flat-right"); - physic.set_velocity_x(0); - - timer.start(4000); - } else if (state == FLAT) { - /* Kick! */ - SoundManager::get()->play_sound(IDToSound(SND_KICK), this, Sector::current()->player->get_pos()); - - if (player->base.x < base.x + (base.width/2)) { - physic.set_velocity_x(5); - dir = RIGHT; - } else { - physic.set_velocity_x(-5); - dir = LEFT; - } - - state = KICK; - player->kick_timer.start(KICKING_TIME); - set_action("flat-left", "flat-right"); - } - - player->bounce(this); - - player_status.score_multiplier++; - - // check for maximum number of squishes - squishcount++; - if(squishcount >= MAX_ICEBLOCK_SQUICHES) { - kill_me(50); - return; - } - - return; - } else if(kind == BAD_FISH || kind == BAD_FLAMEFISH) { - // fish can only be killed when falling down - if(physic.get_velocity_y() >= 0) - return; - - player->bounce(this); - - Sector::current()->add_score(Vector(base.x, base.y), - 25 * player_status.score_multiplier); - - player_status.score_multiplier++; - - // simply remove the fish... - remove_me(); - return; - } else if(kind == BAD_BOUNCINGSNOWBALL) { - squish_me(player); - set_action("squished", "squished"); - return; - } else if(kind == BAD_FLYINGSNOWBALL) { - squish_me(player); - set_action("squished-left", "squished-right"); - return; - } else if(kind == BAD_SNOWBALL) { - squish_me(player); - set_action("squished-left", "squished-right"); - return; - } else if(kind == BAD_WINGLING) { - squish_me(player); - set_action("left", "right"); - } else if(kind == BAD_WALKINGTREE) { - if (state == BGM_BIG) - { - set_action("left-small", "left-small"); - physic.set_velocity_x(physic.get_velocity_x() * 2.0f); - - /* Move to the player's direction */ - if(dir != Sector::current()->player->dir) - physic.set_velocity_x(-physic.get_velocity_x()); - dir = Sector::current()->player->dir; - - // XXX magic number: 66 is BGM_BIG height - - player->bounce(this); - base.y += 66 - base.height; - - Sector::current()->add_score(Vector(base.x, base.y), - 25 * player_status.score_multiplier); - player_status.score_multiplier++; - - state = BGM_SMALL; - } - else - squish_me(player); - } -} - -void -BadGuy::kill_me(int score) -{ - if(kind == BAD_BOMB) - return; - - if(state != HELD) - global_stats.add_points(BADGUYS_KILLED_STAT, 1); - - dying = DYING_FALLING; - if(kind == BAD_MRICEBLOCK) { - set_action("falling-left", "falling-right"); - if(state == HELD) { - state = NORMAL; - Player& tux = *Sector::current()->player; - tux.holding_something = false; - } - } - - physic.enable_gravity(true); - - /* Gain some points: */ - if (score != 0) - Sector::current()->add_score(Vector(base.x, base.y), - score * player_status.score_multiplier); - - /* Play death sound: */ - SoundManager::get()->play_sound(IDToSound(SND_FALL), this, Sector::current()->player->get_pos()); -} - -void -BadGuy::explode(bool right_way) -{ - BadGuy *badguy = Sector::current()->add_bad_guy(base.x, base.y, BAD_BOMB, true); - if(right_way) - { - badguy->timer.start(0); - badguy->state = BOMB_TICKING; - } - badguy->dir = dir; - - remove_me(); -} - -void -BadGuy::collision(const MovingObject&, int) -{ - // later -} - -void -BadGuy::collision(void *p_c_object, int c_object, CollisionType type) -{ - BadGuy* pbad_c = NULL; - Bullet* pbullet_c = NULL; - - if(type == COLLISION_BUMP) { - bump(); - return; - } - - if(type == COLLISION_SQUISH) { - Player* player = static_cast(p_c_object); - squish(player); - return; - } - - /* COLLISION_NORMAL */ - switch (c_object) - { - case CO_BULLET: - pbullet_c = (Bullet*) p_c_object; - - if(pbullet_c->kind == FIRE_BULLET) - { - if (kind != BAD_BOMB && kind != BAD_STALACTITE && kind != BAD_FLAME - && kind != BAD_FLAMEFISH) - kill_me(10); - } - else if(pbullet_c->kind == ICE_BULLET) - { - if(kind == BAD_FLAME || kind == BAD_FLAMEFISH) - kill_me(10); - else - frozen_timer.start(FROZEN_TIME); - } - break; - - case CO_BADGUY: - pbad_c = (BadGuy*) p_c_object; - - - /* If we're a kicked mriceblock, kill [almost] any badguys we hit */ - if(kind == BAD_MRICEBLOCK && state == KICK && - kind != BAD_FLAME && kind != BAD_BOMB && kind != BAD_STALACTITE) - { - pbad_c->kill_me(25); - } - - // a held mriceblock kills the enemy too but falls to ground then - else if(kind == BAD_MRICEBLOCK && state == HELD) - { - pbad_c->kill_me(25); - kill_me(0); - } - - /* Kill badguys that run into exploding bomb */ - else if (kind == BAD_BOMB && dying == DYING_NOT) - { - if (pbad_c->kind == BAD_MRBOMB) - { - // mrbomb transforms into a bomb now - pbad_c->explode(true); - return; - } - else - { - pbad_c->kill_me(50); - } - } - - /* Kill any badguys that get hit by stalactite */ - else if (kind == BAD_STALACTITE && dying == DYING_NOT) - { - if (pbad_c->kind == BAD_MRBOMB) - { - // mrbomb transforms into a bomb now - pbad_c->explode(false); - return; - } - else - pbad_c->kill_me(50); - } - - /* When enemies run into eachother, make them change directions */ - else - { - // Wingling doesn't interact with other badguys - if (pbad_c->kind == BAD_WINGLING || kind == BAD_WINGLING) - break; - - // Jumpy, fish, flame, stalactites, wingling are exceptions - if (pbad_c->kind == BAD_JUMPY || pbad_c->kind == BAD_FLAME - || pbad_c->kind == BAD_STALACTITE || pbad_c->kind == BAD_FISH - || pbad_c->kind == BAD_FLAMEFISH) - break; - - // Bounce off of other badguy if we land on top of him - if (base.y + base.height < pbad_c->base.y + pbad_c->base.height) - { - if (pbad_c->dir == LEFT) - { - dir = RIGHT; - physic.set_velocity(fabsf(physic.get_velocity_x()), 2); - } - else if (pbad_c->dir == RIGHT) - { - dir = LEFT; - physic.set_velocity(-fabsf(physic.get_velocity_x()), 2); - } - - break; - } - else if (base.y + base.height > pbad_c->base.y + pbad_c->base.height) - break; - - if (pbad_c->kind != BAD_FLAME) - { - if (dir == LEFT) - { - dir = RIGHT; - physic.set_velocity_x(fabsf(physic.get_velocity_x())); - - // Put bad guys a part (or they get jammed) - // only needed to do to one of them - if (physic.get_velocity_x() != 0) - base.x = pbad_c->base.x + pbad_c->base.width + 1; - } - else if (dir == RIGHT) - { - dir = LEFT; - physic.set_velocity_x(-fabsf(physic.get_velocity_x())); - } - - } - } - - break; - - case CO_PLAYER: - Player* player = static_cast(p_c_object); - /* Get kicked if were flat */ - if (state == FLAT && !dying) - { - SoundManager::get()->play_sound(IDToSound(SND_KICK), this, Sector::current()->player->get_pos()); - - // Hit from left side - if (player->base.x < base.x) { - physic.set_velocity_x(5); - dir = RIGHT; - } - // Hit from right side - else { - physic.set_velocity_x(-5); - dir = LEFT; - } - - state = KICK; - player->kick_timer.start(KICKING_TIME); - set_action("flat-left", "flat-right"); - } - break; - - } -} - -#endif diff --git a/src/badguy.h b/src/badguy.h deleted file mode 100644 index 5b9444570..000000000 --- a/src/badguy.h +++ /dev/null @@ -1,191 +0,0 @@ -// $Id$ -// -// SuperTux -// Copyright (C) 2000 Bill Kendrick -// Copyright (C) 2004 Tobias Glaesser -// Copyright (C) 2004 Matthias Braun -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -// 02111-1307, USA. - -#ifndef SUPERTUX_BADGUY_H -#define SUPERTUX_BADGUY_H - -#include "SDL.h" - -#include "utils/lispreader.h" -#include "timer.h" -#include "math/physic.h" -#include "defines.h" -#include "special/moving_object.h" -#include "collision.h" -#include "serializable.h" -#include "scene.h" - -using namespace SuperTux; - -/* Timing constants */ -#define KICKING_TIME .2 - -/* Bad guy kinds: */ -enum BadGuyKind { - BAD_MRICEBLOCK, - BAD_JUMPY, - BAD_MRBOMB, - BAD_BOMB, - BAD_STALACTITE, - BAD_FLAME, - BAD_FISH, - BAD_FLAMEFISH, - BAD_BOUNCINGSNOWBALL, - BAD_FLYINGSNOWBALL, - BAD_SPIKY, - BAD_SNOWBALL, - BAD_WINGLING, - BAD_WALKINGTREE, - NUM_BadGuyKinds, - - BAD_INVALID -}; - -BadGuyKind badguykind_from_string(const std::string& str); -std::string badguykind_to_string(BadGuyKind kind); - -#if 0 - -class Player; -class BadGuySpecs; - -/* Badguy type: */ -class BadGuy : public MovingObject, public Serializable -{ -public: - /* Enemy modes: */ - enum BadGuyState { - NORMAL=0, - FLAT, - KICK, - HELD, - - JUMPY_JUMP, - - BOMB_TICKING, - BOMB_EXPLODE, - - STALACTITE_SHAKING, - STALACTITE_FALL, - - FISH_WAIT, - - FLY_UP, - FLY_DOWN, - - BGM_BIG, - BGM_SMALL - }; -public: - DyingType dying; - BadGuyKind kind; - BadGuyState state; - - /** If true the enemy will stay on its current platform, ie. if he - reaches the edge he will turn around and walk into the other - direction, if false the enemy will jump or walk of the edge */ - bool stay_on_platform; - - Direction dir; - Vector start_position; - - Timer frozen_timer; // gets frozen when a ice shot hits it - -private: - bool seen; - int squishcount; /// number of times this enemy was squiched - Vector target; // Target that badguy is aiming for (wingling uses this) - Timer timer; - Physic physic; - float angle; - - std::string action_left, action_right; - - BadGuySpecs* specs; - - int animation_offset; - -public: - BadGuy(BadGuyKind kind, float x, float y); - BadGuy(BadGuyKind kind, LispReader& reader); - virtual ~BadGuy(); - - virtual void write(LispWriter& writer); - - virtual void action(float frame_ratio); - virtual void draw(DrawingContext& context); - virtual void collision(const MovingObject& other, int type); - - void collision(void* p_c_object, int c_object, - CollisionType type = COLLISION_NORMAL); - - /** this functions tries to kill the badguy and lets him fall off the - * screen. Some badguys like the flame might ignore this. - */ - void kill_me(int score); - - /** initializes the badguy (when he appears on screen) */ - void activate(Direction direction); // should only be used by BadGuy's objects - - Surface* get_image(); - -private: - void init(); - - void action_mriceblock(double frame_ratio); - void action_jumpy(double frame_ratio); - void action_bomb(double frame_ratio); - void action_mrbomb(double frame_ratio); - void action_stalactite(double frame_ratio); - void action_flame(double frame_ratio); - void action_fish(double frame_ratio); - void action_bouncingsnowball(double frame_ratio); - void action_flyingsnowball(double frame_ratio); - void action_spiky(double frame_ratio); - void action_snowball(double frame_ratio); - void action_wingling(double frame_ratio); - void action_walkingtree(double frame_ratio); - - /** handles falling down. disables gravity calculation when we're back on - * ground */ - void fall(); - - /** Turn enemy into a bomb. To explode right way pass true */ - void explode(bool right_away); - - /** check if we're running left or right in a wall and eventually change - * direction - */ - void check_horizontal_bump(bool checkcliff = false); - /** called when we're bumped from below with a block */ - void bump(); - /** called when a player jumped on the badguy from above */ - void squish(Player* player); - /** squish ourself, give player score and set dying to DYING_SQICHED */ - void squish_me(Player* player); - /** set sprite's action of the badguy */ - void set_action(std::string action_left, std::string action_right); -}; - -#endif - -#endif /*SUPERTUX_BADGUY_H*/ diff --git a/src/bitmask.cpp b/src/bitmask.cpp deleted file mode 100644 index 76983a0af..000000000 --- a/src/bitmask.cpp +++ /dev/null @@ -1,582 +0,0 @@ -/* - * bitmask.c 1.0 - * ------------- - * Simple and efficient bitmask collision detection routines - * Copyright (C) 2002 Ulf Ekstrom except for the bitcount function. - * - * > See the header file for more info. < - * - * Please email bugs and comments to Ulf Ekstrom, ulfek@ifm.liu.se - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include - -#include -#include -#include -#include "bitmask.h" - -#define MIN(a,b) ((a) < (b) ? (a) : (b)) - -bitmask *bitmask_create(int w, int h) -{ - bitmask *temp = (bitmask*) malloc(sizeof(bitmask)); - if (! temp) - return 0; - temp->w = w; - temp->h = h; - temp->bits = (long unsigned int*) calloc(h*((w - 1)/BITW_LEN + 1),sizeof(BITW)); - if (! temp->bits) - { - free(temp); - return 0; - } - else - return temp; -} - -/* (C) Tobias Glaesser , 2004. - This function isn't available in the original bitmask library. */ -bitmask *bitmask_create_SDL(SDL_Surface* surf) -{ - bitmask* pbitmask = bitmask_create(surf->w, surf->h); - int w,h; - SDL_PixelFormat* fmt; - Uint32 temp, pixel; - Uint8 alpha; - - if(surf->format->BytesPerPixel != 4) //This function only works for true-color surfaces with an alpha channel - return 0; - - fmt = surf->format; - for(h = 0; h <= surf->h; ++h) - { - for(w = 0; w <= surf->w; ++w) - { - - pixel = *((Uint32*)((Uint8 *)surf->pixels + h * surf->pitch + w * 4)); - /* Get Alpha component */ - temp=pixel&fmt->Amask; /* Isolate alpha component */ - temp=temp>>fmt->Ashift;/* Shift it down to 8-bit */ - temp=temp<Aloss; /* Expand to a full 8-bit number */ - alpha=(Uint8)temp; - if (fmt->Amask == 0 || alpha != 0) - bitmask_setbit(pbitmask,w,h); - } - } - return pbitmask; -} -void bitmask_free(bitmask *m) -{ - free(m->bits); - free(m); -} - -void bitmask_clear(bitmask *m) -{ - memset(m->bits,0,m->h*((m->w - 1)/BITW_LEN + 1)*sizeof(BITW)); -} - -void bitmask_fill(bitmask *m) -{ - memset(m->bits,255,m->h*((m->w - 1)/BITW_LEN + 1)*sizeof(BITW)); -} - -int bitmask_overlap(const bitmask *a,const bitmask *b,int xoffset, int yoffset) -{ - BITW *a_entry,*a_end; - BITW *b_entry; - BITW *ap,*bp; - int shift,rshift,i,astripes,bstripes; - - if ((xoffset >= a->w) || (yoffset >= a->h) || (yoffset <= - b->h)) - return 0; - - if (xoffset >= 0) - { - if (yoffset >= 0) - { - a_entry = a->bits + a->h*(xoffset/BITW_LEN) + yoffset; - a_end = a_entry + MIN(b->h,a->h - yoffset); - b_entry = b->bits; - } - else - { - a_entry = a->bits + a->h*(xoffset/BITW_LEN); - a_end = a_entry + MIN(b->h + yoffset,a->h); - b_entry = b->bits - yoffset; - } - shift = xoffset & BITW_MASK; - if (shift) - { - rshift = BITW_LEN - shift; - astripes = (a->w - 1)/BITW_LEN - xoffset/BITW_LEN; - bstripes = (b->w - 1)/BITW_LEN + 1; - if (bstripes > astripes) /* zig-zag .. zig*/ - { - for (i=0;i> shift) & *bp++) - return 1; - a_entry += a->h; - a_end += a->h; - for (ap = a_entry,bp = b_entry;ap < a_end;) - if ((*ap++ << rshift) & *bp++) - return 1; - b_entry += b->h; - } - for (ap = a_entry,bp = b_entry;ap < a_end;) - if ((*ap++ >> shift) & *bp++) - return 1; - return 0; - } - else /* zig-zag */ - { - for (i=0;i> shift) & *bp++) - return 1; - a_entry += a->h; - a_end += a->h; - for (ap = a_entry,bp = b_entry;ap < a_end;) - if ((*ap++ << rshift) & *bp++) - return 1; - b_entry += b->h; - } - return 0; - } - } - else /* xoffset is a multiple of the stripe width, and the above routines wont work */ - { - astripes = (MIN(b->w,a->w - xoffset) - 1)/BITW_LEN + 1; - for (i=0;ih; - a_end += a->h; - b_entry += b->h; - } - return 0; - } - } - else - return bitmask_overlap(b,a,-xoffset,-yoffset); -} - -/* Will hang if there are no bits set in w! */ -static INLINE int firstsetbit(BITW w) -{ - int i = 0; - while ((w & 1) == 0) - { - i++; - w/=2; - } - return i; -} - -/* x and y are given in the coordinates of mask a, and are untouched if the is no overlap */ -int bitmask_overlap_pos(const bitmask *a,const bitmask *b,int xoffset, int yoffset, int *x, int *y) -{ - BITW *a_entry,*a_end; - BITW *b_entry; - BITW *ap,*bp; - int shift,rshift,i,astripes,bstripes,xbase; - - if ((xoffset >= a->w) || (yoffset >= a->h) || (yoffset <= - b->h)) - return 0; - - if (xoffset >= 0) - { - xbase = xoffset/BITW_LEN; /* first stripe from mask a */ - if (yoffset >= 0) - { - a_entry = a->bits + a->h*xbase + yoffset; - a_end = a_entry + MIN(b->h,a->h - yoffset); - b_entry = b->bits; - } - else - { - a_entry = a->bits + a->h*xbase; - a_end = a_entry + MIN(b->h + yoffset,a->h); - b_entry = b->bits - yoffset; - yoffset = 0; /* relied on below */ - } - shift = xoffset & BITW_MASK; - if (shift) - { - rshift = BITW_LEN - shift; - astripes = (a->w - 1)/BITW_LEN - xoffset/BITW_LEN; - bstripes = (b->w - 1)/BITW_LEN + 1; - if (bstripes > astripes) /* zig-zag .. zig*/ - { - for (i=0;ih; - a_end += a->h; - for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++) - if (*ap & (*bp >> rshift)) - { - *y = ap - a_entry + yoffset; - *x = (xbase + i + 1)*BITW_LEN + firstsetbit(*ap & (*bp >> rshift)); - return 1; - } - b_entry += b->h; - } - for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++) - if (*ap & (*bp << shift)) - { - *y = ap - a_entry + yoffset; - *x = (xbase + astripes)*BITW_LEN + firstsetbit(*ap & (*bp << shift)); - return 1; - } - return 0; - } - else /* zig-zag */ - { - for (i=0;ih; - a_end += a->h; - for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++) - if (*ap & (*bp >> rshift)) - { - *y = ap - a_entry + yoffset; - *x = (xbase + i + 1)*BITW_LEN + firstsetbit(*ap & (*bp >> rshift)); - return 1; - } - b_entry += b->h; - } - return 0; - } - } - else /* xoffset is a multiple of the stripe width, and the above routines - won't work. This way is also slightly faster. */ - { - astripes = (MIN(b->w,a->w - xoffset) - 1)/BITW_LEN + 1; - for (i=0;ih; - a_end += a->h; - b_entry += b->h; - } - return 0; - } - } - else - { - if (bitmask_overlap_pos(b,a,-xoffset,-yoffset,x,y)) - { - *x += xoffset; - *y += yoffset; - return 1; - } - else - return 0; - } -} - -static INLINE int bitcount(unsigned long n) -{ - if (BITW_LEN == 32) - { - /* (C) Donald W. Gillies, 1992. All rights reserved. You may reuse - this bitcount() function anywhere you please as long as you retain - this Copyright Notice. */ - register unsigned long tmp; - return (tmp = (n) - (((n) >> 1) & 033333333333) - - (((n) >> 2) & 011111111111), - tmp = ((tmp + (tmp >> 3)) & 030707070707), - tmp = (tmp + (tmp >> 6)), - tmp = (tmp + (tmp >> 12) + (tmp >> 24)) & 077); - /* End of Donald W. Gillies bitcount code */ - } - else - { - /* Handle non-32 bit case the slow way */ - int nbits = 0; - while (n) - { - if (n & 1) - nbits++; - n = n >> 1; - } - return nbits; - } -} - - -int bitmask_overlap_area(const bitmask *a,const bitmask *b,int xoffset, int yoffset) -{ - BITW *a_entry,*a_end; - BITW *b_entry; - BITW *ap,*bp; - int shift,rshift,i,astripes,bstripes; - int count = 0; - - if ((xoffset >= a->w) || (yoffset >= a->h) || (yoffset <= - b->h)) - return 0; - - if (xoffset >= 0) - { - if (yoffset >= 0) - { - a_entry = a->bits + a->h*(xoffset/BITW_LEN) + yoffset; - a_end = a_entry + MIN(b->h,a->h - yoffset); - b_entry = b->bits; - } - else - { - a_entry = a->bits + a->h*(xoffset/BITW_LEN); - a_end = a_entry + MIN(b->h + yoffset,a->h); - b_entry = b->bits - yoffset; - } - shift = xoffset & BITW_MASK; - if (shift) - { - rshift = BITW_LEN - shift; - astripes = (a->w - 1)/BITW_LEN - xoffset/BITW_LEN; - bstripes = (b->w - 1)/BITW_LEN + 1; - if (bstripes > astripes) /* zig-zag .. zig*/ - { - for (i=0;i> shift) | (*(ap + a->h) << rshift)) & *bp); - a_entry += a->h; - a_end += a->h; - b_entry += b->h; - } - for (ap = a_entry,bp = b_entry;ap < a_end;) - count += bitcount((*ap++ >> shift) & *bp++); - return count; - } - else /* zig-zag */ - { - for (i=0;i> shift) | (*(ap + a->h) << rshift)) & *bp); - a_entry += a->h; - a_end += a->h; - b_entry += b->h; - } - return count; - } - } - else /* xoffset is a multiple of the stripe width, and the above routines wont work */ - { - astripes = (MIN(b->w,a->w - xoffset) - 1)/BITW_LEN + 1; - for (i=0;ih; - a_end += a->h; - b_entry += b->h; - } - return count; - } - } - else - return bitmask_overlap_area(b,a,-xoffset,-yoffset); -} - - -/* Draws mask b onto mask a (bitwise OR) */ -void bitmask_draw(bitmask *a,bitmask *b,int xoffset, int yoffset) -{ - BITW *a_entry,*a_end; - BITW *b_entry; - BITW *ap,*bp; - bitmask *swap; - int shift,rshift,i,astripes,bstripes; - - if ((xoffset >= a->w) || (yoffset >= a->h) || (yoffset <= - b->h)) - return; - - if (xoffset >= 0) - { - if (yoffset >= 0) - { - a_entry = a->bits + a->h*(xoffset/BITW_LEN) + yoffset; - a_end = a_entry + MIN(b->h,a->h - yoffset); - b_entry = b->bits; - } - else - { - a_entry = a->bits + a->h*(xoffset/BITW_LEN); - a_end = a_entry + MIN(b->h + yoffset,a->h); - b_entry = b->bits - yoffset; - } - shift = xoffset & BITW_MASK; - if (shift) - { - rshift = BITW_LEN - shift; - astripes = (a->w - 1)/BITW_LEN - xoffset/BITW_LEN; - bstripes = (b->w - 1)/BITW_LEN + 1; - if (bstripes > astripes) /* zig-zag .. zig*/ - { - for (i=0;ih; - a_end += a->h; - for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++) - *ap |= (*bp >> rshift); - b_entry += b->h; - } - for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++) - *ap |= (*bp << shift); - return; - } - else /* zig-zag */ - { - for (i=0;ih; - a_end += a->h; - for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++) - *ap |= (*bp >> rshift); - b_entry += b->h; - } - return; - } - } - else /* xoffset is a multiple of the stripe width, and the above routines won't work. */ - { - astripes = (MIN(b->w,a->w - xoffset) - 1)/BITW_LEN + 1; - for (i=0;ih; - a_end += a->h; - b_entry += b->h; - } - return; - } - } - else - { - /* 'Swapping' arguments to be able to almost reuse the code above, - should be taken care of by the compiler efficiently. */ - swap = a; - a = b; - b = swap; - xoffset *= -1; - yoffset *= -1; - - if (yoffset >= 0) - { - a_entry = a->bits + a->h*(xoffset/BITW_LEN) + yoffset; - a_end = a_entry + MIN(b->h,a->h - yoffset); - b_entry = b->bits; - } - else - { - a_entry = a->bits + a->h*(xoffset/BITW_LEN); - a_end = a_entry + MIN(b->h + yoffset,a->h); - b_entry = b->bits - yoffset; - } - shift = xoffset & BITW_MASK; - if (shift) - { - rshift = BITW_LEN - shift; - astripes = (a->w - 1)/BITW_LEN - xoffset/BITW_LEN; - bstripes = (b->w - 1)/BITW_LEN + 1; - if (bstripes > astripes) /* zig-zag .. zig*/ - { - for (i=0;i> shift); - a_entry += a->h; - a_end += a->h; - for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++) - *bp |= (*ap <h; - } - for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++) - *bp |= (*ap >> shift); - return; - } - else /* zig-zag */ - { - for (i=0;i> shift); - a_entry += a->h; - a_end += a->h; - for (ap = a_entry,bp = b_entry;ap < a_end;ap++,bp++) - *bp |= (*ap << rshift); - b_entry += b->h; - } - return; - } - } - else /* xoffset is a multiple of the stripe width, and the above routines won't work. */ - { - astripes = (MIN(b->w,a->w - xoffset) - 1)/BITW_LEN + 1; - for (i=0;ih; - a_end += a->h; - b_entry += b->h; - } - return; - } - } -} diff --git a/src/bitmask.h b/src/bitmask.h deleted file mode 100644 index e699a7ff5..000000000 --- a/src/bitmask.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * bitmask.c 1.0 - * ------------- - * Simple and efficient bitmask collision detection routines - * Copyright (C) 2002 Ulf Ekstrom except for the bitcount function. - * - * A bitmask is a simple array of bits, which can be used for - * 2d collision detection. Set 'unoccupied' area to zero and - * occupies areas to one and use the bitmask_overlap*() functions - * to check for collisions. - * The current implementation uses 32 bit wide stripes to hold - * the masks, but should work just as well with 64 bit sizes. - * - * The overlap tests uses the following offsets (which may be negative): - * - * +----+----------.. - * |A | yoffset - * | +-+----------.. - * +--|B - * |xoffset - * | | - * : : - * - * For optimal collision detection performance combine these functions - * with some kind of pre-sorting to avoid comparing objects far from - * each other. - * - * Performance of the various functions goes something like: - * (relative timings, smaller is better) - * - * bitmask_overlap() 1.0 - * bitmask_overlap_pos() 1.3 - * bitmask_overlap_area() 1.6 - * - * For maximum performance on my machine I use gcc with - * -O2 -fomit-frame-pointer -funroll-loops - * - * - * If you can make these functions faster or have found any bugs please - * email Ulf Ekstrom, ulfek@ifm.liu.se - * - * - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -#ifndef SUPERTUX_BITMASK_H -#define SUPERTUX_BITMASK_H - -#include -#include - -/* Define INLINE for different compilers. */ -#ifndef INLINE -# ifdef __GNUC__ -# define INLINE inline -# else -# ifdef _MSC_VER -# define INLINE __inline -# else -# define INLINE -# endif -# endif -#endif - -#define BITW unsigned long int -#define BITW_LEN (sizeof(BITW)*CHAR_BIT) -#define BITW_MASK (BITW_LEN - 1) -#define BITN(n) ((BITW)1 << (n)) - -struct bitmask -{ - int w,h; - BITW *bits; -}; - -/* Creates a bitmask of width w and height h. - * The mask is automatically cleared when created. - */ -bitmask *bitmask_create(int w, int h); -void bitmask_free(bitmask *m); - -void bitmask_clear(bitmask *m); -void bitmask_fill(bitmask *m); - -/* Returns nonzero if the bit at (x,y) is set. - * Coordinates start at (0,0) - */ -static INLINE int bitmask_getbit(const bitmask *m,int x,int y) -{ - return m->bits[x/BITW_LEN*m->h + y] & BITN(x & BITW_MASK); -} - - -/* Sets the bit at (x,y) */ -static INLINE void bitmask_setbit(bitmask *m,int x,int y) -{ - m->bits[x/BITW_LEN*m->h + y] |= BITN(x & BITW_MASK); -} - - -/* Clears the bit at (x,y) */ -static INLINE void bitmask_clearbit(bitmask *m,int x,int y) -{ - m->bits[x/BITW_LEN*m->h + y] &= ~BITN(x & BITW_MASK); -} - - -/* Returns nonzero if the masks overlap with the given offset. */ -int bitmask_overlap(const bitmask *a,const bitmask *b,int xoffset, int yoffset); - -/* Like bitmask_overlap(), but will also give a point of intersection. - * x and y are given in the coordinates of mask a, and are untouched if there is - * no overlap. - */ -int bitmask_overlap_pos(const bitmask *a,const bitmask *b,int xoffset, int yoffset, int *x, int *y); - -/* Returns the number of overlapping 'pixels' */ -int bitmask_overlap_area(const bitmask *a,const bitmask *b,int xoffset, int yoffset); - -/* Draws mask b onto mask a (bitwise OR) - * Can be used to compose large (game background?) mask from - * several submasks, which may speed up the testing. - */ -void bitmask_draw(bitmask *a,bitmask *b,int xoffset, int yoffset); - -/* Create a bitmask from a SDL_Surface */ -bitmask* bitmask_create_SDL(SDL_Surface* surf); - -#endif /*SUPERTUX_BITMASK_H*/ diff --git a/src/collision.cpp b/src/collision.cpp index 7b93e8246..237590f02 100644 --- a/src/collision.cpp +++ b/src/collision.cpp @@ -23,7 +23,6 @@ #include #include "defines.h" #include "collision.h" -#include "bitmask.h" #include "scene.h" #include "sector.h" #include "tilemap.h" diff --git a/src/gameloop.cpp b/src/gameloop.cpp index 850000196..c4b048565 100644 --- a/src/gameloop.cpp +++ b/src/gameloop.cpp @@ -46,7 +46,6 @@ #include "app/setup.h" #include "high_scores.h" #include "gui/menu.h" -#include "badguy.h" #include "sector.h" #include "player.h" #include "level.h" diff --git a/src/leveleditor.cpp b/src/leveleditor.cpp index f17fbe1b5..81f0bfb59 100644 --- a/src/leveleditor.cpp +++ b/src/leveleditor.cpp @@ -36,7 +36,6 @@ #include "sector.h" #include "background.h" #include "gameloop.h" -#include "badguy.h" #include "gameobjs.h" #include "camera.h" diff --git a/src/player.h b/src/player.h index cf9fe19c0..45a82bdca 100644 --- a/src/player.h +++ b/src/player.h @@ -21,7 +21,6 @@ #include "SDL.h" -#include "bitmask.h" #include "timer.h" #include "video/surface.h" #include "collision.h" diff --git a/src/resources.cpp b/src/resources.cpp index d6e73647f..6dbe55d19 100644 --- a/src/resources.cpp +++ b/src/resources.cpp @@ -26,10 +26,8 @@ #include "gui/button.h" #include "scene.h" #include "player.h" -#include "badguy.h" #include "gameobjs.h" #include "resources.h" -#include "badguy_specs.h" Surface* img_waves[3]; Surface* img_water; @@ -157,9 +155,6 @@ void loadshared() ice_tux->arms = sprite_manager->create("big-tux-arms"); ice_tux->feet = sprite_manager->create("big-tux-feet"); - /* Load Bad Guys resources */ - badguyspecs_manager = new BadGuySpecsManager(datadir + "/badguys.strf"); - /* Water: */ img_water = new Surface(datadir + "/images/shared/water.png", false); diff --git a/src/sector.cpp b/src/sector.cpp index 37a9e39ec..e09742071 100644 --- a/src/sector.cpp +++ b/src/sector.cpp @@ -29,7 +29,6 @@ #include "app/globals.h" #include "sector.h" #include "utils/lispreader.h" -#include "badguy.h" #include "gameobjs.h" #include "camera.h" #include "background.h" diff --git a/src/sector.h b/src/sector.h index 05595abd0..89270358b 100644 --- a/src/sector.h +++ b/src/sector.h @@ -24,16 +24,18 @@ #include #include "math/vector.h" -#include "badguy.h" #include "audio/musicref.h" #include "video/drawing_context.h" +#include "defines.h" using namespace SuperTux; namespace SuperTux { class GameObject; class LispReader; +class LispWriter; class Sprite; +class Rectangle; } class InteractiveObject; diff --git a/src/worldmap.cpp b/src/worldmap.cpp index 94500acae..0c4b900ff 100644 --- a/src/worldmap.cpp +++ b/src/worldmap.cpp @@ -40,6 +40,7 @@ #include "resources.h" #include "app/gettext.h" #include "misc.h" +#include "scene.h" #define map_message_TIME 2.8