Commit 5e941c85 authored by alistert's avatar alistert

Gameplay processing now takes place a maximum of ~60 times per second. Improved bridges.

parent 2cbd2c54
...@@ -209,7 +209,7 @@ ClientGame::ClientGame (char *address) { ...@@ -209,7 +209,7 @@ ClientGame::ClientGame (char *address) {
clearScreen(0); clearScreen(0);
fontmn2->showString("JOINING GAME", screenW >> 2, (screenH >> 1) - 16); fontmn2->showString("JOINING GAME", screenW >> 2, (screenH >> 1) - 16);
ret = playFrame(-1); ret = step(0);
if (ret < 0) { if (ret < 0) {
...@@ -270,7 +270,7 @@ int ClientGame::setLevel (char *fileName) { ...@@ -270,7 +270,7 @@ int ClientGame::setLevel (char *fileName) {
fontmn2->showString("WAITING FOR SERVER", screenW >> 2, fontmn2->showString("WAITING FOR SERVER", screenW >> 2,
(screenH >> 1) - 16); (screenH >> 1) - 16);
ret = playFrame(-1); ret = step(0);
if (ret < 0) return ret; if (ret < 0) return ret;
...@@ -290,7 +290,7 @@ int ClientGame::setLevel (char *fileName) { ...@@ -290,7 +290,7 @@ int ClientGame::setLevel (char *fileName) {
fontmn2->showNumber(file->tell(), (screenW >> 2) + 56, screenH >> 1); fontmn2->showNumber(file->tell(), (screenW >> 2) + 56, screenH >> 1);
fontmn2->showString("bytes", (screenW >> 2) + 64, screenH >> 1); fontmn2->showString("bytes", (screenW >> 2) + 64, screenH >> 1);
ret = playFrame(-1); ret = step(0);
if (ret < 0) return ret; if (ret < 0) return ret;
...@@ -310,7 +310,7 @@ void ClientGame::send (unsigned char *buffer) { ...@@ -310,7 +310,7 @@ void ClientGame::send (unsigned char *buffer) {
} }
int ClientGame::playFrame (int ticks) { int ClientGame::step (unsigned int ticks) {
unsigned char sendBuffer[BUFFER_LENGTH]; unsigned char sendBuffer[BUFFER_LENGTH];
int length, count; int length, count;
......
...@@ -179,17 +179,15 @@ int Game::play () { ...@@ -179,17 +179,15 @@ int Game::play () {
} }
void Game::view () { void Game::view (int change) {
// Move the viewport towards the exit sign // Move the viewport towards the exit sign
if (TTOF(checkX) > viewX + (viewW << 9) + (160 * mspf)) viewX += 160 * mspf; if (TTOF(checkX) > viewX + (viewW << 9) + change) viewX += change;
else if (TTOF(checkX) < viewX + (viewW << 9) - (160 * mspf)) else if (TTOF(checkX) < viewX + (viewW << 9) - change) viewX -= change;
viewX -= 160 * mspf;
if (TTOF(checkY) > viewY + (viewH << 9) + (160 * mspf)) viewY += 160 * mspf; if (TTOF(checkY) > viewY + (viewH << 9) + change) viewY += change;
else if (TTOF(checkY) < viewY + (viewH << 9) - (160 * mspf)) else if (TTOF(checkY) < viewY + (viewH << 9) - change) viewY -= change;
viewY -= 160 * mspf;
return; return;
...@@ -205,7 +203,7 @@ void Game::send (unsigned char *buffer) { ...@@ -205,7 +203,7 @@ void Game::send (unsigned char *buffer) {
} }
int Game::playFrame (int ticks) { int Game::step (unsigned int ticks) {
// Do nothing // Do nothing
......
...@@ -85,7 +85,7 @@ class Game { ...@@ -85,7 +85,7 @@ class Game {
protected: protected:
char *levelFile; char *levelFile;
int difficulty; int difficulty;
int sendTime, checkTime; unsigned int sendTime, checkTime;
unsigned char checkX, checkY; unsigned char checkX, checkY;
Game (); Game ();
...@@ -96,9 +96,9 @@ class Game { ...@@ -96,9 +96,9 @@ class Game {
virtual int setLevel (char *fileName); virtual int setLevel (char *fileName);
int play (); int play ();
void view (); void view (int change);
virtual void send (unsigned char *buffer); virtual void send (unsigned char *buffer);
virtual int playFrame (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 (Player *player); void resetPlayer (Player *player);
...@@ -127,7 +127,7 @@ class ServerGame : public Game { ...@@ -127,7 +127,7 @@ class ServerGame : public Game {
int setLevel (char *fileName); int setLevel (char *fileName);
void send (unsigned char *buffer); void send (unsigned char *buffer);
int playFrame (int ticks); int step (unsigned int ticks);
void score (unsigned char team); void score (unsigned char team);
void setCheckpoint (unsigned char gridX, unsigned char gridY); void setCheckpoint (unsigned char gridX, unsigned char gridY);
...@@ -150,7 +150,7 @@ class ClientGame : public Game { ...@@ -150,7 +150,7 @@ class ClientGame : public Game {
int setLevel (char *fileName); int setLevel (char *fileName);
void send (unsigned char *buffer); void send (unsigned char *buffer);
int playFrame (int ticks); int step (unsigned int ticks);
void score (unsigned char team); void score (unsigned char team);
void setCheckpoint (unsigned char gridX, unsigned char gridY); void setCheckpoint (unsigned char gridX, unsigned char gridY);
......
...@@ -181,7 +181,7 @@ void ServerGame::send (unsigned char *buffer) { ...@@ -181,7 +181,7 @@ void ServerGame::send (unsigned char *buffer) {
} }
int ServerGame::playFrame (int ticks) { int ServerGame::step (unsigned int ticks) {
unsigned char sendBuffer[BUFFER_LENGTH]; unsigned char sendBuffer[BUFFER_LENGTH];
int count, pcount, length; int count, pcount, length;
......
...@@ -48,10 +48,10 @@ PaletteEffect::~PaletteEffect () { ...@@ -48,10 +48,10 @@ PaletteEffect::~PaletteEffect () {
} }
void PaletteEffect::apply (SDL_Color *shownPalette, bool direct) { void PaletteEffect::apply (SDL_Color *shownPalette, bool direct, int mspf) {
// Apply the next palette effect // Apply the next palette effect
if (next) next->apply(shownPalette, direct); if (next) next->apply(shownPalette, direct, mspf);
return; return;
...@@ -69,12 +69,13 @@ WhiteInPaletteEffect::WhiteInPaletteEffect (fixed newDuration, ...@@ -69,12 +69,13 @@ WhiteInPaletteEffect::WhiteInPaletteEffect (fixed newDuration,
} }
void WhiteInPaletteEffect::apply (SDL_Color *shownPalette, bool direct) { void WhiteInPaletteEffect::apply (SDL_Color *shownPalette, bool direct,
int mspf) {
int count; int count;
// Apply the next palette effect // Apply the next palette effect
if (next) next->apply(shownPalette, direct); if (next) next->apply(shownPalette, direct, mspf);
if (whiteness > F1) { if (whiteness > F1) {
...@@ -119,12 +120,13 @@ FadeInPaletteEffect::FadeInPaletteEffect (int newDuration, ...@@ -119,12 +120,13 @@ FadeInPaletteEffect::FadeInPaletteEffect (int newDuration,
} }
void FadeInPaletteEffect::apply (SDL_Color *shownPalette, bool direct) { void FadeInPaletteEffect::apply (SDL_Color *shownPalette, bool direct,
int mspf) {
int count; int count;
// Apply the next palette effect // Apply the next palette effect
if (next) next->apply(shownPalette, direct); if (next) next->apply(shownPalette, direct, mspf);
if (blackness > F1) { if (blackness > F1) {
...@@ -169,12 +171,13 @@ WhiteOutPaletteEffect::WhiteOutPaletteEffect (int newDuration, ...@@ -169,12 +171,13 @@ WhiteOutPaletteEffect::WhiteOutPaletteEffect (int newDuration,
} }
void WhiteOutPaletteEffect::apply (SDL_Color *shownPalette, bool direct) { void WhiteOutPaletteEffect::apply (SDL_Color *shownPalette, bool direct,
int mspf) {
int count; int count;
// Apply the next palette effect // Apply the next palette effect
if (next) next->apply(shownPalette, direct); if (next) next->apply(shownPalette, direct, mspf);
if (whiteness > F1) { if (whiteness > F1) {
...@@ -217,12 +220,13 @@ FadeOutPaletteEffect::FadeOutPaletteEffect (int newDuration, ...@@ -217,12 +220,13 @@ FadeOutPaletteEffect::FadeOutPaletteEffect (int newDuration,
} }
void FadeOutPaletteEffect::apply (SDL_Color *shownPalette, bool direct) { void FadeOutPaletteEffect::apply (SDL_Color *shownPalette, bool direct,
int mspf) {
int count; int count;
// Apply the next palette effect // Apply the next palette effect
if (next) next->apply(shownPalette, direct); if (next) next->apply(shownPalette, direct, mspf);
if (blackness > F1) { if (blackness > F1) {
...@@ -268,12 +272,13 @@ FlashPaletteEffect::FlashPaletteEffect (unsigned char newRed, ...@@ -268,12 +272,13 @@ FlashPaletteEffect::FlashPaletteEffect (unsigned char newRed,
} }
void FlashPaletteEffect::apply (SDL_Color *shownPalette, bool direct) { void FlashPaletteEffect::apply (SDL_Color *shownPalette, bool direct,
int mspf) {
int count; int count;
// Apply the next palette effect // Apply the next palette effect
if (next) next->apply(shownPalette, direct); if (next) next->apply(shownPalette, direct, mspf);
if (progress < 0) { if (progress < 0) {
...@@ -329,12 +334,13 @@ RotatePaletteEffect::RotatePaletteEffect (unsigned char newFirst, ...@@ -329,12 +334,13 @@ RotatePaletteEffect::RotatePaletteEffect (unsigned char newFirst,
} }
void RotatePaletteEffect::apply (SDL_Color *shownPalette, bool direct) { void RotatePaletteEffect::apply (SDL_Color *shownPalette, bool direct,
int mspf) {
int count; int count;
// Apply the next palette effect // Apply the next palette effect
if (next) next->apply(shownPalette, direct); if (next) next->apply(shownPalette, direct, mspf);
for (count = 0; count < amount; count++) { for (count = 0; count < amount; count++) {
...@@ -371,12 +377,12 @@ SkyPaletteEffect::SkyPaletteEffect (unsigned char newFirst, ...@@ -371,12 +377,12 @@ SkyPaletteEffect::SkyPaletteEffect (unsigned char newFirst,
} }
void SkyPaletteEffect::apply (SDL_Color *shownPalette, bool direct) { void SkyPaletteEffect::apply (SDL_Color *shownPalette, bool direct, int mspf) {
int position, count, y; int position, count, y;
// Apply the next palette effect // Apply the next palette effect
if (next) next->apply(shownPalette, direct); if (next) next->apply(shownPalette, direct, mspf);
position = viewY + (viewH << 9) - F4; position = viewY + (viewH << 9) - F4;
...@@ -438,12 +444,12 @@ P2DPaletteEffect::P2DPaletteEffect (unsigned char newFirst, ...@@ -438,12 +444,12 @@ P2DPaletteEffect::P2DPaletteEffect (unsigned char newFirst,
} }
void P2DPaletteEffect::apply (SDL_Color *shownPalette, bool direct) { void P2DPaletteEffect::apply (SDL_Color *shownPalette, bool direct, int mspf) {
int count, x, y, j; int count, x, y, j;
// Apply the next palette effect // Apply the next palette effect
if (next) next->apply(shownPalette, direct); if (next) next->apply(shownPalette, direct, mspf);
x = FTOI(((256 * 32) - FTOI(viewX)) * speed); x = FTOI(((256 * 32) - FTOI(viewX)) * speed);
...@@ -483,13 +489,13 @@ P1DPaletteEffect::P1DPaletteEffect (unsigned char newFirst, ...@@ -483,13 +489,13 @@ P1DPaletteEffect::P1DPaletteEffect (unsigned char newFirst,
} }
void P1DPaletteEffect::apply (SDL_Color *shownPalette, bool direct) { void P1DPaletteEffect::apply (SDL_Color *shownPalette, bool direct, int mspf) {
fixed position; fixed position;
int count; int count;
// Apply the next palette effect // Apply the next palette effect
if (next) next->apply(shownPalette, direct); if (next) next->apply(shownPalette, direct, mspf);
position = viewX + viewY; position = viewX + viewY;
...@@ -522,12 +528,13 @@ WaterPaletteEffect::WaterPaletteEffect (fixed newDepth, PaletteEffect * nextPE) ...@@ -522,12 +528,13 @@ WaterPaletteEffect::WaterPaletteEffect (fixed newDepth, PaletteEffect * nextPE)
} }
void WaterPaletteEffect::apply (SDL_Color *shownPalette, bool direct) { void WaterPaletteEffect::apply (SDL_Color *shownPalette, bool direct,
int mspf) {
int position, count; int position, count;
// Apply the next palette effect // Apply the next palette effect
if (next) next->apply(shownPalette, direct); if (next) next->apply(shownPalette, direct, mspf);
position = localPlayer->getY() - level->getWaterLevel(0); position = localPlayer->getY() - level->getWaterLevel(0);
......
...@@ -55,7 +55,7 @@ class PaletteEffect { ...@@ -55,7 +55,7 @@ class PaletteEffect {
PaletteEffect (PaletteEffect * nextPE); PaletteEffect (PaletteEffect * nextPE);
virtual ~PaletteEffect (); virtual ~PaletteEffect ();
virtual void apply (SDL_Color *shownPalette, bool direct); virtual void apply (SDL_Color *shownPalette, bool direct, int mspf);
}; };
...@@ -69,7 +69,7 @@ class WhiteInPaletteEffect : public PaletteEffect { ...@@ -69,7 +69,7 @@ class WhiteInPaletteEffect : public PaletteEffect {
public: public:
WhiteInPaletteEffect (int newDuration, PaletteEffect * nextPE); WhiteInPaletteEffect (int newDuration, PaletteEffect * nextPE);
void apply (SDL_Color *shownPalette, bool direct); void apply (SDL_Color *shownPalette, bool direct, int mspf);
}; };
...@@ -83,7 +83,7 @@ class FadeInPaletteEffect : public PaletteEffect { ...@@ -83,7 +83,7 @@ class FadeInPaletteEffect : public PaletteEffect {
public: public:
FadeInPaletteEffect (int newDuration, PaletteEffect * nextPE); FadeInPaletteEffect (int newDuration, PaletteEffect * nextPE);
void apply (SDL_Color *shownPalette, bool direct); void apply (SDL_Color *shownPalette, bool direct, int mspf);
}; };
...@@ -97,7 +97,7 @@ class WhiteOutPaletteEffect : public PaletteEffect { ...@@ -97,7 +97,7 @@ class WhiteOutPaletteEffect : public PaletteEffect {
public: public:
WhiteOutPaletteEffect (int newDuration, PaletteEffect * nextPE); WhiteOutPaletteEffect (int newDuration, PaletteEffect * nextPE);
void apply (SDL_Color *shownPalette, bool direct); void apply (SDL_Color *shownPalette, bool direct, int mspf);
}; };
...@@ -111,7 +111,7 @@ class FadeOutPaletteEffect : public PaletteEffect { ...@@ -111,7 +111,7 @@ class FadeOutPaletteEffect : public PaletteEffect {
public: public:
FadeOutPaletteEffect (int newDuration, PaletteEffect * nextPE); FadeOutPaletteEffect (int newDuration, PaletteEffect * nextPE);
void apply (SDL_Color *shownPalette, bool direct); void apply (SDL_Color *shownPalette, bool direct, int mspf);
}; };
...@@ -127,7 +127,7 @@ class FlashPaletteEffect : public PaletteEffect { ...@@ -127,7 +127,7 @@ class FlashPaletteEffect : public PaletteEffect {
FlashPaletteEffect (unsigned char newRed, unsigned char newGreen, FlashPaletteEffect (unsigned char newRed, unsigned char newGreen,
unsigned char newBlue, int newDuration, PaletteEffect * nextPE); unsigned char newBlue, int newDuration, PaletteEffect * nextPE);
void apply (SDL_Color *shownPalette, bool direct); void apply (SDL_Color *shownPalette, bool direct, int mspf);
}; };
...@@ -146,7 +146,7 @@ class RotatePaletteEffect : public PaletteEffect { ...@@ -146,7 +146,7 @@ class RotatePaletteEffect : public PaletteEffect {
RotatePaletteEffect (unsigned char newFirst, int newAmount, RotatePaletteEffect (unsigned char newFirst, int newAmount,
fixed newSpeed, PaletteEffect * nextPE); fixed newSpeed, PaletteEffect * nextPE);
void apply (SDL_Color *shownPalette, bool direct); void apply (SDL_Color *shownPalette, bool direct, int mspf);
}; };
...@@ -165,7 +165,7 @@ class SkyPaletteEffect : public PaletteEffect { ...@@ -165,7 +165,7 @@ class SkyPaletteEffect : public PaletteEffect {
SkyPaletteEffect (unsigned char newFirst, int newAmount, SkyPaletteEffect (unsigned char newFirst, int newAmount,
fixed newSpeed, SDL_Color *newSkyPalette, PaletteEffect * nextPE); fixed newSpeed, SDL_Color *newSkyPalette, PaletteEffect * nextPE);
void apply (SDL_Color *shownPalette, bool direct); void apply (SDL_Color *shownPalette, bool direct, int mspf);
}; };
...@@ -183,7 +183,7 @@ class P2DPaletteEffect : public PaletteEffect { ...@@ -183,7 +183,7 @@ class P2DPaletteEffect : public PaletteEffect {
P2DPaletteEffect (unsigned char newFirst, int newAmount, P2DPaletteEffect (unsigned char newFirst, int newAmount,
fixed newSpeed, PaletteEffect * nextPE); fixed newSpeed, PaletteEffect * nextPE);
void apply (SDL_Color *shownPalette, bool direct); void apply (SDL_Color *shownPalette, bool direct, int mspf);
}; };
...@@ -201,7 +201,7 @@ class P1DPaletteEffect : public PaletteEffect { ...@@ -201,7 +201,7 @@ class P1DPaletteEffect : public PaletteEffect {
P1DPaletteEffect (unsigned char newFirst, int newAmount, P1DPaletteEffect (unsigned char newFirst, int newAmount,
fixed newSpeed, PaletteEffect * nextPE); fixed newSpeed, PaletteEffect * nextPE);
void apply (SDL_Color *shownPalette, bool direct); void apply (SDL_Color *shownPalette, bool direct, int mspf);
}; };
...@@ -215,7 +215,7 @@ class WaterPaletteEffect : public PaletteEffect { ...@@ -215,7 +215,7 @@ class WaterPaletteEffect : public PaletteEffect {
public: public:
WaterPaletteEffect (fixed newDepth, PaletteEffect * nextPE); WaterPaletteEffect (fixed newDepth, PaletteEffect * nextPE);
void apply (SDL_Color *shownPalette, bool direct); void apply (SDL_Color *shownPalette, bool direct, int mspf);
}; };
......
...@@ -43,7 +43,6 @@ EXTERN int viewW, viewH, screenW, screenH; ...@@ -43,7 +43,6 @@ EXTERN int viewW, viewH, screenW, screenH;
EXTERN bool fullscreen; EXTERN bool fullscreen;
#endif #endif
EXTERN bool fakePalette; EXTERN bool fakePalette;
EXTERN int mspf;
// Palettes // Palettes
EXTERN SDL_Color *currentPalette; EXTERN SDL_Color *currentPalette;
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
#include "player/player.h" #include "player/player.h"
Bullet::Bullet (Player *sourcePlayer, bool lower, int ticks) { Bullet::Bullet (Player *sourcePlayer, bool lower, unsigned int ticks) {
// Properties based on the player // Properties based on the player
...@@ -54,6 +54,7 @@ Bullet::Bullet (Player *sourcePlayer, bool lower, int ticks) { ...@@ -54,6 +54,7 @@ Bullet::Bullet (Player *sourcePlayer, bool lower, int ticks) {
direction |= lower? 2: 0; direction |= lower? 2: 0;
x = source->getX() + (source->getFacing()? PXO_R: PXO_L); x = source->getX() + (source->getFacing()? PXO_R: PXO_L);
y = source->getY() - F8; y = source->getY() - F8;
dx = level->getBullet(type)[B_XSPEED + direction] * 500 * F1;
if (type == 4) { if (type == 4) {
...@@ -79,7 +80,7 @@ Bullet::Bullet (Player *sourcePlayer, bool lower, int ticks) { ...@@ -79,7 +80,7 @@ Bullet::Bullet (Player *sourcePlayer, bool lower, int ticks) {
} }
Bullet::Bullet (Event *sourceEvent, bool facing, int ticks) { Bullet::Bullet (Event *sourceEvent, bool facing, unsigned int ticks) {
// Properties based on the event // Properties based on the event
...@@ -89,7 +90,8 @@ Bullet::Bullet (Event *sourceEvent, bool facing, int ticks) { ...@@ -89,7 +90,8 @@ Bullet::Bullet (Event *sourceEvent, bool facing, int ticks) {
direction = facing? 1: 0; direction = facing? 1: 0;
x = sourceEvent->getX() + (sourceEvent->getWidth() >> 1); x = sourceEvent->getX() + (sourceEvent->getWidth() >> 1);
y = sourceEvent->getY() + (sourceEvent->getHeight() >> 1); y = sourceEvent->getY() - (sourceEvent->getHeight() >> 1);
dx = level->getBullet(type)[B_XSPEED + direction] * 500 * F1;
dy = level->getBullet(type)[B_YSPEED + direction] * 250 * F1; dy = level->getBullet(type)[B_YSPEED + direction] * 250 * F1;
time = ticks + T_BULLET; time = ticks + T_BULLET;
...@@ -100,7 +102,7 @@ Bullet::Bullet (Event *sourceEvent, bool facing, int ticks) { ...@@ -100,7 +102,7 @@ Bullet::Bullet (Event *sourceEvent, bool facing, int ticks) {
} }
Bullet::Bullet (Bird *sourceBird, bool lower, int ticks) { Bullet::Bullet (Bird *sourceBird, bool lower, unsigned int ticks) {
// Properties based on the bird and its player // Properties based on the bird and its player
...@@ -122,6 +124,7 @@ Bullet::Bullet (Bird *sourceBird, bool lower, int ticks) { ...@@ -122,6 +124,7 @@ Bullet::Bullet (Bird *sourceBird, bool lower, int ticks) {
direction |= lower? 2: 0; direction |= lower? 2: 0;
x = sourceBird->getX() + (source->getFacing()? PXO_R: PXO_L); x = sourceBird->getX() + (source->getFacing()? PXO_R: PXO_L);
y = sourceBird->getY(); y = sourceBird->getY();
dx = level->getBullet(type)[B_XSPEED + direction] * 500 * F1;
dy = level->getBullet(type)[B_YSPEED + direction] * 250 * F1; dy = level->getBullet(type)[B_YSPEED + direction] * 250 * F1;
time = ticks + T_BULLET; time = ticks + T_BULLET;
...@@ -170,7 +173,7 @@ Player * Bullet::getSource () { ...@@ -170,7 +173,7 @@ Player * Bullet::getSource () {
} }
bool Bullet::playFrame (int ticks) { bool Bullet::step (unsigned int ticks, int msps) {
signed char *set; signed char *set;
Event *event; Event *event;
...@@ -179,7 +182,7 @@ bool Bullet::playFrame (int ticks) { ...@@ -179,7 +182,7 @@ bool Bullet::playFrame (int ticks) {
// Process the next bullet // Process the next bullet
if (next) { if (next) {
if (next->playFrame(ticks)) removeNext(); if (next->step(ticks, msps)) removeNext();
} }
...@@ -276,14 +279,14 @@ bool Bullet::playFrame (int ticks) { ...@@ -276,14 +279,14 @@ bool Bullet::playFrame (int ticks) {
else if (level->checkMaskDown(x, y + F4)) dy = -600 * F1; else if (level->checkMaskDown(x, y + F4)) dy = -600 * F1;
else if (level->checkMaskDown(x - F4, y)) direction |= 1; else if (level->checkMaskDown(x - F4, y)) direction |= 1;
else if (level->checkMaskDown(x + F4, y)) direction &= ~1; else if (level->checkMaskDown(x + F4, y)) direction &= ~1;
else dy += 6400 * mspf * set[B_GRAVITY]; else dy += 6400 * msps * set[B_GRAVITY];
} else dy += 6400 * mspf * set[B_GRAVITY]; } else dy += 6400 * msps * set[B_GRAVITY];
// Apply trajectory // Apply trajectory
x += (set[B_XSPEED + direction] * 500 * F1 * mspf) >> 10; x += (dx * msps) >> 10;
y += (dy * mspf) >> 10; y += (dy * msps) >> 10;
// Do not destroy the bullet // Do not destroy the bullet
...@@ -292,11 +295,11 @@ bool Bullet::playFrame (int ticks) { ...@@ -292,11 +295,11 @@ bool Bullet::playFrame (int ticks) {
} }
void Bullet::draw () { void Bullet::draw (int change) {
Sprite *sprite; Sprite *sprite;
if (next) next->draw(); if (next) next->draw(change);
if (type == -1) sprite = level->getSprite(130); if (type == -1) sprite = level->getSprite(130);
else sprite = else sprite =
...@@ -304,8 +307,9 @@ void Bullet::draw () { ...@@ -304,8 +307,9 @@ void Bullet::draw () {
[B_SPRITE + direction]); [B_SPRITE + direction]);
// Show the bullet // Show the bullet
sprite->draw(FTOI(x) - (sprite->getWidth() >> 1) - FTOI(viewX), sprite->draw(
FTOI(y) - (sprite->getWidth() >> 1) - FTOI(viewY)); FTOI(getDrawX(change)) - (sprite->getWidth() >> 1) - FTOI(viewX),
FTOI(getDrawY(change)) - (sprite->getHeight() >> 1) - FTOI(viewY));
return; return;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#define _BULLET_H #define _BULLET_H
#include "movable.h"
#include "OpenJazz.h" #include "OpenJazz.h"
...@@ -51,27 +52,28 @@ class Bird; ...@@ -51,27 +52,28 @@ class Bird;
class Event; class Event;
class Player; class Player;
class Bullet { class Bullet : public Movable {
private: private:
Bullet *next; Bullet *next;
Player *source; // If NULL, was fired by an event Player *source; // If NULL, was fired by an event
int type; // -1 is TNT, otherwise this indexes the bullet set int type; // -1 is TNT, otherwise indexes the bullet set
int direction; // 0: Left, 1: Right, 2: L (lower), 3: R (lower) int direction; // 0: Left, 1: Right, 2: L (lower), 3: R (lower)
fixed x, y, dy; unsigned int time; // Time at which the bullet will self-destruct
int time; // The time at which the bullet will self-destruct
public: public:
Bullet (Player *sourcePlayer, bool lower, int ticks); Bullet (Player *sourcePlayer, bool lower,
Bullet (Event *sourceEvent, bool facing, int ticks); unsigned int ticks);
Bullet (Bird *sourceBird, bool lower, int ticks); Bullet (Event *sourceEvent, bool facing,
unsigned int ticks);
Bullet (Bird *sourceBird, bool lower, unsigned int ticks);
~Bullet (); ~Bullet ();
Bullet * getNext (); Bullet * getNext ();
void removeNext (); void removeNext ();
Player * getSource (); Player * getSource ();
bool playFrame (int ticks); bool step (unsigned int ticks, int msps);
void draw (); void draw (int change);
}; };
......
...@@ -101,7 +101,8 @@ int DemoLevel::play () { ...@@ -101,7 +101,8 @@ int DemoLevel::play () {
smoothfps = 50.0f; smoothfps = 50.0f;
tickOffset = globalTicks; tickOffset = globalTicks;
ticks = -10; ticks = 16;
prevStepTicks = 0;
stats = S_NONE; stats = S_NONE;
...@@ -152,9 +153,14 @@ int DemoLevel::play () { ...@@ -152,9 +153,14 @@ int DemoLevel::play () {
// Process frame-by-frame activity // Process frame-by-frame activity
ret = playFrame(); // Process step
if (ticks >= prevStepTicks + 16) {
if (ret < 0) return ret; ret = step();
if (ret < 0) return ret;
}
// Handle player reactions // Handle player reactions
......
...@@ -50,7 +50,7 @@ Event::Event (unsigned char gX, unsigned char gY, Event *nextEvent) { ...@@ -50,7 +50,7 @@ Event::Event (unsigned char gX, unsigned char gY, Event *nextEvent) {
y = TTOF(gY + 1); y = TTOF(gY + 1);
flashTime = 0; flashTime = 0;
// Choose initial animation and direction // Choose initial settings
switch (getProperty(E_BEHAVIOUR)) { switch (getProperty(E_BEHAVIOUR)) {
...@@ -70,6 +70,19 @@ Event::Event (unsigned char gX, unsigned char gY, Event *nextEvent) { ...@@ -70,6 +70,19 @@ Event::Event (unsigned char gX, unsigned char gY, Event *nextEvent) {
break; break;
case 28:
animType = E_LEFTANIM;
x -= F2;
y += ITOF(getProperty(E_YAXIS)) - F40;
// dx and dy used to store leftmost and rightmost player on bridge
// Start with minimum values
dx = getProperty(E_MULTIPURPOSE) * F8;
dy = 0;
break;
default: default:
animType = E_LEFTANIM; animType = E_LEFTANIM;
...@@ -114,7 +127,7 @@ void Event::removeNext () { ...@@ -114,7 +127,7 @@ void Event::removeNext () {
} }
void Event::destroy (int ticks) { void Event::destroy (unsigned int ticks) {
level->setEventTime(gridX, gridY, ticks + T_FINISH); level->setEventTime(gridX, gridY, ticks + T_FINISH);
...@@ -128,7 +141,7 @@ void Event::destroy (int ticks) { ...@@ -128,7 +141,7 @@ void Event::destroy (int ticks) {
} }
bool Event::hit (Player *source, int ticks) { bool Event::hit (Player *source, unsigned int ticks) {
int hitsRemaining; int hitsRemaining;
...@@ -160,20 +173,6 @@ bool Event::isFrom (unsigned char gX, unsigned char gY) { ...@@ -160,20 +173,6 @@ bool Event::isFrom (unsigned char gX, unsigned char gY) {
} }
fixed Event::getX () {
return x;
}
fixed Event::getY () {
return y - getHeight();
}
fixed Event::getWidth () { fixed Event::getWidth () {
fixed width; fixed width;
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#define _EVENTS_H #define _EVENTS_H
#include "movable.h"
#include "OpenJazz.h" #include "OpenJazz.h"
...@@ -74,17 +75,16 @@ ...@@ -74,17 +75,16 @@
class Player; class Player;
class Event { class Event : public Movable {
private: private:
Event *next; Event *next;
unsigned char gridX, gridY; // Grid position of the event unsigned char gridX, gridY; // Grid position of the event
fixed x, y; // Actual position of the event
unsigned char animType; // E_LEFTANIM, etc, or 0 unsigned char animType; // E_LEFTANIM, etc, or 0
unsigned char frame; unsigned char frame;
int flashTime; unsigned int flashTime;
void destroy (int ticks); void destroy (unsigned int ticks);
public: public:
Event (unsigned char gX, unsigned char gY, Event (unsigned char gX, unsigned char gY,
...@@ -93,17 +93,15 @@ class Event { ...@@ -93,17 +93,15 @@ class Event {
Event * getNext (); Event * getNext ();
void removeNext (); void removeNext ();
bool hit (Player *source, int ticks); bool hit (Player *source, unsigned int ticks);
bool isFrom (unsigned char gX, unsigned char gY); bool isFrom (unsigned char gX, unsigned char gY);
fixed getX ();
fixed getY ();
fixed getWidth (); fixed getWidth ();
fixed getHeight (); fixed getHeight ();
bool overlap (fixed left, fixed top, fixed width, bool overlap (fixed left, fixed top, fixed width,
fixed height); fixed height);
signed char getProperty (unsigned char property); signed char getProperty (unsigned char property);
bool playFrame (int ticks); bool step (unsigned int ticks, int msps);
void draw (int ticks); void draw (unsigned int ticks, int change);
}; };
......
This diff is collapsed.
...@@ -237,7 +237,7 @@ unsigned char Level::getEventHits (unsigned char gridX, unsigned char gridY) { ...@@ -237,7 +237,7 @@ unsigned char Level::getEventHits (unsigned char gridX, unsigned char gridY) {
} }
int Level::getEventTime (unsigned char gridX, unsigned char gridY) { unsigned int Level::getEventTime (unsigned char gridX, unsigned char gridY) {
return grid[gridY][gridX].time; return grid[gridY][gridX].time;
...@@ -322,7 +322,8 @@ int Level::hitEvent (Player *source, unsigned char gridX, unsigned char gridY) { ...@@ -322,7 +322,8 @@ int Level::hitEvent (Player *source, unsigned char gridX, unsigned char gridY) {
} }
void Level::setEventTime (unsigned char gridX, unsigned char gridY, int time) { void Level::setEventTime (unsigned char gridX, unsigned char gridY,
unsigned int time) {
grid[gridY][gridX].time = time; grid[gridY][gridX].time = time;
...@@ -511,11 +512,12 @@ void Level::receive (unsigned char *buffer) { ...@@ -511,11 +512,12 @@ void Level::receive (unsigned char *buffer) {
void Level::timeCalcs (bool paused) { void Level::timeCalcs (bool paused) {
// Calculate smoothed fps // Calculate smoothed fps
smoothfps = smoothfps + 1 - (smoothfps * ((float)mspf) / 1000.0f); smoothfps = smoothfps + 1.0f -
(smoothfps * ((float)(ticks - prevTicks)) / 1000.0f);
/* This equation is a simplified version of /* This equation is a simplified version of
(fps * c) + (smoothfps * (1 - c)) (fps * c) + (smoothfps * (1 - c))
where c = (1 / fps) where c = (1 / fps)
and fps = 1000 / mspf and fps = 1000 / (ticks - prevTicks)
In other words, the response of smoothFPS to changes in FPS decreases as the In other words, the response of smoothFPS to changes in FPS decreases as the
framerate increases framerate increases
The following version is for c = (1 / smoothfps) The following version is for c = (1 / smoothfps)
...@@ -523,24 +525,27 @@ void Level::timeCalcs (bool paused) { ...@@ -523,24 +525,27 @@ void Level::timeCalcs (bool paused) {
// smoothfps = (fps / smoothfps) + smoothfps - 1; // smoothfps = (fps / smoothfps) + smoothfps - 1;
// Ignore outlandish values // Ignore outlandish values
if (smoothfps > 9999) smoothfps = 9999; if (smoothfps > 9999.0f) smoothfps = 9999.0f;
if (smoothfps < 1) smoothfps = 1; if (smoothfps < 1.0f) smoothfps = 1.0f;
// Number of ticks of gameplay since the level started // Track number of ticks of gameplay since the level started
prevTicks = ticks;
ticks = globalTicks - tickOffset;
if (paused) { if (paused) {
tickOffset += ticks - prevTicks; tickOffset = globalTicks - ticks;
ticks = prevTicks;
} else if (globalTicks - tickOffset > ticks + 100) {
prevTicks = ticks;
ticks += 100;
} else if (ticks > prevTicks + 100) { tickOffset = globalTicks - ticks;
tickOffset += ticks - (prevTicks + 100); } else {
ticks = prevTicks + 100;
prevTicks = ticks;
ticks = globalTicks - tickOffset;
} }
...@@ -557,7 +562,7 @@ int Level::play () { ...@@ -557,7 +562,7 @@ int Level::play () {
char *string; char *string;
bool paused, pmenu; bool paused, pmenu;
int stats, option; int stats, option;
int returnTime; unsigned int returnTime;
int perfect; int perfect;
int timeBonus; int timeBonus;
int count; int count;
...@@ -568,7 +573,8 @@ int Level::play () { ...@@ -568,7 +573,8 @@ int Level::play () {
smoothfps = 50.0f; smoothfps = 50.0f;
tickOffset = globalTicks; tickOffset = globalTicks;
ticks = -10; ticks = 16;
prevStepTicks = 0;
pmenu = paused = false; pmenu = paused = false;
option = 0; option = 0;
...@@ -688,9 +694,15 @@ int Level::play () { ...@@ -688,9 +694,15 @@ int Level::play () {
for (count = 0; count < PCONTROLS; count++) for (count = 0; count < PCONTROLS; count++)
localPlayer->setControl(count, controls.getState(count)); localPlayer->setControl(count, controls.getState(count));
count = playFrame();
if (count < 0) return count; // Process step
if (ticks >= prevStepTicks + 16) {
count = step();
if (count < 0) return count;
}
// Handle player reactions // Handle player reactions
...@@ -772,7 +784,7 @@ int Level::play () { ...@@ -772,7 +784,7 @@ int Level::play () {
if (timeBonus) { if (timeBonus) {
count = mspf / 100; count = (ticks - prevTicks) / 100;
if (!count) count = 1; if (!count) count = 1;
if (timeBonus == -1) { if (timeBonus == -1) {
...@@ -870,7 +882,7 @@ int Level::play () { ...@@ -870,7 +882,7 @@ int Level::play () {
if (gameMode) { if (gameMode) {
count = game->playFrame(ticks); count = game->step(ticks);
switch (count) { switch (count) {
......
...@@ -115,7 +115,7 @@ class Level { ...@@ -115,7 +115,7 @@ class Level {
int levelNum, worldNum, nextLevelNum, nextWorldNum; int levelNum, worldNum, nextLevelNum, nextWorldNum;
unsigned char difficulty; unsigned char difficulty;
int pathLength; int pathLength;
int endTime; unsigned int endTime;
int enemies, items; int enemies, items;
fixed waterLevel; fixed waterLevel;
fixed energyBar; fixed energyBar;
...@@ -125,11 +125,11 @@ class Level { ...@@ -125,11 +125,11 @@ class Level {
int loadTiles (char *fileName); int loadTiles (char *fileName);
protected: protected:
float smoothfps; float smoothfps;
int tickOffset, prevTicks, ticks; unsigned int tickOffset, prevStepTicks, prevTicks, ticks;
int load (char *fileName, unsigned char diff, bool checkpoint); int load (char *fileName, unsigned char diff, bool checkpoint);
int playFrame (); int step ();
void draw (); void draw ();
void timeCalcs (bool paused); void timeCalcs (bool paused);
...@@ -152,12 +152,12 @@ class Level { ...@@ -152,12 +152,12 @@ class Level {
unsigned char tile); unsigned char tile);
signed char * getEvent (unsigned char gridX, unsigned char gridY); signed char * getEvent (unsigned char gridX, unsigned char gridY);
unsigned char getEventHits (unsigned char gridX, unsigned char gridY); unsigned char getEventHits (unsigned char gridX, unsigned char gridY);
int getEventTime (unsigned char gridX, unsigned char gridY); unsigned int getEventTime (unsigned char gridX, unsigned char gridY);
void clearEvent (unsigned char gridX, unsigned char gridY); void clearEvent (unsigned char gridX, unsigned char gridY);
int hitEvent (Player *source, unsigned char gridX, int hitEvent (Player *source, unsigned char gridX,
unsigned char gridY); unsigned char gridY);
void setEventTime (unsigned char gridX, unsigned char gridY, void setEventTime (unsigned char gridX, unsigned char gridY,
int time); unsigned int time);
signed char * getBullet (unsigned char bullet); signed char * getBullet (unsigned char bullet);
Sprite * getSprite (unsigned char sprite); Sprite * getSprite (unsigned char sprite);
Anim * getAnim (unsigned char anim); Anim * getAnim (unsigned char anim);
......
...@@ -36,11 +36,17 @@ ...@@ -36,11 +36,17 @@
#include "player/player.h" #include "player/player.h"
int Level::playFrame () { int Level::step () {
Bullet *nextBullet; Bullet *nextBullet;
Event *nextEvent; Event *nextEvent;
int x, y; int x, y;
int msps;
// Milliseconds per step
msps = ticks - prevStepTicks;
prevStepTicks = ticks;
// Search for active events // Search for active events
...@@ -74,7 +80,7 @@ int Level::playFrame () { ...@@ -74,7 +80,7 @@ int Level::playFrame () {
// Determine the players' trajectories // Determine the players' trajectories
for (x = 0; x < nPlayers; x++) players[x].control(ticks); for (x = 0; x < nPlayers; x++) players[x].control(ticks, msps);
// Process active events // Process active events
...@@ -83,7 +89,7 @@ int Level::playFrame () { ...@@ -83,7 +89,7 @@ int Level::playFrame () {
if (firstEvent) { if (firstEvent) {
if (firstEvent->playFrame(ticks)) { if (firstEvent->step(ticks, msps)) {
nextEvent = firstEvent->getNext(); nextEvent = firstEvent->getNext();
delete firstEvent; delete firstEvent;
...@@ -98,7 +104,7 @@ int Level::playFrame () { ...@@ -98,7 +104,7 @@ int Level::playFrame () {
if (firstBullet) { if (firstBullet) {
if (firstBullet->playFrame(ticks)) { if (firstBullet->step(ticks, msps)) {
nextBullet = firstBullet->getNext(); nextBullet = firstBullet->getNext();
delete firstBullet; delete firstBullet;
...@@ -111,7 +117,7 @@ int Level::playFrame () { ...@@ -111,7 +117,7 @@ int Level::playFrame () {
// Apply as much of those trajectories as possible, without going into the // Apply as much of those trajectories as possible, without going into the
// scenery // scenery
for (x = 0; x < nPlayers; x++) players[x].move(ticks); for (x = 0; x < nPlayers; x++) players[x].move(ticks, msps);
...@@ -128,17 +134,6 @@ int Level::playFrame () { ...@@ -128,17 +134,6 @@ int Level::playFrame () {
} }
// Calculate viewport
if (game && (stage == LS_END)) game->view();
else localPlayer->view(ticks);
// Ensure the new viewport is within the level
if (viewX < 0) viewX = 0;
if (FTOI(viewX) + viewW >= TTOI(LW)) viewX = ITOF(TTOI(LW) - viewW);
if (viewY < 0) viewY = 0;
if (FTOI(viewY) + viewH >= TTOI(LH)) viewY = ITOF(TTOI(LH) - viewH);
return E_NONE; return E_NONE;
} }
...@@ -161,7 +156,17 @@ void Level::draw () { ...@@ -161,7 +156,17 @@ void Level::draw () {
src.x = 0; src.x = 0;
// Use the local player's viewport // Calculate viewport
if (game && (stage == LS_END)) game->view((ticks - prevTicks) * 160);
else localPlayer->view(ticks, ticks - prevTicks);
// Ensure the new viewport is within the level
if (viewX < 0) viewX = 0;
if (FTOI(viewX) + viewW >= TTOI(LW)) viewX = ITOF(TTOI(LW) - viewW);
if (viewY < 0) viewY = 0;
if (FTOI(viewY) + viewH >= TTOI(LH)) viewY = ITOF(TTOI(LH) - viewH);
// Use the viewport
dst.x = 0; dst.x = 0;
dst.y = 0; dst.y = 0;
vX = FTOI(viewX); vX = FTOI(viewX);
...@@ -240,15 +245,15 @@ void Level::draw () { ...@@ -240,15 +245,15 @@ void Level::draw () {
while (event) { while (event) {
event->draw(ticks); event->draw(ticks, ticks - prevStepTicks);
event = event->getNext(); event = event->getNext();
} }
// Show the players // Show the players
for (x = 0; x < nPlayers; x++)
for (x = 0; x < nPlayers; x++) players[x].draw(ticks); players[x].draw(ticks, ticks - prevStepTicks);
// Show bullets // Show bullets
...@@ -256,7 +261,7 @@ void Level::draw () { ...@@ -256,7 +261,7 @@ void Level::draw () {
while (bullet) { while (bullet) {
bullet->draw(); bullet->draw(ticks - prevStepTicks);
bullet = bullet->getNext(); bullet = bullet->getNext();
} }
...@@ -362,16 +367,17 @@ void Level::draw () { ...@@ -362,16 +367,17 @@ void Level::draw () {
dst.x = 20; dst.x = 20;
x = localPlayer->getEnergy(); x = localPlayer->getEnergy();
y = (ticks - prevTicks) * 40;
if (FTOI(energyBar) < (x << 4)) { if (FTOI(energyBar) < (x << 4)) {
if ((x << 14) - energyBar < mspf * 40) energyBar = x << 14; if ((x << 14) - energyBar < y) energyBar = x << 14;
else energyBar += mspf * 40; else energyBar += y;
} else if (FTOI(energyBar) > (x << 4)) { } else if (FTOI(energyBar) > (x << 4)) {
if (energyBar - (x << 14) < mspf * 40) energyBar = x << 14; if (energyBar - (x << 14) < y) energyBar = x << 14;
else energyBar -= mspf * 40; else energyBar -= y;
} }
......
...@@ -325,7 +325,6 @@ int loadMain () { ...@@ -325,7 +325,6 @@ int loadMain () {
// Establish arbitrary timing // Establish arbitrary timing
mspf = 20;
globalTicks = SDL_GetTicks() - 20; globalTicks = SDL_GetTicks() - 20;
...@@ -435,17 +434,14 @@ int loop (int type) { ...@@ -435,17 +434,14 @@ int loop (int type) {
SDL_Color shownPalette[256]; SDL_Color shownPalette[256];
SDL_Event event; SDL_Event event;
int ret; int prevTicks, ret;
// Show everything that has been drawn so far // Show everything that has been drawn so far
SDL_Flip(screen); SDL_Flip(screen);
// Calculate frame rate and key timing prevTicks = globalTicks;
ret = SDL_GetTicks(); globalTicks = SDL_GetTicks();
mspf = ret - globalTicks;
if (mspf > 100) mspf = 100;
globalTicks = ret;
// Process system events // Process system events
while (SDL_PollEvent(&event)) { while (SDL_PollEvent(&event)) {
...@@ -532,20 +528,22 @@ int loop (int type) { ...@@ -532,20 +528,22 @@ int loop (int type) {
memcpy(shownPalette, currentPalette, sizeof(SDL_Color) * 256); memcpy(shownPalette, currentPalette, sizeof(SDL_Color) * 256);
firstPE->apply(shownPalette, false); firstPE->apply(shownPalette, false, globalTicks - prevTicks);
SDL_SetPalette(screen, SDL_PHYSPAL, shownPalette, 0, 256); SDL_SetPalette(screen, SDL_PHYSPAL, shownPalette, 0, 256);
} else { } else {
firstPE->apply(shownPalette, true); firstPE->apply(shownPalette, true, globalTicks - prevTicks);
} }
} }
#ifdef WIZ #ifdef WIZ
WIZ_AdjustVolume( volume_direction ); WIZ_AdjustVolume( volume_direction );
#endif #endif
return E_NONE; return E_NONE;
} }
......
/*
*
* movable.cpp
*
* 15th January 2005: Created movable.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 the base class for all movable objects.
*
*/
#include "movable.h"
fixed Movable::getDrawX (int change) {
return x + ((dx * change) >> 10);
}
fixed Movable::getDrawY (int change) {
return y + ((dy * change) >> 10);
}
fixed Movable::getX () {
return x;
}
fixed Movable::getY () {
return y;
}
/*
*
* movable.h
*
* 15th January 2005: Created movable.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 _MOVABLE_H
#define _MOVABLE_H
#include "OpenJazz.h"
// Class
class Movable {
protected:
fixed x, y, dx, dy;
fixed getDrawX (int change);
fixed getDrawY (int change);
public:
fixed getX ();
fixed getY ();
};
#endif
...@@ -78,21 +78,7 @@ void Bird::hit () { ...@@ -78,21 +78,7 @@ void Bird::hit () {
} }
fixed Bird::getX () { bool Bird::step (unsigned int ticks, int msps) {
return x;
}
fixed Bird::getY () {
return y;
}
bool Bird::playFrame (int ticks) {
Event *nextEvent; Event *nextEvent;
fixed eventX, eventY; fixed eventX, eventY;
...@@ -122,13 +108,13 @@ bool Bird::playFrame (int ticks) { ...@@ -122,13 +108,13 @@ bool Bird::playFrame (int ticks) {
// To the left of the player, so move right // To the left of the player, so move right
if (dx < F160) dx += 400 * mspf; if (dx < F160) dx += 400 * msps;
} else { } else {
// To the right of the player, so move left // To the right of the player, so move left
if (dx > -F160) dx -= 400 * mspf; if (dx > -F160) dx -= 400 * msps;
} }
...@@ -152,13 +138,13 @@ bool Bird::playFrame (int ticks) { ...@@ -152,13 +138,13 @@ bool Bird::playFrame (int ticks) {
// Above the player, so move downwards // Above the player, so move downwards
if (dy < F160) dy += 400 * mspf; if (dy < F160) dy += 400 * msps;
} else { } else {
// Below the player, so move upwards // Below the player, so move upwards
if (dy > -F160) dy -= 400 * mspf; if (dy > -F160) dy -= 400 * msps;
} }
...@@ -178,7 +164,7 @@ bool Bird::playFrame (int ticks) { ...@@ -178,7 +164,7 @@ bool Bird::playFrame (int ticks) {
while (nextEvent) { while (nextEvent) {
eventX = nextEvent->getX(); eventX = nextEvent->getX();
eventY = nextEvent->getY(); eventY = nextEvent->getY() - nextEvent->getHeight();
if (nextEvent->getProperty(E_HITSTOKILL) && if (nextEvent->getProperty(E_HITSTOKILL) &&
(eventX > x) && (eventX < x + F160) && (eventY > y) && (eventX > x) && (eventX < x + F160) && (eventY > y) &&
...@@ -199,7 +185,7 @@ bool Bird::playFrame (int ticks) { ...@@ -199,7 +185,7 @@ bool Bird::playFrame (int ticks) {
while (nextEvent) { while (nextEvent) {
eventX = nextEvent->getX(); eventX = nextEvent->getX();
eventY = nextEvent->getY(); eventY = nextEvent->getY() - nextEvent->getHeight();
if (nextEvent->getProperty(E_HITSTOKILL) && if (nextEvent->getProperty(E_HITSTOKILL) &&
(eventX > x - F160) && (eventX < x) && (eventY > y) && (eventX > x - F160) && (eventX < x) && (eventY > y) &&
...@@ -231,15 +217,15 @@ bool Bird::playFrame (int ticks) { ...@@ -231,15 +217,15 @@ bool Bird::playFrame (int ticks) {
} }
// Apply trajectory // Apply trajectory
x += (dx * mspf) >> 10; x += (dx * msps) >> 10;
y += (dy * mspf) >> 10; y += (dy * msps) >> 10;
return false; return false;
} }
void Bird::draw (int ticks) { void Bird::draw (unsigned int ticks, int change) {
Anim *anim; Anim *anim;
...@@ -247,7 +233,7 @@ void Bird::draw (int ticks) { ...@@ -247,7 +233,7 @@ void Bird::draw (int ticks) {
BIRD_LEFTANIM); BIRD_LEFTANIM);
anim->setFrame(ticks / 80, true); anim->setFrame(ticks / 80, true);
anim->draw(x, y); anim->draw(getDrawX(change), getDrawY(change));
return; return;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#define _BIRD_H #define _BIRD_H
#include "movable.h"
#include "OpenJazz.h" #include "OpenJazz.h"
...@@ -41,11 +42,10 @@ ...@@ -41,11 +42,10 @@
class Player; class Player;
class Bird { class Bird : public Movable {
private: private:
Player *player; Player *player;
fixed x, y, dx, dy;
bool fleeing; bool fleeing;
int fireTime; int fireTime;
...@@ -56,10 +56,8 @@ class Bird { ...@@ -56,10 +56,8 @@ class Bird {
void reset (); void reset ();
Player * getPlayer (); Player * getPlayer ();
void hit (); void hit ();
fixed getX (); bool step (unsigned int ticks, int msps);
fixed getY (); void draw (unsigned int ticks, int change);
bool playFrame (int ticks);
void draw (int ticks);
}; };
......
...@@ -237,7 +237,8 @@ void Player::setControl (int control, bool state) { ...@@ -237,7 +237,8 @@ void Player::setControl (int control, bool state) {
} }
bool Player::shootEvent (unsigned char gridX, unsigned char gridY, int ticks) { bool Player::shootEvent (unsigned char gridX, unsigned char gridY,
unsigned int ticks) {
signed char *set; signed char *set;
...@@ -331,7 +332,8 @@ bool Player::shootEvent (unsigned char gridX, unsigned char gridY, int ticks) { ...@@ -331,7 +332,8 @@ bool Player::shootEvent (unsigned char gridX, unsigned char gridY, int ticks) {
} }
bool Player::touchEvent (unsigned char gridX, unsigned char gridY, int ticks) { bool Player::touchEvent (unsigned char gridX, unsigned char gridY,
unsigned int ticks) {
signed char *set; signed char *set;
...@@ -485,7 +487,7 @@ bool Player::touchEvent (unsigned char gridX, unsigned char gridY, int ticks) { ...@@ -485,7 +487,7 @@ bool Player::touchEvent (unsigned char gridX, unsigned char gridY, int ticks) {
} }
bool Player::hit (Player *source, int ticks) { bool Player::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;
...@@ -534,7 +536,7 @@ bool Player::hit (Player *source, int ticks) { ...@@ -534,7 +536,7 @@ bool Player::hit (Player *source, int ticks) {
} }
void Player::kill (Player *source, int ticks) { void Player::kill (Player *source, unsigned int ticks) {
if (reaction != PR_NONE) return; if (reaction != PR_NONE) return;
...@@ -615,20 +617,6 @@ int Player::getItems () { ...@@ -615,20 +617,6 @@ int Player::getItems () {
} }
fixed Player::getX () {
return x;
}
fixed Player::getY () {
return y;
}
bool Player::overlap (fixed left, fixed top, fixed width, fixed height) { bool Player::overlap (fixed left, fixed top, fixed width, fixed height) {
return (x + PXO_R >= left) && (x + PXO_L < left + width) && (y >= top) && return (x + PXO_R >= left) && (x + PXO_L < left + width) && (y >= top) &&
...@@ -671,7 +659,7 @@ unsigned char Player::getTeam () { ...@@ -671,7 +659,7 @@ unsigned char Player::getTeam () {
} }
void Player::floatUp (signed char *newEvent) { void Player::floatUp (signed char *newEvent, int speed) {
event = newEvent; event = newEvent;
...@@ -679,7 +667,7 @@ void Player::floatUp (signed char *newEvent) { ...@@ -679,7 +667,7 @@ void Player::floatUp (signed char *newEvent) {
dy = event[E_MULTIPURPOSE] * -F40; dy = event[E_MULTIPURPOSE] * -F40;
if (dy > event[E_MULTIPURPOSE] * -F40) if (dy > event[E_MULTIPURPOSE] * -F40)
dy -= event[E_MULTIPURPOSE] * 320 * mspf; dy -= event[E_MULTIPURPOSE] * 320 * speed;
jumpY = y - (8 * F16); jumpY = y - (8 * F16);
...@@ -690,7 +678,7 @@ void Player::floatUp (signed char *newEvent) { ...@@ -690,7 +678,7 @@ void Player::floatUp (signed char *newEvent) {
void Player::belt (int speed) { void Player::belt (int speed) {
dx += speed * 160 * mspf; dx += speed * 160;
return; return;
...@@ -835,7 +823,7 @@ void Player::receive (unsigned char *buffer) { ...@@ -835,7 +823,7 @@ void Player::receive (unsigned char *buffer) {
} }
int Player::reacted (int ticks) { int Player::reacted (unsigned int ticks) {
int oldReaction; int oldReaction;
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#define _PLAYER_H #define _PLAYER_H
#include "movable.h"
#include "OpenJazz.h" #include "OpenJazz.h"
#include <SDL/SDL.h> #include <SDL/SDL.h>
...@@ -154,7 +155,7 @@ ...@@ -154,7 +155,7 @@
class Bird; class Bird;
class Player { class Player : public Movable {
private: private:
Bird *bird; Bird *bird;
...@@ -175,18 +176,17 @@ class Player { ...@@ -175,18 +176,17 @@ class Player {
3 = 1 orange, 4 = 2 orange, 5 = 3 orange, 6 = 4 orange */ 3 = 1 orange, 4 = 2 orange, 5 = 3 orange, 6 = 4 orange */
bool floating; // false = normal, true = boarding/bird/etc. bool floating; // false = normal, true = boarding/bird/etc.
bool facing; bool facing;
int lookTime; /* Negative if looking up, positive if looking unsigned int lookTime; /* Negative if looking up, positive if looking
down, 0 if neither */ down, 0 if neither */
int reaction; int reaction;
int reactionTime; unsigned int reactionTime;
int fireSpeed; int fireSpeed;
int fireTime; unsigned int fireTime;
fixed jumpHeight; fixed jumpHeight;
fixed jumpY; fixed jumpY;
int fastFeetTime; unsigned int fastFeetTime;
unsigned char warpX, warpY; unsigned char warpX, warpY;
int warpTime; unsigned int warpTime;
fixed x, y, dx, dy;
int enemies, items; int enemies, items;
unsigned char team; unsigned char team;
...@@ -207,11 +207,11 @@ class Player { ...@@ -207,11 +207,11 @@ class Player {
void reset (); void reset ();
void setControl (int control, bool state); void setControl (int control, bool state);
bool shootEvent (unsigned char gridX, unsigned char gridY, bool shootEvent (unsigned char gridX, unsigned char gridY,
int ticks); unsigned int ticks);
bool touchEvent (unsigned char gridX, unsigned char gridY, bool touchEvent (unsigned char gridX, unsigned char gridY,
int ticks); unsigned int ticks);
bool hit (Player *source, int ticks); bool hit (Player *source, unsigned int ticks);
void kill (Player *source, int ticks); void kill (Player *source, unsigned int ticks);
void addScore (int addedScore); void addScore (int addedScore);
int getScore (); int getScore ();
int getEnergy (); int getEnergy ();
...@@ -219,26 +219,24 @@ class Player { ...@@ -219,26 +219,24 @@ class Player {
int getAmmo (bool amount); int getAmmo (bool amount);
int getEnemies (); int getEnemies ();
int getItems (); int getItems ();
fixed getX ();
fixed getY ();
bool overlap (fixed left, fixed top, fixed width, bool overlap (fixed left, fixed top, fixed width,
fixed height); fixed height);
void setPosition (fixed newX, fixed newY); void setPosition (fixed newX, fixed newY);
void setSpeed (fixed newDx, fixed newDy); void setSpeed (fixed newDx, fixed newDy);
bool getFacing (); bool getFacing ();
unsigned char getTeam (); unsigned char getTeam ();
void floatUp (signed char *newEvent); void floatUp (signed char *newEvent, int speed);
void belt (int speed); void belt (int speed);
void setEvent (signed char *newEvent); void setEvent (signed char *newEvent);
void clearEvent (signed char *newEvent, void clearEvent (signed char *newEvent,
unsigned char property); unsigned char property);
void send (unsigned char *data); void send (unsigned char *data);
void receive (unsigned char *buffer); void receive (unsigned char *buffer);
void control (int ticks); void control (unsigned int ticks, int msps);
void move (int ticks); void move (unsigned int ticks, int msps);
void view (int ticks); void view (unsigned int ticks, int mspf);
void draw (int ticks); void draw (unsigned int ticks, int change);
int reacted (int ticks); int reacted (unsigned int ticks);
}; };
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
#include <math.h> #include <math.h>
void Player::control (int ticks) { void Player::control (unsigned int ticks, int msps) {
// Respond to controls, unless the player has been killed // Respond to controls, unless the player has been killed
...@@ -52,7 +52,7 @@ void Player::control (int ticks) { ...@@ -52,7 +52,7 @@ void Player::control (int ticks) {
if (floating) dy = 0; if (floating) dy = 0;
else { else {
dy += PYA_GRAVITY * mspf; dy += PYA_GRAVITY * msps;
if (dy > PYS_FALL) dy = PYS_FALL; if (dy > PYS_FALL) dy = PYS_FALL;
} }
...@@ -65,9 +65,9 @@ void Player::control (int ticks) { ...@@ -65,9 +65,9 @@ void Player::control (int ticks) {
// Walk/run right // Walk/run right
if (dx < 0) dx += PXA_REVERSE * mspf; if (dx < 0) dx += PXA_REVERSE * msps;
else if (dx < PXS_WALK) dx += PXA_WALK * mspf; else if (dx < PXS_WALK) dx += PXA_WALK * msps;
else if (dx < PXS_RUN) dx += PXA_RUN * mspf; else if (dx < PXS_RUN) dx += PXA_RUN * msps;
facing = true; facing = true;
...@@ -75,9 +75,9 @@ void Player::control (int ticks) { ...@@ -75,9 +75,9 @@ void Player::control (int ticks) {
// Walk/run left // Walk/run left
if (dx > 0) dx -= PXA_REVERSE * mspf; if (dx > 0) dx -= PXA_REVERSE * msps;
else if (dx > -PXS_WALK) dx -= PXA_WALK * mspf; else if (dx > -PXS_WALK) dx -= PXA_WALK * msps;
else if (dx > -PXS_RUN) dx -= PXA_RUN * mspf; else if (dx > -PXS_RUN) dx -= PXA_RUN * msps;
facing = false; facing = false;
...@@ -87,15 +87,15 @@ void Player::control (int ticks) { ...@@ -87,15 +87,15 @@ void Player::control (int ticks) {
if (dx > 0) { if (dx > 0) {
if (dx < PXA_STOP * mspf) dx = 0; if (dx < PXA_STOP * msps) dx = 0;
else dx -= PXA_STOP * mspf; else dx -= PXA_STOP * msps;
} }
if (dx < 0) { if (dx < 0) {
if (dx > -PXA_STOP * mspf) dx = 0; if (dx > -PXA_STOP * msps) dx = 0;
else dx += PXA_STOP * mspf; else dx += PXA_STOP * msps;
} }
...@@ -111,17 +111,17 @@ void Player::control (int ticks) { ...@@ -111,17 +111,17 @@ void Player::control (int ticks) {
// Fly upwards // Fly upwards
if (dy > 0) dy -= PXA_REVERSE * mspf; if (dy > 0) dy -= PXA_REVERSE * msps;
else if (dy > -PXS_WALK) dy -= PXA_WALK * mspf; else if (dy > -PXS_WALK) dy -= PXA_WALK * msps;
else if (dy > -PXS_RUN) dy -= PXA_RUN * mspf; else if (dy > -PXS_RUN) dy -= PXA_RUN * msps;
} else if (pcontrols[C_DOWN]) { } else if (pcontrols[C_DOWN]) {
// Fly downwards // Fly downwards
if (dy < 0) dy += PXA_REVERSE * mspf; if (dy < 0) dy += PXA_REVERSE * msps;
else if (dy < PXS_WALK) dy += PXA_WALK * mspf; else if (dy < PXS_WALK) dy += PXA_WALK * msps;
else if (dy < PXS_RUN) dy += PXA_RUN * mspf; else if (dy < PXS_RUN) dy += PXA_RUN * msps;
} else { } else {
...@@ -129,15 +129,15 @@ void Player::control (int ticks) { ...@@ -129,15 +129,15 @@ void Player::control (int ticks) {
if (dy > 0) { if (dy > 0) {
if (dy < PXA_STOP * mspf) dy = 0; if (dy < PXA_STOP * msps) dy = 0;
else dy -= PXA_STOP * mspf; else dy -= PXA_STOP * msps;
} }
if (dy < 0) { if (dy < 0) {
if (dy > -PXA_STOP * mspf) dy = 0; if (dy > -PXA_STOP * msps) dy = 0;
else dy += PXA_STOP * mspf; else dy += PXA_STOP * msps;
} }
...@@ -159,9 +159,9 @@ void Player::control (int ticks) { ...@@ -159,9 +159,9 @@ void Player::control (int ticks) {
// Swim upwards // Swim upwards
if (dy > 0) dy -= PXA_REVERSE * mspf; if (dy > 0) dy -= PXA_REVERSE * msps;
else if (dy > -PXS_WALK) dy -= PXA_WALK * mspf; else if (dy > -PXS_WALK) dy -= PXA_WALK * msps;
else if (dy > -PXS_RUN) dy -= PXA_RUN * mspf; else if (dy > -PXS_RUN) dy -= PXA_RUN * msps;
// Prepare to jump upon leaving the water // Prepare to jump upon leaving the water
...@@ -180,15 +180,15 @@ void Player::control (int ticks) { ...@@ -180,15 +180,15 @@ void Player::control (int ticks) {
// Swim downwards // Swim downwards
if (dy < 0) dy += PXA_REVERSE * mspf; if (dy < 0) dy += PXA_REVERSE * msps;
else if (dy < PXS_WALK) dy += PXA_WALK * mspf; else if (dy < PXS_WALK) dy += PXA_WALK * msps;
else if (dy < PXS_RUN) dy += PXA_RUN * mspf; else if (dy < PXS_RUN) dy += PXA_RUN * msps;
} else { } else {
// Sink // Sink
dy += PYA_SINK * mspf; dy += PYA_SINK * msps;
if (dy > PYS_SINK) dy = PYS_SINK; if (dy > PYS_SINK) dy = PYS_SINK;
} }
...@@ -255,7 +255,7 @@ void Player::control (int ticks) { ...@@ -255,7 +255,7 @@ void Player::control (int ticks) {
} else { } else {
// Fall under gravity // Fall under gravity
dy += PYA_GRAVITY * mspf; dy += PYA_GRAVITY * msps;
if (dy > PYS_FALL) dy = PYS_FALL; if (dy > PYS_FALL) dy = PYS_FALL;
} }
...@@ -331,7 +331,7 @@ void Player::control (int ticks) { ...@@ -331,7 +331,7 @@ void Player::control (int ticks) {
if (bird) { if (bird) {
if (bird->playFrame(ticks)) { if (bird->step(ticks, msps)) {
delete bird; delete bird;
bird = NULL; bird = NULL;
...@@ -346,7 +346,7 @@ void Player::control (int ticks) { ...@@ -346,7 +346,7 @@ void Player::control (int ticks) {
} }
void Player::move (int ticks) { void Player::move (unsigned int ticks, int msps) {
fixed pdx, pdy; fixed pdx, pdy;
int count; int count;
...@@ -364,13 +364,13 @@ void Player::move (int ticks) { ...@@ -364,13 +364,13 @@ void Player::move (int ticks) {
if (fastFeetTime > ticks) { if (fastFeetTime > ticks) {
pdx = (dx * mspf * 3) >> 11; pdx = (dx * msps * 3) >> 11;
pdy = (dy * mspf * 3) >> 11; pdy = (dy * msps * 3) >> 11;
} else { } else {
pdx = (dx * mspf) >> 10; pdx = (dx * msps) >> 10;
pdy = (dy * mspf) >> 10; pdy = (dy * msps) >> 10;
} }
...@@ -516,7 +516,7 @@ void Player::move (int ticks) { ...@@ -516,7 +516,7 @@ void Player::move (int ticks) {
} }
void Player::view (int ticks) { void Player::view (unsigned int ticks, int mspf) {
int oldViewX, oldViewY, speed; int oldViewX, oldViewY, speed;
...@@ -569,10 +569,11 @@ void Player::view (int ticks) { ...@@ -569,10 +569,11 @@ void Player::view (int ticks) {
} }
void Player::draw (int ticks) { void Player::draw (unsigned int ticks, int change) {
Anim *an; Anim *an;
int anim, frame; int anim, frame;
fixed drawX, drawY;
fixed xOffset, yOffset; fixed xOffset, yOffset;
// The current frame for animations // The current frame for animations
...@@ -580,6 +581,12 @@ void Player::draw (int ticks) { ...@@ -580,6 +581,12 @@ void Player::draw (int ticks) {
else frame = ticks / 75; else frame = ticks / 75;
// Get position
drawX = getDrawX(change);
drawY = getDrawY(change);
// Choose player animation // Choose player animation
if (reaction == PR_KILLED) anim = anims[facing? PA_RDIE: PA_LDIE]; if (reaction == PR_KILLED) anim = anims[facing? PA_RDIE: PA_LDIE];
...@@ -604,6 +611,9 @@ void Player::draw (int ticks) { ...@@ -604,6 +611,9 @@ void Player::draw (int ticks) {
level->checkMaskDown(x + PXO_MID, y + F8) || level->checkMaskDown(x + PXO_MID, y + F8) ||
level->checkMaskDown(x + PXO_MR, y + F8)) { level->checkMaskDown(x + PXO_MR, y + F8)) {
drawX = x;
drawY = y;
if (dx) { if (dx) {
if (dx <= -PXS_RUN) anim = anims[PA_LRUN]; if (dx <= -PXS_RUN) anim = anims[PA_LRUN];
...@@ -671,11 +681,10 @@ void Player::draw (int ticks) { ...@@ -671,11 +681,10 @@ void Player::draw (int ticks) {
// Draw "motion blur" // Draw "motion blur"
if (fastFeetTime > ticks) if (fastFeetTime > ticks) an->draw(drawX - (dx >> 6), drawY);
an->draw(x - (dx >> 6), y);
// Draw player // Draw player
an->draw(x, y); an->draw(drawX, drawY);
// Remove red flash or player colour from sprite // Remove red flash or player colour from sprite
...@@ -692,16 +701,16 @@ void Player::draw (int ticks) { ...@@ -692,16 +701,16 @@ void Player::draw (int ticks) {
an = level->getMiscAnim(0); an = level->getMiscAnim(0);
an->setFrame(frame, true); an->setFrame(frame, true);
an->draw(x + PXO_MID + xOffset, y + PYO_MID + yOffset); an->draw(drawX + PXO_MID + xOffset, drawY + PYO_MID + yOffset);
an->setFrame(frame + 1, true); an->setFrame(frame + 1, true);
an->draw(x + PXO_MID - xOffset, y + PYO_MID - yOffset); an->draw(drawX + PXO_MID - xOffset, drawY + PYO_MID - yOffset);
an->setFrame(frame + 2, true); an->setFrame(frame + 2, true);
an->draw(x + PXO_MID + yOffset, y + PYO_MID + xOffset); an->draw(drawX + PXO_MID + yOffset, drawY + PYO_MID + xOffset);
an->setFrame(frame + 3, true); an->setFrame(frame + 3, true);
an->draw(x + PXO_MID - yOffset, y + PYO_MID - xOffset); an->draw(drawX + PXO_MID - yOffset, drawY + PYO_MID - xOffset);
} else if (shield > 2) { } else if (shield > 2) {
...@@ -712,13 +721,13 @@ void Player::draw (int ticks) { ...@@ -712,13 +721,13 @@ void Player::draw (int ticks) {
an = level->getAnim(59); an = level->getAnim(59);
an->draw(x + xOffset, y + PYO_TOP + yOffset); an->draw(drawX + xOffset, drawY + PYO_TOP + yOffset);
if (shield > 3) an->draw(x - xOffset, y + PYO_TOP - yOffset); if (shield > 3) an->draw(drawX - xOffset, drawY + PYO_TOP - yOffset);
if (shield > 4) an->draw(x + yOffset, y + PYO_TOP - xOffset); if (shield > 4) an->draw(drawX + yOffset, drawY + PYO_TOP - xOffset);
if (shield > 5) an->draw(x - yOffset, y + PYO_TOP + xOffset); if (shield > 5) an->draw(drawX - yOffset, drawY + PYO_TOP + xOffset);
} else if (shield) { } else if (shield) {
...@@ -729,21 +738,21 @@ void Player::draw (int ticks) { ...@@ -729,21 +738,21 @@ void Player::draw (int ticks) {
an = level->getAnim(50); an = level->getAnim(50);
an->draw(x + xOffset, y + yOffset + PYO_TOP); an->draw(drawX + xOffset, drawY + yOffset + PYO_TOP);
if (shield == 2) an->draw(x - xOffset, y + PYO_TOP - yOffset); if (shield == 2) an->draw(drawX - xOffset, drawY + PYO_TOP - yOffset);
} }
// Show the bird // Show the bird
if (bird) bird->draw(ticks); if (bird) bird->draw(ticks, change);
// Show the player's name // Show the player's name
if (gameMode) if (gameMode)
panelBigFont->showString(name, FTOI(x - viewX), panelBigFont->showString(name, FTOI(drawX - viewX),
FTOI(y - F32 - F16 - viewY)); FTOI(drawY - F32 - F16 - viewY));
return; return;
......
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