mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-25 11:52:40 +01:00
Migrate first save state struct and update loading
This commit is contained in:
parent
1df6b5c38f
commit
d7604531eb
@ -14,6 +14,56 @@ class ScriptMachine;
|
||||
class PlayerController;
|
||||
struct CutsceneData;
|
||||
|
||||
struct SystemTime
|
||||
{
|
||||
uint16_t year;
|
||||
uint16_t month;
|
||||
uint16_t dayOfWeek;
|
||||
uint16_t day;
|
||||
uint16_t hour;
|
||||
uint16_t minute;
|
||||
uint16_t second;
|
||||
uint16_t millisecond;
|
||||
};
|
||||
|
||||
/** Block 0 State */
|
||||
struct BasicState
|
||||
{
|
||||
/// /!\ This is wchar_t[24] in the original format /!\ we convert on load for convenience
|
||||
char saveName[48];
|
||||
SystemTime saveTime;
|
||||
uint16_t unknown;
|
||||
uint16_t islandNumber;
|
||||
glm::vec3 cameraPosition;
|
||||
uint16_t gameMinuteMS;
|
||||
uint16_t lastTick;
|
||||
uint8_t gameHour;
|
||||
uint8_t _align0[3];
|
||||
uint8_t gameMinute;
|
||||
uint8_t _align1[3];
|
||||
uint16_t padMode;
|
||||
uint8_t _align2[2];
|
||||
uint16_t timeMS;
|
||||
float timeScale;
|
||||
float timeStep;
|
||||
float timeStep_unclipped; // Unknown purpose
|
||||
uint16_t frameCounter;
|
||||
float timeStep2;
|
||||
float framesPerUpdate;
|
||||
float timeScale2;
|
||||
uint16_t lastWeather;
|
||||
uint8_t _align3[2];
|
||||
uint16_t nextWeather;
|
||||
uint8_t _align4[2];
|
||||
uint16_t forcedWeather;
|
||||
uint8_t _align5[2];
|
||||
float weatherInterpolation;
|
||||
uint8_t dateTime[24]; // Unused
|
||||
uint16_t weatherType;
|
||||
float cameraData;
|
||||
float cameraData2;
|
||||
};
|
||||
|
||||
struct TextDisplayData
|
||||
{
|
||||
// This is set by the final display text command.
|
||||
|
@ -4,17 +4,19 @@
|
||||
|
||||
#include <rw/types.hpp>
|
||||
|
||||
#include <engine/GameState.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct GameState;
|
||||
class GameWorld;
|
||||
class ScriptMachine;
|
||||
|
||||
struct SaveGameInfo
|
||||
{
|
||||
std::string saveName;
|
||||
std::string savePath;
|
||||
bool valid;
|
||||
BasicState basicState;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -40,7 +42,7 @@ public:
|
||||
*/
|
||||
static bool loadGame(GameState& state, const std::string& file);
|
||||
|
||||
static SaveGameInfo getSaveInfo(const std::string& file);
|
||||
static bool getSaveInfo(const std::string& file, BasicState* outState);
|
||||
|
||||
/**
|
||||
* Returns save game information for all found saves
|
||||
|
@ -17,48 +17,6 @@ typedef uint16_t BlockWord;
|
||||
typedef uint32_t BlockDword;
|
||||
typedef BlockDword BlockSize;
|
||||
|
||||
struct Block0Data {
|
||||
uint16_t saveName[24];
|
||||
BlockWord year;
|
||||
BlockWord month;
|
||||
BlockWord weekday;
|
||||
BlockWord day;
|
||||
BlockWord hour;
|
||||
BlockWord minute;
|
||||
BlockWord second;
|
||||
BlockWord milliseconds;
|
||||
BlockDword unknown;
|
||||
BlockDword islandNumber;
|
||||
glm::vec3 cameraPosition;
|
||||
BlockDword gameMinuteMS;
|
||||
BlockDword lastTick;
|
||||
uint8_t gameHour;
|
||||
uint8_t _align0[3];
|
||||
uint8_t gameMinute;
|
||||
uint8_t _align1[3];
|
||||
BlockWord padMode;
|
||||
uint8_t _align2[2];
|
||||
BlockDword timeMS;
|
||||
float timeScale;
|
||||
float timeStep;
|
||||
float timeStep_unclipped; // Unknown purpose
|
||||
BlockDword frameCounter;
|
||||
float timeStep2;
|
||||
float framesPerUpdate;
|
||||
float timeScale2;
|
||||
BlockWord lastWeather;
|
||||
uint8_t _align3[2];
|
||||
BlockWord nextWeather;
|
||||
uint8_t _align4[2];
|
||||
BlockWord forcedWeather;
|
||||
uint8_t _align5[2];
|
||||
float weatherInterpolation;
|
||||
uint8_t dateTime[24]; // Unused
|
||||
BlockDword weatherType;
|
||||
float cameraData;
|
||||
float cameraData2;
|
||||
};
|
||||
|
||||
struct Block0ContactInfo {
|
||||
BlockDword missionFlag;
|
||||
BlockDword baseBrief;
|
||||
@ -252,7 +210,7 @@ void SaveGame::writeGame(GameState& state, const std::string& file)
|
||||
std::FILE* saveFile = std::fopen(file.c_str(), "w");
|
||||
|
||||
// BLOCK 0 - Variables
|
||||
Block0Data block0Data = {};
|
||||
BasicState block0Data = {};
|
||||
//strcpy(block0Data.saveName, "OpenRW Save Game");
|
||||
block0Data.islandNumber = 1;
|
||||
block0Data.cameraPosition = glm::vec3(0.f);
|
||||
@ -340,8 +298,8 @@ bool SaveGame::loadGame(GameState& state, const std::string& file)
|
||||
BlockDword blockSize;
|
||||
fread(&blockSize, sizeof(BlockDword), 1, loadFile);
|
||||
|
||||
Block0Data block0Data;
|
||||
fread(&block0Data, sizeof(block0Data), 1, loadFile);
|
||||
BasicState block0Data;
|
||||
fread(&block0Data, sizeof(BasicState), 1, loadFile);
|
||||
|
||||
BlockDword scriptBlockSize;
|
||||
fread(&scriptBlockSize, sizeof(BlockDword), 1, loadFile);
|
||||
@ -489,30 +447,40 @@ bool SaveGame::loadGame(GameState& state, const std::string& file)
|
||||
|
||||
#include <iconv.h>
|
||||
#include <dirent.h>
|
||||
SaveGameInfo SaveGame::getSaveInfo(const std::string& file)
|
||||
bool SaveGame::getSaveInfo(const std::string& file, BasicState *basicState)
|
||||
{
|
||||
std::FILE* loadFile = std::fopen(file.c_str(), "r");
|
||||
|
||||
SaveGameInfo info;
|
||||
info.savePath = file;
|
||||
|
||||
// BLOCK 0
|
||||
BlockDword blockSize;
|
||||
fread(&blockSize, sizeof(BlockDword), 1, loadFile);
|
||||
if( fread(&blockSize, sizeof(BlockDword), 1, loadFile) == 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Block0Data block0Data;
|
||||
fread(&block0Data, sizeof(block0Data), 1, loadFile);
|
||||
// Read block 0 into state
|
||||
if( fread(basicState, sizeof(BasicState), 1, loadFile) == 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::fclose(loadFile);
|
||||
size_t bytes = 0;
|
||||
for(;; bytes++ ) {
|
||||
if(block0Data.saveName[bytes-1] == 0 && block0Data.saveName[bytes] == 0) break;
|
||||
if(basicState->saveName[bytes-1] == 0 && basicState->saveName[bytes] == 0) break;
|
||||
}
|
||||
size_t len = bytes/2;
|
||||
size_t outSize = 24;
|
||||
char outBuff[outSize];
|
||||
char outBuff[48];
|
||||
char* outCur = outBuff;
|
||||
auto icv = iconv_open("UTF-8", "UTF-16");
|
||||
char* saveName = (char*)block0Data.saveName;
|
||||
char* saveName = (char*)basicState->saveName;
|
||||
|
||||
// Convert to UTF-8 and copy back to the return struct
|
||||
iconv(icv, &saveName, &bytes, &outCur, &outSize);
|
||||
return { std::string(outBuff), file };
|
||||
strcpy(basicState->saveName, outBuff);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector< SaveGameInfo > SaveGame::getAllSaveGameInfo()
|
||||
@ -540,7 +508,9 @@ std::vector< SaveGameInfo > SaveGame::getAllSaveGameInfo()
|
||||
if ( ep->d_type == DT_REG ) {
|
||||
realName = ep->d_name;
|
||||
if(realName.find(".b") != realName.npos) {
|
||||
infos.push_back(getSaveInfo(gamePath+"/"+realName));
|
||||
std::string path = gamePath+"/"+realName;
|
||||
infos.emplace_back(SaveGameInfo{path, false, {}});
|
||||
infos.back().valid = getSaveInfo(infos.back().savePath, &infos.back().basicState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,14 +31,22 @@ void MenuState::enterMainMenu()
|
||||
void MenuState::enterLoadMenu()
|
||||
{
|
||||
Menu *m = new Menu(2);
|
||||
m->offset = glm::vec2(200.f, 200.f);
|
||||
m->offset = glm::vec2(20.f, 30.f);
|
||||
m->addEntry(Menu::lambda("Back", [=] { enterMainMenu(); }));
|
||||
auto saves = SaveGame::getAllSaveGameInfo();
|
||||
for(SaveGameInfo& save : saves) {
|
||||
m->addEntry(Menu::lambda(save.saveName, [=] {
|
||||
StateManager::get().enter(new IngameState(game, false));
|
||||
game->loadGame(save.savePath);
|
||||
}));
|
||||
if (save.valid) {
|
||||
std::stringstream ss;
|
||||
ss << save.basicState.saveTime.year << "/" << save.basicState.saveTime.month << "/" << save.basicState.saveTime.day
|
||||
<< " " << save.basicState.saveTime.hour << ":" << save.basicState.saveTime.minute << " " << save.basicState.saveName;
|
||||
m->addEntry(Menu::lambda(ss.str(), [=] {
|
||||
StateManager::get().enter(new IngameState(game, false));
|
||||
game->loadGame(save.savePath);
|
||||
}, 20.f));
|
||||
}
|
||||
else {
|
||||
m->addEntry(Menu::lambda("Corrupt", [=] { }));
|
||||
}
|
||||
}
|
||||
this->enterMenu(m);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user