commit 79d3c1d3
Replays are now sorta working. Single player only... no menu
git-svn-id: https://blockattack.svn.sourceforge.net/svnroot/blockattack/trunk@146 9d7177f8-192b-0410-8f35-a16a89829b06
Changed files
| M | source/code/BlockGame.cpp before |
| M | source/code/BlockGame.hpp before |
| M | source/code/main.cpp before |
| M | source/code/replay.cpp before |
| M | source/code/replay.h before |
diff --git a/source/code/BlockGame.cpp b/source/code/BlockGame.cpp
index 84c5efc..279b231 100644
--- a/source/code/BlockGame.cpp
+++ b/source/code/BlockGame.cpp
@@ -186,12 +186,12 @@ int BlockGame::GetTopY()
return topy;
}
-unsigned int BlockGame::GetGameStartedAt()
+Sint32 BlockGame::GetGameStartedAt()
{
return gameStartedAt;
}
-unsigned int BlockGame::GetGameEndedAt()
+Sint32 BlockGame::GetGameEndedAt()
{
return gameEndedAfter;
}
@@ -478,11 +478,18 @@ void BlockGame::Demonstration(bool toggle)
baseSpeed = 0;
}
//We want to play the replay (must have been loaded beforehand)
-void BlockGame::playReplay(int tx, int ty, unsigned int ticks)
+void BlockGame::playReplay(int tx, int ty, unsigned int ticks, Replay r)
{
+ if(r.getActions().size()==0)
+ {
+ cout << "Empty replay data" << endl;
+ return;
+ }
NewGame(tx, ty,ticks);
- gameStartedAt = ticks;
+ gameStartedAt = ticks+3000;
+ replayIndex = 0;
bReplaying = true; //We are playing, no calculations
+ theReplay = r;
#if NETWORK
bNetworkPlayer = false; //Take input from replay file
#endif
@@ -514,7 +521,6 @@ void BlockGame::setPlayerWon()
TimeHandler::addTime("playTime",TimeHandler::ms2ct(gameEndedAfter));
}
}
- theReplay.setFinalFrame(getPackage(), 1);
bGameOver = true;
hasWonTheGame = true;
showGame = false;
@@ -555,7 +561,6 @@ void BlockGame::setDraw()
{
TimeHandler::addTime("playTime",TimeHandler::ms2ct(gameEndedAfter));
}
- theReplay.setFinalFrame(getPackage(), 3);
hasWonTheGame = false;
bDraw = true;
showGame = false;
@@ -746,6 +751,7 @@ void BlockGame::putStartBlocks(Uint32 n)
format f("%1%");
f % n;
ActionPerformed(ACTION_STARTBLOCKS ,f.str());
+ cout << n << ":" << f.str() << endl;
for (int i=0; i<7; i++)
for (int j=0; j<30; j++)
{
@@ -1391,7 +1397,6 @@ void BlockGame::SetGameOver()
{
theReplay.setName(name);
}
- theReplay.setFinalFrame(getPackage(), 0);
bGameOver = true;
showGame = false;
if(stageClear)
@@ -1504,10 +1509,15 @@ void BlockGame::SwitchAtCursor()
if ((puzzleMode)&&(gameStartedAt<ticks)&&(MovesLeft>0)) MovesLeft--;
}
-//Generates a new line and moves the field one block up (restart puzzle mode)
void BlockGame::PushLine()
{
ActionPerformed(ACTION_PUSH,"");
+ PushLineInternal();
+}
+
+//Generates a new line and moves the field one block up (restart puzzle mode)
+void BlockGame::PushLineInternal()
+{
//If not game over, not high tower and not puzzle mode
if ((!bGameOver) && TowerHeight<13 && (!puzzleMode) && (gameStartedAt<ticks)&&(chain==0))
{
@@ -1532,7 +1542,8 @@ void BlockGame::PushLine()
board[j][0] = rand2() % 6;
}
score+=1;
- MoveCursor('N');
+ if(!bReplaying)
+ MoveCursor('N'); //Workaround for this being done registred too
if (vsMode)
{
if (rand2()%6==1)
@@ -1589,7 +1600,7 @@ void BlockGame::PushPixels()
pixels++;
}
else
- PushLine();
+ PushLineInternal();
if (pixels>bsize)
pixels=0;
}
@@ -2036,38 +2047,8 @@ void BlockGame::Update()
Uint32 tempUInt32;
Uint32 nowTime = ticks; //We remember the time, so it doesn't change during this call
ActionPerformed(ACTION_UPDATE, "");
- if (bReplaying)
- {
- setBoard(theReplay.getFrameSec((Uint32)(nowTime-gameStartedAt)));
- strncpy(name,theReplay.getName().c_str(),30);
- if (theReplay.isFinnished((Uint32)(nowTime-gameStartedAt)))
- switch (theReplay.getFinalStatus())
- {
- case 1: //Winner
- bGameOver = true;
- hasWonTheGame = true;
- break;
- case 2: //Looser
- case 4: //GameOver
- bGameOver = true;
- break;
- case 3: //draw
- bGameOver =true;
- bDraw = true;
- break;
- default:
- bGameOver = true;
- //Nothing
- break;
- };
- }
-#if NETWORK
- if ((!bReplaying)&&(!bNetworkPlayer))
- {
-#else
- if (!bReplaying)
+
{
-#endif
FindTowerHeight();
if ((linesCleared-TowerHeight>stageClearLimit) && (stageClear) && (!bGameOver))
{
@@ -2229,11 +2210,6 @@ void BlockGame::Update()
}
}
}
- if ((!bGameOver)&&(!bReplaying)&&(nowTime>gameStartedAt))
- {
- //cout << nowTime << " bigger than " << gameStartedAt << endl;
- theReplay.setFrameSecTo(nowTime-gameStartedAt, getPackage());
- }
}
void BlockGame::UpdateInternal(int newtick)
@@ -2247,30 +2223,49 @@ void BlockGame::UpdateInternal(int newtick)
void BlockGame::Update(int newtick)
{
-
- UpdateInternal(newtick);
+ if(bReplaying)
+ {
+ /*cout << "Testing " << replayIndex << "<" << theReplay.getActions().size()
+ << " && " << theReplay.getActions().at(replayIndex).time << "<=" <<
+ newtick-gameStartedAt << endl;*/
+ while(replayIndex < theReplay.getActions().size() &&
+ theReplay.getActions().at(replayIndex).time <= newtick-gameStartedAt)
+ {
+ Action a = theReplay.getActions().at(replayIndex);
+ PerformAction(a.time+gameStartedAt,a.action,a.param);
+ ++replayIndex;
+ }
+
+ }
+ else
+ {
+ UpdateInternal(newtick);
+ }
}
void BlockGame::ActionPerformed(int action, string param)
{
- if(bGameOver)
+ if(bGameOver || bReplaying)
return;
theReplay.addAction(ticks-gameStartedAt,action,param);
}
void BlockGame::PerformAction(int tick, int action, string param)
{
- UpdateInternal(tick);
+ stringstream ss(param);
+ int p1,p2;
+ Uint32 p3;
switch(action)
{
case ACTION_UPDATE:
+ UpdateInternal(tick);
break;
case ACTION_MOVECURSOR:
- MoveCursor(param.at(0));
+ MoveCursor(param.at(1));
break;
case ACTION_MOVECURSORTO:
{
- stringstream ss(param);
+
int p1,p2;
ss >> p1 >> p2;
MoveCursorTo(p1,p2);
@@ -2284,8 +2279,6 @@ void BlockGame::PerformAction(int tick, int action, string param)
break;
case ACTION_CREATEGARBAGE:
{
- stringstream ss(param);
- int p1,p2;
ss >> p1 >> p2;
CreateGarbage(p1,p2);
}
@@ -2303,17 +2296,20 @@ void BlockGame::PerformAction(int tick, int action, string param)
setDraw();
break;
case ACTION_GAMESPEED:
- setGameSpeed(boost::lexical_cast<short>(param));
+ ss >> p1;
+ setGameSpeed(p1);
break;
case ACTION_HANDICAP:
- setHandicap(boost::lexical_cast<short>(param));
+ ss >> p1;
+ setHandicap(p1);
break;
case ACTION_NEW:
case ACTION_NEWTT:
case ACTION_NEWVS:
break;
case ACTION_STARTBLOCKS:
- putStartBlocks(boost::lexical_cast<int>(param));
+ ss >> p3;
+ putStartBlocks(p3);
break;
case ACTION_NOP:
break;
diff --git a/source/code/BlockGame.hpp b/source/code/BlockGame.hpp
index eba7d12..16e1224 100644
--- a/source/code/BlockGame.hpp
+++ b/source/code/BlockGame.hpp
@@ -98,8 +98,9 @@ protected:
bool bDisconnected; //The player has disconnected
#endif
unsigned int ticks;
- Uint32 gameStartedAt;
- Uint32 gameEndedAfter; //How long did the game last?
+ Sint32 gameStartedAt;
+ Sint32 gameEndedAfter; //How long did the game last?
+ int replayIndex;
int linesCleared;
int TowerHeight;
BlockGame *garbageTarget;
@@ -157,8 +158,8 @@ public:
bool isGameOver();
int GetTopX();
int GetTopY();
- unsigned int GetGameStartedAt();
- unsigned int GetGameEndedAt();
+ Sint32 GetGameStartedAt();
+ Sint32 GetGameEndedAt();
bool isTimeTrial();
bool isStageClear();
bool isVsMode();
@@ -188,7 +189,7 @@ public:
//Starts new Vs Game (two Player)
void NewVsGame(int tx, int ty, BlockGame *target, bool AI,unsigned int ticks);
//We want to play the replay (must have been loaded beforehand)
- void playReplay(int tx, int ty, unsigned int ticks);
+ void playReplay(int tx, int ty, unsigned int ticks, Replay r);
void putStartBlocks(Uint32 n);
//Creates garbage using a given wide and height
bool CreateGarbage(int wide, int height);
@@ -301,7 +302,7 @@ private:
//////////////////////////////////////////////////////////////////////////
void ActionPerformed(int action, string param);
-
+ void PushLineInternal();
//Updates evrything, if not called nothing happends
void Update();
void UpdateInternal(int newtick);
diff --git a/source/code/main.cpp b/source/code/main.cpp
index 09d3f27..976baf2 100644
--- a/source/code/main.cpp
+++ b/source/code/main.cpp
@@ -3109,6 +3109,13 @@ void StartTwoPlayerVs()
strcpy(player2->name, player2name);
}
+void StartReplay(string filename)
+{
+ Replay r1;
+ r1.loadReplay(filename);
+ player1->playReplay(50,100,SDL_GetTicks(),r1);
+}
+
#if NETWORK
#include "NetworkThing.hpp"
//#include "MenuSystem.h"
@@ -3907,6 +3914,8 @@ int runGame(int gametype, int level)
{
/*This is the test place, place function to test here*/
+ StartReplay("/home/poul/.gamesaves/blockattack/bestTT");
+
//theGame.CreateGreyGarbage();
//char mitNavn[30];
//SelectThemeDialogbox(300,400,mitNavn);
diff --git a/source/code/replay.cpp b/source/code/replay.cpp
index cc74e33..98db327 100644
--- a/source/code/replay.cpp
+++ b/source/code/replay.cpp
@@ -31,86 +31,20 @@ Handles replay
Replay::Replay()
{
- nrOfFrames=0;
isLoaded = false;
+ actions.clear();
}
Replay::Replay(const Replay& r)
{
- bps = r.bps;
- finalPack = r.finalPack;
- nrOfFrames = r.nrOfFrames;
isLoaded = r.isLoaded;
- theResult = r.theResult;
name = r.name;
actions = r.actions;
}
-Uint32 Replay::getNumberOfFrames()
-{
- return nrOfFrames;
-}
-
-void Replay::setFrameSecTo(Uint32 miliseconds, boardPackage bp)
-{
- if (isLoaded)
- return;
- int framesToSet = (miliseconds*FRAMESPERSEC)/1000;
- for (int i=nrOfFrames; i<framesToSet; i++)
- {
- bps.push_back(bp);
- }
- nrOfFrames=framesToSet;
-}
-
-void Replay::setFinalFrame(boardPackage bp,int theStatus)
-{
- if (isLoaded)
- return;
- finalPack = bp;
- switch (theStatus)
- {
- case 1:
- theResult = winner;
- break;
- case 2:
- theResult = looser;
- break;
- case 3:
- theResult = draw;
- break;
- default:
- theResult = gameOver;
- };
-}
-
-//Returns the frame to the current time, if time too high the final frame is returned
-boardPackage Replay::getFrameSec(Uint32 miliseconds)
-{
- int frameToGet = (miliseconds*FRAMESPERSEC)/1000;
- if (!(frameToGet<nrOfFrames))
- return getFinalFrame();
- return bps.at(frameToGet);
-}
-
-bool Replay::isFinnished(Uint32 miliseconds)
-{
- int frameToGet = (miliseconds*FRAMESPERSEC)/1000;
- if (!(frameToGet<nrOfFrames))
- return true;
- return false;
-}
-boardPackage Replay::getFinalFrame()
-{
- return finalPack;
-}
-int Replay::getFinalStatus()
-{
- return theResult;
-}
@@ -148,28 +82,7 @@ bool Replay::saveReplay(string filename,Replay p2)
boardPackage bp;
saveFile.write(reinterpret_cast<char*>(&version),sizeof(Uint32)); //Fileversion
Uint8 nrOfReplays = 2;
- saveFile.write(reinterpret_cast<char*>(&nrOfReplays),sizeof(Uint8)); //nrOfReplaysIn File
- saveFile.write(reinterpret_cast<char*>(&nrOfFrames),sizeof(Uint32)); //Nr of frames in file
- for (int i=0; i<nrOfFrames && i<bps.size(); i++)
- {
- //Writing frames
- bp = bps.at(i);
- saveFile.write(reinterpret_cast<char*>(&bp),sizeof(bp));
- }
- saveFile.write(reinterpret_cast<char*>(&finalPack),sizeof(finalPack));
- saveFile.write(reinterpret_cast<char*>(&theResult),sizeof(theResult));
- saveFile.write(reinterpret_cast<char*>(&name),sizeof(name));
- ///Player 2 starts here!!!!!!!!!!!!!!!!!!!!!!
- saveFile.write(reinterpret_cast<char*>(&p2.nrOfFrames),sizeof(Uint32)); //Nr of frames in file
- for (int i=0; (i<p2.nrOfFrames)&& i<p2.bps.size(); i++)
- {
- //Writing frames
- bp = p2.bps.at(i);
- saveFile.write(reinterpret_cast<char*>(&bp),sizeof(bp));
- }
- saveFile.write(reinterpret_cast<char*>(&p2.finalPack),sizeof(finalPack));
- saveFile.write(reinterpret_cast<char*>(&p2.theResult),sizeof(theResult));
- saveFile.write(reinterpret_cast<char*>(&p2.name),sizeof(name));
+
saveFile.close();
return true;
}
@@ -184,12 +97,12 @@ bool Replay::loadReplay(string filename)
isLoaded = true;
actions.clear();
ifstream loadFile;
- loadFile.open(filename.c_str(),ios::binary);
+ loadFile.open(filename.c_str());
if (loadFile)
{
while(!loadFile.eof()) {
- Uint32 time;
- Uint8 action;
+ Sint32 time;
+ Uint32 action;
string restOfLine;
loadFile >> time >> action;
if(action == 16)
@@ -200,7 +113,7 @@ bool Replay::loadReplay(string filename)
getline(loadFile,name,'\n');
if(command == "PLAYER") {
getline(loadFile,restOfLine,'\n');
- if(restOfLine != "1")
+ if(restOfLine != " 1")
break;
}
} else
@@ -215,7 +128,7 @@ bool Replay::loadReplay(string filename)
}
loadFile.close();
- cout << "Loaded 1 player" << endl;
+ cout << "Loaded 1 player, actions.size="<< actions.size() << endl;
}
else
{
@@ -247,25 +160,7 @@ bool Replay::loadReplay2(string filename)
return false;
}
cout << "loading player 2" << endl;
- loadFile.read(reinterpret_cast<char*>(&nrOfFrames),sizeof(Uint32));
- for (int i=0; (i<nrOfFrames); i++)
- {
- loadFile.read(reinterpret_cast<char*>(&bp),sizeof(bp));
- //bps.push_back(bp); We have already read player 1 with another function
- }
- loadFile.read(reinterpret_cast<char*>(&finalPack),sizeof(finalPack));
- loadFile.read(reinterpret_cast<char*>(&theResult),sizeof(theResult));
- loadFile.read(reinterpret_cast<char*>(&name),sizeof(name));
- loadFile.read(reinterpret_cast<char*>(&nrOfFrames),sizeof(Uint32));
- bps.reserve(nrOfFrames);
- for (int i=0; (i<nrOfFrames); i++)
- {
- loadFile.read(reinterpret_cast<char*>(&bp),sizeof(bp));
- bps.push_back(bp);
- }
- loadFile.read(reinterpret_cast<char*>(&finalPack),sizeof(finalPack));
- loadFile.read(reinterpret_cast<char*>(&theResult),sizeof(theResult));
- loadFile.read(reinterpret_cast<char*>(&name),sizeof(name));
+
break;
default:
cout << "Unknown version: " << version << endl;
@@ -291,7 +186,12 @@ string Replay::getName() const
return name;
}
-void Replay::addAction(int tick, int action, string param) {
+vector<Action> Replay::getActions() const {
+ return actions;
+}
+
+void Replay::addAction(int tick, int action, string param)
+{
cout << tick << " " << action << " " << param << endl;
Action a;
a.time = tick;
diff --git a/source/code/replay.h b/source/code/replay.h
index aa9d85b..78c7e70 100644
--- a/source/code/replay.h
+++ b/source/code/replay.h
@@ -30,8 +30,6 @@ able to give a realistic replay
#ifndef REPLAY_H
#define REPLAY_H 1
-//constants - 3000 is 5 minutes
-#define FRAMESPERSEC 10
#include "SDL.h"
#include <stdlib.h>
@@ -57,7 +55,7 @@ struct boardPackage //92 bytes
struct Action
{
- Uint32 time;
+ Sint32 time;
int action;
string param;
};
@@ -65,16 +63,7 @@ struct Action
class Replay
{
private:
-//Our replay is stored in an array of TOTALFRAMES length
- //boardPackage bps[TOTALFRAMES];
- vector<boardPackage> bps;
vector<Action> actions;
-//The final package is not set to any specific time
- boardPackage finalPack;
-//We store number of frames, so we know how long to read the array
- Uint32 nrOfFrames;
-//An enumerator, so we know how it ends! (should be removed then boardPackage is the 92 byte version)
- enum { gameOver=0, winner, looser, draw } theResult;
//If we are loaded from a file, then we are read only
bool isLoaded;
//Store player name
@@ -86,13 +75,6 @@ public:
Replay(); //Constructor
Replay(const Replay& r); //Copy constructor
- Uint32 getNumberOfFrames(); //Returns number of frames
- void setFrameSecTo(Uint32,boardPackage); //Sets frame at a given time to the package
- void setFinalFrame(boardPackage,int); //Sets the final package
- boardPackage getFrameSec(Uint32); //Gets a frame to a time
- boardPackage getFinalFrame(); //Gets the last frame, that must remain
- int getFinalStatus(); //Return the result: winner, looser, draw or gameOver
- bool isFinnished(Uint32); //Returns true if we are done
//New replay type 2.0.0+:
void addAction(int tick, int action, string param);
@@ -103,9 +85,8 @@ public:
bool loadReplay(string); //laods a replay
bool loadReplay2(string);
void setName(string name);
- string getName() const; //loads the second part of the replay file, if it exists, returns false otherwise
-
-
+ string getName() const;
+ vector<Action> getActions() const; //loads the second part of the replay file, if it exists, returns false otherwise
};
#endif