cheats: support for .CHT cheat files

Issue #167
gui: no need to save background in opengl, use RenderLastFrame instead
disable cheats when online
This commit is contained in:
Flyinghead 2021-04-06 11:41:04 +02:00
parent 2fa3cfea8d
commit 72968290bf
16 changed files with 592 additions and 342 deletions

View File

@ -790,6 +790,7 @@ target_sources(${PROJECT_NAME} PRIVATE
core/rend/gui.h
core/rend/gui_android.cpp
core/rend/gui_android.h
core/rend/gui_cheats.cpp
core/rend/gui_util.cpp
core/rend/gui_util.h
core/rend/mainui.cpp

View File

@ -22,166 +22,167 @@
*/
#include "cheats.h"
#include "hw/sh4/sh4_mem.h"
#include "hw/naomi/naomi_cart.h"
#include "reios/reios.h"
#include "network/picoppp.h"
#include "cfg/cfg.h"
const Cheat CheatManager::_widescreen_cheats[] =
const WidescreenCheat CheatManager::widescreen_cheats[] =
{
{ "MK-51064 ", nullptr, { 0x39EFF4, 0 }, { 0x43700000 } }, // 18 wheeler (USA)
{ "MK-51064", nullptr, { 0x39EFF4, 0 }, { 0x43700000 } }, // 18 wheeler (USA)
{ "MK-5106450", nullptr, { 0x39EFF4, 0 }, { 0x43700000 } }, // 18 wheeler (PAL)
{ "HDR-0080 ", nullptr, { 0x6625C0, 0 }, { 0x43700000 } }, // 18 wheeler (JP)
{ "T-9708N ", nullptr, { 0x0AD5B0, 0x112E00, 0 }, { 0x4A2671C4, 0x401CCCCD } }, // 4 Wheel Thunder (USA)
{ "HDR-0080", nullptr, { 0x6625C0, 0 }, { 0x43700000 } }, // 18 wheeler (JP)
{ "T-9708N", nullptr, { 0x0AD5B0, 0x112E00, 0 }, { 0x4A2671C4, 0x401CCCCD } }, // 4 Wheel Thunder (USA)
{ "MK-5119050", nullptr, { 0x104A34, 0 }, { 0x3F52CCCD } }, // 90 Minutes - Sega Championship Football (PAL)
{ "T40209D 50", nullptr, { 0x2A8750, 0 }, { 0x3F400000 } }, // AeroWings 2 (PAL)
{ "T34101M ", nullptr, { 0x24CF20, 0x24CEEC, 0 }, { 0x3FAAAAAB, 0x43F00000, 0 } }, // Animastar (JP)
{ "MK-51171 ", nullptr, { 0xCA20B8, 0 }, { 0x43700000 } }, // Alien Front Online (USA)
{ "T2101M ", nullptr, { 0x13E8B4, 0x13E8E4, 0 }, { 0x43F00000, 0x3F400000 } }, // Berserk (JP)
{ "T34101M", nullptr, { 0x24CF20, 0x24CEEC, 0 }, { 0x3FAAAAAB, 0x43F00000, 0 } }, // Animastar (JP)
{ "MK-51171", nullptr, { 0xCA20B8, 0 }, { 0x43700000 } }, // Alien Front Online (USA)
{ "T2101M", nullptr, { 0x13E8B4, 0x13E8E4, 0 }, { 0x43F00000, 0x3F400000 } }, // Berserk (JP)
{ "T13001D 18", nullptr, { 0x2DAC44, 0 }, { 0x3F400000 } }, // Blue Stinger (En, De) (PAL)
{ "xxxxxxxxxx", nullptr, { 0x2DAB84, 0 }, { 0x3F400000 } }, // Blue Stinger (Fr) (PAL)
{ "T13001D-05", nullptr, { 0x2D9C84, 0 }, { 0x3F400000 } }, // Blue Stinger (Es, It?) (PAL)
{ "T13001N ", nullptr, { 0x2D9CA4, 0 }, { 0x3F400000 } }, // Blue Stinger (USA)
{ "HDR-0003 ", nullptr, { 0x2D6D80, 0 }, { 0x3F400000 } }, // Blue Stinger (JP)
{ "T42903M ", nullptr, { 0x286E2C, 0x286E5C, 0 }, { 0x43F00000, 0x3F400000 } }, // Bomber Hehhe! (JP)
{ "MK-51065 ", nullptr, { 0x387B84, 0x387BB4, 0 }, { 0x43F00000, 0x3F400000 } }, // Bomberman Online (USA)
{ "T6801M ", nullptr, { 0x042F3C, 0 }, { 0x4384BC09 } }, // Buggy Heat (JP)
{ "T13001N", nullptr, { 0x2D9CA4, 0 }, { 0x3F400000 } }, // Blue Stinger (USA)
{ "HDR-0003", nullptr, { 0x2D6D80, 0 }, { 0x3F400000 } }, // Blue Stinger (JP)
{ "T42903M", nullptr, { 0x286E2C, 0x286E5C, 0 }, { 0x43F00000, 0x3F400000 } }, // Bomber Hehhe! (JP)
{ "MK-51065", nullptr, { 0x387B84, 0x387BB4, 0 }, { 0x43F00000, 0x3F400000 } }, // Bomberman Online (USA)
{ "T6801M", nullptr, { 0x042F3C, 0 }, { 0x4384BC09 } }, // Buggy Heat (JP)
{ "T46601D 05", nullptr, { 0xBB3D14, 0 }, { 0x440A7C9A } }, // Cannon Spike (PAL)
{ "T1215N ", nullptr, { 0xBB3C74, 0 }, { 0x440A7C9A } }, // Cannon Spike (USA)
{ "T1215N", nullptr, { 0xBB3C74, 0 }, { 0x440A7C9A } }, // Cannon Spike (USA)
{ "T44901D 50", nullptr, { 0xB0109C, 0xB010CC, 0 }, { 0x43F00000, 0x3F400000 } }, // Carrier (PAL)
{ "T5701N ", nullptr, { 0xAFD93C, 0xAFD96C, 0 }, { 0x43F00000, 0x3F400000 } }, // Carrier (USA)
{ "T5701N", nullptr, { 0xAFD93C, 0xAFD96C, 0 }, { 0x43F00000, 0x3F400000 } }, // Carrier (USA)
// Capcom vs. SNK Pro (JP)
// You can see the end of the backgrounds on each side. The HUD is shifted to the right.
// Code 2 sets HUD and movements of the characters to a 4:3 zone
{ "T1247M ", nullptr, { 0x1E8238, 0x3D3658, 0x3D3628, 0 }, { 0x43F00000, 0x43D20000, 0x43700000 } },
{ "T1247M", nullptr, { 0x1E8238, 0x3D3658, 0x3D3628, 0 }, { 0x43F00000, 0x43D20000, 0x43700000 } },
// Capcom vs. SNK 2 (JP)
// You can see the end of the backgrounds on each side.
{ "T1249M ", nullptr, { 0x39BFD8, 0x34E9E8, 0x34EFBC, 0 }, { 0x43700000, 0x3F400000, 0x3F400000 } },
{ "T1249M", nullptr, { 0x39BFD8, 0x34E9E8, 0x34EFBC, 0 }, { 0x43700000, 0x3F400000, 0x3F400000 } },
{ "T44902D 50", nullptr, { 0x1DBFF8, 0 }, { 0x43700000 } }, // Charge n Blast (PAL)
{ "T4402M ", nullptr, { 0x1DA9E0, 0 }, { 0x43700000 } }, // Charge n Blast (JP)
{ "T4402M", nullptr, { 0x1DA9E0, 0 }, { 0x43700000 } }, // Charge n Blast (JP)
{ "MK-5104950", nullptr, { 0x2D2D40, 0x2D2D70, 0 }, { 0x3F400000, 0xC2700000 } }, // ChuChu Rocket! (PAL)
{ "T44903D 50", nullptr, { 0x315300, 0x315334, 0 }, { 0x43F00000, 0x3FAAAAAB } }, // Coaster Works (PAL)
// Confidential Mission (PAL) 022F0D58 43700000 - Only works on real Dreamcast
{ "T36901M ", nullptr, { 0x1C8A98, 0 }, { 0x3F400000 } }, // Cool Boarders (JP)
{ "T3106M ", nullptr, { 0x60B59C, 0 }, { 0x3F400000 } }, // Cool Cool Toon (JP)
{ "HDR-0176 ", nullptr, { 0x240FAC, 0 }, { 0x3F400000 } }, // Cosmic Smash (JP)
{ "MK-51035 ", " U ", { 0x2B08B0, 0 }, { 0x43700000 } }, // Crazy Taxi (USA)
{ "MK-51035 ", " E ", { 0x2B3410, 0 }, { 0x43700000 } }, // Crazy Taxi (PAL)
{ "T36901M", nullptr, { 0x1C8A98, 0 }, { 0x3F400000 } }, // Cool Boarders (JP)
{ "T3106M", nullptr, { 0x60B59C, 0 }, { 0x3F400000 } }, // Cool Cool Toon (JP)
{ "HDR-0176", nullptr, { 0x240FAC, 0 }, { 0x3F400000 } }, // Cosmic Smash (JP)
{ "MK-51035", " U ", { 0x2B08B0, 0 }, { 0x43700000 } }, // Crazy Taxi (USA)
{ "MK-51035", " E ", { 0x2B3410, 0 }, { 0x43700000 } }, // Crazy Taxi (PAL)
{ "MK-5113650", nullptr, { 0x2BFB70, 0 }, { 0x43700000 } }, // Crazy Taxi 2 (PAL)
{ "MK-51136 ", nullptr, { 0x2BDDD0, 0 }, { 0x43700000 } }, // Crazy Taxi 2 (USA)
// { "HDR-0159 ", nullptr, { 0x2FBBD0, 0 }, { 0x43700000 } }, // Crazy Taxi 2 (JP) not working
{ "T13004N ", nullptr, { 0x016D94, 0 }, { 0x44234E73 } }, // Cyber Troopers - Virtual On - Oratorio Tangram (USA)
{ "MK-51136", nullptr, { 0x2BDDD0, 0 }, { 0x43700000 } }, // Crazy Taxi 2 (USA)
// { "HDR-0159", nullptr, { 0x2FBBD0, 0 }, { 0x43700000 } }, // Crazy Taxi 2 (JP) not working
{ "T13004N", nullptr, { 0x016D94, 0 }, { 0x44234E73 } }, // Cyber Troopers - Virtual On - Oratorio Tangram (USA)
// D2 (USA)
{ "MK-51036 ", nullptr, { 0x4B5CF4, 0x4B5CC4, 0x3E92A0, 0x3E92A8, 0x3E92C0, 0x3E92C8 },
{ "MK-51036", nullptr, { 0x4B5CF4, 0x4B5CC4, 0x3E92A0, 0x3E92A8, 0x3E92C0, 0x3E92C8 },
{ 0x3F400000, 0x43F00000, 0, 0, 0, 0 } },
// D2 (JP)
{ "T30006M ", nullptr, { 0x4CF42C, 0x4CF45C, 0x3E1A36, 0x3E1A34, 0x3E1A3C, 0x3E1A54, 0x3E1A5C, 0 },
{ "T30006M", nullptr, { 0x4CF42C, 0x4CF45C, 0x3E1A36, 0x3E1A34, 0x3E1A3C, 0x3E1A54, 0x3E1A5C, 0 },
{ 0x43F00000, 0x3F400000, 0x08010000, 0, 0, 0, 0 } },
{ "MK-5103750", nullptr, { 0x1FE270, 0 }, { 0x43700000 } }, // Daytona USA (PAL)
{ "MK-51037 ", nullptr, { 0x1FC6D0, 0 }, { 0x43700000 } }, // Daytona USA (USA)
{ "T9501N-50 ", nullptr, { 0x9821D4, 0 }, { 0x3F400000 } }, // Deadly Skies (PAL)
{ "MK-51037", nullptr, { 0x1FC6D0, 0 }, { 0x43700000 } }, // Daytona USA (USA)
{ "T9501N-50", nullptr, { 0x9821D4, 0 }, { 0x3F400000 } }, // Deadly Skies (PAL)
{ "T8116D 50", nullptr, { 0x2E5530, 0 }, { 0x43700000 } }, // Dead or Alive 2 (PAL)
{ "T3601N ", nullptr, { 0x2F0670, 0 }, { 0x43700000 } }, // Dead or Alive 2 (USA)
{ "T3602M ", nullptr, { 0x2FF798, 0 }, { 0x43700000 } }, // Dead or Alive 2 (JP)
{ "T3601M ", nullptr, { 0x2FBBD0, 0x1E6658, 0 }, { 0x43700000, 0x4414C000 } }, // Dead or Alive 2: Limited Edition (JP) (code 1 fixes HUD)
{ "T2401N ", nullptr, { 0x8BD5B4, 0x8BD5E4, 0 }, { 0x43F00000, 0x3F400000 } }, // Death Crimson OX (USA)
{ "T23201M ", nullptr, { 0x819F44, 0x819F74, 0 }, { 0x43F00000, 0x3F400000 } }, // Death Crimson 2 (JP)
{ "T17714D50 ", nullptr, { 0x0D2ED0, 0x0D2ED4, 0 }, { 0x3FAAAAAB, 0x3F400000 } }, // Donald Duck: Quack Attack (PAL) (Code 1 corrects the HUD)
{ "T3601N", nullptr, { 0x2F0670, 0 }, { 0x43700000 } }, // Dead or Alive 2 (USA)
{ "T3602M", nullptr, { 0x2FF798, 0 }, { 0x43700000 } }, // Dead or Alive 2 (JP)
{ "T3601M", nullptr, { 0x2FBBD0, 0x1E6658, 0 }, { 0x43700000, 0x4414C000 } }, // Dead or Alive 2: Limited Edition (JP) (code 1 fixes HUD)
{ "T2401N", nullptr, { 0x8BD5B4, 0x8BD5E4, 0 }, { 0x43F00000, 0x3F400000 } }, // Death Crimson OX (USA)
{ "T23201M", nullptr, { 0x819F44, 0x819F74, 0 }, { 0x43F00000, 0x3F400000 } }, // Death Crimson 2 (JP)
{ "T17714D50", nullptr, { 0x0D2ED0, 0x0D2ED4, 0 }, { 0x3FAAAAAB, 0x3F400000 } }, // Donald Duck: Quack Attack (PAL) (Code 1 corrects the HUD)
{ "T12503D-50", nullptr, { 0x49CB24, 0 }, { 0x3F0CCCCD } }, // Dragons Blood (PAL)
{ "T17716D 50", nullptr, { 0xF97F40, 0x08DCF8, 0 }, { 0x00000168, 0 } }, // Dragonriders: Chronicles of Pern (PAL)
{ "T17720N ", nullptr, { 0xF97F40, 0x08DCF4, 0 }, { 0x00000168, 0 } }, // Dragonriders: Chronicles of Pern (USA) (Code 1 removes black bars)
{ "T17720N", nullptr, { 0xF97F40, 0x08DCF4, 0 }, { 0x00000168, 0 } }, // Dragonriders: Chronicles of Pern (USA) (Code 1 removes black bars)
{ "MK-5101350", nullptr, { 0x4FCBC0, 0 }, { 0x43700000 } }, // Dynamite Cop (PAL)
{ "MK-51013 ", nullptr, { 0x4FCBC0, 0 }, { 0x43700000 } }, // Dynamite Cop (USA)
{ "MK-51013", nullptr, { 0x4FCBC0, 0 }, { 0x43700000 } }, // Dynamite Cop (USA)
// Draconus: Cult of the Wyrm (USA)
// Code 1-2 increases drawing distance
{ "T40203N ", nullptr, { 0x49D7F4, 0x49D8CC, 0x49D6F8, 0 }, { 0x3F07C3BB, 0x447A0000, 0x3FAAAAAB } },
{ "T40203N", nullptr, { 0x49D7F4, 0x49D8CC, 0x49D6F8, 0 }, { 0x3F07C3BB, 0x447A0000, 0x3FAAAAAB } },
// Ecco the Dolphin: Defender of the Future (PAL)
{ "MK-5103350", nullptr, { 0x275418, 0x040E68, 0x040D1C, 0 }, { 0x49D9A5DA, 0x3F100000, 0x3F100000 } },
{ "T17705D 05", nullptr, { 0x304870, 0 }, { 0x3F400000 } }, // Evolution - The World of Sacred Device (PAL)
{ "T45005D 50", nullptr, { 0x36CE5C, 0x36CE8C, 0 }, { 0x43F00000, 0x3F400000 } }, // Evolution 2 - Far Off Promise (PAL)
{ "T1711N ", nullptr, { 0x36C76C, 0x36C73C, 0 }, { 0x3F400000, 0x43F00000 } }, // Evolution 2 - Far Off Promise (USA)
{ "T1711N", nullptr, { 0x36C76C, 0x36C73C, 0 }, { 0x3F400000, 0x43F00000 } }, // Evolution 2 - Far Off Promise (USA)
{ "T8118D 50", nullptr, { 0x2C6B7C, 0 }, { 0x00004000 } }, // Ferrari F355 Challenge (PAL) vga mode only
{ "HDR-0100 ", nullptr, { 0x3235D4, 0 }, { 0x00004000 } }, // Ferrari F355 Challenge (JP) vga mode only
{ "HDR-0100", nullptr, { 0x3235D4, 0 }, { 0x00004000 } }, // Ferrari F355 Challenge (JP) vga mode only
{ "MK-5115450", nullptr, { 0x3D3B10, 0 }, { 0x43700000 } }, // Fighting Vipers 2 (PAL)
{ "HDR-0133 ", nullptr, { 0x3D3AF0, 0 }, { 0x43700000 } }, // Fighting Vipers 2 (JP)
{ "MK-51114 ", nullptr, { 0x132DD8, 0xA26CA8, 0xA26738, 0xA275B8, 0xA26AD8, 0xA26908, 0 },
{ "HDR-0133", nullptr, { 0x3D3AF0, 0 }, { 0x43700000 } }, // Fighting Vipers 2 (JP)
{ "MK-51114", nullptr, { 0x132DD8, 0xA26CA8, 0xA26738, 0xA275B8, 0xA26AD8, 0xA26908, 0 },
{ 0x3F400000, 0x3F400000, 0x3F400000, 0x3F400000, 0x3F400000, 0x3F400000 } }, // Floigan Bros. Ep. 1 (PAL)
{ "T34201M ", nullptr, { 0x586290, 0x586260, 0 }, { 0x3F400000, 0x43F00000 } }, // Frame Gride (JP)
{ "T34201M", nullptr, { 0x586290, 0x586260, 0 }, { 0x3F400000, 0x43F00000 } }, // Frame Gride (JP)
{ "T-8113D-50", nullptr, { 0x55A354, 0 }, { 0x3FAAAAAB } }, // Fur Fighters (PAL)
{ "T-8107N ", nullptr, { 0x55A374, 0 }, { 0x3FAAAAAB } }, // Fur Fighters (USA)
{ "T-8107N", nullptr, { 0x55A374, 0 }, { 0x3FAAAAAB } }, // Fur Fighters (USA)
{ "T9707D 50", nullptr, { 0x2E7CD0, 0x2E7D04, 0x2E7D10, 0x2E7D0C, 0 },
{ 0x43BEAE39, 0x3DCCCCCD , 0x44A00000, 0xC4200000 } }, // Gauntlet Legends (PAL)
{ "HDR-0004 ", nullptr, { 0x364A64, 0 }, { 0x43BA0000 } }, // Godzilla Generations (JP)
{ "HDR-0047 ", nullptr, { 0x7C3F24, 0x7C3F54, 0 }, { 0x43F00000, 0x3F400000 } }, // Godzilla Generations Maximum Impact (JP)
{ "T41501M ", nullptr, { 0x282604, 0x282634, 0 }, { 0x43F00000, 0x3F400000 } }, // Golem no Maigo (aka The Lost Golem) (JP)
{ "T1219M ", nullptr, { 0xBC3C94, 0 }, { 0x440A7C9A } }, // Gun Spike (JP)
{ "T13301N ", nullptr, { 0x88E780, 0 }, { 0x3F400000 } }, // Gundam Side Story (USA)
// { "T11001N ", nullptr, { 0xC3D6BC, 0xD204A8, 0xD32FC8, 0xC7CF84, 0xD20548, 0 },
{ "HDR-0004", nullptr, { 0x364A64, 0 }, { 0x43BA0000 } }, // Godzilla Generations (JP)
{ "HDR-0047", nullptr, { 0x7C3F24, 0x7C3F54, 0 }, { 0x43F00000, 0x3F400000 } }, // Godzilla Generations Maximum Impact (JP)
{ "T41501M", nullptr, { 0x282604, 0x282634, 0 }, { 0x43F00000, 0x3F400000 } }, // Golem no Maigo (aka The Lost Golem) (JP)
{ "T1219M", nullptr, { 0xBC3C94, 0 }, { 0x440A7C9A } }, // Gun Spike (JP)
{ "T13301N", nullptr, { 0x88E780, 0 }, { 0x3F400000 } }, // Gundam Side Story (USA)
// { "T11001N", nullptr, { 0xC3D6BC, 0xD204A8, 0xD32FC8, 0xC7CF84, 0xD20548, 0 },
// { 0x00363031, 0x00000356, 0x00000280, 0x00000280, 0x00000280 } }, // Half-Life. Not working
{ "MK-5104150", nullptr, { 0x23FCC4, 0 }, { 0x44558000 } }, // Headhunter (PAL)
{ "MK-5100250", nullptr, { 0x4C6708, 0 }, { 0x43700000 } }, // House of the Dead 2, The (PAL)
{ "MK-51002 ", nullptr, { 0x4C6088, 0 }, { 0x43700000 } }, // House of the Dead 2, The (USA)
{ "T38706M ", nullptr, { 0xC0CFA0, 0 }, { 0x3F400000 } }, // Ikaruga (JP)
{ "T46001N ", nullptr, { 0x1C8A98, 0 }, { 0x3F400000 } }, // Illbleed (USA)
{ "MK-51002", nullptr, { 0x4C6088, 0 }, { 0x43700000 } }, // House of the Dead 2, The (USA)
{ "T38706M", nullptr, { 0xC0CFA0, 0 }, { 0x3F400000 } }, // Ikaruga (JP)
{ "T46001N", nullptr, { 0x1C8A98, 0 }, { 0x3F400000 } }, // Illbleed (USA)
{ "T44904D 50", nullptr, { 0x18C15C, 0x18C18C, 0 }, { 0x43F00000, 0x3F400000 } }, // Iron Aces (PAL)
{ "MK-51058 ", nullptr, { 0x32E0FC, 0x32E12C, 0 }, { 0x43F00000, 0x3F400000 } }, // Jet Grind Radio (USA)
{ "MK-51058", nullptr, { 0x32E0FC, 0x32E12C, 0 }, { 0x43F00000, 0x3F400000 } }, // Jet Grind Radio (USA)
{ "MK-5105850", nullptr, { 0x32F9EC, 0x32F9BC, 0 }, { 0x3F400000, 0x43F00000 } }, // Jet Set Radio (PAL)
{ "HDR-0078 ", nullptr, { 0x327A8C, 0x327A5C, 0 }, { 0x3F400000, 0x43F00000 } }, // Jet Set Radio (De La) (JP)
{ "HDR-0078", nullptr, { 0x327A8C, 0x327A5C, 0 }, { 0x3F400000, 0x43F00000 } }, // Jet Set Radio (De La) (JP)
{ "T22902D 50", nullptr, { 0x278508, 0 }, { 0x43700000 } }, // Kao The Kangaroo (PAL)
{ "T22903N ", nullptr, { 0x2780A8, 0 }, { 0x43700000 } }, // Kao The Kangaroo (USA)
{ "T47803M ", nullptr, { 0x0FDFAC, 0 }, { 0x3F400000 } }, // Karous (JP)
// { "T41901N ", nullptr, { 0x53F580, 0xEFB748, 0xEFB750, 0 }, { 0xC4200000, 0x43A00000, 0x43200000 } }, // KISS Psycho Circus The Nightmare Child (USA)
{ "T2501M ", nullptr, { 0x24A878, 0x24A8A8, 0 }, { 0x43F00000, 0x3F400000 } }, // Langrisser Millenium (JP)
{ "T22903N", nullptr, { 0x2780A8, 0 }, { 0x43700000 } }, // Kao The Kangaroo (USA)
{ "T47803M", nullptr, { 0x0FDFAC, 0 }, { 0x3F400000 } }, // Karous (JP)
// { "T41901N", nullptr, { 0x53F580, 0xEFB748, 0xEFB750, 0 }, { 0xC4200000, 0x43A00000, 0x43200000 } }, // KISS Psycho Circus The Nightmare Child (USA)
{ "T2501M", nullptr, { 0x24A878, 0x24A8A8, 0 }, { 0x43F00000, 0x3F400000 } }, // Langrisser Millenium (JP)
{ "T15111D 50", nullptr, { 0x29B90C, 0 }, { 0x3F400000 } }, // Le Mans 24 Hours (PAL)
{ "T15116N ", nullptr, { 0x2198EC, 0 }, { 0x3F400000 } }, // Looney Tunes: Space Race (USA)
{ "T15116N", nullptr, { 0x2198EC, 0 }, { 0x3F400000 } }, // Looney Tunes: Space Race (USA)
{ "MK-5105050", nullptr, { 0x33818C, 0 }, { 0x3FA66666 } }, // Maken X (PAL)
{ "MK-51050 ", nullptr, { 0x30CB4C, 0 }, { 0x3F400000 } }, // Maken X (USA)
{ "T1212N ", nullptr, { 0x2D6B18, 0x268390, 0x268ED8, 0x268934, 0x26947C, 0x269A20, 0x269FC4, 0 },
{ "MK-51050", nullptr, { 0x30CB4C, 0 }, { 0x3F400000 } }, // Maken X (USA)
{ "T1212N", nullptr, { 0x2D6B18, 0x268390, 0x268ED8, 0x268934, 0x26947C, 0x269A20, 0x269FC4, 0 },
{ 0x43700000, 0x3F400000, 0x3F400000, 0x3F400000, 0x3F400000, 0x3F400000, 0x3F400000 } }, // Marvel vs. Capcom 2 (USA)
{ "T1215M ", nullptr, { 0x2FE2C0, 0x28FB38, 0x290680, 0x2900DC, 0x290C24, 0x2911C8, 0x29176C, 0 },
{ "T1215M", nullptr, { 0x2FE2C0, 0x28FB38, 0x290680, 0x2900DC, 0x290C24, 0x2911C8, 0x29176C, 0 },
{ 0x43700000, 0x3F400000, 0x3F400000, 0x3F400000, 0x3F400000, 0x3F400000, 0x3F400000 } }, // Marvel vs. Capcom 2 (JP)
{ "T41402N ", nullptr, { 0x551B80, 0 }, { 0x3F400000 } }, // Max Steel - Covert Missions (USA)
{ "T41402N", nullptr, { 0x551B80, 0 }, { 0x3F400000 } }, // Max Steel - Covert Missions (USA)
{ "MK-5102250", "V1.001", { 0x107FDC, 0x11253C, 0 }, { 0x3F99999A, 0x3F900000 } }, // Metropolis Street Racer (v1.001) (PAL)
{ "MK-5102250", "V1.009", { 0x106B5C, 0x1111F4, 0 }, { 0x3F99999A, 0x3F900000 } }, // Metropolis Street Racer (v1.009) (PAL)
{ "MK-51012 ", nullptr, { 0x10A01C, 0x1146FC, 0 }, { 0x3F99999A, 0x3F900000 } }, // Metropolis Street Racer (USA)
{ "T0000M ", nullptr, { 0x1CAEAC, 0x1CAEDC, 0 }, { 0x43F00000, 0x3F400000 } }, // Millenium Racer Y2K Fighters
{ "T1221M ", nullptr, { 0x426B74, 0 }, { 0x43F00000 } }, // Moero! Justice Gauken (JP)
{ "T9701D ", nullptr, { 0x31290C, 0 }, { 0x3F400000 } }, // Mortal Kombat Gold (PAL)
{ "T-9701N ", nullptr, { 0x337B8C, 0 }, { 0x3FA66666 } }, // Mortal Kombat Gold (USA)
{ "T7020D ", nullptr, { 0x1A5D40, 0x1A5D18, 0x1A5D38, 0x1A5D34, 0x1A5D30, 0x1A5D3C, 0x1A5D0C, 0x1A5D08, 0x1ACB78, 0 },
{ "MK-51012", nullptr, { 0x10A01C, 0x1146FC, 0 }, { 0x3F99999A, 0x3F900000 } }, // Metropolis Street Racer (USA)
{ "T0000M", nullptr, { 0x1CAEAC, 0x1CAEDC, 0 }, { 0x43F00000, 0x3F400000 } }, // Millenium Racer Y2K Fighters
{ "T1221M", nullptr, { 0x426B74, 0 }, { 0x43F00000 } }, // Moero! Justice Gauken (JP)
{ "T9701D", nullptr, { 0x31290C, 0 }, { 0x3F400000 } }, // Mortal Kombat Gold (PAL)
{ "T-9701N", nullptr, { 0x337B8C, 0 }, { 0x3FA66666 } }, // Mortal Kombat Gold (USA)
{ "T7020D", nullptr, { 0x1A5D40, 0x1A5D18, 0x1A5D38, 0x1A5D34, 0x1A5D30, 0x1A5D3C, 0x1A5D0C, 0x1A5D08, 0x1ACB78, 0 },
{ 0x3F59999A, 0x44084000, 0x3FB1EB85, 0x3FAAAAAB, 0x3F800000, 0x3FA66666, 0xC31B0000, 0x42700000, 0x44160000 } }, // Mr Driller (PAL)
{ "T7604M ", nullptr, { 0x43BDA4, 0x43BDD8, 0x4319E8, 0x431A08, 0x431A28, 0x431A48, 0 },
{ "T7604M", nullptr, { 0x43BDA4, 0x43BDD8, 0x4319E8, 0x431A08, 0x431A28, 0x431A48, 0 },
{ 0x43700000, 0x3F9AF5C2, 0x42200000, 0x42200000, 0x438C0000, 0x438C0000 } }, // Nanatsu no Hikan - Senritsu no Bishou (JP)
{ "HDR-0079 ", nullptr, { 0x353744, 0x353774, 0x353778, 0 },
{ "HDR-0079", nullptr, { 0x353744, 0x353774, 0x353778, 0 },
{ 0x43F00000, 0x3F400000, 0x3F800000 } }, // Napple Tale: Arsia in Daydream (JP)
//crash { "MK-51178 ", nullptr, { 0x23AF00, 0x23B160, 0x144D40, 0x2105B4, 0x705B40, 0 },
//crash { "MK-51178", nullptr, { 0x23AF00, 0x23B160, 0x144D40, 0x2105B4, 0x705B40, 0 },
// { 0xBFAAAAAB, 0xBFAAAAAB, 0xBFAAAAAB, 0xBFAAAAAB, 0x44558000 } }, // NBA 2K2
{ "T9504M ", nullptr, { 0xCDE848, 0xCDE844, 0 }, { 0x3F400000, 0x3FA00000 } }, // Nightmare Creatures II (USA)
{ "T9504M", nullptr, { 0xCDE848, 0xCDE844, 0 }, { 0x3F400000, 0x3FA00000 } }, // Nightmare Creatures II (USA)
{ "T-9502D-50", nullptr, { 0xBDE9B0, 0xBDE9C4, 0 }, { 0x3F400000, 0x3FA00000 } }, // Nightmare Creatures II (PAL)
{ "MK-5110250", nullptr, { 0x87B5A4, 0 }, { 0x43700000 } }, // Outtrigger (PAL)
{ "HDR-0118 ", nullptr, { 0x83E284, 0 }, { 0x43700000 } }, // Outtrigger (JP)
{ "HDR-0118", nullptr, { 0x83E284, 0 }, { 0x43700000 } }, // Outtrigger (JP)
{ "T15103D 50", nullptr, { 0x1EEE78, 0 }, { 0x3F400000 } }, // PenPen (PAL)
{ "T17001M ", nullptr, { 0x1C3828, 0 }, { 0x3F400000 } }, // PenPen TriIcelon (JP)
{ "T17001M", nullptr, { 0x1C3828, 0 }, { 0x3F400000 } }, // PenPen TriIcelon (JP)
{ "MK-5110050", nullptr, { 0x548E04, 0x0923C0, 0 }, { 0x43E80000, 0x3F966666 } }, // Phantasy Star Online (PAL) TODO
{ "MK-51100 ", nullptr, { 0x548E84, 0x0925A4, 0 }, { 0x43D20000, 0x3FA66666 } }, // Phantasy Star Online (USA) TODO
{ "HDR-0129 ", nullptr, { 0x57E344, 0x091794, 0 }, { 0x43D20000, 0x3FA66666 } }, // Phantasy Star Online (JP) TODO
{ "MK-51100", nullptr, { 0x548E84, 0x0925A4, 0 }, { 0x43D20000, 0x3FA66666 } }, // Phantasy Star Online (USA) TODO
{ "HDR-0129", nullptr, { 0x57E344, 0x091794, 0 }, { 0x43D20000, 0x3FA66666 } }, // Phantasy Star Online (JP) TODO
{ "MK-5119350", nullptr, { 0x57552C, 0x0A2DD4, 0 }, { 0x43F00000, 0x3F911111 } }, // Phantasy Star Online Ver. 2 (PAL) TODO
{ "MK-51193 ", nullptr, { 0x0A3138, 0x58C8CC, 0 }, { 0x3F911111, 0x43F00000 } }, // Phantasy Star Online Ver. 2 (USA) TODO
{ "T1207N ", nullptr, { 0x7D463C, 0 }, { 0x3F400000 } }, // Plasma Sword - Nightmare of Bilstein (USA)
{ "MK-51193", nullptr, { 0x0A3138, 0x58C8CC, 0 }, { 0x3F911111, 0x43F00000 } }, // Phantasy Star Online Ver. 2 (USA) TODO
{ "T1207N", nullptr, { 0x7D463C, 0 }, { 0x3F400000 } }, // Plasma Sword - Nightmare of Bilstein (USA)
{ "T36801D 50", nullptr, { 0x7FD3C8, 0 }, { 0x43700000 } }, // Power Stone (PAL)
{ "T1201N ", nullptr, { 0x7FCEE8, 0 }, { 0x43700000 } }, // Power Stone (USA)
{ "T1201N", nullptr, { 0x7FCEE8, 0 }, { 0x43700000 } }, // Power Stone (USA)
{ "T36812D 50", nullptr, { 0x868BA8, 0 }, { 0x43700000 } }, // Power Stone 2 (PAL)
{ "T1211N ", nullptr, { 0x8689A8, 0 }, { 0x43700000 } }, // Power Stone 2 (USA)
{ "T1218M ", nullptr, { 0x849AA0, 0 }, { 0x43700000 } }, // Power Stone 2 (JP)
{ "T1211N", nullptr, { 0x8689A8, 0 }, { 0x43700000 } }, // Power Stone 2 (USA)
{ "T1218M", nullptr, { 0x849AA0, 0 }, { 0x43700000 } }, // Power Stone 2 (JP)
{ "T7022D 50", nullptr, { 0x33414C, 0 }, { 0x43F00000 } }, // Project Justice (PAL)
{ "T1219N ", nullptr, { 0x33374C, 0 }, { 0x43F00000 } }, // Project Justice (USA)
{ "MK-51162 ", nullptr, { 0x204308, 0 }, { 0x3FE38E39 } }, // Propeller Arena
{ "T1219N", nullptr, { 0x33374C, 0 }, { 0x43F00000 } }, // Project Justice (USA)
{ "MK-51162", nullptr, { 0x204308, 0 }, { 0x3FE38E39 } }, // Propeller Arena
{ "T-8106D-50", nullptr, { 0x7DA39C, 0 }, { 0x3F400000 } }, // Psychic Force 2012 (PAL)
{ "T9901M ", nullptr, { 0x1AD848, 0 }, { 0x3F400000 } }, // Rainbow Cotton (JP)
{ "T9901M", nullptr, { 0x1AD848, 0 }, { 0x3F400000 } }, // Rainbow Cotton (JP)
{ "T9711D 50", nullptr, { 0x1574D8, 0 }, { 0x43700000 } }, // Ready 2 Rumble Boxing Round 2 (PAL)
{ "T7012D 05", nullptr, { 0x4FF93C, 0x4FF96C, 0 }, { 0x43F00000, 0x3F400000 } }, // Record of Lodoss War (En) (PAL)
{ "xxxxxxxxxx", nullptr, { 0x4FF25C, 0x4FF28C, 0 }, { 0x43F00000, 0x3F400000 } }, // Record of Lodoss War (De) (PAL)
{ "T7012D 09", nullptr, { 0x50499C, 0x5049CC, 0 }, { 0x43F00000, 0x3F400000 } }, // Record of Lodoss War (Fr) (PAL)
{ "MK-5102151", nullptr, { 0x3511A0, 0 }, { 0x3FC58577 } }, // Red Dog (PAL)
{ "HDR-0074 ", nullptr, { 0x1FF60C, 0x1FF610, 0x1FF5DC, 0 }, { 0x3F400000, 0x3F800000, 0x43DC0000 } }, //Rent a Hero n°1
{ "HDR-0074", nullptr, { 0x1FF60C, 0x1FF610, 0x1FF5DC, 0 }, { 0x3F400000, 0x3F800000, 0x43DC0000 } }, //Rent a Hero n°1
// Resident Evil: Code Veronica (De) (PAL)
// Code 1-4 removes the black bars on top and bottom in FMV
{ "xxxxxxxxxx", nullptr, { 0x32A380, 0x383E18, 0x383E38, 0x383E58, 0x383E78, 0 },
@ -195,102 +196,102 @@ const Cheat CheatManager::_widescreen_cheats[] =
{ 0x3F400000, 0x43F00000, 0, 0x43F00000, 0 } },
// Resident Evil: Code Veronica (USA)
// Code 1-4 removes the black bars on top and bottom in FMV
{ "T1204N ", nullptr, { 0x329E40, 0x3838D8, 0x3838F8, 0x383918, 0x383938, 0 },
{ "T1204N", nullptr, { 0x329E40, 0x3838D8, 0x3838F8, 0x383918, 0x383938, 0 },
{ 0x3F400000, 0x43F00000, 0, 0x43F00000, 0 } },
{ "T8107D 50", nullptr, { 0x0464FC, 0x046210, 0 }, { 0x3A888889, 0x44200000 } }, // Re-Volt (PAL) Code 1 is a render fix
{ "MK-5119250", nullptr, { 0x0C5EB4, 0 }, { 0x3A888889 } }, // Rez (PAL)
{ "T15122N ", nullptr, { 0x8E7A80, 0x8E7AB4, 0 }, { 0x43E10000, 0x3FAAAAAB } }, // Ring, The - Terror's Realm (USA)
{ "MK-51010 ", nullptr, { 0x1A4D2C, 0x1A4D5C, 0 }, { 0x43F00000, 0x3F400000 } }, // Rippin' Riders (USA)
{ "HDR-0044 ", nullptr, { 0x298A94, 0x298AC4, 0 }, { 0x43F00000, 0x3F400000 } }, // Roommania #203 (JP)
{ "T15122N", nullptr, { 0x8E7A80, 0x8E7AB4, 0 }, { 0x43E10000, 0x3FAAAAAB } }, // Ring, The - Terror's Realm (USA)
{ "MK-51010", nullptr, { 0x1A4D2C, 0x1A4D5C, 0 }, { 0x43F00000, 0x3F400000 } }, // Rippin' Riders (USA)
{ "HDR-0044", nullptr, { 0x298A94, 0x298AC4, 0 }, { 0x43F00000, 0x3F400000 } }, // Roommania #203 (JP)
{ "MK-5109250", nullptr, { 0x29E6C4, 0 }, { 0x3F400000 } }, // Samba De Amigo (PAL)
{ "T41301N ", nullptr, { 0x77A178, 0 }, { 0x3F400000 } }, // Seventh Cross Evolution (USA)
{ "T41301N", nullptr, { 0x77A178, 0 }, { 0x3F400000 } }, // Seventh Cross Evolution (USA)
{ "T8104D 58", nullptr, { 0x2C03F8, 0 }, { 0x44558000 } }, // Shadow Man (PAL)
{ "T-8106N ", nullptr, { 0x2C03F4, 0 }, { 0x3F400000 } }, // Shadow Man (USA)
{ "MK-51048 ", nullptr, { 0x4AA4DC, 0x2B4E30, 0 }, { 0x3F400000, 0x3F400000 } }, // Seaman (USA)
{ "T-8106N", nullptr, { 0x2C03F4, 0 }, { 0x3F400000 } }, // Shadow Man (USA)
{ "MK-51048", nullptr, { 0x4AA4DC, 0x2B4E30, 0 }, { 0x3F400000, 0x3F400000 } }, // Seaman (USA)
{ "MK-5105350", nullptr, { 0x5D613C, 0 }, { 0x3F400000 } }, // Sega GT (PAL)
{ "MK-51096 ", nullptr, { 0x495050, 0 }, { 0x43700000 } }, // Sega Marine Fishing (USA)
// { "MK-51019 ", nullptr, { 0xB83A48, 0 }, { 0x3F400000 } }, // Sega Rally 2 (USA) not working?
// { "HDR0010 ", nullptr, { 0xBD9BA0, 0 }, { 0x3F400000 } }, // Sega Rally 2 (JP) not working?
{ "HDR-0151 ", nullptr, { 0xAF57DC, 0xAF580C, 0x2122A0, 0 },
{ "MK-51096", nullptr, { 0x495050, 0 }, { 0x43700000 } }, // Sega Marine Fishing (USA)
// { "MK-51019", nullptr, { 0xB83A48, 0 }, { 0x3F400000 } }, // Sega Rally 2 (USA) not working?
// { "HDR0010", nullptr, { 0xBD9BA0, 0 }, { 0x3F400000 } }, // Sega Rally 2 (JP) not working?
{ "HDR-0151", nullptr, { 0xAF57DC, 0xAF580C, 0x2122A0, 0 },
{ 0x43F00000, 0x3F400000, 0x3F400000 } }, // SGGG Segagaga (JP)
{ "MK-5105950", nullptr, { 0x231EF8, 0x1EF370, 0 }, { 0x43800000, 0x7C1EF400 } }, // Shenmue (PAL) code 1 reduces clipping
{ "MK-51059 ", nullptr, { 0x230250, 0 }, { 0x43800000 } }, // Shenmue (USA) Clipping
{ "HDR-0016 ", nullptr, { 0x22E8A0, 0x1EBE70, 0 }, { 0x43800000, 0x7C1EBF00 } }, // Shenmue (JP) code 1 reduces clipping
{ "MK-51059", nullptr, { 0x230250, 0 }, { 0x43800000 } }, // Shenmue (USA) Clipping
{ "HDR-0016", nullptr, { 0x22E8A0, 0x1EBE70, 0 }, { 0x43800000, 0x7C1EBF00 } }, // Shenmue (JP) code 1 reduces clipping
{ "MK-5118450", nullptr, { 0x31186C, 0 }, { 0x43800000 } }, // Shenmue II (PAL) 01160FF4 0000E100 for black bars in cutscenes
// Shenmue II (PAL) Alternative code without clipping or black bars. Might be demanding on real hardware.
// 02311880 C3A00000, 0227E198 35AA359E, 01160FF4 0000E100
{ "HDR-0164 ", nullptr, { 0x30D67C, 0 }, { 0x43700000 } }, // Shenmue II (JP) Clipping
{ "T9505D ", nullptr, { 0xD1FB14, 0x096A4C, 0 }, { 0x3F400000, 0x3FAAAAAB } }, // Silent Scope (PAL) Choose 60Hz in game options
{ "MK-51052 ", " E ", { 0x502A84, 0 }, { 0x3F400000 } }, // Skies of Arcadia (PAL)
{ "MK-51052 ", " U ", { 0x599158, 0 }, { 0x3F400000 } }, // Skies of Arcadia (USA)
{ "HDR-0164", nullptr, { 0x30D67C, 0 }, { 0x43700000 } }, // Shenmue II (JP) Clipping
{ "T9505D", nullptr, { 0xD1FB14, 0x096A4C, 0 }, { 0x3F400000, 0x3FAAAAAB } }, // Silent Scope (PAL) Choose 60Hz in game options
{ "MK-51052", " E ", { 0x502A84, 0 }, { 0x3F400000 } }, // Skies of Arcadia (PAL)
{ "MK-51052", " U ", { 0x599158, 0 }, { 0x3F400000 } }, // Skies of Arcadia (USA)
{ "T15104D 50", nullptr, { 0x17EF68, 0 }, { 0x43F00010 } }, // Slave Zero (PAL) Widescreen, but a bit zoomed in
{ "MK-5101050", nullptr, { 0x1A50EC, 0x1A511C, 0 }, { 0x43F00000, 0x3F400000 } }, // Snow Surfers (PAL)
{ "MK-5100050", nullptr, { 0x88F528, 0x88F55C, 0 }, { 0x43F00000, 0x3FA66666 } }, // Sonic Adventure (PAL)
{ "MK-51000 ", nullptr, { 0x88F5E8, 0x88F61C, 0 }, { 0x43F00000, 0x3FAAAAAB } }, // Sonic Adventure (USA)
{ "MK-51117 ", nullptr, { 0x28DEF8, 0x28DF28, 0 }, { 0x43F00000, 0x3f400000 } }, // Sonic Adventure 2 (USA)
{ "HDR-0165 ", nullptr, { 0x28DF28, 0x28DEF8, 0 }, { 0x3F400000, 0x43F00000 } }, // Sonic Adventure 2 (JP)
{ "MK-51060 ", nullptr, { 0x112A2C, 0 }, { 0x3F400000 } }, // Sonic Shuffle (US)
{ "MK-51000", nullptr, { 0x88F5E8, 0x88F61C, 0 }, { 0x43F00000, 0x3FAAAAAB } }, // Sonic Adventure (USA)
{ "MK-51117", nullptr, { 0x28DEF8, 0x28DF28, 0 }, { 0x43F00000, 0x3f400000 } }, // Sonic Adventure 2 (USA)
{ "HDR-0165", nullptr, { 0x28DF28, 0x28DEF8, 0 }, { 0x3F400000, 0x43F00000 } }, // Sonic Adventure 2 (JP)
{ "MK-51060", nullptr, { 0x112A2C, 0 }, { 0x3F400000 } }, // Sonic Shuffle (US)
{ "MK-5106050", nullptr, { 0x110B4C, 0 }, { 0x3F400000 } }, // Sonic Shuffle (PAL)
{ "T9103M ", nullptr, { 0x25C714, 0x25C744, 0 }, { 0x43F00000, 0x3F400000 } }, // Sorcerian - Shichisei Mahou no Shito
{ "T9103M", nullptr, { 0x25C714, 0x25C744, 0 }, { 0x43F00000, 0x3F400000 } }, // Sorcerian - Shichisei Mahou no Shito
{ "T1401D 50", nullptr, { 0x2D6138, 0 }, { 0x3F400000 } }, // Soul Calibur (PAL)
{ "T1401N ", nullptr, { 0x266C28, 0 }, { 0x3F400000 } }, // Soul Calibur (USA)
{ "T36802N ", " E ", { 0x129FA0, 0x12A9BC, 0x1C9FDC, 0 },
{ "T1401N", nullptr, { 0x266C28, 0 }, { 0x3F400000 } }, // Soul Calibur (USA)
{ "T36802N", " E ", { 0x129FA0, 0x12A9BC, 0x1C9FDC, 0 },
{ 0x3EF55555, 0x3EF55555, 0x000000F0 } }, // Soul Reaver (PAL) Code 2 is a Render Fix
{ "HDR-0190 ", nullptr, { 0x14D3E0, 0 }, { 0x3F400000 } }, // Space Channel 5 Part 2 (JP)
{ "T1216M ", nullptr, { 0x017C38, 0x17F00, 0 }, { 0x3A99999A, 0x3A99999A } }, // Spawn - In the Demon's Hand v1.003 (JP)
{ "T1216N ", nullptr, { 0x017C58, 0x17F20, 0 }, { 0x3A99999A, 0x3A99999A } }, // Spawn - In the Demon's Hand v1.000 (US)
{ "HDR-0190", nullptr, { 0x14D3E0, 0 }, { 0x3F400000 } }, // Space Channel 5 Part 2 (JP)
{ "T1216M", nullptr, { 0x017C38, 0x17F00, 0 }, { 0x3A99999A, 0x3A99999A } }, // Spawn - In the Demon's Hand v1.003 (JP)
{ "T1216N", nullptr, { 0x017C58, 0x17F20, 0 }, { 0x3A99999A, 0x3A99999A } }, // Spawn - In the Demon's Hand v1.000 (US)
{ "T36816D 50", nullptr, { 0x017C78, 0x17F40, 0 }, { 0x3A99999A, 0x3A99999A } }, // Spawn - In the Demon's Hand v1.000 (EU)
// Star Wars Episode I Racer (USA)
// Code 1-4 removes the black bars on top and bottom in FMV
{ "T23001N ", nullptr, { 0x17AE20, 0x29A96C, 0x29A98C, 0x29A9AC, 0x29A9CC, 0 },
{ "T23001N", nullptr, { 0x17AE20, 0x29A96C, 0x29A98C, 0x29A9AC, 0x29A9CC, 0 },
{ 0x3F400000, 0x42900000, 0x42900000, 0x43CE0000, 0x43CE0000 } },
{ "T40206N ", nullptr, { 0x43296C, 0 }, { 0x3F400000, 0 } }, // Super Magnetic Neo (US)
{ "T40206N", nullptr, { 0x43296C, 0 }, { 0x3F400000, 0 } }, // Super Magnetic Neo (US)
{ "T40206D 50", nullptr, { 0x43E34C, 0 }, { 0x3F400000, 0 } }, // Super Magnetic Neo (EU)
// { "T7014D 50", nullptr, { 0xE2B234, 0 }, { 0x3F800000 } }, // Super Runabout (PAL) doesn't work?
{ "T17721D 50", nullptr, { 0x45CED4, 0 }, { 0x3F400000 } }, // Surf Rocket Racers (PAL) alt: 021EBF40 3F400000
{ "T17703D 50", nullptr, { 0xCD8950, 0 }, { 0x3F111111 } }, // Suzuki Alstare Extreme Racing
{ "T36807D 05", nullptr, { 0x140F74, 0x140FA4, 0 }, { 0x43FA0000, 0x3F400000 } }, // Sword of Bersek (PAL)
{ "T-36805N ", nullptr, { 0x13F1C4, 0x13F194, 0 }, { 0x3F400000, 0x43F00000 } }, // Sword of Bersek (USA)
{ "MK-51186 ", nullptr, { 0x4A19B0, 0 }, { 0x43700000 } }, // Tennis 2K2 (USA)
{ "T15123N ", nullptr, { 0x29B7BC, 0 }, { 0x3F400000 } }, // Test Drive Le Mans (USA) doesn't work?
{ "T20801M ", nullptr, { 0x1AAC80, 0x1AACB0, 0 }, { 0x43F00000, 0x3F400000 } }, // Tetris 4D (JP)
{ "T-36805N", nullptr, { 0x13F1C4, 0x13F194, 0 }, { 0x3F400000, 0x43F00000 } }, // Sword of Bersek (USA)
{ "MK-51186", nullptr, { 0x4A19B0, 0 }, { 0x43700000 } }, // Tennis 2K2 (USA)
{ "T15123N", nullptr, { 0x29B7BC, 0 }, { 0x3F400000 } }, // Test Drive Le Mans (USA) doesn't work?
{ "T20801M", nullptr, { 0x1AAC80, 0x1AACB0, 0 }, { 0x43F00000, 0x3F400000 } }, // Tetris 4D (JP)
{ "MK-5101153", nullptr, { 0x14EFA8, 0x14EFD8, 0 }, { 0x43F00000, 0x3F400000 } }, // Timestalkers (PAL)
{ "T7009D50 ", nullptr, { 0x39173C, 0 }, { 0x3F400000 } }, // Tech Romancer (PAL)
{ "T35402M ", nullptr, { 0x315370, 0x3153A0, 0 }, { 0x43F00000, 0x3F400000 } }, // Tokyo Bus Guide (JP) doesn't work?
{ "T7009D50", nullptr, { 0x39173C, 0 }, { 0x3F400000 } }, // Tech Romancer (PAL)
{ "T35402M", nullptr, { 0x315370, 0x3153A0, 0 }, { 0x43F00000, 0x3F400000 } }, // Tokyo Bus Guide (JP) doesn't work?
{ "T40201D 50", nullptr, { 0x1D9F10, 0 }, { 0x3F400000 } }, // Tokyo Highway Challenge (PAL)
{ "T40210D 50", nullptr, { 0x21E4F8, 0 }, { 0x43700000 } }, // Tokyo Highway Challenge 2 (PAL)
{ "xxxxxxxxxx", nullptr, { 0x21DEF8, 0 }, { 0x3F400000 } }, // Tokyo Street Racer 2 (USA)
// { "T36804D05 ", nullptr, { 0xB75E28, 0 }, { 0x3EC00000 } }, // Tomb Raider: The Last Revelation (UK) (PAL) clipping, use hex patch instead
// { "T36804D05", nullptr, { 0xB75E28, 0 }, { 0x3EC00000 } }, // Tomb Raider: The Last Revelation (UK) (PAL) clipping, use hex patch instead
{ "T13008D 05", nullptr, { 0x1D7C20, 0 }, { 0x3FA66666 } }, // Tony Hawk's Pro Skater 2 (PAL)
{ "T13006N ", nullptr, { 0x1D77A0, 0 }, { 0x3FA66666 } }, // Tony Hawk's Pro Skater 2 (USA)
{ "T13006N", nullptr, { 0x1D77A0, 0 }, { 0x3FA66666 } }, // Tony Hawk's Pro Skater 2 (USA)
{ "MK-5102050", nullptr, { 0x0D592C, 0 }, { 0x3FD00000 } }, // Toy Commander (PAL)
{ "xxxxxxxxxx", nullptr, { 0x469FCC, 0x469FFC, 0 }, { 0x44700000, 0x3F400000 } }, // Toyota Doricatch Series: Land Cruiser 100/Cygnus
{ "MK-5109505", nullptr, { 0x1B2718, 0 }, { 0x3F400000 } }, // UEFA Dream Soccer (PAL)
{ "T40203D 50", nullptr, { 0x1D74E8, 0x1D7518, 0 }, { 0x43F00000, 0x3F400000 } }, // Ultimate Fighting Championship (PAL)
{ "T40204N ", nullptr, { 0x1A9684, 0 }, { 0x3F400000 } }, // Ultimate Fighting Championship (USA) problems with cam in game
{ "T40204N", nullptr, { 0x1A9684, 0 }, { 0x3F400000 } }, // Ultimate Fighting Championship (USA) problems with cam in game
{ "T-8110D-50", nullptr, { 0x0C6B90, 0x0C6B94, 0 }, { 0x43F00000, 0x43870000 } }, // Vanishing Point (PAL)
// { "MK-5109450", nullptr, { 0x244134, 0x7A73B8, 0x7830D8, 0x7A74B8, 0x783138, 0x7A85A0, 0x6C7928, 0x6C7930, 0x6C7948, 0x6C7950, 0 },
//crash { 0x43F00000, 0x3F9C932E, 0x3F9C932E, 0x3F9C932E, 0x3F9C932E, 0x3F400000, 0, 0, 0, 0 } }, // Virtua Athlete 2K (PAL)
{ "MK-5100150", nullptr, { 0x19D718, 0 }, { 0x43700000 } }, // Virtua Fighter 3 TB (PAL)
{ "HDR-0002 ", nullptr, { 0x199FB0, 0 }, { 0x43700000 } }, // Virtua Fighter 3 TB (JP)
{ "HDR-0002", nullptr, { 0x199FB0, 0 }, { 0x43700000 } }, // Virtua Fighter 3 TB (JP)
{ "MK-5105450", nullptr, { 0x456378, 0 }, { 0x43700000 } }, // Virtua Tennis (v1.001) (PAL)
{ "MK-51054 ", nullptr, { 0x450A90, 0 }, { 0x43700000 } }, // Virtua Tennis (USA)
{ "MK-51054", nullptr, { 0x450A90, 0 }, { 0x43700000 } }, // Virtua Tennis (USA)
{ "MK-5118650", nullptr, { 0x4A4A20, 0 }, { 0x43700000 } }, // Virtua Tennis 2 (PAL)
// { "T0000 ", nullptr, { 0x3A514C, 0x3A6170, 0 }, { 0x3F400000, 0x00000356 } }, // Volgarr the Viking. Not working
// { "T0000", nullptr, { 0x3A514C, 0x3A6170, 0 }, { 0x3F400000, 0x00000356 } }, // Volgarr the Viking. Not working
{ "xxxxxxxxxx", nullptr, { 0x20BB68, 0x1ACBD0, 0x1B9ADC, 0 }, // Code 1 reduces clipping. Code 2 fixes the clock.
{ 0x43700000, 0x7C1ACC60, 0x3F400000 } }, // What's Shenmue (JP)
{ "T40504D 50", nullptr, { 0x75281C, 0 }, { 0x3F400000 } }, // Wetrix+ (PAL) not working?
{ "MK-51152 ", nullptr, { 0x014E90, 0 }, { 0x43700000 } }, // World Series Baseball 2K2 (USA)
{ "T20401M ", nullptr, { 0x323CB0, 0x1ACBD0, 0x1B9ADC, 0 }, // Code 1 reduces clipping. Code 2 fixes the HUD.
{ "MK-51152", nullptr, { 0x014E90, 0 }, { 0x43700000 } }, // World Series Baseball 2K2 (USA)
{ "T20401M", nullptr, { 0x323CB0, 0x1ACBD0, 0x1B9ADC, 0 }, // Code 1 reduces clipping. Code 2 fixes the HUD.
{ 0x43700000, 0x1ACC60, 0x3F400000 } }, // Zero Gunner 2 (JP)
{ "MK-5103850", nullptr, { 0x9484E8, 0 }, { 0x43700000 } }, // Zombie Revenge (PAL)
{ "MK-51038 ", nullptr, { 0x948058, 0 }, { 0x43700000 } }, // Zombie Revenge (USA)
{ "HDR-0026 ", nullptr, { 0x948B18, 0 }, { 0x43700000 } }, // Zombie Revenge (JP)
{ "T43301M ", nullptr, { 0x4B0218, 0 }, { 0x3F400000 } }, // Zusar Vasar (JP)
{ "MK-51038", nullptr, { 0x948058, 0 }, { 0x43700000 } }, // Zombie Revenge (USA)
{ "HDR-0026", nullptr, { 0x948B18, 0 }, { 0x43700000 } }, // Zombie Revenge (JP)
{ "T43301M", nullptr, { 0x4B0218, 0 }, { 0x3F400000 } }, // Zusar Vasar (JP)
{ nullptr },
};
const Cheat CheatManager::_naomi_widescreen_cheats[] =
const WidescreenCheat CheatManager::naomi_widescreen_cheats[] =
{
{ "KNIGHTS OF VALOUR THE 7 SPIRITS", nullptr, { 0x475B70, 0x475B40, 0 }, { 0x3F400000, 0x43F00000 } },
{ "Dolphin Blue", nullptr, { 0x3F2E2C, 0x3F2190, 0x3F2E6C, 0x3F215C, 0 },
@ -303,54 +304,216 @@ const Cheat CheatManager::_naomi_widescreen_cheats[] =
};
CheatManager cheatManager;
bool CheatManager::Reset()
void CheatManager::loadCheatFile(const std::string& filename)
{
active = false;
_widescreen_cheat = nullptr;
FILE* cheatfile = nowide::fopen(filename.c_str(), "r");
if (cheatfile == nullptr)
{
WARN_LOG(COMMON, "Cannot open cheat file '%s'", filename.c_str());
return;
}
cheats.clear();
Cheat cheat;
int cheatNumber = 0;
char buffer[512];
while (fgets(buffer, sizeof(buffer), cheatfile) != nullptr)
{
std::string l = buffer;
auto equalPos = l.find("=");
if (equalPos == std::string::npos)
continue;
auto quotePos = l.find("\"", equalPos);
if (quotePos == std::string::npos)
continue;
auto quote2Pos = l.find("\"", quotePos + 1);
if (quote2Pos == std::string::npos)
continue;
if (l.substr(0, 5) != "cheat" || l[5] < '0' || l[5] > '9')
continue;
char *p;
int number = strtol(&l[5], &p, 10);
if (number != cheatNumber && cheat.type != Cheat::Type::disabled)
{
cheatNumber = number;
cheats.push_back(cheat);
cheat = Cheat();
}
std::string param = trim_trailing_ws(l.substr(p - &l[0], equalPos - (p - &l[0])));
std::string value = l.substr(quotePos + 1, quote2Pos - quotePos - 1);
if (param == "_address")
{
cheat.address = strtol(value.c_str(), nullptr, 10);
verify(cheat.address < RAM_SIZE);
}
else if (param == "_cheat_type")
cheat.type = (Cheat::Type)strtol(value.c_str(), nullptr, 10);
else if (param == "_desc")
cheat.description = value;
else if (param == "_memory_search_size")
cheat.size = 1 << strtol(value.c_str(), nullptr, 10);
else if (param == "_value")
cheat.value = strtol(value.c_str(), nullptr, 10);
else if (param == "_repeat_count")
cheat.repeatCount = strtol(value.c_str(), nullptr, 10);
else if (param == "_repeat_add_to_value")
cheat.repeatValueIncrement = strtol(value.c_str(), nullptr, 10);
else if (param == "_repeat_add_to_address")
cheat.repeatAddressIncrement = strtol(value.c_str(), nullptr, 10);
else if (param == "_enable")
cheat.enabled = value == "true";
}
std::fclose(cheatfile);
if (cheat.type != Cheat::Type::disabled)
cheats.push_back(cheat);
active = !cheats.empty();
INFO_LOG(COMMON, "%d cheats loaded", (int)cheats.size());
cfgSaveStr("cheats", gameId, filename);
}
void CheatManager::reset(const std::string& gameId)
{
if (this->gameId != gameId)
{
cheats.clear();
active = false;
this->gameId = gameId;
std::string cheatFile = cfgLoadStr("cheats", gameId, "");
if (!cheatFile.empty())
loadCheatFile(cheatFile);
}
widescreen_cheat = nullptr;
if (!config::WidescreenGameHacks)
return false;
return;
if (settings.platform.system == DC_PLATFORM_DREAMCAST)
{
std::string game_id(ip_meta.product_number, sizeof(ip_meta.product_number));
for (int i = 0; _widescreen_cheats[i].game_id != nullptr; i++)
for (int i = 0; widescreen_cheats[i].game_id != nullptr; i++)
{
if (!strncmp(game_id.c_str(), _widescreen_cheats[i].game_id, game_id.length())
&& (_widescreen_cheats[i].area_or_version == nullptr
|| !strncmp(ip_meta.area_symbols, _widescreen_cheats[i].area_or_version, sizeof(ip_meta.area_symbols))
|| !strncmp(ip_meta.product_version, _widescreen_cheats[i].area_or_version, sizeof(ip_meta.product_version))))
if (!strcmp(gameId.c_str(), widescreen_cheats[i].game_id)
&& (widescreen_cheats[i].area_or_version == nullptr
|| !strncmp(ip_meta.area_symbols, widescreen_cheats[i].area_or_version, sizeof(ip_meta.area_symbols))
|| !strncmp(ip_meta.product_version, widescreen_cheats[i].area_or_version, sizeof(ip_meta.product_version))))
{
_widescreen_cheat = &_widescreen_cheats[i];
NOTICE_LOG(COMMON, "Applying widescreen hack to game %s", game_id.c_str());
widescreen_cheat = &widescreen_cheats[i];
NOTICE_LOG(COMMON, "Applying widescreen hack to game %s", gameId.c_str());
break;
}
}
}
else
{
for (int i = 0; _naomi_widescreen_cheats[i].game_id != nullptr; i++)
for (int i = 0; naomi_widescreen_cheats[i].game_id != nullptr; i++)
{
if (!strcmp(naomi_game_id, _naomi_widescreen_cheats[i].game_id))
if (!strcmp(gameId.c_str(), naomi_widescreen_cheats[i].game_id))
{
_widescreen_cheat = &_naomi_widescreen_cheats[i];
NOTICE_LOG(COMMON, "Applying widescreen hack to game %s", naomi_game_id);
widescreen_cheat = &naomi_widescreen_cheats[i];
NOTICE_LOG(COMMON, "Applying widescreen hack to game %s", gameId.c_str());
break;
}
}
}
if (_widescreen_cheat == nullptr)
return false;
for (size_t i = 0; i < ARRAY_SIZE(_widescreen_cheat->addresses) && _widescreen_cheat->addresses[i] != 0; i++)
verify(_widescreen_cheat->addresses[i] < RAM_SIZE);
active = true;
return true;
if (widescreen_cheat == nullptr)
return;
for (size_t i = 0; i < ARRAY_SIZE(widescreen_cheat->addresses) && widescreen_cheat->addresses[i] != 0; i++)
verify(widescreen_cheat->addresses[i] < RAM_SIZE);
}
void CheatManager::Apply()
u32 CheatManager::readRam(u32 addr, u32 bits)
{
if (_widescreen_cheat != nullptr)
switch (bits)
{
for (size_t i = 0; i < ARRAY_SIZE(_widescreen_cheat->addresses) && _widescreen_cheat->addresses[i] != 0; i++)
WriteMem32_nommu(0x8C000000 + _widescreen_cheat->addresses[i], _widescreen_cheat->values[i]);
case 8:
return ReadMem8_nommu(0x8C000000 + addr);
case 16:
return ReadMem16_nommu(0x8C000000 + addr);
case 32:
return ReadMem32_nommu(0x8C000000 + addr);
default:
die("invalid size");
return 0;
}
}
void CheatManager::writeRam(u32 addr, u32 value, u32 bits)
{
switch (bits)
{
case 8:
WriteMem8_nommu(0x8C000000 + addr, (u8)value);
break;
case 16:
WriteMem16_nommu(0x8C000000 + addr, (u16)value);
break;
case 32:
WriteMem32_nommu(0x8C000000 + addr, value);
break;
default:
die("invalid size");
break;
}
}
void CheatManager::apply()
{
if (widescreen_cheat != nullptr)
{
for (size_t i = 0; i < ARRAY_SIZE(widescreen_cheat->addresses) && widescreen_cheat->addresses[i] != 0; i++)
writeRam(widescreen_cheat->addresses[i], widescreen_cheat->values[i], 32);
}
if (active && !networkStarted())
{
bool skipCheat = false;
for (const Cheat& cheat : cheats)
{
if (skipCheat) {
skipCheat = false;
continue;
}
if (!cheat.enabled)
continue;
bool setValue = false;
u32 valueToSet = 0;
switch (cheat.type)
{
case Cheat::Type::disabled:
default:
break;
case Cheat::Type::setValue:
setValue = true;
valueToSet = cheat.value;
break;
case Cheat::Type::increase:
setValue = true;
valueToSet = readRam(cheat.address, cheat.size) + cheat.value;
break;
case Cheat::Type::decrease:
setValue = true;
valueToSet = readRam(cheat.address, cheat.size) - cheat.value;
break;
case Cheat::Type::runNextIfEq:
skipCheat = readRam(cheat.address, cheat.size) != cheat.value;
break;
case Cheat::Type::runNextIfNeq:
skipCheat = readRam(cheat.address, cheat.size) == cheat.value;
break;
case Cheat::Type::runNextIfGt:
skipCheat = readRam(cheat.address, cheat.size) <= cheat.value;
break;
case Cheat::Type::runNextIfLt:
skipCheat = readRam(cheat.address, cheat.size) >= cheat.value;
break;
}
if (setValue)
{
u32 address = cheat.address;
for (u32 repeat = 0; repeat < cheat.repeatCount; repeat++)
{
writeRam(address, valueToSet, cheat.size);
address += cheat.repeatAddressIncrement * cheat.size / 8;
valueToSet += cheat.repeatValueIncrement;
}
}
}
}
}

View File

@ -21,7 +21,7 @@
#pragma once
#include "types.h"
struct Cheat
struct WidescreenCheat
{
const char *game_id;
const char *area_or_version;
@ -29,19 +29,52 @@ struct Cheat
u32 values[16];
};
struct Cheat
{
enum class Type {
disabled,
setValue,
increase,
decrease,
runNextIfEq,
runNextIfNeq,
runNextIfGt,
runNextIfLt
};
Type type = Type::disabled;
std::string description;
bool enabled = false;
u32 size = 0;
u32 address = 0;
u32 value = 0;
u32 repeatCount = 1;
u32 repeatValueIncrement = 0;
u32 repeatAddressIncrement = 0;
};
class CheatManager
{
public:
CheatManager() : _widescreen_cheat(nullptr) {}
bool Reset(); // Returns true if using 16:9 anamorphic screen ratio
void Apply();
bool isActive() const { return active; }
void reset(const std::string& gameId);
void apply();
size_t cheatCount() const { return cheats.size(); }
const std::string& cheatDescription(size_t index) const { return cheats[index].description; }
bool cheatEnabled(size_t index) const { return cheats[index].enabled; }
void enableCheat(size_t index, bool enabled) { cheats[index].enabled = enabled; }
void loadCheatFile(const std::string& filename);
// Returns true if using 16:9 anamorphic screen ratio
bool isWidescreen() const { return widescreen_cheat != nullptr; }
private:
static const Cheat _widescreen_cheats[];
static const Cheat _naomi_widescreen_cheats[];
const Cheat *_widescreen_cheat;
u32 readRam(u32 addr, u32 bits);
void writeRam(u32 addr, u32 value, u32 bits);
static const WidescreenCheat widescreen_cheats[];
static const WidescreenCheat naomi_widescreen_cheats[];
const WidescreenCheat *widescreen_cheat = nullptr;
bool active = false;
std::vector<Cheat> cheats;
std::string gameId;
};
extern CheatManager cheatManager;

View File

@ -392,7 +392,7 @@ void rend_vblank()
}
render_called = false;
check_framebuffer_write();
cheatManager.Apply();
cheatManager.apply();
}
void check_framebuffer_write()

View File

@ -1079,6 +1079,11 @@ void stop_pico()
pico_thread.WaitToEnd();
}
bool networkStarted()
{
return pico_thread_running;
}
#else
#include "types.h"
@ -1088,5 +1093,8 @@ void stop_pico() { }
void write_pico(u8 b) { }
int read_pico() { return -1; }
void pico_receive_eth_frame(const u8* frame, u32 size) {}
bool networkStarted()
{
return false;
}
#endif

View File

@ -24,6 +24,7 @@ bool start_pico();
void stop_pico();
void write_pico(u8 b);
int read_pico();
bool networkStarted();
void pico_receive_eth_frame(const u8 *frame, u32 size);
// implemented in bba

View File

@ -580,7 +580,8 @@ static void dc_start_game(const char *path)
else if (settings.platform.system == DC_PLATFORM_ATOMISWAVE)
mcfg_CreateAtomisWaveControllers();
}
if (cheatManager.Reset())
cheatManager.reset(config::Settings::instance().getGameId());
if (cheatManager.isWidescreen())
{
gui_display_notification("Widescreen cheat activated", 1000);
config::ScreenStretching.override(134); // 4:3 -> 16:9

View File

@ -68,6 +68,7 @@
#include "wsi/gl_context.h"
#include "glcache.h"
#include "hw/pvr/Renderer_if.h"
// OpenGL Data
static char g_GlslVersionString[32] = "";
@ -76,7 +77,6 @@ static GLuint g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0;
static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0;
static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0;
static unsigned int g_VboHandle = 0, g_ElementsHandle = 0;
static GLuint g_BackgroundTexture = 0;
// Functions
bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
@ -118,7 +118,7 @@ void ImGui_ImplOpenGL3_NewFrame()
// OpenGL3 Render function.
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so.
void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data, bool save_background)
void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
{
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
ImGuiIO& io = ImGui::GetIO();
@ -140,28 +140,6 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data, bool save_backgr
}
#endif
if (save_background)
{
#ifndef GLES2
if (!theGLContext.IsGLES() && glReadBuffer != NULL)
glReadBuffer(GL_FRONT);
// (Re-)create the background texture and reserve space for it
if (g_BackgroundTexture != 0)
glcache.DeleteTextures(1, &g_BackgroundTexture);
g_BackgroundTexture = glcache.GenTexture();
glcache.BindTexture(GL_TEXTURE_2D, g_BackgroundTexture);
glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, fb_width, fb_height, 0, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)NULL);
// Copy the current framebuffer into it
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, fb_width, fb_height);
#endif
}
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill
glcache.Enable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
@ -506,10 +484,6 @@ void ImGui_ImplOpenGL3_DestroyDeviceObjects()
g_ShaderHandle = 0;
ImGui_ImplOpenGL3_DestroyFontsTexture();
if (g_BackgroundTexture != 0)
glcache.DeleteTextures(1, &g_BackgroundTexture);
g_BackgroundTexture = 0;
}
void ImGui_ImplOpenGL3_DrawBackground()
@ -518,16 +492,8 @@ void ImGui_ImplOpenGL3_DrawBackground()
glcache.Disable(GL_SCISSOR_TEST);
glcache.ClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
if (g_BackgroundTexture != 0)
{
ImGuiIO& io = ImGui::GetIO();
ImGui::SetNextWindowPos(ImVec2(0, 0));
ImGui::SetNextWindowSize(io.DisplaySize);
ImGui::Begin("background", NULL, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoFocusOnAppearing
| ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoBackground);
ImGui::GetWindowDrawList()->AddImage((ImTextureID)(uintptr_t)g_BackgroundTexture, ImVec2(0, 0), io.DisplaySize, ImVec2(0, 1), ImVec2(1, 0), 0xffffffff);
ImGui::End();
}
if (renderer != nullptr)
renderer->RenderLastFrame();
}
static ImTextureID createSimpleTexture(const unsigned int *data, u32 width, u32 height)

View File

@ -32,7 +32,7 @@
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = NULL);
IMGUI_IMPL_API void ImGui_ImplOpenGL3_Shutdown();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data, bool save_background = false);
IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data);
IMGUI_IMPL_API void ImGui_ImplOpenGL3_DrawBackground();
IMGUI_IMPL_API ImTextureID ImGui_ImplOpenGL3_CreateVmuTexture(const unsigned int *);
IMGUI_IMPL_API void ImGui_ImplOpenGL3_DeleteTexture(ImTextureID);

View File

@ -45,7 +45,6 @@
extern void UpdateInputState();
static bool game_started;
extern int screen_width, screen_height;
extern u8 kb_shift; // shift keys pressed (bitmask)
extern u8 kb_key[6]; // normal keys pressed
@ -54,7 +53,6 @@ int screen_dpi = 96;
static bool inited = false;
float scaling = 1;
GuiState gui_state = GuiState::Main;
static bool settings_opening;
#ifdef __ANDROID__
static bool touch_up;
#endif
@ -70,11 +68,6 @@ static void displayCrosshairs();
GameScanner scanner;
float gui_get_scaling()
{
return scaling;
}
static void emuEventCallback(Event event)
{
switch (event)
@ -249,7 +242,7 @@ void gui_init()
EventManager::listen(Event::Terminate, emuEventCallback);
}
void ImGui_Impl_NewFrame()
static void ImGui_Impl_NewFrame()
{
if (config::RendererType.isOpenGL())
ImGui_ImplOpenGL3_NewFrame();
@ -358,7 +351,6 @@ void gui_open_settings()
if (gui_state == GuiState::Closed)
{
gui_state = GuiState::Commands;
settings_opening = true;
HideOSD();
}
else if (gui_state == GuiState::VJoyEdit)
@ -391,16 +383,12 @@ static void gui_display_commands()
{
dc_stop();
ImGui_Impl_NewFrame();
ImGui::NewFrame();
if (!settings_opening && config::RendererType.isOpenGL())
ImGui_ImplOpenGL3_DrawBackground();
if (config::RendererType.isOpenGL())
ImGui_ImplOpenGL3_DrawBackground();
if (!config::FloatVMUs)
// If floating VMUs, they are already visible on the background
display_vmus();
display_vmus();
ImGui::SetNextWindowPos(ImVec2(screen_width / 2.f, screen_height / 2.f), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
centerNextWindow();
ImGui::SetNextWindowSize(ImVec2(330 * scaling, 0));
ImGui::Begin("##commands", NULL, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize);
@ -454,7 +442,13 @@ static void gui_display_commands()
}
}
ImGui::NextColumn();
if (ImGui::Button("Exit", ImVec2(150 * scaling, 50 * scaling)))
if (ImGui::Button("Cheats", ImVec2(150 * scaling, 50 * scaling)))
{
gui_state = GuiState::Cheats;
}
ImGui::Columns(1, nullptr, false);
if (ImGui::Button("Exit", ImVec2(300 * scaling + ImGui::GetStyle().ColumnsMinSpacing + ImGui::GetStyle().FramePadding.x * 2 - 1,
50 * scaling)))
{
// Exit to main menu
dc_term_game();
@ -464,10 +458,6 @@ static void gui_display_commands()
}
ImGui::End();
ImGui::Render();
ImGui_impl_RenderDrawData(ImGui::GetDrawData(), settings_opening);
settings_opening = false;
}
const char *maple_device_types[] = { "None", "Sega Controller", "Light Gun", "Keyboard", "Mouse", "Twin Stick", "Ascii Stick" };
@ -597,11 +587,6 @@ static double map_start_time;
static bool arcade_button_mode;
static u32 gamepad_port;
static void input_detected(u32 code)
{
mapped_code = code;
}
static void detect_input_popup(int index, bool analog)
{
ImVec2 padding = ImVec2(20 * scaling, 20 * scaling);
@ -725,7 +710,10 @@ static void controller_mapping_popup(const std::shared_ptr<GamepadDevice>& gamep
ImGui::OpenPopup("Map Button");
mapped_device = gamepad;
mapped_code = -1;
gamepad->detect_btn_input(&input_detected);
gamepad->detect_btn_input([](u32 code)
{
mapped_code = code;
});
}
detect_input_popup(j, false);
ImGui::NextColumn();
@ -772,7 +760,10 @@ static void controller_mapping_popup(const std::shared_ptr<GamepadDevice>& gamep
ImGui::OpenPopup("Map Axis");
mapped_device = gamepad;
mapped_code = -1;
gamepad->detect_axis_input(&input_detected);
gamepad->detect_axis_input([](u32 code)
{
mapped_code = code;
});
}
detect_input_popup(j, true);
ImGui::NextColumn();
@ -848,7 +839,7 @@ static void contentpath_warning_popup()
{
scanner.stop();
ImGui::OpenPopup("Select Directory");
select_directory_popup("Select Directory", scaling, [](bool cancelled, std::string selection)
select_file_popup("Select Directory", [](bool cancelled, std::string selection)
{
show_contentpath_selection = false;
if (!cancelled)
@ -861,23 +852,10 @@ static void contentpath_warning_popup()
}
}
void directory_selected_callback(bool cancelled, std::string selection)
{
if (!cancelled)
{
scanner.stop();
config::ContentPath.get().push_back(selection);
scanner.refresh();
}
}
static void gui_display_settings()
{
static bool maple_devices_changed;
ImGui_Impl_NewFrame();
ImGui::NewFrame();
RenderType pvr_rend = config::RendererType;
bool vulkan = !config::RendererType.isOpenGL();
ImGui::SetNextWindowPos(ImVec2(0, 0));
@ -991,7 +969,15 @@ static void gui_display_settings()
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(24 * scaling, 3 * scaling));
if (ImGui::Button("Add"))
ImGui::OpenPopup("Select Directory");
select_directory_popup("Select Directory", scaling, &directory_selected_callback);
select_file_popup("Select Directory", [](bool cancelled, std::string selection)
{
if (!cancelled)
{
scanner.stop();
config::ContentPath.get().push_back(selection);
scanner.refresh();
}
});
ImGui::PopStyleVar();
ImGui::ListBoxFooter();
@ -1624,9 +1610,6 @@ static void gui_display_settings()
ImGui::End();
ImGui::PopStyleVar();
ImGui::Render();
ImGui_impl_RenderDrawData(ImGui::GetDrawData(), false);
if (vulkan != !config::RendererType.isOpenGL())
pvr_rend = !vulkan ? RenderType::OpenGL
: config::RendererType == RenderType::OpenGL_OIT ? RenderType::Vulkan_OIT : RenderType::Vulkan;
@ -1650,19 +1633,11 @@ static std::string get_notification()
inline static void gui_display_demo()
{
ImGui_Impl_NewFrame();
ImGui::NewFrame();
ImGui::ShowDemoWindow();
ImGui::Render();
ImGui_impl_RenderDrawData(ImGui::GetDrawData(), false);
}
static void gui_display_content()
{
ImGui_Impl_NewFrame();
ImGui::NewFrame();
ImGui::SetNextWindowPos(ImVec2(0, 0));
ImGui::SetNextWindowSize(ImVec2(screen_width, screen_height));
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0);
@ -1672,7 +1647,9 @@ static void gui_display_content()
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(20 * scaling, 8 * scaling)); // from 8, 4
ImGui::AlignTextToFramePadding();
ImGui::Indent(10 * scaling);
ImGui::Text("GAMES");
ImGui::Unindent(10 * scaling);
static ImGuiTextFilter filter;
if (KeyboardDevice::GetInstance() != NULL)
@ -1682,8 +1659,8 @@ static void gui_display_content()
}
if (gui_state != GuiState::SelectDisk)
{
ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize("Settings").x - ImGui::GetStyle().FramePadding.x * 2.0f /*+ ImGui::GetStyle().ItemSpacing.x*/);
if (ImGui::Button("Settings"))//, ImVec2(0, 30 * scaling)))
ImGui::SameLine(ImGui::GetContentRegionMax().x - ImGui::CalcTextSize("Settings").x - ImGui::GetStyle().FramePadding.x * 2.0f);
if (ImGui::Button("Settings"))
gui_state = GuiState::Settings;
}
ImGui::PopStyleVar();
@ -1751,9 +1728,6 @@ static void gui_display_content()
error_popup();
contentpath_warning_popup();
ImGui::Render();
ImGui_impl_RenderDrawData(ImGui::GetDrawData(), false);
}
static void systemdir_selected_callback(bool cancelled, std::string selection)
@ -1793,14 +1767,8 @@ static void systemdir_selected_callback(bool cancelled, std::string selection)
static void gui_display_onboarding()
{
ImGui_Impl_NewFrame();
ImGui::NewFrame();
ImGui::OpenPopup("Select System Directory");
select_directory_popup("Select System Directory", scaling, &systemdir_selected_callback);
ImGui::Render();
ImGui_impl_RenderDrawData(ImGui::GetDrawData(), false);
select_file_popup("Select System Directory", &systemdir_selected_callback);
}
static std::future<bool> networkStatus;
@ -1813,10 +1781,7 @@ static void start_network()
static void gui_network_start()
{
ImGui_Impl_NewFrame();
ImGui::NewFrame();
ImGui::SetNextWindowPos(ImVec2(screen_width / 2, screen_height / 2), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
centerNextWindow();
ImGui::SetNextWindowSize(ImVec2(330 * scaling, 180 * scaling));
ImGui::Begin("##network", NULL, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize);
@ -1860,21 +1825,16 @@ static void gui_network_start()
ImGui::End();
ImGui::Render();
ImGui_impl_RenderDrawData(ImGui::GetDrawData(), false);
if ((kcode[0] & DC_BTN_START) == 0)
naomiNetwork.startNow();
}
static void gui_display_loadscreen()
{
ImGui_Impl_NewFrame();
ImGui::NewFrame();
if (config::RendererType.isOpenGL())
ImGui_ImplOpenGL3_DrawBackground();
ImGui::SetNextWindowPos(ImVec2(screen_width / 2, screen_height / 2), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
centerNextWindow();
ImGui::SetNextWindowSize(ImVec2(330 * scaling, 180 * scaling));
ImGui::Begin("##loading", NULL, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize);
@ -1923,13 +1883,25 @@ static void gui_display_loadscreen()
ImGui::PopStyleVar();
ImGui::End();
ImGui::Render();
ImGui_impl_RenderDrawData(ImGui::GetDrawData(), false);
}
void gui_display_ui()
{
if (gui_state == GuiState::Closed || gui_state == GuiState::VJoyEdit)
return;
if (gui_state == GuiState::Main)
{
std::string game_file = settings.imgread.ImagePath;
if (!game_file.empty())
{
gui_start_game(game_file);
return;
}
}
ImGui_Impl_NewFrame();
ImGui::NewFrame();
switch (gui_state)
{
case GuiState::Settings:
@ -1940,13 +1912,7 @@ void gui_display_ui()
break;
case GuiState::Main:
//gui_display_demo();
{
std::string game_file = settings.imgread.ImagePath;
if (!game_file.empty())
gui_start_game(game_file);
else
gui_display_content();
}
gui_display_content();
break;
case GuiState::Closed:
break;
@ -1969,10 +1935,15 @@ void gui_display_ui()
case GuiState::NetworkStart:
gui_network_start();
break;
case GuiState::Cheats:
gui_cheats();
break;
default:
die("Unknown UI state");
break;
}
ImGui::Render();
ImGui_impl_RenderDrawData(ImGui::GetDrawData());
if (gui_state == GuiState::Closed)
dc_resume();

View File

@ -28,6 +28,7 @@ void gui_display_osd();
void gui_open_onboarding();
void gui_term();
void gui_refresh_files();
void gui_cheats();
extern int screen_dpi;
extern float scaling;
@ -45,10 +46,10 @@ enum class GuiState {
VJoyEditCommands,
SelectDisk,
Loading,
NetworkStart
NetworkStart,
Cheats
};
extern GuiState gui_state;
void ImGui_Impl_NewFrame();
static inline bool gui_is_open()
{
@ -58,7 +59,9 @@ static inline bool gui_is_content_browser()
{
return gui_state == GuiState::Main;
}
float gui_get_scaling();
static inline float gui_get_scaling() {
return scaling;
}
#define XHAIR_WIDTH (40 * scaling)
#define XHAIR_HEIGHT (40 * scaling)

View File

@ -31,10 +31,7 @@ void vjoy_stop_editing(bool canceled);
void gui_display_vjoy_commands(int screen_width, int screen_height, float scaling)
{
ImGui_Impl_NewFrame();
ImGui::NewFrame();
ImGui::SetNextWindowPos(ImVec2(screen_width / 2.f, screen_height / 2.f), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
centerNextWindow();
ImGui::Begin("Virtual Joystick", NULL, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse
| ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize);
@ -58,9 +55,6 @@ void gui_display_vjoy_commands(int screen_width, int screen_height, float scalin
gui_state = GuiState::Settings;
}
ImGui::End();
ImGui::Render();
ImGui_impl_RenderDrawData(ImGui::GetDrawData(), false);
}
#endif // __ANDROID__

74
core/rend/gui_cheats.cpp Normal file
View File

@ -0,0 +1,74 @@
/*
Copyright 2021 flyinghead
This file is part of Flycast.
Flycast is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Flycast is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
*/
#include "gui.h"
#include "imgui/imgui.h"
#include "gui_util.h"
#include "cheats.h"
void gui_cheats()
{
if (config::RendererType.isOpenGL())
ImGui_ImplOpenGL3_DrawBackground();
centerNextWindow();
ImGui::SetNextWindowSize(ImVec2(std::min<float>(screen_width, 600 * scaling), std::min<float>(screen_height, 400 * scaling)));
ImGui::Begin("##main", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar
| ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(20 * scaling, 8 * scaling)); // from 8, 4
ImGui::AlignTextToFramePadding();
ImGui::Indent(10 * scaling);
ImGui::Text("CHEATS");
ImGui::SameLine(ImGui::GetWindowContentRegionMax().x - ImGui::CalcTextSize("Close").x - ImGui::GetStyle().FramePadding.x * 4.f
- ImGui::CalcTextSize("Load").x - ImGui::GetStyle().ItemSpacing.x);
if (ImGui::Button("Load"))
ImGui::OpenPopup("Select cheat file");
select_file_popup("Select cheat file", [](bool cancelled, std::string selection)
{
if (cancelled)
return;
cheatManager.loadCheatFile(selection);
}, true, "cht");
ImGui::SameLine();
if (ImGui::Button("Close"))
gui_state = GuiState::Commands;
ImGui::Unindent(10 * scaling);
ImGui::PopStyleVar();
ImGui::BeginChild(ImGui::GetID("cheats"), ImVec2(0, 0), true);
{
if (cheatManager.cheatCount() == 0)
ImGui::Text("(No cheat loaded)");
else
for (size_t i = 0; i < cheatManager.cheatCount(); i++)
{
ImGui::PushID(("cheat" + std::to_string(i)).c_str());
bool v = cheatManager.cheatEnabled(i);
if (ImGui::Checkbox(cheatManager.cheatDescription(i).c_str(), &v))
cheatManager.enableCheat(i, v);
ImGui::PopID();
}
}
ImGui::EndChild();
ImGui::End();
}

View File

@ -28,11 +28,9 @@
#include "imgui/imgui.h"
#include "imgui/imgui_internal.h"
extern int screen_width, screen_height;
static std::string select_current_directory;
static std::vector<std::string> select_subfolders;
static std::vector<std::string> display_files;
static std::vector<std::string> subfolders;
static std::vector<std::string> folderFiles;
bool subfolders_read;
#ifdef _WIN32
static const std::string separators = "/\\";
@ -43,7 +41,8 @@ static const std::string native_separator = "/";
#endif
#define PSEUDO_ROOT ":"
void select_directory_popup(const char *prompt, float scaling, StringCallback callback)
void select_file_popup(const char *prompt, StringCallback callback,
bool selectFile, const std::string& selectExtension)
{
if (select_current_directory.empty())
{
@ -93,8 +92,8 @@ void select_directory_popup(const char *prompt, float scaling, StringCallback ca
if (!subfolders_read)
{
select_subfolders.clear();
display_files.clear();
subfolders.clear();
folderFiles.clear();
error_message.clear();
#ifdef _WIN32
if (select_current_directory == PSEUDO_ROOT)
@ -104,7 +103,7 @@ void select_directory_popup(const char *prompt, float scaling, StringCallback ca
u32 drives = GetLogicalDrives();
for (int i = 0; i < 32; i++)
if ((drives & (1 << i)) != 0)
select_subfolders.push_back(std::string(1, (char)('A' + i)) + ":\\");
subfolders.push_back(std::string(1, (char)('A' + i)) + ":\\");
}
else
#elif __ANDROID__
@ -117,12 +116,12 @@ void select_directory_popup(const char *prompt, float scaling, StringCallback ca
const char *pcolon = strchr(home, ':');
if (pcolon != NULL)
{
select_subfolders.push_back(std::string(home, pcolon - home));
subfolders.push_back(std::string(home, pcolon - home));
home = pcolon + 1;
}
else
{
select_subfolders.push_back(home);
subfolders.push_back(home);
home = NULL;
}
}
@ -134,7 +133,7 @@ void select_directory_popup(const char *prompt, float scaling, StringCallback ca
if (dir == NULL)
{
error_message = "Cannot read " + select_current_directory;
select_subfolders.emplace_back("..");
subfolders.emplace_back("..");
}
else
{
@ -169,36 +168,45 @@ void select_directory_popup(const char *prompt, float scaling, StringCallback ca
{
if (name == "..")
dotdot_seen = true;
select_subfolders.push_back(name);
subfolders.push_back(name);
}
else
{
std::string extension = get_file_extension(name);
if (extension == "zip" || extension == "7z" || extension == "chd" || extension == "gdi" || ((config::HideLegacyNaomiRoms
|| (extension != "bin" && extension != "lst" && extension != "dat"))
&& extension != "cdi" && extension != "cue") == false )
display_files.push_back(name);
if (selectFile)
{
if (extension == selectExtension)
folderFiles.push_back(name);
}
else if (extension == "zip" || extension == "7z" || extension == "chd"
|| extension == "gdi" || extension == "cdi" || extension == "cue"
|| (!config::HideLegacyNaomiRoms
&& (extension == "bin" || extension == "lst" || extension == "dat")))
folderFiles.push_back(name);
}
}
flycast::closedir(dir);
#if defined(_WIN32) || defined(__ANDROID__)
if (!dotdot_seen)
select_subfolders.emplace_back("..");
subfolders.emplace_back("..");
#else
(void)dotdot_seen;
#endif
}
}
std::stable_sort(select_subfolders.begin(), select_subfolders.end());
std::stable_sort(subfolders.begin(), subfolders.end());
std::stable_sort(folderFiles.begin(), folderFiles.end());
subfolders_read = true;
}
ImGui::Text("%s", error_message.empty() ? select_current_directory.c_str() : error_message.c_str());
ImGui::BeginChild(ImGui::GetID("dir_list"), ImVec2(0, - 30 * scaling - ImGui::GetStyle().ItemSpacing.y), true);
ImGui::BeginChild(ImGui::GetID("dir_list"), ImVec2(0, - 30 * gui_get_scaling() - ImGui::GetStyle().ItemSpacing.y), true);
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(8 * scaling, 20 * scaling)); // from 8, 4
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(8 * gui_get_scaling(), 20 * gui_get_scaling())); // from 8, 4
for (auto& name : select_subfolders)
for (const auto& name : subfolders)
{
std::string child_path;
if (name == "..")
@ -253,23 +261,38 @@ void select_directory_popup(const char *prompt, float scaling, StringCallback ca
select_current_directory = child_path;
}
}
ImGui::PushStyleColor(ImGuiCol_Text, { 1, 1, 1, 0.3f });
for (auto& name : display_files)
ImGui::PushStyleColor(ImGuiCol_Text, { 1, 1, 1, selectFile ? 1.f : 0.3f });
for (const auto& name : folderFiles)
{
ImGui::Text("%s", name.c_str());
if (selectFile)
{
if (ImGui::Selectable(name.c_str()))
{
subfolders_read = false;
callback(false, select_current_directory + native_separator + name);
ImGui::CloseCurrentPopup();
}
}
else
{
ImGui::Text("%s", name.c_str());
}
}
ImGui::PopStyleColor();
ImGui::PopStyleVar();
ImGui::EndChild();
if (ImGui::Button("Select Current Directory", ImVec2(0, 30 * scaling)))
if (!selectFile)
{
subfolders_read = false;
callback(false, select_current_directory);
ImGui::CloseCurrentPopup();
if (ImGui::Button("Select Current Directory", ImVec2(0, 30 * gui_get_scaling())))
{
subfolders_read = false;
callback(false, select_current_directory);
ImGui::CloseCurrentPopup();
}
ImGui::SameLine();
}
ImGui::SameLine();
if (ImGui::Button("Cancel", ImVec2(0, 30 * scaling)))
if (ImGui::Button("Cancel", ImVec2(0, 30 * gui_get_scaling())))
{
subfolders_read = false;
callback(true, "");

View File

@ -28,11 +28,14 @@
#include "vulkan/vulkan_context.h"
#include "gui.h"
extern int screen_width, screen_height;
typedef void (*StringCallback)(bool cancelled, std::string selection);
void select_directory_popup(const char *prompt, float scaling, StringCallback callback);
void select_file_popup(const char *prompt, StringCallback callback,
bool selectFile = false, const std::string& extension = "");
static inline void ImGui_impl_RenderDrawData(ImDrawData *draw_data, bool save_background = false)
static inline void ImGui_impl_RenderDrawData(ImDrawData *draw_data)
{
#ifdef USE_VULKAN
if (!config::RendererType.isOpenGL())
@ -61,7 +64,7 @@ static inline void ImGui_impl_RenderDrawData(ImDrawData *draw_data, bool save_ba
else
#endif
{
ImGui_ImplOpenGL3_RenderDrawData(draw_data, save_background);
ImGui_ImplOpenGL3_RenderDrawData(draw_data);
}
}
@ -79,3 +82,8 @@ template<typename T>
bool OptionRadioButton(const char *name, config::Option<T>& option, T value, const char *help = nullptr);
void OptionComboBox(const char *name, config::Option<int>& option, const char *values[], int count,
const char *help = nullptr);
static inline void centerNextWindow()
{
ImGui::SetNextWindowPos(ImVec2(screen_width / 2.f, screen_height / 2.f), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
}

View File

@ -126,6 +126,7 @@
84B7BF7F1B72720200F9733F /* stdclass.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84B7BEA71B72720200F9733F /* stdclass.cpp */; };
84B7BF831B727AD700F9733F /* osx-main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84B7BF821B727AD700F9733F /* osx-main.mm */; };
84B7BF861B72871600F9733F /* EmuGLView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B7BF851B72871600F9733F /* EmuGLView.swift */; };
AE039B40261C61C8005E24C5 /* gui_cheats.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE039B3F261C61C8005E24C5 /* gui_cheats.cpp */; };
AE1E293B2095FB1600FC6BA2 /* rec_cpp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE1E293A2095FB1600FC6BA2 /* rec_cpp.cpp */; };
AE1E294020A96B0B00FC6BA2 /* rec_x64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE1E293F20A96B0B00FC6BA2 /* rec_x64.cpp */; };
AE2A24DA22AE7EB600DD3034 /* ssa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE2A24D922AE7EB600DD3034 /* ssa.cpp */; };
@ -665,6 +666,7 @@
84B7BF821B727AD700F9733F /* osx-main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "osx-main.mm"; sourceTree = "<group>"; };
84B7BF841B72821900F9733F /* emulator-osx-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "emulator-osx-Bridging-Header.h"; sourceTree = "<group>"; };
84B7BF851B72871600F9733F /* EmuGLView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmuGLView.swift; sourceTree = "<group>"; };
AE039B3F261C61C8005E24C5 /* gui_cheats.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gui_cheats.cpp; sourceTree = "<group>"; };
AE1E293A2095FB1600FC6BA2 /* rec_cpp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rec_cpp.cpp; sourceTree = "<group>"; };
AE1E293F20A96B0B00FC6BA2 /* rec_x64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rec_x64.cpp; sourceTree = "<group>"; };
AE2A234922941A0500DD3034 /* NaomiConfig.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = NaomiConfig.xcconfig; sourceTree = "<group>"; };
@ -1993,6 +1995,7 @@
84B7BE9B1B72720200F9733F /* gles */,
AED73EAB2348E49800ECDB64 /* CustomTexture.cpp */,
AED73EAC2348E49900ECDB64 /* CustomTexture.h */,
AE039B3F261C61C8005E24C5 /* gui_cheats.cpp */,
AEE6279222247C0A00EC7E89 /* gui_util.cpp */,
AEE6279322247C0A00EC7E89 /* gui_util.h */,
AEE6276A220D7B5500EC7E89 /* gui.cpp */,
@ -2936,6 +2939,7 @@
559E934125FCBFCA001B0F40 /* decoder-aarch64.cc in Sources */,
AE7BCB592415515B007285F8 /* arm7_rec.cpp in Sources */,
AE649C3C218C555600EF4A81 /* cdrom.c in Sources */,
AE039B40261C61C8005E24C5 /* gui_cheats.cpp in Sources */,
AE649BF3218C552500EF4A81 /* bitmath.c in Sources */,
AE649C30218C553A00EF4A81 /* Sort.c in Sources */,
AE82C6B325B64AE200C79BC2 /* zip_source_file_stdio.c in Sources */,