Speed patch

This commit is contained in:
Martin Janiczek 2022-10-15 17:29:03 +02:00
parent 21aec548af
commit a330eb9d6a
5 changed files with 76 additions and 4 deletions

View File

@ -2787,7 +2787,7 @@ void _object_animate()
Object* object = sad->obj; Object* object = sad->obj;
unsigned int time = getTicks(); unsigned int time = getMultipliedTicks();
if (getTicksBetween(time, sad->animationTimestamp) < sad->ticksPerFrame) { if (getTicksBetween(time, sad->animationTimestamp) < sad->ticksPerFrame) {
continue; continue;
} }

View File

@ -1,6 +1,7 @@
#include "input.h" #include "input.h"
#include <SDL.h> #include <SDL.h>
#include <time.h>
#include "audio_engine.h" #include "audio_engine.h"
#include "color.h" #include "color.h"
@ -9,6 +10,7 @@
#include "kb.h" #include "kb.h"
#include "memory.h" #include "memory.h"
#include "mouse.h" #include "mouse.h"
#include "sfall_config.h"
#include "svga.h" #include "svga.h"
#include "text_font.h" #include "text_font.h"
#include "vcr.h" #include "vcr.h"
@ -116,6 +118,15 @@ static TickerListNode* gTickerListHead;
// 0x6AC788 // 0x6AC788
static unsigned int gTickerLastTimestamp; static unsigned int gTickerLastTimestamp;
static bool gSpeedPatchEnabled;
static int gSpeedMultiInitial;
static float gSpeedMulti;
static unsigned int gLastTickCount;
static unsigned int gStoredTickCount;
static float gTickCountFraction;
static time_t gStartTime;
// 0x4C8A70 // 0x4C8A70
int inputInit(int a1) int inputInit(int a1)
{ {
@ -155,6 +166,17 @@ int inputInit(int a1)
// CE: Prevents frying CPU when window is not focused. // CE: Prevents frying CPU when window is not focused.
inputSetIdleFunc(idleImpl); inputSetIdleFunc(idleImpl);
// SFALL: Speed patch
gSpeedPatchEnabled = false;
configGetBool(&gSfallConfig, SFALL_CONFIG_SPEED_KEY, SFALL_CONFIG_SPEED_ENABLE_KEY, &gSpeedPatchEnabled);
gSpeedMultiInitial = 100;
configGetInt(&gSfallConfig, SFALL_CONFIG_SPEED_KEY, SFALL_CONFIG_SPEED_MULTI_INITIAL_KEY, &gSpeedMultiInitial);
gSpeedMulti = gSpeedMultiInitial / 100.0f;
gLastTickCount = SDL_GetTicks();
gStoredTickCount = 0;
gTickCountFraction = 0.0f;
gStartTime = time(NULL);
return 0; return 0;
} }
@ -606,16 +628,56 @@ void screenshotHandlerConfigure(int keyCode, ScreenshotHandler* handler)
} }
// 0x4C9370 // 0x4C9370
// Returns the original tick count (unaffected by the sfall speed patch).
unsigned int getTicks() unsigned int getTicks()
{ {
return SDL_GetTicks(); return SDL_GetTicks();
} }
// Inspired by sfall SpeedPatch.cpp.
// Returns the potentially sped up (multiplied) tick count.
unsigned int getMultipliedTicks()
{
unsigned int newTickCount = SDL_GetTicks();
if (newTickCount == gLastTickCount) return gStoredTickCount;
// Just in case someone's been running their computer for 49 days straight
if (gLastTickCount > newTickCount) {
gLastTickCount = newTickCount;
return gStoredTickCount;
}
float elapsed = static_cast<float>(newTickCount - gLastTickCount);
gLastTickCount = newTickCount;
// Multiply the tick count difference by the multiplier
/* TODO janiczek: Original condition was:
if (IsGameLoaded() && enabled && (!(mode = GetLoopFlags()) || mode == LoopFlag::COMBAT || mode == (LoopFlag::COMBAT | LoopFlag::PCOMBAT) || (mode & LoopFlag::WORLDMAP)) && !slideShow)
*/
if (gSpeedPatchEnabled) {
elapsed *= gSpeedMulti;
elapsed += gTickCountFraction;
gTickCountFraction = modff(gTickCountFraction, &gTickCountFraction);
}
gStoredTickCount += static_cast<unsigned int>(elapsed);
return gStoredTickCount;
}
// Done by sfall (presumably) because this time gets converted to game time.
// If you've played the game at 8x speed for a while, you'll want the time in
// the savefile to agree with the time in the game at the time you saved it.
time_t getLocalTimeAfterSpeedup()
{
return gStartTime + gStoredTickCount / 1000;
}
// 0x4C937C // 0x4C937C
void inputPauseForTocks(unsigned int delay) void inputPauseForTocks(unsigned int delay)
{ {
// NOTE: Uninline. // NOTE: Uninline.
unsigned int start = getTicks(); unsigned int start = getMultipliedTicks();
unsigned int end = getTicks(); unsigned int end = getTicks();
// NOTE: Uninline. // NOTE: Uninline.
@ -644,7 +706,10 @@ void inputBlockForTocks(unsigned int ms)
// 0x4C93E0 // 0x4C93E0
unsigned int getTicksSince(unsigned int start) unsigned int getTicksSince(unsigned int start)
{ {
unsigned int end = SDL_GetTicks(); // TODO janiczek: this one was supposed to be patched, but the game seems to work better without that.
// We can retry after implementing the big condition, it will likely fix
// all the issues, eg. with inventory animation spinning too fast etc.
unsigned int end = getTicks();
// NOTE: Uninline. // NOTE: Uninline.
return getTicksBetween(end, start); return getTicksBetween(end, start);

View File

@ -1,6 +1,8 @@
#ifndef FALLOUT_INPUT_H_ #ifndef FALLOUT_INPUT_H_
#define FALLOUT_INPUT_H_ #define FALLOUT_INPUT_H_
#include <time.h>
namespace fallout { namespace fallout {
typedef void(IdleFunc)(); typedef void(IdleFunc)();
@ -26,6 +28,8 @@ void takeScreenshot();
int screenshotHandlerDefaultImpl(int width, int height, unsigned char* data, unsigned char* palette); int screenshotHandlerDefaultImpl(int width, int height, unsigned char* data, unsigned char* palette);
void screenshotHandlerConfigure(int keyCode, ScreenshotHandler* handler); void screenshotHandlerConfigure(int keyCode, ScreenshotHandler* handler);
unsigned int getTicks(); unsigned int getTicks();
unsigned int getMultipliedTicks();
time_t getLocalTimeAfterSpeedup();
void inputPauseForTocks(unsigned int ms); void inputPauseForTocks(unsigned int ms);
void inputBlockForTocks(unsigned int ms); void inputBlockForTocks(unsigned int ms);
unsigned int getTicksSince(unsigned int a1); unsigned int getTicksSince(unsigned int a1);

View File

@ -1714,7 +1714,7 @@ static int lsgSaveHeaderInSlot(int slot)
return -1; return -1;
} }
time_t now = time(NULL); time_t now = getLocalTimeAfterSpeedup();
struct tm* local = localtime(&now); struct tm* local = localtime(&now);
temp[0] = local->tm_mday; temp[0] = local->tm_mday;

View File

@ -7,6 +7,7 @@ namespace fallout {
#define SFALL_CONFIG_FILE_NAME "ddraw.ini" #define SFALL_CONFIG_FILE_NAME "ddraw.ini"
#define SFALL_CONFIG_SPEED_KEY "Speed"
#define SFALL_CONFIG_MISC_KEY "Misc" #define SFALL_CONFIG_MISC_KEY "Misc"
#define SFALL_CONFIG_DUDE_NATIVE_LOOK_JUMPSUIT_MALE_KEY "MaleDefaultModel" #define SFALL_CONFIG_DUDE_NATIVE_LOOK_JUMPSUIT_MALE_KEY "MaleDefaultModel"
@ -59,6 +60,8 @@ namespace fallout {
#define SFALL_CONFIG_TWEAKS_FILE_KEY "TweaksFile" #define SFALL_CONFIG_TWEAKS_FILE_KEY "TweaksFile"
#define SFALL_CONFIG_GAME_DIALOG_GENDER_WORDS_KEY "DialogGenderWords" #define SFALL_CONFIG_GAME_DIALOG_GENDER_WORDS_KEY "DialogGenderWords"
#define SFALL_CONFIG_TOWN_MAP_HOTKEYS_FIX "TownMapHotkeysFix" #define SFALL_CONFIG_TOWN_MAP_HOTKEYS_FIX "TownMapHotkeysFix"
#define SFALL_CONFIG_SPEED_ENABLE_KEY "Enable"
#define SFALL_CONFIG_SPEED_MULTI_INITIAL_KEY "SpeedMultiInitial"
#define SFALL_CONFIG_BURST_MOD_DEFAULT_CENTER_MULTIPLIER 1 #define SFALL_CONFIG_BURST_MOD_DEFAULT_CENTER_MULTIPLIER 1
#define SFALL_CONFIG_BURST_MOD_DEFAULT_CENTER_DIVISOR 3 #define SFALL_CONFIG_BURST_MOD_DEFAULT_CENTER_DIVISOR 3