Commit 588abf12 authored by alistert's avatar alistert

Added basic support for JJ2 levels.

parent 3abea93d
...@@ -9,6 +9,8 @@ objects = src/bonus/bonus.o \ ...@@ -9,6 +9,8 @@ objects = src/bonus/bonus.o \
src/io/gfx/scale2x/scale2x.o src/io/gfx/scale2x/scale3x.o \ src/io/gfx/scale2x/scale2x.o src/io/gfx/scale2x/scale3x.o \
src/io/gfx/scale2x/scalebit.o src/io/gfx/scale2x/simple2x.o \ src/io/gfx/scale2x/scalebit.o src/io/gfx/scale2x/simple2x.o \
src/io/controls.o src/io/file.o src/io/network.o src/io/sound.o \ src/io/controls.o src/io/file.o src/io/network.o src/io/sound.o \
src/jj2level/jj2layer.o src/jj2level/jj2level.o \
src/jj2level/jj2levelframe.o src/jj2level/jj2levelload.o \
src/level/event/bridge.o src/level/event/guardians.o \ src/level/event/bridge.o src/level/event/guardians.o \
src/level/event/event.o src/level/event/eventframe.o \ src/level/event/event.o src/level/event/eventframe.o \
src/level/bullet.o src/level/demolevel.o src/level/level.o \ src/level/bullet.o src/level/demolevel.o src/level/level.o \
...@@ -16,14 +18,15 @@ objects = src/bonus/bonus.o \ ...@@ -16,14 +18,15 @@ objects = src/bonus/bonus.o \
src/menu/gamemenu.o src/menu/mainmenu.o src/menu/menu.o \ src/menu/gamemenu.o src/menu/mainmenu.o src/menu/menu.o \
src/menu/setupmenu.o \ src/menu/setupmenu.o \
src/planet/planet.o \ src/planet/planet.o \
src/player/bird.o src/player/bonusplayer.o src/player/levelplayer.o \ src/player/bird.o src/player/bonusplayer.o src/player/jj2levelplayer.o \
src/player/jj2levelplayerframe.o src/player/levelplayer.o \
src/player/levelplayerframe.o src/player/player.o \ src/player/levelplayerframe.o src/player/player.o \
src/scene/scene.o src/scene/sceneload.o \ src/scene/scene.o src/scene/sceneload.o \
src/baselevel.o src/main.o src/util.o src/baselevel.o src/main.o src/util.o
OpenJazz: $(objects) OpenJazz: $(objects)
cc -Wall -o OpenJazz -lSDL -lstdc++ $(objects) cc -Wall -o OpenJazz -lSDL -lstdc++ -lz $(objects)
%.o: %.cpp %.o: %.cpp
cc -Wall -DUSE_SOCKETS -DSCALE -Isrc -O2 -c $< -o $@ cc -Wall -DUSE_SOCKETS -DSCALE -Isrc -O2 -c $< -o $@
......
...@@ -33,6 +33,8 @@ OBJS = src/bonus/bonus.o \ ...@@ -33,6 +33,8 @@ OBJS = src/bonus/bonus.o \
src/io/gfx/scale2x/scale2x.o src/io/gfx/scale2x/scale3x.o \ src/io/gfx/scale2x/scale2x.o src/io/gfx/scale2x/scale3x.o \
src/io/gfx/scale2x/scalebit.o src/io/gfx/scale2x/simple2x.o \ src/io/gfx/scale2x/scalebit.o src/io/gfx/scale2x/simple2x.o \
src/io/controls.o src/io/file.o src/io/network.o src/io/sound.o \ src/io/controls.o src/io/file.o src/io/network.o src/io/sound.o \
src/jj2level/jj2layer.o src/jj2level/jj2level.o \
src/jj2level/jj2levelframe.o src/jj2level/jj2levelload.o \
src/level/event/bridge.o src/level/event/guardians.o \ src/level/event/bridge.o src/level/event/guardians.o \
src/level/event/event.o src/level/event/eventframe.o \ src/level/event/event.o src/level/event/eventframe.o \
src/level/bullet.o src/level/demolevel.o src/level/level.o \ src/level/bullet.o src/level/demolevel.o src/level/level.o \
...@@ -40,7 +42,8 @@ OBJS = src/bonus/bonus.o \ ...@@ -40,7 +42,8 @@ OBJS = src/bonus/bonus.o \
src/menu/gamemenu.o src/menu/mainmenu.o src/menu/menu.o \ src/menu/gamemenu.o src/menu/mainmenu.o src/menu/menu.o \
src/menu/setupmenu.o \ src/menu/setupmenu.o \
src/planet/planet.o \ src/planet/planet.o \
src/player/bird.o src/player/bonusplayer.o src/player/levelplayer.o \ src/player/bird.o src/player/bonusplayer.o src/player/jj2levelplayer.o \
src/player/jj2levelplayerframe.o src/player/levelplayer.o \
src/player/levelplayerframe.o src/player/player.o \ src/player/levelplayerframe.o src/player/player.o \
src/scene/scene.o src/scene/sceneload.o \ src/scene/scene.o src/scene/sceneload.o \
src/baselevel.o src/main.o src/util.o src/baselevel.o src/main.o src/util.o
...@@ -68,7 +71,7 @@ endif ...@@ -68,7 +71,7 @@ endif
endif endif
CXXFLAGS += -g -Wall -O3 -fsigned-char -DUSE_SOCKETS -I$(PREFIX)/include -I$(PREFIX)/include/SDL -Isrc CXXFLAGS += -g -Wall -O3 -fsigned-char -DUSE_SOCKETS -I$(PREFIX)/include -I$(PREFIX)/include/SDL -Isrc
LDFLAGS += -L$(PREFIX)/lib -lSDL LDFLAGS += -L$(PREFIX)/lib -lSDL -lz
# Uncomment the following two lines for music (requires libmodplug) # Uncomment the following two lines for music (requires libmodplug)
CXXFLAGS += -DUSE_MODPLUG -I$(PREFIX)/include/libmodplug CXXFLAGS += -DUSE_MODPLUG -I$(PREFIX)/include/libmodplug
......
...@@ -9,6 +9,8 @@ objects = src/bonus/bonus.o \ ...@@ -9,6 +9,8 @@ objects = src/bonus/bonus.o \
src/io/gfx/scale2x/scale2x.o src/io/gfx/scale2x/scale3x.o \ src/io/gfx/scale2x/scale2x.o src/io/gfx/scale2x/scale3x.o \
src/io/gfx/scale2x/scalebit.o src/io/gfx/scale2x/simple2x.o \ src/io/gfx/scale2x/scalebit.o src/io/gfx/scale2x/simple2x.o \
src/io/controls.o src/io/file.o src/io/network.o src/io/sound.o \ src/io/controls.o src/io/file.o src/io/network.o src/io/sound.o \
src/jj2level/jj2layer.o src/jj2level/jj2level.o \
src/jj2level/jj2levelframe.o src/jj2level/jj2levelload.o \
src/level/event/bridge.o src/level/event/guardians.o \ src/level/event/bridge.o src/level/event/guardians.o \
src/level/event/event.o src/level/event/eventframe.o \ src/level/event/event.o src/level/event/eventframe.o \
src/level/bullet.o src/level/demolevel.o src/level/level.o \ src/level/bullet.o src/level/demolevel.o src/level/level.o \
...@@ -16,7 +18,8 @@ objects = src/bonus/bonus.o \ ...@@ -16,7 +18,8 @@ objects = src/bonus/bonus.o \
src/menu/gamemenu.o src/menu/mainmenu.o src/menu/menu.o \ src/menu/gamemenu.o src/menu/mainmenu.o src/menu/menu.o \
src/menu/setupmenu.o \ src/menu/setupmenu.o \
src/planet/planet.o \ src/planet/planet.o \
src/player/bird.o src/player/bonusplayer.o src/player/levelplayer.o \ src/player/bird.o src/player/bonusplayer.o src/player/jj2levelplayer.o \
src/player/jj2levelplayerframe.o src/player/levelplayer.o \
src/player/levelplayerframe.o src/player/player.o \ src/player/levelplayerframe.o src/player/player.o \
src/scene/scene.o src/scene/sceneload.o \ src/scene/scene.o src/scene/sceneload.o \
src/baselevel.o src/main.o src/util.o src/baselevel.o src/main.o src/util.o
...@@ -29,7 +32,7 @@ CXXFLAGS += -g -Wall -O2 -DUSE_SOCKETS -DSCALE ...@@ -29,7 +32,7 @@ CXXFLAGS += -g -Wall -O2 -DUSE_SOCKETS -DSCALE
#LDFLAGS += `pkg-config --libs libmodplug` #LDFLAGS += `pkg-config --libs libmodplug`
OpenJazz: $(objects) OpenJazz: $(objects)
cc $(CXXFLAGS) -o OpenJazz $(LDFLAGS) -lSDL -lstdc++ $(objects) cc $(CXXFLAGS) -o OpenJazz $(LDFLAGS) -lSDL -lstdc++ -lz $(objects)
%.o: %.cpp %.o: %.cpp
cc $(CXXFLAGS) -Isrc -c $< -o $@ cc $(CXXFLAGS) -Isrc -c $< -o $@
......
...@@ -27,14 +27,17 @@ ...@@ -27,14 +27,17 @@
#include "game/game.h" #include "game/game.h"
#include "io/controls.h"
#include "io/gfx/font.h" #include "io/gfx/font.h"
#include "io/gfx/paletteeffects.h" #include "io/gfx/paletteeffects.h"
#include "io/gfx/sprite.h" #include "io/gfx/sprite.h"
#include "io/gfx/video.h" #include "io/gfx/video.h"
#include "io/sound.h" #include "io/sound.h"
#include "menu/menu.h"
#include "player/player.h" #include "player/player.h"
#include "scene/scene.h" #include "scene/scene.h"
#include "baselevel.h" #include "baselevel.h"
#include "loop.h"
BaseLevel::BaseLevel () { BaseLevel::BaseLevel () {
...@@ -49,6 +52,8 @@ BaseLevel::BaseLevel () { ...@@ -49,6 +52,8 @@ BaseLevel::BaseLevel () {
// Set the level stage // Set the level stage
stage = LS_NORMAL; stage = LS_NORMAL;
stats = 0;
return; return;
} }
...@@ -141,7 +146,7 @@ void BaseLevel::timeCalcs () { ...@@ -141,7 +146,7 @@ void BaseLevel::timeCalcs () {
} }
void BaseLevel::drawStats (int stats, unsigned char bg) { void BaseLevel::drawStats (unsigned char bg) {
int count, width; int count, width;
...@@ -204,6 +209,112 @@ void BaseLevel::drawStats (int stats, unsigned char bg) { ...@@ -204,6 +209,112 @@ void BaseLevel::drawStats (int stats, unsigned char bg) {
} }
int BaseLevel::loop (bool& menu, int& option, bool& message) {
int ret;
// Networking
if (gameMode) {
ret = game->step(ticks);
switch (ret) {
case E_UNUSED:
return E_NONE;
case E_NONE:
break;
default:
return ret;
}
}
// Main loop
if (::loop(NORMAL_LOOP, paletteEffects) == E_QUIT) return E_QUIT;
if (controls.release(C_ESCAPE)) {
menu = !menu;
option = 0;
}
if (controls.release(C_PAUSE)) message = !message;
if (controls.release(C_STATS)) {
if (!gameMode) stats ^= S_SCREEN;
else stats = (stats + 1) & 3;
}
if (menu) {
// Deal with menu controls
if (controls.release(C_UP)) option = (option + 4) % 5;
if (controls.release(C_DOWN)) option = (option + 1) % 5;
if (controls.release(C_ENTER)) {
switch (option) {
case 0: // Continue
menu = false;
break;
case 1: // Save
break;
case 2: // Load
break;
case 3: // Setup
if (!gameMode) {
if (setupMenu.setup() == E_QUIT) return E_QUIT;
// Restore level palette
video.setPalette(palette);
}
break;
case 4: // Quit game
return E_NONE;
}
}
}
if (!gameMode) paused = message || menu;
timeCalcs();
return 1;
}
void BaseLevel::addTimer () { void BaseLevel::addTimer () {
unsigned char buffer[MTL_L_PROP]; unsigned char buffer[MTL_L_PROP];
...@@ -228,3 +339,32 @@ void BaseLevel::addTimer () { ...@@ -228,3 +339,32 @@ void BaseLevel::addTimer () {
} }
void BaseLevel::setStage (LevelStage newStage) {
unsigned char buffer[MTL_L_STAGE];
if (stage == newStage) return;
stage = newStage;
if (gameMode) {
buffer[0] = MTL_L_STAGE;
buffer[1] = MT_L_STAGE;
buffer[2] = stage;
game->send(buffer);
}
return;
}
LevelStage BaseLevel::getStage () {
return stage;
}
...@@ -25,8 +25,7 @@ ...@@ -25,8 +25,7 @@
#include "io/gfx/paletteeffects.h" #include "io/gfx/paletteeffects.h"
#include "menu/menu.h"
#include <SDL/SDL.h>
// Macros // Macros
...@@ -40,6 +39,12 @@ ...@@ -40,6 +39,12 @@
// Enums // Enums
enum LevelType {
LT_LEVEL, LT_BONUS, LT_JJ2LEVEL
};
enum LevelStats { enum LevelStats {
S_PLAYERS = 1, S_SCREEN = 2 S_PLAYERS = 1, S_SCREEN = 2
...@@ -60,6 +65,9 @@ class Sprite; ...@@ -60,6 +65,9 @@ class Sprite;
class BaseLevel { class BaseLevel {
private:
SetupMenu setupMenu;
protected: protected:
SDL_Surface* tileSet; SDL_Surface* tileSet;
Sprite* spriteSet; Sprite* spriteSet;
...@@ -72,18 +80,29 @@ class BaseLevel { ...@@ -72,18 +80,29 @@ class BaseLevel {
int items; int items;
bool paused; bool paused;
LevelStage stage; LevelStage stage;
int stats;
int playScene (char* file); int playScene (char* file);
void timeCalcs (); void timeCalcs ();
void drawStats (int stats, unsigned char bg); void drawStats (unsigned char bg);
int loop (bool& menu, int& option, bool& message);
public: public:
BaseLevel (); BaseLevel ();
~BaseLevel (); virtual ~BaseLevel ();
void addTimer (); void addTimer ();
LevelStage getStage ();
void setStage (LevelStage stage);
virtual void receive (unsigned char* buffer) = 0;
}; };
// Variables
EXTERN BaseLevel* baseLevel;
EXTERN fixed viewX, viewY;
#endif #endif
...@@ -36,9 +36,7 @@ ...@@ -36,9 +36,7 @@
#include "io/gfx/sprite.h" #include "io/gfx/sprite.h"
#include "io/gfx/video.h" #include "io/gfx/video.h"
#include "io/sound.h" #include "io/sound.h"
#include "menu/menu.h"
#include "player/bonusplayer.h" #include "player/bonusplayer.h"
#include "loop.h"
#include "util.h" #include "util.h"
#include <string.h> #include <string.h>
...@@ -335,11 +333,11 @@ Bonus::Bonus (char * fileName, unsigned char diff) { ...@@ -335,11 +333,11 @@ Bonus::Bonus (char * fileName, unsigned char diff) {
game->setCheckpoint(x, y); game->setCheckpoint(x, y);
for (count = 0; count < nPlayers; count++) game->resetPlayer(players + count, true, string); for (count = 0; count < nPlayers; count++) game->resetPlayer(players + count, LT_BONUS, string);
} else { } else {
localPlayer->reset(true, string, x, y); localPlayer->reset(LT_BONUS, string, x, y);
} }
...@@ -352,9 +350,6 @@ Bonus::Bonus (char * fileName, unsigned char diff) { ...@@ -352,9 +350,6 @@ Bonus::Bonus (char * fileName, unsigned char diff) {
// Palette animations // Palette animations
// Free any existing palette effects
if (paletteEffects) delete paletteEffects;
// Spinny whirly thing // Spinny whirly thing
paletteEffects = new RotatePaletteEffect(112, 16, F32, NULL); paletteEffects = new RotatePaletteEffect(112, 16, F32, NULL);
...@@ -409,6 +404,44 @@ bool Bonus::checkMask (fixed x, fixed y) { ...@@ -409,6 +404,44 @@ bool Bonus::checkMask (fixed x, fixed y) {
} }
void Bonus::receive (unsigned char* buffer) {
// Interpret data received from client/server
switch (buffer[1]) {
case MT_L_PROP:
if (buffer[2] == 2) {
if (stage == LS_NORMAL)
endTime += 2 * 60 * 1000; // 2 minutes. Is this right?
}
break;
case MT_L_GRID:
if (buffer[4] == 0) grid[buffer[3]][buffer[2]].tile = buffer[5];
else if (buffer[4] == 2)
grid[buffer[3]][buffer[2]].event = buffer[5];
break;
case MT_L_STAGE:
stage = LevelStage(buffer[2]);
break;
}
return;
}
int Bonus::step () { int Bonus::step () {
BonusPlayer* bonusPlayer; BonusPlayer* bonusPlayer;
...@@ -659,10 +692,10 @@ void Bonus::draw () { ...@@ -659,10 +692,10 @@ void Bonus::draw () {
int Bonus::play () { int Bonus::play () {
SetupMenu setupMenu; const char* options[5] =
const char *options[3] = {"continue game", "setup options", "quit game"}; {"continue game", "save game", "load game", "setup options", "quit game"};
bool pmenu, pmessage; bool pmenu, pmessage;
int stats, option; int option;
unsigned int returnTime; unsigned int returnTime;
int count; int count;
...@@ -673,7 +706,6 @@ int Bonus::play () { ...@@ -673,7 +706,6 @@ int Bonus::play () {
pmessage = pmenu = false; pmessage = pmenu = false;
option = 0; option = 0;
stats = 0;
returnTime = 0; returnTime = 0;
...@@ -681,69 +713,10 @@ int Bonus::play () { ...@@ -681,69 +713,10 @@ int Bonus::play () {
while (true) { while (true) {
if (loop(NORMAL_LOOP, paletteEffects) == E_QUIT) return E_QUIT; count = loop(pmenu, option, pmessage);
if (controls.release(C_ESCAPE)) {
pmenu = !pmenu;
option = 0;
}
if (controls.release(C_PAUSE)) pmessage = !pmessage;
if (controls.release(C_STATS)) {
if (!gameMode) stats ^= S_SCREEN;
else stats = (stats + 1) & 3;
}
if (pmenu) {
// Deal with menu controls
if (controls.release(C_UP)) option = (option + 2) % 3;
if (controls.release(C_DOWN)) option = (option + 1) % 3;
if (controls.release(C_ENTER)) {
switch (option) {
case 0: // Continue
pmenu = false;
break;
case 1: // Setup
if (!gameMode) {
if (setupMenu.setup() == E_QUIT) return E_QUIT;
// Restore level palette
video.setPalette(palette);
}
break;
case 2: // Quit game
return E_NONE;
}
}
}
if (!gameMode) paused = pmessage || pmenu;
timeCalcs();
if (count <= 0) return count;
// Check if level has been won // Check if level has been won
if (returnTime && (ticks > returnTime)) { if (returnTime && (ticks > returnTime)) {
...@@ -791,7 +764,7 @@ int Bonus::play () { ...@@ -791,7 +764,7 @@ int Bonus::play () {
font->showString("pause", (canvasW >> 1) - 44, 32); font->showString("pause", (canvasW >> 1) - 44, 32);
// Draw statistics // Draw statistics
drawStats(stats, 0); drawStats(0);
// Draw the menu // Draw the menu
if (pmenu) { if (pmenu) {
......
...@@ -75,6 +75,7 @@ class Bonus : public BaseLevel { ...@@ -75,6 +75,7 @@ class Bonus : public BaseLevel {
~Bonus (); ~Bonus ();
bool checkMask (fixed x, fixed y); bool checkMask (fixed x, fixed y);
void receive (unsigned char* buffer);
int play (); int play ();
}; };
......
...@@ -146,8 +146,6 @@ ClientGame::ClientGame (char* address) { ...@@ -146,8 +146,6 @@ ClientGame::ClientGame (char* address) {
// Download the level from the server // Download the level from the server
level = NULL;
levelFile = createString(LEVEL_FILE); levelFile = createString(LEVEL_FILE);
file = NULL; file = NULL;
...@@ -398,7 +396,7 @@ int ClientGame::step (unsigned int ticks) { ...@@ -398,7 +396,7 @@ int ClientGame::step (unsigned int ticks) {
players[count].init((char *)recvBuffer + 9, players[count].init((char *)recvBuffer + 9,
recvBuffer + 5, recvBuffer[4]); recvBuffer + 5, recvBuffer[4]);
resetPlayer(players + count, false, NULL); resetPlayer(players + count, LT_LEVEL, NULL);
printf("Player %d joined team %d.\n", count, recvBuffer[4]); printf("Player %d joined team %d.\n", count, recvBuffer[4]);
...@@ -452,7 +450,7 @@ int ClientGame::step (unsigned int ticks) { ...@@ -452,7 +450,7 @@ int ClientGame::step (unsigned int ticks) {
case MC_LEVEL: case MC_LEVEL:
if (level) level->receive(recvBuffer); if (baseLevel) baseLevel->receive(recvBuffer);
break; break;
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "io/gfx/font.h" #include "io/gfx/font.h"
#include "io/gfx/video.h" #include "io/gfx/video.h"
#include "io/sound.h" #include "io/sound.h"
#include "jj2level/jj2level.h"
#include "level/level.h" #include "level/level.h"
#include "planet/planet.h" #include "planet/planet.h"
#include "player/bonusplayer.h" #include "player/bonusplayer.h"
...@@ -115,11 +116,11 @@ int Game::play () { ...@@ -115,11 +116,11 @@ int Game::play () {
// Load and play the level // Load and play the level
if (!strncmp(levelFile, F_BONUSMAP, 8)) { if (!strncasecmp(levelFile, F_BONUSMAP, 8)) {
try { try {
bonus = new Bonus(levelFile, difficulty); baseLevel = bonus = new Bonus(levelFile, difficulty);
} catch (int e) { } catch (int e) {
...@@ -132,6 +133,7 @@ int Game::play () { ...@@ -132,6 +133,7 @@ int Game::play () {
if (ret <= 0) { if (ret <= 0) {
delete bonus; delete bonus;
baseLevel = NULL;
if (ret == E_NONE) playMusic("menusng.psm"); if (ret == E_NONE) playMusic("menusng.psm");
...@@ -147,12 +149,58 @@ int Game::play () { ...@@ -147,12 +149,58 @@ int Game::play () {
} }
delete bonus; delete bonus;
baseLevel = NULL;
} else if (!strcasecmp(levelFile + strlen(levelFile) - 4, ".j2l")) {
try {
baseLevel = jj2Level = new JJ2Level(levelFile, difficulty, checkpoint);
} catch (int e) {
return e;
}
ret = jj2Level->play();
if (ret <= 0) {
delete jj2Level;
baseLevel = jj2Level = NULL;
if (ret == E_NONE) playMusic("menusng.psm");
return ret;
} else if (ret == WON) {
// Won the level
// Do not use old level's checkpoint coordinates
checkpoint = false;
} else {
// Lost the level
if (!localPlayer->getLives()) return E_NONE;
// Use checkpoint coordinates
checkpoint = true;
}
delete jj2Level;
baseLevel = jj2Level = NULL;
} else { } else {
try { try {
level = new Level(levelFile, difficulty, checkpoint); baseLevel = level = new Level(levelFile, difficulty, checkpoint);
} catch (int e) { } catch (int e) {
...@@ -196,7 +244,8 @@ int Game::play () { ...@@ -196,7 +244,8 @@ int Game::play () {
if (ret <= 0) { if (ret <= 0) {
delete level; delete level;
baseLevel = level = NULL;
if (ret == E_NONE) playMusic("menusng.psm"); if (ret == E_NONE) playMusic("menusng.psm");
...@@ -222,6 +271,7 @@ int Game::play () { ...@@ -222,6 +271,7 @@ int Game::play () {
} }
delete level; delete level;
baseLevel = level = NULL;
} }
...@@ -284,7 +334,7 @@ void Game::setCheckpoint (unsigned char gridX, unsigned char gridY) { ...@@ -284,7 +334,7 @@ void Game::setCheckpoint (unsigned char gridX, unsigned char gridY) {
} }
void Game::resetPlayer (LevelPlayer *player) { void Game::resetPlayer (Player *player) {
player->reset(checkX, checkY); player->reset(checkX, checkY);
...@@ -293,9 +343,9 @@ void Game::resetPlayer (LevelPlayer *player) { ...@@ -293,9 +343,9 @@ void Game::resetPlayer (LevelPlayer *player) {
} }
void Game::resetPlayer (Player *player, bool bonus, char* anims) { void Game::resetPlayer (Player *player, LevelType levelType, char* anims) {
player->reset(bonus, anims, checkX, checkY); player->reset(levelType, anims, checkX, checkY);
return; return;
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "gamemode.h" #include "gamemode.h"
#include "baselevel.h"
#include "io/network.h" #include "io/network.h"
...@@ -80,7 +81,6 @@ ...@@ -80,7 +81,6 @@
// Classes // Classes
class File; class File;
class Player;
class Game { class Game {
...@@ -103,8 +103,8 @@ class Game { ...@@ -103,8 +103,8 @@ class Game {
virtual int step (unsigned int ticks); virtual int step (unsigned int ticks);
virtual void score (unsigned char team); virtual void score (unsigned char team);
virtual void setCheckpoint (unsigned char gridX, unsigned char gridY); virtual void setCheckpoint (unsigned char gridX, unsigned char gridY);
void resetPlayer (LevelPlayer *player); void resetPlayer (Player *player);
void resetPlayer (Player *player, bool bonus, char* anims); void resetPlayer (Player *player, LevelType levelType, char* anims);
}; };
......
...@@ -28,27 +28,27 @@ ...@@ -28,27 +28,27 @@
#include "player/levelplayer.h" #include "player/levelplayer.h"
bool GameMode::hit (LevelPlayer *source, LevelPlayer *victim) { bool GameMode::hit (Player *source, Player *victim) {
return true; return true;
} }
bool GameMode::kill (LevelPlayer *source, LevelPlayer *victim) { bool GameMode::kill (Player *source, Player *victim) {
if (source && (victim->player == localPlayer)) game->score(source->player->getTeam()); if (source && (victim == localPlayer)) game->score(source->getTeam());
return true; return true;
} }
bool GameMode::endOfLevel (LevelPlayer *player, unsigned char gridX, unsigned char gridY) { bool GameMode::endOfLevel (Player *player, unsigned char gridX, unsigned char gridY) {
game->setCheckpoint(gridX, gridY); game->setCheckpoint(gridX, gridY);
level->setStage(LS_END); baseLevel->setStage(LS_END);
return true; return true;
...@@ -153,11 +153,11 @@ GameModeType CoopGameMode::getMode () { ...@@ -153,11 +153,11 @@ GameModeType CoopGameMode::getMode () {
} }
bool CoopGameMode::endOfLevel (LevelPlayer *player, unsigned char gridX, unsigned char gridY) { bool CoopGameMode::endOfLevel (Player *player, unsigned char gridX, unsigned char gridY) {
game->setCheckpoint(gridX, gridY); game->setCheckpoint(gridX, gridY);
level->setStage(LS_END); baseLevel->setStage(LS_END);
return true; return true;
...@@ -185,16 +185,16 @@ GameModeType RaceGameMode::getMode () { ...@@ -185,16 +185,16 @@ GameModeType RaceGameMode::getMode () {
} }
bool RaceGameMode::hit (LevelPlayer *source, LevelPlayer *victim) { bool RaceGameMode::hit (Player *source, Player *victim) {
return false; return false;
} }
bool RaceGameMode::endOfLevel (LevelPlayer *player, unsigned char gridX, unsigned char gridY) { bool RaceGameMode::endOfLevel (Player *player, unsigned char gridX, unsigned char gridY) {
if (player->player == localPlayer) game->score(localPlayer->getTeam()); if (player == localPlayer) game->score(localPlayer->getTeam());
game->resetPlayer(player); game->resetPlayer(player);
......
...@@ -44,7 +44,7 @@ enum GameModeType { ...@@ -44,7 +44,7 @@ enum GameModeType {
// Classes // Classes
class Font; class Font;
class LevelPlayer; class Player;
class GameMode { class GameMode {
...@@ -52,9 +52,9 @@ class GameMode { ...@@ -52,9 +52,9 @@ class GameMode {
virtual GameModeType getMode () = 0; virtual GameModeType getMode () = 0;
virtual unsigned char chooseTeam () = 0; virtual unsigned char chooseTeam () = 0;
virtual void drawScore (Font* font) = 0; virtual void drawScore (Font* font) = 0;
virtual bool hit (LevelPlayer *source, LevelPlayer *victim); virtual bool hit (Player *source, Player *victim);
virtual bool kill (LevelPlayer *source, LevelPlayer *victim); virtual bool kill (Player *source, Player *victim);
virtual bool endOfLevel (LevelPlayer *player, unsigned char gridX, unsigned char gridY); virtual bool endOfLevel (Player *player, unsigned char gridX, unsigned char gridY);
virtual void outOfTime (); virtual void outOfTime ();
}; };
...@@ -87,7 +87,7 @@ class CoopGameMode : public CooperativeGameMode { ...@@ -87,7 +87,7 @@ class CoopGameMode : public CooperativeGameMode {
public: public:
GameModeType getMode (); GameModeType getMode ();
bool endOfLevel (LevelPlayer *player, unsigned char gridX, unsigned char gridY); bool endOfLevel (Player *player, unsigned char gridX, unsigned char gridY);
}; };
...@@ -118,8 +118,8 @@ class RaceGameMode : public FreeForAllGameMode { ...@@ -118,8 +118,8 @@ class RaceGameMode : public FreeForAllGameMode {
public: public:
GameModeType getMode (); GameModeType getMode ();
bool hit (LevelPlayer *source, LevelPlayer *victim); bool hit (Player *source, Player *victim);
bool endOfLevel (LevelPlayer *player, unsigned char gridX, unsigned char gridY); bool endOfLevel (Player *player, unsigned char gridX, unsigned char gridY);
}; };
......
...@@ -257,12 +257,11 @@ int ServerGame::step (unsigned int ticks) { ...@@ -257,12 +257,11 @@ int ServerGame::step (unsigned int ticks) {
players[nPlayers].init((char *)(recvBuffers[count]) + 9, players[nPlayers].init((char *)(recvBuffers[count]) + 9,
recvBuffers[count] + 5, recvBuffers[count][4]); recvBuffers[count] + 5, recvBuffers[count][4]);
resetPlayer(players + nPlayers, false, NULL); resetPlayer(players + nPlayers, LT_LEVEL, NULL);
printf("Player %d joined team %d.\n", nPlayers, recvBuffers[count][4]); printf("Player %d joined team %d.\n", nPlayers, recvBuffers[count][4]);
recvBuffers[count][3] = clientPlayer[count] = recvBuffers[count][3] = clientPlayer[count] = nPlayers;
nPlayers;
nPlayers++; nPlayers++;
...@@ -279,8 +278,7 @@ int ServerGame::step (unsigned int ticks) { ...@@ -279,8 +278,7 @@ int ServerGame::step (unsigned int ticks) {
for (pcount = 0; pcount < nPlayers; pcount++) { for (pcount = 0; pcount < nPlayers; pcount++) {
if (players[pcount].getTeam() == if (players[pcount].getTeam() == recvBuffers[count][2])
recvBuffers[count][2])
players[pcount].teamScore++; players[pcount].teamScore++;
} }
...@@ -291,7 +289,7 @@ int ServerGame::step (unsigned int ticks) { ...@@ -291,7 +289,7 @@ int ServerGame::step (unsigned int ticks) {
case MC_LEVEL: case MC_LEVEL:
level->receive(recvBuffers[count]); baseLevel->receive(recvBuffers[count]);
break; break;
...@@ -364,14 +362,13 @@ int ServerGame::step (unsigned int ticks) { ...@@ -364,14 +362,13 @@ int ServerGame::step (unsigned int ticks) {
for (pcount = 0; pcount < nPlayers; pcount++) { for (pcount = 0; pcount < nPlayers; pcount++) {
sendBuffer[0] = MTL_G_PJOIN + sendBuffer[0] = MTL_G_PJOIN + strlen(players[pcount].getName());
strlen(players[pcount].getName());
sendBuffer[2] = count; sendBuffer[2] = count;
sendBuffer[3] = pcount; sendBuffer[3] = pcount;
sendBuffer[4] = players[pcount].getTeam(); sendBuffer[4] = players[pcount].getTeam();
memcpy(sendBuffer + 5, players[pcount].getCols(), 4); memcpy(sendBuffer + 5, players[pcount].getCols(), PCOLOURS);
memcpy(sendBuffer + 9, players[pcount].getName(), memcpy(sendBuffer + 9, players[pcount].getName(), strlen(players[pcount].getName()) + 1);
strlen(players[pcount].getName()) + 1);
net->send(clientSock[count], sendBuffer); net->send(clientSock[count], sendBuffer);
} }
...@@ -402,10 +399,8 @@ int ServerGame::step (unsigned int ticks) { ...@@ -402,10 +399,8 @@ int ServerGame::step (unsigned int ticks) {
players[clientPlayer[count]].deinit(); players[clientPlayer[count]].deinit();
// If necessary, move more recent players // If necessary, move more recent players
for (pcount = clientPlayer[count]; pcount < nPlayers; for (pcount = clientPlayer[count]; pcount < nPlayers; pcount++)
pcount++) memcpy(players + pcount, players + pcount + 1, sizeof(Player));
memcpy(players + pcount, players + pcount + 1,
sizeof(Player));
// Clear duplicate pointers // Clear duplicate pointers
memset(players + nPlayers, 0, sizeof(Player)); memset(players + nPlayers, 0, sizeof(Player));
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "util.h" #include "util.h"
#include <string.h> #include <string.h>
#include <zlib.h>
File::File (const char* name, bool write) { File::File (const char* name, bool write) {
...@@ -283,6 +284,24 @@ void File::skipRLE () { ...@@ -283,6 +284,24 @@ void File::skipRLE () {
} }
unsigned char* File::loadLZ (int compressedLength, int length) {
unsigned char* compressedBuffer;
unsigned char* buffer;
compressedBuffer = loadBlock(compressedLength);
buffer = new unsigned char[length];
uncompress(buffer, (unsigned long int *)&length, compressedBuffer, compressedLength);
delete[] compressedBuffer;
return buffer;
}
char * File::loadString () { char * File::loadString () {
......
...@@ -56,6 +56,7 @@ class File { ...@@ -56,6 +56,7 @@ class File {
unsigned char* loadBlock (int length); unsigned char* loadBlock (int length);
unsigned char* loadRLE (int length); unsigned char* loadRLE (int length);
void skipRLE (); void skipRLE ();
unsigned char* loadLZ (int compressedLength, int length);
char* loadString (); char* loadString ();
SDL_Surface* loadSurface (int width, int height); SDL_Surface* loadSurface (int width, int height);
unsigned char* loadPixels (int length); unsigned char* loadPixels (int length);
......
...@@ -24,8 +24,10 @@ ...@@ -24,8 +24,10 @@
#include "paletteeffects.h" #include "paletteeffects.h"
#include "video.h" #include "video.h"
#include "jj2level/jj2level.h"
#include "level/level.h" #include "level/level.h"
#include "player/levelplayer.h" #include "player/jj2levelplayer.h"
#include "player/levelplayer.h"
#include <string.h> #include <string.h>
...@@ -527,7 +529,10 @@ void WaterPaletteEffect::apply (SDL_Color* shownPalette, bool direct, int mspf) ...@@ -527,7 +529,10 @@ void WaterPaletteEffect::apply (SDL_Color* shownPalette, bool direct, int mspf)
currentPalette = video.getPalette(); currentPalette = video.getPalette();
position = localPlayer->getLevelPlayer()->getY() - level->getWaterLevel();
if (level) position = localPlayer->getLevelPlayer()->getY() - level->getWaterLevel();
else if (jj2Level) position = localPlayer->getJJ2LevelPlayer()->getY() - jj2Level->getWaterLevel();
else return;
if (position <= 0) return; if (position <= 0) return;
......
/*
*
* jj2layer.cpp
*
* 30th June 2010: Created jj2layer.cpp from parts of jj2levelframe.cpp
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2010 Alister Thomson
*
* OpenJazz is distributed under the terms of
* the GNU General Public License, version 2.0
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
/*
* Handles JJ2 level layers.
*
*/
#include "jj2level.h"
#include "io/gfx/video.h"
JJ2Layer::JJ2Layer () {
// Create a blank layer
width = height = 1;
grid = new JJ2GridElement *[1];
*(grid) = new JJ2GridElement[1];
(*grid)->tile = 0;
return;
}
JJ2Layer::JJ2Layer (int newWidth, int newHeight) {
int row;
width = newWidth;
height = newHeight;
grid = new JJ2GridElement *[height];
*(grid) = new JJ2GridElement[width * height];
for (row = 0; row < height; row++) grid[row] = *(grid) + (row * width);
return;
}
JJ2Layer::~JJ2Layer () {
delete[] *(grid);
delete[] grid;
return;
}
int JJ2Layer::getHeight () {
return height;
}
int JJ2Layer::getTile (int x, int y) {
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) return 0;
return grid[y][x].tile;
}
int JJ2Layer::getWidth () {
return width;
}
void JJ2Layer::draw (SDL_Surface* tileSet) {
SDL_Rect src, dst;
int vX, vY;
int x, y;
// Set tile drawing dimensions
src.w = TTOI(1);
src.h = TTOI(1);
src.x = 0;
// Calculate the layer view
if (width <= 30) {
vX = 0;
vY = 0;
} else {
vX = FTOI(viewX);
vY = FTOI(viewY);
}
for (y = 0; y <= ITOT(viewH - 1) + 1; y++) {
for (x = 0; x <= ITOT(viewW - 1) + 1; x++) {
dst.x = TTOI(x) - (vX & 31);
dst.y = TTOI(y) - (vY & 31);
src.y = TTOI(getTile(x + ITOT(vX), y + ITOT(vY)));
if (src.y) SDL_BlitSurface(tileSet, &src, canvas, &dst);
}
}
return;
}
/*
*
* jj2level.cpp
*
* 29th June 2010: Created jj2level.cpp from parts of level.cpp
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2010 Alister Thomson
*
* OpenJazz is distributed under the terms of
* the GNU General Public License, version 2.0
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
/*
* Deals with the creating, playing and freeing of levels.
*
*/
#include "jj2level.h"
#include "game/game.h"
#include "game/gamemode.h"
#include "io/controls.h"
#include "io/file.h"
#include "io/gfx/font.h"
#include "io/gfx/paletteeffects.h"
#include "io/gfx/sprite.h"
#include "io/gfx/video.h"
#include "io/sound.h"
#include "player/jj2levelplayer.h"
#include "scene/scene.h"
#include "util.h"
#include <string.h>
JJ2Level::JJ2Level (char* fileName, unsigned char diff, bool checkpoint) {
int ret;
// Load level data
ret = load(fileName, diff, checkpoint);
if (ret < 0) throw ret;
return;
}
JJ2Level::~JJ2Level () {
int count;
for (count = 0; count < LAYERS; count++) delete layers[count];
delete[] mask;
delete[] musicFile;
delete[] nextLevel;
delete font;
// Restore panel font palette
panelBigFont->restorePalette();
panelSmallFont->restorePalette();
return;
}
bool JJ2Level::checkMaskUp (fixed x, fixed y) {
JJ2GridElement *ge;
// Anything off the edge of the map is solid
if ((x < 0) || (y < 0) || (x >= TTOF(layers[3]->getWidth())) || (y >= TTOF(layers[3]->getHeight())))
return true;
ge = layers[3]->grid[FTOT(y)] + FTOT(x);
// Event 122 is one-way
//if (ge->event == 122) return false;
// Check the mask in the tile in question
return mask[(ge->tile << 10) + ((y >> 5) & 992) + ((x >> 10) & 31)];
}
bool JJ2Level::checkMaskDown (fixed x, fixed y) {
// Anything off the edge of the map is solid
if ((x < 0) || (y < 0) || (x >= TTOF(layers[3]->getWidth())) || (y >= TTOF(layers[3]->getHeight())))
return true;
// Check the mask in the tile in question
return mask[(layers[3]->grid[FTOT(y)][FTOT(x)].tile << 10) + ((y >> 5) & 992) + ((x >> 10) & 31)];
}
bool JJ2Level::checkSpikes (fixed x, fixed y) {
JJ2GridElement *ge;
// Anything off the edge of the map is not spikes
if ((x < 0) || (y < 0) || (x > TTOF(layers[3]->getWidth())) || (y > TTOF(layers[3]->getHeight())))
return false;
ge = layers[3]->grid[FTOT(y)] + FTOT(x);
// Event 126 is spikes
//if (ge->event != 126) return false;
// Check the mask in the tile in question
//return mask[(ge->tile << 10) + ((y >> 5) & 992) + ((x >> 10) & 31)];
return false;
}
void JJ2Level::setNext (char* fileName) {
unsigned char buffer[MTL_L_PROP];
delete[] nextLevel;
nextLevel = createString(fileName);
if (gameMode) {
buffer[0] = MTL_L_PROP;
buffer[1] = MT_L_PROP;
buffer[2] = 0; // set next level
buffer[3] = 0;
buffer[4] = 0;
game->send(buffer);
}
return;
}
void JJ2Level::setFrame (unsigned char gridX, unsigned char gridY, unsigned char frame) {
unsigned char buffer[MTL_L_GRID];
layers[3]->grid[gridY][gridX].frame = frame;
if (gameMode) {
buffer[0] = MTL_L_GRID;
buffer[1] = MT_L_GRID;
buffer[2] = gridX;
buffer[3] = gridY;
buffer[4] = 0; // tile variable
buffer[5] = frame;
game->send(buffer);
}
return;
}
Sprite* JJ2Level::getSprite (unsigned char sprite) {
return spriteSet + sprite;
}
Anim* JJ2Level::getAnim (unsigned char anim) {
return animSet + anim;
}
void JJ2Level::setWaterLevel (unsigned char gridY) {
unsigned char buffer[MTL_L_PROP];
waterLevelTarget = TTOF(gridY);
if (gameMode) {
buffer[0] = MTL_L_PROP;
buffer[1] = MT_L_PROP;
buffer[2] = 1; // set water level
buffer[3] = gridY;
buffer[4] = 0; // Doesn't really matter
game->send(buffer);
}
return;
}
fixed JJ2Level::getWaterLevel () {
return waterLevel;
}
void JJ2Level::receive (unsigned char* buffer) {
// Interpret data received from client/server
switch (buffer[1]) {
case MT_L_PROP:
if (buffer[2] == 1) {
waterLevelTarget = TTOF(buffer[3]);
} else if (buffer[2] == 2) {
if (stage == LS_NORMAL)
endTime += 2 * 60 * 1000; // 2 minutes. Is this right?
}
break;
case MT_L_GRID:
if (buffer[4] == 0) layers[3]->grid[buffer[3]][buffer[2]].frame = buffer[5];
break;
case MT_L_STAGE:
stage = LevelStage(buffer[2]);
break;
}
return;
}
int JJ2Level::play () {
JJ2LevelPlayer* jj2LevelPlayer;
const char* options[5] =
{"continue game", "save game", "load game", "setup options", "quit game"};
bool pmessage, pmenu;
int option;
unsigned int returnTime;
int count;
jj2LevelPlayer = localPlayer->getJJ2LevelPlayer();
tickOffset = globalTicks;
ticks = 16;
prevStepTicks = 0;
pmessage = pmenu = false;
option = 0;
returnTime = 0;
video.setPalette(palette);
playMusic(musicFile);
while (true) {
count = loop(pmenu, option, pmessage);
if (count <= 0) return count;
// Check if level has been won
if (game && returnTime && (ticks > returnTime)) {
count = game->setLevel(nextLevel);
if (count < 0) return count;
return WON;
}
// Process frame-by-frame activity
if (!paused && (ticks >= prevStepTicks + 16)) {
// Apply controls to local player
for (count = 0; count < PCONTROLS; count++)
localPlayer->setControl(count, controls.getState(count));
count = step();
if (count) return count;
}
// Draw the graphics
draw();
// If paused, draw "PAUSE"
if (pmessage && !pmenu)
font->showString("pause", (canvasW >> 1) - 44, 32);
// Draw statistics
drawStats(JJ2_BLACK);
if (stage == LS_END) {
// The level is over, so draw gem counts
returnTime = ticks + 1000;
playSound(S_UPLOOP);
// Display statistics
font->showString("red gems", (canvasW >> 1) - 152, (canvasH >> 1) - 60);
font->showNumber(jj2LevelPlayer->getGems(0), (canvasW >> 1) + 124, (canvasH >> 1) - 60);
font->showString("green gems", (canvasW >> 1) - 152, (canvasH >> 1) - 40);
font->showNumber(jj2LevelPlayer->getGems(1), (canvasW >> 1) + 124, (canvasH >> 1) - 40);
font->showString("blue gems", (canvasW >> 1) - 152, (canvasH >> 1) - 20);
font->showNumber(jj2LevelPlayer->getGems(2), (canvasW >> 1) + 124, (canvasH >> 1) - 20);
}
if (pmenu) {
// Draw the menu
drawRect((canvasW >> 2) - 8, (canvasH >> 1) - 46, 144, 92, JJ2_BLACK);
for (count = 0; count < 5; count++) {
if (count == option) fontmn2->mapPalette(240, 8, 31, -8);
else fontmn2->mapPalette(240, 8, 71, -8);
fontmn2->showString(options[count], canvasW >> 2, (canvasH >> 1) + (count << 4) - 38);
}
fontmn2->restorePalette();
}
}
return E_NONE;
}
/*
*
* jj2level.h
*
* 29th June 2010: Created jj2level.h from parts of level.h
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2010 Alister Thomson
*
* OpenJazz is distributed under the terms of
* the GNU General Public License, version 2.0
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
/* "Tile" is a flexible term. Here it is used to refer specifically to the
individual elements of the tile set.
"Tiles" in the context of level units are referred to as grid elements. */
#ifndef _JJ2LEVEL_H
#define _JJ2LEVEL_H
#include "baselevel.h"
#include "io/gfx/anim.h"
#include "OpenJazz.h"
#include <SDL/SDL.h>
// Constants
// Number of layers
#define LAYERS 8
// Black palette index
#define JJ2_BLACK 0
// Datatypes
typedef struct {
unsigned short int tile; // Indexes the tile set
unsigned char frame; // Current frame being used (for animated tiles)
} JJ2GridElement;
// Classes
class Font;
class JJ2Layer {
private:
int width, height;
public:
JJ2GridElement** grid;
JJ2Layer ();
JJ2Layer (int newWidth, int newHeight);
~JJ2Layer ();
int getHeight ();
int getTile (int x, int y);
int getWidth ();
void draw (SDL_Surface* tileSet);
};
class JJ2Level : public BaseLevel {
private:
char* musicFile;
char* nextLevel;
Anim animSet[128];
char* mask;
int soundMap[32];
JJ2Layer* layers[LAYERS];
unsigned char difficulty;
fixed waterLevel;
fixed waterLevelTarget;
fixed waterLevelSpeed;
void loadSprite (File* file, Sprite* sprite);
int loadSprites (char* fileName);
int loadTiles (char* fileName);
int load (char* fileName, unsigned char diff, bool checkpoint);
int step ();
void draw ();
public:
Font* font;
JJ2Level (char* fileName, unsigned char diff, bool checkpoint);
~JJ2Level ();
bool checkMaskUp (fixed x, fixed y);
bool checkMaskDown (fixed x, fixed y);
bool checkSpikes (fixed x, fixed y);
void setNext (char* fileName);
void setFrame (unsigned char gridX, unsigned char gridY, unsigned char frame);
Sprite* getSprite (unsigned char sprite);
Anim* getAnim (unsigned char anim);
void setWaterLevel (unsigned char gridY);
fixed getWaterLevel ();
void receive (unsigned char* buffer);
int play ();
};
// Variable
EXTERN JJ2Level* jj2Level;
#endif
/*
*
* jj2levelframe.cpp
*
* 29th June 2010: Created jj2levelframe.cpp from parts of levelframe.cpp
* 30th June 2010: Created jj2layer.cpp from parts of jj2levelframe.cpp
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2010 Alister Thomson
*
* OpenJazz is distributed under the terms of
* the GNU General Public License, version 2.0
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
/*
* Provides the once-per-frame functions for levels.
*
*/
#include "jj2level.h"
#include "game/game.h"
#include "game/gamemode.h"
#include "io/controls.h"
#include "io/gfx/font.h"
#include "io/gfx/video.h"
#include "player/jj2levelplayer.h"
#include "util.h"
int JJ2Level::step () {
int x;
int msps;
// Milliseconds per step
msps = ticks - prevStepTicks;
prevStepTicks = ticks;
// Determine the players' trajectories
for (x = 0; x < nPlayers; x++) players[x].getJJ2LevelPlayer()->control(ticks, msps);
// Apply as much of those trajectories as possible, without going into the
// scenery
for (x = 0; x < nPlayers; x++) players[x].getJJ2LevelPlayer()->move(ticks, msps);
// Handle change in water level
if (waterLevel < waterLevelTarget) waterLevelSpeed += 100 * msps;
else waterLevelSpeed -= 100 * msps;
if (waterLevelSpeed > 40000) waterLevelSpeed = 40000;
if (waterLevelSpeed < -40000) waterLevelSpeed = -40000;
waterLevel += (waterLevelSpeed * msps) >> 10;
// Handle player reactions
for (x = 0; x < nPlayers; x++) {
if (players[x].getJJ2LevelPlayer()->reacted(ticks) == JJ2PR_KILLED) {
if (!gameMode) return LOST;
game->resetPlayer(players + x);
}
}
return E_NONE;
}
void JJ2Level::draw () {
int count, energy;
unsigned int change;
// Calculate viewport
if (game && (stage == LS_END)) game->view(paused? 0: ((ticks - prevTicks) * 160));
else localPlayer->getJJ2LevelPlayer()->view(ticks, paused? 0: (ticks - prevTicks));
// Ensure the new viewport is within the level
if (viewX < 0) viewX = 0;
if (FTOI(viewX) + viewW >= TTOI(layers[3]->getWidth())) viewX = ITOF(TTOI(layers[3]->getWidth()) - viewW);
if (viewY < 0) viewY = 0;
if (FTOI(viewY) + viewH >= TTOI(layers[3]->getHeight())) viewY = ITOF(TTOI(layers[3]->getHeight()) - viewH);
// Show background layers
for (count = 7; count >= 3; count--) layers[count]->draw(tileSet);
// Calculate change since last step
change = paused? 0: ticks - prevStepTicks;
// Show the players
for (count = 0; count < nPlayers; count++) players[count].getJJ2LevelPlayer()->draw(ticks, change);
// Show foreground layers
for (count = 2; count >= 0; count--) layers[count]->draw(tileSet);
// Temporary lines showing the water level
drawRect(0, FTOI(waterLevel - viewY), canvasW, 2, 72);
drawRect(0, FTOI(waterLevel - viewY) + 3, canvasW, 1, 72);
drawRect(0, FTOI(waterLevel - viewY) + 6, canvasW, 1, 72);
drawRect(0, FTOI(waterLevel - viewY) + 10, canvasW, 1, 72);
// Show "panel" data
// Show score
if (gameMode) gameMode->drawScore(font);
else panelSmallFont->showNumber(localPlayer->getScore(), 16, 8);
// Draw hearts
energy = localPlayer->getJJ2LevelPlayer()->getEnergy();
for (count = 1; count <= energy; count++) {
drawRect(viewW - (count * 12), 4, 8, 8, 48);
}
// Show lives
panelSmallFont->showNumber(localPlayer->getLives(), 16, canvasH - 16);
// Show ammo
if (localPlayer->getAmmo(false) == -1) {
panelSmallFont->showString(":", viewW - 24, canvasH - 16);
panelSmallFont->showString(";", viewW - 16, canvasH - 16);
} else panelSmallFont->showNumber(localPlayer->getAmmo(true), viewW - 8, canvasH - 16);
return;
}
This diff is collapsed.
...@@ -231,7 +231,7 @@ Bullet* Bullet::step (unsigned int ticks, int msps) { ...@@ -231,7 +231,7 @@ Bullet* Bullet::step (unsigned int ticks, int msps) {
ITOF(sprite->getWidth()), ITOF(sprite->getHeight()))) { ITOF(sprite->getWidth()), ITOF(sprite->getHeight()))) {
// If the hit was successful, destroy the bullet // If the hit was successful, destroy the bullet
if (players[count].getLevelPlayer()->hit(source, ticks)) return remove(); if (players[count].getLevelPlayer()->hit(source? source->player: NULL, ticks)) return remove();
} }
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
#include "io/gfx/video.h" #include "io/gfx/video.h"
#include "player/levelplayer.h" #include "player/levelplayer.h"
#include "loop.h" #include "loop.h"
#include "util.h" #include "util.h"
DemoLevel::DemoLevel (const char* fileName) { DemoLevel::DemoLevel (const char* fileName) {
...@@ -94,7 +94,6 @@ DemoLevel::~DemoLevel () { ...@@ -94,7 +94,6 @@ DemoLevel::~DemoLevel () {
int DemoLevel::play () { int DemoLevel::play () {
int stats;
unsigned char macroPoint; unsigned char macroPoint;
int ret; int ret;
...@@ -103,14 +102,12 @@ int DemoLevel::play () { ...@@ -103,14 +102,12 @@ int DemoLevel::play () {
ticks = 16; ticks = 16;
prevStepTicks = 0; prevStepTicks = 0;
stats = 0;
video.setPalette(palette); video.setPalette(palette);
while (true) { while (true) {
// Do general processing // Do general processing
if (loop(NORMAL_LOOP, paletteEffects) == E_QUIT) return E_QUIT; if (::loop(NORMAL_LOOP, paletteEffects) == E_QUIT) return E_QUIT;
if (controls.release(C_ESCAPE)) return E_NONE; if (controls.release(C_ESCAPE)) return E_NONE;
...@@ -172,7 +169,7 @@ int DemoLevel::play () { ...@@ -172,7 +169,7 @@ int DemoLevel::play () {
// Draw the graphics // Draw the graphics
draw(); draw();
drawStats(stats, BLACK); drawStats(LEVEL_BLACK);
font->showString("demo", (canvasW >> 1) - 36, 32); font->showString("demo", (canvasW >> 1) - 36, 32);
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
* 19th July 2009: Added parts of levelload.cpp to level.cpp * 19th July 2009: Added parts of levelload.cpp to level.cpp
* 30th March 2010: Created baselevel.cpp from parts of level.cpp and * 30th March 2010: Created baselevel.cpp from parts of level.cpp and
* levelframe.cpp * levelframe.cpp
* 29th June 2010: Created jj2level.cpp from parts of level.cpp
* *
* Part of the OpenJazz project * Part of the OpenJazz project
* *
...@@ -50,11 +51,9 @@ ...@@ -50,11 +51,9 @@
#include "io/gfx/sprite.h" #include "io/gfx/sprite.h"
#include "io/gfx/video.h" #include "io/gfx/video.h"
#include "io/sound.h" #include "io/sound.h"
#include "menu/menu.h"
#include "player/levelplayer.h" #include "player/levelplayer.h"
#include "scene/scene.h" #include "scene/scene.h"
#include "loop.h" #include "util.h"
#include "util.h"
#include <string.h> #include <string.h>
...@@ -77,9 +76,6 @@ Level::Level (char* fileName, unsigned char diff, bool checkpoint) { ...@@ -77,9 +76,6 @@ Level::Level (char* fileName, unsigned char diff, bool checkpoint) {
ret = load(fileName, diff, checkpoint); ret = load(fileName, diff, checkpoint);
if (ret < 0) throw ret; if (ret < 0) throw ret;
// Arbitrary initial value
smoothfps = 50.0f;
return; return;
...@@ -187,8 +183,7 @@ void Level::setNext (int nextLevel, int nextWorld) { ...@@ -187,8 +183,7 @@ void Level::setNext (int nextLevel, int nextWorld) {
} }
void Level::setTile (unsigned char gridX, unsigned char gridY, void Level::setTile (unsigned char gridX, unsigned char gridY, unsigned char tile) {
unsigned char tile) {
unsigned char buffer[MTL_L_GRID]; unsigned char buffer[MTL_L_GRID];
...@@ -400,35 +395,6 @@ void Level::flash (unsigned char red, unsigned char green, unsigned char blue, i ...@@ -400,35 +395,6 @@ void Level::flash (unsigned char red, unsigned char green, unsigned char blue, i
} }
void Level::setStage (LevelStage newStage) {
unsigned char buffer[MTL_L_STAGE];
if (stage == newStage) return;
stage = newStage;
if (gameMode) {
buffer[0] = MTL_L_STAGE;
buffer[1] = MT_L_STAGE;
buffer[2] = stage;
game->send(buffer);
}
return;
}
LevelStage Level::getStage () {
return stage;
}
int Level::playBonus () { int Level::playBonus () {
Bonus *bonus; Bonus *bonus;
...@@ -444,7 +410,7 @@ int Level::playBonus () { ...@@ -444,7 +410,7 @@ int Level::playBonus () {
try { try {
bonus = new Bonus(bonusFile, difficulty); baseLevel = bonus = new Bonus(bonusFile, difficulty);
} catch (int e) { } catch (int e) {
...@@ -457,6 +423,7 @@ int Level::playBonus () { ...@@ -457,6 +423,7 @@ int Level::playBonus () {
ret = bonus->play(); ret = bonus->play();
delete bonus; delete bonus;
baseLevel = NULL;
if (ret == E_NONE) playMusic("menusng.psm"); if (ret == E_NONE) playMusic("menusng.psm");
...@@ -520,9 +487,8 @@ int Level::play () { ...@@ -520,9 +487,8 @@ int Level::play () {
const char* options[5] = const char* options[5] =
{"continue game", "save game", "load game", "setup options", "quit game"}; {"continue game", "save game", "load game", "setup options", "quit game"};
char *string; char *string;
SetupMenu setupMenu;
bool pmessage, pmenu; bool pmessage, pmenu;
int stats, option; int option;
unsigned int returnTime; unsigned int returnTime;
int perfect; int perfect;
int timeBonus; int timeBonus;
...@@ -537,7 +503,6 @@ int Level::play () { ...@@ -537,7 +503,6 @@ int Level::play () {
pmessage = pmenu = false; pmessage = pmenu = false;
option = 0; option = 0;
stats = 0;
returnTime = 0; returnTime = 0;
timeBonus = -1; timeBonus = -1;
...@@ -549,76 +514,9 @@ int Level::play () { ...@@ -549,76 +514,9 @@ int Level::play () {
while (true) { while (true) {
if (loop(NORMAL_LOOP, paletteEffects) == E_QUIT) return E_QUIT; count = loop(pmenu, option, pmessage);
if (controls.release(C_ESCAPE)) {
pmenu = !pmenu;
option = 0;
}
if (controls.release(C_PAUSE)) pmessage = !pmessage;
if (controls.release(C_STATS)) {
if (!gameMode) stats ^= S_SCREEN;
else stats = (stats + 1) & 3;
}
if (pmenu) {
// Deal with menu controls
if (controls.release(C_UP)) option = (option + 4) % 5;
if (controls.release(C_DOWN)) option = (option + 1) % 5;
if (controls.release(C_ENTER)) {
switch (option) {
case 0: // Continue
pmenu = false;
break;
case 1: // Save
break;
case 2: // Load
break;
case 3: // Setup
if (!gameMode) {
if (setupMenu.setup() == E_QUIT) return E_QUIT;
// Restore level palette
video.setPalette(palette);
}
break;
case 4: // Quit game
return E_NONE;
}
}
}
if (!gameMode) paused = pmessage || pmenu;
timeCalcs(); if (count <= 0) return count;
// Check if level has been won // Check if level has been won
...@@ -676,13 +574,9 @@ int Level::play () { ...@@ -676,13 +574,9 @@ int Level::play () {
if (pmessage && !pmenu) if (pmessage && !pmenu)
font->showString("pause", (canvasW >> 1) - 44, 32); font->showString("pause", (canvasW >> 1) - 44, 32);
// If this is a competitive game, draw the score
if (gameMode) gameMode->drawScore(font);
// Draw statistics // Draw statistics
drawStats(stats, BLACK); drawStats(LEVEL_BLACK);
if (stage == LS_END) { if (stage == LS_END) {
...@@ -728,7 +622,6 @@ int Level::play () { ...@@ -728,7 +622,6 @@ int Level::play () {
} }
// Display statistics & bonuses // Display statistics & bonuses
// TODO: Display percentage symbol
font->showString("time", (canvasW >> 1) - 152, (canvasH >> 1) - 60); font->showString("time", (canvasW >> 1) - 152, (canvasH >> 1) - 60);
font->showNumber(timeBonus, (canvasW >> 1) + 124, (canvasH >> 1) - 60); font->showNumber(timeBonus, (canvasW >> 1) + 124, (canvasH >> 1) - 60);
...@@ -762,7 +655,7 @@ int Level::play () { ...@@ -762,7 +655,7 @@ int Level::play () {
// Draw the menu // Draw the menu
drawRect((canvasW >> 2) - 8, (canvasH >> 1) - 46, 144, 92, BLACK); drawRect((canvasW >> 2) - 8, (canvasH >> 1) - 46, 144, 92, LEVEL_BLACK);
for (count = 0; count < 5; count++) { for (count = 0; count < 5; count++) {
...@@ -777,31 +670,6 @@ int Level::play () { ...@@ -777,31 +670,6 @@ int Level::play () {
} }
// Networking
if (gameMode) {
count = game->step(ticks);
switch (count) {
case E_UNUSED:
return E_NONE;
case E_NONE:
break;
default:
return count;
}
}
} }
return E_NONE; return E_NONE;
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* 4th February 2009: Created events.h from parts of level.h * 4th February 2009: Created events.h from parts of level.h
* 19th March 2009: Created sprite.h from parts of level.h * 19th March 2009: Created sprite.h from parts of level.h
* 30th March 2010: Created baselevel.h from parts of level.h * 30th March 2010: Created baselevel.h from parts of level.h
* 29th June 2010: Created jj2level.h from parts of level.h
* *
* Part of the OpenJazz project * Part of the OpenJazz project
* *
...@@ -53,7 +54,7 @@ ...@@ -53,7 +54,7 @@
#define TKEY 127 /* Tileset colour key */ #define TKEY 127 /* Tileset colour key */
// Black palette index // Black palette index
#define BLACK 31 #define LEVEL_BLACK 31
// Fade delays // Fade delays
#define T_START 500 #define T_START 500
...@@ -113,10 +114,10 @@ class Level : public BaseLevel { ...@@ -113,10 +114,10 @@ class Level : public BaseLevel {
fixed waterLevelSpeed; fixed waterLevelSpeed;
fixed energyBar; fixed energyBar;
void loadSprite (File* file, Sprite* sprite); void loadSprite (File* file, Sprite* sprite);
int loadSprites (char* fileName); int loadSprites (char* fileName);
int loadTiles (char* fileName); int loadTiles (char* fileName);
int playBonus (); int playBonus ();
protected: protected:
int load (char* fileName, unsigned char diff, bool checkpoint); int load (char* fileName, unsigned char diff, bool checkpoint);
...@@ -124,14 +125,14 @@ class Level : public BaseLevel { ...@@ -124,14 +125,14 @@ class Level : public BaseLevel {
void draw (); void draw ();
public: public:
Font* font; Font* font;
Event* events; Event* events;
Bullet* bullets; Bullet* bullets;
EventPath path[PATHS]; EventPath path[PATHS];
Level (); Level ();
Level (char* fileName, unsigned char diff, bool checkpoint); Level (char* fileName, unsigned char diff, bool checkpoint);
virtual ~Level (); virtual ~Level ();
bool checkMaskUp (fixed x, fixed y); bool checkMaskUp (fixed x, fixed y);
bool checkMaskDown (fixed x, fixed y); bool checkMaskDown (fixed x, fixed y);
...@@ -152,8 +153,6 @@ class Level : public BaseLevel { ...@@ -152,8 +153,6 @@ class Level : public BaseLevel {
fixed getWaterLevel (); fixed getWaterLevel ();
void playSound (int sound); void playSound (int sound);
void flash (unsigned char red, unsigned char green, unsigned char blue, int duration); void flash (unsigned char red, unsigned char green, unsigned char blue, int duration);
void setStage (LevelStage stage);
LevelStage getStage ();
void receive (unsigned char* buffer); void receive (unsigned char* buffer);
virtual int play (); virtual int play ();
...@@ -174,10 +173,9 @@ class DemoLevel : public Level { ...@@ -174,10 +173,9 @@ class DemoLevel : public Level {
}; };
// Variables // Variable
EXTERN Level* level; EXTERN Level* level;
EXTERN fixed viewX, viewY;
#endif #endif
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
* 19th July 2009: Created levelframe.cpp from parts of level.cpp * 19th July 2009: Created levelframe.cpp from parts of level.cpp
* 30th March 2010: Created baselevel.cpp from parts of level.cpp and * 30th March 2010: Created baselevel.cpp from parts of level.cpp and
* levelframe.cpp * levelframe.cpp
* 29th June 2010: Created jj2levelframe.cpp from parts of levelframe.cpp
* *
* Part of the OpenJazz project * Part of the OpenJazz project
* *
...@@ -56,8 +57,7 @@ int Level::step () { ...@@ -56,8 +57,7 @@ int Level::step () {
// Search for active events // Search for active events
for (y = FTOT(viewY) - 5; y < ITOT(FTOI(viewY) + viewH) + 5; y++) { for (y = FTOT(viewY) - 5; y < ITOT(FTOI(viewY) + viewH) + 5; y++) {
for (x = FTOT(viewX) - 5; x < ITOT(FTOI(viewX) + viewW) + 5; x++) for (x = FTOT(viewX) - 5; x < ITOT(FTOI(viewX) + viewW) + 5; x++) {
{
if ((x >= 0) && (y >= 0) && (x < LW) && (y < LH) && if ((x >= 0) && (y >= 0) && (x < LW) && (y < LH) &&
grid[y][x].event && (grid[y][x].event < 121)) { grid[y][x].event && (grid[y][x].event < 121)) {
...@@ -157,7 +157,7 @@ int Level::step () { ...@@ -157,7 +157,7 @@ int Level::step () {
if (!gameMode) return LOST; if (!gameMode) return LOST;
game->resetPlayer(players[x].getLevelPlayer()); game->resetPlayer(players + x);
} }
...@@ -247,8 +247,7 @@ void Level::draw () { ...@@ -247,8 +247,7 @@ void Level::draw () {
// If this tile uses a black background, draw it // If this tile uses a black background, draw it
if (ge->bg) if (ge->bg)
drawRect(TTOI(x) - (vX & 31), TTOI(y) - (vY & 31), 32, 32, drawRect(TTOI(x) - (vX & 31), TTOI(y) - (vY & 31), 32, 32, LEVEL_BLACK);
BLACK);
// If this is not a foreground tile, draw it // If this is not a foreground tile, draw it
...@@ -329,6 +328,10 @@ void Level::draw () { ...@@ -329,6 +328,10 @@ void Level::draw () {
if (events) events->drawEnergy(ticks); if (events) events->drawEnergy(ticks);
// If this is a competitive game, draw the score
if (gameMode) gameMode->drawScore(font);
// Show panel // Show panel
SDL_SetClipRect(canvas, NULL); SDL_SetClipRect(canvas, NULL);
...@@ -336,13 +339,12 @@ void Level::draw () { ...@@ -336,13 +339,12 @@ void Level::draw () {
// Change the ammo type display on the panel // Change the ammo type display on the panel
dst.x = 250; dst.x = 250;
dst.y = 2; dst.y = 2;
SDL_BlitSurface(panelAmmo[localPlayer->getAmmo(false) + 1], NULL, panel, SDL_BlitSurface(panelAmmo[localPlayer->getAmmo(false) + 1], NULL, panel, &dst);
&dst);
dst.x = 0; dst.x = 0;
dst.y = canvasH - 33; dst.y = canvasH - 33;
SDL_BlitSurface(panel, NULL, canvas, &dst); SDL_BlitSurface(panel, NULL, canvas, &dst);
drawRect(0, canvasH - 1, SW, 1, BLACK); drawRect(0, canvasH - 1, SW, 1, LEVEL_BLACK);
// Show panel data // Show panel data
...@@ -424,7 +426,7 @@ void Level::draw () { ...@@ -424,7 +426,7 @@ void Level::draw () {
// Fill in remaining energy bar space with black // Fill in remaining energy bar space with black
drawRect(dst.x, canvasH - 13, dst.w, 7, BLACK); drawRect(dst.x, canvasH - 13, dst.w, 7, LEVEL_BLACK);
return; return;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* 18th July 2009: Created demolevel.cpp from parts of level.cpp and * 18th July 2009: Created demolevel.cpp from parts of level.cpp and
* levelload.cpp * levelload.cpp
* 19th July 2009: Added parts of levelload.cpp to level.cpp * 19th July 2009: Added parts of levelload.cpp to level.cpp
* 28th June 2010: Created levelloadjj2.cpp from parts of levelload.cpp
* *
* Part of the OpenJazz project * Part of the OpenJazz project
* *
...@@ -34,10 +35,8 @@ ...@@ -34,10 +35,8 @@
#include "level.h" #include "level.h"
#include "game/game.h" #include "game/game.h"
#include "game/gamemode.h"
#include "io/file.h" #include "io/file.h"
#include "io/gfx/font.h" #include "io/gfx/font.h"
#include "io/gfx/paletteeffects.h"
#include "io/gfx/sprite.h" #include "io/gfx/sprite.h"
#include "io/gfx/video.h" #include "io/gfx/video.h"
#include "io/sound.h" #include "io/sound.h"
...@@ -229,10 +228,10 @@ int Level::loadSprites (char * fileName) { ...@@ -229,10 +228,10 @@ int Level::loadSprites (char * fileName) {
} }
int Level::loadTiles (char * fileName) { int Level::loadTiles (char* fileName) {
File *file; File* file;
unsigned char *buffer; unsigned char* buffer;
int rle, pos, index, count, fileSize; int rle, pos, index, count, fileSize;
int tiles; int tiles;
...@@ -264,7 +263,7 @@ int Level::loadTiles (char * fileName) { ...@@ -264,7 +263,7 @@ int Level::loadTiles (char * fileName) {
tiles = 240; // Never more than 240 tiles tiles = 240; // Never more than 240 tiles
buffer = new unsigned char[tiles * 1024]; buffer = new unsigned char[tiles << 10];
file->seek(4, false); file->seek(4, false);
...@@ -273,7 +272,7 @@ int Level::loadTiles (char * fileName) { ...@@ -273,7 +272,7 @@ int Level::loadTiles (char * fileName) {
// Read the RLE pixels // Read the RLE pixels
// file::loadRLE() cannot be used, for reasons that will become clear // file::loadRLE() cannot be used, for reasons that will become clear
while ((pos < 1024 * tiles) && (file->tell() < fileSize)) { while ((pos < (tiles << 10)) && (file->tell() < fileSize)) {
rle = file->loadChar(); rle = file->loadChar();
...@@ -296,9 +295,9 @@ int Level::loadTiles (char * fileName) { ...@@ -296,9 +295,9 @@ int Level::loadTiles (char * fileName) {
file->seek(2, false); /* I assume this is the length of the next file->seek(2, false); /* I assume this is the length of the next
tile block */ tile block */
if (pos == 1024 * 60) file->seek(2, false); if (pos == (60 << 10)) file->seek(2, false);
if (pos == 1024 * 120) file->seek(2, false); if (pos == (120 << 10)) file->seek(2, false);
if (pos == 1024 * 180) file->seek(2, false); if (pos == (180 << 10)) file->seek(2, false);
} }
...@@ -308,7 +307,7 @@ int Level::loadTiles (char * fileName) { ...@@ -308,7 +307,7 @@ int Level::loadTiles (char * fileName) {
// Work out how many tiles were actually loaded // Work out how many tiles were actually loaded
// Should be a multiple of 60 // Should be a multiple of 60
tiles = pos / 1024; tiles = pos >> 10;
tileSet = createSurface(buffer, TTOI(1), TTOI(tiles)); tileSet = createSurface(buffer, TTOI(1), TTOI(tiles));
SDL_SetColorKey(tileSet, SDL_SRCCOLORKEY, TKEY); SDL_SetColorKey(tileSet, SDL_SRCCOLORKEY, TKEY);
...@@ -423,7 +422,7 @@ int Level::load (char *fileName, unsigned char diff, bool checkpoint) { ...@@ -423,7 +422,7 @@ int Level::load (char *fileName, unsigned char diff, bool checkpoint) {
delete[] string; delete[] string;
if (loop(NORMAL_LOOP) == E_QUIT) return E_QUIT; if (::loop(NORMAL_LOOP) == E_QUIT) return E_QUIT;
...@@ -442,8 +441,6 @@ int Level::load (char *fileName, unsigned char diff, bool checkpoint) { ...@@ -442,8 +441,6 @@ int Level::load (char *fileName, unsigned char diff, bool checkpoint) {
} }
// Load level data from a Level#.### file
// Load the blocks.### extension // Load the blocks.### extension
// Skip past all level data // Skip past all level data
...@@ -555,7 +552,7 @@ int Level::load (char *fileName, unsigned char diff, bool checkpoint) { ...@@ -555,7 +552,7 @@ int Level::load (char *fileName, unsigned char diff, bool checkpoint) {
// Load mask data // Load mask data
buffer = file->loadRLE(tiles * 8); buffer = file->loadRLE(tiles * 8);
// Unpack bits // Unpack bits
for (count = 0; count < tiles; count++) { for (count = 0; count < tiles; count++) {
...@@ -792,18 +789,18 @@ int Level::load (char *fileName, unsigned char diff, bool checkpoint) { ...@@ -792,18 +789,18 @@ int Level::load (char *fileName, unsigned char diff, bool checkpoint) {
if (!checkpoint) game->setCheckpoint(startX, startY); if (!checkpoint) game->setCheckpoint(startX, startY);
for (count = 0; count < nPlayers; count++) game->resetPlayer(players + count, false, string + 3); for (count = 0; count < nPlayers; count++) game->resetPlayer(players + count, LT_LEVEL, string + 3);
} else { } else {
localPlayer->reset(false, string + 3, startX, startY); localPlayer->reset(LT_LEVEL, string + 3, startX, startY);
} }
delete[] string; delete[] string;
// Load Skip to bullet set // Load miscellaneous animations
miscAnims[0] = file->loadChar(); miscAnims[0] = file->loadChar();
miscAnims[1] = file->loadChar(); miscAnims[1] = file->loadChar();
miscAnims[2] = file->loadChar(); miscAnims[2] = file->loadChar();
...@@ -847,9 +844,6 @@ int Level::load (char *fileName, unsigned char diff, bool checkpoint) { ...@@ -847,9 +844,6 @@ int Level::load (char *fileName, unsigned char diff, bool checkpoint) {
sky = false; sky = false;
// Free any existing palette effects
if (paletteEffects) delete paletteEffects;
switch (type) { switch (type) {
case 2: case 2:
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include "io/gfx/video.h" #include "io/gfx/video.h"
#include "io/network.h" #include "io/network.h"
#include "io/sound.h" #include "io/sound.h"
#include "jj2level/jj2level.h"
#include "level/level.h" #include "level/level.h"
#include "menu/menu.h" #include "menu/menu.h"
#include "player/player.h" #include "player/player.h"
...@@ -456,7 +457,11 @@ int loadMain (int argc, char *argv[]) { ...@@ -456,7 +457,11 @@ int loadMain (int argc, char *argv[]) {
// Initiate networking // Initiate networking
net = new Network(); net = new Network();
baseLevel = NULL;
level = NULL;
jj2Level = NULL;
return E_NONE; return E_NONE;
} }
......
...@@ -108,10 +108,9 @@ GameMenu::~GameMenu () { ...@@ -108,10 +108,9 @@ GameMenu::~GameMenu () {
} }
int GameMenu::newGameDifficulty (GameModeType mode, int levelNum, int worldNum) { int GameMenu::newGameDifficulty (GameModeType mode, char* firstLevel) {
const char *options[4] = {"easy", "medium", "hard", "turbo"}; const char *options[4] = {"easy", "medium", "hard", "turbo"};
char *firstLevel;
SDL_Rect src, dst; SDL_Rect src, dst;
int count; int count;
...@@ -154,9 +153,6 @@ int GameMenu::newGameDifficulty (GameModeType mode, int levelNum, int worldNum) ...@@ -154,9 +153,6 @@ int GameMenu::newGameDifficulty (GameModeType mode, int levelNum, int worldNum)
playSound(S_ORB); playSound(S_ORB);
if (levelNum == -1) firstLevel = createFileName(F_BONUSMAP, worldNum);
else firstLevel = createFileName(F_LEVEL, levelNum, worldNum);
if (mode == M_SINGLE) { if (mode == M_SINGLE) {
try { try {
...@@ -165,8 +161,6 @@ int GameMenu::newGameDifficulty (GameModeType mode, int levelNum, int worldNum) ...@@ -165,8 +161,6 @@ int GameMenu::newGameDifficulty (GameModeType mode, int levelNum, int worldNum)
} catch (int e) { } catch (int e) {
delete[] firstLevel;
message("COULD NOT START GAME"); message("COULD NOT START GAME");
return e; return e;
...@@ -181,8 +175,6 @@ int GameMenu::newGameDifficulty (GameModeType mode, int levelNum, int worldNum) ...@@ -181,8 +175,6 @@ int GameMenu::newGameDifficulty (GameModeType mode, int levelNum, int worldNum)
} catch (int e) { } catch (int e) {
delete[] firstLevel;
message("COULD NOT CREATE SERVER"); message("COULD NOT CREATE SERVER");
return e; return e;
...@@ -191,8 +183,6 @@ int GameMenu::newGameDifficulty (GameModeType mode, int levelNum, int worldNum) ...@@ -191,8 +183,6 @@ int GameMenu::newGameDifficulty (GameModeType mode, int levelNum, int worldNum)
} }
delete[] firstLevel;
// Play the level(s) // Play the level(s)
...@@ -224,9 +214,27 @@ int GameMenu::newGameDifficulty (GameModeType mode, int levelNum, int worldNum) ...@@ -224,9 +214,27 @@ int GameMenu::newGameDifficulty (GameModeType mode, int levelNum, int worldNum)
} }
int GameMenu::newGameDifficulty (GameModeType mode, int levelNum, int worldNum) {
char* firstLevel;
int ret;
if (levelNum == -1) firstLevel = createFileName(F_BONUSMAP, worldNum);
else firstLevel = createFileName(F_LEVEL, levelNum, worldNum);
ret = newGameDifficulty(mode, firstLevel);
delete[] firstLevel;
return ret;
}
int GameMenu::newGameLevel (GameModeType mode) { int GameMenu::newGameLevel (GameModeType mode) {
/*
int option, worldNum, levelNum; int option, worldNum, levelNum;
worldNum = levelNum = option = 0; worldNum = levelNum = option = 0;
...@@ -288,7 +296,31 @@ int GameMenu::newGameLevel (GameModeType mode) { ...@@ -288,7 +296,31 @@ int GameMenu::newGameLevel (GameModeType mode) {
} }
return E_NONE; return E_NONE;
*/
char* fileName;
int ret;
fileName = createString("castle1.j2l");
ret = E_NONE;
while (true) {
ret = textInput("level file name:", fileName);
if (ret < 0) break;
ret = newGameDifficulty(mode, fileName);
if (ret < 0) break;
}
delete[] fileName;
return ret;
} }
......
...@@ -272,7 +272,7 @@ int MainMenu::main () { ...@@ -272,7 +272,7 @@ int MainMenu::main () {
try { try {
level = new DemoLevel(F_MACRO); baseLevel = level = new DemoLevel(F_MACRO);
} catch (int e) { } catch (int e) {
...@@ -293,7 +293,9 @@ int MainMenu::main () { ...@@ -293,7 +293,9 @@ int MainMenu::main () {
} }
delete level; delete level;
baseLevel = level = NULL;
delete[] players; delete[] players;
localPlayer = NULL; localPlayer = NULL;
......
...@@ -129,6 +129,8 @@ int Menu::textInput (const char* request, char*& text) { ...@@ -129,6 +129,8 @@ int Menu::textInput (const char* request, char*& text) {
int count, terminate, character, x; int count, terminate, character, x;
unsigned int cursor; unsigned int cursor;
video.setPalette(menuPalette);
// Create input string // Create input string
input = createEditableString(text); input = createEditableString(text);
......
...@@ -60,6 +60,7 @@ class GameMenu : public Menu { ...@@ -60,6 +60,7 @@ class GameMenu : public Menu {
int episodes; int episodes;
unsigned char difficulty; unsigned char difficulty;
int newGameDifficulty (GameModeType mode, char* firstLevel);
int newGameDifficulty (GameModeType mode, int levelNum, int worldNum); int newGameDifficulty (GameModeType mode, int levelNum, int worldNum);
int newGameLevel (GameModeType mode); int newGameLevel (GameModeType mode);
int newGameEpisode (GameModeType mode); int newGameEpisode (GameModeType mode);
......
...@@ -506,8 +506,7 @@ int SetupMenu::setup () { ...@@ -506,8 +506,7 @@ int SetupMenu::setup () {
const char *setupOptions[6] = {"character", "keyboard", "joystick", "resolution", "scaling", "sound"}; const char *setupOptions[6] = {"character", "keyboard", "joystick", "resolution", "scaling", "sound"};
const char *setupCharacterOptions[5] = {"name", "fur", "bandana", "gun", "wristband"}; const char *setupCharacterOptions[5] = {"name", "fur", "bandana", "gun", "wristband"};
const char *setupCharacterColOptions[8] = {"white", "red", "orange", "yellow", "green", "blue", "animation 1", "animation 2"}; const char *setupCharacterColOptions[8] = {"white", "red", "orange", "yellow", "green", "blue", "animation 1", "animation 2"};
const unsigned char setupCharacterCols[8] = {PC_WHITE, PC_RED, PC_ORANGE, const unsigned char setupCharacterCols[8] = {PC_GREY, PC_RED, PC_ORANGE, PC_YELLOW, PC_LGREEN, PC_BLUE, PC_SANIM, PC_LANIM};
PC_YELLOW, PC_LGREEN, PC_BLUE, PC_SANIM, PC_LANIM};
int ret; int ret;
int option, suboption, subsuboption; int option, suboption, subsuboption;
...@@ -549,8 +548,7 @@ int SetupMenu::setup () { ...@@ -549,8 +548,7 @@ int SetupMenu::setup () {
if (ret == E_QUIT) return E_QUIT; if (ret == E_QUIT) return E_QUIT;
if (ret == E_NONE) if (ret == E_NONE)
characterCols[suboption - 1] = characterCols[suboption - 1] = setupCharacterCols[subsuboption];
setupCharacterCols[subsuboption];
break; break;
......
...@@ -39,6 +39,9 @@ ...@@ -39,6 +39,9 @@
BonusPlayer::BonusPlayer (Player* parent, char *newAnims, unsigned char startX, unsigned char startY) { BonusPlayer::BonusPlayer (Player* parent, char *newAnims, unsigned char startX, unsigned char startY) {
int count;
player = parent; player = parent;
memcpy(anims, newAnims, PANIMS); memcpy(anims, newAnims, PANIMS);
...@@ -50,6 +53,15 @@ BonusPlayer::BonusPlayer (Player* parent, char *newAnims, unsigned char startX, ...@@ -50,6 +53,15 @@ BonusPlayer::BonusPlayer (Player* parent, char *newAnims, unsigned char startX,
dr = 0; dr = 0;
gems = 0; gems = 0;
// Create the player's palette
for (count = 0; count < 256; count++)
palette[count].r = palette[count].g = palette[count].b = count;
// TODO: Custom colours
return; return;
} }
......
...@@ -60,6 +60,7 @@ class Bonus; ...@@ -60,6 +60,7 @@ class Bonus;
class BonusPlayer { class BonusPlayer {
private: private:
SDL_Color palette[256];
char anims[PANIMS]; char anims[PANIMS];
fixed x, y, direction, dr; fixed x, y, direction, dr;
unsigned char animType; unsigned char animType;
......
/*
*
* jj2levelplayer.cpp
*
* 29th June 2010: Created jj2levelplayer.cpp from parts of levelplayer.cpp
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2010 Alister Thomson
*
* OpenJazz is distributed under the terms of
* the GNU General Public License, version 2.0
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
/*
* Deals with the creation and destruction of players in levels, and their
* interactions with other level objects.
*
*/
#include "jj2levelplayer.h"
#include "game/game.h"
#include "game/gamemode.h"
#include "io/sound.h"
#include "jj2level/jj2level.h"
#include <string.h>
JJ2LevelPlayer::JJ2LevelPlayer (Player* parent, char* newAnims, unsigned char startX, unsigned char startY, bool hasBird) {
int offsets[14] = {JJ2PCO_GREY, JJ2PCO_SGREEN, JJ2PCO_BLUE, JJ2PCO_RED,
JJ2PCO_LGREEN, JJ2PCO_LEVEL1, JJ2PCO_YELLOW, JJ2PCO_LEVEL2,
JJ2PCO_ORANGE, JJ2PCO_LEVEL3, JJ2PCO_LEVEL4, JJ2PCO_SANIM, JJ2PCO_LANIM,
JJ2PCO_LEVEL5};
int lengths[14] = {JJ2PCL_GREY, JJ2PCL_SGREEN, JJ2PCL_BLUE, JJ2PCL_RED,
JJ2PCL_LGREEN, JJ2PCL_LEVEL1, JJ2PCL_YELLOW, JJ2PCL_LEVEL2,
JJ2PCL_ORANGE, JJ2PCL_LEVEL3, JJ2PCL_LEVEL4, JJ2PCL_SANIM, JJ2PCL_LANIM,
JJ2PCL_LEVEL5};
int count, start, length;
player = parent;
if (newAnims) memcpy(anims, newAnims, PANIMS);
else memset(anims, 0, PANIMS);
bird = hasBird;
shield = JJ2S_NONE;
reset(startX, startY);
// Create the player's palette
for (count = 0; count < 256; count++)
palette[count].r = palette[count].g = palette[count].b = count;
// Fur colours
start = offsets[player->cols[0]];
length = lengths[player->cols[0]];
for (count = 0; count < 16; count++)
palette[count + 48].r = palette[count + 48].g = palette[count + 48].b =
(count * length / 16) + start;
// Bandana colours
start = offsets[player->cols[1]];
length = lengths[player->cols[1]];
for (count = 0; count < 16; count++)
palette[count + 32].r = palette[count + 32].g = palette[count + 32].b =
(count * length / 16) + start;
// Gun colours
start = offsets[player->cols[2]];
length = lengths[player->cols[2]];
for (count = 0; count < 9; count++)
palette[count + 23].r = palette[count + 23].g = palette[count + 23].b =
(count * length / 9) + start;
// Wristband colours
start = offsets[player->cols[3]];
length = lengths[player->cols[3]];
for (count = 0; count < 8; count++)
palette[count + 88].r = palette[count + 88].g = palette[count + 88].b =
(count * length / 8) + start;
// Fix creepy black eyes
for (count = 0; count < 16; count++)
palette[count].r = palette[count].g = palette[count].b = (count >> 1) + 64;
return;
}
JJ2LevelPlayer::~JJ2LevelPlayer () {
return;
}
void JJ2LevelPlayer::reset (unsigned char startX, unsigned char startY) {
energy = 5;
floating = false;
facing = true;
reaction = JJ2PR_NONE;
reactionTime = 0;
jumpHeight = ITOF(92);
jumpY = TTOF(256);
fastFeetTime = 0;
warpTime = 0;
dx = 0;
dy = 0;
x = TTOF(startX);
y = TTOF(startY);
gems[0] = gems[1] = gems[2] = gems[3] = 0;
return;
}
void JJ2LevelPlayer::addGem (int colour) {
gems[colour]++;
return;
}
unsigned char JJ2LevelPlayer::getAnim () {
return anims[animType];
}
int JJ2LevelPlayer::getEnergy () {
return energy;
}
bool JJ2LevelPlayer::getFacing () {
return facing;
}
int JJ2LevelPlayer::getGems (int colour) {
return gems[colour];
}
bool JJ2LevelPlayer::hasBird () {
return bird;
}
bool JJ2LevelPlayer::hit (Player *source, unsigned int ticks) {
// Invulnerable if reacting to e.g. having been hit
if (reaction != JJ2PR_NONE) return false;
// Hits from the same team have no effect
if (source && (source->getTeam() == player->team)) return false;
if (!gameMode || gameMode->hit(source, player)) {
energy--;
//if (bird) bird->hit();
playSound(S_OW);
}
if (energy) {
reaction = JJ2PR_HURT;
reactionTime = ticks + PRT_HURT;
if (dx < 0) {
dx = PXS_RUN;
dy = PYS_JUMP;
} else {
dx = -PXS_RUN;
dy = PYS_JUMP;
}
} else {
kill(source, ticks);
}
return true;
}
void JJ2LevelPlayer::kill (Player *source, unsigned int ticks) {
if (reaction != JJ2PR_NONE) return;
if (!gameMode || gameMode->kill(source, player)) {
energy = 0;
player->lives--;
reaction = JJ2PR_KILLED;
reactionTime = ticks + PRT_KILLED;
}
return;
}
bool JJ2LevelPlayer::overlap (fixed left, fixed top, fixed width, fixed height) {
return (x + PXO_R >= left) && (x + PXO_L < left + width) &&
(y >= top) && (y + PYO_TOP < top + height);
}
JJ2PlayerReaction JJ2LevelPlayer::reacted (unsigned int ticks) {
JJ2PlayerReaction oldReaction;
if ((reaction != JJ2PR_NONE) && (reactionTime < ticks)) {
oldReaction = reaction;
reaction = JJ2PR_NONE;
return oldReaction;
}
return JJ2PR_NONE;
}
void JJ2LevelPlayer::setPosition (fixed newX, fixed newY) {
x = newX;
y = newY;
return;
}
void JJ2LevelPlayer::setSpeed (fixed newDx, fixed newDy) {
dx = newDx;
if (newDy) dy = newDy;
return;
}
bool JJ2LevelPlayer::takeEvent (unsigned char gridX, unsigned char gridY, unsigned int ticks) {
return true;
}
bool JJ2LevelPlayer::touchEvent (unsigned char gridX, unsigned char gridY, unsigned int ticks, int msps) {
return false;
}
void JJ2LevelPlayer::send (unsigned char *buffer) {
// Copy data to be sent to clients/server
buffer[9] = bird? 1: 0;
buffer[23] = energy;
buffer[25] = shield;
buffer[26] = floating;
buffer[27] = getFacing();
buffer[29] = jumpHeight >> 24;
buffer[30] = (jumpHeight >> 16) & 255;
buffer[31] = (jumpHeight >> 8) & 255;
buffer[32] = jumpHeight & 255;
buffer[33] = jumpY >> 24;
buffer[34] = (jumpY >> 16) & 255;
buffer[35] = (jumpY >> 8) & 255;
buffer[36] = jumpY & 255;
buffer[37] = x >> 24;
buffer[38] = (x >> 16) & 255;
buffer[39] = (x >> 8) & 255;
buffer[40] = x & 255;
buffer[41] = y >> 24;
buffer[42] = (y >> 16) & 255;
buffer[43] = (y >> 8) & 255;
buffer[44] = y & 255;
return;
}
void JJ2LevelPlayer::receive (unsigned char *buffer) {
// Interpret data received from client/server
switch (buffer[1]) {
case MT_P_ANIMS:
memcpy(anims, (char *)buffer + 3, PANIMS);
break;
case MT_P_TEMP:
if ((buffer[9] & 1) && !bird) bird = true;
if (!(buffer[9] & 1) && bird) {
bird = false;
}
energy = buffer[23];
shield = (JJ2Shield)buffer[25];
floating = buffer[26];
facing = buffer[27];
jumpHeight = (buffer[29] << 24) + (buffer[30] << 16) + (buffer[31] << 8) + buffer[32];
jumpY = (buffer[33] << 24) + (buffer[34] << 16) + (buffer[35] << 8) + buffer[36];
x = (buffer[37] << 24) + (buffer[38] << 16) + (buffer[39] << 8) + buffer[40];
y = (buffer[41] << 24) + (buffer[42] << 16) + (buffer[43] << 8) + buffer[44];
break;
}
return;
}
/*
*
* jj2levelplayer.h
*
* 29th June 2010: Created jj2levelplayer.h from parts of levelplayer.h
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2010 Alister Thomson
*
* OpenJazz is distributed under the terms of
* the GNU General Public License, version 2.0
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
/* "Tile" is a flexible term. Here it is used to refer specifically to the
individual elements of the tile set.
"Tiles" in the context of level units are referred to as grid elements. */
#ifndef _JJ2LEVELPLAYER_H
#define _JJ2LEVELPLAYER_H
#include "player.h"
#include "level/movable.h"
#include "OpenJazz.h"
#include <SDL/SDL.h>
// Constants
// Colour offsets
#define JJ2PCO_GREY 72
#define JJ2PCO_SGREEN 16
#define JJ2PCO_BLUE 35
#define JJ2PCO_RED 24
#define JJ2PCO_LGREEN 16
#define JJ2PCO_LEVEL1 96
#define JJ2PCO_YELLOW 59
#define JJ2PCO_LEVEL2 112
#define JJ2PCO_ORANGE 43
#define JJ2PCO_LEVEL3 128
#define JJ2PCO_LEVEL4 144
#define JJ2PCO_SANIM 160
#define JJ2PCO_LANIM 176
#define JJ2PCO_LEVEL5 208
// Colour lengths
#define JJ2PCL_GREY 8
#define JJ2PCL_SGREEN 8
#define JJ2PCL_BLUE 5
#define JJ2PCL_RED 8
#define JJ2PCL_LGREEN 8
#define JJ2PCL_LEVEL1 16
#define JJ2PCL_YELLOW 5
#define JJ2PCL_LEVEL2 16
#define JJ2PCL_ORANGE 5
#define JJ2PCL_LEVEL3 16
#define JJ2PCL_LEVEL4 16
#define JJ2PCL_SANIM 16
#define JJ2PCL_LANIM 32
#define JJ2PCL_LEVEL5 16
// Animations
#define PA_LWALK 0
#define PA_RWALK 1
#define PA_LJUMP 2
#define PA_RJUMP 3
#define PA_LSPIN 4
#define PA_RSPIN 5
#define PA_LSHOOT 6
#define PA_RSHOOT 7
#define PA_LCROUCH 8
#define PA_RCROUCH 9
#define PA_LFALL 10
#define PA_RFALL 11
#define PA_LHURT 12
#define PA_RHURT 13
#define PA_LLEAN 14
#define PA_RLEAN 15
#define PA_LBOARD 16
#define PA_RBOARD 17
#define PA_LSTAND 18
#define PA_RSTAND 19
#define PA_LEAT 20
#define PA_REAT 21
#define PA_LEDGE 22
#define PA_REDGE 23
#define PA_LOOKUP 24
#define PA_LOOKDOWN 25
#define PA_LSWIM 26
#define PA_RSWIM 27
#define PA_LRUN 28
#define PA_RRUN 29
#define PA_LDIE 30
#define PA_RDIE 31
#define PA_LSTOP 32
#define PA_RSTOP 33
#define PA_LHALT 34 /* Yeah, I was wondering the same thing... */
#define PA_RHALT 35
#define PA_RSPRING 36
#define PA_LSPRING 37 /* Surely these are the wrong way round? */
// Player reaction times
#define PRT_HURT 1000
#define PRT_HURTANIM 200
#define PRT_KILLED 2000
#define PRT_INVINCIBLE 10000
// Other time periods
#define T_FASTFEET 25000
#define T_WARP 1000
// Player offsets
#define PXO_MID F16
#define PXO_L (PXO_MID - F10)
#define PXO_ML (PXO_MID - F4)
#define PXO_MR (PXO_MID + F4)
#define PXO_R (PXO_MID + F10)
#define PYO_TOP (-F20)
#define PYO_MID (-F10)
// Player speeds
#define PXS_WALK ITOF(300)
#define PXS_RUN ITOF(325)
#define PXS_FFRUN ITOF(500)
#define PYS_FALL ITOF(350)
#define PYS_SINK ITOF(150)
#define PYS_JUMP ITOF(-350)
// Player accelerations
#define PXA_REVERSE 900
#define PXA_STOP 1000
#define PXA_WALK 500
#define PXA_RUN 200
#define PXA_FFRUN 200
#define PYA_GRAVITY 2750
#define PYA_SINK 1000
// Enum
enum JJ2PlayerReaction {
JJ2PR_NONE, JJ2PR_HURT, JJ2PR_KILLED, JJ2PR_INVINCIBLE
};
enum JJ2Shield {
JJ2S_NONE = 0, JJ2S_FLAME = 1, JJ2S_BUBBLE = 2, JJ2S_PLASMA = 3, JJ2S_LASER = 4
};
// Classes
class Anim;
class JJ2LevelPlayer : public Movable {
private:
bool bird; // Placeholder for eventual JJ2Bird object
SDL_Color palette[256];
char anims[PANIMS];
int energy;
JJ2Shield shield;
int floating; /* 0 = normal, 1 = helicopter ears, 2 = boarding */
bool facing;
unsigned char animType;
int lookTime; /* Negative if looking up, positive if looking down, 0 if neither */
JJ2PlayerReaction reaction;
unsigned int reactionTime;
unsigned int fireTime;
fixed jumpHeight;
fixed jumpY;
unsigned int fastFeetTime;
unsigned char warpX, warpY;
unsigned int warpTime;
int gems[4];
public:
Player* player;
JJ2LevelPlayer (Player* parent, char* newAnims, unsigned char startX, unsigned char startY, bool hasBird);
~JJ2LevelPlayer ();
void reset (unsigned char startX, unsigned char startY);
void addGem (int colour);
unsigned char getAnim ();
int getEnemies ();
int getEnergy ();
bool getFacing ();
int getGems (int colour);
bool hasBird ();
bool hit (Player* source, unsigned int ticks);
void kill (Player* source, unsigned int ticks);
bool overlap (fixed left, fixed top, fixed width, fixed height);
JJ2PlayerReaction reacted (unsigned int ticks);
void setPosition (fixed newX, fixed newY);
void setSpeed (fixed newDx, fixed newDy);
bool takeEvent (unsigned char gridX, unsigned char gridY, unsigned int ticks);
bool touchEvent (unsigned char gridX, unsigned char gridY, unsigned int ticks, int msps);
void send (unsigned char* buffer);
void receive (unsigned char* buffer);
void control (unsigned int ticks, int msps);
void move (unsigned int ticks, int msps);
void view (unsigned int ticks, int mspf);
void draw (unsigned int ticks, int change);
};
#endif
This diff is collapsed.
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
* levelplayer.cpp * levelplayer.cpp
* *
* 24th June 2010: Created levelplayer.cpp from parts of player.cpp * 24th June 2010: Created levelplayer.cpp from parts of player.cpp
* 29th June 2010: Created jj2levelplayer.cpp from parts of levelplayer.cpp
* *
* Part of the OpenJazz project * Part of the OpenJazz project
* *
...@@ -40,6 +41,12 @@ ...@@ -40,6 +41,12 @@
LevelPlayer::LevelPlayer (Player* parent, char* newAnims, unsigned char startX, unsigned char startY, bool hasBird) { LevelPlayer::LevelPlayer (Player* parent, char* newAnims, unsigned char startX, unsigned char startY, bool hasBird) {
int offsets[15] = {PCO_GREY, PCO_SGREEN, PCO_BLUE, PCO_RED, PCO_LGREEN,
PCO_LEVEL1, PCO_YELLOW, PCO_LEVEL2, PCO_ORANGE, PCO_LEVEL3, PCO_LEVEL4,
PCO_SANIM, PCO_LANIM, PCO_LEVEL5, 256};
int count, start, length;
player = parent; player = parent;
if (newAnims) memcpy(anims, newAnims, PANIMS); if (newAnims) memcpy(anims, newAnims, PANIMS);
...@@ -54,6 +61,53 @@ LevelPlayer::LevelPlayer (Player* parent, char* newAnims, unsigned char startX, ...@@ -54,6 +61,53 @@ LevelPlayer::LevelPlayer (Player* parent, char* newAnims, unsigned char startX,
reset(startX, startY); reset(startX, startY);
// Create the player's palette
for (count = 0; count < 256; count++)
palette[count].r = palette[count].g = palette[count].b = count;
// Fur colours
start = offsets[player->cols[0]];
length = offsets[player->cols[0] + 1] - start;
for (count = 0; count < 16; count++)
palette[count + 48].r = palette[count + 48].g = palette[count + 48].b =
(count * length / 16) + start;
// Bandana colours
start = offsets[player->cols[1]];
length = offsets[player->cols[1] + 1] - start;
for (count = 0; count < 16; count++)
palette[count + 32].r = palette[count + 32].g = palette[count + 32].b =
(count * length / 16) + start;
// Gun colours
start = offsets[player->cols[2]];
length = offsets[player->cols[2] + 1] - start;
for (count = 0; count < 9; count++)
palette[count + 23].r = palette[count + 23].g = palette[count + 23].b =
(count * length / 9) + start;
// Wristband colours
start = offsets[player->cols[3]];
length = offsets[player->cols[3] + 1] - start;
for (count = 0; count < 8; count++)
palette[count + 88].r = palette[count + 88].g = palette[count + 88].b =
(count * length / 8) + start;
return; return;
} }
...@@ -159,18 +213,18 @@ bool LevelPlayer::hasGem () { ...@@ -159,18 +213,18 @@ bool LevelPlayer::hasGem () {
} }
bool LevelPlayer::hit (LevelPlayer *source, unsigned int ticks) { bool LevelPlayer::hit (Player *source, unsigned int ticks) {
// Invulnerable if reacting to e.g. having been hit // Invulnerable if reacting to e.g. having been hit
if (reaction != PR_NONE) return false; if (reaction != PR_NONE) return false;
// Hits from the same team have no effect // Hits from the same team have no effect
if (source && (source->player->getTeam() == player->team)) return false; if (source && (source->getTeam() == player->team)) return false;
if (shield == 3) shield = 0; if (shield == 3) shield = 0;
else if (shield) shield--; else if (shield) shield--;
else if (!gameMode || gameMode->hit(source, this)) { else if (!gameMode || gameMode->hit(source, player)) {
energy--; energy--;
...@@ -208,11 +262,11 @@ bool LevelPlayer::hit (LevelPlayer *source, unsigned int ticks) { ...@@ -208,11 +262,11 @@ bool LevelPlayer::hit (LevelPlayer *source, unsigned int ticks) {
} }
void LevelPlayer::kill (LevelPlayer *source, unsigned int ticks) { void LevelPlayer::kill (Player *source, unsigned int ticks) {
if (reaction != PR_NONE) return; if (reaction != PR_NONE) return;
if (!gameMode || gameMode->kill(source, this)) { if (!gameMode || gameMode->kill(source, player)) {
energy = 0; energy = 0;
player->lives--; player->lives--;
...@@ -324,7 +378,7 @@ bool LevelPlayer::takeEvent (unsigned char gridX, unsigned char gridY, unsigned ...@@ -324,7 +378,7 @@ bool LevelPlayer::takeEvent (unsigned char gridX, unsigned char gridY, unsigned
level->setStage(LS_END); level->setStage(LS_END);
} else if (!(gameMode->endOfLevel(this, gridX, gridY))) return false; } else if (!(gameMode->endOfLevel(player, gridX, gridY))) return false;
break; break;
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
* levelplayer.h * levelplayer.h
* *
* 24th June 2010: Created levelplayer.h from parts of player.h * 24th June 2010: Created levelplayer.h from parts of player.h
* 29th June 2010: Created jj2levelplayer.h from parts of levelplayer.h
* *
* Part of the OpenJazz project * Part of the OpenJazz project
* *
...@@ -39,6 +40,22 @@ ...@@ -39,6 +40,22 @@
// Constants // Constants
// Colour offsets
#define PCO_GREY 0
#define PCO_SGREEN 16
#define PCO_BLUE 23
#define PCO_RED 32
#define PCO_LGREEN 48
#define PCO_LEVEL1 64
#define PCO_YELLOW 75
#define PCO_LEVEL2 80
#define PCO_ORANGE 88
#define PCO_LEVEL3 96
#define PCO_LEVEL4 104
#define PCO_SANIM 112
#define PCO_LANIM 116
#define PCO_LEVEL5 124
// Animations // Animations
#define PA_LWALK 0 #define PA_LWALK 0
#define PA_RWALK 1 #define PA_RWALK 1
...@@ -134,6 +151,7 @@ class LevelPlayer : public Movable { ...@@ -134,6 +151,7 @@ class LevelPlayer : public Movable {
private: private:
Bird* bird; Bird* bird;
SDL_Color palette[256];
char anims[PANIMS]; char anims[PANIMS];
int energy; int energy;
int shield; /* 0 = none, 1 = 1 yellow, 2 = 2 yellow, 3 = 1 orange, 4 = 2 orange, 5 = 3 orange, 6 = 4 orange */ int shield; /* 0 = none, 1 = 1 yellow, 2 = 2 yellow, 3 = 1 orange, 4 = 2 orange, 5 = 3 orange, 6 = 4 orange */
...@@ -172,8 +190,8 @@ class LevelPlayer : public Movable { ...@@ -172,8 +190,8 @@ class LevelPlayer : public Movable {
int getItems (); int getItems ();
bool hasBird (); bool hasBird ();
bool hasGem (); bool hasGem ();
bool hit (LevelPlayer* source, unsigned int ticks); bool hit (Player* source, unsigned int ticks);
void kill (LevelPlayer* source, unsigned int ticks); void kill (Player* source, unsigned int ticks);
bool overlap (fixed left, fixed top, fixed width, fixed height); bool overlap (fixed left, fixed top, fixed width, fixed height);
PlayerReaction reacted (unsigned int ticks); PlayerReaction reacted (unsigned int ticks);
void setEvent (unsigned char gridX, unsigned char gridY); void setEvent (unsigned char gridX, unsigned char gridY);
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
* *
* 18th July 2009: Created playerframe.cpp from parts of player.cpp * 18th July 2009: Created playerframe.cpp from parts of player.cpp
* 24th June 2010: Renamed playerframe.cpp to levelplayerframe.cpp * 24th June 2010: Renamed playerframe.cpp to levelplayerframe.cpp
* 29th June 2010: Created jj2levelplayerframe.cpp from parts of
* levelplayerframe.cpp
* *
* Part of the OpenJazz project * Part of the OpenJazz project
* *
...@@ -703,8 +705,8 @@ void LevelPlayer::draw (unsigned int ticks, int change) { ...@@ -703,8 +705,8 @@ void LevelPlayer::draw (unsigned int ticks, int change) {
else { else {
an->setPalette(player->palette, 23, 41); an->setPalette(palette, 23, 41);
an->setPalette(player->palette, 88, 8); an->setPalette(palette, 88, 8);
} }
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "bird.h" #include "bird.h"
#include "bonusplayer.h" #include "bonusplayer.h"
#include "jj2levelplayer.h"
#include "levelplayer.h" #include "levelplayer.h"
#include "baselevel.h" #include "baselevel.h"
...@@ -48,6 +49,7 @@ Player::Player () { ...@@ -48,6 +49,7 @@ Player::Player () {
levelPlayer = NULL; levelPlayer = NULL;
bonusPlayer = NULL; bonusPlayer = NULL;
jj2LevelPlayer = NULL;
name = NULL; name = NULL;
...@@ -67,11 +69,6 @@ Player::~Player () { ...@@ -67,11 +69,6 @@ Player::~Player () {
void Player::init (char *playerName, unsigned char *playerCols, unsigned char newTeam) { void Player::init (char *playerName, unsigned char *playerCols, unsigned char newTeam) {
int offsets[15] = {PC_WHITE, PC_SGREEN, PC_BLUE, PC_RED, PC_LGREEN,
PC_LEVEL1, PC_YELLOW, PC_LEVEL2, PC_ORANGE, PC_LEVEL3, PC_LEVEL4,
PC_SANIM, PC_LANIM, PC_LEVEL5, 256};
int count, start, length;
// Clear existing player // Clear existing player
deinit(); deinit();
...@@ -91,72 +88,19 @@ void Player::init (char *playerName, unsigned char *playerCols, unsigned char ne ...@@ -91,72 +88,19 @@ void Player::init (char *playerName, unsigned char *playerCols, unsigned char ne
team = newTeam; team = newTeam;
teamScore = 0; teamScore = 0;
if (playerCols) {
// Create the player's palette
memcpy(cols, playerCols, PCOLOURS);
for (count = 0; count < 256; count++)
palette[count].r = palette[count].g = palette[count].b = count; } else {
if (playerCols == NULL) return; cols[0] = CHAR_FUR;
cols[1] = CHAR_BAND;
memcpy(cols, playerCols, 4); cols[2] = CHAR_GUN;
cols[3] = CHAR_WBAND;
// Fur colours
}
count = 0;
while (cols[0] >= offsets[count + 1]) count++;
start = offsets[count];
length = offsets[count + 1] - start;
for (count = 0; count < 16; count++)
palette[count + 48].r = palette[count + 48].g = palette[count + 48].b =
(count * length / 16) + start;
// Bandana colours
count = 0;
while (cols[1] >= offsets[count + 1]) count++;
start = offsets[count];
length = offsets[count + 1] - start;
for (count = 0; count < 16; count++)
palette[count + 32].r = palette[count + 32].g = palette[count + 32].b =
(count * length / 16) + start;
// Gun colours
count = 0;
while (cols[2] >= offsets[count + 1]) count++;
start = offsets[count];
length = offsets[count + 1] - start;
for (count = 0; count < 9; count++)
palette[count + 23].r = palette[count + 23].g = palette[count + 23].b =
(count * length / 9) + start;
// Wristband colours
count = 0;
while (cols[3] >= offsets[count + 1]) count++;
start = offsets[count];
length = offsets[count + 1] - start;
for (count = 0; count < 8; count++)
palette[count + 88].r = palette[count + 88].g = palette[count + 88].b =
(count * length / 8) + start;
return; return;
} }
...@@ -166,8 +110,10 @@ void Player::deinit () { ...@@ -166,8 +110,10 @@ void Player::deinit () {
if (levelPlayer) delete levelPlayer; if (levelPlayer) delete levelPlayer;
if (bonusPlayer) delete bonusPlayer; if (bonusPlayer) delete bonusPlayer;
if (jj2LevelPlayer) delete levelPlayer;
levelPlayer = NULL; levelPlayer = NULL;
bonusPlayer = NULL; bonusPlayer = NULL;
jj2LevelPlayer = NULL;
if (name) delete[] name; if (name) delete[] name;
name = NULL; name = NULL;
...@@ -177,7 +123,16 @@ void Player::deinit () { ...@@ -177,7 +123,16 @@ void Player::deinit () {
} }
void Player::reset (bool bonus, char* newAnims, unsigned char x, unsigned char y) { void Player::reset (unsigned char x, unsigned char y) {
if (levelPlayer) levelPlayer->reset(x, y);
return;
}
void Player::reset (LevelType levelType, char* newAnims, unsigned char x, unsigned char y) {
int count; int count;
...@@ -185,20 +140,44 @@ void Player::reset (bool bonus, char* newAnims, unsigned char x, unsigned char y ...@@ -185,20 +140,44 @@ void Player::reset (bool bonus, char* newAnims, unsigned char x, unsigned char y
bird = levelPlayer->hasBird(); bird = levelPlayer->hasBird();
delete levelPlayer; delete levelPlayer;
levelPlayer = NULL;
} }
if (bonusPlayer) delete bonusPlayer; if (bonusPlayer) {
if (bonus) { delete bonusPlayer;
bonusPlayer = NULL;
levelPlayer = NULL; }
bonusPlayer = new BonusPlayer(this, newAnims, x, y);
} else { if (jj2LevelPlayer) {
levelPlayer = new LevelPlayer(this, newAnims, x, y, bird); bird = jj2LevelPlayer->hasBird();
bonusPlayer = NULL; delete jj2LevelPlayer;
jj2LevelPlayer = NULL;
}
switch (levelType) {
case LT_LEVEL:
levelPlayer = new LevelPlayer(this, newAnims, x, y, bird);
break;
case LT_BONUS:
bonusPlayer = new BonusPlayer(this, newAnims, x, y);
break;
case LT_JJ2LEVEL:
jj2LevelPlayer = new JJ2LevelPlayer(this, newAnims, x, y, bird);
break;
} }
...@@ -230,6 +209,13 @@ char * Player::getName () { ...@@ -230,6 +209,13 @@ char * Player::getName () {
} }
JJ2LevelPlayer* Player::getJJ2LevelPlayer () {
return jj2LevelPlayer;
}
LevelPlayer* Player::getLevelPlayer () { LevelPlayer* Player::getLevelPlayer () {
return levelPlayer; return levelPlayer;
...@@ -337,6 +323,7 @@ void Player::send (unsigned char *buffer) { ...@@ -337,6 +323,7 @@ void Player::send (unsigned char *buffer) {
buffer[45] = pcontrols[C_SWIM]; buffer[45] = pcontrols[C_SWIM];
if (levelPlayer) levelPlayer->send(buffer); if (levelPlayer) levelPlayer->send(buffer);
if (jj2LevelPlayer) jj2LevelPlayer->send(buffer);
return; return;
...@@ -370,6 +357,7 @@ void Player::receive (unsigned char *buffer) { ...@@ -370,6 +357,7 @@ void Player::receive (unsigned char *buffer) {
} }
if (levelPlayer) levelPlayer->receive(buffer); if (levelPlayer) levelPlayer->receive(buffer);
if (jj2LevelPlayer) jj2LevelPlayer->receive(buffer);
return; return;
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment