Commit 45e4cd58 authored by VanillaSalt's avatar VanillaSalt

replay undo (slow)

parent 4c7a39c4
......@@ -50,6 +50,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
mainGame->btnReplayStart->setVisible(false);
mainGame->btnReplayPause->setVisible(true);
mainGame->btnReplayStep->setVisible(false);
mainGame->btnReplayUndo->setVisible(false);
ReplayMode::Pause(false, false);
break;
}
......@@ -59,6 +60,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
mainGame->btnReplayStart->setVisible(true);
mainGame->btnReplayPause->setVisible(false);
mainGame->btnReplayStep->setVisible(true);
mainGame->btnReplayUndo->setVisible(true);
ReplayMode::Pause(true, false);
break;
}
......@@ -80,6 +82,12 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
ReplayMode::SwapField();
break;
}
case BUTTON_REPLAY_UNDO: {
if(!mainGame->dInfo.isReplay)
break;
ReplayMode::Undo();
break;
}
case BUTTON_REPLAY_SAVE: {
if(mainGame->ebRSName->getText()[0] == 0)
break;
......
......@@ -493,13 +493,14 @@ bool Game::Initialize() {
btnRSYes = env->addButton(rect<s32>(70, 80, 140, 105), wReplaySave, BUTTON_REPLAY_SAVE, dataManager.GetSysString(1341));
btnRSNo = env->addButton(rect<s32>(170, 80, 240, 105), wReplaySave, BUTTON_REPLAY_CANCEL, dataManager.GetSysString(1212));
//replay control
wReplayControl = env->addStaticText(L"", rect<s32>(205, 143, 295, 273), true, false, 0, -1, true);
wReplayControl = env->addStaticText(L"", rect<s32>(205, 118, 295, 273), true, false, 0, -1, true);
wReplayControl->setVisible(false);
btnReplayStart = env->addButton(rect<s32>(5, 5, 85, 25), wReplayControl, BUTTON_REPLAY_START, dataManager.GetSysString(1343));
btnReplayPause = env->addButton(rect<s32>(5, 30, 85, 50), wReplayControl, BUTTON_REPLAY_PAUSE, dataManager.GetSysString(1344));
btnReplayStep = env->addButton(rect<s32>(5, 55, 85, 75), wReplayControl, BUTTON_REPLAY_STEP, dataManager.GetSysString(1345));
btnReplaySwap = env->addButton(rect<s32>(5, 80, 85, 100), wReplayControl, BUTTON_REPLAY_SWAP, dataManager.GetSysString(1346));
btnReplayExit = env->addButton(rect<s32>(5, 105, 85, 125), wReplayControl, BUTTON_REPLAY_EXIT, dataManager.GetSysString(1347));
btnReplayUndo = env->addButton(rect<s32>(5, 80, 85, 100), wReplayControl, BUTTON_REPLAY_UNDO, dataManager.GetSysString(1360));
btnReplaySwap = env->addButton(rect<s32>(5, 105, 85, 125), wReplayControl, BUTTON_REPLAY_SWAP, dataManager.GetSysString(1346));
btnReplayExit = env->addButton(rect<s32>(5, 130, 85, 150), wReplayControl, BUTTON_REPLAY_EXIT, dataManager.GetSysString(1347));
//chat
wChat = env->addWindow(rect<s32>(305, 615, 1020, 640), false, L"");
wChat->getCloseButton()->setVisible(false);
......
......@@ -379,6 +379,7 @@ public:
irr::gui::IGUIButton* btnReplayStart;
irr::gui::IGUIButton* btnReplayPause;
irr::gui::IGUIButton* btnReplayStep;
irr::gui::IGUIButton* btnReplayUndo;
irr::gui::IGUIButton* btnReplayExit;
irr::gui::IGUIButton* btnReplaySwap;
//surrender/leave
......@@ -497,6 +498,7 @@ extern Game* mainGame;
#define BUTTON_REPLAY_STEP 322
#define BUTTON_REPLAY_EXIT 323
#define BUTTON_REPLAY_SWAP 324
#define BUTTON_REPLAY_UNDO 325
#define BUTTON_REPLAY_SAVE 330
#define BUTTON_REPLAY_CANCEL 331
#define LISTBOX_SINGLEPLAY_LIST 350
......
......@@ -178,6 +178,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
mainGame->btnReplayStart->setVisible(false);
mainGame->btnReplayPause->setVisible(true);
mainGame->btnReplayStep->setVisible(false);
mainGame->btnReplayUndo->setVisible(false);
mainGame->wPhase->setVisible(true);
mainGame->dField.panel = 0;
mainGame->dField.hovered_card = 0;
......
......@@ -221,5 +221,8 @@ char Replay::ReadInt8() {
return -1;
return *pdata++;
}
void Replay::Rewind() {
pdata = replay_data;
}
}
......@@ -41,6 +41,7 @@ public:
int ReadInt32();
short ReadInt16();
char ReadInt8();
void Rewind();
FILE* fp;
ReplayHeader pheader;
......
......@@ -14,8 +14,11 @@ bool ReplayMode::is_closing = false;
bool ReplayMode::is_pausing = false;
bool ReplayMode::is_paused = false;
bool ReplayMode::is_swaping = false;
bool ReplayMode::is_restarting = false;
bool ReplayMode::exit_pending = false;
int ReplayMode::skip_turn = 0;
int ReplayMode::current_step = 0;
int ReplayMode::skip_step = 0;
bool ReplayMode::StartReplay(int skipturn) {
skip_turn = skipturn;
......@@ -52,7 +55,7 @@ bool ReplayMode::ReadReplayResponse() {
return result;
}
int ReplayMode::ReplayThread(void* param) {
ReplayHeader rh = cur_replay.pheader;
const ReplayHeader& rh = cur_replay.pheader;
mainGame->dInfo.isFirst = true;
mtrandom rnd;
int seed = rh.seed;
......@@ -135,6 +138,8 @@ int ReplayMode::ReplayThread(void* param) {
char engineBuffer[0x1000];
is_continuing = true;
exit_pending = false;
current_step = 0;
skip_step = 0;
if(skip_turn < 0)
skip_turn = 0;
if(skip_turn) {
......@@ -181,21 +186,129 @@ int ReplayMode::ReplayThread(void* param) {
}
return 0;
}
void ReplayMode::Restart(bool refresh) {
end_duel(pduel);
mainGame->dInfo.isStarted = false;
mainGame->dField.panel = 0;
mainGame->dField.hovered_card = 0;
mainGame->dField.clicked_card = 0;
mainGame->dField.Clear();
//mainGame->device->setEventReceiver(&mainGame->dField);
cur_replay.Rewind();
const ReplayHeader& rh = cur_replay.pheader;
//mainGame->dInfo.isFirst = true;
mtrandom rnd;
int seed = rh.seed;
rnd.reset(seed);
if(rh.flag & REPLAY_TAG) {
cur_replay.ReadData(mainGame->dInfo.hostname, 40);
cur_replay.ReadData(mainGame->dInfo.hostname_tag, 40);
cur_replay.ReadData(mainGame->dInfo.clientname_tag, 40);
cur_replay.ReadData(mainGame->dInfo.clientname, 40);
mainGame->dInfo.isTag = true;
} else {
cur_replay.ReadData(mainGame->dInfo.hostname, 40);
cur_replay.ReadData(mainGame->dInfo.clientname, 40);
}
//set_card_reader((card_reader)DataManager::CardReader);
//set_message_handler((message_handler)MessageHandler);
pduel = create_duel(rnd.rand());
int start_lp = cur_replay.ReadInt32();
int start_hand = cur_replay.ReadInt32();
int draw_count = cur_replay.ReadInt32();
int opt = cur_replay.ReadInt32();
set_player_info(pduel, 0, start_lp, start_hand, draw_count);
set_player_info(pduel, 1, start_lp, start_hand, draw_count);
mainGame->dInfo.lp[0] = start_lp;
mainGame->dInfo.lp[1] = start_lp;
myswprintf(mainGame->dInfo.strLP[0], L"%d", mainGame->dInfo.lp[0]);
myswprintf(mainGame->dInfo.strLP[1], L"%d", mainGame->dInfo.lp[1]);
mainGame->dInfo.turn = 0;
mainGame->dInfo.strTurn[0] = 0;
if(!(opt & DUEL_TAG_MODE)) {
int main = cur_replay.ReadInt32();
for(int i = 0; i < main; ++i)
new_card(pduel, cur_replay.ReadInt32(), 0, 0, LOCATION_DECK, 0, POS_FACEDOWN_DEFENCE);
int extra = cur_replay.ReadInt32();
for(int i = 0; i < extra; ++i)
new_card(pduel, cur_replay.ReadInt32(), 0, 0, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENCE);
mainGame->dField.Initial(0, main, extra);
main = cur_replay.ReadInt32();
for(int i = 0; i < main; ++i)
new_card(pduel, cur_replay.ReadInt32(), 1, 1, LOCATION_DECK, 0, POS_FACEDOWN_DEFENCE);
extra = cur_replay.ReadInt32();
for(int i = 0; i < extra; ++i)
new_card(pduel, cur_replay.ReadInt32(), 1, 1, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENCE);
mainGame->dField.Initial(1, main, extra);
} else {
int main = cur_replay.ReadInt32();
for(int i = 0; i < main; ++i)
new_card(pduel, cur_replay.ReadInt32(), 0, 0, LOCATION_DECK, 0, POS_FACEDOWN_DEFENCE);
int extra = cur_replay.ReadInt32();
for(int i = 0; i < extra; ++i)
new_card(pduel, cur_replay.ReadInt32(), 0, 0, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENCE);
mainGame->dField.Initial(0, main, extra);
main = cur_replay.ReadInt32();
for(int i = 0; i < main; ++i)
new_tag_card(pduel, cur_replay.ReadInt32(), 0, LOCATION_DECK);
extra = cur_replay.ReadInt32();
for(int i = 0; i < extra; ++i)
new_tag_card(pduel, cur_replay.ReadInt32(), 0, LOCATION_EXTRA);
main = cur_replay.ReadInt32();
for(int i = 0; i < main; ++i)
new_card(pduel, cur_replay.ReadInt32(), 1, 1, LOCATION_DECK, 0, POS_FACEDOWN_DEFENCE);
extra = cur_replay.ReadInt32();
for(int i = 0; i < extra; ++i)
new_card(pduel, cur_replay.ReadInt32(), 1, 1, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENCE);
mainGame->dField.Initial(1, main, extra);
main = cur_replay.ReadInt32();
for(int i = 0; i < main; ++i)
new_tag_card(pduel, cur_replay.ReadInt32(), 1, LOCATION_DECK);
extra = cur_replay.ReadInt32();
for(int i = 0; i < extra; ++i)
new_tag_card(pduel, cur_replay.ReadInt32(), 1, LOCATION_EXTRA);
}
start_duel(pduel, opt);
if(refresh) {
mainGame->dField.RefreshAllCards();
mainGame->dInfo.isStarted = true;
//mainGame->dInfo.isReplay = true;
}
skip_turn = 0;
is_restarting = true;
}
void ReplayMode::Undo() {
Restart(false);
skip_step = current_step - 1;
if(skip_step < 0)
skip_step = 0;
current_step = 0;
if(skip_step) {
mainGame->dInfo.isReplaySkiping = true;
mainGame->gMutex.Lock();
Pause(false, false);
} else
mainGame->dInfo.isReplaySkiping = false;
}
bool ReplayMode::ReplayAnalyze(char* msg, unsigned int len) {
char* offset, *pbuf = msg;
char* pbuf = msg;
int player, count;
bool pauseable;
is_restarting = false;
while (pbuf - msg < (int)len) {
if(is_closing)
return false;
if(is_restarting) {
is_restarting = false;
return true;
}
if(is_swaping) {
mainGame->gMutex.Lock();
mainGame->dField.ReplaySwap();
mainGame->gMutex.Unlock();
is_swaping = false;
}
offset = pbuf;
pauseable = true;
char* offset = pbuf;
bool pauseable = true;
mainGame->dInfo.curMsg = BufferIO::ReadUInt8(pbuf);
switch (mainGame->dInfo.curMsg) {
case MSG_RETRY: {
......@@ -662,11 +775,24 @@ bool ReplayMode::ReplayAnalyze(char* msg, unsigned int len) {
break;
}
}
if(pauseable && is_pausing) {
is_paused = true;
mainGame->actionSignal.Reset();
mainGame->actionSignal.Wait();
is_paused = false;
if(pauseable) {
if(skip_step) {
skip_step--;
if(skip_step == 0) {
Pause(true, false);
mainGame->dInfo.isStarted = true;
mainGame->dInfo.isReplaySkiping = false;
mainGame->dField.RefreshAllCards();
mainGame->gMutex.Unlock();
}
}
if(is_pausing) {
is_paused = true;
mainGame->actionSignal.Reset();
mainGame->actionSignal.Wait();
is_paused = false;
}
current_step++;
}
}
return true;
......
......@@ -17,8 +17,11 @@ private:
static bool is_pausing;
static bool is_paused;
static bool is_swaping;
static bool is_restarting;
static bool exit_pending;
static int skip_turn;
static int current_step;
static int skip_step;
public:
static Replay cur_replay;
......@@ -30,6 +33,8 @@ public:
static void Pause(bool is_pause, bool is_step);
static bool ReadReplayResponse();
static int ReplayThread(void* param);
static void Restart(bool refresh);
static void Undo();
static bool ReplayAnalyze(char* msg, unsigned int len);
static void ReplayRefresh(int flag = 0x781fff);
......
......@@ -328,6 +328,7 @@
!system 1352 主要信息:
!system 1353 播放起始于回合:
!system 1354 不显示卡片系列
!system 1360 上一步
!system 1390 等待行动中...
!system 1391 等待行动中....
!system 1392 等待行动中.....
......
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