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)&&(gameStartedAt0)) 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) && (gameStartedAtbsize) 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(param)); + ss >> p1; + setGameSpeed(p1); break; case ACTION_HANDICAP: - setHandicap(boost::lexical_cast(param)); + ss >> p1; + setHandicap(p1); break; case ACTION_NEW: case ACTION_NEWTT: case ACTION_NEWVS: break; case ACTION_STARTBLOCKS: - putStartBlocks(boost::lexical_cast(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(&version),sizeof(Uint32)); //Fileversion Uint8 nrOfReplays = 2; - saveFile.write(reinterpret_cast(&nrOfReplays),sizeof(Uint8)); //nrOfReplaysIn File - saveFile.write(reinterpret_cast(&nrOfFrames),sizeof(Uint32)); //Nr of frames in file - for (int i=0; i(&bp),sizeof(bp)); - } - saveFile.write(reinterpret_cast(&finalPack),sizeof(finalPack)); - saveFile.write(reinterpret_cast(&theResult),sizeof(theResult)); - saveFile.write(reinterpret_cast(&name),sizeof(name)); - ///Player 2 starts here!!!!!!!!!!!!!!!!!!!!!! - saveFile.write(reinterpret_cast(&p2.nrOfFrames),sizeof(Uint32)); //Nr of frames in file - for (int i=0; (i(&bp),sizeof(bp)); - } - saveFile.write(reinterpret_cast(&p2.finalPack),sizeof(finalPack)); - saveFile.write(reinterpret_cast(&p2.theResult),sizeof(theResult)); - saveFile.write(reinterpret_cast(&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(&nrOfFrames),sizeof(Uint32)); - for (int i=0; (i(&bp),sizeof(bp)); - //bps.push_back(bp); We have already read player 1 with another function - } - loadFile.read(reinterpret_cast(&finalPack),sizeof(finalPack)); - loadFile.read(reinterpret_cast(&theResult),sizeof(theResult)); - loadFile.read(reinterpret_cast(&name),sizeof(name)); - loadFile.read(reinterpret_cast(&nrOfFrames),sizeof(Uint32)); - bps.reserve(nrOfFrames); - for (int i=0; (i(&bp),sizeof(bp)); - bps.push_back(bp); - } - loadFile.read(reinterpret_cast(&finalPack),sizeof(finalPack)); - loadFile.read(reinterpret_cast(&theResult),sizeof(theResult)); - loadFile.read(reinterpret_cast(&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 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 @@ -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 bps; vector 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 getActions() const; //loads the second part of the replay file, if it exists, returns false otherwise }; #endif