diff --git a/bsnes.cfg b/bsnes.cfg new file mode 100644 index 00000000..fe7948a4 --- /dev/null +++ b/bsnes.cfg @@ -0,0 +1,189 @@ +# Default path to look for ROM files in ("" = use default directory) +# (default = "") +fs.rom_path = "" + +# Default path for all save RAM and cheat files ("" = use current directory) +# (default = "") +fs.save_path = "" + +# Extension to be used for all save RAM files +# (default = "srm") +fs.save_ext = "srm" + +# Use precalculated TV-style gamma ramp +# (default = true) +snes.colorfilter.gamma_ramp = true + +# Convert color to sepia tone +# (default = false) +snes.colorfilter.sepia = false + +# Convert color to grayscale tone +# (default = false) +snes.colorfilter.grayscale = false + +# Invert output image colors +# (default = false) +snes.colorfilter.invert = false + +# +# (default = 0) +snes.colorfilter.contrast = 0 + +# +# (default = 0) +snes.colorfilter.brightness = 0 + +# +# (default = 80) +snes.colorfilter.gamma = 80 + +# Merge fields in NTSC video filter +# Set to true if using filter at any refresh rate other than 60hz +# +# (default = true) +snes.ntsc_merge_fields = true + +# Mutes SNES audio output when enabled +# (default = false) +snes.mute = true + +# Regulate speed to 60hz (NTSC) / 50hz (PAL) +# (default = true) +system.regulate_speed = false + +# Slowest speed setting (in hz) +# (default = 16000) +system.speed_slowest = 16000 + +# Slow speed setting +# (default = 24000) +system.speed_slow = 24000 + +# Normal speed setting +# (default = 32000) +system.speed_normal = 32000 + +# Fast speed setting +# (default = 48000) +system.speed_fast = 48000 + +# Fastest speed setting +# (default = 64000) +system.speed_fastest = 64000 + +# Video renderer +# "dd" (DirectDraw7 -- faster, less features) +# "d3d" (Direct3D9 -- slower, more features) +# (default = "d3d") +video.renderer = "d3d" + +# +# (default = 2) +video.profile = 0 + +# Video profile 0-7 configuration +# Please use bsnes GUI configuration editor to modify video profile settings +# Format: software_filter;hardware_filter;video_standard;multiplier-1;correct_aspect_ratio; +# enable_scanlines;manual_render_size;render_width;render_height; +# resolution_width;resolution_height;refresh_rate;triple_buffering +# (default = "0;0;0;0;false;false;false;256;224;0;0;0;false") +video.profile_0 = "0;0;0;0;false;false;false;256;239;0;0;0;false" + +# +# (default = "0;0;0;1;false;false;false;512;448;0;0;0;false") +video.profile_1 = "0;0;0;1;false;false;false;512;448;0;0;0;false" + +# +# (default = "0;1;0;1;true;false;false;597;448;0;0;0;false") +video.profile_2 = "0;1;0;1;true;false;false;597;448;0;0;0;false" + +# +# (default = "0;1;0;2;true;false;false;896;672;0;0;0;false") +video.profile_3 = "0;1;0;2;true;false;false;896;672;0;0;0;false" + +# +# (default = "0;1;0;3;true;false;false;1195;896;0;0;0;false") +video.profile_4 = "0;1;0;3;true;false;false;1195;896;0;0;0;false" + +# +# (default = "0;0;0;0;false;false;false;256;224;0;0;0;false") +video.profile_5 = "0;0;0;0;false;false;false;256;224;0;0;0;false" + +# +# (default = "0;0;0;0;false;false;false;256;224;0;0;0;false") +video.profile_6 = "0;0;0;0;false;false;false;256;224;0;0;0;false" + +# +# (default = "0;0;0;0;false;false;false;256;224;0;0;0;false") +video.profile_7 = "0;0;0;0;false;false;false;256;224;0;0;0;false" + +# Use Video RAM instead of System RAM +# (default = true) +video.use_vram = true + +# Use triple buffering +# (default = false) +video.triple_buffering = false + +# Progressive scanline intensity +# Value is percentage of intensity from 0 to 100 +# (default = 30) +video.pscanline_intensity = 30 + +# Interlace scanline intensity +# (default = 50) +video.iscanline_intensity = 50 + +# Axis resistance for all analog joypads +# Affects responsiveness of analog stick movement by specifying what percentage +# in any given direction the axis must be pressed to trigger a button press. +# In other words, this determines how hard you have to press the analog stick to +# simulate pressing e.g. left or right on a digital joypad. +# Value is a percentage, from 0 (axis will trigger with virtually any axis movement) +# up to 100 (axis must be pressed fully to given corner). +# Value affects all four directions of the axis equally. +# Note: Values below 10 or above 90 are not recommended and may not work at all. +# (default = 75) +input.axis_resistance = 75 + +# Allow up+down and left+right key combinations for joypad 1 (not recommended) +# (default = false) +input.joypad1.allow_invalid_input = false + +# Joypad 1 button map +# Format: Up; Down; Left; Right; A; B; X; Y; L; R; Select; Start +# (default = "up | joypad0.up; down | joypad0.down; left | joypad0.left; right | joypad0.right; x | joypad0.button3; z | joypad0.button2; s | joypad0.button1; a | joypad0.button0; d | joypad0.button6; c | joypad0.button7; rshift | joypad0.button4; enter | joypad0.button5") +input.joypad1.map = "up | joypad0.up; down | joypad0.down; left | joypad0.left; right | joypad0.right; x | joypad0.button3; z | joypad0.button2; s | joypad0.button1; a | joypad0.button0; d | joypad0.button6; c | joypad0.button7; rshift | joypad0.button4; enter | joypad0.button5" + +# Allow up+down and left+right key combinations for joypad 2 (not recommended) +# (default = false) +input.joypad2.allow_invalid_input = false + +# Joypad 2 button map +# Format: Up; Down; Left; Right; A; B; X; Y; L; R; Select; Start +# (default = "t | joypad1.up; g | joypad1.down; f | joypad1.left; h | joypad1.right; k | joypad1.button3; j | joypad1.button2; i | joypad1.button1; u | joypad1.button0; o | joypad1.button6; l | joypad1.button7; lbracket | joypad1.button4; rbracket | joypad1.button5") +input.joypad2.map = "t | joypad1.up; g | joypad1.down; f | joypad1.left; h | joypad1.right; k | joypad1.button3; j | joypad1.button2; i | joypad1.button1; u | joypad1.button0; o | joypad1.button6; l | joypad1.button7; lbracket | joypad1.button4; rbracket | joypad1.button5" + +# Number of lines buffered for debugger console +# (default = 100) +debugger.console_lines = 100 + +# Image format for screenshots +# Valid formats: "bmp", "png", "jpg" +# (default = "png") +misc.image_format = "png" + +# Window style for main emulation window +# (default = "titlebar|frame|minimize|dragmove") +misc.window_style = "titlebar|frame|minimize|dragmove" + +# Show framerate +# (default = true) +misc.show_fps = true + +# Alpha level (opacity) of configuration window +# Value must be between 64 (25% opaque, 75% transparent) and 255 (100% opaque) +# (default = 255) +misc.config_window_alpha_level = 255 + diff --git a/bsnes.exe b/bsnes.exe deleted file mode 100644 index cf6174a6..00000000 Binary files a/bsnes.exe and /dev/null differ diff --git a/bsnes_pgo.exe b/bsnes_pgo.exe new file mode 100644 index 00000000..38b191ed Binary files /dev/null and b/bsnes_pgo.exe differ diff --git a/src/base.h b/src/base.h index 44ec33cf..fb6150e0 100644 --- a/src/base.h +++ b/src/base.h @@ -1,4 +1,4 @@ -#define BSNES_VERSION "0.016.38" +#define BSNES_VERSION "0.016.42" #define BSNES_TITLE "bsnes v" BSNES_VERSION #define MEMCORE bMemBus @@ -20,7 +20,7 @@ //#define JMA_SUPPORT //debugging extensions (~10% speed hit) -#define DEBUGGER +//#define DEBUGGER //snes core polymorphism //(allow mem/cpu/apu/ppu overriding, ~10% speed hit) diff --git a/src/config/config.cpp b/src/config/config.cpp index a486fdd9..0100125d 100644 --- a/src/config/config.cpp +++ b/src/config/config.cpp @@ -45,7 +45,7 @@ SNES::VideoColorAdjust SNES::contrast(&config_file, "snes.colorfilter.contrast", SNES::VideoColorAdjust SNES::brightness(&config_file, "snes.colorfilter.brightness", "", 0, Setting::DEC); SNES::VideoColorAdjust SNES::gamma(&config_file, "snes.colorfilter.gamma", - "", 100, Setting::DEC); + "", 80, Setting::DEC); void SNES::VideoColorAdjust::set(uint32 _data) { Setting::set(_data); diff --git a/src/cpu/scpu/dma/dma.cpp b/src/cpu/scpu/dma/dma.cpp index 3a57770f..4964ff8a 100644 --- a/src/cpu/scpu/dma/dma.cpp +++ b/src/cpu/scpu/dma/dma.cpp @@ -233,9 +233,6 @@ void sCPU::hdma_init() { void sCPU::dma_power() { for(int i = 0; i < 8; i++) { - channel[i].dma_enabled = false; - channel[i].hdma_enabled = false; - channel[i].dmap = 0xff; channel[i].direction = 1; channel[i].hdma_indirect = true; @@ -260,6 +257,9 @@ void sCPU::dma_power() { void sCPU::dma_reset() { for(int i = 0; i < 8; i++) { + channel[i].dma_enabled = false; + channel[i].hdma_enabled = false; + channel[i].hdma_completed = false; channel[i].hdma_do_transfer = false; } diff --git a/src/cpu/scpu/mmio/mmio.cpp b/src/cpu/scpu/mmio/mmio.cpp index 285fd996..32e46c99 100644 --- a/src/cpu/scpu/mmio/mmio.cpp +++ b/src/cpu/scpu/mmio/mmio.cpp @@ -51,8 +51,7 @@ uint8 sCPU::mmio_r4016() { uint8 r = regs.mdr & 0xfc; r |= status.joypad1_bits & 1; if(status.joypad_strobe_latch == 0) { - status.joypad1_bits >>= 1; - status.joypad1_bits |= ~0xffff; + status.joypad1_bits = asr<1>(status.joypad1_bits); } return r; @@ -66,8 +65,7 @@ uint8 sCPU::mmio_r4017() { uint8 r = (regs.mdr & 0xe0) | 0x1c; r |= status.joypad2_bits & 1; if(status.joypad_strobe_latch == 0) { - status.joypad2_bits >>= 1; - status.joypad2_bits |= ~0xffff; + status.joypad2_bits = asr<1>(status.joypad2_bits); } return r; diff --git a/src/lib/libbase.h b/src/lib/libbase.h index 5882ef79..16b0b3aa 100644 --- a/src/lib/libbase.h +++ b/src/lib/libbase.h @@ -1,5 +1,5 @@ /* - libbase : version 0.08a ~byuu (07/14/06) + libbase : version 0.08b ~byuu (07/30/06) */ #ifndef __LIBBASE @@ -100,18 +100,47 @@ enum { b = 1 << (bits - 1), m = (1 << (bits - 1)) - 1 }; return (x > m) ? m : (x < -b) ? -b : x; } -//requires compiler SAR (shift arithmetic right) support template inline signed sclip(const signed x) { -enum { s = sizeof(x) * 8 - bits }; - return (x << s) >> s; +enum { b = 1 << (bits - 1), m = (1 << (bits - 1)) - 1 }; + return (x & b) ? (x | ~m) : (x & m); } -//use this if compiler uses SLR (shift logical right) +//requires compiler arithmetic shift right support +//c++ standard does not define whether >> is arithmetic or logical //template inline signed sclip(const signed x) { -//enum { b = 1 << (bits - 1), m = (1 << (bits - 1)) - 1 }; -// return (x & b) ? (x | ~m) : (x & m); +//enum { s = sizeof(x) * 8 - bits }; +// return (x << s) >> s; //} +template inline T rol(const T x) { +enum { s = (sizeof(T) << 3) - bits }; + return (x << bits) | (x >> s); +} + +template inline T ror(const T x) { +enum { s = (sizeof(T) << 3) - bits }; + return (x >> bits) | (x << s); +} + +template inline T asl(const T x) { + return (x << bits); +} + +template inline T asr(const T x) { +enum { h = 1 << ((sizeof(T) << 3) - 1) }; +enum { m = ~((1 << ((sizeof(T) << 3) - bits)) - 1) }; + return (x >> bits) | ((0 - !!(x & h)) & m); +} + +template inline T lsl(const T x) { + return (x << bits); +} + +template inline T lsr(const T x) { +enum { m = ((1 << ((sizeof(T) << 3) - bits)) - 1) }; + return (x >> bits) & m; +} + template class uint_t { private: base data; diff --git a/src/lib/libco_win32.cpp b/src/lib/libco_win32.cpp index c6fbaf1b..7418d168 100644 --- a/src/lib/libco_win32.cpp +++ b/src/lib/libco_win32.cpp @@ -1,5 +1,5 @@ /* - libco_win32 : version 0.04 ~byuu (05/11/06) + libco_win32 : version 0.06 ~byuu (05/21/06) win32-x86 implementation of libco */ @@ -7,7 +7,7 @@ #define _WIN32_WINNT 0x0400 #include -#include "libco.h" +#include "libco_win32.h" namespace libco_win32 { bool co_enabled = false; @@ -20,16 +20,16 @@ namespace libco_win32 { } }; -extern "C" void co_init() { +void co_init() { if(libco_win32::co_enabled == true)return; libco_win32::co_enabled = true; ConvertThreadToFiber(0); } -extern "C" void co_term() { +void co_term() { /***** -//ConverFiberToThread() only exists in WinXP+ +//ConverFiberToThread() only exists on WinXP+ if(libco_win32::co_enabled == false)return; libco_win32::co_enabled = false; @@ -38,31 +38,31 @@ extern "C" void co_term() { *****/ } -extern "C" thread_t co_active() { +thread_t co_active() { if(libco_win32::co_enabled == false)co_init(); return GetCurrentFiber(); } -extern "C" thread_t co_create(thread_p coentry, unsigned int heapsize) { +thread_t co_create(thread_p coentry, unsigned int heapsize) { if(libco_win32::co_enabled == false)co_init(); return CreateFiber(heapsize, libco_win32::coentry_proc, (void*)coentry); } -extern "C" void co_delete(thread_t cothread) { +void co_delete(thread_t cothread) { DeleteFiber(cothread); } -extern "C" void co_jump(thread_t cothread) { +void co_jump(thread_t cothread) { SwitchToFiber(cothread); } -extern "C" void co_call(thread_t cothread) { +void co_call(thread_t cothread) { libco_win32::co_stack[libco_win32::co_stackptr++] = co_active(); co_jump(cothread); } -extern "C" void co_return() { +void co_return() { co_jump(libco_win32::co_stack[--libco_win32::co_stackptr]); } diff --git a/src/lib/libco_win32.h b/src/lib/libco_win32.h new file mode 100644 index 00000000..8cd9857a --- /dev/null +++ b/src/lib/libco_win32.h @@ -0,0 +1,15 @@ +/* + libco_win32 : version 0.06 ~byuu (05/21/2006) +*/ + +typedef void (*thread_t); +typedef void (*thread_p)(); + +void co_init(); +void co_term(); +thread_t co_active(); +thread_t co_create(thread_p coentry, unsigned int heapsize); +void co_delete(thread_t cothread); +void co_jump(thread_t cothread); +void co_call(thread_t cothread); +void co_return(); diff --git a/src/lib/libkeymap.h b/src/lib/libkeymap.h index 63171f48..af4c68ce 100644 --- a/src/lib/libkeymap.h +++ b/src/lib/libkeymap.h @@ -1,13 +1,17 @@ /* - libkeymap : version 0.01 ~byuu (07/14/06) + libkeymap : version 0.02 ~byuu (07/30/06) */ #ifndef __LIBKEYMAP #define __LIBKEYMAP class keymap { +private: +char tmp[32]; + public: +uint null; uint esc; uint f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12; uint print_screen, scroll_lock, pause; @@ -30,8 +34,14 @@ uint tab, enter, space; uint lctrl, rctrl, lalt, ralt, lshift, rshift; uint lwin, rwin, menu; +struct { + uint up, down, left, right; + uint button[128]; +} joypad[16]; + uint find(const char *key) { #define match(n) if(!strcmp(#n, key))return n; + match(null) match(esc) match(f1) match(f2) match(f3) match(f4) match(f5) match(f6) match(f7) match(f8) match(f9) match(f10) match(f11) match(f12) @@ -62,10 +72,32 @@ uint lwin, rwin, menu; match(ralt) match(lshift) match(rshift) match(lwin) match(rwin) match(menu) #undef match + + if(!memcmp(key, "joypad", 6)) { + const char *p = key + 6; + int joy, bn, n; + sscanf(p, "%d%n", &joy, &n); + p += n; + if(*p == '.') { + p++; + if(!strcmp(p, "up")) { return joypad[joy].up; } + if(!strcmp(p, "down")) { return joypad[joy].down; } + if(!strcmp(p, "left")) { return joypad[joy].left; } + if(!strcmp(p, "right")) { return joypad[joy].right; } + if(!memcmp(p, "button", 6)) { + p += 6; + sscanf(p, "%d", &bn); + return joypad[joy].button[bn]; + } + } + } + + return 0; } const char *find(uint key) { #define match(n) if(n == key)return #n; + match(null) match(esc) match(f1) match(f2) match(f3) match(f4) match(f5) match(f6) match(f7) match(f8) match(f9) match(f10) match(f11) match(f12) @@ -96,9 +128,22 @@ uint lwin, rwin, menu; match(ralt) match(lshift) match(rshift) match(lwin) match(rwin) match(menu) #undef match + + for(int joy = 0; joy < 16; joy++) { + if(joypad[joy].up == key) { sprintf(tmp, "joypad%d.up", joy); return tmp; } + if(joypad[joy].down == key) { sprintf(tmp, "joypad%d.down", joy); return tmp; } + if(joypad[joy].left == key) { sprintf(tmp, "joypad%d.left", joy); return tmp; } + if(joypad[joy].right == key) { sprintf(tmp, "joypad%d.right", joy); return tmp; } + for(int bn = 0; bn < 128; bn++) { + if(joypad[joy].button[bn] == key) { sprintf(tmp, "joypad%d.button%d", joy, bn); return tmp; } + } + } + + return "null"; } keymap() { + null = 0; esc = 0; f1 = f2 = f3 = f4 = f5 = f6 = 0; f7 = f8 = f9 = f10 = f11 = f12 = 0; @@ -122,6 +167,14 @@ uint lwin, rwin, menu; tab = enter = space = 0; lctrl = rctrl = lalt = ralt = lshift = rshift = 0; lwin = rwin = menu = 0; + + for(int joy = 0; joy < 16; joy++) { + joypad[joy].up = 0; + joypad[joy].down = 0; + joypad[joy].left = 0; + joypad[joy].right = 0; + memset(joypad[joy].button, 0, sizeof(joypad[joy].button)); + } } }; diff --git a/src/memory/bmemory/bmemory.cpp b/src/memory/bmemory/bmemory.cpp index 449faffd..cc1de1f6 100644 --- a/src/memory/bmemory/bmemory.cpp +++ b/src/memory/bmemory/bmemory.cpp @@ -45,7 +45,7 @@ void bMemBus::load_cart() { cart_map_system(); uint region = read(0xffd9) & 0x7f; - cartridge.info.region = (region == 0 || region == 1 || region == 13) ? Cartridge::NTSC : Cartridge::PAL; + cartridge.info.region = (region <= 1 || region >= 13) ? Cartridge::NTSC : Cartridge::PAL; if(cartridge.info.region == Cartridge::NTSC) { snes->set_region(SNES::NTSC); } else { diff --git a/src/ppu/bppu/bppu.cpp b/src/ppu/bppu/bppu.cpp index dbc974dc..09db2b96 100644 --- a/src/ppu/bppu/bppu.cpp +++ b/src/ppu/bppu/bppu.cpp @@ -18,7 +18,7 @@ void bPPU::scanline() { if(line.y == 1) { //mosaic reset - for(int32 bg = BG1; bg <= BG4; bg++) { + for(int bg = BG1; bg <= BG4; bg++) { regs.bg_y[bg] = 1; } @@ -32,7 +32,7 @@ void bPPU::scanline() { regs.oam_firstsprite = (regs.oam_addr >> 2) & 127; } } else { - for(int32 bg = BG1; bg <= BG4; bg++) { + for(int bg = BG1; bg <= BG4; bg++) { if(!regs.mosaic_enabled[bg] || !regs.mosaic_countdown) { regs.bg_y[bg] = line.y; } @@ -88,25 +88,6 @@ void bPPU::power() { region = snes->region(); - reset(); -} - -void bPPU::reset() { - PPU::reset(); - frame(); - - memset(sprite_list, 0, sizeof(sprite_list)); - -//open bus support - regs.ppu1_mdr = 0xff; - regs.ppu2_mdr = 0xff; - -//bg line counters - regs.bg_y[0] = 0; - regs.bg_y[1] = 0; - regs.bg_y[2] = 0; - regs.bg_y[3] = 0; - //$2100 regs.display_disabled = 0; regs.display_brightness = 0; @@ -135,12 +116,12 @@ void bPPU::reset() { regs.hires = false; //$2106 - regs.mosaic_size = 0; - regs.mosaic_enabled[BG1] = false; - regs.mosaic_enabled[BG2] = false; - regs.mosaic_enabled[BG3] = false; - regs.mosaic_enabled[BG4] = false; - regs.mosaic_countdown = 0; + regs.mosaic_size = 0; + regs.mosaic_enabled[BG1] = false; + regs.mosaic_enabled[BG2] = false; + regs.mosaic_enabled[BG3] = false; + regs.mosaic_enabled[BG4] = false; + regs.mosaic_countdown = 0; //$2107-$210a regs.bg_scaddr[BG1] = 0x0000; @@ -159,7 +140,7 @@ void bPPU::reset() { regs.bg_tdaddr[BG4] = 0x0000; //$210d-$2114 - regs.bg_ofslatch = 0x00; + regs.bg_ofslatch = 0x00; regs.m7_hofs = regs.m7_vofs = 0x0000; regs.bg_hofs[BG1] = regs.bg_vofs[BG1] = 0x0000; regs.bg_hofs[BG2] = regs.bg_vofs[BG2] = 0x0000; @@ -304,7 +285,26 @@ void bPPU::reset() { regs.time_over = false; regs.range_over = false; - line.width = 256; //needed for clear_window_cache() + reset(); +} + +void bPPU::reset() { + PPU::reset(); + frame(); + + memset(sprite_list, 0, sizeof(sprite_list)); + +//open bus support + regs.ppu1_mdr = 0xff; + regs.ppu2_mdr = 0xff; + +//bg line counters + regs.bg_y[0] = 0; + regs.bg_y[1] = 0; + regs.bg_y[2] = 0; + regs.bg_y[3] = 0; + + line.width = 256; clear_tiledata_cache(); } @@ -376,21 +376,21 @@ bPPU::bPPU() { init_tiledata_cache(); - for(int32 l = 0; l < 16; l++) { + for(int l = 0; l < 16; l++) { mosaic_table[l] = (uint16*)malloc(4096 * 2); - for(int32 i = 0; i < 4096; i++) { + for(int i = 0; i < 4096; i++) { mosaic_table[l][i] = (i / (l + 1)) * (l + 1); } } light_table = (uint16*)malloc(16 * 32768 * 2); uint16 *ptr = (uint16*)light_table; - for(int32 l = 0; l < 16; l++) { - int32 r, g, b; + for(int l = 0; l < 16; l++) { + int r, g, b; #if 0 double y, cb, cr; double kr = 0.2126, kb = 0.0722, kg = (1.0 - kr - kb); - for(int32 i = 0; i < 32768; i++) { + for(int i = 0; i < 32768; i++) { if(l == 0) { *ptr++ = 0; continue; } if(l == 15) { *ptr++ = i; continue; } @@ -398,27 +398,27 @@ uint16 *ptr = (uint16*)light_table; g = (i >> 5) & 31; b = (i >> 10) & 31; - y = double(r) * kr + double(g) * kg + double(b) * kb; - cb = (double(b) - y) / (2.0 - 2.0 * kb); - cr = (double(r) - y) / (2.0 - 2.0 * kr); + y = (double)r * kr + (double)g * kg + (double)b * kb; + cb = ((double)b - y) / (2.0 - 2.0 * kb); + cr = ((double)r - y) / (2.0 - 2.0 * kr); - y *= double(l) / 15.0; - cb *= double(l) / 15.0; - cr *= double(l) / 15.0; + y *= (double)l / 15.0; + cb *= (double)l / 15.0; + cr *= (double)l / 15.0; r = y + cr * (2.0 - 2.0 * kr); b = y + cb * (2.0 - 2.0 * kb); g = (y - b * kb - r * kr) / kg; - r = (r > 31) ? 31 : ((r < 0) ? 0 : r); - g = (g > 31) ? 31 : ((g < 0) ? 0 : g); - b = (b > 31) ? 31 : ((b < 0) ? 0 : b); + r = minmax<0, 31>(r); + g = minmax<0, 31>(g); + b = minmax<0, 31>(b); *ptr++ = (r) | (g << 5) | (b << 10); } #else - double m = double(l) / 15.0; - for(int32 i = 0; i < 32768; i++) { + double m = (double)l / 15.0; + for(int i = 0; i < 32768; i++) { if(l == 0) { *ptr++ = 0; continue; } if(l == 15) { *ptr++ = i; continue; } @@ -426,9 +426,9 @@ uint16 *ptr = (uint16*)light_table; g = (i >> 5) & 31; b = (i >> 10) & 31; - r = (int32)(double(r) * m); - g = (int32)(double(g) * m); - b = (int32)(double(b) * m); + r = minmax<0, 31>((int)((double)r * m)); + g = minmax<0, 31>((int)((double)g * m)); + b = minmax<0, 31>((int)((double)b * m)); *ptr++ = (r) | (g << 5) | (b << 10); } diff --git a/src/sdl/Makefile b/src/sdl/Makefile deleted file mode 100644 index c49a9f84..00000000 --- a/src/sdl/Makefile +++ /dev/null @@ -1,120 +0,0 @@ -CC = cc -CXX = c++ -CFLAGS = -O3 -fomit-frame-pointer -ffast-math -CXXFLAGS = $(CFLAGS) -fno-rtti -OBJS = sdlmain.o \ - libstring.o libconfig.o libbpf.o \ - reader.o cart.o \ - memory.o bmemory.o \ - cpu.o bcpu.o \ - apu.o bapu.o \ - bdsp.o \ - ppu.o bppu.o \ - snes.o \ - srtc.o sdd1.o c4.o \ - adler32.o compress.o crc32.o deflate.o gzio.o inffast.o \ - inflate.o inftrees.o ioapi.o trees.o unzip.o zip.o zutil.o \ - jma.o jcrc32.o lzmadec.o 7zlzma.o iiostrm.o inbyte.o lzma.o winout.o - -all: $(OBJS) - $(CXX) $(CXXFLAGS) $(OBJS) `sdl11-config --cflags --libs` -o bsnes_sdl - -clean: - rm *.o - -#################### -### sdl-specific ### -#################### -sdlmain.o: *.cpp *.h - $(CXX) $(CXXFLAGS) -c sdlmain.cpp `sdl11-config --cflags` - -################# -### libraries ### -################# -libstring.o: ../lib/*.cpp ../lib/*.h - $(CXX) $(CXXFLAGS) -c ../lib/libstring.cpp -libconfig.o: ../lib/*.cpp ../lib/*.h - $(CXX) $(CXXFLAGS) -c ../lib/libconfig.cpp -libbpf.o: ../lib/*.cpp ../lib/*.h - $(CXX) $(CXXFLAGS) -c ../lib/libbpf.cpp - -############## -### memory ### -############## -memory.o: ../memory/memory.cpp ../memory/memory.h - $(CXX) $(CXXFLAGS) -c ../memory/memory.cpp - -bmemory.o: ../memory/bmemory/* - $(CXX) $(CXXFLAGS) -c ../memory/bmemory/bmemory.cpp - -########### -### cpu ### -########### -cpu.o: ../cpu/*.cpp ../cpu/*.h - $(CXX) $(CXXFLAGS) -c ../cpu/cpu.cpp - -bcpu.o: ../cpu/bcpu/* - $(CXX) $(CXXFLAGS) -c ../cpu/bcpu/bcpu.cpp - -########### -### apu ### -########### -apu.o: ../apu/* - $(CXX) $(CXXFLAGS) -c ../apu/apu.cpp - -bapu.o: ../apu/bapu/* - $(CXX) $(CXXFLAGS) -c ../apu/bapu/bapu.cpp - -########### -### dsp ### -########### -bdsp.o: ../dsp/bdsp/* - $(CXX) $(CXXFLAGS) -c ../dsp/bdsp/bdsp.cpp - -########### -### ppu ### -########### -ppu.o: ../ppu/*.cpp ../ppu/*.h - $(CXX) $(CXXFLAGS) -c ../ppu/ppu.cpp - -bppu.o: ../ppu/bppu/* - $(CXX) $(CXXFLAGS) -c ../ppu/bppu/bppu.cpp - -################# -### utilities ### -################# -reader.o: ../reader/*.cpp ../reader/*.h - $(CXX) $(CXXFLAGS) -c ../reader/reader.cpp - -cart.o: ../cart/*.cpp ../cart/*.h - $(CXX) $(CXXFLAGS) -c ../cart/cart.cpp - -############ -### snes ### -############ -snes.o: ../snes/*.cpp ../snes/*.h - $(CXX) $(CXXFLAGS) -c ../snes/snes.cpp - -##################### -### special chips ### -##################### -srtc.o: ../chip/srtc/*.cpp ../chip/srtc/*.h - $(CXX) $(CXXFLAGS) -c ../chip/srtc/srtc.cpp - -sdd1.o: ../chip/sdd1/*.cpp ../chip/sdd1/*.h - $(CXX) $(CXXFLAGS) -c ../chip/sdd1/sdd1.cpp - -c4.o: ../chip/c4/*.cpp ../chip/c4/*.h - $(CXX) $(CXXFLAGS) -c ../chip/c4/c4.cpp - -############ -### zlib ### -############ -adler32.o: ../reader/zlib/*.c ../reader/zlib/*.h - $(CC) $(CFLAGS) -c ../reader/zlib/*.c - -########### -### jma ### -########### -jma.o: ../reader/jma/*.cpp ../reader/jma/*.h - $(CXX) $(CXXFLAGS) -c ../reader/jma/*.cpp diff --git a/src/sdl/Makefile.win32 b/src/sdl/Makefile.win32 deleted file mode 100644 index f25aff99..00000000 --- a/src/sdl/Makefile.win32 +++ /dev/null @@ -1,119 +0,0 @@ -CC = cl -CFLAGS = /nologo /O2 /EHsc -OBJS = sdlmain.obj \ - libstring.obj libconfig.obj libbpf.obj \ - reader.obj cart.obj \ - memory.obj bmemory.obj \ - cpu.obj bcpu.obj \ - apu.obj bapu.obj \ - bdsp.obj \ - ppu.obj bppu.obj \ - snes.obj \ - srtc.obj sdd1.obj c4.obj -# adler32.obj compress.obj crc32.obj deflate.obj gzio.obj inffast.obj \ -# inflate.obj inftrees.obj ioapi.obj trees.obj unzip.obj zip.obj zutil.obj \ -# jma.obj jcrc32.obj lzmadec.obj 7zlzma.obj iiostrm.obj inbyte.obj lzma.obj winout.obj -LIBS = kernel32.lib user32.lib gdi32.lib sdlmain.lib sdl.lib - -all: $(OBJS) - $(CC) /Febsnes_sdl.exe $(CFLAGS) $(OBJS) $(LIBS) - -clean: - del *.obj - -#################### -### sdl-specific ### -#################### -sdlmain.obj: *.cpp *.h - $(CC) $(CFLAGS) /c sdlmain.cpp - -################# -### libraries ### -################# -libstring.obj: ../lib/*.cpp ../lib/*.h - $(CC) $(CFLAGS) /c ../lib/libstring.cpp -libconfig.obj: ../lib/*.cpp ../lib/*.h - $(CC) $(CFLAGS) /c ../lib/libconfig.cpp -libbpf.obj: ../lib/*.cpp ../lib/*.h - $(CC) $(CFLAGS) /c ../lib/libbpf.cpp - -############## -### memory ### -############## -memory.obj: ../memory/memory.cpp ../memory/memory.h - $(CC) $(CFLAGS) /c ../memory/memory.cpp - -bmemory.obj: ../memory/bmemory/* - $(CC) $(CFLAGS) /c ../memory/bmemory/bmemory.cpp - -########### -### cpu ### -########### -cpu.obj: ../cpu/*.cpp ../cpu/*.h - $(CC) $(CFLAGS) /c ../cpu/cpu.cpp - -bcpu.obj: ../cpu/bcpu/* - $(CC) $(CFLAGS) /c ../cpu/bcpu/bcpu.cpp - -########### -### apu ### -########### -apu.obj: ../apu/* - $(CC) $(CFLAGS) /c ../apu/apu.cpp - -bapu.obj: ../apu/bapu/* - $(CC) $(CFLAGS) /c ../apu/bapu/bapu.cpp - -########### -### dsp ### -########### -bdsp.obj: ../dsp/bdsp/* - $(CC) $(CFLAGS) /c ../dsp/bdsp/bdsp.cpp - -########### -### ppu ### -########### -ppu.obj: ../ppu/*.cpp ../ppu/*.h - $(CC) $(CFLAGS) /c ../ppu/ppu.cpp - -bppu.obj: ../ppu/bppu/* - $(CC) $(CFLAGS) /c ../ppu/bppu/bppu.cpp - -################# -### utilities ### -################# -reader.obj: ../reader/*.cpp ../reader/*.h - $(CC) $(CFLAGS) /c ../reader/reader.cpp - -cart.obj: ../cart/*.cpp ../cart/*.h - $(CC) $(CFLAGS) /c ../cart/cart.cpp - -############ -### snes ### -############ -snes.obj: ../snes/*.cpp ../snes/*.h - $(CC) $(CFLAGS) /c ../snes/snes.cpp - -##################### -### special chips ### -##################### -srtc.obj: ../chip/srtc/*.cpp ../chip/srtc/*.h - $(CC) $(CFLAGS) /c ../chip/srtc/srtc.cpp - -sdd1.obj: ../chip/sdd1/*.cpp ../chip/sdd1/*.h - $(CC) $(CFLAGS) /c ../chip/sdd1/sdd1.cpp - -c4.obj: ../chip/c4/*.cpp ../chip/c4/*.h - $(CC) $(CFLAGS) /c ../chip/c4/c4.cpp - -############ -### zlib ### -############ -adler32.obj: ../reader/zlib/*.c ../reader/zlib/*.h - $(CC) $(CFLAGS) /c ../reader/zlib/*.c - -########### -### jma ### -########### -jma.obj: ../reader/jma/*.cpp ../reader/jma/*.h - $(CC) $(CFLAGS) /c ../reader/jma/*.cpp diff --git a/src/sdl/bsnes_sdl.cfg b/src/sdl/bsnes_sdl.cfg deleted file mode 100644 index cc1ac3db..00000000 --- a/src/sdl/bsnes_sdl.cfg +++ /dev/null @@ -1,98 +0,0 @@ -# Default path to look for ROM files in ("" = use default directory) -# (default = "") -fs.rom_path = "" - -# Default path for all save RAM files ("" = use current directory) -# (default = "") -fs.sram_path = "" - -# Extension to be used for all save RAM files -# (default = "srm") -fs.sram_ext = "srm" - -# Applies contrast adjust filter to video output when enabled -# Works by lowering the brightness of darker colors, -# while leaving brighter colors alone; thus reducing saturation -# (default = true) -snes.video_color_curve = true - -# Selects color adjustment filter for video output -# 0 = Normal (no filter, rgb555) -# 1 = Grayscale mode (l5) -# 2 = VGA mode (rgb332) -# 3 = Genesis mode (rgb333) -# (default = 0) -snes.video_color_adjust_mode = 0 - -# Mutes SNES audio output when enabled -# (default = false) -snes.mute = true - -# Enable fullscreen mode at startup -# (default = false) -video.fullscreen = false - -# Window / Fullscreen width -# (default = 320) -video.display_width = 320 - -# Window / Fullscreen height -# (default = 240) -video.display_height = 240 - -# SNES video output width -# (default = 256) -video.output_width = 256 - -# SNES video output height -# (default = 223) -video.output_height = 223 - -# Joypad1 up -# (default = 0x111) -input.joypad1.up = 0x111 - -# Joypad1 down -# (default = 0x112) -input.joypad1.down = 0x112 - -# Joypad1 left -# (default = 0x114) -input.joypad1.left = 0x114 - -# Joypad1 right -# (default = 0x113) -input.joypad1.right = 0x113 - -# Joypad1 A -# (default = 0x78) -input.joypad1.a = 0x78 - -# Joypad1 B -# (default = 0x7a) -input.joypad1.b = 0x7a - -# Joypad1 X -# (default = 0x73) -input.joypad1.x = 0x73 - -# Joypad1 Y -# (default = 0x61) -input.joypad1.y = 0x61 - -# Joypad1 L -# (default = 0x64) -input.joypad1.l = 0x64 - -# Joypad1 R -# (default = 0x63) -input.joypad1.r = 0x63 - -# Joypad1 select -# (default = 0x12f) -input.joypad1.select = 0x12f - -# Joypad1 start -# (default = 0xd) -input.joypad1.start = 0xd - diff --git a/src/sdl/cc.bat b/src/sdl/cc.bat deleted file mode 100644 index cc1ab957..00000000 --- a/src/sdl/cc.bat +++ /dev/null @@ -1,2 +0,0 @@ -@nmake /NOLOGO /f Makefile.win32 -@pause \ No newline at end of file diff --git a/src/sdl/clean.bat b/src/sdl/clean.bat deleted file mode 100644 index 74d64470..00000000 --- a/src/sdl/clean.bat +++ /dev/null @@ -1,3 +0,0 @@ -@nmake /NOLOGO /f Makefile.win32 clean -@del output.wav -@del bsnes_sdl.exe diff --git a/src/sdl/config.cpp b/src/sdl/config.cpp deleted file mode 100644 index 163d3646..00000000 --- a/src/sdl/config.cpp +++ /dev/null @@ -1,32 +0,0 @@ -namespace config { - -struct Video { - static Setting fullscreen; - static Setting display_width, display_height; - static Setting output_width, output_height; -} video; -Setting Video::fullscreen(&config_file, "video.fullscreen", "Enable fullscreen mode at startup", false, Setting::TRUE_FALSE); -Setting Video::display_width (&config_file, "video.display_width", "Window / Fullscreen width", 320, Setting::DEC); -Setting Video::display_height(&config_file, "video.display_height", "Window / Fullscreen height", 240, Setting::DEC); -Setting Video::output_width (&config_file, "video.output_width", "SNES video output width", 256, Setting::DEC); -Setting Video::output_height (&config_file, "video.output_height", "SNES video output height", 223, Setting::DEC); - -struct Input { - struct Joypad { - static Setting up, down, left, right, a, b, x, y, l, r, select, start; - } joypad1; -} input; -Setting Input::Joypad::up (&config_file, "input.joypad1.up", "Joypad1 up", SDLK_UP, Setting::HEX); -Setting Input::Joypad::down (&config_file, "input.joypad1.down", "Joypad1 down", SDLK_DOWN, Setting::HEX); -Setting Input::Joypad::left (&config_file, "input.joypad1.left", "Joypad1 left", SDLK_LEFT, Setting::HEX); -Setting Input::Joypad::right (&config_file, "input.joypad1.right", "Joypad1 right", SDLK_RIGHT, Setting::HEX); -Setting Input::Joypad::a (&config_file, "input.joypad1.a", "Joypad1 A", SDLK_x, Setting::HEX); -Setting Input::Joypad::b (&config_file, "input.joypad1.b", "Joypad1 B", SDLK_z, Setting::HEX); -Setting Input::Joypad::x (&config_file, "input.joypad1.x", "Joypad1 X", SDLK_s, Setting::HEX); -Setting Input::Joypad::y (&config_file, "input.joypad1.y", "Joypad1 Y", SDLK_a, Setting::HEX); -Setting Input::Joypad::l (&config_file, "input.joypad1.l", "Joypad1 L", SDLK_d, Setting::HEX); -Setting Input::Joypad::r (&config_file, "input.joypad1.r", "Joypad1 R", SDLK_c, Setting::HEX); -Setting Input::Joypad::select(&config_file, "input.joypad1.select", "Joypad1 select", SDLK_RSHIFT, Setting::HEX); -Setting Input::Joypad::start (&config_file, "input.joypad1.start", "Joypad1 start", SDLK_RETURN, Setting::HEX); - -}; diff --git a/src/sdl/render.cpp b/src/sdl/render.cpp deleted file mode 100644 index df8a53e3..00000000 --- a/src/sdl/render.cpp +++ /dev/null @@ -1,17 +0,0 @@ -void render() { -SNES::video_info vi; - snes->get_video_info(&vi); - - screen_info.rs.x = 0; - screen_info.rs.y = (vi.height == 224) ? 1 : 2; - screen_info.rs.w = vi.width; - screen_info.rs.h = (vi.height == 224) ? 223 : 446; - -//documentation says not to use this, but it's rather ridiculous that a graphics -//library wouldn't support simple image scaling... so let's use it anyway and see -//what happens... -//SDL_SoftStretch(backbuffer, &screen_info.rs, screen, &screen_info.rd); - SDL_BlitSurface(backbuffer, &screen_info.rs, screen, &screen_info.rd); - - SDL_UpdateRect(screen, screen_info.rd.x, screen_info.rd.y, screen_info.rd.w, screen_info.rd.h); -} diff --git a/src/sdl/sdlmain.h b/src/sdl/sdlmain.h deleted file mode 100644 index 668c2c8f..00000000 --- a/src/sdl/sdlmain.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifdef _WIN32_ -#include -#include -#else -#include "SDL.h" -#endif - -SDL_Surface *screen, *backbuffer; - -struct { - SDL_Rect rs, rd; -} screen_info; diff --git a/src/sdl/sdlrun.bat b/src/sdl/sdlrun.bat deleted file mode 100644 index aa59b644..00000000 --- a/src/sdl/sdlrun.bat +++ /dev/null @@ -1 +0,0 @@ -bsnes_sdl c:\root\bsnes_testrom\zelda_us.smc diff --git a/src/snes/video/filter.h b/src/snes/video/filter.h index cfde9a84..a8f2c2ce 100644 --- a/src/snes/video/filter.h +++ b/src/snes/video/filter.h @@ -25,7 +25,7 @@ public: */ virtual void run(uint32 *colortbl, uint16 *data, uint32 width, uint32 height, uint32 pitch, uint16 *output, uint32 max_width, uint32 max_height, uint32 output_pitch, - uint32 req_width, uint32 req_height, uint32 &result_width, uint32 &result_height, uint16 *scanline_widths = 0) = 0; + uint32 req_width, uint32 req_height, uint &result_width, uint &result_height, uint16 *scanline_widths = 0) = 0; virtual ~VideoFilter() {} }; diff --git a/src/snes/video/filter_direct.cpp b/src/snes/video/filter_direct.cpp index 36e587bf..bf3f2d1e 100644 --- a/src/snes/video/filter_direct.cpp +++ b/src/snes/video/filter_direct.cpp @@ -1,7 +1,7 @@ void DirectVideoFilter::run( uint32 *colortbl, uint16 *data, uint32 width, uint32 height, uint32 pitch, uint16 *output, uint32 max_width, uint32 max_height, uint32 output_pitch, -uint32 req_width, uint32 req_height, uint32 &result_width, uint32 &result_height, +uint32 req_width, uint32 req_height, uint &result_width, uint &result_height, uint16 *scanline_widths ) { pitch >>= 1; diff --git a/src/snes/video/filter_direct.h b/src/snes/video/filter_direct.h index 03e93fdb..97c76299 100644 --- a/src/snes/video/filter_direct.h +++ b/src/snes/video/filter_direct.h @@ -2,5 +2,5 @@ class DirectVideoFilter : public VideoFilter { public: void run(uint32 *colortbl, uint16 *data, uint32 width, uint32 height, uint32 pitch, uint16 *output, uint32 max_width, uint32 max_height, uint32 output_pitch, - uint32 req_width, uint32 req_height, uint32 &result_width, uint32 &result_height, uint16 *scanline_widths = 0); + uint32 req_width, uint32 req_height, uint &result_width, uint &result_height, uint16 *scanline_widths = 0); }; diff --git a/src/snes/video/filter_hq2x.cpp b/src/snes/video/filter_hq2x.cpp index cc99eb55..5688fc22 100644 --- a/src/snes/video/filter_hq2x.cpp +++ b/src/snes/video/filter_hq2x.cpp @@ -64,7 +64,7 @@ static uint16 blend10(uint32 c1, uint32 c2, uint32 c3) { void HQ2xVideoFilter::run( uint32 *colortbl, uint16 *data, uint32 width, uint32 height, uint32 pitch, uint16 *output, uint32 max_width, uint32 max_height, uint32 output_pitch, -uint32 req_width, uint32 req_height, uint32 &result_width, uint32 &result_height, +uint32 req_width, uint32 req_height, uint &result_width, uint &result_height, uint16 *scanline_widths ) { pitch >>= 1; diff --git a/src/snes/video/filter_hq2x.h b/src/snes/video/filter_hq2x.h index dd657cf0..32419131 100644 --- a/src/snes/video/filter_hq2x.h +++ b/src/snes/video/filter_hq2x.h @@ -4,7 +4,7 @@ uint32 yuvtable[32768]; uint32 diff_offset, diff_mask; void run(uint32 *colortbl, uint16 *data, uint32 width, uint32 height, uint32 pitch, uint16 *output, uint32 max_width, uint32 max_height, uint32 output_pitch, - uint32 req_width, uint32 req_height, uint32 &result_width, uint32 &result_height, uint16 *scanline_widths = 0); + uint32 req_width, uint32 req_height, uint &result_width, uint &result_height, uint16 *scanline_widths = 0); void lores_progressive(uint32 *colortbl, uint16 *data, uint32 height, uint32 pitch, uint16 *output, uint32 output_pitch); diff --git a/src/snes/video/filter_ntsc.cpp b/src/snes/video/filter_ntsc.cpp index d38edd5b..5a136eae 100644 --- a/src/snes/video/filter_ntsc.cpp +++ b/src/snes/video/filter_ntsc.cpp @@ -40,7 +40,7 @@ snes_ntsc_setup_t setup = defaults; void NtscVideoFilter::run( uint32 *colortbl, uint16 *data, uint32 width, uint32 height, uint32 pitch, uint16 *output, uint32 max_width, uint32 max_height, uint32 output_pitch, -uint32 req_width, uint32 req_height, uint32 &result_width, uint32 &result_height, +uint32 req_width, uint32 req_height, uint &result_width, uint &result_height, uint16 *scanline_widths) { if(!ntsc)return; diff --git a/src/snes/video/filter_ntsc.h b/src/snes/video/filter_ntsc.h index dd31cb2f..a25af470 100644 --- a/src/snes/video/filter_ntsc.h +++ b/src/snes/video/filter_ntsc.h @@ -16,7 +16,7 @@ public: // where 0 < i < height void run(uint32 *colortbl, uint16 *data, uint32 width, uint32 height, uint32 pitch, uint16 *output, uint32 max_width, uint32 max_height, uint32 output_pitch, - uint32 req_width, uint32 req_height, uint32 &result_width, uint32 &result_height, + uint32 req_width, uint32 req_height, uint &result_width, uint &result_height, uint16 *scanline_widths = 0); NtscVideoFilter(); diff --git a/src/snes/video/filter_scale2x.cpp b/src/snes/video/filter_scale2x.cpp index d52666a2..47f9aa0b 100644 --- a/src/snes/video/filter_scale2x.cpp +++ b/src/snes/video/filter_scale2x.cpp @@ -1,7 +1,7 @@ void Scale2xVideoFilter::run( uint32 *colortbl, uint16 *data, uint32 width, uint32 height, uint32 pitch, uint16 *output, uint32 max_width, uint32 max_height, uint32 output_pitch, -uint32 req_width, uint32 req_height, uint32 &result_width, uint32 &result_height, +uint32 req_width, uint32 req_height, uint &result_width, uint &result_height, uint16 *scanline_widths ) { pitch >>= 1; diff --git a/src/snes/video/filter_scale2x.h b/src/snes/video/filter_scale2x.h index c2bfbe39..dd338f54 100644 --- a/src/snes/video/filter_scale2x.h +++ b/src/snes/video/filter_scale2x.h @@ -2,7 +2,7 @@ class Scale2xVideoFilter : public VideoFilter { public: void run(uint32 *colortbl, uint16 *data, uint32 width, uint32 height, uint32 pitch, uint16 *output, uint32 max_width, uint32 max_height, uint32 output_pitch, - uint32 req_width, uint32 req_height, uint32 &result_width, uint32 &result_height, uint16 *scanline_widths = 0); + uint32 req_width, uint32 req_height, uint &result_width, uint &result_height, uint16 *scanline_widths = 0); void lores_progressive(uint32 *colortbl, uint16 *data, uint32 height, uint32 pitch, uint16 *output, uint32 output_pitch); diff --git a/src/snes/video/video.cpp b/src/snes/video/video.cpp index d2cbcfeb..c38583b0 100644 --- a/src/snes/video/video.cpp +++ b/src/snes/video/video.cpp @@ -1,8 +1,9 @@ -void SNES::set_video_format(uint32 filter, uint32 pixel_format) { +void SNES::set_video_format(uint filter, uint video_standard, uint pixel_format) { //only make changes at the start of a new frame - video_format.filter = filter; - video_format.pixel_format = pixel_format; - video_format.modified = true; + video_format.filter = filter; + video_format.video_standard = video_standard; + video_format.pixel_format = pixel_format; + video_format.modified = true; } /***** @@ -23,26 +24,42 @@ void SNES::update_video_format() { case VIDEOFILTER_SCALE2X: video_filter = new Scale2xVideoFilter(); break; } - video.pixel_format = video_format.pixel_format; + video.video_standard = video_format.video_standard; + video.pixel_format = video_format.pixel_format; update_color_lookup_table(); } void SNES::get_video_info(video_info *info) { - info->filter = video.filter; - info->pixel_format = video.pixel_format; - info->width = video.width; - info->height = video.height; + info->filter = video.filter; + info->video_standard = video.video_standard; + info->pixel_format = video.pixel_format; + info->width = video.width; + info->height = video.height; } void SNES::video_update() { if(r_ppu->renderer_enabled()) { update_video_format(); - video.ppu_data = (uint16*)r_ppu->output + (int(r_cpu->overscan()) << 13) + 1024; + video.ppu_data = (uint16*)r_ppu->output; // video_normalize(); - video.raster_width = (video.frame_hires == false) ? 256 : 512; - video.raster_height = (video.frame_interlace == false) ? 224 : 448; + switch(video.video_standard) { + default: + case VIDEOSTANDARD_NTSC: + video.raster_width = 256; + video.raster_height = 224; + video.ppu_data += (int(r_cpu->overscan()) << 13) + 1024; + break; + case VIDEOSTANDARD_PAL: + video.raster_width = 256; + video.raster_height = 239; + video.ppu_data += 1024; + break; + } + + if(video.frame_hires) { video.raster_width <<= 1; } + if(video.frame_interlace) { video.raster_height <<= 1; } video.data = (uint16*)video_lock(video.pitch); if(video.data) { @@ -64,7 +81,7 @@ void SNES::video_update() { void SNES::video_scanline() { int y = r_cpu->vcounter(); -int o = int(r_cpu->overscan()) << 3; +int o = (video.video_standard == VIDEOSTANDARD_NTSC) ? (int(r_cpu->overscan()) << 3) : 0; if(y <= (0 + o) || y >= (225 + o))return; y -= o; @@ -86,6 +103,6 @@ void SNES::video_init() { video.raster_data = (uint16*)malloc(512 * 480 * sizeof(uint16)); memset(video.raster_data, 0, 512 * 480 * sizeof(uint16)); video_filter = 0; - set_video_format(VIDEOFILTER_DIRECT, PIXELFORMAT_RGB565); + set_video_format(VIDEOFILTER_DIRECT, VIDEOSTANDARD_NTSC, PIXELFORMAT_RGB565); update_video_format(); } diff --git a/src/snes/video/video.h b/src/snes/video/video.h index 04100a5e..3988a1f5 100644 --- a/src/snes/video/video.h +++ b/src/snes/video/video.h @@ -1,3 +1,8 @@ +enum { + VIDEOSTANDARD_NTSC, + VIDEOSTANDARD_PAL, +}; + enum { PIXELFORMAT_RGB444, PIXELFORMAT_RGB555, @@ -17,23 +22,23 @@ uint32 color_lookup_table[32768]; struct { uint16 *data, *raster_data, *ppu_data; - uint32 raster_width, raster_height; - uint32 width, height; - uint32 filter, pixel_format; - uint32 pitch; + uint raster_width, raster_height; + uint width, height; + uint filter, video_standard, pixel_format; + uint pitch; bool frame_hires, frame_interlace; } video; struct { - bool modified; - uint32 filter, pixel_format; + bool modified; + uint filter, video_standard, pixel_format; } video_format; uint16 pline_width[240], iline_width[480]; struct video_info { - uint32 filter, pixel_format, width, height; + uint filter, video_standard, pixel_format, width, height; }; void contrast_adjust(int32 &input); @@ -42,10 +47,10 @@ struct video_info { //public functions void update_color_lookup_table(); - virtual void set_video_format(uint32 filter, uint32 pixel_format); + virtual void set_video_format(uint filter, uint video_standard, uint pixel_format); virtual void get_video_info(video_info *info); virtual void video_run() = 0; - virtual uint16 *video_lock(uint32 &pitch) = 0; + virtual uint16 *video_lock(uint &pitch) = 0; virtual void video_unlock() = 0; //private functions diff --git a/src/ui/Makefile b/src/ui/Makefile index 906ed8cb..0f9115ba 100644 --- a/src/ui/Makefile +++ b/src/ui/Makefile @@ -4,7 +4,7 @@ CXX = cl AS = nasm RM = del OBJ = obj -CFLAGS = /nologo /O2 /arch:SSE2 /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 +CFLAGS = /nologo /O2 /MD /arch:SSE2 /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 COMPILE = $(CC) $(CFLAGS) /c ASSEMBLE = $(AS) -f win32 LINK = @@ -18,7 +18,7 @@ CXX = cl AS = nasm RM = del OBJ = obj -CFLAGS = /nologo /O2 /GL /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 +CFLAGS = /nologo /O2 /MD /GL /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 COMPILE = $(CC) $(CFLAGS) /c ASSEMBLE = $(AS) -f win32 LINK = /link /LTCG @@ -32,7 +32,7 @@ CXX = cl AS = nasm RM = del OBJ = obj -CFLAGS = /nologo /O2 /GL /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 +CFLAGS = /nologo /O2 /MD /GL /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 COMPILE = $(CC) $(CFLAGS) /c ASSEMBLE = $(AS) -f win32 LINK = /link /PGD:bsnes.pgd /LTCG:PGINSTRUMENT @@ -46,7 +46,7 @@ CXX = cl AS = nasm RM = del OBJ = obj -CFLAGS = /nologo /O2 /arch:SSE2 /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 +CFLAGS = /nologo /O2 /MD /arch:SSE2 /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 COMPILE = $(CC) $(CFLAGS) /c ASSEMBLE = $(AS) -f win32 LINK = /link /PGD:bsnes.pgd /LTCG:PGOPTIMIZE @@ -54,6 +54,20 @@ LIBS = kernel32.lib user32.lib gdi32.lib winmm.lib comdlg32.lib comctl32.lib \ d3d9.lib d3dx9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib endif +ifeq ($(PLATFORM),win-visualc-sdl) +CC = cl +CXX = cl +AS = nasm +RM = del +OBJ = obj +CFLAGS = /nologo /O2 /MD /DPLATFORM_SDL /DCOMPILER_VISUALC /DPROCESSOR_X86 +COMPILE = $(CC) $(CFLAGS) /c +ASSEMBLE = $(AS) -f win32 +LINK = +LIBS = kernel32.lib user32.lib gdi32.lib winmm.lib comdlg32.lib comctl32.lib \ + sdlmain.lib sdl.lib +endif + OBJS = main.$(OBJ) \ libco.$(OBJ) libstring.$(OBJ) libconfig.$(OBJ) \ reader.$(OBJ) cart.$(OBJ) cheat.$(OBJ) \ @@ -71,6 +85,7 @@ OBJS = main.$(OBJ) \ all: $(OBJS) rc /r /fobsnes.res bsnes.rc $(CC) /Febsnes.exe $(CFLAGS) $(OBJS) bsnes.res $(LIBS) $(LINK) + mt -nologo -manifest bsnes.exe.manifest -outputresource:bsnes.exe;1 clean: $(RM) *.$(OBJ) @@ -79,6 +94,7 @@ clean: $(RM) *.pgc $(RM) *.ilk $(RM) *.pdb + $(RM) *.manifest ######################### ### platform-specific ### @@ -91,6 +107,7 @@ main.$(OBJ): *.cpp *.h video/* audio/* input/* ../config/* win/* win/settings/* ################# libco.$(OBJ): ../lib/* $(ASSEMBLE) -o libco.$(OBJ) ../lib/libco_x86.asm +# $(COMPILE) /Folibco.obj ../lib/libco_win32.cpp libstring.$(OBJ): ../lib/*.cpp ../lib/*.h $(COMPILE) ../lib/libstring.cpp diff --git a/src/ui/audio/audio.h b/src/ui/audio/audio.h index 7089e2df..98033921 100644 --- a/src/ui/audio/audio.h +++ b/src/ui/audio/audio.h @@ -7,5 +7,5 @@ uint frequency; virtual void init() = 0; virtual void term() = 0; - Audio() { frequency = 32000; } + Audio() : frequency(32000) {} } *uiAudio; diff --git a/src/ui/config.cpp b/src/ui/config.cpp index 34e49f95..ae2372cc 100644 --- a/src/ui/config.cpp +++ b/src/ui/config.cpp @@ -107,9 +107,9 @@ Setting Input::Joypad1::start (0, "input.joypad1.start", "", 0, Setting::HEX); Setting Input::Joypad1::map(&config_file, "input.joypad1.map", "Joypad 1 button map\n" "Format: Up; Down; Left; Right; A; B; X; Y; L; R; Select; Start", - "up | joy0.up; down | joy0.down; left | joy0.left; right | joy0.right; " - "x | joy0.button4; z | joy0.button3; s | joy0.button1; a | joy0.button0; " - "d | joy0.button6; c | joy0.button7; rshift | joy0.button2; enter | joy0.button5"); + "up | joypad0.up; " "down | joypad0.down; " "left | joypad0.left; " "right | joypad0.right; " + "x | joypad0.button3; " "z | joypad0.button2; " "s | joypad0.button1; " "a | joypad0.button0; " + "d | joypad0.button6; " "c | joypad0.button7; " "rshift | joypad0.button4; " "enter | joypad0.button5"); // @@ -131,8 +131,8 @@ Setting Input::Joypad2::start (0, "input.joypad2.start", "", 0, Setting::HEX); Setting Input::Joypad2::map(&config_file, "input.joypad2.map", "Joypad 2 button map\n" "Format: Up; Down; Left; Right; A; B; X; Y; L; R; Select; Start", - "t | joy1.up; g | joy1.down; f | joy1.left; h | joy1.right; " - "k | joy1.button4; j | joy1.button3; i | joy1.button1; u | joy1.button0; " - "o | joy1.button6; l | joy1.button7; lbracket | joy1.button2; rbracket | joy1.button5"); + "t | joypad1.up; " "g | joypad1.down; " "f | joypad1.left; " "h | joypad1.right; " + "k | joypad1.button3; " "j | joypad1.button2; " "i | joypad1.button1; " "u | joypad1.button0; " + "o | joypad1.button6; " "l | joypad1.button7; " "lbracket | joypad1.button4; " "rbracket | joypad1.button5"); }; diff --git a/src/ui/input/dinput.cpp b/src/ui/input/dinput.cpp index 4727f04c..cbe99806 100644 --- a/src/ui/input/dinput.cpp +++ b/src/ui/input/dinput.cpp @@ -1,16 +1,24 @@ +void InputDI::poll(uint8 device) { + if(wMain.hwnd != GetForegroundWindow()) { + clear_input(); + return; + } + Input::poll(device); +} + void InputDI::poll() { HRESULT hr; DIJOYSTATE2 js; - memset(keystate, 0, 256); + memset(keystate, 0, sizeof(keystate)); + if(di_key) { hr = di_key->GetDeviceState(256, keystate); if(FAILED(hr)) { di_key->Acquire(); - di_key->GetDeviceState(256, keystate); + hr = di_key->GetDeviceState(256, keystate); } } - memset(joystate, 0, INPUT_JOYMAX * 256); for(int i = 0; i < di_joy_count; i++) { if(!di_joy[i])continue; @@ -23,178 +31,30 @@ DIJOYSTATE2 js; } di_joy[i]->GetDeviceState(sizeof(DIJOYSTATE2), &js); - uint32 index = i * 256; //joypad index - memcpy(joystate + index, js.rgbButtons, 128); - //map d-pad axes to joystate[index + {128 - 131}] - int32 resistance = config::input.axis_resistance; + uint index = 0x100 + i * 128; //joypad index + memcpy(keystate + index, js.rgbButtons, 124); + + //map d-pad axes to keystate[index + {124 - 127}] + int resistance = config::input.axis_resistance; if(resistance < 1)resistance = 1; if(resistance > 99)resistance = 99; resistance = int32(double(resistance) * 32768.0 / 100.0); - int32 resistance_lo = 0x7fff - resistance; - int32 resistance_hi = 0x8000 + resistance; - joystate[index + 128] = (js.lY <= resistance_lo) ? 0x80 : 0x00; - joystate[index + 129] = (js.lY >= resistance_hi) ? 0x80 : 0x00; - joystate[index + 130] = (js.lX <= resistance_lo) ? 0x80 : 0x00; - joystate[index + 131] = (js.lX >= resistance_hi) ? 0x80 : 0x00; + int resistance_lo = 0x7fff - resistance; + int resistance_hi = 0x8000 + resistance; + keystate[index + 124] = (js.lY <= resistance_lo) ? 0x80 : 0x00; + keystate[index + 125] = (js.lY >= resistance_hi) ? 0x80 : 0x00; + keystate[index + 126] = (js.lX <= resistance_lo) ? 0x80 : 0x00; + keystate[index + 127] = (js.lX >= resistance_hi) ? 0x80 : 0x00; //map analog POV (analog directional pad) as well - uint32 pov = js.rgdwPOV[0]; - joystate[index + 128] |= (pov == 0 || pov == 31500 || pov == 4500) ? 0x80 : 0x00; - joystate[index + 129] |= (pov == 18000 || pov == 13500 || pov == 22500) ? 0x80 : 0x00; - joystate[index + 130] |= (pov == 27000 || pov == 22500 || pov == 31500) ? 0x80 : 0x00; - joystate[index + 131] |= (pov == 9000 || pov == 4500 || pov == 13500) ? 0x80 : 0x00; + uint pov = js.rgdwPOV[0]; + keystate[index + 124] |= (pov == 0 || pov == 31500 || pov == 4500) ? 0x80 : 0x00; + keystate[index + 125] |= (pov == 18000 || pov == 13500 || pov == 22500) ? 0x80 : 0x00; + keystate[index + 126] |= (pov == 27000 || pov == 22500 || pov == 31500) ? 0x80 : 0x00; + keystate[index + 127] |= (pov == 9000 || pov == 4500 || pov == 13500) ? 0x80 : 0x00; } } -bool InputDI::button_down(uint32 r) { - if((r & JOYMASK) != JOY_NONE) { - uint8 joynum = (r >> 16) & 0xff; - joynum %= INPUT_JOYMAX; - if(joystate[(joynum * 256) + ((r >> 8) & 0xff)] & 0x80) { - return true; - } - } - - if((r & KEYMASK) != KEY_NONE) { - //keypad value defined - if(keystate[r & 0xff] & 0x80) { - return true; - } - } - - return false; -} - -void InputDI::poll(uint8 type) { - poll(); - -HWND fw = GetForegroundWindow(); -#define poll_key(__key) \ - __key = (fw == wMain.hwnd) ? button_down(uint32(config::input.__key)) : 0 - - switch(type) { - case SNES::DEV_JOYPAD1: - poll_key(joypad1.up); - poll_key(joypad1.down); - poll_key(joypad1.left); - poll_key(joypad1.right); - poll_key(joypad1.a); - poll_key(joypad1.b); - poll_key(joypad1.x); - poll_key(joypad1.y); - poll_key(joypad1.l); - poll_key(joypad1.r); - poll_key(joypad1.select); - poll_key(joypad1.start); - break; - case SNES::DEV_JOYPAD2: - poll_key(joypad2.up); - poll_key(joypad2.down); - poll_key(joypad2.left); - poll_key(joypad2.right); - poll_key(joypad2.a); - poll_key(joypad2.b); - poll_key(joypad2.x); - poll_key(joypad2.y); - poll_key(joypad2.l); - poll_key(joypad2.r); - poll_key(joypad2.select); - poll_key(joypad2.start); - break; - } - -#undef poll_key -} - -bool InputDI::get_status(uint8 device, uint8 button) { - switch(device) { - case SNES::DEV_JOYPAD1: - switch(button) { - case SNES::JOYPAD_UP: return joypad1.up; - case SNES::JOYPAD_DOWN: return joypad1.down; - case SNES::JOYPAD_LEFT: return joypad1.left; - case SNES::JOYPAD_RIGHT: return joypad1.right; - case SNES::JOYPAD_A: return joypad1.a; - case SNES::JOYPAD_B: return joypad1.b; - case SNES::JOYPAD_X: return joypad1.x; - case SNES::JOYPAD_Y: return joypad1.y; - case SNES::JOYPAD_L: return joypad1.l; - case SNES::JOYPAD_R: return joypad1.r; - case SNES::JOYPAD_SELECT: return joypad1.select; - case SNES::JOYPAD_START: return joypad1.start; - } - break; - case SNES::DEV_JOYPAD2: - switch(button) { - case SNES::JOYPAD_UP: return joypad2.up; - case SNES::JOYPAD_DOWN: return joypad2.down; - case SNES::JOYPAD_LEFT: return joypad2.left; - case SNES::JOYPAD_RIGHT: return joypad2.right; - case SNES::JOYPAD_A: return joypad2.a; - case SNES::JOYPAD_B: return joypad2.b; - case SNES::JOYPAD_X: return joypad2.x; - case SNES::JOYPAD_Y: return joypad2.y; - case SNES::JOYPAD_L: return joypad2.l; - case SNES::JOYPAD_R: return joypad2.r; - case SNES::JOYPAD_SELECT: return joypad2.select; - case SNES::JOYPAD_START: return joypad2.start; - } - break; - } - - return false; -} - -void InputDI::set_status(uint8 device, uint8 button, bool status) { - switch(device) { - case SNES::DEV_JOYPAD1: - switch(button) { - case SNES::JOYPAD_UP: joypad1.up = status; break; - case SNES::JOYPAD_DOWN: joypad1.down = status; break; - case SNES::JOYPAD_LEFT: joypad1.left = status; break; - case SNES::JOYPAD_RIGHT: joypad1.right = status; break; - case SNES::JOYPAD_A: joypad1.a = status; break; - case SNES::JOYPAD_B: joypad1.b = status; break; - case SNES::JOYPAD_X: joypad1.x = status; break; - case SNES::JOYPAD_Y: joypad1.y = status; break; - case SNES::JOYPAD_L: joypad1.l = status; break; - 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; - case SNES::DEV_JOYPAD2: - switch(button) { - case SNES::JOYPAD_UP: joypad2.up = status; break; - case SNES::JOYPAD_DOWN: joypad2.down = status; break; - case SNES::JOYPAD_LEFT: joypad2.left = status; break; - case SNES::JOYPAD_RIGHT: joypad2.right = status; break; - case SNES::JOYPAD_A: joypad2.a = status; break; - case SNES::JOYPAD_B: joypad2.b = status; break; - case SNES::JOYPAD_X: joypad2.x = status; break; - case SNES::JOYPAD_Y: joypad2.y = status; break; - case SNES::JOYPAD_L: joypad2.l = status; break; - 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; - } -} - -void InputDI::clear_input() { - joypad1.up = joypad2.up = - joypad1.down = joypad2.down = - joypad1.left = joypad2.left = - joypad1.right = joypad2.right = - joypad1.a = joypad2.a = - joypad1.b = joypad2.b = - joypad1.x = joypad2.x = - joypad1.y = joypad2.y = - joypad1.l = joypad2.l = - joypad1.r = joypad2.r = - joypad1.select = joypad2.select = - joypad1.start = joypad2.start = false; -} - BOOL CALLBACK DI_EnumJoypadsCallback(const DIDEVICEINSTANCE *instance, void *context) { return static_cast(uiInput)->enum_joypads(instance); } diff --git a/src/ui/input/dinput.h b/src/ui/input/dinput.h index 4c75319a..74c02538 100644 --- a/src/ui/input/dinput.h +++ b/src/ui/input/dinput.h @@ -7,23 +7,13 @@ LPDIRECTINPUT8 di; LPDIRECTINPUTDEVICE8 di_key, di_joy[INPUT_JOYMAX]; uint32 di_joy_count; -struct joypad { - bool up, down, left, right; - bool a, b, x, y, l, r; - bool select, start; -} joypad1, joypad2; - void poll(); - bool button_down(uint32 r); - - void poll(uint8 type); - bool get_status(uint8 device, uint8 button); - void set_status(uint8 device, uint8 button, bool status); - void clear_input(); - bool enum_joypads(const DIDEVICEINSTANCE *instance); + void poll(uint8 device); void init(); void term(); + bool enum_joypads(const DIDEVICEINSTANCE *instance); + InputDI() { di = 0; di_key = 0; diff --git a/src/ui/input/dinput_keymap.cpp b/src/ui/input/dinput_keymap.cpp index a9511388..994b41e8 100644 --- a/src/ui/input/dinput_keymap.cpp +++ b/src/ui/input/dinput_keymap.cpp @@ -1,117 +1,127 @@ -keymap.esc = 0x01; +key.esc = 0x01; -keymap.f1 = 0x3b; -keymap.f2 = 0x3c; -keymap.f3 = 0x3d; -keymap.f4 = 0x3e; -keymap.f5 = 0x3f; -keymap.f6 = 0x40; -keymap.f7 = 0x41; -keymap.f8 = 0x42; -keymap.f9 = 0x43; -keymap.f10 = 0x44; -keymap.f11 = 0x57; -keymap.f12 = 0x58; +key.f1 = 0x3b; +key.f2 = 0x3c; +key.f3 = 0x3d; +key.f4 = 0x3e; +key.f5 = 0x3f; +key.f6 = 0x40; +key.f7 = 0x41; +key.f8 = 0x42; +key.f9 = 0x43; +key.f10 = 0x44; +key.f11 = 0x57; +key.f12 = 0x58; -keymap.print_screen = 0xb7; -keymap.scroll_lock = 0x46; -keymap.pause = 0xc5; +key.print_screen = 0xb7; +key.scroll_lock = 0x46; +key.pause = 0xc5; -keymap.tilde = 0x29; +key.tilde = 0x29; -keymap.num_0 = 0x0b; -keymap.num_1 = 0x02; -keymap.num_2 = 0x03; -keymap.num_3 = 0x04; -keymap.num_4 = 0x05; -keymap.num_5 = 0x06; -keymap.num_6 = 0x07; -keymap.num_7 = 0x08; -keymap.num_8 = 0x09; -keymap.num_9 = 0x0a; +key.num_0 = 0x0b; +key.num_1 = 0x02; +key.num_2 = 0x03; +key.num_3 = 0x04; +key.num_4 = 0x05; +key.num_5 = 0x06; +key.num_6 = 0x07; +key.num_7 = 0x08; +key.num_8 = 0x09; +key.num_9 = 0x0a; -keymap.minus = 0x0c; -keymap.plus = 0x0d; -keymap.backspace = 0x0e; +key.minus = 0x0c; +key.plus = 0x0d; +key.backspace = 0x0e; -keymap.ins = 0xd2; -keymap.del = 0xd3; -keymap.home = 0xc7; -keymap.end = 0xcf; -keymap.page_up = 0xc9; -keymap.page_down = 0xd1; +key.ins = 0xd2; +key.del = 0xd3; +key.home = 0xc7; +key.end = 0xcf; +key.page_up = 0xc9; +key.page_down = 0xd1; -keymap.a = 0x1e; -keymap.b = 0x30; -keymap.c = 0x2e; -keymap.d = 0x20; -keymap.e = 0x12; -keymap.f = 0x21; -keymap.g = 0x22; -keymap.h = 0x23; -keymap.i = 0x17; -keymap.j = 0x24; -keymap.k = 0x25; -keymap.l = 0x26; -keymap.m = 0x32; -keymap.n = 0x31; -keymap.o = 0x18; -keymap.p = 0x19; -keymap.q = 0x10; -keymap.r = 0x13; -keymap.s = 0x1f; -keymap.t = 0x14; -keymap.u = 0x16; -keymap.v = 0x2f; -keymap.w = 0x11; -keymap.x = 0x2d; -keymap.y = 0x15; -keymap.z = 0x2c; +key.a = 0x1e; +key.b = 0x30; +key.c = 0x2e; +key.d = 0x20; +key.e = 0x12; +key.f = 0x21; +key.g = 0x22; +key.h = 0x23; +key.i = 0x17; +key.j = 0x24; +key.k = 0x25; +key.l = 0x26; +key.m = 0x32; +key.n = 0x31; +key.o = 0x18; +key.p = 0x19; +key.q = 0x10; +key.r = 0x13; +key.s = 0x1f; +key.t = 0x14; +key.u = 0x16; +key.v = 0x2f; +key.w = 0x11; +key.x = 0x2d; +key.y = 0x15; +key.z = 0x2c; -keymap.lbracket = 0x1a; -keymap.rbracket = 0x1b; -keymap.pipe = 0x2b; -keymap.colon = 0x27; -keymap.quote = 0x28; -keymap.comma = 0x33; -keymap.period = 0x34; -keymap.question = 0x35; +key.lbracket = 0x1a; +key.rbracket = 0x1b; +key.pipe = 0x2b; +key.colon = 0x27; +key.quote = 0x28; +key.comma = 0x33; +key.period = 0x34; +key.question = 0x35; -keymap.numpad_0 = 0x52; -keymap.numpad_1 = 0x4f; -keymap.numpad_2 = 0x50; -keymap.numpad_3 = 0x51; -keymap.numpad_4 = 0x4b; -keymap.numpad_5 = 0x4c; -keymap.numpad_6 = 0x4d; -keymap.numpad_7 = 0x47; -keymap.numpad_8 = 0x48; -keymap.numpad_9 = 0x49; -keymap.numpad_plus = 0x4e; -keymap.numpad_minus = 0x4a; -keymap.numpad_mul = 0x37; -keymap.numpad_div = 0xb5; -keymap.numpad_enter = 0x9c; -keymap.numpad_point = 0x53; +key.numpad_0 = 0x52; +key.numpad_1 = 0x4f; +key.numpad_2 = 0x50; +key.numpad_3 = 0x51; +key.numpad_4 = 0x4b; +key.numpad_5 = 0x4c; +key.numpad_6 = 0x4d; +key.numpad_7 = 0x47; +key.numpad_8 = 0x48; +key.numpad_9 = 0x49; +key.numpad_plus = 0x4e; +key.numpad_minus = 0x4a; +key.numpad_mul = 0x37; +key.numpad_div = 0xb5; +key.numpad_enter = 0x9c; +key.numpad_point = 0x53; -keymap.numlock = 0x45; -keymap.capslock = 0x3a; +key.numlock = 0x45; +key.capslock = 0x3a; -keymap.up = 0xc8; -keymap.down = 0xd0; -keymap.left = 0xcb; -keymap.right = 0xcd; +key.up = 0xc8; +key.down = 0xd0; +key.left = 0xcb; +key.right = 0xcd; -keymap.tab = 0x0f; -keymap.enter = 0x1c; -keymap.space = 0x39; -keymap.lctrl = 0x1d; -keymap.rctrl = 0x9d; -keymap.lalt = 0x38; -keymap.ralt = 0xb8; -keymap.lshift = 0x2a; -keymap.rshift = 0x36; +key.tab = 0x0f; +key.enter = 0x1c; +key.space = 0x39; +key.lctrl = 0x1d; +key.rctrl = 0x9d; +key.lalt = 0x38; +key.ralt = 0xb8; +key.lshift = 0x2a; +key.rshift = 0x36; -keymap.lwin = 0xdb; -keymap.rwin = 0xdc; -keymap.menu = 0xdd; +key.lwin = 0xdb; +key.rwin = 0xdc; +key.menu = 0xdd; + +for(int joy = 0; joy < 16; joy++) { + key.joypad[joy].up = 0x100 + (joy * 128) + 124; + key.joypad[joy].down = 0x100 + (joy * 128) + 125; + key.joypad[joy].left = 0x100 + (joy * 128) + 126; + key.joypad[joy].right = 0x100 + (joy * 128) + 127; + for(int bn = 0; bn <= 123; bn++) { + key.joypad[joy].button[bn] = 0x100 + (joy * 128) + bn; + } +} diff --git a/src/ui/input/input.cpp b/src/ui/input/input.cpp index e8215e83..d6319b81 100644 --- a/src/ui/input/input.cpp +++ b/src/ui/input/input.cpp @@ -1,208 +1,140 @@ -void Input::ui_poll_input(Window *focus, bool require_window_focus) { - if(require_window_focus == true) { - if(GetFocus() != focus->hwnd)return; - } - +void Input::poll(uint8 device) { poll(); -EventInfo info; - info.window = focus; - info.window_id = focus->id; - info.control = 0; +#define poll_key(__key) \ + __key = bool(keystate[(uint(config::input.__key) >> 0) & 4095]) | \ + bool(keystate[(uint(config::input.__key) >> 16) & 4095]) - for(int i = 0; i < 256; i++) { - if(!old_keystate[i] && keystate[i]) { - info.event_id = EVENT_INPUTKEYDOWN; - info.control_id = KEYFLAG | i; - focus->Event(info); - } else if(old_keystate[i] && !keystate[i]) { - info.event_id = EVENT_INPUTKEYUP; - info.control_id = KEYFLAG | i; - focus->Event(info); - } + switch(device) { + case SNES::DEV_JOYPAD1: + poll_key(joypad1.up); + poll_key(joypad1.down); + poll_key(joypad1.left); + poll_key(joypad1.right); + poll_key(joypad1.a); + poll_key(joypad1.b); + poll_key(joypad1.x); + poll_key(joypad1.y); + poll_key(joypad1.l); + poll_key(joypad1.r); + poll_key(joypad1.select); + poll_key(joypad1.start); + break; + case SNES::DEV_JOYPAD2: + poll_key(joypad2.up); + poll_key(joypad2.down); + poll_key(joypad2.left); + poll_key(joypad2.right); + poll_key(joypad2.a); + poll_key(joypad2.b); + poll_key(joypad2.x); + poll_key(joypad2.y); + poll_key(joypad2.l); + poll_key(joypad2.r); + poll_key(joypad2.select); + poll_key(joypad2.start); + break; } - for(int j = 0; j < INPUT_JOYMAX; j++) { - for(int i = 0; i < 256; i++) { - if(!old_joystate[j * 256 + i] && joystate[j * 256 + i]) { - info.event_id = EVENT_INPUTKEYDOWN; - info.control_id = JOYFLAG | (j << 8) | i; - focus->Event(info); - } else if(old_joystate[j * 256 + i] && !joystate[j * 256 + i]) { - info.event_id = EVENT_INPUTKEYUP; - info.control_id = JOYFLAG | (j << 8) | i; - focus->Event(info); - } +#undef poll_key +} + +bool Input::get_status(uint8 device, uint8 button) { + switch(device) { + case SNES::DEV_JOYPAD1: + switch(button) { + case SNES::JOYPAD_UP: return joypad1.up; + case SNES::JOYPAD_DOWN: return joypad1.down; + case SNES::JOYPAD_LEFT: return joypad1.left; + case SNES::JOYPAD_RIGHT: return joypad1.right; + case SNES::JOYPAD_A: return joypad1.a; + case SNES::JOYPAD_B: return joypad1.b; + case SNES::JOYPAD_X: return joypad1.x; + case SNES::JOYPAD_Y: return joypad1.y; + case SNES::JOYPAD_L: return joypad1.l; + case SNES::JOYPAD_R: return joypad1.r; + case SNES::JOYPAD_SELECT: return joypad1.select; + case SNES::JOYPAD_START: return joypad1.start; } - } - - memcpy(old_keystate, keystate, 256); - memcpy(old_joystate, joystate, INPUT_JOYMAX * 256); -} - -void Input::ui_clear_input() { - memset(keystate, 0, 256); - memset(joystate, 0, INPUT_JOYMAX * 256); - memset(old_keystate, 0, 256); - memset(old_joystate, 0, INPUT_JOYMAX * 256); -} - -//this does not poll actual key state, it relies on -//current keystate buffer to be up-to-date. -//it is intended to be used inside -//Input::EVENT_INPUTKEY* messages only. -//calling Input::ui_poll_input() first will allow -//this function to be used anywhere. -bool Input::keydown(uint id) { - if(id < 256) { - return (keystate[id] != 0); + break; + case SNES::DEV_JOYPAD2: + switch(button) { + case SNES::JOYPAD_UP: return joypad2.up; + case SNES::JOYPAD_DOWN: return joypad2.down; + case SNES::JOYPAD_LEFT: return joypad2.left; + case SNES::JOYPAD_RIGHT: return joypad2.right; + case SNES::JOYPAD_A: return joypad2.a; + case SNES::JOYPAD_B: return joypad2.b; + case SNES::JOYPAD_X: return joypad2.x; + case SNES::JOYPAD_Y: return joypad2.y; + case SNES::JOYPAD_L: return joypad2.l; + case SNES::JOYPAD_R: return joypad2.r; + case SNES::JOYPAD_SELECT: return joypad2.select; + case SNES::JOYPAD_START: return joypad2.start; + } + break; } return false; } -//turn string into keymap value, eg -//"esc" returns keymap.esc -uint Input::stringtokeymap(const char *str) { -uint r = JOYKEY_NONE; -string t, part; - strcpy(t, str); - replace(t, ".", "|"); - split(part, "|", t); - -#define cmp(__n) if(strmatch(#__n, part[0]) == true)r = (r & ~KEYMASK) | keymap.__n; - cmp(esc) - cmp(f1) cmp(f2) cmp(f3) cmp(f4) cmp(f5) cmp(f6) - cmp(f7) cmp(f8) cmp(f9) cmp(f10) cmp(f11) cmp(f12) - cmp(print_screen) cmp(scroll_lock) cmp(pause) - - cmp(tilde) - cmp(num_0) cmp(num_1) cmp(num_2) cmp(num_3) cmp(num_4) - cmp(num_5) cmp(num_6) cmp(num_7) cmp(num_8) cmp(num_9) - cmp(minus) cmp(plus) cmp(backspace) - cmp(ins) cmp(del) cmp(home) cmp(end) cmp(page_up) cmp(page_down) - - cmp(a) cmp(b) cmp(c) cmp(d) cmp(e) cmp(f) cmp(g) cmp(h) cmp(i) - cmp(j) cmp(k) cmp(l) cmp(m) cmp(n) cmp(o) cmp(p) cmp(q) cmp(r) - cmp(s) cmp(t) cmp(u) cmp(v) cmp(w) cmp(x) cmp(y) cmp(z) - - cmp(lbracket) cmp(rbracket) cmp(pipe) - cmp(colon) cmp(quote) - cmp(comma) cmp(period) cmp(question) - - cmp(numpad_0) cmp(numpad_1) cmp(numpad_2) cmp(numpad_3) cmp(numpad_4) - cmp(numpad_5) cmp(numpad_6) cmp(numpad_7) cmp(numpad_8) cmp(numpad_9) - cmp(numpad_plus) cmp(numpad_minus) cmp(numpad_mul) cmp(numpad_div) - cmp(numpad_enter) cmp(numpad_point) - - cmp(numlock) cmp(capslock) - - cmp(up) cmp(down) cmp(left) cmp(right) - - cmp(tab) cmp(enter) cmp(space) - cmp(lctrl) cmp(rctrl) - cmp(lalt) cmp(ralt) - cmp(lshift) cmp(rshift) - - cmp(lwin) cmp(rwin) cmp(menu) -#undef cmp - - if(count(part) < 3)return r; - - strcpy(t, part[1]); - replace(t, "joy", ""); -uint controller = strdec(t), button; - - strcpy(t, part[2]); - if(strmatch(t, "up")) { - button = 0x80; - } else if(strmatch(t, "down")) { - button = 0x81; - } else if(strmatch(t, "left")) { - button = 0x82; - } else if(strmatch(t, "right")) { - button = 0x83; - } else { - replace(t, "button", ""); - button = strdec(t); +void Input::set_status(uint8 device, uint8 button, bool status) { + switch(device) { + case SNES::DEV_JOYPAD1: + switch(button) { + case SNES::JOYPAD_UP: joypad1.up = status; break; + case SNES::JOYPAD_DOWN: joypad1.down = status; break; + case SNES::JOYPAD_LEFT: joypad1.left = status; break; + case SNES::JOYPAD_RIGHT: joypad1.right = status; break; + case SNES::JOYPAD_A: joypad1.a = status; break; + case SNES::JOYPAD_B: joypad1.b = status; break; + case SNES::JOYPAD_X: joypad1.x = status; break; + case SNES::JOYPAD_Y: joypad1.y = status; break; + case SNES::JOYPAD_L: joypad1.l = status; break; + 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; + case SNES::DEV_JOYPAD2: + switch(button) { + case SNES::JOYPAD_UP: joypad2.up = status; break; + case SNES::JOYPAD_DOWN: joypad2.down = status; break; + case SNES::JOYPAD_LEFT: joypad2.left = status; break; + case SNES::JOYPAD_RIGHT: joypad2.right = status; break; + case SNES::JOYPAD_A: joypad2.a = status; break; + case SNES::JOYPAD_B: joypad2.b = status; break; + case SNES::JOYPAD_X: joypad2.x = status; break; + case SNES::JOYPAD_Y: joypad2.y = status; break; + case SNES::JOYPAD_L: joypad2.l = status; break; + 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; } - - r = (r & ~JOYMASK) | (controller << 16) | (button << 8); - - return r; } -//turn keymap value into string, -//eg 0x01 returns "esc" -const char *Input::keymaptostring(uint key) { -static char result[128]; - strcpy(result, "keynone"); - -uint r = key & KEYMASK; - -#define cmp(__n) if(r == keymap.__n)strcpy(result, #__n); - cmp(esc) - cmp(f1) cmp(f2) cmp(f3) cmp(f4) cmp(f5) cmp(f6) - cmp(f7) cmp(f8) cmp(f9) cmp(f10) cmp(f11) cmp(f12) - cmp(print_screen) cmp(scroll_lock) cmp(pause) - - cmp(tilde) - cmp(num_0) cmp(num_1) cmp(num_2) cmp(num_3) cmp(num_4) - cmp(num_5) cmp(num_6) cmp(num_7) cmp(num_8) cmp(num_9) - cmp(minus) cmp(plus) cmp(backspace) - cmp(ins) cmp(del) cmp(home) cmp(end) cmp(page_up) cmp(page_down) - - cmp(a) cmp(b) cmp(c) cmp(d) cmp(e) cmp(f) cmp(g) cmp(h) cmp(i) - cmp(j) cmp(k) cmp(l) cmp(m) cmp(n) cmp(o) cmp(p) cmp(q) cmp(r) - cmp(s) cmp(t) cmp(u) cmp(v) cmp(w) cmp(x) cmp(y) cmp(z) - - cmp(lbracket) cmp(rbracket) cmp(pipe) - cmp(colon) cmp(quote) - cmp(comma) cmp(period) cmp(question) - - cmp(numpad_0) cmp(numpad_1) cmp(numpad_2) cmp(numpad_3) cmp(numpad_4) - cmp(numpad_5) cmp(numpad_6) cmp(numpad_7) cmp(numpad_8) cmp(numpad_9) - cmp(numpad_plus) cmp(numpad_minus) cmp(numpad_mul) cmp(numpad_div) - cmp(numpad_enter) cmp(numpad_point) - - cmp(numlock) cmp(capslock) - - cmp(up) cmp(down) cmp(left) cmp(right) - - cmp(tab) cmp(enter) cmp(space) - cmp(lctrl) cmp(rctrl) - cmp(lalt) cmp(ralt) - cmp(lshift) cmp(rshift) - - cmp(lwin) cmp(rwin) cmp(menu) -#undef cmp - - if((key & JOYMASK) != JOY_NONE) { - strcat(result, " | joy"); - r = (key >> 16) & 0xff; - char tmp[16]; - sprintf(tmp, "%d", r); - strcat(result, tmp); - strcat(result, "."); - r = (key >> 8) & 0xff; - if(r == 0x80) { - strcat(result, "up"); - } else if(r == 0x81) { - strcat(result, "down"); - } else if(r == 0x82) { - strcat(result, "left"); - } else if(r == 0x83) { - strcat(result, "right"); - } else { - sprintf(tmp, "button%d", r); - strcat(result, tmp); - } - } - - return result; +void Input::clear_input() { + joypad1.up = joypad2.up = + joypad1.down = joypad2.down = + joypad1.left = joypad2.left = + joypad1.right = joypad2.right = + joypad1.a = joypad2.a = + joypad1.b = joypad2.b = + joypad1.x = joypad2.x = + joypad1.y = joypad2.y = + joypad1.l = joypad2.l = + joypad1.r = joypad2.r = + joypad1.select = joypad2.select = + joypad1.start = joypad2.start = false; } -uint Input::get_keymap(uint device, uint button) { +//this does not poll actual key state, it relies on +//current keystate buffer to be up-to-date. +bool Input::keydown(uint16 key) { + return (keystate[key] != 0); +} + +uint Input::get_key(uint device, uint button) { switch(device) { case SNES::DEV_JOYPAD1: switch(button) { @@ -235,44 +167,53 @@ uint Input::get_keymap(uint device, uint button) { case SNES::JOYPAD_START: return config::input.joypad2.start; } break; } - return JOYKEY_NONE; + + return 0; } -void Input::set_keymap(uint device, uint button, uint keymap) { +void Input::set_key(uint device, uint button, uint key) { 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; + case SNES::JOYPAD_UP: config::input.joypad1.up = key; break; + case SNES::JOYPAD_DOWN: config::input.joypad1.down = key; break; + case SNES::JOYPAD_LEFT: config::input.joypad1.left = key; break; + case SNES::JOYPAD_RIGHT: config::input.joypad1.right = key; break; + case SNES::JOYPAD_A: config::input.joypad1.a = key; break; + case SNES::JOYPAD_B: config::input.joypad1.b = key; break; + case SNES::JOYPAD_X: config::input.joypad1.x = key; break; + case SNES::JOYPAD_Y: config::input.joypad1.y = key; break; + case SNES::JOYPAD_L: config::input.joypad1.l = key; break; + case SNES::JOYPAD_R: config::input.joypad1.r = key; break; + case SNES::JOYPAD_SELECT: config::input.joypad1.select = key; break; + case SNES::JOYPAD_START: config::input.joypad1.start = key; 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; + case SNES::JOYPAD_UP: config::input.joypad2.up = key; break; + case SNES::JOYPAD_DOWN: config::input.joypad2.down = key; break; + case SNES::JOYPAD_LEFT: config::input.joypad2.left = key; break; + case SNES::JOYPAD_RIGHT: config::input.joypad2.right = key; break; + case SNES::JOYPAD_A: config::input.joypad2.a = key; break; + case SNES::JOYPAD_B: config::input.joypad2.b = key; break; + case SNES::JOYPAD_X: config::input.joypad2.x = key; break; + case SNES::JOYPAD_Y: config::input.joypad2.y = key; break; + case SNES::JOYPAD_L: config::input.joypad2.l = key; break; + case SNES::JOYPAD_R: config::input.joypad2.r = key; break; + case SNES::JOYPAD_SELECT: config::input.joypad2.select = key; break; + case SNES::JOYPAD_START: config::input.joypad2.start = key; break; } break; } } +uint Input::decode(substring &str) { +string p; + split(p, "|", str); +uint r = key.find(strptr(p[0])) & 4095; + if(count(p) >= 2) { r |= (key.find(strptr(p[1])) & 4095) << 16; } + return r; +} + void Input::init() { string t, part; strcpy(t, config::input.joypad1.map.sget()); @@ -280,72 +221,82 @@ string t, part; replace(t, "\t", ""); strlower(t); split(part, ";", t); - config::input.joypad1.up = stringtokeymap(strptr(part[ 0])); - config::input.joypad1.down = stringtokeymap(strptr(part[ 1])); - config::input.joypad1.left = stringtokeymap(strptr(part[ 2])); - config::input.joypad1.right = stringtokeymap(strptr(part[ 3])); - config::input.joypad1.a = stringtokeymap(strptr(part[ 4])); - config::input.joypad1.b = stringtokeymap(strptr(part[ 5])); - config::input.joypad1.x = stringtokeymap(strptr(part[ 6])); - config::input.joypad1.y = stringtokeymap(strptr(part[ 7])); - config::input.joypad1.l = stringtokeymap(strptr(part[ 8])); - config::input.joypad1.r = stringtokeymap(strptr(part[ 9])); - config::input.joypad1.select = stringtokeymap(strptr(part[10])); - config::input.joypad1.start = stringtokeymap(strptr(part[11])); + config::input.joypad1.up = decode(part[ 0]); + config::input.joypad1.down = decode(part[ 1]); + config::input.joypad1.left = decode(part[ 2]); + config::input.joypad1.right = decode(part[ 3]); + config::input.joypad1.a = decode(part[ 4]); + config::input.joypad1.b = decode(part[ 5]); + config::input.joypad1.x = decode(part[ 6]); + config::input.joypad1.y = decode(part[ 7]); + config::input.joypad1.l = decode(part[ 8]); + config::input.joypad1.r = decode(part[ 9]); + config::input.joypad1.select = decode(part[10]); + config::input.joypad1.start = decode(part[11]); strcpy(t, config::input.joypad2.map.sget()); replace(t, " ", ""); replace(t, "\t", ""); strlower(t); split(part, ";", t); - config::input.joypad2.up = stringtokeymap(strptr(part[ 0])); - config::input.joypad2.down = stringtokeymap(strptr(part[ 1])); - config::input.joypad2.left = stringtokeymap(strptr(part[ 2])); - config::input.joypad2.right = stringtokeymap(strptr(part[ 3])); - config::input.joypad2.a = stringtokeymap(strptr(part[ 4])); - config::input.joypad2.b = stringtokeymap(strptr(part[ 5])); - config::input.joypad2.x = stringtokeymap(strptr(part[ 6])); - config::input.joypad2.y = stringtokeymap(strptr(part[ 7])); - config::input.joypad2.l = stringtokeymap(strptr(part[ 8])); - config::input.joypad2.r = stringtokeymap(strptr(part[ 9])); - config::input.joypad2.select = stringtokeymap(strptr(part[10])); - config::input.joypad2.start = stringtokeymap(strptr(part[11])); + config::input.joypad2.up = decode(part[ 0]); + config::input.joypad2.down = decode(part[ 1]); + config::input.joypad2.left = decode(part[ 2]); + config::input.joypad2.right = decode(part[ 3]); + config::input.joypad2.a = decode(part[ 4]); + config::input.joypad2.b = decode(part[ 5]); + config::input.joypad2.x = decode(part[ 6]); + config::input.joypad2.y = decode(part[ 7]); + config::input.joypad2.l = decode(part[ 8]); + config::input.joypad2.r = decode(part[ 9]); + config::input.joypad2.select = decode(part[10]); + config::input.joypad2.start = decode(part[11]); +} + +const char *Input::encode(uint k) { + strcpy(tmp, key.find(k & 4095)); + if(k >> 16) { + strcat(tmp, " | "); + strcat(tmp, key.find((k >> 16) & 4095)); + } + return tmp; } void Input::term() { string result; char t[256]; strcpy(result, ""); - strcat(result, keymaptostring(config::input.joypad1.up)); strcat(result, "; "); - strcat(result, keymaptostring(config::input.joypad1.down)); strcat(result, "; "); - strcat(result, keymaptostring(config::input.joypad1.left)); strcat(result, "; "); - strcat(result, keymaptostring(config::input.joypad1.right)); strcat(result, "; "); - strcat(result, keymaptostring(config::input.joypad1.a)); strcat(result, "; "); - strcat(result, keymaptostring(config::input.joypad1.b)); strcat(result, "; "); - strcat(result, keymaptostring(config::input.joypad1.x)); strcat(result, "; "); - strcat(result, keymaptostring(config::input.joypad1.y)); strcat(result, "; "); - strcat(result, keymaptostring(config::input.joypad1.l)); strcat(result, "; "); - strcat(result, keymaptostring(config::input.joypad1.r)); strcat(result, "; "); - strcat(result, keymaptostring(config::input.joypad1.select)); strcat(result, "; "); - strcat(result, keymaptostring(config::input.joypad1.start)); + strcat(result, encode((uint)config::input.joypad1.up)); strcat(result, "; "); + strcat(result, encode((uint)config::input.joypad1.down)); strcat(result, "; "); + strcat(result, encode((uint)config::input.joypad1.left)); strcat(result, "; "); + strcat(result, encode((uint)config::input.joypad1.right)); strcat(result, "; "); + strcat(result, encode((uint)config::input.joypad1.a)); strcat(result, "; "); + strcat(result, encode((uint)config::input.joypad1.b)); strcat(result, "; "); + strcat(result, encode((uint)config::input.joypad1.x)); strcat(result, "; "); + strcat(result, encode((uint)config::input.joypad1.y)); strcat(result, "; "); + strcat(result, encode((uint)config::input.joypad1.l)); strcat(result, "; "); + strcat(result, encode((uint)config::input.joypad1.r)); strcat(result, "; "); + strcat(result, encode((uint)config::input.joypad1.select)); strcat(result, "; "); + strcat(result, encode((uint)config::input.joypad1.start)); config::input.joypad1.map.sset(strptr(result)); strcpy(result, ""); - strcat(result, keymaptostring(config::input.joypad2.up)); strcat(result, "; "); - strcat(result, keymaptostring(config::input.joypad2.down)); strcat(result, "; "); - strcat(result, keymaptostring(config::input.joypad2.left)); strcat(result, "; "); - strcat(result, keymaptostring(config::input.joypad2.right)); strcat(result, "; "); - strcat(result, keymaptostring(config::input.joypad2.a)); strcat(result, "; "); - strcat(result, keymaptostring(config::input.joypad2.b)); strcat(result, "; "); - strcat(result, keymaptostring(config::input.joypad2.x)); strcat(result, "; "); - strcat(result, keymaptostring(config::input.joypad2.y)); strcat(result, "; "); - strcat(result, keymaptostring(config::input.joypad2.l)); strcat(result, "; "); - strcat(result, keymaptostring(config::input.joypad2.r)); strcat(result, "; "); - strcat(result, keymaptostring(config::input.joypad2.select)); strcat(result, "; "); - strcat(result, keymaptostring(config::input.joypad2.start)); + strcat(result, encode((uint)config::input.joypad2.up)); strcat(result, "; "); + strcat(result, encode((uint)config::input.joypad2.down)); strcat(result, "; "); + strcat(result, encode((uint)config::input.joypad2.left)); strcat(result, "; "); + strcat(result, encode((uint)config::input.joypad2.right)); strcat(result, "; "); + strcat(result, encode((uint)config::input.joypad2.a)); strcat(result, "; "); + strcat(result, encode((uint)config::input.joypad2.b)); strcat(result, "; "); + strcat(result, encode((uint)config::input.joypad2.x)); strcat(result, "; "); + strcat(result, encode((uint)config::input.joypad2.y)); strcat(result, "; "); + strcat(result, encode((uint)config::input.joypad2.l)); strcat(result, "; "); + strcat(result, encode((uint)config::input.joypad2.r)); strcat(result, "; "); + strcat(result, encode((uint)config::input.joypad2.select)); strcat(result, "; "); + strcat(result, encode((uint)config::input.joypad2.start)); config::input.joypad2.map.sset(strptr(result)); } Input::Input() { - ui_clear_input(); + memset(keystate, 0, sizeof(keystate)); + clear_input(); } diff --git a/src/ui/input/input.h b/src/ui/input/input.h index 7f1ff840..035932e9 100644 --- a/src/ui/input/input.h +++ b/src/ui/input/input.h @@ -1,83 +1,37 @@ -#define INPUT_JOYMAX 8 +#include "../../lib/libkeymap.h" +#define INPUT_JOYMAX 16 class Input { +private: +char tmp[256]; + public: -enum { - EVENT_INPUTKEYDOWN = EVENT_USER + 0, - EVENT_INPUTKEYUP = EVENT_USER + 1, -}; +struct joypad { + bool up, down, left, right; + bool a, b, x, y, l, r; + bool select, start; +} joypad1, joypad2; -//this must be initialized by init() -struct Keymap { - uint esc; - uint f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12; - uint print_screen, scroll_lock, pause; - - uint tilde; - uint num_0, num_1, num_2, num_3, num_4; - uint num_5, num_6, num_7, num_8, num_9; - uint minus, plus, backspace; - uint ins, del, home, end, page_up, page_down; - - uint a, b, c, d, e, f, g, h, i, j, k, l, m; - uint n, o, p, q, r, s, t, u, v, w, x, y, z; - - uint lbracket, rbracket, pipe; - uint colon, quote; - uint comma, period, question; - - uint numpad_0, numpad_1, numpad_2, numpad_3, numpad_4; - uint numpad_5, numpad_6, numpad_7, numpad_8, numpad_9; - uint numpad_plus, numpad_minus, numpad_mul, numpad_div; - uint numpad_enter, numpad_point; - - uint numlock, capslock; - - uint up, down, left, right; - - uint tab, enter, space; - uint lctrl, rctrl; - uint lalt, ralt; - uint lshift, rshift; - - uint lwin, rwin, menu; -} keymap; - -uint8 keystate[256], joystate[INPUT_JOYMAX * 256]; -uint8 old_keystate[256], old_joystate[INPUT_JOYMAX * 256]; - -enum { -//bit 31: clear = keypress, set = joypress - KEYFLAG = 0x00000000, - JOYFLAG = 0x80000000, - - JOYMASK = 0xffff00, - KEYMASK = 0x0000ff, - JOYKEYMASK = 0xffffff, - JOY_NONE = 0xffff00, - KEY_NONE = 0x0000ff, - JOYKEY_NONE = 0xffffff, -}; +keymap key; //this must be initialized by init() +bool8 keystate[4096]; virtual void poll() = 0; - - virtual void ui_poll_input(Window *focus, bool require_window_focus = true); - virtual void ui_clear_input(); - - virtual void poll(uint8 type) = 0; - virtual bool get_status(uint8 device, uint8 button) = 0; - virtual void set_status(uint8 device, uint8 button, bool status) = 0; - virtual void clear_input() = 0; + virtual void poll(uint8 device); virtual void init(); virtual void term(); //helper functions - 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); + bool get_status(uint8 device, uint8 button); + void set_status(uint8 device, uint8 button, bool status); + void clear_input(); + + bool keydown(uint16 key); + uint get_key(uint device, uint button); + void set_key(uint device, uint button, uint key); + + uint decode(substring&); + const char *encode(uint); Input(); } *uiInput; diff --git a/src/ui/main.cpp b/src/ui/main.cpp index e7e70ef5..a425c554 100644 --- a/src/ui/main.cpp +++ b/src/ui/main.cpp @@ -1,6 +1,7 @@ #define INTERFACE_MAIN #include "../base.h" +#include "main.h" #include "config.cpp" void init_snes(); @@ -10,31 +11,25 @@ void term_snes(); * OS abstraction layer *****/ -//#include "video/video.h" -//#include "audio/audio.h" -//#include "input/input.h" +#include "video/video.h" +#include "audio/audio.h" +#include "input/input.h" -//#include "video/video.cpp" -//#include "input/input.cpp" - -/***** - * emulation abstraction layer - *****/ - -#include "bsnes.h" +#include "video/video.cpp" +#include "input/input.cpp" /***** * platform abstraction layer *****/ -#ifdef PLATFORM_WIN +#if defined(PLATFORM_WIN) #include "win/main.cpp" +#elif defined(PLATFORM_SDL) + #include "sdl/main.cpp" #else #error "unsupported platform" #endif -#include "bsnes.cpp" - /***** * platform independent code *****/ diff --git a/src/ui/main.h b/src/ui/main.h new file mode 100644 index 00000000..e69de29b diff --git a/src/sdl/bsnes.cpp b/src/ui/sdl/bsnes.cpp similarity index 87% rename from src/sdl/bsnes.cpp rename to src/ui/sdl/bsnes.cpp index ca29091f..a532e33c 100644 --- a/src/sdl/bsnes.cpp +++ b/src/ui/sdl/bsnes.cpp @@ -15,14 +15,8 @@ void bSNES::video_run() { if(r_ppu->status.frames_updated) { char s[512], t[512]; r_ppu->status.frames_updated = false; -// if((bool)config::gui.show_fps == true) { - sprintf(s, "%s : %d fps", BSNES_TITLE, r_ppu->status.frames_executed); -// if(w_main->frameskip != 0) { -// sprintf(t, " (%d frames)", r_ppu->status.frames_rendered); -// strcat(s, t); -// } - SDL_WM_SetCaption(s, 0); -// } + sprintf(s, "%s : %d fps", BSNES_TITLE, r_ppu->status.frames_executed); + SDL_WM_SetCaption(s, 0); } render(); @@ -30,7 +24,7 @@ void bSNES::video_run() { void bSNES::sound_run(uint32 data) {} -uint16 *bSNES::video_lock(uint32 &pitch) { +uint16 *bSNES::video_lock(uint &pitch) { if(SDL_MUSTLOCK(screen)) { SDL_LockSurface(screen); } diff --git a/src/sdl/bsnes.h b/src/ui/sdl/bsnes.h similarity index 86% rename from src/sdl/bsnes.h rename to src/ui/sdl/bsnes.h index a1595cbc..f2cf2863 100644 --- a/src/sdl/bsnes.h +++ b/src/ui/sdl/bsnes.h @@ -17,7 +17,7 @@ enum { STOP = 0, RUN }; void video_run(); void sound_run(uint32 data); - uint16 *video_lock(uint32 &data); + uint16 *video_lock(uint &data); void video_unlock(); void set_status(uint32 new_status); @@ -29,6 +29,4 @@ enum { STOP = 0, RUN }; void notify(uint32 message, uint32 param1 = 0, uint32 param2 = 0); bSNES(); -}; - -bSNES *bsnes; +} *bsnes; diff --git a/src/sdl/sdlmain.cpp b/src/ui/sdl/main.cpp similarity index 55% rename from src/sdl/sdlmain.cpp rename to src/ui/sdl/main.cpp index 317829f9..5a6ee7ad 100644 --- a/src/sdl/sdlmain.cpp +++ b/src/ui/sdl/main.cpp @@ -1,12 +1,4 @@ -#define INTERFACE_MAIN -#include "../base.h" -#include "sdlmain.h" - -#include "config.cpp" - -#ifdef _WIN32_ -HWND hwnd; -#endif +#include "main.h" #include "bsnes.h" #include "render.cpp" @@ -18,7 +10,7 @@ va_list args; va_start(args, s); vsprintf(str, s, args); va_end(args); -#ifdef _WIN32_ +#ifdef _WIN32 MessageBox(0, str, "bsnes", MB_OK); #else fprintf(stdout, "%s\r\n", str); @@ -34,42 +26,12 @@ va_list args; fprintf(stdout, "%s\r\n", str); } -void init_snes() { -#ifdef POLYMORPHISM - deref(mem) = new bMemBus(); - deref(cpu) = new bCPU(); - deref(apu) = new bAPU(); - deref(dsp) = new bDSP(); - deref(ppu) = new bPPU(); -#endif - snes = new bSNES(); - bsnes = static_cast(snes); - - snes->init(); - -//TODO: add sound support and remove this, -//this is used with linux/bsd and mkfifo to -//play audio in real-time while sound output -//isn't available. - snes->log_audio_enable("output.wav"); -} - -void term_snes() { - snes->term(); -#ifdef POLYMORPHISM - SafeDelete(deref(mem)); - SafeDelete(deref(cpu)); - SafeDelete(deref(apu)); - SafeDelete(deref(dsp)); - SafeDelete(deref(ppu)); -#endif - SafeDelete(snes); -} - void center_window() { -#ifdef _WIN32_ +#ifdef _WIN32 +HWND hwnd; RECT rc; int x, y; + hwnd = FindWindow(0, BSNES_TITLE); GetWindowRect(hwnd, &rc); x = (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left)) >> 1; y = (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top)) >> 1; @@ -77,29 +39,13 @@ int x, y; #endif } -void set_window_info() { -//SDL won't draw anything if you blit an image that's larger than -//the display mode/window, even if you use the SoftStretch blit and -//clip the source + dest rectangles properly... - if((int)config::video.display_width < (int)config::video.output_width) { - config::video.display_width = config::video.output_width; - } - if((int)config::video.display_height < (int)config::video.output_height) { - config::video.display_height = config::video.output_height; - } - - screen_info.rd.x = ((int)config::video.display_width - (int)config::video.output_width ) >> 1; - screen_info.rd.y = ((int)config::video.display_height - (int)config::video.output_height) >> 1; - screen_info.rd.w = config::video.output_width; - screen_info.rd.h = config::video.output_height; -} - -#ifdef _WIN32_ +#ifdef _WIN32 int __stdcall WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) { int argc = __argc; char **argv = __argv; + SDL_SetModuleHandle(GetModuleHandle(0)); #else -int main(int argc, char *argv[]) { +int SDL_main(int argc, char *argv[]) { #endif SDL_Event event; @@ -120,17 +66,20 @@ SDL_Event event; SDL_Init(SDL_INIT_VIDEO); atexit(SDL_Quit); - set_window_info(); - screen = SDL_SetVideoMode(config::video.display_width, config::video.display_height, 16, + + screen_rect.x = 0; + screen_rect.y = 0; + screen_rect.w = 256; + screen_rect.h = 224; + + screen = SDL_SetVideoMode(screen_rect.w, screen_rect.h, 16, SDL_HWSURFACE | ((config::video.fullscreen) ? SDL_FULLSCREEN : 0)); if(!screen) { alert("Failed to initialize SDL"); goto _end; } + backbuffer = SDL_CreateRGBSurface(SDL_HWSURFACE, 512, 448, 16, 0xf800, 0x07e0, 0x001f, 0x0000); if(!backbuffer) { alert("Failed to initialize SDL"); goto _end; } SDL_WM_SetCaption(BSNES_TITLE, 0); -#ifdef _WIN32_ - hwnd = FindWindow(0, BSNES_TITLE); -#endif center_window(); snes->power(); diff --git a/src/ui/sdl/main.h b/src/ui/sdl/main.h new file mode 100644 index 00000000..e49a3bf2 --- /dev/null +++ b/src/ui/sdl/main.h @@ -0,0 +1,8 @@ +#ifdef _WIN32 + #include +#endif + +#include "SDL.h" + +SDL_Surface *screen, *backbuffer; +SDL_Rect screen_rect; diff --git a/src/ui/sdl/render.cpp b/src/ui/sdl/render.cpp new file mode 100644 index 00000000..56b6922a --- /dev/null +++ b/src/ui/sdl/render.cpp @@ -0,0 +1,18 @@ +void render() { +SNES::video_info vi; + snes->get_video_info(&vi); + +SDL_Rect rect; + rect.x = 0; + rect.y = (vi.height == 224) ? 1 : 2; + rect.w = vi.width; + rect.h = (vi.height == 224) ? 223 : 446; + +//documentation says not to use this, but it's rather ridiculous that a graphics +//library wouldn't support simple image scaling... so let's use it anyway and see +//what happens... + SDL_SoftStretch(backbuffer, &rect, screen, &screen_rect); +//SDL_BlitSurface(backbuffer, &rect, screen, &screen_rect); + + SDL_UpdateRect(screen, screen_rect.x, screen_rect.y, screen_rect.w, screen_rect.h); +} diff --git a/src/ui/video/d3d.cpp b/src/ui/video/d3d.cpp index f0c55607..0f2d2f26 100644 --- a/src/ui/video/d3d.cpp +++ b/src/ui/video/d3d.cpp @@ -5,7 +5,6 @@ HRESULT hr; term(); update_video_settings(); - update_window(); lpd3d = Direct3DCreate9(D3D_SDK_VERSION); if(!lpd3d) { @@ -117,7 +116,6 @@ HRESULT hr; static_cast(flags.v_pool), &vertex_buffer, NULL); clear_video(); - update_window(); return true; } @@ -170,7 +168,7 @@ D3DLOCKED_RECT d3dlr; } } -uint16 *VideoD3D::lock(uint32 &pitch) { +uint16 *VideoD3D::lock(uint &pitch) { if(caps.stretchrect == false) { texture->GetLevelDesc(0, &d3dsd); texture->GetSurfaceLevel(0, &surface); diff --git a/src/ui/video/d3d.h b/src/ui/video/d3d.h index 8a2e1405..ec4bedb5 100644 --- a/src/ui/video/d3d.h +++ b/src/ui/video/d3d.h @@ -36,9 +36,12 @@ struct { void set_vertex(uint32 px, uint32 py, uint32 pw, uint32 ph, uint32 tw, uint32 th, uint32 x, uint32 y, uint32 w, uint32 h); - uint16 *lock(uint32 &pitch); + uint16 *lock(uint &pitch); void unlock(); + uint screen_width() { return GetScreenWidth(); } + uint screen_height() { return GetScreenHeight(); } + void pause_enable(); void pause_disable(); diff --git a/src/ui/video/ddraw.cpp b/src/ui/video/ddraw.cpp index bb860163..118c9782 100644 --- a/src/ui/video/ddraw.cpp +++ b/src/ui/video/ddraw.cpp @@ -2,7 +2,6 @@ bool VideoDD::update_video_profile() { term(); update_video_settings(); - update_window(); DirectDrawCreate(0, &lpdd, 0); lpdd->QueryInterface(IID_IDirectDraw7, (void**)&lpdd7); @@ -23,7 +22,6 @@ bool VideoDD::update_video_profile() { create_render_target(); clear_video(); - update_window(); return true; } @@ -85,7 +83,7 @@ DDBLTFX fx; surface->Blt(0, 0, 0, DDBLT_WAIT | DDBLT_COLORFILL, &fx); } -uint16 *VideoDD::lock(uint32 &pitch) { +uint16 *VideoDD::lock(uint &pitch) { if(surface->Lock(0, &ddsd, DDLOCK_WAIT, 0) != DD_OK)return 0; pitch = ddsd.lPitch; return (uint16*)ddsd.lpSurface; diff --git a/src/ui/video/ddraw.h b/src/ui/video/ddraw.h index bc78dd5f..6e3a79c2 100644 --- a/src/ui/video/ddraw.h +++ b/src/ui/video/ddraw.h @@ -11,9 +11,12 @@ DDSURFACEDESC2 ddsd; DDSCAPS2 ddscaps; public: - uint16 *lock(uint32 &pitch); + uint16 *lock(uint &pitch); void unlock(); + uint screen_width() { return GetScreenWidth(); } + uint screen_height() { return GetScreenHeight(); } + bool update_video_profile(); void init(); void term(); diff --git a/src/ui/video/video.cpp b/src/ui/video/video.cpp index 55cf11a2..b2e46775 100644 --- a/src/ui/video/video.cpp +++ b/src/ui/video/video.cpp @@ -73,20 +73,20 @@ uint profile = uint(config::video.profile); load_video_settings(profile); VideoSettings *v = &video_settings[profile]; - snes->set_video_format(v->software_filter, SNES::PIXELFORMAT_RGB565); + snes->set_video_format(v->software_filter, v->video_standard, SNES::PIXELFORMAT_RGB565); if(v->manual_render_size == true) { settings.render_width = v->render_width; settings.render_height = v->render_height; } else { settings.render_width = 256; - settings.render_height = (v->video_standard == 0) ? 224 : 239; + settings.render_height = (v->video_standard == SNES::VIDEOSTANDARD_NTSC) ? 224 : 239; settings.render_width *= (v->multiplier + 1); settings.render_height *= (v->multiplier + 1); if(v->correct_aspect_ratio == true) { - settings.render_width = uint( double(settings.render_height) / 3.0 * 4.0 ); + settings.render_width = (uint)( (double)settings.render_height / 3.0 * 4.0 ); } } @@ -94,9 +94,9 @@ VideoSettings *v = &video_settings[profile]; settings.triple_buffering = v->triple_buffering; settings.enable_scanlines = v->enable_scanlines; - if(bool(config::video.fullscreen) == true) { - settings.resolution_width = (v->resolution_width) ? v->resolution_width : GetScreenWidth(); - settings.resolution_height = (v->resolution_height) ? v->resolution_height : GetScreenHeight(); + if((bool)config::video.fullscreen == true) { + settings.resolution_width = (v->resolution_width) ? v->resolution_width : screen_width(); + settings.resolution_height = (v->resolution_height) ? v->resolution_height : screen_height(); settings.refresh_rate = v->refresh_rate; } else { settings.resolution_width = settings.render_width; @@ -104,28 +104,19 @@ VideoSettings *v = &video_settings[profile]; settings.refresh_rate = 0; } - settings.internal_height_normal = 224; - settings.internal_height_overscan = (v->video_standard == 0) ? 224 : 239; - - settings.rx = (settings.resolution_width - settings.render_width) >> 1; - settings.ry = (settings.resolution_height - settings.render_height) >> 1; - settings.rw = (settings.render_width); - settings.rh = (settings.render_height); -} - -void Video::update_window() { -string t; - if(bool(config::video.fullscreen) == true) { - strcpy(t, "topmost|popup"); - if(wMain.Visible())strcat(t, "|visible"); - wMain.HideMenu(); - HideCursor(); + if(settings.render_width <= settings.resolution_width) { + settings.rx = (settings.resolution_width - settings.render_width) >> 1; + settings.rw = settings.render_width; } else { - strcpy(t, config::misc.window_style.sget()); - if(wMain.Visible())strcat(t, "|visible"); - wMain.ShowMenu(); - ShowCursor(); + settings.rx = 0; + settings.rw = settings.resolution_width; + } + + if(settings.render_height <= settings.resolution_height) { + settings.ry = (settings.resolution_height - settings.render_height) >> 1; + settings.rh = settings.render_height; + } else { + settings.ry = 0; + settings.rh = settings.resolution_height; } - wMain.SetStyle(strptr(t)); - wMain.Resize(settings.resolution_width, settings.resolution_height, true); } diff --git a/src/ui/video/video.h b/src/ui/video/video.h index dffc5def..0369e6ed 100644 --- a/src/ui/video/video.h +++ b/src/ui/video/video.h @@ -38,21 +38,21 @@ struct { uint resolution_height; uint refresh_rate; - uint internal_height_normal; - uint internal_height_overscan; - uint rx, ry, rw, rh; } settings; void update_video_settings(); - void update_window(); - virtual uint16 *lock(uint32 &pitch) = 0; + virtual uint16 *lock(uint &pitch) = 0; virtual void unlock() = 0; + virtual uint screen_width() = 0; + virtual uint screen_height() = 0; + + virtual bool update_video_profile() = 0; + virtual void clear_video() = 0; + virtual void pause_enable() {} virtual void pause_disable() {} - virtual void clear_video() = 0; - virtual bool update_video_profile() = 0; virtual void update_hardware_filter() {} virtual void update_scanlines() {} diff --git a/src/ui/bsnes.cpp b/src/ui/win/bsnes.cpp similarity index 94% rename from src/ui/bsnes.cpp rename to src/ui/win/bsnes.cpp index f776eeb5..7f93167a 100644 --- a/src/ui/bsnes.cpp +++ b/src/ui/win/bsnes.cpp @@ -84,7 +84,7 @@ void bSNES::sound_run(uint32 data) { *** video functions *** ***********************/ -uint16 *bSNES::video_lock(uint32 &pitch) { +uint16 *bSNES::video_lock(uint &pitch) { return uiVideo->lock(pitch); } diff --git a/src/ui/bsnes.h b/src/ui/win/bsnes.h similarity index 86% rename from src/ui/bsnes.h rename to src/ui/win/bsnes.h index 57867974..b1e11267 100644 --- a/src/ui/bsnes.h +++ b/src/ui/win/bsnes.h @@ -15,7 +15,7 @@ uint32 state; void sound_run(uint32 data); //video functions - uint16 *video_lock(uint32 &pitch); + uint16 *video_lock(uint &pitch); void video_unlock(); //input functions @@ -26,6 +26,4 @@ uint32 state; void notify(uint32 message, uint32 param1 = 0, uint32 param2 = 0); bSNES() { state = RUN; } -}; - -bSNES *bsnes; +} *bsnes; diff --git a/src/ui/win/event.cpp b/src/ui/win/event.cpp index 67390cfc..a9f0892c 100644 --- a/src/ui/win/event.cpp +++ b/src/ui/win/event.cpp @@ -27,6 +27,23 @@ void set_video_profile(uint profile) { if(profile > 7)profile = 0; config::video.profile = profile; + uiVideo->update_video_settings(); + +string t; + if(bool(config::video.fullscreen) == true) { + strcpy(t, "topmost|popup"); + if(wMain.Visible())strcat(t, "|visible"); + wMain.HideMenu(); + HideCursor(); + } else { + strcpy(t, config::misc.window_style.sget()); + if(wMain.Visible())strcat(t, "|visible"); + wMain.ShowMenu(); + ShowCursor(); + } + wMain.SetStyle(strptr(t)); + wMain.Resize(uiVideo->settings.resolution_width, uiVideo->settings.resolution_height, true); + uiVideo->update_video_profile(); wMain.CheckMenuItem(MENU_SETTINGS_VIDEOPROFILE_0, profile == 0); diff --git a/src/ui/win/main.cpp b/src/ui/win/main.cpp index ed5bdc05..75e17c26 100644 --- a/src/ui/win/main.cpp +++ b/src/ui/win/main.cpp @@ -3,15 +3,12 @@ #include "config.cpp" +#include "bsnes.h" + #include "event.h" #include "ui.h" -#include "../video/video.h" -#include "../audio/audio.h" -#include "../input/input.h" - -#include "../video/video.cpp" -#include "../input/input.cpp" +#include "bsnes.cpp" #include "../video/d3d.h" #include "../video/ddraw.h" diff --git a/src/ui/win/settings/ui_inputconfig.cpp b/src/ui/win/settings/ui_inputconfig.cpp index bb5a86be..c79caa8d 100644 --- a/src/ui/win/settings/ui_inputconfig.cpp +++ b/src/ui/win/settings/ui_inputconfig.cpp @@ -1,7 +1,6 @@ void CALLBACK wInputConfigInputTimerProc(HWND hwnd, UINT msg, UINT event, DWORD time) { if(!uiInput)return; - - uiInput->ui_poll_input(&wInputConfig, false); + ui_poll_input(&wInputConfig, false); } bool InputConfigWindow::Event(EventInfo &info) { @@ -13,13 +12,13 @@ bool InputConfigWindow::Event(EventInfo &info) { HDC hdcsrc = CreateCompatibleDC(hdc); HBITMAP hbm = LoadBitmap(GetModuleHandle(0), MAKEINTRESOURCE(102)); SelectObject(hdcsrc, hbm); - BitBlt(hdc, 285, 139, 190, 100, hdcsrc, 0, 0, SRCCOPY); + BitBlt(hdc, 285, 169, 190, 100, hdcsrc, 0, 0, SRCCOPY); DeleteDC(hdcsrc); DeleteObject(hbm); EndPaint(hwnd, &ps); } break; - case Input::EVENT_INPUTKEYDOWN: { + case EVENT_INPUTKEYDOWN: { if(button_update.active == true) { button_update.id = info.control_id; ButtonUpdateEnd(); @@ -42,19 +41,32 @@ bool InputConfigWindow::Event(EventInfo &info) { case EVENT_DOUBLECLICKED: { if(info.control == &ButtonList) { int sel = ButtonList.GetSelection(); - if(sel != -1)ButtonUpdateBegin(sel); + if(sel != -1) { + button_update.primary = true; + ButtonUpdateBegin(sel); + } } } break; case EVENT_CLICKED: { - if(info.control == &ButtonUpdate) { + if(info.control == &ButtonUpdatePrimary || + info.control == &ButtonUpdateSecondary) { int sel = ButtonList.GetSelection(); - if(sel != -1)ButtonUpdateBegin(sel); + if(sel != -1) { + button_update.primary = (info.control == &ButtonUpdatePrimary); + ButtonUpdateBegin(sel); + } } else if(info.control == &ButtonClear) { int sel = ButtonList.GetSelection(); if(sel != -1) { + button_update.primary = true; ButtonUpdateBegin(sel); - button_update.id = uiInput->keymap.esc; + button_update.id = uiInput->key.esc; + ButtonUpdateEnd(); + + button_update.primary = false; + ButtonUpdateBegin(sel); + button_update.id = uiInput->key.esc; ButtonUpdateEnd(); } } else if(info.control == &AllowBadInput) { @@ -100,9 +112,12 @@ 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))); \ + strcpy(tmp, uiInput->key.find((uiInput->get_key(device, SNES::JOYPAD_##__bn) >> 0) & 4095)); \ + strcat(tmp, " | "); \ + strcat(tmp, uiInput->key.find((uiInput->get_key(device, SNES::JOYPAD_##__bn) >> 16) & 4095)); \ split(part, " | ", tmp); \ - replace(part[0], "keynone", ""); \ + replace(part[0], "null", ""); \ + replace(part[1], "null", ""); \ if(count(part) < 2)strcpy(part[1], ""); \ sprintf(t, #__label "|%s|%s", strptr(part[0]), strptr(part[1])); \ ButtonList.AddItem(t); @@ -137,35 +152,19 @@ void InputConfigWindow::ButtonUpdateEnd() { button_update.active = false; KillTimer(hwnd, 0); -uint old_id, id = button_update.id; - if(id == uiInput->keymap.esc) { - //escape key was pressed, clear key + joy mapping - id = Input::JOYKEY_NONE; +uint id = button_update.id; + if(id == uiInput->key.esc) { id = 0; } + +uint old_id = uiInput->get_key(button_update.controller, button_update.button); + if(button_update.primary == true) { + id &= 0xffff; + id |= old_id & ~0xffff; } else { - old_id = uiInput->get_keymap(button_update.controller, button_update.button); - - if(id & Input::JOYFLAG) { - //joypad key was pressed - - //format for EVENT_INPUTKEY(DOWN|UP) is (joypad<<8)|button, - //format for config file is (joypad<<16)|(button<<8)|key. - //the idea is to allow config file to have both key and joypad - //mapping for a single SNES button, so id must be converted to - //config file format. - id <<= 8; - - id &= Input::JOYMASK; - id |= old_id & Input::KEYMASK; - } else { - //keyboard key was pressed - id &= Input::KEYMASK; - id |= old_id & Input::JOYMASK; - } - - id &= Input::JOYKEYMASK; + id <<= 16; + id |= old_id & 0xffff; } - uiInput->set_keymap(button_update.controller, button_update.button, id); + uiInput->set_key(button_update.controller, button_update.button, id); Message.SetText("Button updated. Select another button to update."); int sel = ButtonList.GetSelection(); @@ -215,10 +214,11 @@ int x = 15, y = 30; 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"); + ButtonList.AddColumn(Listview::LEFT, 100, "Primary"); + ButtonList.AddColumn(Listview::LEFT, 100, "Secondary"); + ButtonUpdatePrimary.Create(this, "visible", x + 270, y, 92, 25, "Set Primary"); + ButtonUpdateSecondary.Create(this, "visible", x + 270 + 98, y, 92, 25, "Set Secondary"); + ButtonClear.Create(this, "visible", x + 270, y + 30, 190, 25, "Clear Primary + Secondary"); y += 200; AllowBadInput.Create(this, "visible", x, y, 460, 15, diff --git a/src/ui/win/settings/ui_inputconfig.h b/src/ui/win/settings/ui_inputconfig.h index bd248a6c..32d698a3 100644 --- a/src/ui/win/settings/ui_inputconfig.h +++ b/src/ui/win/settings/ui_inputconfig.h @@ -8,11 +8,13 @@ Combobox Selected; Label Separator; Label Message; Listview ButtonList; -Button ButtonUpdate; +Button ButtonUpdatePrimary; +Button ButtonUpdateSecondary; Button ButtonClear; Checkbox AllowBadInput; struct { + bool primary; bool active; uint controller; uint button; diff --git a/src/ui/win/settings/ui_videosettings.cpp b/src/ui/win/settings/ui_videosettings.cpp index 284ac758..a387a4c0 100644 --- a/src/ui/win/settings/ui_videosettings.cpp +++ b/src/ui/win/settings/ui_videosettings.cpp @@ -62,8 +62,8 @@ char t[64 + 1]; save_video_settings(profile); //update current video mode if necessary - if(profile == uint(config::video.profile)) { - uiVideo->update_video_profile(); + if(profile == (uint)config::video.profile) { + event::set_video_profile(config::video.profile); } } @@ -97,8 +97,8 @@ int x = 15, y = 30; y += 25; VideoStandardLabel.Create(this, "visible", x, y + 3, 85, 15, "Video standard:"); - VideoStandard.Create(this, "visible|disabled", x + 85, y, 140, 200, - "NTSC|PAL|PAL (centered)"); + VideoStandard.Create(this, "visible", x + 85, y, 140, 200, + "NTSC|PAL"); MultiplierLabel.Create(this, "visible", x + 235, y + 3, 85, 15, "Multiplier:"); Multiplier.Create(this, "visible", x + 320, y, 140, 200, diff --git a/src/ui/win/ui.cpp b/src/ui/win/ui.cpp index 1afad2b7..0e963a72 100644 --- a/src/ui/win/ui.cpp +++ b/src/ui/win/ui.cpp @@ -1,3 +1,4 @@ +#include "ui_input.cpp" #include "ui_main.cpp" #include "ui_about.cpp" #include "settings/settings.cpp" diff --git a/src/ui/win/ui.h b/src/ui/win/ui.h index cd5b67d3..b40d36d2 100644 --- a/src/ui/win/ui.h +++ b/src/ui/win/ui.h @@ -1,5 +1,10 @@ #define KeyDown(__key) ((GetAsyncKeyState(__key) & 0x8000) ? 1 : 0) +enum { + EVENT_INPUTKEYDOWN = EVENT_USER + 0, + EVENT_INPUTKEYUP = EVENT_USER + 1, +}; + namespace global { Font vwf, fwf, font_about, font_header, font_list; }; diff --git a/src/ui/win/ui_about.cpp b/src/ui/win/ui_about.cpp index cc6bfcf2..ad71cd81 100644 --- a/src/ui/win/ui_about.cpp +++ b/src/ui/win/ui_about.cpp @@ -5,7 +5,7 @@ const char AboutWindow::about_text[4096] = "" "\r\n\r\n\r\n\r\n\r\n" "Contributors:\r\n" " anomie, blargg, DMV27, GIGO, kode54, Nach,\r\n" - " Overload, Richard Bannister, TRAC\r\n"; + " Overload, Richard Bannister, TRAC, zones\r\n"; bool AboutWindow::Event(EventInfo &info) { switch(info.event_id) { diff --git a/src/ui/win/ui_input.cpp b/src/ui/win/ui_input.cpp new file mode 100644 index 00000000..5f48e9a5 --- /dev/null +++ b/src/ui/win/ui_input.cpp @@ -0,0 +1,29 @@ +bool8 old_keystate[4096]; + +void ui_poll_input(Window *focus, bool require_window_focus = true) { + if(require_window_focus == true) { + if(GetFocus() != focus->hwnd)return; + } + + uiInput->poll(); + +bool8 *keystate = uiInput->keystate; +EventInfo info; + info.window = focus; + info.window_id = focus->id; + info.control = 0; + + for(int i = 0; i < 4096; i++) { + if(!old_keystate[i] && keystate[i]) { + info.event_id = EVENT_INPUTKEYDOWN; + info.control_id = i; + focus->Event(info); + } else if(old_keystate[i] && !keystate[i]) { + info.event_id = EVENT_INPUTKEYUP; + info.control_id = i; + focus->Event(info); + } + } + + memcpy(old_keystate, keystate, sizeof(keystate)); +} diff --git a/src/ui/win/ui_main.cpp b/src/ui/win/ui_main.cpp index ca355bef..f86f2891 100644 --- a/src/ui/win/ui_main.cpp +++ b/src/ui/win/ui_main.cpp @@ -1,7 +1,5 @@ void CALLBACK wMainInputTimerProc(HWND hwnd, UINT msg, UINT event, DWORD time) { - if(!uiInput)return; - - uiInput->ui_poll_input(&wMain); + if(uiInput) { ui_poll_input(&wMain); } } void MainWindow::SetFrameskip(uint fs) { @@ -42,11 +40,11 @@ void MainWindow::SetRegulationSpeed(uint speed) { bool MainWindow::Event(EventInfo &info) { switch(info.event_id) { - case Input::EVENT_INPUTKEYDOWN: { - Input::Keymap *keymap = &uiInput->keymap; - uint key = info.control_id; - bool ctrl = uiInput->keydown(keymap->lctrl) || uiInput->keydown(keymap->rctrl); - if(key == keymap->esc) { + case EVENT_INPUTKEYDOWN: { + keymap *key = &uiInput->key; + uint id = info.control_id; + bool ctrl = uiInput->keydown(key->lctrl) || uiInput->keydown(key->rctrl); + if(id == key->esc) { if(bool(config::video.fullscreen) == false) { ShowMenu(!MenuVisible()); Center(); @@ -54,37 +52,37 @@ bool MainWindow::Event(EventInfo &info) { config::video.fullscreen = false; event::set_video_profile(config::video.profile); } - } else if(key == keymap->f11) { + } else if(id == key->f11) { event::toggle_fullscreen(); - } else if(key == keymap->f12) { + } else if(id == key->f12) { if(bsnes->get_state() == bSNES::RUN) { bsnes->set_state(bSNES::STOP); } else if(bsnes->get_state() == bSNES::STOP) { bsnes->set_state(bSNES::RUN); } - } else if(key == keymap->num_1 && ctrl) { + } else if(id == key->num_1 && ctrl) { event::set_video_profile(0); - } else if(key == keymap->num_2 && ctrl) { + } else if(id == key->num_2 && ctrl) { event::set_video_profile(1); - } else if(key == keymap->num_3 && ctrl) { + } else if(id == key->num_3 && ctrl) { event::set_video_profile(2); - } else if(key == keymap->num_4 && ctrl) { + } else if(id == key->num_4 && ctrl) { event::set_video_profile(3); - } else if(key == keymap->num_5 && ctrl) { + } else if(id == key->num_5 && ctrl) { event::set_video_profile(4); - } else if(key == keymap->num_6 && ctrl) { + } else if(id == key->num_6 && ctrl) { event::set_video_profile(5); - } else if(key == keymap->num_7 && ctrl) { + } else if(id == key->num_7 && ctrl) { event::set_video_profile(6); - } else if(key == keymap->num_8 && ctrl) { + } else if(id == key->num_8 && ctrl) { event::set_video_profile(7); - } else if((key == keymap->minus && !ctrl) || key == keymap->numpad_minus) { + } else if((id == key->minus && !ctrl) || id == key->numpad_minus) { if(frameskip > 0)SetFrameskip(frameskip - 1); - } else if((key == keymap->plus && !ctrl) || key == keymap->numpad_plus) { + } else if((id == key->plus && !ctrl) || id == key->numpad_plus) { if(frameskip < 9)SetFrameskip(frameskip + 1); - } else if(key == keymap->minus && ctrl) { + } else if(id == key->minus && ctrl) { if(regulation_speed > 0)SetRegulationSpeed(regulation_speed - 1); - } else if(key == keymap->plus && ctrl) { + } else if(id == key->plus && ctrl) { if(regulation_speed < 4)SetRegulationSpeed(regulation_speed + 1); } } break;