Commit 53646b83 authored by alistert's avatar alistert

Added existing OpenJazz code.

parents
/*
*
* OpenJazz.h
*
* 23rd August 2005: Created OpenJazz.h
* 31st January 2006: Created level.h from parts of OpenJazz.h
* 31st January 2006: Created player.h from parts of OpenJazz.h
* 3rd February 2009: Created menu.h from parts of OpenJazz.h
* 3rd February 2009: Created file.h from parts of OpenJazz.h
* 3rd February 2009: Created font.h from parts of OpenJazz.h
* 4th February 2009: Created palette.h from parts of OpenJazz.h
* 2nd March 2009: Created network.h from parts of OpenJazz.h
* 2nd June 2009: Created sound.h from parts of OpenJazz.h
* 3rd June 2009: Created network.h from parts of OpenJazz.h
* 13th July 2009: Created controls.h from parts of OpenJazz.h
* 13th July 2009: Created graphics.h from parts of OpenJazz.h
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2009 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
*
*/
#ifndef _OPENJAZZ_H
#define _OPENJAZZ_H
#ifndef EXTERN
#define EXTERN extern
#endif
// Constants
// Numbers in -10 exponent fixed point
#define FE 128
#define FQ 256
#define FH 512
#define F1 1024
#define F2 2048
#define F4 4096
#define F8 8192
#define F10 10240
#define F12 12288
#define F16 16384
#define F20 20480
#define F24 24576
#define F32 32768
#define F36 36864
#define F40 40960
#define F80 81920
#define F64 65536
#define F100 102400
#define F160 163840
// File names
#define CONFIG_FILE "openjazz.cfg"
#define LOGO_FILE "openjazz.000"
#define LEVEL_FILE "openjazz.tmp"
#ifdef UPPERCASE_FILENAMES
#define F_MAINCHAR "MAINCHAR.000"
#define F_MENU "MENU.000"
#define F_PANEL "PANEL.000"
// File name formats
#define F_BLOCKS "BLOCKS"
#define F_LEVEL "LEVEL"
#define F_PLANET "PLANET"
#define F_SPRITES "SPRITES"
#else
#define F_MAINCHAR "mainchar.000"
#define F_MENU "menu.000"
#define F_PANEL "panel.000"
// File name formats
#define F_BLOCKS "blocks"
#define F_LEVEL "level"
#define F_PLANET "planet"
#define F_SPRITES "sprites"
#endif
// Standard string length
#define STRING_LENGTH 32
// Loop return type
#define NORMAL_LOOP 0
#define KEY_LOOP 1
#define JOYSTICK_LOOP 2
// Return values
#define E_DATA -14
#define E_VERSION -13
#define E_TIMEOUT -12
#define E_N_OTHER -11
#define E_N_CONNECT -10
#define E_N_ADDRESS -9
#define E_N_LISTEN -8
#define E_N_BIND -7
#define E_N_SOCKET -6
#define E_DEMOTYPE -5
#define E_FILE -4
#define E_VIDEO -3
#define E_UNUSED -2
#define E_QUIT -1
#define E_NONE 0
#define WON 1
#define LOST 2
#define JOYSTICKB 0x100
#define JOYSTICKANEG 0x200
#define JOYSTICKAPOS 0x300
// Time interval
#define T_FRAME 20
// Macros
// For fixed-point operations
#define FTOI(x) ((x) >> 10)
#define ITOF(x) ((x) << 10)
#define MUL(x, y) (((x) * (y)) >> 10)
#define DIV(x, y) (((x) << 10) / (y))
// Datatype
typedef int fixed;
// Variable
// Time
EXTERN unsigned int globalTicks;
// Functions in main.cpp
EXTERN int loop (int type);
// Functions in util.cpp
EXTERN bool fileExists (char *fileName);
EXTERN char * createString (char *string);
EXTERN char * createString (char *first, char *second);
EXTERN char * createFileName (char *type, int extension);
EXTERN char * createFileName (char *type, char *extension);
EXTERN char * createFileName (char *type, int level, int extension);
EXTERN char * createEditableString (char *string);
EXTERN void log (char *message);
EXTERN void log (char *message, char *detail);
EXTERN void log (char *message, int number);
EXTERN void logError (char *message, char *detail);
#endif
/*
*
* bonus.cpp
*
* 23rd August 2005: Created bonus.c
* 3rd February 2009: Renamed bonus.c to bonus.cpp
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2009 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 loading, running and freeing of bonus levels.
*
*/
#include "bonus.h"
#include "io/controls.h"
#include "io/file.h"
Bonus::Bonus (char * fileName) {
File *file;
try {
file = new File(fileName, false);
} catch (int e) {
throw e;
}
// TODO: Load bonus level data
delete file;
return;
}
Bonus::~Bonus () {
// Nothing to do
return;
}
int Bonus::play () {
while (true) {
if (loop(NORMAL_LOOP) == E_QUIT) return E_QUIT;
if (controls.release(C_ESCAPE)) return E_NONE;
// TODO: Bonus levels
}
return E_NONE;
}
/*
*
* bonus.h
*
* 3rd February 2009: Created bonus.h
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2009 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
*
*/
#ifndef _BONUS_H
#define _BONUS_H
// Class
class Bonus {
public:
Bonus (char * fileName);
~Bonus ();
int play ();
};
#endif
/*
*
* clientgame.cpp
*
* 18th July 2009: Created clientgame.cpp from parts of game.cpp
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2009 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
*
*/
#include "game.h"
#include "gamemode.h"
#include "io/controls.h"
#include "io/file.h"
#include "io/gfx/font.h"
#include "io/gfx/paletteeffects.h"
#include "io/gfx/video.h"
#include "io/network.h"
#include "level/level.h"
#include "menu/menu.h"
#include "player/player.h"
#include <string.h>
ClientGame::ClientGame (char *address) {
unsigned char buffer[BUFFER_LENGTH];
unsigned int timeout;
int count, ret, mode;
sock = net->join(address);
if (sock < 0) throw sock; // Tee hee hee hee hee.
// Receive initialisation message
count = 0;
timeout = globalTicks + T_SCHECK + T_TIMEOUT;
// Wait for whole message to arrive
while (count < MTL_G_PROPS) {
if (loop(NORMAL_LOOP) == E_QUIT) {
net->close(sock);
throw E_QUIT;
}
if (controls.release(C_ESCAPE)) {
net->close(sock);
throw E_UNUSED;
}
SDL_Delay(T_FRAME);
clearScreen(0);
fontmn2->showString("WAITING FOR REPLY", screenW >> 2,
(screenH >> 1) - 16);
ret = net->recv(sock, buffer + count, MTL_G_PROPS - count);
if (ret > 0) count += ret;
if (globalTicks > timeout) {
net->close(sock);
throw E_TIMEOUT;
}
}
// Make sure message is valid
if (buffer[1] != MT_G_PROPS) {
net->close(sock);
throw E_DATA;
} else if (buffer[2] != 1) {
net->close(sock);
throw E_VERSION;
}
printf("Connected to server (version %d).\n", buffer[2]);
// Copy game parameters
mode = buffer[3];
difficulty = buffer[4];
maxPlayers = buffer[5];
nPlayers = buffer[6];
clientID = buffer[7];
printf("Game mode %d, difficulty %d, %d of %d players.\n", mode,
difficulty, nPlayers, maxPlayers);
if (nPlayers > maxPlayers) {
net->close(sock);
throw E_DATA;
}
gameMode = createGameMode(mode);
if (gameMode == NULL) {
net->close(sock);
throw E_DATA;
}
// Create players
nPlayers = 0;
players = new Player[maxPlayers];
// Download the level from the server
level = NULL;
levelFile = createString(LEVEL_FILE);
file = NULL;
ret = setLevel(NULL);
if (ret < 0) {
net->close(sock);
if (file) delete file;
delete gameMode;
throw ret;
}
// Add a new player to the game
buffer[0] = MTL_G_PJOIN + strlen(characterName);
buffer[1] = MT_G_PJOIN;
buffer[2] = clientID;
buffer[3] = 0; // Player's number, assigned by the server
buffer[4] = 0; // Player's team, assigned by the server
memcpy(buffer + 5, characterCols, 4);
memcpy(buffer + 9, characterName, strlen(characterName) + 1);
send(buffer);
// Wait for acknowledgement
localPlayer = NULL;
while (!localPlayer) {
if (loop(NORMAL_LOOP) == E_QUIT) {
net->close(sock);
if (file) delete file;
delete gameMode;
throw E_QUIT;
}
if (controls.release(C_ESCAPE)) {
net->close(sock);
if (file) delete file;
delete gameMode;
throw E_UNUSED;
}
clearScreen(0);
fontmn2->showString("JOINING GAME", screenW >> 2, (screenH >> 1) - 16);
ret = playFrame(-1);
if (ret < 0) {
net->close(sock);
if (file) delete file;
delete gameMode;
throw ret;
}
}
return;
}
ClientGame::~ClientGame () {
net->close(sock);
if (file) delete file;
delete gameMode;
return;
}
int ClientGame::setLevel (char *fileName) {
int ret;
// Free the palette effects
if (firstPE) {
delete firstPE;
firstPE = NULL;
}
usePalette(menu->palettes[1]);
// Wait for level data to start arriving
while (!file && levelFile) {
if (loop(NORMAL_LOOP) == E_QUIT) return E_QUIT;
if (controls.release(C_ESCAPE)) return E_UNUSED;
SDL_Delay(T_FRAME);
clearScreen(0);
fontmn2->showString("WAITING FOR SERVER", screenW >> 2,
(screenH >> 1) - 16);
ret = playFrame(-1);
if (ret < 0) return ret;
}
// Wait for level data to finish arriving
while (file && levelFile) {
if (loop(NORMAL_LOOP) == E_QUIT) return E_QUIT;
if (controls.release(C_ESCAPE)) return E_UNUSED;
SDL_Delay(T_FRAME);
clearScreen(0);
fontmn2->showString("downloaded", screenW >> 2, (screenH >> 1) - 16);
fontmn2->showNumber(file->tell(), (screenW >> 2) + 56, screenH >> 1);
fontmn2->showString("bytes", (screenW >> 2) + 64, screenH >> 1);
ret = playFrame(-1);
if (ret < 0) return ret;
}
return E_NONE;
}
void ClientGame::send (unsigned char *buffer) {
net->send(sock, buffer);
return;
}
int ClientGame::playFrame (int ticks) {
unsigned char sendBuffer[BUFFER_LENGTH];
int length, count;
bool firstMessage;
// Receive data from server
if (received == 0) {
// Not currently receiving a message
// See if there is a new message to receive
length = net->recv(sock, recvBuffer, 1);
if (length > 0) received++;
}
if (received > 0) {
// Currently receiving a message
// See if there is any more data
length = net->recv(sock, recvBuffer + received,
recvBuffer[0] - received);
if (length > 0) received += length;
// See if the whole message has arrived
if (received >= recvBuffer[0]) {
switch (recvBuffer[1] & MCMASK) {
case MC_GAME:
if (recvBuffer[1] == MT_G_LEVEL) {
if (!file) {
// Not already storing level data, so open the file
try {
file = new File(levelFile, true);
} catch (int e) {
return e;
}
firstMessage = true;
} else firstMessage = false;
file->seek((recvBuffer[2] << 8) + recvBuffer[3], true);
for (count = 4; count < recvBuffer[0]; count++)
file->storeChar(recvBuffer[count]);
// If a zero-length block has been sent, it is the last
if (recvBuffer[0] == MTL_G_LEVEL) {
if (firstMessage) {
// If the last message was also the first,
// then the run of levels has ended
delete[] levelFile;
levelFile = NULL;
}
delete file;
file = NULL;
}
break;
}
if ((recvBuffer[1] == MT_G_PJOIN) &&
(recvBuffer[3] < maxPlayers)) {
printf("Player %d joined the game.\n", recvBuffer[3]);
// Add the new player, and any that have been missed
for (count = nPlayers; count <= recvBuffer[3]; count++)
{
players[count].init((char *)recvBuffer + 9,
recvBuffer + 5, recvBuffer[4]);
players[count].reset();
printf("Player %d joined team %d.\n",
count, recvBuffer[4]);
}
nPlayers = count;
if (recvBuffer[2] == clientID)
localPlayer = players + recvBuffer[3];
}
if ((recvBuffer[1] == MT_G_PQUIT) &&
(recvBuffer[2] < nPlayers)) {
printf("Player %d left the game.\n", recvBuffer[2]);
// Remove the player
players[recvBuffer[2]].deinit();
// If necessary, move more recent players
for (count = recvBuffer[2]; count < nPlayers; count++)
memcpy(players + count, players + count + 1,
sizeof(Player));
// Clear duplicate pointers
memset(players + nPlayers, 0, sizeof(Player));
}
if (recvBuffer[1] == MT_G_CHECK) {
checkX = recvBuffer[2];
checkY = recvBuffer[3];
}
if (recvBuffer[1] == MT_G_SCORE) {
for (count = 0; count < nPlayers; count++) {
if (players[count].getTeam() == recvBuffer[2])
players[count].teamScore++;
}
}
break;
case MC_LEVEL:
if (level) level->receive(recvBuffer);
break;
case MC_PLAYER:
if (recvBuffer[2] < maxPlayers)
players[recvBuffer[2]].receive(recvBuffer);
break;
}
received = 0;
}
}
if (ticks >= checkTime) {
// Check for disconnection
if (!(net->isConnected(sock))) {
if (file) delete file;
file = NULL;
return E_N_OTHER;
}
checkTime = ticks + T_CCHECK;
}
if (localPlayer && (ticks >= sendTime)) {
// Update server
sendBuffer[0] = MTL_P_TEMP;
sendBuffer[1] = MT_P_TEMP;
sendBuffer[2] = 0;
localPlayer->send(sendBuffer);
send(sendBuffer);
sendTime = ticks + T_CSEND;
}
return E_NONE;
}
void ClientGame::score (unsigned char team) {
unsigned char buffer[MTL_G_SCORE];
// Inform server
buffer[0] = MTL_G_SCORE;
buffer[1] = MT_G_SCORE;
buffer[2] = team;
send(buffer);
return;
}
void ClientGame::setCheckpoint (unsigned char gridX, unsigned char gridY) {
unsigned char buffer[MTL_G_CHECK];
if (gameMode) {
buffer[0] = MTL_G_CHECK;
buffer[1] = MT_G_CHECK;
buffer[2] = gridX;
buffer[3] = gridY;
send(buffer);
}
return;
}
/*
*
* game.cpp
*
* 9th March 2009: Created game.cpp from parts of menu.cpp and level.cpp
* 3rd June 2009: Created network.cpp from parts of game.cpp
* 18th July 2009: Created servergame.cpp from parts of game.cpp
* 18th July 2009: Created clientgame.cpp from parts of game.cpp
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2009 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
*
*/
#include "game.h"
#include "gamemode.h"
#include "io/controls.h"
#include "io/gfx/font.h"
#include "io/gfx/video.h"
#include "io/sound.h"
#include "level/level.h"
#include "player/player.h"
#include "scene.h"
Game::Game () {
levelFile = NULL;
players = NULL;
return;
}
Game::Game (char *firstLevel, int gameDifficulty) {
levelFile = createString(firstLevel);
difficulty = gameDifficulty;
gameMode = NULL;
// Create the player
nPlayers = 1;
localPlayer = players = new Player[1];
localPlayer->init(characterName, NULL, 0);
return;
}
Game::~Game () {
if (levelFile) delete[] levelFile;
if (players != NULL) delete[] players;
localPlayer = NULL;
return;
}
int Game::setLevel (char *fileName) {
if (levelFile) delete[] levelFile;
if (!fileName) levelFile = NULL;
else levelFile = createString(fileName);
return E_NONE;
}
int Game::play () {
Scene * scene;
bool checkpoint;
int ret;
checkpoint = false;
// Play the level(s)
while (true) {
sendTime = checkTime = 0;
// Load the level
try {
level = new Level(levelFile, difficulty, checkpoint);
} catch (int e) {
return e;
}
ret = level->play();
switch (ret) {
case E_NONE: // Quit game
delete level;
playMusic("menusng.psm");
return E_NONE;
case WON: // Completed level
// If there is no next level, load and play the cutscene
if (!levelFile) {
scene = level->createScene();
delete level;
scene->play();
delete scene;
return E_NONE;
}
// Do not use old level's checkpoint coordinates
checkpoint = false;
break;
case LOST: // Lost level
if (!localPlayer->getLives()) {
delete level;
return E_NONE; // Not really a success...
}
// Use checkpoint coordinates
checkpoint = true;
break;
default: // Error
delete level;
return ret;
}
// Unload the previous level
delete level;
}
return E_NONE;
}
void Game::view () {
// Move the viewport towards the exit sign
if (TTOF(checkX) > viewX + (viewW << 9) + (160 * mspf)) viewX += 160 * mspf;
else if (TTOF(checkX) < viewX + (viewW << 9) - (160 * mspf))
viewX -= 160 * mspf;
if (TTOF(checkY) > viewY + (viewH << 9) + (160 * mspf)) viewY += 160 * mspf;
else if (TTOF(checkY) < viewY + (viewH << 9) - (160 * mspf))
viewY -= 160 * mspf;
return;
}
void Game::send (unsigned char *buffer) {
// Do nothing
return;
}
int Game::playFrame (int ticks) {
// Do nothing
return E_NONE;
}
void Game::score (unsigned char team) {
// Do nothing
return;
}
void Game::setCheckpoint (unsigned char gridX, unsigned char gridY) {
checkX = gridX;
checkY = gridY;
return;
}
void Game::resetPlayer (Player *player) {
player->reset();
player->setPosition(TTOF(checkX), TTOF(checkY));
return;
}
/*
*
* game.h
*
* 2nd March 2009: Created network.h from parts of OpenJazz.h
* 9th February 2009: Renamed network.h to game.h
* 2nd August 2009: Created gamemode.h from parts of game.h
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2009 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
*
*/
#ifndef _GAME_H
#define _GAME_H
#include "io/network.h"
// Constants
// Time intervals
#define T_SSEND 20
#define T_SCHECK 1000
#define T_CSEND 10
#define T_CCHECK 1000
// Message categories and types
#define MCMASK 0xF0
#define MC_GAME 0x00
#define MC_LEVEL 0x10
#define MC_PLAYER 0x20
#define MT_G_PROPS 0x00 /* Game properties */
#define MT_G_PJOIN 0x01 /* New player joined */
#define MT_G_PQUIT 0x02 /* Player left */
#define MT_G_LEVEL 0x03 /* Level data */
#define MT_G_CHECK 0x04
#define MT_G_SCORE 0x05 /* Team scored a roast/lap/etc. */
#define MT_L_PROP 0x10 /* Level property */
#define MT_L_GRID 0x11 /* Change to gridElement */
#define MT_L_STAGE 0x12 /* Change in level stage */
#define MT_P_ANIMS 0x20 /* Player animations */
#define MT_P_TEMP 0x21 /* Temporary player properties, e.g. position */
// Minimum message lengths, including header
#define MTL_G_PROPS 8
#define MTL_G_PJOIN 10
#define MTL_G_PQUIT 3
#define MTL_G_LEVEL 4
#define MTL_G_CHECK 4
#define MTL_G_SCORE 3
#define MTL_L_PROP 5
#define MTL_L_GRID 6
#define MTL_L_STAGE 3
#define MTL_P_ANIMS (PANIMS + 3)
#define MTL_P_TEMP 45
#define BUFFER_LENGTH 255 /* Should always be big enough to hold any message */
// Classes
class File;
class Player;
class Game {
protected:
char *levelFile;
int difficulty;
int sendTime, checkTime;
unsigned char checkX, checkY;
Game ();
public:
Game (char *firstLevel, int gameDifficulty);
virtual ~Game ();
virtual int setLevel (char *fileName);
int play ();
void view ();
virtual void send (unsigned char *buffer);
virtual int playFrame (int ticks);
virtual void score (unsigned char team);
virtual void setCheckpoint (unsigned char gridX, unsigned char gridY);
void resetPlayer (Player *player);
};
class ServerGame : public Game {
private:
int clientStatus[MAX_CLIENTS]; /*
-2: Connected and operational
-1: Not connected
>=0: Number of bytes of the level that have been sent */
int clientPlayer[MAX_CLIENTS];
int clientSock[MAX_CLIENTS];
unsigned char recvBuffers[MAX_CLIENTS][BUFFER_LENGTH];
int received[MAX_CLIENTS];
unsigned char *levelData;
int levelSize;
int sock;
public:
ServerGame (int mode, char *firstLevel, int gameDifficulty);
~ServerGame ();
int setLevel (char *fileName);
void send (unsigned char *buffer);
int playFrame (int ticks);
void score (unsigned char team);
void setCheckpoint (unsigned char gridX, unsigned char gridY);
};
class ClientGame : public Game {
private:
File *file;
unsigned char recvBuffer[BUFFER_LENGTH];
int received;
int clientID;
int maxPlayers;
int sock;
public:
ClientGame (char *address);
~ClientGame ();
int setLevel (char *fileName);
void send (unsigned char *buffer);
int playFrame (int ticks);
void score (unsigned char team);
void setCheckpoint (unsigned char gridX, unsigned char gridY);
};
// Variable
EXTERN Game *game;
#endif
/*
*
* gamemode.cpp
*
* 2nd August 2009: Created gamemode.cpp from parts of servergame.cpp
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2009 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
*
*/
#include "game.h"
#include "gamemode.h"
#include "io/gfx/font.h"
#include "level/level.h"
#include "player/player.h"
bool GameMode::hit (Player *source, Player *victim) {
return true;
}
bool GameMode::kill (Player *source, Player *victim) {
if (source && (victim == localPlayer)) game->score(source->getTeam());
return true;
}
bool GameMode::endOfLevel (Player *player, unsigned char gridX,
unsigned char gridY) {
game->setCheckpoint(gridX, gridY);
level->setStage(LS_END);
return true;
}
void GameMode::outOfTime () {
return;
}
unsigned char CooperativeGameMode::chooseTeam () {
// All players are on the same team
return 0;
}
void CooperativeGameMode::drawScore () {
// Do nothing
return;
}
unsigned char FreeForAllGameMode::chooseTeam () {
// Every player is on a separate team
int count;
unsigned char team;
team = 1;
// Find a team number higher than any other
for (count = nPlayers - 1; count >= 0; count--) {
if (players[count].getTeam() > team)
team = players[count].getTeam() + 1;
}
return team;
}
void FreeForAllGameMode::drawScore () {
fontmn1->showNumber(localPlayer->teamScore, 64, 4);
return;
}
unsigned char TeamGameMode::chooseTeam () {
// Players are split between two teams
int count, difference;
// Calculate team imbalance
difference = 0;
for (count = 0; count < nPlayers; count++) {
if (players[count].getTeam()) difference++;
else difference--;
}
// Assign to the team with the least players
if (difference >= 0) return 0;
return 1;
}
void TeamGameMode::drawScore () {
fontmn1->showNumber(localPlayer->teamScore, 64, 4);
return;
}
int CoopGameMode::getMode () {
return M_COOP;
}
bool CoopGameMode::endOfLevel (Player *player, unsigned char gridX,
unsigned char gridY) {
game->setCheckpoint(gridX, gridY);
level->setStage(LS_END);
return true;
}
int BattleGameMode::getMode () {
return M_BATTLE;
}
int TeamBattleGameMode::getMode () {
return M_TEAMBATTLE;
}
int RaceGameMode::getMode () {
return M_RACE;
}
bool RaceGameMode::hit (Player *source, Player *victim) {
return false;
}
bool RaceGameMode::endOfLevel (Player *player, unsigned char gridX,
unsigned char gridY) {
if (player == localPlayer) game->score(player->getTeam());
game->resetPlayer(player);
return false;
}
GameMode * createGameMode (int mode) {
switch (mode) {
case M_COOP:
return new CoopGameMode();
case M_BATTLE:
return new BattleGameMode();
case M_TEAMBATTLE:
return new TeamBattleGameMode();
case M_RACE:
return new RaceGameMode();
}
return NULL;
}
/*
*
* gamemode.h
*
* 2nd August 2009: Created gamemode.h from parts of game.h
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2009 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
*
*/
#ifndef _GAMEMODE_H
#define _GAMEMODE_H
#include "io/network.h"
// Constants
// Game modes
#define M_SINGLE 0
#define M_COOP 1
#define M_BATTLE 2
#define M_TEAMBATTLE 3
#define M_RACE 4
#define MAX_PLAYERS (MAX_CLIENTS + 1)
// Classes
class Player;
class GameMode {
public:
virtual int getMode () = 0;
virtual unsigned char chooseTeam () = 0;
virtual void drawScore () = 0;
virtual bool hit (Player *source, Player *victim);
virtual bool kill (Player *source, Player *victim);
virtual bool endOfLevel (Player *player, unsigned char gridX,
unsigned char gridY);
virtual void outOfTime ();
};
class CooperativeGameMode : public GameMode {
public:
unsigned char chooseTeam ();
virtual void drawScore ();
};
class FreeForAllGameMode : public GameMode {
public:
unsigned char chooseTeam ();
virtual void drawScore ();
};
class TeamGameMode : public GameMode {
public:
unsigned char chooseTeam ();
virtual void drawScore ();
};
class CoopGameMode : public CooperativeGameMode {
public:
int getMode ();
bool endOfLevel (Player *player, unsigned char gridX,
unsigned char gridY);
};
class BattleGameMode : public FreeForAllGameMode {
private:
int targetKills;
public:
int getMode ();
};
class TeamBattleGameMode : public TeamGameMode {
private:
int targetKills;
public:
int getMode ();
};
class RaceGameMode : public FreeForAllGameMode {
private:
int targetLaps;
public:
int getMode ();
bool hit (Player *source, Player *victim);
bool endOfLevel (Player *player, unsigned char gridX,
unsigned char gridY);
};
// Variable
EXTERN GameMode *gameMode; // NULL for single-player games
// Function
GameMode * createGameMode (int mode);
#endif
This diff is collapsed.
/*
*
* controls.cpp
*
* 13th July 2009: Created controls.cpp from parts of main.cpp
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2009 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 input.
*
*/
#include "controls.h"
Controls::Controls () {
int count;
keys[C_UP].key = SDLK_UP;
keys[C_DOWN].key = SDLK_DOWN;
keys[C_LEFT].key = SDLK_LEFT;
keys[C_RIGHT].key = SDLK_RIGHT;
#ifdef WIN32
keys[C_JUMP].key = SDLK_RALT;
keys[C_FIRE].key = SDLK_SPACE;
#else
keys[C_JUMP].key = SDLK_SPACE;
keys[C_FIRE].key = SDLK_LALT;
#endif
keys[C_CHANGE].key = SDLK_RCTRL;
keys[C_ENTER].key = SDLK_RETURN;
keys[C_ESCAPE].key = SDLK_ESCAPE;
keys[C_STATS].key = SDLK_F9;
keys[C_PAUSE].key = SDLK_p;
buttons[C_UP].button = -1;
buttons[C_DOWN].button = -1;
buttons[C_LEFT].button = -1;
buttons[C_RIGHT].button = -1;
buttons[C_JUMP].button = 1;
buttons[C_FIRE].button = 0;
buttons[C_CHANGE].button = 3;
buttons[C_ENTER].button = 0;
buttons[C_ESCAPE].button = -1;
buttons[C_STATS].button = -1;
buttons[C_PAUSE].button = -1;
axes[C_UP].axis = 1;
axes[C_UP].direction = false;
axes[C_DOWN].axis = 1;
axes[C_DOWN].direction = true;
axes[C_LEFT].axis = 0;
axes[C_LEFT].direction = false;
axes[C_RIGHT].axis = 0;
axes[C_RIGHT].direction = true;
axes[C_JUMP].axis = -1;
axes[C_FIRE].axis = -1;
axes[C_CHANGE].axis = -1;
axes[C_ENTER].axis = -1;
axes[C_ESCAPE].axis = -1;
axes[C_STATS].axis = -1;
axes[C_PAUSE].axis = -1;
for (count = 0; count < CONTROLS; count++) {
controls[count].time = 0;
controls[count].state = false;
}
return;
}
void Controls::setKey (int control, int key) {
keys[control].key = key;
return;
}
void Controls::setButton (int control, int button) {
buttons[control].button = button;
return;
}
void Controls::setAxis (int control, int axis, bool direction) {
axes[control].axis = axis;
axes[control].direction = direction;
return;
}
int Controls::getKey (int control) {
return keys[control].key;
}
int Controls::getButton (int control) {
return buttons[control].button;
}
int Controls::getAxis (int control) {
return axes[control].axis;
}
int Controls::getAxisDirection (int control) {
return axes[control].direction;
}
int Controls::update (SDL_Event *event, int type) {
int count;
count = CONTROLS;
switch (event->type) {
case SDL_KEYDOWN:
for (count = 0; count < CONTROLS; count++)
if (event->key.keysym.sym == keys[count].key) {
keys[count].state = true;
break;
}
if (type == KEY_LOOP) return event->key.keysym.sym;
break;
case SDL_KEYUP:
for (count = 0; count < CONTROLS; count++)
if (event->key.keysym.sym == keys[count].key) {
keys[count].state = false;
break;
}
break;
case SDL_JOYBUTTONDOWN:
for (count = 0; count < CONTROLS; count++)
if (event->jbutton.button == buttons[count].button) {
buttons[count].state = true;
break;
}
if (type == JOYSTICK_LOOP) return JOYSTICKB | event->jbutton.button;
break;
case SDL_JOYBUTTONUP:
for (count = 0; count < CONTROLS; count++)
if (event->jbutton.button == buttons[count].button) {
buttons[count].state = false;
break;
}
break;
case SDL_JOYAXISMOTION:
for (count = 0; count < CONTROLS; count++)
if (event->jaxis.axis == axes[count].axis) {
if (!axes[count].direction &&
(event->jaxis.value < -16384)) {
axes[count].state = true;
break;
}
else if (axes[count].direction &&
(event->jaxis.value > 16384)) {
axes[count].state = true;
break;
}
else axes[count].state = false;
}
if (type == JOYSTICK_LOOP) {
if (event->jaxis.value < -16384)
return JOYSTICKANEG | event->jaxis.axis;
if (event->jaxis.value > 16384)
return JOYSTICKAPOS | event->jaxis.axis;
}
break;
}
if (count < CONTROLS) {
if (!(keys[count].state || buttons[count].state || axes[count].state)) {
controls[count].time = 0;
controls[count].state = false;
}
}
return E_NONE;
}
void Controls::loop () {
int count;
// Apply controls to universal control tracking
for (count = 0; count < CONTROLS; count++)
controls[count].state = (controls[count].time < globalTicks) &&
(keys[count].state || buttons[count].state || axes[count].state);
return;
}
bool Controls::getState (int control) {
return controls[control].state;
}
bool Controls::release (int control) {
if (!controls[control].state) return false;
controls[control].time = globalTicks + T_KEY;
controls[control].state = false;
return true;
}
/*
*
* controls.h
*
* 13th July 2009: Created controls.h from parts of OpenJazz.h
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2009 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
*
*/
#ifndef _INPUT_H
#define _INPUT_H
#include "OpenJazz.h"
#include <SDL/SDL.h>
// Constants
// Indexes for the keys / buttons / axes player controls arrays
#define C_UP 0
#define C_DOWN 1
#define C_LEFT 2
#define C_RIGHT 3
#define C_JUMP 4
#define C_FIRE 5
#define C_CHANGE 6 /* Change weapon */
#define C_ENTER 7
#define C_ESCAPE 8
#define C_STATS 9
#define C_PAUSE 10
// Size of those arrays
#define CONTROLS 11
// Time interval
#define T_KEY 500
// Class
class Controls {
private:
struct {
int key; // Keyboard key
bool state;
} keys[CONTROLS];
struct {
int button; // Joystick button
bool state;
} buttons[CONTROLS];
struct {
int axis; // Joystick axis
bool direction; // Axis direction
bool state;
} axes[CONTROLS];
struct {
unsigned int time; /* The time from which the control will respond
to being pressed */
bool state;
} controls[CONTROLS];
public:
Controls ();
void setKey (int control, int key);
void setButton (int control, int button);
void setAxis (int control, int axis, bool direction);
int getKey (int control);
int getButton (int control);
int getAxis (int control);
int getAxisDirection (int control);
int update (SDL_Event *event, int type);
void loop ();
bool getState (int control);
bool release (int control);
};
// Variable
EXTERN Controls controls;
#endif
/*
*
* file.cpp
*
* 3rd February 2009: Created file.cpp from parts of util.cpp
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2009 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
*
*/
#include "file.h"
#include "io/gfx/video.h"
File::File (char * fileName, bool write) {
// Open the file from the current directory
f = fopen(fileName, write ? "wb": "rb");
// If that succeeded, done
if (f) {
//log("Opened file", fileName);
filePath = createString(fileName);
return;
}
// Create the file path
filePath = createString(path, fileName);
// Open the file from the path
f = fopen(filePath, write ? "wb": "rb");
if (f == NULL) {
log("Could not open file", fileName);
delete[] filePath;
throw E_FILE;
}
//log("Opened file", filePath);
return;
}
File::~File () {
fclose(f);
//log("Closed file", filePath);
delete[] filePath;
return;
}
int File::getSize () {
int pos, size;
pos = ftell(f);
fseek(f, 0, SEEK_END);
size = ftell(f);
fseek(f, pos, SEEK_SET);
return size;
}
int File::tell () {
return ftell(f);
}
void File::seek (int offset, bool reset) {
fseek(f, offset, reset ? SEEK_SET: SEEK_CUR);
return;
}
unsigned char File::loadChar () {
return fgetc(f);
}
void File::storeChar (unsigned char val) {
fputc(val, f);
return;
}
unsigned short int File::loadShort () {
unsigned short int val;
val = fgetc(f);
val += fgetc(f) << 8;
return val;
}
void File::storeShort (unsigned short int val) {
fputc(val & 255, f);
fputc(val >> 8, f);
return;
}
signed long int File::loadInt () {
unsigned long int val;
val = fgetc(f);
val += fgetc(f) << 8;
val += fgetc(f) << 16;
val += fgetc(f) << 24;
return *((signed long int *)&val);
}
void File::storeInt (signed long int val) {
unsigned long int uval;
uval = *((unsigned long int *)&val);
fputc(uval & 255, f);
fputc((uval >> 8) & 255, f);
fputc((uval >> 16) & 255, f);
fputc(uval >> 24, f);
return;
}
unsigned char * File::loadBlock (int length) {
unsigned char *buffer;
buffer = new unsigned char[length];
fread(buffer, 1, length, f);
return buffer;
}
unsigned char * File::loadRLE (int length) {
unsigned char *buffer;
int rle, pos, byte, count, next;
// Determine the offset that follows the block
next = fgetc(f);
next += fgetc(f) << 8;
next += ftell(f);
buffer = new unsigned char[length];
pos = 0;
while (pos < length) {
rle = fgetc(f);
if (rle > 127) {
byte = fgetc(f);
for (count = 0; count < (rle & 127); count++) {
buffer[pos++] = byte;
if (pos >= length) break;
}
} else if (rle > 0) {
for (count = 0; count < rle; count++) {
buffer[pos++] = fgetc(f);
if (pos >= length) break;
}
} else buffer[pos++] = fgetc(f);
}
fseek(f, next, SEEK_SET);
return buffer;
}
void File::skipRLE () {
int next;
next = fgetc(f);
next += fgetc(f) << 8;
fseek(f, next, SEEK_CUR);
return;
}
char * File::loadString () {
char *string;
int length, count;
length = fgetc(f);
count = 0;
if (length) {
string = new char[length + 1];
for (; count < length; count++) string[count] = fgetc(f);
} else {
// If the length is not given, assume it is an 8.3 file name
string = new char[13];
for (; count < 9; count++) {
string[count] = fgetc(f);
if (string[count] == '.') {
string[++count] = fgetc(f);
string[++count] = fgetc(f);
string[++count] = fgetc(f);
count++;
break;
}
}
}
string[count] = 0;
return string;
}
SDL_Surface * File::loadSurface (int width, int height) {
return createSurface(loadRLE(width * height), width, height);
}
void File::loadPalette (SDL_Color *palette) {
unsigned char *buffer;
int count;
buffer = loadRLE(768);
for (count = 0; count < 256; count++) {
// Palette entries are 6-bit
// Shift them upwards to 8-bit, and fill in the lower 2 bits
palette[count].r = (buffer[count * 3] << 2) + (buffer[count * 3] >> 4);
palette[count].g = (buffer[(count * 3) + 1] << 2) +
(buffer[(count * 3) + 1] >> 4);
palette[count].b = (buffer[(count * 3) + 2] << 2) +
(buffer[(count * 3) + 2] >> 4);
}
delete[] buffer;
return;
}
/*
*
* file.h
*
* 3rd February 2009: Created file.h from parts of OpenJazz.h
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2009 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
*
*/
#ifndef _FILE_H
#define _FILE_H
#include "OpenJazz.h"
#include <SDL/SDL.h>
#include <stdio.h>
// Class
class File {
private:
FILE *f;
char *filePath;
public:
File (char * fileName, bool write);
~File ();
int getSize ();
void seek (int offset, bool reset);
int tell ();
unsigned char loadChar ();
void storeChar (unsigned char val);
unsigned short int loadShort ();
void storeShort (unsigned short int val);
signed long int loadInt ();
void storeInt (signed long int val);
unsigned char * loadBlock (int length);
unsigned char * loadRLE (int length);
void skipRLE ();
char * loadString ();
SDL_Surface * loadSurface (int width, int height);
void loadPalette (SDL_Color *palette);
};
//Variable
// Path to game data
EXTERN char *path;
#endif
/*
*
* anim.cpp
*
* 26th July 2009: Created anim.cpp from parts of sprite.cpp
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2009 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
*
*/
#include "anim.h"
#include "sprite.h"
#include "level/level.h"
Anim::Anim () {
frame = 0;
return;
}
Anim::~Anim () {
return;
}
void Anim::setData (int amount, signed char x, signed char y) {
frames = amount;
xOffset = x << 2;
yOffset = y;
return;
}
void Anim::setFrame (int nextFrame, bool looping) {
if (looping) frame = nextFrame % frames;
else frame = (nextFrame >= frames)? frames - 1: nextFrame;
return;
}
void Anim::setFrameData (Sprite *sprite, signed char x, signed char y) {
sprites[frame] = sprite;
xOffsets[frame] = x << 2;
yOffsets[frame] = y;
return;
}
int Anim::getWidth () {
return sprites[frame]->getWidth();
}
int Anim::getHeight() {
return sprites[frame]->getHeight();
}
void Anim::draw (int x, int y) {
sprites[frame]->draw(FTOI(x) + xOffsets[frame] - xOffset - FTOI(viewX),
FTOI(y) + yOffsets[frame] - yOffset - FTOI(viewY));
return;
}
void Anim::setPalette (SDL_Color *palette, int start, int amount) {
sprites[frame]->setPalette(palette, 0, 256);
return;
}
void Anim::flashPalette (int index) {
sprites[frame]->flashPalette(index);
return;
}
void Anim::restorePalette () {
sprites[frame]->restorePalette();
return;
}
/*
*
* anim.h
*
* 26th July 2009: Created anim.h from parts of sprite.h
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2009 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
*
*/
#ifndef _ANIM_H
#define _ANIM_H
#include <SDL/SDL.h>
// Classes
class Sprite;
class Anim {
private:
Sprite *sprites[19];
signed char xOffset;
signed char yOffset;
signed char xOffsets[19];
signed char yOffsets[19];
unsigned char frames; // Number of frames
unsigned char frame; // Current frame
public:
Anim ();
~Anim ();
void setData (int amount, signed char x, signed char y);
void setFrame (int nextFrame, bool looping);
void setFrameData (Sprite *frameSprite, signed char x, signed char y);
int getWidth ();
int getHeight ();
void draw (int x, int y);
void setPalette (SDL_Color *palette, int start, int amount);
void flashPalette (int index);
void restorePalette ();
};
#endif
/*
*
* font.cpp
*
* 23rd August 2005: Created font.c
* 3rd February 2009: Renamed font.c to font.cpp
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2009 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 loading, displaying and freeing of screen fonts.
*
*/
#include "../file.h"
#include "font.h"
#include "video.h"
#include <string.h>
Font::Font (char * fileName) {
File *file;
unsigned char *pixels, *character;
int rle, pos, byte, count, next, fileSize;
int chr, width, height, y;
// Load font from a font file
try {
file = new File(fileName, false);
} catch (int e) {
throw e;
}
file->seek(19, true);
width = file->loadChar() << 2;
h = file->loadChar() << 1;
w = new unsigned char[128];
pixels = new unsigned char[width * h * 128];
memset(pixels, 0, width * h * 128);
file->seek(23, true);
w[0] = width >> 1;
fileSize = file->getSize();
for (chr = 1; chr < 128; chr++) {
file->seek(2, false);
next = file->loadChar();
if (file->tell() > fileSize) break;
next += file->loadChar() << 8;
next += file->tell();
file->seek(1, false);
w[chr] = file->loadChar();
file->seek(1, false);
height = file->loadChar();
character = new unsigned char[(w[chr] * height) + 1];
pos = 0;
while (pos < w[chr] * height) {
rle = file->loadChar();
if (rle > 127) {
byte = file->loadChar();
for (count = 0; count < (rle & 127); count++) {
character[pos++] = byte;
if (pos >= w[chr] * height) break;
}
} else if (rle > 0) {
for (count = 0; count < rle; count++) {
character[pos++] = file->loadChar();
if (pos >= w[chr] * height) break;
}
} else break;
}
character[pos] = character[pos - 1];
for (y = 0; y < height; y++)
memcpy(pixels + (((chr * h) + y) * width),
character + (y * w[chr]) + 1, w[chr]);
delete[] character;
w[chr] += 2;
file->seek(next, true);
}
delete file;
for (; chr < 128; chr++) w[chr] = width >> 1;
surface = createSurface(pixels, width, h * 128);
SDL_SetColorKey(surface, SDL_SRCCOLORKEY, 0);
// Create ASCII->font map
if (!strcmp(fileName, "fontmn1.0fn")) {
for (count = 0; count < 48; count++) map[count] = 0;
for (; count < 58; count++) map[count] = count - 8;
for (; count < 65; count++) map[count] = 0;
for (; count < 91; count++) map[count] = count - 64;
for (; count < 97; count++) map[count] = 0;
for (; count < 123; count++) map[count] = count - 96;
for (; count < 128; count++) map[count] = 0;
} else if (!strcmp(fileName, "fontmn2.0fn")) {
for (count = 0; count < 43; count++) map[count] = 0;
map[33] = 89;
map[34] = 96;
map[39] = 95;
map[43] = 87;
map[44] = 83;
map[45] = 86;
map[46] = 84;
map[47] = 90;
count = 48;
for (; count < 58; count++) map[count] = count + 5;
map[58] = 94;
map[59] = 93;
map[60] = 0;
map[61] = 88;
map[62] = 0;
map[63] = 85;
map[64] = 0;
count = 65;
for (; count < 91; count++) map[count] = count - 38;
for (; count < 97; count++) map[count] = 0;
for (; count < 123; count++) map[count] = count - 96;
for (; count < 128; count++) map[count] = 0;
} else {
for (count = 0; count < 40; count++) map[count] = 0;
for (; count < 42; count++) map[count] = count + 25;
for (; count < 48; count++) map[count] = 0;
map[44] = 101;
map[45] = 104;
map[46] = 102;
for (; count < 58; count++) map[count] = count + 5;
for (; count < 65; count++) map[count] = 0;
map[63] = 103;
for (; count < 91; count++) map[count] = count - 64;
for (; count < 97; count++) map[count] = 0;
for (; count < 123; count++) map[count] = count - 70;
for (; count < 128; count++) map[count] = 0;
}
return;
}
Font::Font (File *file, bool big) {
unsigned char *pixels;
int rle, pos, index, count;
// Load font from panel.000
if (big) h = 8;
else h = 7;
pixels = new unsigned char[320 * h];
if (big) {
// Load the large panel font
// Starts at 4691 and goes 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-:.
pixels[0] = BLACK;
pos = 1;
file->seek(4691, true);
} else {
// Load the small panel font
// Starts at 6975 and goes 0123456789oo (where oo = infinity)
pos = 0;
file->seek(6975, true);
}
// RLE decompression and horizontal to vertical character rearrangement
while (pos < 320 * h) {
rle = file->loadChar();
if (rle >= 128) {
index = file->loadChar();
for (count = 0; count < (rle & 127); count++) {
pixels[(pos & 7) + ((pos / 320) * 8) +
(((pos % 320)>>3) * 8 * h)] = index;
pos++;
}
} else if (rle > 0) {
for (count = 0; count < rle; count++) {
pixels[(pos & 7) + ((pos / 320) * 8) +
(((pos % 320)>>3) * 8 * h)] = file->loadChar();
pos++;
}
} else break;
}
if (big) {
// Create ASCII->font map
for (count = 0; count < 45; count++) map[count] = 39;
map[45] = 36;
map[46] = 38;
for (count = 47; count < 48; count++) map[count] = 39;
for (; count < 58; count++) map[count] = count - 48;
map[58] = 37;
for (count = 59; count < 65; count++) map[count] = 39;
for (; count < 91; count++) map[count] = count - 55;
for (; count < 97; count++) map[count] = 39;
for (; count < 123; count++) map[count] = count - 87;
for (; count < 128; count++) map[count] = 39;
// Set font dimensions
w = new unsigned char[40];
for (count = 0; count < 40; count++) w[count] = 8;
} else {
// Create ASCII->font map
for (count = 0; count < 48; count++) map[count] = 12;
// Use :; to represent the infinity symbol
for (; count < 60; count++) map[count] = count - 48;
for (; count < 128; count++) map[count] = 12;
// Set font dimensions
w = new unsigned char[13];
for (count = 0; count < 13; count++) w[count] = 8;
}
surface = createSurface(pixels, 8, 40 * h);
return;
}
Font::~Font () {
SDL_FreeSurface(surface);
delete[] w;
return;
}
int Font::showString (char * s, int x, int y) {
SDL_Rect src, dst;
unsigned int count;
int xOffset, yOffset;
// Determine the characters' dimensions
src.x = 0;
src.h = h;
// Determine the position at which to draw the first character
xOffset = x;
yOffset = y;
// Go through each character of the string
for (count = 0; s[count]; count++) {
if (s[count] == '\n') {
xOffset = x;
yOffset += h;
} else {
// Determine the character's position on the screen
src.w = w[(int)(map[(int)(s[count])])];
dst.y = yOffset;
dst.x = xOffset;
// Determine the character's position in the font
if (s[count] >= 0) src.y = map[(int)(s[count])] * h;
else src.y = 0;
// Draw the character to the screen
SDL_BlitSurface(surface, &src, screen, &dst);
xOffset += w[(int)(map[(int)(s[count])])];
}
}
return xOffset;
}
void Font::showNumber (int n, int x, int y) {
SDL_Rect src, dst;
int count, offset;
// Determine the characters' dimensions
src.x = 0;
src.h = h;
// n being 0 is a special case. It must not be considered to be a trailing
// zero, as these are not displayed.
if (!n) {
// Determine 0's position on the screen
src.w = w[(int)(map['0'])];
dst.y = y;
dst.x = x - src.w;
// Determine 0's position in the font
src.y = map['0'] * h;
// Draw 0 to the screen
SDL_BlitSurface(surface, &src, screen, &dst);
return;
}
// Determine the length of the number to be drawn
if (n > 0) count = n;
else count = -n;
// Determine the position at which to draw the lowest digit
offset = x;
while (count) {
// Determine the digit's position on the screen
src.w = w[(int)(map['0' + (count % 10)])];
offset -= src.w;
dst.y = y;
dst.x = offset;
// Determine the digit's position in the font
src.y = map['0' + (count % 10)] * h;
// Draw the digit to the screen
SDL_BlitSurface(surface, &src, screen, &dst);
count /= 10;
}
// If needed, draw the negative sign
if (n < 0) {
// Determine the negative sign's position on the screen
src.w = w[(int)(map['-'])];
dst.y = y;
dst.x = offset - src.w;
// Determine the negative sign's position on the screen
src.y = map['-'] * h;
// Draw the negative sign to the screen
SDL_BlitSurface(surface, &src, screen, &dst);
}
return;
}
void Font::mapPalette (int start, int length, int newStart, int newLength) {
SDL_Color palette[256];
int count;
// Map a range of palette indices to another range
for (count = 0; count < length; count++)
palette[count].r = palette[count].g = palette[count].b =
(count * newLength / length) + newStart;
SDL_SetPalette(surface, SDL_LOGPAL, palette, start, length);
return;
}
void Font::restorePalette () {
::restorePalette(surface);
return;
}
/*
*
* font.h
*
* 3rd February 2009: Created font.h from parts of OpenJazz.h
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2009 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
*
*/
#ifndef _FONT_H
#define _FONT_H
#include "OpenJazz.h"
#include <SDL/SDL.h>
// Classes
class File;
class Font {
private:
SDL_Surface *surface;
unsigned char *w;
unsigned char h; // Dimensions of the letters
char map[128]; // Maps ASCII values to letter positions
public:
Font (char *fileName);
Font (File *file, bool big);
~Font ();
int showString (char *s, int x, int y);
void showNumber (int n, int x, int y);
void mapPalette (int start, int length, int newStart,
int newLength);
void restorePalette ();
};
// Variables
EXTERN Font *font2; /* Taken from .0FN file name */
EXTERN Font *fontbig; /* Taken from .0FN file name */
EXTERN Font *fontiny; /* Taken from .0FN file name */
EXTERN Font *fontmn1; /* Taken from .0FN file name */
EXTERN Font *fontmn2; /* Taken from .0FN file name */
EXTERN Font *panelBigFont; /* Not a font file, found in PANEL.000 */
EXTERN Font *panelSmallFont; /* Not a font file, found in PANEL.000 */
#endif
This diff is collapsed.
/*
*
* paletteeffects.h
*
* 4th February 2009: Created palette.h from parts of OpenJazz.h
* 1st August 2009: Renamed palette.h to paletteeffects.h
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2009 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
*
*/
#ifndef _PALETTE_H
#define _PALETTE_H
#include "OpenJazz.h"
#include <SDL/SDL.h>
// Constants
// Types of palette effect
#define PE_FADE 0 /* Fades to black, then remains black */
#define PE_ROTATE 1 /* Cyclical colour animation */
// Level background palette effects
#define PE_SKY 2 /* Transfers the appropriate section of the background
palette to the main palette */
#define PE_2D 8 /* Real parallaxing background */
#define PE_1D 9 /* Diagonal lines parallaxing background */
#define PE_WATER 11 /* The deeper below water, the darker it gets */
// Class
class PaletteEffect {
protected:
PaletteEffect *next; // Next effect to use
public:
PaletteEffect (PaletteEffect * nextPE);
virtual ~PaletteEffect ();
virtual void apply (SDL_Color *shownPalette, bool direct);
};
class WhiteInPaletteEffect : public PaletteEffect {
private:
int duration; // Number of milliseconds the effect lasts
fixed whiteness;
public:
WhiteInPaletteEffect (int newDuration, PaletteEffect * nextPE);
void apply (SDL_Color *shownPalette, bool direct);
};
class FadeInPaletteEffect : public PaletteEffect {
private:
int duration; // Number of milliseconds the effect lasts
fixed blackness;
public:
FadeInPaletteEffect (int newDuration, PaletteEffect * nextPE);
void apply (SDL_Color *shownPalette, bool direct);
};
class WhiteOutPaletteEffect : public PaletteEffect {
private:
int duration; // Number of milliseconds the effect lasts
fixed whiteness;
public:
WhiteOutPaletteEffect (int newDuration, PaletteEffect * nextPE);
void apply (SDL_Color *shownPalette, bool direct);
};
class FadeOutPaletteEffect : public PaletteEffect {
private:
int duration; // Number of milliseconds the effect lasts
fixed blackness;
public:
FadeOutPaletteEffect (int newDuration, PaletteEffect * nextPE);
void apply (SDL_Color *shownPalette, bool direct);
};
class FlashPaletteEffect : public PaletteEffect {
private:
int duration; // Number of milliseconds the effect lasts
fixed progress;
unsigned char red, green, blue; // Flash colour
public:
FlashPaletteEffect (unsigned char newRed, unsigned char newGreen,
unsigned char newBlue, int newDuration, PaletteEffect * nextPE);
void apply (SDL_Color *shownPalette, bool direct);
};
class RotatePaletteEffect : public PaletteEffect {
private:
unsigned char first; /* The first palette index affected by the
effect */
int amount; /* The number of (consecutive) palette indices
affected by the effect */
fixed speed; // Rotations per second
fixed position;
public:
RotatePaletteEffect (unsigned char newFirst, int newAmount,
fixed newSpeed, PaletteEffect * nextPE);
void apply (SDL_Color *shownPalette, bool direct);
};
class SkyPaletteEffect : public PaletteEffect {
private:
SDL_Color *skyPalette;
unsigned char first; /* The first palette index affected by the
effect */
int amount; /* The number of (consecutive) palette
indices affected by the effect */
fixed speed; // Relative Y speed - as in Jazz 2
public:
SkyPaletteEffect (unsigned char newFirst, int newAmount,
fixed newSpeed, SDL_Color *newSkyPalette, PaletteEffect * nextPE);
void apply (SDL_Color *shownPalette, bool direct);
};
class P2DPaletteEffect : public PaletteEffect {
private:
unsigned char first; /* The first palette index affected by the
effect */
int amount; /* The number of (consecutive) palette indices
affected by the effect */
fixed speed; // Relative X & Y speed - as in Jazz 2
public:
P2DPaletteEffect (unsigned char newFirst, int newAmount,
fixed newSpeed, PaletteEffect * nextPE);
void apply (SDL_Color *shownPalette, bool direct);
};
class P1DPaletteEffect : public PaletteEffect {
private:
unsigned char first; /* The first palette index affected by the
effect */
int amount; /* The number of (consecutive) palette indices
affected by the effect */
fixed speed; // Relative X & Y speed - as in Jazz 2
public:
P1DPaletteEffect (unsigned char newFirst, int newAmount,
fixed newSpeed, PaletteEffect * nextPE);
void apply (SDL_Color *shownPalette, bool direct);
};
class WaterPaletteEffect : public PaletteEffect {
private:
fixed depth; /* Number of pixels between water surface and total
darkness */
public:
WaterPaletteEffect (fixed newDepth, PaletteEffect * nextPE);
void apply (SDL_Color *shownPalette, bool direct);
};
// Variable
EXTERN PaletteEffect *firstPE;
#endif
/*
*
* sprite.cpp
*
* 19th March 2009: Created sprite.cpp from parts of event.cpp and player.cpp
* 26th July 2009: Created anim.cpp from parts of sprite.cpp
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2009 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
*
*/
#include "video.h"
#include "sprite.h"
Sprite::Sprite () {
pixels = NULL;
return;
}
Sprite::~Sprite () {
if (pixels) SDL_FreeSurface(pixels);
return;
}
void Sprite::clearPixels () {
unsigned char *data;
if (pixels) SDL_FreeSurface(pixels);
data = new unsigned char[1];
*data = SKEY;
pixels = createSurface(data, 1, 1);
SDL_SetColorKey(pixels, SDL_SRCCOLORKEY, SKEY);
return;
}
void Sprite::setPixels (unsigned char *data, int width, int height) {
if (pixels) SDL_FreeSurface(pixels);
pixels = createSurface(data, width, height);
SDL_SetColorKey(pixels, SDL_SRCCOLORKEY, SKEY);
return;
}
int Sprite::getWidth () {
return pixels->w;
}
int Sprite::getHeight() {
return pixels->h;
}
void Sprite::setPalette (SDL_Color *palette, int start, int amount) {
SDL_SetPalette(pixels, SDL_LOGPAL, palette + start, start, amount);
return;
}
void Sprite::flashPalette (int index) {
SDL_Color palette[256];
int count;
// Map the whole palette to one index
for (count = 0; count < 256; count++)
palette[count].r = palette[count].g = palette[count].b = index;
SDL_SetPalette(pixels, SDL_LOGPAL, palette, 0, 256);
return;
}
void Sprite::restorePalette () {
::restorePalette(pixels);
return;
}
void Sprite::draw (int x, int y) {
SDL_Rect dst;
dst.x = x + xOffset;
dst.y = y + yOffset;
SDL_BlitSurface(pixels, NULL, screen, &dst);
return;
}
/*
*
* sprite.h
*
* 19th March 2009: Created sprite.h from parts of level.h
* 26th July 2009: Created anim.h from parts of sprite.h
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2009 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
*
*/
#ifndef _SPRITE_H
#define _SPRITE_H
#include <SDL/SDL.h>
// Constant
#define SKEY 254 /* Sprite colour key */
// Class
class Sprite {
private:
SDL_Surface *pixels;
public:
unsigned char xOffset;
unsigned char yOffset;
Sprite ();
~Sprite ();
void clearPixels ();
void setPixels (unsigned char *data, int width, int height);
int getWidth ();
int getHeight ();
void draw (int x, int y);
void setPalette (SDL_Color *palette, int start, int amount);
void flashPalette (int index);
void restorePalette ();
};
#endif
/*
*
* video.cpp
*
* 13th July 2009: Created graphics.cpp from parts of util.cpp
* 26th July 2009: Renamed graphics.cpp to video.cpp
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2009 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
*
*/
/*
* Contains graphics utility functions.
*
*/
#include "video.h"
#include <string.h>
SDL_Surface * createSurface (unsigned char * pixels, int width, int height) {
SDL_Surface *ret;
int y;
// Create the surface
ret = SDL_CreateRGBSurface(SDL_HWSURFACE, width, height, 8, 0, 0, 0, 0);
// Set the surface's palette
SDL_SetPalette(ret, SDL_LOGPAL, logicalPalette, 0, 256);
// Upload pixel data to the surface
if (SDL_MUSTLOCK(ret)) SDL_LockSurface(ret);
for (y = 0; y < height; y++)
memcpy(((unsigned char *)(ret->pixels)) + (ret->pitch * y),
pixels + (width * y), width);
if (SDL_MUSTLOCK(ret)) SDL_UnlockSurface(ret);
// Free redundant pixel data
delete[] pixels;
return ret;
}
#ifndef FULLSCREEN_ONLY
void toggleFullscreen () {
fullscreen = !fullscreen;
if (fullscreen) {
SDL_ShowCursor(SDL_DISABLE);
screen = SDL_SetVideoMode(screenW, screenH, 8,
SDL_FULLSCREEN | SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_HWPALETTE);
SDL_SetPalette(screen, SDL_LOGPAL, logicalPalette, 0, 256);
SDL_SetPalette(screen, SDL_PHYSPAL, currentPalette, 0, 256);
/* A real 8-bit display is quite likely if the user has the right video
card, the right video drivers, the right version of DirectX/whatever,
and the right version of SDL. In other words, it's not likely enough.
If a real palette is assumed when
a) there really is a real palette, there will be an extremely small
speed gain.
b) the palette is emulated, there will be a HUGE speed loss.
Therefore, assume the palette is emulated. */
// TODO: Find a better way
fakePalette = true;
} else {
screen = SDL_SetVideoMode(screenW, screenH, 8,
SDL_RESIZABLE | SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_HWPALETTE);
SDL_SetPalette(screen, SDL_LOGPAL, logicalPalette, 0, 256);
SDL_SetPalette(screen, SDL_PHYSPAL, currentPalette, 0, 256);
SDL_ShowCursor(SDL_ENABLE);
/* Assume that in windowed mode the palette is being emulated.
This is extremely likely. */
// TODO: Find a better way
fakePalette = true;
}
return;
}
#endif
void usePalette (SDL_Color *palette) {
// Make palette changes invisible until the next draw. Hopefully.
clearScreen(SDL_MapRGB(screen->format, 0, 0, 0));
SDL_Flip(screen);
SDL_SetPalette(screen, SDL_PHYSPAL, palette, 0, 256);
currentPalette = palette;
return;
}
void restorePalette (SDL_Surface *surface) {
SDL_SetPalette(surface, SDL_LOGPAL, logicalPalette, 0, 256);
return;
}
void clearScreen (int index) {
SDL_FillRect(screen, NULL, index);
return;
}
void drawRect (int x, int y, int width, int height, int index) {
SDL_Rect dst;
dst.x = x;
dst.y = y;
dst.w = width;
dst.h = height;
SDL_FillRect(screen, &dst, index);
return;
}
/*
*
* video.h
*
* 13th July 2009: Created graphics.h from parts of OpenJazz.h
* 26th July 2009: Renamed graphics.h to video.h
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2009 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
*
*/
#ifndef _GRAPHICS_H
#define _GRAPHICS_H
#include "OpenJazz.h"
#include <SDL/SDL.h>
// Constants
// Black palette index
#define BLACK 31
// Variables
EXTERN SDL_Surface *screen;
EXTERN int viewW, viewH, screenW, screenH;
#ifndef FULLSCREEN_ONLY
EXTERN bool fullscreen;
#endif
EXTERN bool fakePalette;
EXTERN int mspf;
// Palettes
EXTERN SDL_Color *currentPalette;
EXTERN SDL_Color logicalPalette[256];
// Panel
EXTERN SDL_Surface *panel;
EXTERN SDL_Surface *panelAmmo[5];
// Functions
EXTERN SDL_Surface * createSurface (unsigned char *pixels, int width,
int height);
#ifndef FULLSCREEN_ONLY
EXTERN void toggleFullscreen ();
#endif
EXTERN void usePalette (SDL_Color *palette);
EXTERN void restorePalette (SDL_Surface *surface);
EXTERN void clearScreen (int index);
EXTERN void drawRect (int x, int y, int width, int height,
int index);
#endif
This diff is collapsed.
/*
*
* network.h
*
* 3rd June 2009: Created network.h from parts of OpenJazz.h
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2005-2009 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
*
*/
#ifndef _NETWORK_H
#define _NETWORK_H
#include "OpenJazz.h"
// Constants
// Defaults
#define NET_ADDRESS "192.168.0.1"
#define NET_PORT 10052
// Timeout interval
#define T_TIMEOUT 30000
// Client limit
#define MAX_CLIENTS 31
// Class
class Network {
public:
Network ();
~Network ();
int host ();
int join (char *address);
int accept (int sock);
void close (int sock);
int send (int sock, unsigned char *buffer);
int recv (int sock, unsigned char *buffer, int length);
bool isConnected (int sock);
int getError ();
};
// Variables
EXTERN char *netAddress;
EXTERN Network *net;
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
*
* planet.h
*
* 3rd of February 2009: Created planet.h
*
* Part of the OpenJazz project
*
*
* Copyright (c) 2009 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
*
*/
#ifndef _PLANET_H
#define _PLANET_H
// Class
class Planet {
public:
Planet (char * fileName);
~Planet ();
int play ();
};
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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