diff --git a/src/base.h b/src/base.h index d36372a9..1b1bb63c 100644 --- a/src/base.h +++ b/src/base.h @@ -1,4 +1,4 @@ -#define BSNES_VERSION "0.015 rc2" //wip45 +#define BSNES_VERSION "0.015 rc3" //wip47 #define BSNES_TITLE "bsnes v" BSNES_VERSION #define MEMCORE bMemBus @@ -19,8 +19,8 @@ //enable JMA support //#define JMA_SUPPORT -//snes core polymorphism (allow mem/cpu/apu/ppu overriding, -//~10% speed hit) +//snes core polymorphism +//(allow mem/cpu/apu/ppu overriding, ~10% speed hit) //#define POLYMORPHISM //this should be declared in the port-specific makefiles diff --git a/src/cheat/cheat.cpp b/src/cheat/cheat.cpp index e5ff58ed..9d5fde47 100644 --- a/src/cheat/cheat.cpp +++ b/src/cheat/cheat.cpp @@ -1,11 +1,18 @@ #include "../base.h" +/***** + * string <> binary code translation routines + * decode() "7e1234:56" -> 0x7e123456 + * encode() 0x7e123456 -> "7e1234:56" + *****/ + bool Cheat::decode(char *str, uint32 &addr, uint8 &data, uint8 &type) { string t, part; strcpy(t, str); strlower(t); - if(strlen(t) == 8) { + if(strlen(t) == 8 || (strlen(t) == 9 && strptr(t)[6] == ':')) { type = CT_PRO_ACTION_REPLAY; + replace(t, ":", ""); uint32 r = strhex(t); addr = r >> 8; data = r & 0xff; @@ -38,7 +45,7 @@ string t, part; bool Cheat::encode(char *str, uint32 addr, uint8 data, uint8 type) { if(type == CT_PRO_ACTION_REPLAY) { - sprintf(str, "%0.6x%0.2x", addr, data); + sprintf(str, "%0.6x:%0.2x", addr, data); return true; } else if(type == CT_GAME_GENIE) { uint32 r = addr; @@ -61,8 +68,83 @@ bool Cheat::encode(char *str, uint32 addr, uint8 data, uint8 type) { return false; } -//enable cheat system when at least one cheat is enabled, -//disable otherwise to speed up emulation +/***** + * address lookup table manipulation and mirroring + * mirror_address() 0x000000 -> 0x7e0000 + * set() enable specified address, mirror accordingly + * clear() disable specified address, mirror accordingly + *****/ + +uint Cheat::mirror_address(uint addr) { + if((addr & 0x40e000) != 0x0000)return addr; +//8k WRAM mirror +//$[00-3f|80-bf]:[0000-1fff] -> $7e:[0000-1fff] + return (0x7e0000 + (addr & 0x1fff)); +} + +void Cheat::set(uint32 addr) { + addr = mirror_address(addr); + + mask[addr >> 3] |= 1 << (addr & 7); + if((addr & 0xffe000) == 0x7e0000) { + //mirror $7e:[0000-1fff] to $[00-3f|80-bf]:[0000-1fff] + uint mirror; + for(int x = 0; x <= 0x3f; x++) { + mirror = ((0x00 + x) << 16) + (addr & 0x1fff); + mask[mirror >> 3] |= 1 << (mirror & 7); + mirror = ((0x80 + x) << 16) + (addr & 0x1fff); + mask[mirror >> 3] |= 1 << (mirror & 7); + } + } +} + +void Cheat::clear(uint32 addr) { + addr = mirror_address(addr); + +//is there more than one cheat code using the same address +//(and likely a different override value) that is enabled? +//if so, do not clear code lookup table entry for this address. +uint8 r; + if(read(addr, r) == true)return; + + mask[addr >> 3] &= ~(1 << (addr & 7)); + if((addr & 0xffe000) == 0x7e0000) { + //mirror $7e:[0000-1fff] to $[00-3f|80-bf]:[0000-1fff] + uint mirror; + for(int x = 0; x <= 0x3f; x++) { + mirror = ((0x00 + x) << 16) + (addr & 0x1fff); + mask[mirror >> 3] &= ~(1 << (mirror & 7)); + mirror = ((0x80 + x) << 16) + (addr & 0x1fff); + mask[mirror >> 3] &= ~(1 << (mirror & 7)); + } + } +} + +/***** + * read() is used by MemBus::read() if Cheat::enabled(addr) + * returns true to look up cheat code. + * returns true if cheat code was found, false if it was not. + * when true, cheat code substitution value is stored in data. + *****/ + +bool Cheat::read(uint32 addr, uint8 &data) { + addr = mirror_address(addr); + for(int i = 0; i < cheat_count; i++) { + if(enabled(i) == false)continue; + if(addr == mirror_address(index[i].addr)) { + data = index[i].data; + return true; + } + } +//code not found, or code is disabled + return false; +} + +/***** + * update_cheat_status() will scan to see if any codes are + * enabled. if any are, make sure the cheat system is on. + * otherwise, turn cheat system off to speed up emulation. + *****/ void Cheat::update_cheat_status() { for(int i = 0; i < cheat_count; i++) { if(index[i].enabled) { @@ -73,18 +155,9 @@ void Cheat::update_cheat_status() { cheat_enabled = false; } -uint8 Cheat::read(uint32 addr) { - addr &= 0xffffff; - for(int i = 0; i < cheat_count; i++) { - if(index[i].addr == addr) { - return index[i].data; - } - } - -//cheat not found? disable and return 0 - clear(addr); - return 0x00; -} +/***** + * cheat list manipulation routines + *****/ bool Cheat::add(bool enable, char *code, char *desc) { if(cheat_count >= CHEAT_LIMIT)return false; @@ -93,7 +166,6 @@ uint32 addr, len; uint8 data, type; if(decode(code, addr, data, type) == false)return false; - (enable) ? set(addr) : clear(addr); index[cheat_count].enabled = enable; index[cheat_count].addr = addr; index[cheat_count].data = data; @@ -106,6 +178,7 @@ uint8 data, type; memcpy(index[cheat_count].desc, desc, len); index[cheat_count].desc[len] = 0; cheat_count++; + (enable) ? set(addr) : clear(addr); update_cheat_status(); return true; @@ -118,8 +191,11 @@ uint32 addr, len; uint8 data, type; if(decode(code, addr, data, type) == false)return false; +//disable current code and clear from code lookup table + index[n].enabled = false; clear(index[n].addr); - set(addr); + +//update code and enable in code lookup table index[n].enabled = enable; index[n].addr = addr; index[n].data = data; @@ -131,6 +207,7 @@ uint8 data, type; len = len > 128 ? 128 : len; memcpy(index[n].desc, desc, len); index[n].desc[len] = 0; + set(addr); update_cheat_status(); return true; @@ -162,6 +239,10 @@ bool Cheat::get(uint32 n, bool &enable, uint32 &addr, uint8 &data, char *code, c return true; } +/***** + * code status modifier routines + *****/ + bool Cheat::enabled(uint32 n) { if(n >= cheat_count)return false; return index[n].enabled; @@ -169,18 +250,22 @@ bool Cheat::enabled(uint32 n) { void Cheat::enable(uint32 n) { if(n >= cheat_count)return; - set(index[n].addr); index[n].enabled = true; + set(index[n].addr); update_cheat_status(); } void Cheat::disable(uint32 n) { if(n >= cheat_count)return; - clear(index[n].addr); index[n].enabled = false; + clear(index[n].addr); update_cheat_status(); } +/***** + * cheat file manipulation routines + *****/ + bool Cheat::load(Reader *rf) { if(!rf->ready())return false; @@ -227,6 +312,10 @@ char t[4096]; return true; } +/***** + * initialization routines + *****/ + void Cheat::clear() { cheat_enabled = false; cheat_count = 0; diff --git a/src/cheat/cheat.h b/src/cheat/cheat.h index ad69b5cf..e8567f1c 100644 --- a/src/cheat/cheat.h +++ b/src/cheat/cheat.h @@ -17,15 +17,20 @@ uint8 mask[0x200000]; inline bool enabled() { return cheat_enabled; } inline uint count() { return cheat_count; } - inline bool exists(uint32 addr) { return !!(mask[addr >> 3] & 1 << (addr & 7)); } - inline void set(uint32 addr) { mask[addr >> 3] |= 1 << (addr & 7); } - inline void clear(uint32 addr) { mask[addr >> 3] &= ~(1 << (addr & 7)); } + inline bool exists(uint32 addr) { return bool(mask[addr >> 3] & 1 << (addr & 7)); } bool decode(char *str, uint32 &addr, uint8 &data, uint8 &type); bool encode(char *str, uint32 addr, uint8 data, uint8 type); +private: + uint mirror_address(uint addr); + void set(uint32 addr); + void clear(uint32 addr); +public: + + bool read(uint32 addr, uint8 &data); + void update_cheat_status(); - uint8 read(uint32 addr); bool add(bool enable, char *code, char *desc); bool edit(uint32 n, bool enable, char *code, char *desc); bool get(uint32 n, bool &enable, uint32 &addr, uint8 &data, char *code, char *desc); diff --git a/src/cpu/bcpu/bcpu_mmio.cpp b/src/cpu/bcpu/bcpu_mmio.cpp index 88d14cfd..efc76b3f 100644 --- a/src/cpu/bcpu/bcpu_mmio.cpp +++ b/src/cpu/bcpu/bcpu_mmio.cpp @@ -411,7 +411,7 @@ void bCPU::mmio_w2183(uint8 value) { //strobing $4016.d0 affects both controller port latches. //$4017 bit 0 writes are ignored. void bCPU::mmio_w4016(uint8 value) { - status.joypad_strobe_latch = !!(value & 1); + status.joypad_strobe_latch = bool(value & 1); if(status.joypad_strobe_latch == 1) { snes->poll_input(SNES::DEV_JOYPAD1); @@ -423,10 +423,10 @@ void bCPU::mmio_w4016(uint8 value) { //NMITIMEN void bCPU::mmio_w4200(uint8 value) { - status.nmi_enabled = !!(value & 0x80); - status.virq_enabled = !!(value & 0x20); - status.hirq_enabled = !!(value & 0x10); - status.auto_joypad_poll = !!(value & 0x01); + status.nmi_enabled = bool(value & 0x80); + status.virq_enabled = bool(value & 0x20); + status.hirq_enabled = bool(value & 0x10); + status.auto_joypad_poll = bool(value & 0x01); if(time.nmi_read == 0) { if(time.nmi_line == 1 && !status.nmi_enabled == 0) { @@ -522,9 +522,9 @@ int len; //HDMAEN void bCPU::mmio_w420c(uint8 value) { - for(int i=0;i<8;i++) { - channel[i].hdma_enabled = !!(value & (1 << i)); - channel[i].hdma_active = !!(value & (1 << i)); + for(int i = 0; i < 8; i++) { + channel[i].hdma_enabled = bool(value & (1 << i)); + channel[i].hdma_active = bool(value & (1 << i)); } } @@ -536,10 +536,10 @@ void bCPU::mmio_w420d(uint8 value) { //DMAPx void bCPU::mmio_w43x0(uint8 value, uint8 i) { channel[i].dmap = value; - channel[i].direction = !!(value & 0x80); - channel[i].hdma_indirect = !!(value & 0x40); - channel[i].incmode = (value & 0x10)?-1:1; - channel[i].fixedxfer = !!(value & 0x08); + channel[i].direction = bool(value & 0x80); + channel[i].hdma_indirect = bool(value & 0x40); + channel[i].incmode = (value & 0x10) ? -1 : 1; + channel[i].fixedxfer = bool(value & 0x08); channel[i].xfermode = value & 7; } diff --git a/src/cpu/bcpu/dma/dma.cpp b/src/cpu/bcpu/dma/dma.cpp index 1912d416..4718e2bd 100644 --- a/src/cpu/bcpu/dma/dma.cpp +++ b/src/cpu/bcpu/dma/dma.cpp @@ -183,7 +183,7 @@ static uint8 hdma_xferlen[8] = { 1, 2, 2, 4, 4, 4, 2, 4 }; } channel[i].hdma_line_counter--; - channel[i].hdma_do_transfer = !!(channel[i].hdma_line_counter & 0x80); + channel[i].hdma_do_transfer = bool(channel[i].hdma_line_counter & 0x80); if((channel[i].hdma_line_counter & 0x7f) == 0) { hdma_update(i); } diff --git a/src/data/snes_controller.bmp b/src/data/snes_controller.bmp new file mode 100644 index 00000000..ae1e2bb1 Binary files /dev/null and b/src/data/snes_controller.bmp differ diff --git a/src/lib/libbase.h b/src/lib/libbase.h index 49350785..a829a38d 100644 --- a/src/lib/libbase.h +++ b/src/lib/libbase.h @@ -1,5 +1,5 @@ /* - libbase : version 0.06 ~byuu (02/18/06) + libbase : version 0.07 ~byuu (04/21/06) */ #ifndef __LIBBASE @@ -12,14 +12,14 @@ #include #include -#ifndef TRUE -#define TRUE 1 -#endif - #ifndef FALSE #define FALSE 0 #endif +#ifndef TRUE +#define TRUE 1 +#endif + #define SafeFree(__n) if(__n) { free(__n); __n = 0; } #define SafeDelete(__n) if(__n) { delete(__n); __n = 0; } #define SafeRelease(__n) if(__n) { __n->Release(); __n = 0; } @@ -42,6 +42,16 @@ typedef signed short int16; typedef signed long int32; typedef signed long long int64; +template void swap(T &x, T &y) { +T z = x; + x = y; + y = z; +} + +template T bound_range(T &x, Targ min, Targ max) { + return (x < T(min)) ? T(min) : (x > T(max)) ? T(max) : x; +} + inline bool fexists(const char *fn) { FILE *fp = fopen(fn, "rb"); if(!fp)return false; diff --git a/src/lib/libwin32_window.cpp b/src/lib/libwin32_window.cpp index 17c73464..e2004459 100644 --- a/src/lib/libwin32_window.cpp +++ b/src/lib/libwin32_window.cpp @@ -313,6 +313,7 @@ void Window::SetIcon(uint resource_id) { void Window::Show(bool do_show) { if(do_show == true) { + if(Visible() == false)Resize(); ShowWindow(hwnd, SW_NORMAL); state.ws |= WS_VISIBLE; } else { diff --git a/src/memory/bmemory/bmemory.cpp b/src/memory/bmemory/bmemory.cpp index 455009ed..26554b35 100644 --- a/src/memory/bmemory/bmemory.cpp +++ b/src/memory/bmemory/bmemory.cpp @@ -106,7 +106,7 @@ uint8 r; #ifdef CHEAT_SYSTEM if(cheat.enabled()) { if(cheat.exists(addr)) { - return cheat.read(addr); + if(cheat.read(addr, r) == true)return r; } } #endif diff --git a/src/ppu/bppu/bppu_mmio.cpp b/src/ppu/bppu/bppu_mmio.cpp index 63004adc..cdb1e411 100644 --- a/src/ppu/bppu/bppu_mmio.cpp +++ b/src/ppu/bppu/bppu_mmio.cpp @@ -67,7 +67,7 @@ uint16 hc = r_cpu->hcycles(); //INIDISP void bPPU::mmio_w2100(uint8 value) { - regs.display_disabled = !!(value & 0x80); + regs.display_disabled = bool(value & 0x80); regs.display_brightness = value & 15; } @@ -86,7 +86,7 @@ void bPPU::mmio_w2102(uint8 value) { //OAMADDH void bPPU::mmio_w2103(uint8 value) { - regs.oam_priority = !!(value & 0x80); + regs.oam_priority = bool(value & 0x80); regs.oam_baseaddr = ((value & 1) << 8) | (regs.oam_baseaddr & 0xff); regs.oam_addr = regs.oam_baseaddr << 1; } @@ -110,11 +110,11 @@ void bPPU::mmio_w2104(uint8 value) { //BGMODE void bPPU::mmio_w2105(uint8 value) { - regs.bg_tilesize[BG4] = !!(value & 0x80); - regs.bg_tilesize[BG3] = !!(value & 0x40); - regs.bg_tilesize[BG2] = !!(value & 0x20); - regs.bg_tilesize[BG1] = !!(value & 0x10); - regs.bg3_priority = !!(value & 0x08); + regs.bg_tilesize[BG4] = bool(value & 0x80); + regs.bg_tilesize[BG3] = bool(value & 0x40); + regs.bg_tilesize[BG2] = bool(value & 0x20); + regs.bg_tilesize[BG1] = bool(value & 0x10); + regs.bg3_priority = bool(value & 0x08); regs.bg_mode = (value & 7); regs.hires = (regs.bg_mode == 5 || regs.bg_mode == 6); } @@ -122,10 +122,10 @@ void bPPU::mmio_w2105(uint8 value) { //MOSAIC void bPPU::mmio_w2106(uint8 value) { regs.mosaic_size = (value >> 4) & 15; - regs.mosaic_enabled[BG4] = !!(value & 0x08); - regs.mosaic_enabled[BG3] = !!(value & 0x04); - regs.mosaic_enabled[BG2] = !!(value & 0x02); - regs.mosaic_enabled[BG1] = !!(value & 0x01); + regs.mosaic_enabled[BG4] = bool(value & 0x08); + regs.mosaic_enabled[BG3] = bool(value & 0x04); + regs.mosaic_enabled[BG2] = bool(value & 0x02); + regs.mosaic_enabled[BG1] = bool(value & 0x01); } //BG1SC @@ -220,7 +220,7 @@ void bPPU::mmio_w2114(uint8 value) { //VMAIN void bPPU::mmio_w2115(uint8 value) { - regs.vram_incmode = !!(value & 0x80); + regs.vram_incmode = bool(value & 0x80); regs.vram_mapping = (value >> 2) & 3; switch(value & 3) { case 0:regs.vram_incsize = 1;break; @@ -287,8 +287,8 @@ uint16 addr = get_vram_address() + 1; //M7SEL void bPPU::mmio_w211a(uint8 value) { regs.mode7_repeat = (value >> 6) & 3; - regs.mode7_vflip = !!(value & 0x02); - regs.mode7_hflip = !!(value & 0x01); + regs.mode7_vflip = bool(value & 0x02); + regs.mode7_hflip = bool(value & 0x01); } //M7A @@ -347,38 +347,38 @@ void bPPU::mmio_w2122(uint8 value) { //W12SEL void bPPU::mmio_w2123(uint8 value) { - regs.window2_enabled[BG2] = !!(value & 0x80); - regs.window2_invert [BG2] = !!(value & 0x40); - regs.window1_enabled[BG2] = !!(value & 0x20); - regs.window1_invert [BG2] = !!(value & 0x10); - regs.window2_enabled[BG1] = !!(value & 0x08); - regs.window2_invert [BG1] = !!(value & 0x04); - regs.window1_enabled[BG1] = !!(value & 0x02); - regs.window1_invert [BG1] = !!(value & 0x01); + regs.window2_enabled[BG2] = bool(value & 0x80); + regs.window2_invert [BG2] = bool(value & 0x40); + regs.window1_enabled[BG2] = bool(value & 0x20); + regs.window1_invert [BG2] = bool(value & 0x10); + regs.window2_enabled[BG1] = bool(value & 0x08); + regs.window2_invert [BG1] = bool(value & 0x04); + regs.window1_enabled[BG1] = bool(value & 0x02); + regs.window1_invert [BG1] = bool(value & 0x01); } //W34SEL void bPPU::mmio_w2124(uint8 value) { - regs.window2_enabled[BG4] = !!(value & 0x80); - regs.window2_invert [BG4] = !!(value & 0x40); - regs.window1_enabled[BG4] = !!(value & 0x20); - regs.window1_invert [BG4] = !!(value & 0x10); - regs.window2_enabled[BG3] = !!(value & 0x08); - regs.window2_invert [BG3] = !!(value & 0x04); - regs.window1_enabled[BG3] = !!(value & 0x02); - regs.window1_invert [BG3] = !!(value & 0x01); + regs.window2_enabled[BG4] = bool(value & 0x80); + regs.window2_invert [BG4] = bool(value & 0x40); + regs.window1_enabled[BG4] = bool(value & 0x20); + regs.window1_invert [BG4] = bool(value & 0x10); + regs.window2_enabled[BG3] = bool(value & 0x08); + regs.window2_invert [BG3] = bool(value & 0x04); + regs.window1_enabled[BG3] = bool(value & 0x02); + regs.window1_invert [BG3] = bool(value & 0x01); } //WOBJSEL void bPPU::mmio_w2125(uint8 value) { - regs.window2_enabled[COL] = !!(value & 0x80); - regs.window2_invert [COL] = !!(value & 0x40); - regs.window1_enabled[COL] = !!(value & 0x20); - regs.window1_invert [COL] = !!(value & 0x10); - regs.window2_enabled[OAM] = !!(value & 0x08); - regs.window2_invert [OAM] = !!(value & 0x04); - regs.window1_enabled[OAM] = !!(value & 0x02); - regs.window1_invert [OAM] = !!(value & 0x01); + regs.window2_enabled[COL] = bool(value & 0x80); + regs.window2_invert [COL] = bool(value & 0x40); + regs.window1_enabled[COL] = bool(value & 0x20); + regs.window1_invert [COL] = bool(value & 0x10); + regs.window2_enabled[OAM] = bool(value & 0x08); + regs.window2_invert [OAM] = bool(value & 0x04); + regs.window1_enabled[OAM] = bool(value & 0x02); + regs.window1_invert [OAM] = bool(value & 0x01); } //WH0 @@ -417,58 +417,58 @@ void bPPU::mmio_w212b(uint8 value) { //TM void bPPU::mmio_w212c(uint8 value) { - regs.bg_enabled[OAM] = !!(value & 0x10); - regs.bg_enabled[BG4] = !!(value & 0x08); - regs.bg_enabled[BG3] = !!(value & 0x04); - regs.bg_enabled[BG2] = !!(value & 0x02); - regs.bg_enabled[BG1] = !!(value & 0x01); + regs.bg_enabled[OAM] = bool(value & 0x10); + regs.bg_enabled[BG4] = bool(value & 0x08); + regs.bg_enabled[BG3] = bool(value & 0x04); + regs.bg_enabled[BG2] = bool(value & 0x02); + regs.bg_enabled[BG1] = bool(value & 0x01); } //TS void bPPU::mmio_w212d(uint8 value) { - regs.bgsub_enabled[OAM] = !!(value & 0x10); - regs.bgsub_enabled[BG4] = !!(value & 0x08); - regs.bgsub_enabled[BG3] = !!(value & 0x04); - regs.bgsub_enabled[BG2] = !!(value & 0x02); - regs.bgsub_enabled[BG1] = !!(value & 0x01); + regs.bgsub_enabled[OAM] = bool(value & 0x10); + regs.bgsub_enabled[BG4] = bool(value & 0x08); + regs.bgsub_enabled[BG3] = bool(value & 0x04); + regs.bgsub_enabled[BG2] = bool(value & 0x02); + regs.bgsub_enabled[BG1] = bool(value & 0x01); } //TMW void bPPU::mmio_w212e(uint8 value) { - regs.window_enabled[OAM] = !!(value & 0x10); - regs.window_enabled[BG4] = !!(value & 0x08); - regs.window_enabled[BG3] = !!(value & 0x04); - regs.window_enabled[BG2] = !!(value & 0x02); - regs.window_enabled[BG1] = !!(value & 0x01); + regs.window_enabled[OAM] = bool(value & 0x10); + regs.window_enabled[BG4] = bool(value & 0x08); + regs.window_enabled[BG3] = bool(value & 0x04); + regs.window_enabled[BG2] = bool(value & 0x02); + regs.window_enabled[BG1] = bool(value & 0x01); } //TSW void bPPU::mmio_w212f(uint8 value) { - regs.sub_window_enabled[OAM] = !!(value & 0x10); - regs.sub_window_enabled[BG4] = !!(value & 0x08); - regs.sub_window_enabled[BG3] = !!(value & 0x04); - regs.sub_window_enabled[BG2] = !!(value & 0x02); - regs.sub_window_enabled[BG1] = !!(value & 0x01); + regs.sub_window_enabled[OAM] = bool(value & 0x10); + regs.sub_window_enabled[BG4] = bool(value & 0x08); + regs.sub_window_enabled[BG3] = bool(value & 0x04); + regs.sub_window_enabled[BG2] = bool(value & 0x02); + regs.sub_window_enabled[BG1] = bool(value & 0x01); } //CGWSEL void bPPU::mmio_w2130(uint8 value) { regs.color_mask = (value >> 6) & 3; regs.colorsub_mask = (value >> 4) & 3; - regs.addsub_mode = !!(value & 0x02); - regs.direct_color = !!(value & 0x01); + regs.addsub_mode = bool(value & 0x02); + regs.direct_color = bool(value & 0x01); } //CGADDSUB void bPPU::mmio_w2131(uint8 value) { - regs.color_mode = !!(value & 0x80); - regs.color_halve = !!(value & 0x40); - regs.color_enabled[BACK] = !!(value & 0x20); - regs.color_enabled[OAM] = !!(value & 0x10); - regs.color_enabled[BG4] = !!(value & 0x08); - regs.color_enabled[BG3] = !!(value & 0x04); - regs.color_enabled[BG2] = !!(value & 0x02); - regs.color_enabled[BG1] = !!(value & 0x01); + regs.color_mode = bool(value & 0x80); + regs.color_halve = bool(value & 0x40); + regs.color_enabled[BACK] = bool(value & 0x20); + regs.color_enabled[OAM] = bool(value & 0x10); + regs.color_enabled[BG4] = bool(value & 0x08); + regs.color_enabled[BG3] = bool(value & 0x04); + regs.color_enabled[BG2] = bool(value & 0x02); + regs.color_enabled[BG1] = bool(value & 0x01); } //COLDATA @@ -482,11 +482,11 @@ void bPPU::mmio_w2132(uint8 value) { //SETINI void bPPU::mmio_w2133(uint8 value) { - regs.mode7_extbg = !!(value & 0x40); - regs.pseudo_hires = !!(value & 0x08); - regs.overscan = !!(value & 0x04); - regs.oam_interlace = !!(value & 0x02); - regs.interlace = !!(value & 0x01); + regs.mode7_extbg = bool(value & 0x40); + regs.pseudo_hires = bool(value & 0x08); + regs.overscan = bool(value & 0x04); + regs.oam_interlace = bool(value & 0x02); + regs.interlace = bool(value & 0x01); r_cpu->set_overscan(regs.overscan); } diff --git a/src/ppu/bppu/bppu_render_bg.cpp b/src/ppu/bppu/bppu_render_bg.cpp index c93ad66b..f9f99014 100644 --- a/src/ppu/bppu/bppu_render_bg.cpp +++ b/src/ppu/bppu/bppu_render_bg.cpp @@ -147,18 +147,18 @@ int32 prev_x = -1, prev_y = -1; t = bg_get_tile(bg, mosaic_x, mosaic_y); - mirror_y = !!(t & 0x8000); - mirror_x = !!(t & 0x4000); + mirror_y = bool(t & 0x8000); + mirror_x = bool(t & 0x4000); tile_pri = (t & 0x2000) ? pri1_pos : pri0_pos; tile_num = t; if(tile_width == 4) { //16x16 horizontal tile mirroring - if(!!(mosaic_x & 8) != mirror_x)tile_num++; + if(bool(mosaic_x & 8) != mirror_x)tile_num++; } if(tile_height == 4) { //16x16 vertical tile mirroring - if(!!(mosaic_y & 8) != mirror_y)tile_num += 16; + if(bool(mosaic_y & 8) != mirror_y)tile_num += 16; } tile_num &= 0x03ff; diff --git a/src/ppu/bppu/bppu_render_oam.cpp b/src/ppu/bppu/bppu_render_oam.cpp index d0a8e13a..9bb31884 100644 --- a/src/ppu/bppu/bppu_render_oam.cpp +++ b/src/ppu/bppu/bppu_render_oam.cpp @@ -2,8 +2,8 @@ void bPPU::build_sprite_list() { uint8 *tableA = oam, *tableB = oam + 512; for(int i = 0; i < 128; i++) { - uint x = !!(*tableB & (1 << ((i & 3) << 1))); //0x01, 0x04, 0x10, 0x40 - bool size = !!(*tableB & (2 << ((i & 3) << 1))); //0x02, 0x08, 0x20, 0x80 + uint x = bool(*tableB & (1 << ((i & 3) << 1))); //0x01, 0x04, 0x10, 0x40 + bool size = bool(*tableB & (2 << ((i & 3) << 1))); //0x02, 0x08, 0x20, 0x80 switch(regs.oam_basesize) { case 0: sprite_list[i].width = (!size) ? 8 : 16; @@ -35,8 +35,8 @@ uint8 *tableA = oam, *tableB = oam + 512; sprite_list[i].x = (x << 8) + tableA[0]; sprite_list[i].y = tableA[1] + 1; sprite_list[i].character = tableA[2]; - sprite_list[i].vflip = !!(tableA[3] & 0x80); - sprite_list[i].hflip = !!(tableA[3] & 0x40); + sprite_list[i].vflip = bool(tableA[3] & 0x80); + sprite_list[i].hflip = bool(tableA[3] & 0x40); sprite_list[i].priority = (tableA[3] >> 4) & 3; sprite_list[i].palette = (tableA[3] >> 1) & 7; sprite_list[i].use_nameselect = tableA[3] & 1; diff --git a/src/ppu/bppu/bppu_render_windows.cpp b/src/ppu/bppu/bppu_render_windows.cpp index 11994baf..7bea657f 100644 --- a/src/ppu/bppu/bppu_render_windows.cpp +++ b/src/ppu/bppu/bppu_render_windows.cpp @@ -39,9 +39,7 @@ uint16 window2_right = regs.window2_right; } if(regs.window1_enabled[bg] == true && regs.window2_enabled[bg] == false) { - if(regs.window1_invert[bg] == true) { - set ^= clr; clr ^= set; set ^= clr; - } + if(regs.window1_invert[bg] == true)swap(set, clr); for(int x = 0; x < 256; x++) { wtbl[x] = (x >= window1_left && x <= window1_right) ? set : clr; } @@ -49,9 +47,7 @@ uint16 window2_right = regs.window2_right; } if(regs.window1_enabled[bg] == false && regs.window2_enabled[bg] == true) { - if(regs.window2_invert[bg] == true) { - set ^= clr; clr ^= set; set ^= clr; - } + if(regs.window2_invert[bg] == true)swap(set, clr); for(int x = 0; x < 256; x++) { wtbl[x] = (x >= window2_left && x <= window2_right) ? set : clr; } diff --git a/src/snes/video/video_colortable.cpp b/src/snes/video/video_colortable.cpp index 2206754f..b330a050 100644 --- a/src/snes/video/video_colortable.cpp +++ b/src/snes/video/video_colortable.cpp @@ -10,19 +10,19 @@ double lmin, lmax; lmin = 0.0 - double(int32(config::snes.contrast)); lmax = 255.0 + double(int32(config::snes.contrast)); int32 result = int32(lmin + double(input) * ((lmax - lmin) / 256.0)); - input = (result > 255) ? 255 : (result < 0) ? 0 : result; + input = bound_range(result, 0, 255); } void SNES::brightness_adjust(int32 &input) { int32 result; result = input + int32(config::snes.brightness); - input = (result > 255) ? 255 : (result < 0) ? 0 : result; + input = bound_range(result, 0, 255); } void SNES::gamma_adjust(int32 &input) { int32 result; result = int32(pow((double(input + 1) / 256.0), double(config::snes.gamma) / 100.0) * 256.0); - input = (result > 255) ? 255 : (result < 0) ? 0 : result; + input = bound_range(result, 0, 255); } void SNES::update_color_lookup_table() { @@ -55,14 +55,14 @@ uint32 col; r = int32(double(l) * (1.0 + 0.300)); g = int32(double(l) * (1.0 - 0.055)); b = int32(double(l) * (1.0 - 0.225)); - r = (r > 255) ? 255 : (r < 0) ? 0 : r; - g = (g > 255) ? 255 : (g < 0) ? 0 : g; - b = (b > 255) ? 255 : (b < 0) ? 0 : b; + r = bound_range(r, 0, 255); + g = bound_range(g, 0, 255); + b = bound_range(b, 0, 255); } if(bool(config::snes.grayscale) == true) { l = int32(double(r) * kr + double(g) * kg + double(b) * kb); - l = (l > 255) ? 255 : (l < 0) ? 0 : l; + l = bound_range(l, 0, 255); r = g = b = l; } diff --git a/src/win/Makefile b/src/win/Makefile index 93921b8b..653d3e0e 100644 --- a/src/win/Makefile +++ b/src/win/Makefile @@ -1,5 +1,6 @@ CC = cl CFLAGS = /nologo /O2 /arch:SSE2 /wd4996 +#CFLAGS = /nologo /O2 /GL /EHsc /wd4996 OBJS = main.obj \ libstring.obj libconfig.obj libbpf.obj \ reader.obj cart.obj cheat.obj \ @@ -19,7 +20,8 @@ LIBS = kernel32.lib user32.lib gdi32.lib comdlg32.lib comctl32.lib \ all: $(OBJS) rc /r /fobsnes.res bsnes.rc $(CC) /Febsnes.exe $(CFLAGS) $(OBJS) bsnes.res $(LIBS) -#/link /PGD:bsnes.pgd /LTCG:PGINSTRUMENT +# $(CC) /Febsnes.exe $(CFLAGS) $(OBJS) bsnes.res $(LIBS) /link /PGD:bsnes.pgd /LTCG:PGINSTRUMENT +# $(CC) /Febsnes.exe $(CFLAGS) $(OBJS) bsnes.res $(LIBS) /link /PGD:bsnes.pgd /LTCG:PGOPTIMIZE clean: del *.obj diff --git a/src/win/bsnes.rc b/src/win/bsnes.rc index a33fc3aa..86b7ad0e 100644 --- a/src/win/bsnes.rc +++ b/src/win/bsnes.rc @@ -1,5 +1,7 @@ -#define IDI_APP_ICON 100 -#define IDB_ABOUT_ART 101 +#define IDI_APP_ICON 100 +#define IDB_ABOUT_ART 101 +#define IDB_CONTROLLER_ART 102 -IDI_APP_ICON ICON DISCARDABLE "../data/bsnes.ico" -IDB_ABOUT_ART BITMAP DISCARDABLE "../data/about.bmp" +IDI_APP_ICON ICON DISCARDABLE "../data/bsnes.ico" +IDB_ABOUT_ART BITMAP DISCARDABLE "../data/about.bmp" +IDB_CONTROLLER_ART BITMAP DISCARDABLE "../data/snes_controller.bmp" diff --git a/src/win/config.cpp b/src/win/config.cpp index f6e48240..dda4a5e9 100644 --- a/src/win/config.cpp +++ b/src/win/config.cpp @@ -28,11 +28,11 @@ struct Video { Setting Video::renderer(&config_file, "video.renderer", "Video renderer\n" "\"dd\" (DirectDraw7 -- faster, less features)\n" "\"d3d\" (Direct3D9 -- slower, more features)", "d3d"); -Setting Video::profile(&config_file, "video.profile", "Video profile to load at startup", 2, Setting::DEC); +Setting Video::profile(0, "video.profile", "", 2, Setting::DEC); Setting Video::profile_windowed_default(&config_file, "video.profile_windowed_default", - "Windowed profile to select for Alt+Enter", 0, Setting::DEC); + "Windowed profile to select for Alt+Enter", 2, Setting::DEC); Setting Video::profile_fullscreen_default(&config_file, "video.profile_fullscreen_default", - "Fullscreen profile to select for Alt+Enter", 5, Setting::DEC); + "Fullscreen profile to select for Alt+Enter", 9, Setting::DEC); /* software_filter * hardware_filter @@ -51,19 +51,20 @@ Setting Video::profile_fullscreen_default(&config_file, "video.profile_fullscree */ Setting Video::profile_0(&config_file, "video.profile_0", "Video profile 0 configuration\n" "Please use bsnes GUI configuration editor to modify video profile settings\n" - "Format: software_filter;hardware_filter;video_standard;multiplier;correct_aspect_ratio;\n" + "Format: software_filter;hardware_filter;video_standard;multiplier-1;correct_aspect_ratio;\n" " enable_scanlines;manual_render_size;render_width;render_height;fullscreen;\n" " resolution_width;resolution_height;refresh_rate;triple_buffering" - "", "0;0;0;0;false;false;false;256;224;false;640;480;60;false"); -Setting Video::profile_1(&config_file, "video.profile_1", "", "0;0;0;0;false;false;false;256;224;false;640;480;60;false"); -Setting Video::profile_2(&config_file, "video.profile_2", "", "0;0;0;0;false;false;false;256;224;false;640;480;60;false"); -Setting Video::profile_3(&config_file, "video.profile_3", "", "0;0;0;0;false;false;false;256;224;false;640;480;60;false"); -Setting Video::profile_4(&config_file, "video.profile_4", "", "0;0;0;0;false;false;false;256;224;false;640;480;60;false"); -Setting Video::profile_5(&config_file, "video.profile_5", "", "0;0;0;0;false;false;false;256;224;false;640;480;60;false"); -Setting Video::profile_6(&config_file, "video.profile_6", "", "0;0;0;0;false;false;false;256;224;false;640;480;60;false"); -Setting Video::profile_7(&config_file, "video.profile_7", "", "0;0;0;0;false;false;false;256;224;false;640;480;60;false"); -Setting Video::profile_8(&config_file, "video.profile_8", "", "0;0;0;0;false;false;false;256;224;false;640;480;60;false"); -Setting Video::profile_9(&config_file, "video.profile_9", "", "0;0;0;0;false;false;false;256;224;false;640;480;60;false"); + "", "0;0;0;0;false;false;false;256;224;false;320;240;0;false"); +Setting Video::profile_1(&config_file, "video.profile_1", "", "0;0;0;1;false;false;false;512;448;false;640;480;0;false"); +Setting Video::profile_2(&config_file, "video.profile_2", "", "0;1;0;1;true;false;false;597;448;false;640;480;0;false"); +Setting Video::profile_3(&config_file, "video.profile_3", "", "0;1;0;2;true;false;false;896;672;false;1024;768;0;false"); +Setting Video::profile_4(&config_file, "video.profile_4", "", "0;1;0;3;true;false;false;1195;896;false;1280;960;0;false"); + +Setting Video::profile_5(&config_file, "video.profile_5", "", "0;0;0;0;false;false;false;256;224;true;320;240;0;false"); +Setting Video::profile_6(&config_file, "video.profile_6", "", "0;0;0;1;false;false;false;512;448;true;640;480;0;false"); +Setting Video::profile_7(&config_file, "video.profile_7", "", "0;1;0;1;true;false;false;597;448;true;640;480;0;false"); +Setting Video::profile_8(&config_file, "video.profile_8", "", "0;1;0;2;true;false;false;896;672;true;1024;768;0;false"); +Setting Video::profile_9(&config_file, "video.profile_9", "", "0;1;0;3;true;false;false;1195;896;true;1280;960;0;false"); Setting Video::use_vram(&config_file, "video.use_vram", "Use Video RAM instead of System RAM", true, Setting::TRUE_FALSE); Setting Video::triple_buffering(&config_file, "video.triple_buffering", "Use triple buffering", false, Setting::TRUE_FALSE); @@ -175,6 +176,6 @@ Setting Misc::show_fps(&config_file, "misc.show_fps", "Show framerate", true, Se Setting Misc::config_window_alpha_level(&config_file, "misc.config_window_alpha_level", "Alpha level (opacity) of configuration window\n" "Value must be between 64 (25% opaque, 75% transparent) and 255 (100% opaque)", - 192, Setting::DEC); + 255, Setting::DEC); }; diff --git a/src/win/input/dinput.cpp b/src/win/input/dinput.cpp index 5007b3b2..4727f04c 100644 --- a/src/win/input/dinput.cpp +++ b/src/win/input/dinput.cpp @@ -161,8 +161,7 @@ void InputDI::set_status(uint8 device, uint8 button, bool status) { case SNES::JOYPAD_R: joypad1.r = status; break; case SNES::JOYPAD_SELECT: joypad1.select = status; break; case SNES::JOYPAD_START: joypad1.start = status; break; - } - break; + } break; case SNES::DEV_JOYPAD2: switch(button) { case SNES::JOYPAD_UP: joypad2.up = status; break; @@ -177,8 +176,7 @@ void InputDI::set_status(uint8 device, uint8 button, bool status) { case SNES::JOYPAD_R: joypad2.r = status; break; case SNES::JOYPAD_SELECT: joypad2.select = status; break; case SNES::JOYPAD_START: joypad2.start = status; break; - } - break; + } break; } } diff --git a/src/win/input/input.cpp b/src/win/input/input.cpp index d9c51179..e8215e83 100644 --- a/src/win/input/input.cpp +++ b/src/win/input/input.cpp @@ -202,6 +202,77 @@ uint r = key & KEYMASK; return result; } +uint Input::get_keymap(uint device, uint button) { + switch(device) { + case SNES::DEV_JOYPAD1: + switch(button) { + case SNES::JOYPAD_UP: return config::input.joypad1.up; + case SNES::JOYPAD_DOWN: return config::input.joypad1.down; + case SNES::JOYPAD_LEFT: return config::input.joypad1.left; + case SNES::JOYPAD_RIGHT: return config::input.joypad1.right; + case SNES::JOYPAD_A: return config::input.joypad1.a; + case SNES::JOYPAD_B: return config::input.joypad1.b; + case SNES::JOYPAD_X: return config::input.joypad1.x; + case SNES::JOYPAD_Y: return config::input.joypad1.y; + case SNES::JOYPAD_L: return config::input.joypad1.l; + case SNES::JOYPAD_R: return config::input.joypad1.r; + case SNES::JOYPAD_SELECT: return config::input.joypad1.select; + case SNES::JOYPAD_START: return config::input.joypad1.start; + } break; + case SNES::DEV_JOYPAD2: + switch(button) { + case SNES::JOYPAD_UP: return config::input.joypad2.up; + case SNES::JOYPAD_DOWN: return config::input.joypad2.down; + case SNES::JOYPAD_LEFT: return config::input.joypad2.left; + case SNES::JOYPAD_RIGHT: return config::input.joypad2.right; + case SNES::JOYPAD_A: return config::input.joypad2.a; + case SNES::JOYPAD_B: return config::input.joypad2.b; + case SNES::JOYPAD_X: return config::input.joypad2.x; + case SNES::JOYPAD_Y: return config::input.joypad2.y; + case SNES::JOYPAD_L: return config::input.joypad2.l; + case SNES::JOYPAD_R: return config::input.joypad2.r; + case SNES::JOYPAD_SELECT: return config::input.joypad2.select; + case SNES::JOYPAD_START: return config::input.joypad2.start; + } break; + } + return JOYKEY_NONE; +} + +void Input::set_keymap(uint device, uint button, uint keymap) { + switch(device) { + case SNES::DEV_JOYPAD1: + switch(button) { + case SNES::JOYPAD_UP: config::input.joypad1.up = keymap; break; + case SNES::JOYPAD_DOWN: config::input.joypad1.down = keymap; break; + case SNES::JOYPAD_LEFT: config::input.joypad1.left = keymap; break; + case SNES::JOYPAD_RIGHT: config::input.joypad1.right = keymap; break; + case SNES::JOYPAD_A: config::input.joypad1.a = keymap; break; + case SNES::JOYPAD_B: config::input.joypad1.b = keymap; break; + case SNES::JOYPAD_X: config::input.joypad1.x = keymap; break; + case SNES::JOYPAD_Y: config::input.joypad1.y = keymap; break; + case SNES::JOYPAD_L: config::input.joypad1.l = keymap; break; + case SNES::JOYPAD_R: config::input.joypad1.r = keymap; break; + case SNES::JOYPAD_SELECT: config::input.joypad1.select = keymap; break; + case SNES::JOYPAD_START: config::input.joypad1.start = keymap; break; + } break; + case SNES::DEV_JOYPAD2: + switch(button) { + case SNES::JOYPAD_UP: config::input.joypad2.up = keymap; break; + case SNES::JOYPAD_DOWN: config::input.joypad2.down = keymap; break; + case SNES::JOYPAD_LEFT: config::input.joypad2.left = keymap; break; + case SNES::JOYPAD_RIGHT: config::input.joypad2.right = keymap; break; + case SNES::JOYPAD_A: config::input.joypad2.a = keymap; break; + case SNES::JOYPAD_B: config::input.joypad2.b = keymap; break; + case SNES::JOYPAD_X: config::input.joypad2.x = keymap; break; + case SNES::JOYPAD_Y: config::input.joypad2.y = keymap; break; + case SNES::JOYPAD_L: config::input.joypad2.l = keymap; break; + case SNES::JOYPAD_R: config::input.joypad2.r = keymap; break; + case SNES::JOYPAD_SELECT: config::input.joypad2.select = keymap; break; + case SNES::JOYPAD_START: config::input.joypad2.start = keymap; break; + } break; + } +} + void Input::init() { string t, part; strcpy(t, config::input.joypad1.map.sget()); diff --git a/src/win/input/input.h b/src/win/input/input.h index faa462ce..46516f7a 100644 --- a/src/win/input/input.h +++ b/src/win/input/input.h @@ -76,6 +76,8 @@ enum { bool keydown(uint id); uint stringtokeymap(const char *str); const char *keymaptostring(uint key); + uint get_keymap(uint device, uint button); + void set_keymap(uint device, uint button, uint keymap); Input(); }; diff --git a/src/win/settings/ui_coloradjust.cpp b/src/win/settings/ui_coloradjust.cpp index 83471d7a..007642db 100644 --- a/src/win/settings/ui_coloradjust.cpp +++ b/src/win/settings/ui_coloradjust.cpp @@ -54,7 +54,7 @@ bool ColorAdjustWindow::Event(EventInfo &info) { } void ColorAdjustWindow::Setup() { - Header.Create(this, "visible", 0, 0, 475, 30, "Color Adjust"); + Header.Create(this, "visible", 0, 0, 475, 30, "Color Adjustment"); Header.SetFont(global::font_header); int x = 15, y = 30; diff --git a/src/win/settings/ui_inputconfig.cpp b/src/win/settings/ui_inputconfig.cpp index 133858bb..bb5a86be 100644 --- a/src/win/settings/ui_inputconfig.cpp +++ b/src/win/settings/ui_inputconfig.cpp @@ -7,6 +7,18 @@ void CALLBACK wInputConfigInputTimerProc(HWND hwnd, UINT msg, UINT event, DWORD bool InputConfigWindow::Event(EventInfo &info) { switch(info.event_id) { + case EVENT_DRAW: { + PAINTSTRUCT ps; + HDC hdc = BeginPaint(hwnd, &ps); + HDC hdcsrc = CreateCompatibleDC(hdc); + HBITMAP hbm = LoadBitmap(GetModuleHandle(0), MAKEINTRESOURCE(102)); + SelectObject(hdcsrc, hbm); + BitBlt(hdc, 285, 139, 190, 100, hdcsrc, 0, 0, SRCCOPY); + DeleteDC(hdcsrc); + DeleteObject(hbm); + EndPaint(hwnd, &ps); + } break; + case Input::EVENT_INPUTKEYDOWN: { if(button_update.active == true) { button_update.id = info.control_id; @@ -17,30 +29,35 @@ bool InputConfigWindow::Event(EventInfo &info) { case EVENT_CHANGED: { if(info.control == &Resistance) { config::input.axis_resistance = Resistance.GetPos(); - ResistanceLabel.SetText("Resistance: %d%%", uint(config::input.axis_resistance)); + ResistanceLabel.SetText("Joypad axis resistance: %d%%", uint(config::input.axis_resistance)); } else if(info.control == &Selected) { switch(Selected.GetSelection()) { case 0: AllowBadInput.Check(config::input.joypad1.allow_invalid_input); break; case 1: AllowBadInput.Check(config::input.joypad2.allow_invalid_input); break; } + UpdateButtonList(); + } + } break; + + case EVENT_DOUBLECLICKED: { + if(info.control == &ButtonList) { + int sel = ButtonList.GetSelection(); + if(sel != -1)ButtonUpdateBegin(sel); } } break; case EVENT_CLICKED: { - if(info.control == &ButtonUp) ButtonUpdate(BUTTON_UP); - if(info.control == &ButtonDown) ButtonUpdate(BUTTON_DOWN); - if(info.control == &ButtonLeft) ButtonUpdate(BUTTON_LEFT); - if(info.control == &ButtonRight) ButtonUpdate(BUTTON_RIGHT); - if(info.control == &ButtonA) ButtonUpdate(BUTTON_A); - if(info.control == &ButtonB) ButtonUpdate(BUTTON_B); - if(info.control == &ButtonX) ButtonUpdate(BUTTON_X); - if(info.control == &ButtonY) ButtonUpdate(BUTTON_Y); - if(info.control == &ButtonL) ButtonUpdate(BUTTON_L); - if(info.control == &ButtonR) ButtonUpdate(BUTTON_R); - if(info.control == &ButtonSelect)ButtonUpdate(BUTTON_SELECT); - if(info.control == &ButtonStart) ButtonUpdate(BUTTON_START); - - if(info.control == &AllowBadInput) { + if(info.control == &ButtonUpdate) { + int sel = ButtonList.GetSelection(); + if(sel != -1)ButtonUpdateBegin(sel); + } else if(info.control == &ButtonClear) { + int sel = ButtonList.GetSelection(); + if(sel != -1) { + ButtonUpdateBegin(sel); + button_update.id = uiInput->keymap.esc; + ButtonUpdateEnd(); + } + } else if(info.control == &AllowBadInput) { switch(Selected.GetSelection()) { case 0: config::input.joypad1.allow_invalid_input.toggle(); @@ -61,31 +78,53 @@ bool InputConfigWindow::Event(EventInfo &info) { const char *InputConfigWindow::GetCaption(uint button) { switch(button) { - case BUTTON_UP: return "Up"; - case BUTTON_DOWN: return "Down"; - case BUTTON_LEFT: return "Left"; - case BUTTON_RIGHT: return "Right"; - case BUTTON_A: return "A"; - case BUTTON_B: return "B"; - case BUTTON_X: return "X"; - case BUTTON_Y: return "Y"; - case BUTTON_L: return "L"; - case BUTTON_R: return "R"; - case BUTTON_SELECT: return "Select"; - case BUTTON_START: return "Start"; + case SNES::JOYPAD_UP: return "Up"; + case SNES::JOYPAD_DOWN: return "Down"; + case SNES::JOYPAD_LEFT: return "Left"; + case SNES::JOYPAD_RIGHT: return "Right"; + case SNES::JOYPAD_A: return "A"; + case SNES::JOYPAD_B: return "B"; + case SNES::JOYPAD_X: return "X"; + case SNES::JOYPAD_Y: return "Y"; + case SNES::JOYPAD_L: return "L"; + case SNES::JOYPAD_R: return "R"; + case SNES::JOYPAD_SELECT: return "Select"; + case SNES::JOYPAD_START: return "Start"; } - return ""; } -void InputConfigWindow::ButtonUpdate(uint button) { +void InputConfigWindow::UpdateButtonList() { + ButtonList.DeleteAllItems(); +uint device = Selected.GetSelection(); +char t[512], tmp[512]; +string str, part; +#define add(__label, __bn) \ + strcpy(tmp, uiInput->keymaptostring(uiInput->get_keymap(device, SNES::JOYPAD_##__bn))); \ + split(part, " | ", tmp); \ + replace(part[0], "keynone", ""); \ + if(count(part) < 2)strcpy(part[1], ""); \ + sprintf(t, #__label "|%s|%s", strptr(part[0]), strptr(part[1])); \ + ButtonList.AddItem(t); + + add(Up, UP); add(Down, DOWN); add(Left, LEFT); add(Right, RIGHT); + add(Y, Y); add(X, X); add(B, B); add(A, A); + add(L, L); add(R, R); add(Select, SELECT); add(Start, START); +#undef add +} + +void InputConfigWindow::ButtonUpdateBegin(uint button) { if(button_update.active == true)return; +// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 +//convert Up, Down, Left, Right, Y, X, B, A, L, R, Select, Start +//to B, Y, Select, Start, Up, Down, Left, Right, A, X, L, R +uint translate_table[12] = { 4, 5, 6, 7, 1, 9, 0, 8, 10, 11, 2, 3 }; button_update.active = true; button_update.controller = Selected.GetSelection(); - button_update.button = button; + button_update.button = translate_table[button]; - Message.SetText("Press button or key for 'Controller %d::%s', " + Message.SetText("Press key or button for 'Controller %d::%s', " "or press escape to clear button assignment.", button_update.controller + 1, GetCaption(button_update.button)); SetFocus(Message.hwnd); @@ -103,40 +142,7 @@ uint old_id, id = button_update.id; //escape key was pressed, clear key + joy mapping id = Input::JOYKEY_NONE; } else { - switch(button_update.controller) { - case 0: - switch(button_update.button) { - case BUTTON_UP: old_id = config::input.joypad1.up; break; - case BUTTON_DOWN: old_id = config::input.joypad1.down; break; - case BUTTON_LEFT: old_id = config::input.joypad1.left; break; - case BUTTON_RIGHT: old_id = config::input.joypad1.right; break; - case BUTTON_A: old_id = config::input.joypad1.a; break; - case BUTTON_B: old_id = config::input.joypad1.b; break; - case BUTTON_X: old_id = config::input.joypad1.x; break; - case BUTTON_Y: old_id = config::input.joypad1.y; break; - case BUTTON_L: old_id = config::input.joypad1.l; break; - case BUTTON_R: old_id = config::input.joypad1.r; break; - case BUTTON_SELECT: old_id = config::input.joypad1.select; break; - case BUTTON_START: old_id = config::input.joypad1.start; break; - } - break; - case 1: - switch(button_update.button) { - case BUTTON_UP: old_id = config::input.joypad2.up; break; - case BUTTON_DOWN: old_id = config::input.joypad2.down; break; - case BUTTON_LEFT: old_id = config::input.joypad2.left; break; - case BUTTON_RIGHT: old_id = config::input.joypad2.right; break; - case BUTTON_A: old_id = config::input.joypad2.a; break; - case BUTTON_B: old_id = config::input.joypad2.b; break; - case BUTTON_X: old_id = config::input.joypad2.x; break; - case BUTTON_Y: old_id = config::input.joypad2.y; break; - case BUTTON_L: old_id = config::input.joypad2.l; break; - case BUTTON_R: old_id = config::input.joypad2.r; break; - case BUTTON_SELECT: old_id = config::input.joypad2.select; break; - case BUTTON_START: old_id = config::input.joypad2.start; break; - } - break; - } + old_id = uiInput->get_keymap(button_update.controller, button_update.button); if(id & Input::JOYFLAG) { //joypad key was pressed @@ -159,48 +165,19 @@ uint old_id, id = button_update.id; id &= Input::JOYKEYMASK; } - switch(button_update.controller) { - case 0: - switch(button_update.button) { - case BUTTON_UP: config::input.joypad1.up = id; break; - case BUTTON_DOWN: config::input.joypad1.down = id; break; - case BUTTON_LEFT: config::input.joypad1.left = id; break; - case BUTTON_RIGHT: config::input.joypad1.right = id; break; - case BUTTON_A: config::input.joypad1.a = id; break; - case BUTTON_B: config::input.joypad1.b = id; break; - case BUTTON_X: config::input.joypad1.x = id; break; - case BUTTON_Y: config::input.joypad1.y = id; break; - case BUTTON_L: config::input.joypad1.l = id; break; - case BUTTON_R: config::input.joypad1.r = id; break; - case BUTTON_SELECT: config::input.joypad1.select = id; break; - case BUTTON_START: config::input.joypad1.start = id; break; - } - break; - case 1: - switch(button_update.button) { - case BUTTON_UP: config::input.joypad2.up = id; break; - case BUTTON_DOWN: config::input.joypad2.down = id; break; - case BUTTON_LEFT: config::input.joypad2.left = id; break; - case BUTTON_RIGHT: config::input.joypad2.right = id; break; - case BUTTON_A: config::input.joypad2.a = id; break; - case BUTTON_B: config::input.joypad2.b = id; break; - case BUTTON_X: config::input.joypad2.x = id; break; - case BUTTON_Y: config::input.joypad2.y = id; break; - case BUTTON_L: config::input.joypad2.l = id; break; - case BUTTON_R: config::input.joypad2.r = id; break; - case BUTTON_SELECT: config::input.joypad2.select = id; break; - case BUTTON_START: config::input.joypad2.start = id; break; - } - break; - } + uiInput->set_keymap(button_update.controller, button_update.button, id); Message.SetText("Button updated. Select another button to update."); +int sel = ButtonList.GetSelection(); + UpdateButtonList(); + ButtonList.SetSelection(sel); } void InputConfigWindow::Show() { Selected.SetSelection(0); AllowBadInput.Check(config::input.joypad1.allow_invalid_input); Message.SetText("Select button to update."); + UpdateButtonList(); Window::Show(); } @@ -217,60 +194,36 @@ void InputConfigWindow::Setup() { Header.SetFont(global::font_header); int x = 15, y = 30; - ResistanceDesc.Create(this, "visible|sunken|vscroll|multiline|readonly", x, y, 460, 45, - "Joypad axis resistance: (75% = default)\r\n" - "Controls how much force needs to be applied to an analog " - "joypad axis in any given direction to trigger a button press. (continued)\r\n\r\n" - "Example: With a resistance of 10% (minimum), one would barely need to tap " - "left to trigger a left button press. However, with a resistance of 90% " - "(maximum), one would need to push the axis as far to the left as possible to " - "trigger a left button press.\r\n\r\n" - "Generally, a lower resistance will work better when trying to input combos (eg " - "in fighting games), whereas a higher resistance will prevent accidental button " - "presses.\r\n\r\n" - "This setting only applies when the controller is in analog input mode.\r\n\r\n" - "Because it is possible to use multiple real controllers for a single emulated " - "SNES controller, there is only one global axis resistance setting. This setting " - "will thusly affect all joypads connected to this computer." - ); - y += 45; - ResistanceLabel.Create(this, "visible", x, y + 3, 100, 15); - ResistanceLabel.SetText("Resistance: %d%%", uint(config::input.axis_resistance)); - Resistance.Create(this, "visible", x + 100, y, 360, 25); + ResistanceLabel.Create(this, "visible", x, y + 3, 150, 15); + ResistanceLabel.SetText("Joypad axis resistance: %d%%", uint(config::input.axis_resistance)); + Resistance.Create(this, "visible", x + 150, y, 310, 25); Resistance.SetRange(10, 90); Resistance.SetPos(config::input.axis_resistance); y += 25; - Separator.Create(this, "visible|sunken", x, y + 5, 460, 3); - y += 15; - SelectLabel.Create(this, "visible", x, y + 3, 150, 15, "Select controller to configure:"); Selected.Create(this, "visible", x + 150, y, 100, 200); Selected.AddItem("Controller 1"); Selected.AddItem("Controller 2"); y += 25; + Separator.Create(this, "visible|sunken", x, y + 1, 460, 3); + y += 9; + Message.Create(this, "visible", x, y, 460, 15); y += 20; - ButtonL.Create (this, "visible", x + 100, y, 40, 25, "L"); - ButtonR.Create (this, "visible", x + 205, y, 40, 25, "R"); + ButtonList.Create(this, "visible|edge", x, y, 265, 195); + ButtonList.AddColumn(Listview::LEFT, 61, "Button"); + ButtonList.AddColumn(Listview::LEFT, 100, "Key Mapping"); + ButtonList.AddColumn(Listview::LEFT, 100, "Joypad Mapping"); + ButtonUpdate.Create(this, "visible", x + 270, y, 92, 25, "Update"); + ButtonClear.Create(this, "visible", x + 270 + 98, y, 92, 25, "Clear"); + y += 200; - ButtonUp.Create (this, "visible", x + 40, y + 15, 40, 25, "Up"); - ButtonLeft.Create (this, "visible", x, y + 40, 40, 25, "Left"); - ButtonRight.Create (this, "visible", x + 80, y + 40, 40, 25, "Right"); - ButtonDown.Create (this, "visible", x + 40, y + 65, 40, 25, "Down"); - - ButtonSelect.Create(this, "visible", x + 130, y + 55, 40, 25, "Select"); - ButtonStart.Create (this, "visible", x + 180, y + 55, 40, 25, "Start"); - - ButtonX.Create (this, "visible", x + 270, y + 15, 40, 25, "X"); - ButtonY.Create (this, "visible", x + 230, y + 40, 40, 25, "Y"); - ButtonA.Create (this, "visible", x + 310, y + 40, 40, 25, "A"); - ButtonB.Create (this, "visible", x + 270, y + 65, 40, 25, "B"); - - AllowBadInput.Create(this, "visible", x, y + 95, 460, 15, - "Allow up+down and left+right button combinations (not recommended -- can cause bugs)"); + AllowBadInput.Create(this, "visible", x, y, 460, 15, + "Allow up+down and left+right button combinations (not recommended -- can trigger bugs)"); + y += 15; } InputConfigWindow::InputConfigWindow() { diff --git a/src/win/settings/ui_inputconfig.h b/src/win/settings/ui_inputconfig.h index 1d170de3..bd248a6c 100644 --- a/src/win/settings/ui_inputconfig.h +++ b/src/win/settings/ui_inputconfig.h @@ -1,17 +1,15 @@ class InputConfigWindow : public Window { public: Label Header; -Editbox ResistanceDesc; Label ResistanceLabel; Slider Resistance; -Label Separator; Label SelectLabel; Combobox Selected; +Label Separator; Label Message; -Button ButtonL, ButtonR; -Button ButtonUp, ButtonDown, ButtonLeft, ButtonRight; -Button ButtonSelect, ButtonStart; -Button ButtonA, ButtonB, ButtonX, ButtonY; +Listview ButtonList; +Button ButtonUpdate; +Button ButtonClear; Checkbox AllowBadInput; struct { @@ -21,19 +19,13 @@ struct { uint id; } button_update; -enum { - BUTTON_L, BUTTON_R, - BUTTON_UP, BUTTON_DOWN, BUTTON_LEFT, BUTTON_RIGHT, - BUTTON_SELECT, BUTTON_START, - BUTTON_A, BUTTON_B, BUTTON_X, BUTTON_Y, -}; - bool Event(EventInfo &info); void Show(); void Hide(); const char *GetCaption(uint button); - void ButtonUpdate(uint button); + void UpdateButtonList(); + void ButtonUpdateBegin(uint button); void ButtonUpdateEnd(); void Setup(); diff --git a/src/win/settings/ui_rastersettings.cpp b/src/win/settings/ui_rastersettings.cpp index 0b92cbf0..ba50c5ee 100644 --- a/src/win/settings/ui_rastersettings.cpp +++ b/src/win/settings/ui_rastersettings.cpp @@ -23,12 +23,9 @@ void RasterSettingsWindow::Setup() { Header.SetFont(global::font_header); int x = 15, y = 30; - ScanlineDesc.Create(this, "visible|sunken|multiline|readonly", x, y, 460, 45, - "Scanline Intensity Adjust: (0% = no scanlines, 100% = full scanlines)\r\n" - "This setting will affect all video modes. However, scanlines are only applied " - "if current video profile has hardware scanlines enabled, and render height >= 448." - ); - y += 50; + ScanlineLabel.Create(this, "visible", x, y, 460, 15, + "Scanline intensity adjust: (0% = no scanlines, 100% = full scanlines)"); + y += 20; PScanlineLabel.Create(this, "visible", x, y, 100, 15); PScanlineLabel.SetText("Progressive: %d%%", uint(config::video.pscanline_intensity)); diff --git a/src/win/settings/ui_rastersettings.h b/src/win/settings/ui_rastersettings.h index 22a8fddb..a538f5b3 100644 --- a/src/win/settings/ui_rastersettings.h +++ b/src/win/settings/ui_rastersettings.h @@ -1,7 +1,7 @@ class RasterSettingsWindow : public Window { public: Label Header; -Editbox ScanlineDesc; +Label ScanlineLabel; Label PScanlineLabel; Slider PScanlineSlider; Label IScanlineLabel; diff --git a/src/win/settings/ui_settings.cpp b/src/win/settings/ui_settings.cpp index 370f37a4..52fa544c 100644 --- a/src/win/settings/ui_settings.cpp +++ b/src/win/settings/ui_settings.cpp @@ -27,8 +27,8 @@ bool SettingsWindow::Event(EventInfo &info) { void SettingsWindow::Show() { settings.show_active_panel(); - SetFocus(Panel.hwnd); Window::Show(); + Panel.Focus(); } void SettingsWindow::Hide() { @@ -39,7 +39,7 @@ void SettingsWindow::Hide() { void SettingsWindow::Setup() { Panel.Create(this, "visible|edge", 5, 5, 150, 360, "Video Settings|" - "Color Adjust|" + "Color Adjustment|" "Raster Settings|" "|" "Input Configuration|" diff --git a/src/win/settings/ui_videosettings.cpp b/src/win/settings/ui_videosettings.cpp index 32745bf0..49a8db2d 100644 --- a/src/win/settings/ui_videosettings.cpp +++ b/src/win/settings/ui_videosettings.cpp @@ -3,12 +3,12 @@ bool VideoSettingsWindow::Event(EventInfo &info) { case EVENT_CHANGED: case EVENT_CLICKED: { - if(info.control == &VideoProfile) { - LoadSettings(VideoProfile.GetSelection()); - } else if(info.control == &WinProfile) { + if(info.control == &WinProfile) { config::video.profile_windowed_default = WinProfile.GetSelection(); } else if(info.control == &FullProfile) { config::video.profile_fullscreen_default = FullProfile.GetSelection(); + } else if(info.control == &VideoProfile) { + LoadSettings(VideoProfile.GetSelection()); } else if(info.control == &ApplySettings) { SaveSettings(VideoProfile.GetSelection()); } else if(info.control == &SelectProfile) { @@ -74,9 +74,9 @@ char t[64 + 1]; } void VideoSettingsWindow::Show() { - VideoProfile.SetSelection(config::video.profile); WinProfile.SetSelection(config::video.profile_windowed_default); FullProfile.SetSelection(config::video.profile_fullscreen_default); + VideoProfile.SetSelection(config::video.profile); LoadSettings(config::video.profile); Window::Show(); } @@ -86,12 +86,6 @@ void VideoSettingsWindow::Setup() { Header.SetFont(global::font_header); int x = 15, y = 30; - VideoProfileLabel.Create(this, "visible", x, y + 3, 135, 15, "Video profile to configure:"); - VideoProfile.Create(this, "visible", x + 135, y, 90, 200, - "Profile 0|Profile 1|Profile 2|Profile 3|Profile 4|" - "Profile 5|Profile 6|Profile 7|Profile 8|Profile 9"); - y += 25; - WinProfileLabel.Create(this, "visible", x, y + 3, 135, 15, "Default windowed profile:"); WinProfile.Create(this, "visible", x + 135, y, 90, 200, "Profile 0|Profile 1|Profile 2|Profile 3|Profile 4|" @@ -103,16 +97,22 @@ int x = 15, y = 30; "Profile 5|Profile 6|Profile 7|Profile 8|Profile 9"); y += 25; + VideoProfileLabel.Create(this, "visible", x, y + 3, 135, 15, "Video profile to configure:"); + VideoProfile.Create(this, "visible", x + 135, y, 90, 200, + "Profile 0|Profile 1|Profile 2|Profile 3|Profile 4|" + "Profile 5|Profile 6|Profile 7|Profile 8|Profile 9"); + y += 25; + Separator1.Create(this, "visible|sunken", x, y + 5, 460, 3); y += 15; SoftwareFilterLabel.Create(this, "visible", x, y + 3, 85, 15, "Software filter:"); SoftwareFilter.Create(this, "visible", x + 85, y, 140, 200, - "Direct|NTSC|HQ2x|Scale2x"); + "None|NTSC|HQ2x|Scale2x"); HardwareFilterLabel.Create(this, "visible", x + 235, y + 3, 85, 15, "Hardware filter:"); HardwareFilter.Create(this, "visible", x + 320, y, 140, 200, - "Pixel|Bilinear"); + "None|Bilinear"); y += 25; VideoStandardLabel.Create(this, "visible", x, y + 3, 85, 15, "Video standard:"); diff --git a/src/win/settings/ui_videosettings.h b/src/win/settings/ui_videosettings.h index 70299c26..64348de0 100644 --- a/src/win/settings/ui_videosettings.h +++ b/src/win/settings/ui_videosettings.h @@ -1,12 +1,12 @@ class VideoSettingsWindow : public Window { public: Label Header; -Label VideoProfileLabel; -Combobox VideoProfile; Label WinProfileLabel; Combobox WinProfile; Label FullProfileLabel; Combobox FullProfile; +Label VideoProfileLabel; +Combobox VideoProfile; Label Separator1; Label SoftwareFilterLabel; Combobox SoftwareFilter; diff --git a/src/win/ui.h b/src/win/ui.h index 94a8ecf8..e5024353 100644 --- a/src/win/ui.h +++ b/src/win/ui.h @@ -44,10 +44,7 @@ MENU_SETTINGS, MENU_SETTINGS_FRAMESKIP_7, MENU_SETTINGS_FRAMESKIP_8, MENU_SETTINGS_FRAMESKIP_9, - MENU_SETTINGS_VIDEO_OPTIONS, - MENU_SETTINGS_VIDEO_OPTIONS_USEVRAM, - MENU_SETTINGS_VIDEO_OPTIONS_TRIPLEBUF, - MENU_SETTINGS_VIDEO_OPTIONS_SHOWFPS, + MENU_SETTINGS_SHOWFPS, //--- MENU_SETTINGS_MUTE, //--- diff --git a/src/win/ui_main.cpp b/src/win/ui_main.cpp index 37efc18a..6f772651 100644 --- a/src/win/ui_main.cpp +++ b/src/win/ui_main.cpp @@ -171,21 +171,10 @@ bool MainWindow::Event(EventInfo &info) { SetFrameskip(info.control_id - MENU_SETTINGS_FRAMESKIP_0); } break; - case MENU_SETTINGS_VIDEO_OPTIONS_USEVRAM: { - config::video.use_vram.toggle(); - event::set_video_profile(config::video.profile); - CheckMenuItem(MENU_SETTINGS_VIDEO_OPTIONS_USEVRAM, config::video.use_vram); - } break; - - case MENU_SETTINGS_VIDEO_OPTIONS_TRIPLEBUF: { - config::video.triple_buffering.toggle(); - CheckMenuItem(MENU_SETTINGS_VIDEO_OPTIONS_TRIPLEBUF, config::video.triple_buffering); - } break; - - case MENU_SETTINGS_VIDEO_OPTIONS_SHOWFPS: { + case MENU_SETTINGS_SHOWFPS: { config::misc.show_fps.toggle(); SetWindowText(hwnd, BSNES_TITLE); - CheckMenuItem(MENU_SETTINGS_VIDEO_OPTIONS_SHOWFPS, config::misc.show_fps); + CheckMenuItem(MENU_SETTINGS_SHOWFPS, config::misc.show_fps); } break; case MENU_SETTINGS_MUTE: { @@ -286,11 +275,7 @@ char t[128]; AddMenuItem(MENU_SETTINGS_FRAMESKIP_9, "&9"); EndMenuGroup(); - AddMenuGroup("&Video Options"); - AddMenuItem(MENU_SETTINGS_VIDEO_OPTIONS_USEVRAM, "Use &Video Memory Surface"); - AddMenuItem(MENU_SETTINGS_VIDEO_OPTIONS_TRIPLEBUF, "Use &Triple Buffering"); - AddMenuItem(MENU_SETTINGS_VIDEO_OPTIONS_SHOWFPS, "&Show FPS"); - EndMenuGroup(); + AddMenuItem(MENU_SETTINGS_SHOWFPS, "&Show FPS"); AddMenuSeparator(); AddMenuItem(MENU_SETTINGS_MUTE, "&Mute Sound Output"); @@ -299,20 +284,15 @@ char t[128]; AddMenuGroup("&Speed Regulation"); AddMenuItem(MENU_SETTINGS_SPEED_REGULATION_ENABLE, "&Enable"); AddMenuSeparator(); - sprintf(t, "&Slowest (%d%%, %dhz)", uint(100.0 * (double(config::system.speed_slowest) / 32000.0)), - uint(config::system.speed_slowest)); + sprintf(t, "&Slowest (%d%%)", uint(100.0 * (double(config::system.speed_slowest) / 32000.0))); AddMenuItem(MENU_SETTINGS_SPEED_REGULATION_SLOWEST, t); - sprintf(t, "&Slow (%d%%, %dhz)", uint(100.0 * (double(config::system.speed_slow) / 32000.0)), - uint(config::system.speed_slow)); + sprintf(t, "&Slow (%d%%)", uint(100.0 * (double(config::system.speed_slow) / 32000.0))); AddMenuItem(MENU_SETTINGS_SPEED_REGULATION_SLOW, t); - sprintf(t, "&Normal (%d%%, %dhz)", uint(100.0 * (double(config::system.speed_normal) / 32000.0)), - uint(config::system.speed_normal)); + sprintf(t, "&Normal (%d%%)", uint(100.0 * (double(config::system.speed_normal) / 32000.0))); AddMenuItem(MENU_SETTINGS_SPEED_REGULATION_NORMAL, t); - sprintf(t, "&Fast (%d%%, %dhz)", uint(100.0 * (double(config::system.speed_fast) / 32000.0)), - uint(config::system.speed_fast)); + sprintf(t, "&Fast (%d%%)", uint(100.0 * (double(config::system.speed_fast) / 32000.0))); AddMenuItem(MENU_SETTINGS_SPEED_REGULATION_FAST, t); - sprintf(t, "&Fastest (%d%%, %dhz)", uint(100.0 * (double(config::system.speed_fastest) / 32000.0)), - uint(config::system.speed_fastest)); + sprintf(t, "&Fastest (%d%%)", uint(100.0 * (double(config::system.speed_fastest) / 32000.0))); AddMenuItem(MENU_SETTINGS_SPEED_REGULATION_FASTEST, t); EndMenuGroup(); @@ -331,9 +311,7 @@ char t[128]; ShowMenu(); - CheckMenuItem(MENU_SETTINGS_VIDEO_OPTIONS_USEVRAM, config::video.use_vram); - CheckMenuItem(MENU_SETTINGS_VIDEO_OPTIONS_TRIPLEBUF, config::video.triple_buffering); - CheckMenuItem(MENU_SETTINGS_VIDEO_OPTIONS_SHOWFPS, config::misc.show_fps); + CheckMenuItem(MENU_SETTINGS_SHOWFPS, config::misc.show_fps); CheckMenuItem(MENU_SETTINGS_MUTE, config::snes.mute); CheckMenuItem(MENU_SETTINGS_SPEED_REGULATION_ENABLE, config::system.regulate_speed);