Browse Source

Fix demomode line endings

pull/3781/head
Gleb Mazovetskiy 4 years ago
parent
commit
1f2d67f98b
  1. 602
      Source/engine/demomode.cpp
  2. 62
      Source/engine/demomode.h

602
Source/engine/demomode.cpp

@ -1,301 +1,301 @@
/** /**
* @file animationinfo.h * @file animationinfo.h
* *
* Contains most of the the demomode specific logic * Contains most of the the demomode specific logic
*/ */
#include <deque> #include <deque>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include "demomode.h" #include "demomode.h"
#include "menu.h" #include "menu.h"
#include "nthread.h" #include "nthread.h"
#include "options.h" #include "options.h"
#include "pfile.h" #include "pfile.h"
#include "utils/display.h" #include "utils/display.h"
#include "utils/paths.h" #include "utils/paths.h"
namespace devilution { namespace devilution {
namespace { namespace {
enum class DemoMsgType { enum class DemoMsgType {
GameTick = 0, GameTick = 0,
Rendering = 1, Rendering = 1,
Message = 2, Message = 2,
}; };
struct demoMsg { struct demoMsg {
DemoMsgType type; DemoMsgType type;
uint32_t message; uint32_t message;
int32_t wParam; int32_t wParam;
int32_t lParam; int32_t lParam;
float progressToNextGameTick; float progressToNextGameTick;
}; };
int DemoNumber = -1; int DemoNumber = -1;
bool Timedemo = false; bool Timedemo = false;
int RecordNumber = -1; int RecordNumber = -1;
std::ofstream DemoRecording; std::ofstream DemoRecording;
std::deque<demoMsg> Demo_Message_Queue; std::deque<demoMsg> Demo_Message_Queue;
uint32_t DemoModeLastTick = 0; uint32_t DemoModeLastTick = 0;
int LogicTick = 0; int LogicTick = 0;
int StartTime = 0; int StartTime = 0;
int DemoGraphicsWidth = 640; int DemoGraphicsWidth = 640;
int DemoGraphicsHeight = 480; int DemoGraphicsHeight = 480;
void PumpDemoMessage(DemoMsgType demoMsgType, uint32_t message, int32_t wParam, int32_t lParam, float progressToNextGameTick) void PumpDemoMessage(DemoMsgType demoMsgType, uint32_t message, int32_t wParam, int32_t lParam, float progressToNextGameTick)
{ {
demoMsg msg; demoMsg msg;
msg.type = demoMsgType; msg.type = demoMsgType;
msg.message = message; msg.message = message;
msg.wParam = wParam; msg.wParam = wParam;
msg.lParam = lParam; msg.lParam = lParam;
msg.progressToNextGameTick = progressToNextGameTick; msg.progressToNextGameTick = progressToNextGameTick;
Demo_Message_Queue.push_back(msg); Demo_Message_Queue.push_back(msg);
} }
bool LoadDemoMessages(int i) bool LoadDemoMessages(int i)
{ {
std::ifstream demofile; std::ifstream demofile;
char demoFilename[16]; char demoFilename[16];
snprintf(demoFilename, 15, "demo_%d.dmo", i); snprintf(demoFilename, 15, "demo_%d.dmo", i);
demofile.open(paths::PrefPath() + demoFilename); demofile.open(paths::PrefPath() + demoFilename);
if (!demofile.is_open()) { if (!demofile.is_open()) {
return false; return false;
} }
std::string line; std::string line;
std::getline(demofile, line); std::getline(demofile, line);
std::stringstream header(line); std::stringstream header(line);
std::string number; std::string number;
std::getline(header, number, ','); // Demo version std::getline(header, number, ','); // Demo version
if (std::stoi(number) != 0) { if (std::stoi(number) != 0) {
return false; return false;
} }
std::getline(header, number, ','); std::getline(header, number, ',');
gSaveNumber = std::stoi(number); gSaveNumber = std::stoi(number);
std::getline(header, number, ','); std::getline(header, number, ',');
DemoGraphicsWidth = std::stoi(number); DemoGraphicsWidth = std::stoi(number);
std::getline(header, number, ','); std::getline(header, number, ',');
DemoGraphicsHeight = std::stoi(number); DemoGraphicsHeight = std::stoi(number);
while (std::getline(demofile, line)) { while (std::getline(demofile, line)) {
std::stringstream command(line); std::stringstream command(line);
std::getline(command, number, ','); std::getline(command, number, ',');
int typeNum = std::stoi(number); int typeNum = std::stoi(number);
auto type = static_cast<DemoMsgType>(typeNum); auto type = static_cast<DemoMsgType>(typeNum);
std::getline(command, number, ','); std::getline(command, number, ',');
float progressToNextGameTick = std::stof(number); float progressToNextGameTick = std::stof(number);
switch (type) { switch (type) {
case DemoMsgType::Message: { case DemoMsgType::Message: {
std::getline(command, number, ','); std::getline(command, number, ',');
uint32_t message = std::stoi(number); uint32_t message = std::stoi(number);
std::getline(command, number, ','); std::getline(command, number, ',');
int32_t wParam = std::stoi(number); int32_t wParam = std::stoi(number);
std::getline(command, number, ','); std::getline(command, number, ',');
int32_t lParam = std::stoi(number); int32_t lParam = std::stoi(number);
PumpDemoMessage(type, message, wParam, lParam, progressToNextGameTick); PumpDemoMessage(type, message, wParam, lParam, progressToNextGameTick);
break; break;
} }
default: default:
PumpDemoMessage(type, 0, 0, 0, progressToNextGameTick); PumpDemoMessage(type, 0, 0, 0, progressToNextGameTick);
break; break;
} }
} }
demofile.close(); demofile.close();
DemoModeLastTick = SDL_GetTicks(); DemoModeLastTick = SDL_GetTicks();
return true; return true;
} }
} // namespace } // namespace
namespace demo { namespace demo {
void InitPlayBack(int demoNumber, bool timedemo) void InitPlayBack(int demoNumber, bool timedemo)
{ {
DemoNumber = demoNumber; DemoNumber = demoNumber;
Timedemo = timedemo; Timedemo = timedemo;
if (!LoadDemoMessages(demoNumber)) { if (!LoadDemoMessages(demoNumber)) {
SDL_Log("Unable to load demo file"); SDL_Log("Unable to load demo file");
diablo_quit(1); diablo_quit(1);
} }
} }
void InitRecording(int recordNumber) void InitRecording(int recordNumber)
{ {
RecordNumber = recordNumber; RecordNumber = recordNumber;
} }
void OverrideOptions() void OverrideOptions()
{ {
#ifndef USE_SDL1 #ifndef USE_SDL1
sgOptions.Graphics.fitToScreen.SetValue(false); sgOptions.Graphics.fitToScreen.SetValue(false);
#endif #endif
#if SDL_VERSION_ATLEAST(2, 0, 0) #if SDL_VERSION_ATLEAST(2, 0, 0)
sgOptions.Graphics.bHardwareCursor = false; sgOptions.Graphics.bHardwareCursor = false;
#endif #endif
if (Timedemo) { if (Timedemo) {
#ifndef USE_SDL1 #ifndef USE_SDL1
sgOptions.Graphics.vSync.SetValue(false); sgOptions.Graphics.vSync.SetValue(false);
#endif #endif
sgOptions.Graphics.limitFPS.SetValue(false); sgOptions.Graphics.limitFPS.SetValue(false);
} }
} }
bool IsRunning() bool IsRunning()
{ {
return DemoNumber != -1; return DemoNumber != -1;
} }
bool IsRecording() bool IsRecording()
{ {
return RecordNumber != -1; return RecordNumber != -1;
}; };
bool GetRunGameLoop(bool &drawGame, bool &processInput) bool GetRunGameLoop(bool &drawGame, bool &processInput)
{ {
if (Demo_Message_Queue.empty()) if (Demo_Message_Queue.empty())
app_fatal("Demo queue empty"); app_fatal("Demo queue empty");
demoMsg dmsg = Demo_Message_Queue.front(); demoMsg dmsg = Demo_Message_Queue.front();
if (dmsg.type == DemoMsgType::Message) if (dmsg.type == DemoMsgType::Message)
app_fatal("Unexpected Message"); app_fatal("Unexpected Message");
if (Timedemo) { if (Timedemo) {
// disable additonal rendering to speedup replay // disable additonal rendering to speedup replay
drawGame = dmsg.type == DemoMsgType::GameTick; drawGame = dmsg.type == DemoMsgType::GameTick;
} else { } else {
int currentTickCount = SDL_GetTicks(); int currentTickCount = SDL_GetTicks();
int ticksElapsed = currentTickCount - DemoModeLastTick; int ticksElapsed = currentTickCount - DemoModeLastTick;
bool tickDue = ticksElapsed >= gnTickDelay; bool tickDue = ticksElapsed >= gnTickDelay;
drawGame = false; drawGame = false;
if (tickDue) { if (tickDue) {
if (dmsg.type == DemoMsgType::GameTick) { if (dmsg.type == DemoMsgType::GameTick) {
DemoModeLastTick = currentTickCount; DemoModeLastTick = currentTickCount;
} }
} else { } else {
float progressToNextGameTick = clamp((float)ticksElapsed / (float)gnTickDelay, 0.F, 1.F); float progressToNextGameTick = clamp((float)ticksElapsed / (float)gnTickDelay, 0.F, 1.F);
if (dmsg.type == DemoMsgType::GameTick || dmsg.progressToNextGameTick > progressToNextGameTick) { if (dmsg.type == DemoMsgType::GameTick || dmsg.progressToNextGameTick > progressToNextGameTick) {
// we are ahead of the replay => add a additional rendering for smoothness // we are ahead of the replay => add a additional rendering for smoothness
gfProgressToNextGameTick = progressToNextGameTick; gfProgressToNextGameTick = progressToNextGameTick;
processInput = false; processInput = false;
drawGame = true; drawGame = true;
return false; return false;
} }
} }
} }
gfProgressToNextGameTick = dmsg.progressToNextGameTick; gfProgressToNextGameTick = dmsg.progressToNextGameTick;
Demo_Message_Queue.pop_front(); Demo_Message_Queue.pop_front();
if (dmsg.type == DemoMsgType::GameTick) if (dmsg.type == DemoMsgType::GameTick)
LogicTick++; LogicTick++;
return dmsg.type == DemoMsgType::GameTick; return dmsg.type == DemoMsgType::GameTick;
} }
bool FetchMessage(tagMSG *lpMsg) bool FetchMessage(tagMSG *lpMsg)
{ {
SDL_Event e; SDL_Event e;
if (SDL_PollEvent(&e) != 0) { if (SDL_PollEvent(&e) != 0) {
if (e.type == SDL_QUIT) { if (e.type == SDL_QUIT) {
lpMsg->message = DVL_WM_QUIT; lpMsg->message = DVL_WM_QUIT;
lpMsg->lParam = 0; lpMsg->lParam = 0;
lpMsg->wParam = 0; lpMsg->wParam = 0;
return true; return true;
} }
if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE) { if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE) {
Demo_Message_Queue.clear(); Demo_Message_Queue.clear();
ClearMessageQueue(); ClearMessageQueue();
DemoNumber = -1; DemoNumber = -1;
Timedemo = false; Timedemo = false;
last_tick = SDL_GetTicks(); last_tick = SDL_GetTicks();
} }
if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_KP_PLUS && sgGameInitInfo.nTickRate < 255) { if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_KP_PLUS && sgGameInitInfo.nTickRate < 255) {
sgGameInitInfo.nTickRate++; sgGameInitInfo.nTickRate++;
sgOptions.Gameplay.nTickRate = sgGameInitInfo.nTickRate; sgOptions.Gameplay.nTickRate = sgGameInitInfo.nTickRate;
gnTickDelay = 1000 / sgGameInitInfo.nTickRate; gnTickDelay = 1000 / sgGameInitInfo.nTickRate;
} }
if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_KP_MINUS && sgGameInitInfo.nTickRate > 1) { if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_KP_MINUS && sgGameInitInfo.nTickRate > 1) {
sgGameInitInfo.nTickRate--; sgGameInitInfo.nTickRate--;
sgOptions.Gameplay.nTickRate = sgGameInitInfo.nTickRate; sgOptions.Gameplay.nTickRate = sgGameInitInfo.nTickRate;
gnTickDelay = 1000 / sgGameInitInfo.nTickRate; gnTickDelay = 1000 / sgGameInitInfo.nTickRate;
} }
} }
if (!Demo_Message_Queue.empty()) { if (!Demo_Message_Queue.empty()) {
demoMsg dmsg = Demo_Message_Queue.front(); demoMsg dmsg = Demo_Message_Queue.front();
if (dmsg.type == DemoMsgType::Message) { if (dmsg.type == DemoMsgType::Message) {
lpMsg->message = dmsg.message; lpMsg->message = dmsg.message;
lpMsg->lParam = dmsg.lParam; lpMsg->lParam = dmsg.lParam;
lpMsg->wParam = dmsg.wParam; lpMsg->wParam = dmsg.wParam;
gfProgressToNextGameTick = dmsg.progressToNextGameTick; gfProgressToNextGameTick = dmsg.progressToNextGameTick;
Demo_Message_Queue.pop_front(); Demo_Message_Queue.pop_front();
return true; return true;
} }
} }
lpMsg->message = 0; lpMsg->message = 0;
lpMsg->lParam = 0; lpMsg->lParam = 0;
lpMsg->wParam = 0; lpMsg->wParam = 0;
return false; return false;
} }
void RecordGameLoopResult(bool runGameLoop) void RecordGameLoopResult(bool runGameLoop)
{ {
DemoRecording << static_cast<uint32_t>(runGameLoop ? DemoMsgType::GameTick : DemoMsgType::Rendering) << "," << gfProgressToNextGameTick << "\n"; DemoRecording << static_cast<uint32_t>(runGameLoop ? DemoMsgType::GameTick : DemoMsgType::Rendering) << "," << gfProgressToNextGameTick << "\n";
} }
void RecordMessage(tagMSG *lpMsg) void RecordMessage(tagMSG *lpMsg)
{ {
if (!gbRunGame || !DemoRecording.is_open()) if (!gbRunGame || !DemoRecording.is_open())
return; return;
DemoRecording << static_cast<uint32_t>(DemoMsgType::Message) << "," << gfProgressToNextGameTick << "," << lpMsg->message << "," << lpMsg->wParam << "," << lpMsg->lParam << "\n"; DemoRecording << static_cast<uint32_t>(DemoMsgType::Message) << "," << gfProgressToNextGameTick << "," << lpMsg->message << "," << lpMsg->wParam << "," << lpMsg->lParam << "\n";
} }
void NotifyGameLoopStart() void NotifyGameLoopStart()
{ {
if (IsRecording()) { if (IsRecording()) {
char demoFilename[16]; char demoFilename[16];
snprintf(demoFilename, 15, "demo_%d.dmo", RecordNumber); snprintf(demoFilename, 15, "demo_%d.dmo", RecordNumber);
DemoRecording.open(paths::PrefPath() + demoFilename, std::fstream::trunc); DemoRecording.open(paths::PrefPath() + demoFilename, std::fstream::trunc);
DemoRecording << "0," << gSaveNumber << "," << gnScreenWidth << "," << gnScreenHeight << "\n"; DemoRecording << "0," << gSaveNumber << "," << gnScreenWidth << "," << gnScreenHeight << "\n";
} }
if (IsRunning()) { if (IsRunning()) {
StartTime = SDL_GetTicks(); StartTime = SDL_GetTicks();
LogicTick = 0; LogicTick = 0;
} }
} }
void NotifyGameLoopEnd() void NotifyGameLoopEnd()
{ {
if (IsRecording()) { if (IsRecording()) {
DemoRecording.close(); DemoRecording.close();
RecordNumber = -1; RecordNumber = -1;
} }
if (IsRunning()) { if (IsRunning()) {
float secounds = (SDL_GetTicks() - StartTime) / 1000.0; float secounds = (SDL_GetTicks() - StartTime) / 1000.0;
SDL_Log("%d frames, %.2f seconds: %.1f fps", LogicTick, secounds, LogicTick / secounds); SDL_Log("%d frames, %.2f seconds: %.1f fps", LogicTick, secounds, LogicTick / secounds);
gbRunGameResult = false; gbRunGameResult = false;
gbRunGame = false; gbRunGame = false;
} }
} }
} // namespace demo } // namespace demo
} // namespace devilution } // namespace devilution

62
Source/engine/demomode.h

@ -1,31 +1,31 @@
/** /**
* @file animationinfo.h * @file animationinfo.h
* *
* Contains most of the the demomode specific logic * Contains most of the the demomode specific logic
*/ */
#pragma once #pragma once
#include "miniwin/miniwin.h" #include "miniwin/miniwin.h"
namespace devilution { namespace devilution {
namespace demo { namespace demo {
void InitPlayBack(int demoNumber, bool timedemo); void InitPlayBack(int demoNumber, bool timedemo);
void InitRecording(int recordNumber); void InitRecording(int recordNumber);
void OverrideOptions(); void OverrideOptions();
bool IsRunning(); bool IsRunning();
bool IsRecording(); bool IsRecording();
bool GetRunGameLoop(bool &drawGame, bool &processInput); bool GetRunGameLoop(bool &drawGame, bool &processInput);
bool FetchMessage(tagMSG *lpMsg); bool FetchMessage(tagMSG *lpMsg);
void RecordGameLoopResult(bool runGameLoop); void RecordGameLoopResult(bool runGameLoop);
void RecordMessage(tagMSG *lpMsg); void RecordMessage(tagMSG *lpMsg);
void NotifyGameLoopStart(); void NotifyGameLoopStart();
void NotifyGameLoopEnd(); void NotifyGameLoopEnd();
} // namespace demo } // namespace demo
} // namespace devilution } // namespace devilution

Loading…
Cancel
Save