From 106c00873aabf409282fa7b78665846cfad02800 Mon Sep 17 00:00:00 2001 From: andon Date: Tue, 31 Jan 2017 05:40:32 -0500 Subject: [PATCH] Changes to support multiple game versions. --- include/DLL_VERSION.H | 4 +- include/framerate.h | 3 + src/config.cpp | 2 +- src/framerate.cpp | 566 ++++++++++++++++++++++++++++++++++++-- src/render.cpp | 12 +- src/tbt/control_panel.cpp | 36 ++- version.ini | Bin 7400 -> 8010 bytes 7 files changed, 574 insertions(+), 49 deletions(-) diff --git a/include/DLL_VERSION.H b/include/DLL_VERSION.H index 644ca50..536fc27 100644 --- a/include/DLL_VERSION.H +++ b/include/DLL_VERSION.H @@ -3,8 +3,8 @@ #define TBF_MAJOR 0 #define TBF_MINOR 5 -#define TBF_BUILD 2 -#define TBF_REV 1 +#define TBF_BUILD 3 +#define TBF_REV 0 diff --git a/include/framerate.h b/include/framerate.h index 3b98854..9aa7643 100644 --- a/include/framerate.h +++ b/include/framerate.h @@ -86,6 +86,9 @@ namespace tbf // True if the executable has been modified (at run-time) to allow 60 FPS extern bool variable_speed_installed; + // Allow Namco's limiter to run one frame to propogate user setting changes + extern bool need_reset; + // This is actually setup in the SK DLL that loads this one extern uint32_t target_fps; diff --git a/src/config.cpp b/src/config.cpp index 791949e..7496617 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -429,7 +429,7 @@ TBF_LoadConfig (std::wstring name) framerate.replace_limiter->load (config.framerate.replace_limiter); framerate.tolerance->load (config.framerate.tolerance); - framerate.limit_addr->load (config.framerate.limit_addr); + //framerate.limit_addr->load (config.framerate.limit_addr); textures.remaster->load (config.textures.remaster); textures.uncompressed->load (config.textures.uncompressed); diff --git a/src/framerate.cpp b/src/framerate.cpp index 8c26e90..fabd390 100644 --- a/src/framerate.cpp +++ b/src/framerate.cpp @@ -32,21 +32,67 @@ #include "textures.h" #include + +#pragma pack(push,1) + +typedef struct { + uint8_t len; + uint8_t p_rep; + uint8_t p_lock; + uint8_t p_seg; + uint8_t p_66; + uint8_t p_67; + uint8_t rex; + uint8_t rex_w; + uint8_t rex_r; + uint8_t rex_x; + uint8_t rex_b; + uint8_t opcode; + uint8_t opcode2; + uint8_t modrm; + uint8_t modrm_mod; + uint8_t modrm_reg; + uint8_t modrm_rm; + uint8_t sib; + uint8_t sib_scale; + uint8_t sib_index; + uint8_t sib_base; + union { + uint8_t imm8; + uint16_t imm16; + uint32_t imm32; + uint64_t imm64; + } imm; + union { + uint8_t disp8; + uint16_t disp16; + uint32_t disp32; + } disp; + uint32_t flags; +} hde64s; + +#pragma pack(pop) + +extern "C" unsigned int hde64_disasm(const void *code, hde64s *hs); + + + // // @TODO: Develop a heuristic to scan for this memory address; // hardcoding it is going to break stuff :) // -#define TICK_ADDR_BASE (uintptr_t)config.framerate.limit_addr +volatile uintptr_t TICK_ADDR_BASE = 0x0UL; -int32_t tbf::FrameRateFix::tick_scale = INT32_MAX; // 0 FPS +int32_t tbf::FrameRateFix::tick_scale = INT32_MAX; // 0 FPS +bool tbf::FrameRateFix::need_reset = false; -CRITICAL_SECTION tbf::FrameRateFix::alter_speed_cs = { 0 }; +CRITICAL_SECTION tbf::FrameRateFix::alter_speed_cs = { 0 }; -bool tbf::FrameRateFix::variable_speed_installed = false; -uint32_t tbf::FrameRateFix::target_fps = 0; +bool tbf::FrameRateFix::variable_speed_installed = false; +uint32_t tbf::FrameRateFix::target_fps = 0; -HMODULE tbf::FrameRateFix::bink_dll = 0; -HMODULE tbf::FrameRateFix::kernel32_dll = 0; +HMODULE tbf::FrameRateFix::bink_dll = 0; +HMODULE tbf::FrameRateFix::kernel32_dll = 0; typedef void (*NamcoLimiter_pfn)(void); NamcoLimiter_pfn NamcoLimiter_Original = nullptr; @@ -176,10 +222,13 @@ CreateTimerQueueTimer_Override ( } void -NamcoLimiter_Detour(void) +NamcoLimiter_Detour (void) { - if (! config.framerate.replace_limiter) + if ((! config.framerate.replace_limiter) || tbf::FrameRateFix::need_reset) NamcoLimiter_Original (); + + if (tbf::FrameRateFix::need_reset) + tbf::FrameRateFix::need_reset = false; } void @@ -214,21 +263,26 @@ tbf::FrameRateFix::Init (void) //Tales of Berseria.Kaim::Thread::`default constructor closure'+251F64 - 8B 0D 3A691FFF - mov ecx,["Tales of Berseria.exe"+B15074] { [1104.03] } - uint8_t sig [] = { 0x48, 0x83, 0xec, 0x38, 0X8B, 0x0d, 0x3A, 0x69, 0x1F, 0xFF, 0x85, 0xc9 }; - uint8_t mask [] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff }; + uint8_t sig [] = { 0x48, 0x83, 0xec, 0x38, 0X8B, 0x0d, 0x3A, 0x69, 0x1F, 0xFF, 0x85, 0xc9 }; + uint8_t mask [] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff }; void* limiter_addr = TBF_Scan (sig, sizeof (sig), mask); + uintptr_t rip = (uintptr_t)limiter_addr + 18; - if (limiter_addr != nullptr) { + if (limiter_addr != nullptr) + { dll_log->Log ( L"[FrameLimit] Scanned Namco's Framerate Limit Bug Address: %ph", limiter_addr ); - } else { + } + + else { dll_log->Log (L"[FrameLimit] >> ERROR: Unable to find Framerate Limiter code!"); } - if (limiter_addr != nullptr) { + if (limiter_addr != nullptr) + { //dll_log->LogEx (true, L"[FrameLimit] * Installing variable rate simulation... "); #if 0 @@ -245,11 +299,22 @@ tbf::FrameRateFix::Init (void) limiter_addr, NamcoLimiter_Detour, (LPVOID *)&NamcoLimiter_Original ); - TBF_EnableHook (limiter_addr); - - DWORD* pTickAddr = - (DWORD *)(TBF_GetBaseAddr () + TICK_ADDR_BASE); + hde64s dis = { }; + + hde64_disasm ((void *)(rip), &dis); + + uintptr_t off = + (uintptr_t)(dis.disp.disp32 + rip + 0x6) & ( 0x00FFFFFFUL ); + + dll_log->Log ( L"[FrameLimit] Framerate Limiter Preference at Addr.: (Base+%ph)", off); + + config.framerate.limit_addr = off; + TICK_ADDR_BASE = off; + + + DWORD* pTickAddr = + (DWORD *)(TBF_GetBaseAddr () + TICK_ADDR_BASE); __try { @@ -265,6 +330,8 @@ tbf::FrameRateFix::Init (void) dll_log->Log ( L"[Import Tbl] Access Violation While Attempting to " L"Install Variable Rate Limiter." ); } + + TBF_EnableHook (limiter_addr); } } @@ -299,8 +366,8 @@ tbf::FrameRateFix::GetTargetFrametime (void) if (! variable_speed_installed) return 16.666666f; - int32_t* pTickScale = - (int32_t *)(TBF_GetBaseAddr () + TICK_ADDR_BASE); + volatile int32_t* pTickScale = + (volatile int32_t *)(TBF_GetBaseAddr () + TICK_ADDR_BASE); return ( (float)(*pTickScale) * 16.6666666f ); } @@ -312,15 +379,16 @@ tbf::FrameRateFix::GetTargetFrametime (void) void tbf::FrameRateFix::RenderTick (void) { - int32_t* pTickScale = - (int32_t *)(TBF_GetBaseAddr () + TICK_ADDR_BASE); + volatile int32_t* pTickScale = + (volatile int32_t *)(TBF_GetBaseAddr () + TICK_ADDR_BASE); // In case we fail to locate the actual variable in memory, // allback to this... if (! variable_speed_installed) pTickScale = &tick_scale; - if (*pTickScale != tick_scale) { + if (*pTickScale != tick_scale) +{ dll_log->Log ( L"[FrameLimit] [@] Framerate limit changed from " L"%04.1f FPS to %04.1f FPS...", 60.0f / (float)tick_scale, @@ -339,4 +407,456 @@ tbf::FrameRateFix::RenderTick (void) config.framerate.tolerance ); } +} + + + + + + + + + + + + + + + + + + + + + +#define C_NONE 0x00 +#define C_MODRM 0x01 +#define C_IMM8 0x02 +#define C_IMM16 0x04 +#define C_IMM_P66 0x10 +#define C_REL8 0x20 +#define C_REL32 0x40 +#define C_GROUP 0x80 +#define C_ERROR 0xff + +#define PRE_ANY 0x00 +#define PRE_NONE 0x01 +#define PRE_F2 0x02 +#define PRE_F3 0x04 +#define PRE_66 0x08 +#define PRE_67 0x10 +#define PRE_LOCK 0x20 +#define PRE_SEG 0x40 +#define PRE_ALL 0xff + +#define DELTA_OPCODES 0x4a +#define DELTA_FPU_REG 0xfd +#define DELTA_FPU_MODRM 0x104 +#define DELTA_PREFIXES 0x13c +#define DELTA_OP_LOCK_OK 0x1ae +#define DELTA_OP2_LOCK_OK 0x1c6 +#define DELTA_OP_ONLY_MEM 0x1d8 +#define DELTA_OP2_ONLY_MEM 0x1e7 + +unsigned char hde64_table[] = { + 0xa5,0xaa,0xa5,0xb8,0xa5,0xaa,0xa5,0xaa,0xa5,0xb8,0xa5,0xb8,0xa5,0xb8,0xa5, + 0xb8,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xac,0xc0,0xcc,0xc0,0xa1,0xa1, + 0xa1,0xa1,0xb1,0xa5,0xa5,0xa6,0xc0,0xc0,0xd7,0xda,0xe0,0xc0,0xe4,0xc0,0xea, + 0xea,0xe0,0xe0,0x98,0xc8,0xee,0xf1,0xa5,0xd3,0xa5,0xa5,0xa1,0xea,0x9e,0xc0, + 0xc0,0xc2,0xc0,0xe6,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0xab, + 0x8b,0x90,0x64,0x5b,0x5b,0x5b,0x5b,0x5b,0x92,0x5b,0x5b,0x76,0x90,0x92,0x92, + 0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x6a,0x73,0x90, + 0x5b,0x52,0x52,0x52,0x52,0x5b,0x5b,0x5b,0x5b,0x77,0x7c,0x77,0x85,0x5b,0x5b, + 0x70,0x5b,0x7a,0xaf,0x76,0x76,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b, + 0x5b,0x5b,0x86,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xd5,0x03,0xcc,0x01,0xbc, + 0x03,0xf0,0x03,0x03,0x04,0x00,0x50,0x50,0x50,0x50,0xff,0x20,0x20,0x20,0x20, + 0x01,0x01,0x01,0x01,0xc4,0x02,0x10,0xff,0xff,0xff,0x01,0x00,0x03,0x11,0xff, + 0x03,0xc4,0xc6,0xc8,0x02,0x10,0x00,0xff,0xcc,0x01,0x01,0x01,0x00,0x00,0x00, + 0x00,0x01,0x01,0x03,0x01,0xff,0xff,0xc0,0xc2,0x10,0x11,0x02,0x03,0x01,0x01, + 0x01,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x10, + 0x10,0x10,0x10,0x02,0x10,0x00,0x00,0xc6,0xc8,0x02,0x02,0x02,0x02,0x06,0x00, + 0x04,0x00,0x02,0xff,0x00,0xc0,0xc2,0x01,0x01,0x03,0x03,0x03,0xca,0x40,0x00, + 0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00,0x00,0x00,0x00, + 0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff, + 0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x00, + 0xff,0x40,0x40,0x40,0x40,0x41,0x49,0x40,0x40,0x40,0x40,0x4c,0x42,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x40,0x4f,0x44,0x53,0x40,0x40,0x40,0x44,0x57,0x43, + 0x5c,0x40,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x40,0x40,0x64,0x66,0x6e,0x6b,0x40,0x40,0x6a,0x46,0x40,0x40,0x44,0x46,0x40, + 0x40,0x5b,0x44,0x40,0x40,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x01,0x06, + 0x06,0x02,0x06,0x06,0x00,0x06,0x00,0x0a,0x0a,0x00,0x00,0x00,0x02,0x07,0x07, + 0x06,0x02,0x0d,0x06,0x06,0x06,0x0e,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04, + 0x04,0x04,0x05,0x06,0x06,0x06,0x00,0x00,0x00,0x0e,0x00,0x00,0x08,0x00,0x10, + 0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01,0x86,0x00, + 0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba,0xf8,0xbb, + 0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00,0xc4,0xff, + 0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00,0x13,0x09, + 0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07,0xb2,0xff, + 0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf,0xe7,0x08, + 0x00,0xf0,0x02,0x00 +}; + +#define F_MODRM 0x00000001 +#define F_SIB 0x00000002 +#define F_IMM8 0x00000004 +#define F_IMM16 0x00000008 +#define F_IMM32 0x00000010 +#define F_IMM64 0x00000020 +#define F_DISP8 0x00000040 +#define F_DISP16 0x00000080 +#define F_DISP32 0x00000100 +#define F_RELATIVE 0x00000200 +#define F_ERROR 0x00001000 +#define F_ERROR_OPCODE 0x00002000 +#define F_ERROR_LENGTH 0x00004000 +#define F_ERROR_LOCK 0x00008000 +#define F_ERROR_OPERAND 0x00010000 +#define F_PREFIX_REPNZ 0x01000000 +#define F_PREFIX_REPX 0x02000000 +#define F_PREFIX_REP 0x03000000 +#define F_PREFIX_66 0x04000000 +#define F_PREFIX_67 0x08000000 +#define F_PREFIX_LOCK 0x10000000 +#define F_PREFIX_SEG 0x20000000 +#define F_PREFIX_REX 0x40000000 +#define F_PREFIX_ANY 0x7f000000 + +#define PREFIX_SEGMENT_CS 0x2e +#define PREFIX_SEGMENT_SS 0x36 +#define PREFIX_SEGMENT_DS 0x3e +#define PREFIX_SEGMENT_ES 0x26 +#define PREFIX_SEGMENT_FS 0x64 +#define PREFIX_SEGMENT_GS 0x65 +#define PREFIX_LOCK 0xf0 +#define PREFIX_REPNZ 0xf2 +#define PREFIX_REPX 0xf3 +#define PREFIX_OPERAND_SIZE 0x66 +#define PREFIX_ADDRESS_SIZE 0x67 + + +extern "C" +unsigned int +hde64_disasm (const void *code, hde64s *hs) +{ + uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0; + uint8_t *ht = hde64_table, m_mod, m_reg, m_rm, disp_size = 0; + uint8_t op64 = 0; + + // Avoid using memset to reduce the footprint. +#ifndef _MSC_VER + memset((LPBYTE)hs, 0, sizeof(hde64s)); +#else + __stosb((LPBYTE)hs, 0, sizeof(hde64s)); +#endif + + for (x = 16; x; x--) + switch (c = *p++) { + case 0xf3: + hs->p_rep = c; + pref |= PRE_F3; + break; + case 0xf2: + hs->p_rep = c; + pref |= PRE_F2; + break; + case 0xf0: + hs->p_lock = c; + pref |= PRE_LOCK; + break; + case 0x26: case 0x2e: case 0x36: + case 0x3e: case 0x64: case 0x65: + hs->p_seg = c; + pref |= PRE_SEG; + break; + case 0x66: + hs->p_66 = c; + pref |= PRE_66; + break; + case 0x67: + hs->p_67 = c; + pref |= PRE_67; + break; + default: + goto pref_done; + } + pref_done: + + hs->flags = (uint32_t)pref << 23; + + if (!pref) + pref |= PRE_NONE; + + if ((c & 0xf0) == 0x40) { + hs->flags |= F_PREFIX_REX; + if ((hs->rex_w = (c & 0xf) >> 3) && (*p & 0xf8) == 0xb8) + op64++; + hs->rex_r = (c & 7) >> 2; + hs->rex_x = (c & 3) >> 1; + hs->rex_b = c & 1; + if (((c = *p++) & 0xf0) == 0x40) { + opcode = c; + goto error_opcode; + } + } + + if ((hs->opcode = c) == 0x0f) { + hs->opcode2 = c = *p++; + ht += DELTA_OPCODES; + } else if (c >= 0xa0 && c <= 0xa3) { + op64++; + if (pref & PRE_67) + pref |= PRE_66; + else + pref &= ~PRE_66; + } + + opcode = c; + cflags = ht[ht[opcode / 4] + (opcode % 4)]; + + if (cflags == C_ERROR) { + error_opcode: + hs->flags |= F_ERROR | F_ERROR_OPCODE; + cflags = 0; + if ((opcode & -3) == 0x24) + cflags++; + } + + x = 0; + if (cflags & C_GROUP) { + uint16_t t; + t = *(uint16_t *)(ht + (cflags & 0x7f)); + cflags = (uint8_t)t; + x = (uint8_t)(t >> 8); + } + + if (hs->opcode2) { + ht = hde64_table + DELTA_PREFIXES; + if (ht[ht[opcode / 4] + (opcode % 4)] & pref) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + } + + if (cflags & C_MODRM) { + hs->flags |= F_MODRM; + hs->modrm = c = *p++; + hs->modrm_mod = m_mod = c >> 6; + hs->modrm_rm = m_rm = c & 7; + hs->modrm_reg = m_reg = (c & 0x3f) >> 3; + + if (x && ((x << m_reg) & 0x80)) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + + if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) { + uint8_t t = opcode - 0xd9; + if (m_mod == 3) { + ht = hde64_table + DELTA_FPU_MODRM + t*8; + t = ht[m_reg] << m_rm; + } else { + ht = hde64_table + DELTA_FPU_REG; + t = ht[t] << m_reg; + } + if (t & 0x80) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + } + + if (pref & PRE_LOCK) { + if (m_mod == 3) { + hs->flags |= F_ERROR | F_ERROR_LOCK; + } else { + uint8_t *table_end, op = opcode; + if (hs->opcode2) { + ht = hde64_table + DELTA_OP2_LOCK_OK; + table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK; + } else { + ht = hde64_table + DELTA_OP_LOCK_OK; + table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK; + op &= -2; + } + for (; ht != table_end; ht++) + if (*ht++ == op) { + if (!((*ht << m_reg) & 0x80)) + goto no_lock_error; + else + break; + } + hs->flags |= F_ERROR | F_ERROR_LOCK; + no_lock_error: + ; + } + } + + if (hs->opcode2) { + switch (opcode) { + case 0x20: case 0x22: + m_mod = 3; + if (m_reg > 4 || m_reg == 1) + goto error_operand; + else + goto no_error_operand; + case 0x21: case 0x23: + m_mod = 3; + if (m_reg == 4 || m_reg == 5) + goto error_operand; + else + goto no_error_operand; + } + } else { + switch (opcode) { + case 0x8c: + if (m_reg > 5) + goto error_operand; + else + goto no_error_operand; + case 0x8e: + if (m_reg == 1 || m_reg > 5) + goto error_operand; + else + goto no_error_operand; + } + } + + if (m_mod == 3) { + uint8_t *table_end; + if (hs->opcode2) { + ht = hde64_table + DELTA_OP2_ONLY_MEM; + table_end = ht + sizeof(hde64_table) - DELTA_OP2_ONLY_MEM; + } else { + ht = hde64_table + DELTA_OP_ONLY_MEM; + table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM; + } + for (; ht != table_end; ht += 2) + if (*ht++ == opcode) { + if (*ht++ & pref && !((*ht << m_reg) & 0x80)) + goto error_operand; + else + break; + } + goto no_error_operand; + } else if (hs->opcode2) { + switch (opcode) { + case 0x50: case 0xd7: case 0xf7: + if (pref & (PRE_NONE | PRE_66)) + goto error_operand; + break; + case 0xd6: + if (pref & (PRE_F2 | PRE_F3)) + goto error_operand; + break; + case 0xc5: + goto error_operand; + } + goto no_error_operand; + } else + goto no_error_operand; + + error_operand: + hs->flags |= F_ERROR | F_ERROR_OPERAND; + no_error_operand: + + c = *p++; + if (m_reg <= 1) { + if (opcode == 0xf6) + cflags |= C_IMM8; + else if (opcode == 0xf7) + cflags |= C_IMM_P66; + } + + switch (m_mod) { + case 0: + if (pref & PRE_67) { + if (m_rm == 6) + disp_size = 2; + } else + if (m_rm == 5) + disp_size = 4; + break; + case 1: + disp_size = 1; + break; + case 2: + disp_size = 2; + if (!(pref & PRE_67)) + disp_size <<= 1; + } + + if (m_mod != 3 && m_rm == 4) { + hs->flags |= F_SIB; + p++; + hs->sib = c; + hs->sib_scale = c >> 6; + hs->sib_index = (c & 0x3f) >> 3; + if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1)) + disp_size = 4; + } + + p--; + switch (disp_size) { + case 1: + hs->flags |= F_DISP8; + hs->disp.disp8 = *p; + break; + case 2: + hs->flags |= F_DISP16; + hs->disp.disp16 = *(uint16_t *)p; + break; + case 4: + hs->flags |= F_DISP32; + hs->disp.disp32 = *(uint32_t *)p; + } + p += disp_size; + } else if (pref & PRE_LOCK) + hs->flags |= F_ERROR | F_ERROR_LOCK; + + if (cflags & C_IMM_P66) { + if (cflags & C_REL32) { + if (pref & PRE_66) { + hs->flags |= F_IMM16 | F_RELATIVE; + hs->imm.imm16 = *(uint16_t *)p; + p += 2; + goto disasm_done; + } + goto rel32_ok; + } + if (op64) { + hs->flags |= F_IMM64; + hs->imm.imm64 = *(uint64_t *)p; + p += 8; + } else if (!(pref & PRE_66)) { + hs->flags |= F_IMM32; + hs->imm.imm32 = *(uint32_t *)p; + p += 4; + } else + goto imm16_ok; + } + + + if (cflags & C_IMM16) { + imm16_ok: + hs->flags |= F_IMM16; + hs->imm.imm16 = *(uint16_t *)p; + p += 2; + } + if (cflags & C_IMM8) { + hs->flags |= F_IMM8; + hs->imm.imm8 = *p++; + } + + if (cflags & C_REL32) { + rel32_ok: + hs->flags |= F_IMM32 | F_RELATIVE; + hs->imm.imm32 = *(uint32_t *)p; + p += 4; + } else if (cflags & C_REL8) { + hs->flags |= F_IMM8 | F_RELATIVE; + hs->imm.imm8 = *p++; + } + + disasm_done: + + if ((hs->len = (uint8_t)(p-(uint8_t *)code)) > 15) { + hs->flags |= F_ERROR | F_ERROR_LENGTH; + hs->len = 15; + } + + return (unsigned int)hs->len; } \ No newline at end of file diff --git a/src/render.cpp b/src/render.cpp index 1c8ca4f..71cde40 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -1504,17 +1504,7 @@ D3D9Reset_Detour ( IDirect3DDevice9 *This, HRESULT hr = D3D9Reset_Original (This, pPresentationParameters); - if (SUCCEEDED (hr)) - { - HWND hWnd = pPresentationParameters->hDeviceWindow; - - DWORD dwStyle = - GetClassLong ( hWnd, GCL_STYLE ); - - dwStyle &= ~(CS_DBLCLKS); - - SetClassLong ( hWnd, GCL_STYLE, dwStyle ); - } + tbf::FrameRateFix::need_reset = true; return hr; } diff --git a/src/tbt/control_panel.cpp b/src/tbt/control_panel.cpp index df25e9c..efe96cb 100644 --- a/src/tbt/control_panel.cpp +++ b/src/tbt/control_panel.cpp @@ -197,10 +197,8 @@ TBFix_DrawConfigUI (void) int limiter = config.framerate.replace_limiter ? 1 : 0; - const char* szLabel = (limiter == 0 ? "Framerate Limiter (choose something else!)" : "Framerate Limiter"); - - ImGui::Combo (szLabel, &limiter, "Namco (A.K.A. Stutterfest 2017)\0" - "Special K (Precision Timing For The Win!)\0\0", 2 ); + ImGui::Combo ( "Framerate Limiter", &limiter, "Namco (A.K.A. Stutterfest 2017)\0" + "Special K (Precision Timing For The Win!)\0\0", 2 ); static float values [120] = { 0 }; static int values_offset = 0; @@ -266,17 +264,31 @@ TBFix_DrawConfigUI (void) ImGui::SameLine (); if (! config.framerate.replace_limiter) { + ImGui::BeginChild ( "LimitDisclaimer", ImVec2 ( 330.0f, 80.0f ) ); ImGui::TextColored ( ImVec4 (1.0f, 1.0f, 0.0f, 1.0f), - "\n" - "\n" - " ... working limiters do not resemble EKGs!" ); + "Working limiters do not resemble seismographs!" ); + + ImGui::Separator (); + + ImGui::PushStyleColor ( ImGuiCol_Text, ImVec4 ( 0.666f, 0.666f, 0.666f, 1.0f ) ); + ImGui::TextWrapped ( "\nOnly use this limiter for reference purposes, or when making " + "changes to the in-game framerate setting." ); + ImGui::PopStyleColor (); + ImGui::EndChild (); } else { - ImGui::TextColored ( ImVec4 ( 0.2f, 1.0f, 0.2f, 1.0f), - "\n" - "\n" - "This is how a framerate limiter should work." ); + ImGui::BeginChild ( "LimitDisclaimer", ImVec2 ( 310.0f, 80.0f ) ); + ImGui::TextColored ( ImVec4 ( 0.2f, 1.0f, 0.2f, 1.0f), + "This is how a framerate limiter should work." ); + + ImGui::Separator (); + + ImGui::PushStyleColor ( ImGuiCol_Text, ImVec4 ( 0.666f, 0.666f, 0.666f, 1.0f ) ); + ImGui::TextWrapped ( "\nSelect Namco's Limiter before making any changes to framerate limit in-game," + " or the setting will not take effect." ); + ImGui::PopStyleColor (); + ImGui::EndChild (); bool changed = ImGui::SliderFloat ( "Special K Framerate Tolerance", &config.framerate.tolerance, 0.005f, 0.5); @@ -575,7 +587,7 @@ TBFix_DrawConfigUI (void) need_restart |= ImGui::RadioButton ("Stereo", (int *)&config.audio.channels, 2); ImGui::SameLine (); need_restart |= ImGui::RadioButton ("Quadraphonic", (int *)&config.audio.channels, 4); ImGui::SameLine (); need_restart |= ImGui::RadioButton ("5.1 Surround", (int *)&config.audio.channels, 6); ImGui::SameLine (); - need_restart |= ImGui::RadioButton ("7.1 SUrround", (int *)&config.audio.channels, 8); + need_restart |= ImGui::RadioButton ("7.1 Surround", (int *)&config.audio.channels, 8); ImGui::TreePop ( ); ImGui::TreePush (""); diff --git a/version.ini b/version.ini index 19664f8cebef486c0214cb51c997dd328917c26a..2b2ad1d788db221fcf4de0f4d8600777f9ba0723 100644 GIT binary patch literal 8010 zcmeI1-A~g{7{=dg6aRFU$5rgE@t4?BXK@SJ3~xOJ(vd_qz+IKV}BGO(RI-S1rK6FxhNc62~d&nxP6|NMob|B*F zg!m(e`51|(TsQedw&V8rg0(4kXHHVPAs>ooXh47{mp$Jk`vV5Jvw{Jlu-50=TtslSD3~z(;)$AldE+%NnaK7P@FKEhwAnF(iQi2 zwss4CnzPf@X}ig67Y7b`P7p_5Kcn-S`v}AAGROZvo9x3tXVlga=ZxCAj$g`a4Jzwb zi8F48VsSU>hHEjxE?v}xA=@0)PgRh&oNjomt%bbi(=d;(8nU{fs)8aeo@zq&m!|go znXU?o)f%7>>r_XPI(80SQ7O;Gz9`b*xk!1p@kNo;07c@BLes5P10;*nHzlstof$=4 zQV&K^{N)fT_gb4fxj!cXDEa|#PZ z_$izagHJ^XMfeGvT$xsP?F*p@-`$C4cMC=M?#_RosNUV;zwjtpo-;~smg~WvO!QXk z)7?VRt^ta+H;T0ypzwS5P%gr=UhK(wLJ^+zVo%l+itwx#d$OKTglE0jll6omJYU3~ Pe4+ndgwMt5wYm5UAf!N4 delta 830 zcmdr~OG*Pl5PcyT1hW#d6LA)TN`B5H7(`HFFd+Uy1{ZGBF-9|JCcjD4Rmcqty>jOX z+;{?AdJA273w_mN7G6P`p6;sZdR0^Jy>EQ2J+uuQ8Cc`aqwWRb%P zzZMF#D{v8@h6e9hE)!MMk;XQBM$U0V>w?}Q`aC_Nn3!PhGv?EuqOZr8Pnq>VNvPk&z=`dH&gYMUQEqC*9{%O*kCcgo%(H;lyQ3X1zo%Ni}yteMIMn4*8IA z3)_Ltm!YQhc$+$-#+Xk%c=VY#!j48M@pYHfm`HLvWYFWA;Md+_y&A5GCqxR%%Z!A2 zDUw7{NSXQW5K@E}rb>Gb?G~3vLK=~hE>B5t2v#SUM~@WVH)ZoM?7 GKNCNHFq%F9