2022-05-19 01:51:26 -07:00
|
|
|
#include "selfrun.h"
|
|
|
|
|
2022-09-15 02:38:23 -07:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
#include "core.h"
|
2022-05-19 01:51:26 -07:00
|
|
|
#include "db.h"
|
|
|
|
#include "game.h"
|
2022-07-29 06:04:05 -07:00
|
|
|
#include "game_config.h"
|
2022-10-04 23:23:27 -07:00
|
|
|
#include "input.h"
|
2022-10-03 06:42:34 -07:00
|
|
|
#include "kb.h"
|
2022-10-03 02:41:33 -07:00
|
|
|
#include "mouse.h"
|
2022-07-29 06:04:05 -07:00
|
|
|
#include "platform_compat.h"
|
2022-10-02 23:37:05 -07:00
|
|
|
#include "vcr.h"
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-09-23 05:43:44 -07:00
|
|
|
namespace fallout {
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// 0x51C8D8
|
2022-07-29 06:04:05 -07:00
|
|
|
int gSelfrunState = SELFRUN_STATE_TURNED_OFF;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x4A8BE0
|
2022-07-29 06:04:05 -07:00
|
|
|
int selfrunInitFileList(char*** fileListPtr, int* fileListLengthPtr)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
if (fileListPtr == NULL) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fileListLengthPtr == NULL) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
*fileListLengthPtr = fileNameListInit("selfrun\\*.sdf", fileListPtr, 0, 0);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x4A8C10
|
2022-07-29 06:04:05 -07:00
|
|
|
int selfrunFreeFileList(char*** fileListPtr)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
if (fileListPtr == NULL) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
fileNameListFree(fileListPtr, 0);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
// 0x4A8C28
|
|
|
|
int selfrunPreparePlayback(const char* fileName, SelfrunData* selfrunData)
|
|
|
|
{
|
|
|
|
if (fileName == NULL) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (selfrunData == NULL) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vcrGetState() != VCR_STATE_TURNED_OFF) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gSelfrunState != SELFRUN_STATE_TURNED_OFF) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
char path[COMPAT_MAX_PATH];
|
|
|
|
sprintf(path, "%s%s", "selfrun\\", fileName);
|
|
|
|
|
|
|
|
if (selfrunReadData(path, selfrunData) != 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
gSelfrunState = SELFRUN_STATE_PLAYING;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x4A8C88
|
|
|
|
void selfrunPlaybackLoop(SelfrunData* selfrunData)
|
|
|
|
{
|
|
|
|
if (gSelfrunState == SELFRUN_STATE_PLAYING) {
|
|
|
|
char path[COMPAT_MAX_PATH];
|
|
|
|
sprintf(path, "%s%s", "selfrun\\", selfrunData->recordingFileName);
|
|
|
|
|
|
|
|
if (vcrPlay(path, VCR_TERMINATE_ON_KEY_PRESS | VCR_TERMINATE_ON_MOUSE_PRESS, selfrunPlaybackCompleted)) {
|
|
|
|
bool cursorWasHidden = cursorIsHidden();
|
|
|
|
if (cursorWasHidden) {
|
|
|
|
mouseShowCursor();
|
|
|
|
}
|
|
|
|
|
|
|
|
while (gSelfrunState == SELFRUN_STATE_PLAYING) {
|
2022-10-05 00:11:47 -07:00
|
|
|
int keyCode = inputGetInput();
|
2022-07-29 06:04:05 -07:00
|
|
|
if (keyCode != selfrunData->stopKeyCode) {
|
|
|
|
gameHandleKey(keyCode, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
while (mouseGetEvent() != 0) {
|
2022-10-05 00:11:47 -07:00
|
|
|
inputGetInput();
|
2022-07-29 06:04:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (cursorWasHidden) {
|
|
|
|
mouseHideCursor();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x4A8D28
|
|
|
|
int selfrunPrepareRecording(const char* recordingName, const char* mapFileName, SelfrunData* selfrunData)
|
|
|
|
{
|
|
|
|
if (recordingName == NULL) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mapFileName == NULL) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vcrGetState() != VCR_STATE_TURNED_OFF) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gSelfrunState != SELFRUN_STATE_TURNED_OFF) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
sprintf(selfrunData->recordingFileName, "%s%s", recordingName, ".vcr");
|
|
|
|
strcpy(selfrunData->mapFileName, mapFileName);
|
|
|
|
|
|
|
|
selfrunData->stopKeyCode = KEY_CTRL_R;
|
|
|
|
|
|
|
|
char path[COMPAT_MAX_PATH];
|
|
|
|
sprintf(path, "%s%s%s", "selfrun\\", recordingName, ".sdf");
|
|
|
|
|
|
|
|
if (selfrunWriteData(path, selfrunData) != 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
gSelfrunState = SELFRUN_STATE_RECORDING;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x4A8DDC
|
|
|
|
void selfrunRecordingLoop(SelfrunData* selfrunData)
|
|
|
|
{
|
|
|
|
if (gSelfrunState == SELFRUN_STATE_RECORDING) {
|
|
|
|
char path[COMPAT_MAX_PATH];
|
|
|
|
sprintf(path, "%s%s", "selfrun\\", selfrunData->recordingFileName);
|
|
|
|
if (vcrRecord(path)) {
|
|
|
|
if (!cursorIsHidden()) {
|
|
|
|
mouseShowCursor();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool done = false;
|
|
|
|
while (!done) {
|
2022-10-05 00:11:47 -07:00
|
|
|
int keyCode = inputGetInput();
|
2022-07-29 06:04:05 -07:00
|
|
|
if (keyCode == selfrunData->stopKeyCode) {
|
|
|
|
vcrStop();
|
|
|
|
_game_user_wants_to_quit = 2;
|
|
|
|
done = true;
|
|
|
|
} else {
|
|
|
|
gameHandleKey(keyCode, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
gSelfrunState = SELFRUN_STATE_TURNED_OFF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// 0x4A8E74
|
2022-07-29 06:04:05 -07:00
|
|
|
void selfrunPlaybackCompleted(int reason)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
_game_user_wants_to_quit = 2;
|
2022-07-29 06:04:05 -07:00
|
|
|
gSelfrunState = SELFRUN_STATE_TURNED_OFF;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x4A8E8C
|
|
|
|
int selfrunReadData(const char* path, SelfrunData* selfrunData)
|
|
|
|
{
|
|
|
|
if (path == NULL) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (selfrunData == NULL) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
File* stream = fileOpen(path, "rb");
|
|
|
|
if (stream == NULL) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int rc = -1;
|
|
|
|
if (fileReadFixedLengthString(stream, selfrunData->recordingFileName, SELFRUN_RECORDING_FILE_NAME_LENGTH) == 0
|
|
|
|
&& fileReadFixedLengthString(stream, selfrunData->mapFileName, SELFRUN_MAP_FILE_NAME_LENGTH) == 0
|
|
|
|
&& fileReadInt32(stream, &(selfrunData->stopKeyCode)) == 0) {
|
|
|
|
rc = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
fileClose(stream);
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x4A8EF4
|
|
|
|
int selfrunWriteData(const char* path, SelfrunData* selfrunData)
|
|
|
|
{
|
|
|
|
if (path == NULL) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (selfrunData == NULL) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
char* masterPatches;
|
|
|
|
configGetString(&gGameConfig, GAME_CONFIG_SYSTEM_KEY, GAME_CONFIG_MASTER_PATCHES_KEY, &masterPatches);
|
|
|
|
|
|
|
|
char selfrunDirectoryPath[COMPAT_MAX_PATH];
|
|
|
|
sprintf(selfrunDirectoryPath, "%s\\%s", masterPatches, "selfrun\\");
|
|
|
|
|
|
|
|
compat_mkdir(selfrunDirectoryPath);
|
|
|
|
|
|
|
|
File* stream = fileOpen(path, "wb");
|
|
|
|
if (stream == NULL) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int rc = -1;
|
|
|
|
if (fileWriteFixedLengthString(stream, selfrunData->recordingFileName, SELFRUN_RECORDING_FILE_NAME_LENGTH) == 0
|
|
|
|
&& fileWriteFixedLengthString(stream, selfrunData->mapFileName, SELFRUN_MAP_FILE_NAME_LENGTH) == 0
|
|
|
|
&& fileWriteInt32(stream, selfrunData->stopKeyCode) == 0) {
|
|
|
|
rc = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
fileClose(stream);
|
|
|
|
|
|
|
|
return rc;
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
2022-09-23 05:43:44 -07:00
|
|
|
|
|
|
|
} // namespace fallout
|