mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Replay: Prep side data structure.
This commit is contained in:
parent
89186d8113
commit
76e2a40e5f
1 changed files with 71 additions and 27 deletions
|
@ -28,9 +28,10 @@ enum class ReplayState {
|
||||||
SAVE,
|
SAVE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// File data formats below.
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
|
|
||||||
struct ReplayItem {
|
struct ReplayItemHeader {
|
||||||
ReplayAction action;
|
ReplayAction action;
|
||||||
uint64_t timestamp;
|
uint64_t timestamp;
|
||||||
union {
|
union {
|
||||||
|
@ -38,33 +39,52 @@ struct ReplayItem {
|
||||||
uint8_t analog[2][2];
|
uint8_t analog[2][2];
|
||||||
uint32_t result;
|
uint32_t result;
|
||||||
uint64_t result64;
|
uint64_t result64;
|
||||||
// TODO: Where do we store read data?
|
// NOTE: Certain action types have data, always sized by this/result.
|
||||||
struct {
|
uint32_t size;
|
||||||
uint32_t offset;
|
|
||||||
uint32_t size;
|
|
||||||
} read;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ReplayItem(ReplayAction a, uint64_t t) {
|
ReplayItemHeader(ReplayAction a, uint64_t t) {
|
||||||
action = a;
|
action = a;
|
||||||
timestamp = t;
|
timestamp = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReplayItem(ReplayAction a, uint64_t t, uint32_t v) : ReplayItem(a, t) {
|
ReplayItemHeader(ReplayAction a, uint64_t t, uint32_t v) : ReplayItemHeader(a, t) {
|
||||||
result = v;
|
result = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReplayItem(ReplayAction a, uint64_t t, uint64_t v) : ReplayItem(a, t) {
|
ReplayItemHeader(ReplayAction a, uint64_t t, uint64_t v) : ReplayItemHeader(a, t) {
|
||||||
result64 = v;
|
result64 = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReplayItem(ReplayAction a, uint64_t t, uint8_t v[2][2]) : ReplayItem(a, t) {
|
ReplayItemHeader(ReplayAction a, uint64_t t, uint8_t v[2][2]) : ReplayItemHeader(a, t) {
|
||||||
memcpy(analog, v, sizeof(analog));
|
memcpy(analog, v, sizeof(analog));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const int REPLAY_MAX_FILENAME = 256;
|
||||||
|
|
||||||
|
struct ReplayFileInfo {
|
||||||
|
char filename[REPLAY_MAX_FILENAME]{};
|
||||||
|
int64_t size = 0;
|
||||||
|
uint16_t access = 0;
|
||||||
|
uint8_t exists = 0;
|
||||||
|
uint8_t isDirectory = 0;
|
||||||
|
|
||||||
|
int64_t atime = 0;
|
||||||
|
int64_t ctime = 0;
|
||||||
|
int64_t mtime = 0;
|
||||||
|
};
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
struct ReplayItem {
|
||||||
|
ReplayItemHeader info;
|
||||||
|
std::vector<u8> data;
|
||||||
|
|
||||||
|
ReplayItem(ReplayItemHeader h) : info(h) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static std::vector<ReplayItem> replayItems;
|
static std::vector<ReplayItem> replayItems;
|
||||||
static ReplayState replayState = ReplayState::IDLE;
|
static ReplayState replayState = ReplayState::IDLE;
|
||||||
|
|
||||||
|
@ -74,25 +94,25 @@ static uint8_t lastAnalog[2][2];
|
||||||
|
|
||||||
static void ReplaySaveCtrl(uint32_t &buttons, uint8_t analog[2][2], uint64_t t) {
|
static void ReplaySaveCtrl(uint32_t &buttons, uint8_t analog[2][2], uint64_t t) {
|
||||||
if (lastButtons != buttons) {
|
if (lastButtons != buttons) {
|
||||||
replayItems.push_back({ ReplayAction::BUTTONS, t, buttons });
|
replayItems.push_back(ReplayItemHeader(ReplayAction::BUTTONS, t, buttons));
|
||||||
lastButtons = buttons;
|
lastButtons = buttons;
|
||||||
}
|
}
|
||||||
if (memcmp(lastAnalog, analog, sizeof(lastAnalog)) != 0) {
|
if (memcmp(lastAnalog, analog, sizeof(lastAnalog)) != 0) {
|
||||||
replayItems.push_back({ ReplayAction::ANALOG, t, analog });
|
replayItems.push_back(ReplayItemHeader(ReplayAction::ANALOG, t, analog));
|
||||||
memcpy(lastAnalog, analog, sizeof(lastAnalog));
|
memcpy(lastAnalog, analog, sizeof(lastAnalog));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ReplayExecuteCtrl(uint32_t &buttons, uint8_t analog[2][2], uint64_t t) {
|
static void ReplayExecuteCtrl(uint32_t &buttons, uint8_t analog[2][2], uint64_t t) {
|
||||||
for (; replayCtrlPos < replayItems.size() && t >= replayItems[replayCtrlPos].timestamp; ++replayCtrlPos) {
|
for (; replayCtrlPos < replayItems.size() && t >= replayItems[replayCtrlPos].info.timestamp; ++replayCtrlPos) {
|
||||||
const auto &item = replayItems[replayCtrlPos];
|
const auto &item = replayItems[replayCtrlPos];
|
||||||
switch (item.action) {
|
switch (item.info.action) {
|
||||||
case ReplayAction::BUTTONS:
|
case ReplayAction::BUTTONS:
|
||||||
buttons = item.buttons;
|
buttons = item.info.buttons;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ReplayAction::ANALOG:
|
case ReplayAction::ANALOG:
|
||||||
memcpy(analog, item.analog, sizeof(analog));
|
memcpy(analog, item.info.analog, sizeof(analog));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -126,7 +146,7 @@ uint32_t ReplayApplyDisk(ReplayAction action, uint32_t result, uint64_t t) {
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
case ReplayState::SAVE:
|
case ReplayState::SAVE:
|
||||||
replayItems.push_back({ action, t, result });
|
replayItems.push_back(ReplayItemHeader(action, t, result));
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
case ReplayState::IDLE:
|
case ReplayState::IDLE:
|
||||||
|
@ -143,7 +163,7 @@ uint64_t ReplayApplyDisk64(ReplayAction action, uint64_t result, uint64_t t) {
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
case ReplayState::SAVE:
|
case ReplayState::SAVE:
|
||||||
replayItems.push_back({ action, t, result });
|
replayItems.push_back(ReplayItemHeader(action, t, result));
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
case ReplayState::IDLE:
|
case ReplayState::IDLE:
|
||||||
|
@ -160,10 +180,13 @@ uint32_t ReplayApplyDiskRead(void *data, uint32_t readSize, uint32_t dataSize, u
|
||||||
return readSize;
|
return readSize;
|
||||||
|
|
||||||
case ReplayState::SAVE:
|
case ReplayState::SAVE:
|
||||||
// TODO
|
{
|
||||||
//replayItems.push_back({ action, t, readSize });
|
ReplayItem item = ReplayItemHeader(ReplayAction::FILE_READ, t, readSize);
|
||||||
//data?
|
item.data.resize(readSize);
|
||||||
|
memcpy(&item.data[0], data, readSize);
|
||||||
|
replayItems.push_back(item);
|
||||||
return readSize;
|
return readSize;
|
||||||
|
}
|
||||||
|
|
||||||
case ReplayState::IDLE:
|
case ReplayState::IDLE:
|
||||||
default:
|
default:
|
||||||
|
@ -171,6 +194,16 @@ uint32_t ReplayApplyDiskRead(void *data, uint32_t readSize, uint32_t dataSize, u
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReplayFileInfo ConvertFileInfo(const PSPFileInfo &data) {
|
||||||
|
// TODO
|
||||||
|
return ReplayFileInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
PSPFileInfo ConvertFileInfo(const ReplayFileInfo &data) {
|
||||||
|
// TODO
|
||||||
|
return PSPFileInfo();
|
||||||
|
}
|
||||||
|
|
||||||
PSPFileInfo ReplayApplyDiskFileInfo(const PSPFileInfo &data, uint64_t t) {
|
PSPFileInfo ReplayApplyDiskFileInfo(const PSPFileInfo &data, uint64_t t) {
|
||||||
switch (replayState) {
|
switch (replayState) {
|
||||||
case ReplayState::EXECUTE:
|
case ReplayState::EXECUTE:
|
||||||
|
@ -179,10 +212,14 @@ PSPFileInfo ReplayApplyDiskFileInfo(const PSPFileInfo &data, uint64_t t) {
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
case ReplayState::SAVE:
|
case ReplayState::SAVE:
|
||||||
// TODO
|
{
|
||||||
//replayItems.push_back({ action, t });
|
ReplayFileInfo info = ConvertFileInfo(data);
|
||||||
//data?
|
ReplayItem item = ReplayItemHeader(ReplayAction::FILE_INFO, t, (uint32_t)sizeof(info));
|
||||||
|
item.data.resize(sizeof(info));
|
||||||
|
memcpy(&item.data[0], &info, sizeof(info));
|
||||||
|
replayItems.push_back(item);
|
||||||
return data;
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
case ReplayState::IDLE:
|
case ReplayState::IDLE:
|
||||||
default:
|
default:
|
||||||
|
@ -198,10 +235,17 @@ std::vector<PSPFileInfo> ReplayApplyDiskListing(const std::vector<PSPFileInfo> &
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
case ReplayState::SAVE:
|
case ReplayState::SAVE:
|
||||||
// TODO
|
{
|
||||||
//replayItems.push_back({ action, t });
|
size_t sz = sizeof(ReplayFileInfo) * data.size();
|
||||||
//data?
|
ReplayItem item = ReplayItemHeader(ReplayAction::FILE_LISTING, t, (uint32_t)sz);
|
||||||
|
item.data.resize(sz);
|
||||||
|
for (size_t i = 0; i < data.size(); ++i) {
|
||||||
|
ReplayFileInfo info = ConvertFileInfo(data[i]);
|
||||||
|
memcpy(&item.data[i * sizeof(ReplayFileInfo)], &info, sizeof(info));
|
||||||
|
}
|
||||||
|
replayItems.push_back(item);
|
||||||
return data;
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
case ReplayState::IDLE:
|
case ReplayState::IDLE:
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Add table
Reference in a new issue