Update to bsnes v015 rc3 release.

[No changelog available]
This commit is contained in:
byuu 2006-04-22 01:02:32 +00:00
parent 9f63cb1b99
commit 6b6233b3af
30 changed files with 470 additions and 376 deletions

View File

@ -1,4 +1,4 @@
#define BSNES_VERSION "0.015 rc2" //wip45
#define BSNES_VERSION "0.015 rc3" //wip47
#define BSNES_TITLE "bsnes v" BSNES_VERSION
#define MEMCORE bMemBus
@ -19,8 +19,8 @@
//enable JMA support
//#define JMA_SUPPORT
//snes core polymorphism (allow mem/cpu/apu/ppu overriding,
//~10% speed hit)
//snes core polymorphism
//(allow mem/cpu/apu/ppu overriding, ~10% speed hit)
//#define POLYMORPHISM
//this should be declared in the port-specific makefiles

View File

@ -1,11 +1,18 @@
#include "../base.h"
/*****
* string <> binary code translation routines
* decode() "7e1234:56" -> 0x7e123456
* encode() 0x7e123456 -> "7e1234:56"
*****/
bool Cheat::decode(char *str, uint32 &addr, uint8 &data, uint8 &type) {
string t, part;
strcpy(t, str);
strlower(t);
if(strlen(t) == 8) {
if(strlen(t) == 8 || (strlen(t) == 9 && strptr(t)[6] == ':')) {
type = CT_PRO_ACTION_REPLAY;
replace(t, ":", "");
uint32 r = strhex(t);
addr = r >> 8;
data = r & 0xff;
@ -38,7 +45,7 @@ string t, part;
bool Cheat::encode(char *str, uint32 addr, uint8 data, uint8 type) {
if(type == CT_PRO_ACTION_REPLAY) {
sprintf(str, "%0.6x%0.2x", addr, data);
sprintf(str, "%0.6x:%0.2x", addr, data);
return true;
} else if(type == CT_GAME_GENIE) {
uint32 r = addr;
@ -61,8 +68,83 @@ bool Cheat::encode(char *str, uint32 addr, uint8 data, uint8 type) {
return false;
}
//enable cheat system when at least one cheat is enabled,
//disable otherwise to speed up emulation
/*****
* address lookup table manipulation and mirroring
* mirror_address() 0x000000 -> 0x7e0000
* set() enable specified address, mirror accordingly
* clear() disable specified address, mirror accordingly
*****/
uint Cheat::mirror_address(uint addr) {
if((addr & 0x40e000) != 0x0000)return addr;
//8k WRAM mirror
//$[00-3f|80-bf]:[0000-1fff] -> $7e:[0000-1fff]
return (0x7e0000 + (addr & 0x1fff));
}
void Cheat::set(uint32 addr) {
addr = mirror_address(addr);
mask[addr >> 3] |= 1 << (addr & 7);
if((addr & 0xffe000) == 0x7e0000) {
//mirror $7e:[0000-1fff] to $[00-3f|80-bf]:[0000-1fff]
uint mirror;
for(int x = 0; x <= 0x3f; x++) {
mirror = ((0x00 + x) << 16) + (addr & 0x1fff);
mask[mirror >> 3] |= 1 << (mirror & 7);
mirror = ((0x80 + x) << 16) + (addr & 0x1fff);
mask[mirror >> 3] |= 1 << (mirror & 7);
}
}
}
void Cheat::clear(uint32 addr) {
addr = mirror_address(addr);
//is there more than one cheat code using the same address
//(and likely a different override value) that is enabled?
//if so, do not clear code lookup table entry for this address.
uint8 r;
if(read(addr, r) == true)return;
mask[addr >> 3] &= ~(1 << (addr & 7));
if((addr & 0xffe000) == 0x7e0000) {
//mirror $7e:[0000-1fff] to $[00-3f|80-bf]:[0000-1fff]
uint mirror;
for(int x = 0; x <= 0x3f; x++) {
mirror = ((0x00 + x) << 16) + (addr & 0x1fff);
mask[mirror >> 3] &= ~(1 << (mirror & 7));
mirror = ((0x80 + x) << 16) + (addr & 0x1fff);
mask[mirror >> 3] &= ~(1 << (mirror & 7));
}
}
}
/*****
* read() is used by MemBus::read() if Cheat::enabled(addr)
* returns true to look up cheat code.
* returns true if cheat code was found, false if it was not.
* when true, cheat code substitution value is stored in data.
*****/
bool Cheat::read(uint32 addr, uint8 &data) {
addr = mirror_address(addr);
for(int i = 0; i < cheat_count; i++) {
if(enabled(i) == false)continue;
if(addr == mirror_address(index[i].addr)) {
data = index[i].data;
return true;
}
}
//code not found, or code is disabled
return false;
}
/*****
* update_cheat_status() will scan to see if any codes are
* enabled. if any are, make sure the cheat system is on.
* otherwise, turn cheat system off to speed up emulation.
*****/
void Cheat::update_cheat_status() {
for(int i = 0; i < cheat_count; i++) {
if(index[i].enabled) {
@ -73,18 +155,9 @@ void Cheat::update_cheat_status() {
cheat_enabled = false;
}
uint8 Cheat::read(uint32 addr) {
addr &= 0xffffff;
for(int i = 0; i < cheat_count; i++) {
if(index[i].addr == addr) {
return index[i].data;
}
}
//cheat not found? disable and return 0
clear(addr);
return 0x00;
}
/*****
* cheat list manipulation routines
*****/
bool Cheat::add(bool enable, char *code, char *desc) {
if(cheat_count >= CHEAT_LIMIT)return false;
@ -93,7 +166,6 @@ uint32 addr, len;
uint8 data, type;
if(decode(code, addr, data, type) == false)return false;
(enable) ? set(addr) : clear(addr);
index[cheat_count].enabled = enable;
index[cheat_count].addr = addr;
index[cheat_count].data = data;
@ -106,6 +178,7 @@ uint8 data, type;
memcpy(index[cheat_count].desc, desc, len);
index[cheat_count].desc[len] = 0;
cheat_count++;
(enable) ? set(addr) : clear(addr);
update_cheat_status();
return true;
@ -118,8 +191,11 @@ uint32 addr, len;
uint8 data, type;
if(decode(code, addr, data, type) == false)return false;
//disable current code and clear from code lookup table
index[n].enabled = false;
clear(index[n].addr);
set(addr);
//update code and enable in code lookup table
index[n].enabled = enable;
index[n].addr = addr;
index[n].data = data;
@ -131,6 +207,7 @@ uint8 data, type;
len = len > 128 ? 128 : len;
memcpy(index[n].desc, desc, len);
index[n].desc[len] = 0;
set(addr);
update_cheat_status();
return true;
@ -162,6 +239,10 @@ bool Cheat::get(uint32 n, bool &enable, uint32 &addr, uint8 &data, char *code, c
return true;
}
/*****
* code status modifier routines
*****/
bool Cheat::enabled(uint32 n) {
if(n >= cheat_count)return false;
return index[n].enabled;
@ -169,18 +250,22 @@ bool Cheat::enabled(uint32 n) {
void Cheat::enable(uint32 n) {
if(n >= cheat_count)return;
set(index[n].addr);
index[n].enabled = true;
set(index[n].addr);
update_cheat_status();
}
void Cheat::disable(uint32 n) {
if(n >= cheat_count)return;
clear(index[n].addr);
index[n].enabled = false;
clear(index[n].addr);
update_cheat_status();
}
/*****
* cheat file manipulation routines
*****/
bool Cheat::load(Reader *rf) {
if(!rf->ready())return false;
@ -227,6 +312,10 @@ char t[4096];
return true;
}
/*****
* initialization routines
*****/
void Cheat::clear() {
cheat_enabled = false;
cheat_count = 0;

View File

@ -17,15 +17,20 @@ uint8 mask[0x200000];
inline bool enabled() { return cheat_enabled; }
inline uint count() { return cheat_count; }
inline bool exists(uint32 addr) { return !!(mask[addr >> 3] & 1 << (addr & 7)); }
inline void set(uint32 addr) { mask[addr >> 3] |= 1 << (addr & 7); }
inline void clear(uint32 addr) { mask[addr >> 3] &= ~(1 << (addr & 7)); }
inline bool exists(uint32 addr) { return bool(mask[addr >> 3] & 1 << (addr & 7)); }
bool decode(char *str, uint32 &addr, uint8 &data, uint8 &type);
bool encode(char *str, uint32 addr, uint8 data, uint8 type);
private:
uint mirror_address(uint addr);
void set(uint32 addr);
void clear(uint32 addr);
public:
bool read(uint32 addr, uint8 &data);
void update_cheat_status();
uint8 read(uint32 addr);
bool add(bool enable, char *code, char *desc);
bool edit(uint32 n, bool enable, char *code, char *desc);
bool get(uint32 n, bool &enable, uint32 &addr, uint8 &data, char *code, char *desc);

View File

@ -411,7 +411,7 @@ void bCPU::mmio_w2183(uint8 value) {
//strobing $4016.d0 affects both controller port latches.
//$4017 bit 0 writes are ignored.
void bCPU::mmio_w4016(uint8 value) {
status.joypad_strobe_latch = !!(value & 1);
status.joypad_strobe_latch = bool(value & 1);
if(status.joypad_strobe_latch == 1) {
snes->poll_input(SNES::DEV_JOYPAD1);
@ -423,10 +423,10 @@ void bCPU::mmio_w4016(uint8 value) {
//NMITIMEN
void bCPU::mmio_w4200(uint8 value) {
status.nmi_enabled = !!(value & 0x80);
status.virq_enabled = !!(value & 0x20);
status.hirq_enabled = !!(value & 0x10);
status.auto_joypad_poll = !!(value & 0x01);
status.nmi_enabled = bool(value & 0x80);
status.virq_enabled = bool(value & 0x20);
status.hirq_enabled = bool(value & 0x10);
status.auto_joypad_poll = bool(value & 0x01);
if(time.nmi_read == 0) {
if(time.nmi_line == 1 && !status.nmi_enabled == 0) {
@ -522,9 +522,9 @@ int len;
//HDMAEN
void bCPU::mmio_w420c(uint8 value) {
for(int i=0;i<8;i++) {
channel[i].hdma_enabled = !!(value & (1 << i));
channel[i].hdma_active = !!(value & (1 << i));
for(int i = 0; i < 8; i++) {
channel[i].hdma_enabled = bool(value & (1 << i));
channel[i].hdma_active = bool(value & (1 << i));
}
}
@ -536,10 +536,10 @@ void bCPU::mmio_w420d(uint8 value) {
//DMAPx
void bCPU::mmio_w43x0(uint8 value, uint8 i) {
channel[i].dmap = value;
channel[i].direction = !!(value & 0x80);
channel[i].hdma_indirect = !!(value & 0x40);
channel[i].incmode = (value & 0x10)?-1:1;
channel[i].fixedxfer = !!(value & 0x08);
channel[i].direction = bool(value & 0x80);
channel[i].hdma_indirect = bool(value & 0x40);
channel[i].incmode = (value & 0x10) ? -1 : 1;
channel[i].fixedxfer = bool(value & 0x08);
channel[i].xfermode = value & 7;
}

View File

@ -183,7 +183,7 @@ static uint8 hdma_xferlen[8] = { 1, 2, 2, 4, 4, 4, 2, 4 };
}
channel[i].hdma_line_counter--;
channel[i].hdma_do_transfer = !!(channel[i].hdma_line_counter & 0x80);
channel[i].hdma_do_transfer = bool(channel[i].hdma_line_counter & 0x80);
if((channel[i].hdma_line_counter & 0x7f) == 0) {
hdma_update(i);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View File

@ -1,5 +1,5 @@
/*
libbase : version 0.06 ~byuu (02/18/06)
libbase : version 0.07 ~byuu (04/21/06)
*/
#ifndef __LIBBASE
@ -12,14 +12,14 @@
#include <time.h>
#include <math.h>
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#define SafeFree(__n) if(__n) { free(__n); __n = 0; }
#define SafeDelete(__n) if(__n) { delete(__n); __n = 0; }
#define SafeRelease(__n) if(__n) { __n->Release(); __n = 0; }
@ -42,6 +42,16 @@ typedef signed short int16;
typedef signed long int32;
typedef signed long long int64;
template<typename T> void swap(T &x, T &y) {
T z = x;
x = y;
y = z;
}
template<typename T, typename Targ> T bound_range(T &x, Targ min, Targ max) {
return (x < T(min)) ? T(min) : (x > T(max)) ? T(max) : x;
}
inline bool fexists(const char *fn) {
FILE *fp = fopen(fn, "rb");
if(!fp)return false;

View File

@ -313,6 +313,7 @@ void Window::SetIcon(uint resource_id) {
void Window::Show(bool do_show) {
if(do_show == true) {
if(Visible() == false)Resize();
ShowWindow(hwnd, SW_NORMAL);
state.ws |= WS_VISIBLE;
} else {

View File

@ -106,7 +106,7 @@ uint8 r;
#ifdef CHEAT_SYSTEM
if(cheat.enabled()) {
if(cheat.exists(addr)) {
return cheat.read(addr);
if(cheat.read(addr, r) == true)return r;
}
}
#endif

View File

@ -67,7 +67,7 @@ uint16 hc = r_cpu->hcycles();
//INIDISP
void bPPU::mmio_w2100(uint8 value) {
regs.display_disabled = !!(value & 0x80);
regs.display_disabled = bool(value & 0x80);
regs.display_brightness = value & 15;
}
@ -86,7 +86,7 @@ void bPPU::mmio_w2102(uint8 value) {
//OAMADDH
void bPPU::mmio_w2103(uint8 value) {
regs.oam_priority = !!(value & 0x80);
regs.oam_priority = bool(value & 0x80);
regs.oam_baseaddr = ((value & 1) << 8) | (regs.oam_baseaddr & 0xff);
regs.oam_addr = regs.oam_baseaddr << 1;
}
@ -110,11 +110,11 @@ void bPPU::mmio_w2104(uint8 value) {
//BGMODE
void bPPU::mmio_w2105(uint8 value) {
regs.bg_tilesize[BG4] = !!(value & 0x80);
regs.bg_tilesize[BG3] = !!(value & 0x40);
regs.bg_tilesize[BG2] = !!(value & 0x20);
regs.bg_tilesize[BG1] = !!(value & 0x10);
regs.bg3_priority = !!(value & 0x08);
regs.bg_tilesize[BG4] = bool(value & 0x80);
regs.bg_tilesize[BG3] = bool(value & 0x40);
regs.bg_tilesize[BG2] = bool(value & 0x20);
regs.bg_tilesize[BG1] = bool(value & 0x10);
regs.bg3_priority = bool(value & 0x08);
regs.bg_mode = (value & 7);
regs.hires = (regs.bg_mode == 5 || regs.bg_mode == 6);
}
@ -122,10 +122,10 @@ void bPPU::mmio_w2105(uint8 value) {
//MOSAIC
void bPPU::mmio_w2106(uint8 value) {
regs.mosaic_size = (value >> 4) & 15;
regs.mosaic_enabled[BG4] = !!(value & 0x08);
regs.mosaic_enabled[BG3] = !!(value & 0x04);
regs.mosaic_enabled[BG2] = !!(value & 0x02);
regs.mosaic_enabled[BG1] = !!(value & 0x01);
regs.mosaic_enabled[BG4] = bool(value & 0x08);
regs.mosaic_enabled[BG3] = bool(value & 0x04);
regs.mosaic_enabled[BG2] = bool(value & 0x02);
regs.mosaic_enabled[BG1] = bool(value & 0x01);
}
//BG1SC
@ -220,7 +220,7 @@ void bPPU::mmio_w2114(uint8 value) {
//VMAIN
void bPPU::mmio_w2115(uint8 value) {
regs.vram_incmode = !!(value & 0x80);
regs.vram_incmode = bool(value & 0x80);
regs.vram_mapping = (value >> 2) & 3;
switch(value & 3) {
case 0:regs.vram_incsize = 1;break;
@ -287,8 +287,8 @@ uint16 addr = get_vram_address() + 1;
//M7SEL
void bPPU::mmio_w211a(uint8 value) {
regs.mode7_repeat = (value >> 6) & 3;
regs.mode7_vflip = !!(value & 0x02);
regs.mode7_hflip = !!(value & 0x01);
regs.mode7_vflip = bool(value & 0x02);
regs.mode7_hflip = bool(value & 0x01);
}
//M7A
@ -347,38 +347,38 @@ void bPPU::mmio_w2122(uint8 value) {
//W12SEL
void bPPU::mmio_w2123(uint8 value) {
regs.window2_enabled[BG2] = !!(value & 0x80);
regs.window2_invert [BG2] = !!(value & 0x40);
regs.window1_enabled[BG2] = !!(value & 0x20);
regs.window1_invert [BG2] = !!(value & 0x10);
regs.window2_enabled[BG1] = !!(value & 0x08);
regs.window2_invert [BG1] = !!(value & 0x04);
regs.window1_enabled[BG1] = !!(value & 0x02);
regs.window1_invert [BG1] = !!(value & 0x01);
regs.window2_enabled[BG2] = bool(value & 0x80);
regs.window2_invert [BG2] = bool(value & 0x40);
regs.window1_enabled[BG2] = bool(value & 0x20);
regs.window1_invert [BG2] = bool(value & 0x10);
regs.window2_enabled[BG1] = bool(value & 0x08);
regs.window2_invert [BG1] = bool(value & 0x04);
regs.window1_enabled[BG1] = bool(value & 0x02);
regs.window1_invert [BG1] = bool(value & 0x01);
}
//W34SEL
void bPPU::mmio_w2124(uint8 value) {
regs.window2_enabled[BG4] = !!(value & 0x80);
regs.window2_invert [BG4] = !!(value & 0x40);
regs.window1_enabled[BG4] = !!(value & 0x20);
regs.window1_invert [BG4] = !!(value & 0x10);
regs.window2_enabled[BG3] = !!(value & 0x08);
regs.window2_invert [BG3] = !!(value & 0x04);
regs.window1_enabled[BG3] = !!(value & 0x02);
regs.window1_invert [BG3] = !!(value & 0x01);
regs.window2_enabled[BG4] = bool(value & 0x80);
regs.window2_invert [BG4] = bool(value & 0x40);
regs.window1_enabled[BG4] = bool(value & 0x20);
regs.window1_invert [BG4] = bool(value & 0x10);
regs.window2_enabled[BG3] = bool(value & 0x08);
regs.window2_invert [BG3] = bool(value & 0x04);
regs.window1_enabled[BG3] = bool(value & 0x02);
regs.window1_invert [BG3] = bool(value & 0x01);
}
//WOBJSEL
void bPPU::mmio_w2125(uint8 value) {
regs.window2_enabled[COL] = !!(value & 0x80);
regs.window2_invert [COL] = !!(value & 0x40);
regs.window1_enabled[COL] = !!(value & 0x20);
regs.window1_invert [COL] = !!(value & 0x10);
regs.window2_enabled[OAM] = !!(value & 0x08);
regs.window2_invert [OAM] = !!(value & 0x04);
regs.window1_enabled[OAM] = !!(value & 0x02);
regs.window1_invert [OAM] = !!(value & 0x01);
regs.window2_enabled[COL] = bool(value & 0x80);
regs.window2_invert [COL] = bool(value & 0x40);
regs.window1_enabled[COL] = bool(value & 0x20);
regs.window1_invert [COL] = bool(value & 0x10);
regs.window2_enabled[OAM] = bool(value & 0x08);
regs.window2_invert [OAM] = bool(value & 0x04);
regs.window1_enabled[OAM] = bool(value & 0x02);
regs.window1_invert [OAM] = bool(value & 0x01);
}
//WH0
@ -417,58 +417,58 @@ void bPPU::mmio_w212b(uint8 value) {
//TM
void bPPU::mmio_w212c(uint8 value) {
regs.bg_enabled[OAM] = !!(value & 0x10);
regs.bg_enabled[BG4] = !!(value & 0x08);
regs.bg_enabled[BG3] = !!(value & 0x04);
regs.bg_enabled[BG2] = !!(value & 0x02);
regs.bg_enabled[BG1] = !!(value & 0x01);
regs.bg_enabled[OAM] = bool(value & 0x10);
regs.bg_enabled[BG4] = bool(value & 0x08);
regs.bg_enabled[BG3] = bool(value & 0x04);
regs.bg_enabled[BG2] = bool(value & 0x02);
regs.bg_enabled[BG1] = bool(value & 0x01);
}
//TS
void bPPU::mmio_w212d(uint8 value) {
regs.bgsub_enabled[OAM] = !!(value & 0x10);
regs.bgsub_enabled[BG4] = !!(value & 0x08);
regs.bgsub_enabled[BG3] = !!(value & 0x04);
regs.bgsub_enabled[BG2] = !!(value & 0x02);
regs.bgsub_enabled[BG1] = !!(value & 0x01);
regs.bgsub_enabled[OAM] = bool(value & 0x10);
regs.bgsub_enabled[BG4] = bool(value & 0x08);
regs.bgsub_enabled[BG3] = bool(value & 0x04);
regs.bgsub_enabled[BG2] = bool(value & 0x02);
regs.bgsub_enabled[BG1] = bool(value & 0x01);
}
//TMW
void bPPU::mmio_w212e(uint8 value) {
regs.window_enabled[OAM] = !!(value & 0x10);
regs.window_enabled[BG4] = !!(value & 0x08);
regs.window_enabled[BG3] = !!(value & 0x04);
regs.window_enabled[BG2] = !!(value & 0x02);
regs.window_enabled[BG1] = !!(value & 0x01);
regs.window_enabled[OAM] = bool(value & 0x10);
regs.window_enabled[BG4] = bool(value & 0x08);
regs.window_enabled[BG3] = bool(value & 0x04);
regs.window_enabled[BG2] = bool(value & 0x02);
regs.window_enabled[BG1] = bool(value & 0x01);
}
//TSW
void bPPU::mmio_w212f(uint8 value) {
regs.sub_window_enabled[OAM] = !!(value & 0x10);
regs.sub_window_enabled[BG4] = !!(value & 0x08);
regs.sub_window_enabled[BG3] = !!(value & 0x04);
regs.sub_window_enabled[BG2] = !!(value & 0x02);
regs.sub_window_enabled[BG1] = !!(value & 0x01);
regs.sub_window_enabled[OAM] = bool(value & 0x10);
regs.sub_window_enabled[BG4] = bool(value & 0x08);
regs.sub_window_enabled[BG3] = bool(value & 0x04);
regs.sub_window_enabled[BG2] = bool(value & 0x02);
regs.sub_window_enabled[BG1] = bool(value & 0x01);
}
//CGWSEL
void bPPU::mmio_w2130(uint8 value) {
regs.color_mask = (value >> 6) & 3;
regs.colorsub_mask = (value >> 4) & 3;
regs.addsub_mode = !!(value & 0x02);
regs.direct_color = !!(value & 0x01);
regs.addsub_mode = bool(value & 0x02);
regs.direct_color = bool(value & 0x01);
}
//CGADDSUB
void bPPU::mmio_w2131(uint8 value) {
regs.color_mode = !!(value & 0x80);
regs.color_halve = !!(value & 0x40);
regs.color_enabled[BACK] = !!(value & 0x20);
regs.color_enabled[OAM] = !!(value & 0x10);
regs.color_enabled[BG4] = !!(value & 0x08);
regs.color_enabled[BG3] = !!(value & 0x04);
regs.color_enabled[BG2] = !!(value & 0x02);
regs.color_enabled[BG1] = !!(value & 0x01);
regs.color_mode = bool(value & 0x80);
regs.color_halve = bool(value & 0x40);
regs.color_enabled[BACK] = bool(value & 0x20);
regs.color_enabled[OAM] = bool(value & 0x10);
regs.color_enabled[BG4] = bool(value & 0x08);
regs.color_enabled[BG3] = bool(value & 0x04);
regs.color_enabled[BG2] = bool(value & 0x02);
regs.color_enabled[BG1] = bool(value & 0x01);
}
//COLDATA
@ -482,11 +482,11 @@ void bPPU::mmio_w2132(uint8 value) {
//SETINI
void bPPU::mmio_w2133(uint8 value) {
regs.mode7_extbg = !!(value & 0x40);
regs.pseudo_hires = !!(value & 0x08);
regs.overscan = !!(value & 0x04);
regs.oam_interlace = !!(value & 0x02);
regs.interlace = !!(value & 0x01);
regs.mode7_extbg = bool(value & 0x40);
regs.pseudo_hires = bool(value & 0x08);
regs.overscan = bool(value & 0x04);
regs.oam_interlace = bool(value & 0x02);
regs.interlace = bool(value & 0x01);
r_cpu->set_overscan(regs.overscan);
}

View File

@ -147,18 +147,18 @@ int32 prev_x = -1, prev_y = -1;
t = bg_get_tile(bg, mosaic_x, mosaic_y);
mirror_y = !!(t & 0x8000);
mirror_x = !!(t & 0x4000);
mirror_y = bool(t & 0x8000);
mirror_x = bool(t & 0x4000);
tile_pri = (t & 0x2000) ? pri1_pos : pri0_pos;
tile_num = t;
if(tile_width == 4) { //16x16 horizontal tile mirroring
if(!!(mosaic_x & 8) != mirror_x)tile_num++;
if(bool(mosaic_x & 8) != mirror_x)tile_num++;
}
if(tile_height == 4) { //16x16 vertical tile mirroring
if(!!(mosaic_y & 8) != mirror_y)tile_num += 16;
if(bool(mosaic_y & 8) != mirror_y)tile_num += 16;
}
tile_num &= 0x03ff;

View File

@ -2,8 +2,8 @@ void bPPU::build_sprite_list() {
uint8 *tableA = oam, *tableB = oam + 512;
for(int i = 0; i < 128; i++) {
uint x = !!(*tableB & (1 << ((i & 3) << 1))); //0x01, 0x04, 0x10, 0x40
bool size = !!(*tableB & (2 << ((i & 3) << 1))); //0x02, 0x08, 0x20, 0x80
uint x = bool(*tableB & (1 << ((i & 3) << 1))); //0x01, 0x04, 0x10, 0x40
bool size = bool(*tableB & (2 << ((i & 3) << 1))); //0x02, 0x08, 0x20, 0x80
switch(regs.oam_basesize) {
case 0: sprite_list[i].width = (!size) ? 8 : 16;
@ -35,8 +35,8 @@ uint8 *tableA = oam, *tableB = oam + 512;
sprite_list[i].x = (x << 8) + tableA[0];
sprite_list[i].y = tableA[1] + 1;
sprite_list[i].character = tableA[2];
sprite_list[i].vflip = !!(tableA[3] & 0x80);
sprite_list[i].hflip = !!(tableA[3] & 0x40);
sprite_list[i].vflip = bool(tableA[3] & 0x80);
sprite_list[i].hflip = bool(tableA[3] & 0x40);
sprite_list[i].priority = (tableA[3] >> 4) & 3;
sprite_list[i].palette = (tableA[3] >> 1) & 7;
sprite_list[i].use_nameselect = tableA[3] & 1;

View File

@ -39,9 +39,7 @@ uint16 window2_right = regs.window2_right;
}
if(regs.window1_enabled[bg] == true && regs.window2_enabled[bg] == false) {
if(regs.window1_invert[bg] == true) {
set ^= clr; clr ^= set; set ^= clr;
}
if(regs.window1_invert[bg] == true)swap(set, clr);
for(int x = 0; x < 256; x++) {
wtbl[x] = (x >= window1_left && x <= window1_right) ? set : clr;
}
@ -49,9 +47,7 @@ uint16 window2_right = regs.window2_right;
}
if(regs.window1_enabled[bg] == false && regs.window2_enabled[bg] == true) {
if(regs.window2_invert[bg] == true) {
set ^= clr; clr ^= set; set ^= clr;
}
if(regs.window2_invert[bg] == true)swap(set, clr);
for(int x = 0; x < 256; x++) {
wtbl[x] = (x >= window2_left && x <= window2_right) ? set : clr;
}

View File

@ -10,19 +10,19 @@ double lmin, lmax;
lmin = 0.0 - double(int32(config::snes.contrast));
lmax = 255.0 + double(int32(config::snes.contrast));
int32 result = int32(lmin + double(input) * ((lmax - lmin) / 256.0));
input = (result > 255) ? 255 : (result < 0) ? 0 : result;
input = bound_range(result, 0, 255);
}
void SNES::brightness_adjust(int32 &input) {
int32 result;
result = input + int32(config::snes.brightness);
input = (result > 255) ? 255 : (result < 0) ? 0 : result;
input = bound_range(result, 0, 255);
}
void SNES::gamma_adjust(int32 &input) {
int32 result;
result = int32(pow((double(input + 1) / 256.0), double(config::snes.gamma) / 100.0) * 256.0);
input = (result > 255) ? 255 : (result < 0) ? 0 : result;
input = bound_range(result, 0, 255);
}
void SNES::update_color_lookup_table() {
@ -55,14 +55,14 @@ uint32 col;
r = int32(double(l) * (1.0 + 0.300));
g = int32(double(l) * (1.0 - 0.055));
b = int32(double(l) * (1.0 - 0.225));
r = (r > 255) ? 255 : (r < 0) ? 0 : r;
g = (g > 255) ? 255 : (g < 0) ? 0 : g;
b = (b > 255) ? 255 : (b < 0) ? 0 : b;
r = bound_range(r, 0, 255);
g = bound_range(g, 0, 255);
b = bound_range(b, 0, 255);
}
if(bool(config::snes.grayscale) == true) {
l = int32(double(r) * kr + double(g) * kg + double(b) * kb);
l = (l > 255) ? 255 : (l < 0) ? 0 : l;
l = bound_range(l, 0, 255);
r = g = b = l;
}

View File

@ -1,5 +1,6 @@
CC = cl
CFLAGS = /nologo /O2 /arch:SSE2 /wd4996
#CFLAGS = /nologo /O2 /GL /EHsc /wd4996
OBJS = main.obj \
libstring.obj libconfig.obj libbpf.obj \
reader.obj cart.obj cheat.obj \
@ -19,7 +20,8 @@ LIBS = kernel32.lib user32.lib gdi32.lib comdlg32.lib comctl32.lib \
all: $(OBJS)
rc /r /fobsnes.res bsnes.rc
$(CC) /Febsnes.exe $(CFLAGS) $(OBJS) bsnes.res $(LIBS)
#/link /PGD:bsnes.pgd /LTCG:PGINSTRUMENT
# $(CC) /Febsnes.exe $(CFLAGS) $(OBJS) bsnes.res $(LIBS) /link /PGD:bsnes.pgd /LTCG:PGINSTRUMENT
# $(CC) /Febsnes.exe $(CFLAGS) $(OBJS) bsnes.res $(LIBS) /link /PGD:bsnes.pgd /LTCG:PGOPTIMIZE
clean:
del *.obj

View File

@ -1,5 +1,7 @@
#define IDI_APP_ICON 100
#define IDB_ABOUT_ART 101
#define IDI_APP_ICON 100
#define IDB_ABOUT_ART 101
#define IDB_CONTROLLER_ART 102
IDI_APP_ICON ICON DISCARDABLE "../data/bsnes.ico"
IDB_ABOUT_ART BITMAP DISCARDABLE "../data/about.bmp"
IDI_APP_ICON ICON DISCARDABLE "../data/bsnes.ico"
IDB_ABOUT_ART BITMAP DISCARDABLE "../data/about.bmp"
IDB_CONTROLLER_ART BITMAP DISCARDABLE "../data/snes_controller.bmp"

View File

@ -28,11 +28,11 @@ struct Video {
Setting Video::renderer(&config_file, "video.renderer", "Video renderer\n"
"\"dd\" (DirectDraw7 -- faster, less features)\n"
"\"d3d\" (Direct3D9 -- slower, more features)", "d3d");
Setting Video::profile(&config_file, "video.profile", "Video profile to load at startup", 2, Setting::DEC);
Setting Video::profile(0, "video.profile", "", 2, Setting::DEC);
Setting Video::profile_windowed_default(&config_file, "video.profile_windowed_default",
"Windowed profile to select for Alt+Enter", 0, Setting::DEC);
"Windowed profile to select for Alt+Enter", 2, Setting::DEC);
Setting Video::profile_fullscreen_default(&config_file, "video.profile_fullscreen_default",
"Fullscreen profile to select for Alt+Enter", 5, Setting::DEC);
"Fullscreen profile to select for Alt+Enter", 9, Setting::DEC);
/* software_filter
* hardware_filter
@ -51,19 +51,20 @@ Setting Video::profile_fullscreen_default(&config_file, "video.profile_fullscree
*/
Setting Video::profile_0(&config_file, "video.profile_0", "Video profile 0 configuration\n"
"Please use bsnes GUI configuration editor to modify video profile settings\n"
"Format: software_filter;hardware_filter;video_standard;multiplier;correct_aspect_ratio;\n"
"Format: software_filter;hardware_filter;video_standard;multiplier-1;correct_aspect_ratio;\n"
" enable_scanlines;manual_render_size;render_width;render_height;fullscreen;\n"
" resolution_width;resolution_height;refresh_rate;triple_buffering"
"", "0;0;0;0;false;false;false;256;224;false;640;480;60;false");
Setting Video::profile_1(&config_file, "video.profile_1", "", "0;0;0;0;false;false;false;256;224;false;640;480;60;false");
Setting Video::profile_2(&config_file, "video.profile_2", "", "0;0;0;0;false;false;false;256;224;false;640;480;60;false");
Setting Video::profile_3(&config_file, "video.profile_3", "", "0;0;0;0;false;false;false;256;224;false;640;480;60;false");
Setting Video::profile_4(&config_file, "video.profile_4", "", "0;0;0;0;false;false;false;256;224;false;640;480;60;false");
Setting Video::profile_5(&config_file, "video.profile_5", "", "0;0;0;0;false;false;false;256;224;false;640;480;60;false");
Setting Video::profile_6(&config_file, "video.profile_6", "", "0;0;0;0;false;false;false;256;224;false;640;480;60;false");
Setting Video::profile_7(&config_file, "video.profile_7", "", "0;0;0;0;false;false;false;256;224;false;640;480;60;false");
Setting Video::profile_8(&config_file, "video.profile_8", "", "0;0;0;0;false;false;false;256;224;false;640;480;60;false");
Setting Video::profile_9(&config_file, "video.profile_9", "", "0;0;0;0;false;false;false;256;224;false;640;480;60;false");
"", "0;0;0;0;false;false;false;256;224;false;320;240;0;false");
Setting Video::profile_1(&config_file, "video.profile_1", "", "0;0;0;1;false;false;false;512;448;false;640;480;0;false");
Setting Video::profile_2(&config_file, "video.profile_2", "", "0;1;0;1;true;false;false;597;448;false;640;480;0;false");
Setting Video::profile_3(&config_file, "video.profile_3", "", "0;1;0;2;true;false;false;896;672;false;1024;768;0;false");
Setting Video::profile_4(&config_file, "video.profile_4", "", "0;1;0;3;true;false;false;1195;896;false;1280;960;0;false");
Setting Video::profile_5(&config_file, "video.profile_5", "", "0;0;0;0;false;false;false;256;224;true;320;240;0;false");
Setting Video::profile_6(&config_file, "video.profile_6", "", "0;0;0;1;false;false;false;512;448;true;640;480;0;false");
Setting Video::profile_7(&config_file, "video.profile_7", "", "0;1;0;1;true;false;false;597;448;true;640;480;0;false");
Setting Video::profile_8(&config_file, "video.profile_8", "", "0;1;0;2;true;false;false;896;672;true;1024;768;0;false");
Setting Video::profile_9(&config_file, "video.profile_9", "", "0;1;0;3;true;false;false;1195;896;true;1280;960;0;false");
Setting Video::use_vram(&config_file, "video.use_vram", "Use Video RAM instead of System RAM", true, Setting::TRUE_FALSE);
Setting Video::triple_buffering(&config_file, "video.triple_buffering", "Use triple buffering", false, Setting::TRUE_FALSE);
@ -175,6 +176,6 @@ Setting Misc::show_fps(&config_file, "misc.show_fps", "Show framerate", true, Se
Setting Misc::config_window_alpha_level(&config_file, "misc.config_window_alpha_level",
"Alpha level (opacity) of configuration window\n"
"Value must be between 64 (25% opaque, 75% transparent) and 255 (100% opaque)",
192, Setting::DEC);
255, Setting::DEC);
};

View File

@ -161,8 +161,7 @@ void InputDI::set_status(uint8 device, uint8 button, bool status) {
case SNES::JOYPAD_R: joypad1.r = status; break;
case SNES::JOYPAD_SELECT: joypad1.select = status; break;
case SNES::JOYPAD_START: joypad1.start = status; break;
}
break;
} break;
case SNES::DEV_JOYPAD2:
switch(button) {
case SNES::JOYPAD_UP: joypad2.up = status; break;
@ -177,8 +176,7 @@ void InputDI::set_status(uint8 device, uint8 button, bool status) {
case SNES::JOYPAD_R: joypad2.r = status; break;
case SNES::JOYPAD_SELECT: joypad2.select = status; break;
case SNES::JOYPAD_START: joypad2.start = status; break;
}
break;
} break;
}
}

View File

@ -202,6 +202,77 @@ uint r = key & KEYMASK;
return result;
}
uint Input::get_keymap(uint device, uint button) {
switch(device) {
case SNES::DEV_JOYPAD1:
switch(button) {
case SNES::JOYPAD_UP: return config::input.joypad1.up;
case SNES::JOYPAD_DOWN: return config::input.joypad1.down;
case SNES::JOYPAD_LEFT: return config::input.joypad1.left;
case SNES::JOYPAD_RIGHT: return config::input.joypad1.right;
case SNES::JOYPAD_A: return config::input.joypad1.a;
case SNES::JOYPAD_B: return config::input.joypad1.b;
case SNES::JOYPAD_X: return config::input.joypad1.x;
case SNES::JOYPAD_Y: return config::input.joypad1.y;
case SNES::JOYPAD_L: return config::input.joypad1.l;
case SNES::JOYPAD_R: return config::input.joypad1.r;
case SNES::JOYPAD_SELECT: return config::input.joypad1.select;
case SNES::JOYPAD_START: return config::input.joypad1.start;
} break;
case SNES::DEV_JOYPAD2:
switch(button) {
case SNES::JOYPAD_UP: return config::input.joypad2.up;
case SNES::JOYPAD_DOWN: return config::input.joypad2.down;
case SNES::JOYPAD_LEFT: return config::input.joypad2.left;
case SNES::JOYPAD_RIGHT: return config::input.joypad2.right;
case SNES::JOYPAD_A: return config::input.joypad2.a;
case SNES::JOYPAD_B: return config::input.joypad2.b;
case SNES::JOYPAD_X: return config::input.joypad2.x;
case SNES::JOYPAD_Y: return config::input.joypad2.y;
case SNES::JOYPAD_L: return config::input.joypad2.l;
case SNES::JOYPAD_R: return config::input.joypad2.r;
case SNES::JOYPAD_SELECT: return config::input.joypad2.select;
case SNES::JOYPAD_START: return config::input.joypad2.start;
} break;
}
return JOYKEY_NONE;
}
void Input::set_keymap(uint device, uint button, uint keymap) {
switch(device) {
case SNES::DEV_JOYPAD1:
switch(button) {
case SNES::JOYPAD_UP: config::input.joypad1.up = keymap; break;
case SNES::JOYPAD_DOWN: config::input.joypad1.down = keymap; break;
case SNES::JOYPAD_LEFT: config::input.joypad1.left = keymap; break;
case SNES::JOYPAD_RIGHT: config::input.joypad1.right = keymap; break;
case SNES::JOYPAD_A: config::input.joypad1.a = keymap; break;
case SNES::JOYPAD_B: config::input.joypad1.b = keymap; break;
case SNES::JOYPAD_X: config::input.joypad1.x = keymap; break;
case SNES::JOYPAD_Y: config::input.joypad1.y = keymap; break;
case SNES::JOYPAD_L: config::input.joypad1.l = keymap; break;
case SNES::JOYPAD_R: config::input.joypad1.r = keymap; break;
case SNES::JOYPAD_SELECT: config::input.joypad1.select = keymap; break;
case SNES::JOYPAD_START: config::input.joypad1.start = keymap; break;
} break;
case SNES::DEV_JOYPAD2:
switch(button) {
case SNES::JOYPAD_UP: config::input.joypad2.up = keymap; break;
case SNES::JOYPAD_DOWN: config::input.joypad2.down = keymap; break;
case SNES::JOYPAD_LEFT: config::input.joypad2.left = keymap; break;
case SNES::JOYPAD_RIGHT: config::input.joypad2.right = keymap; break;
case SNES::JOYPAD_A: config::input.joypad2.a = keymap; break;
case SNES::JOYPAD_B: config::input.joypad2.b = keymap; break;
case SNES::JOYPAD_X: config::input.joypad2.x = keymap; break;
case SNES::JOYPAD_Y: config::input.joypad2.y = keymap; break;
case SNES::JOYPAD_L: config::input.joypad2.l = keymap; break;
case SNES::JOYPAD_R: config::input.joypad2.r = keymap; break;
case SNES::JOYPAD_SELECT: config::input.joypad2.select = keymap; break;
case SNES::JOYPAD_START: config::input.joypad2.start = keymap; break;
} break;
}
}
void Input::init() {
string t, part;
strcpy(t, config::input.joypad1.map.sget());

View File

@ -76,6 +76,8 @@ enum {
bool keydown(uint id);
uint stringtokeymap(const char *str);
const char *keymaptostring(uint key);
uint get_keymap(uint device, uint button);
void set_keymap(uint device, uint button, uint keymap);
Input();
};

View File

@ -54,7 +54,7 @@ bool ColorAdjustWindow::Event(EventInfo &info) {
}
void ColorAdjustWindow::Setup() {
Header.Create(this, "visible", 0, 0, 475, 30, "Color Adjust");
Header.Create(this, "visible", 0, 0, 475, 30, "Color Adjustment");
Header.SetFont(global::font_header);
int x = 15, y = 30;

View File

@ -7,6 +7,18 @@ void CALLBACK wInputConfigInputTimerProc(HWND hwnd, UINT msg, UINT event, DWORD
bool InputConfigWindow::Event(EventInfo &info) {
switch(info.event_id) {
case EVENT_DRAW: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
HDC hdcsrc = CreateCompatibleDC(hdc);
HBITMAP hbm = LoadBitmap(GetModuleHandle(0), MAKEINTRESOURCE(102));
SelectObject(hdcsrc, hbm);
BitBlt(hdc, 285, 139, 190, 100, hdcsrc, 0, 0, SRCCOPY);
DeleteDC(hdcsrc);
DeleteObject(hbm);
EndPaint(hwnd, &ps);
} break;
case Input::EVENT_INPUTKEYDOWN: {
if(button_update.active == true) {
button_update.id = info.control_id;
@ -17,30 +29,35 @@ bool InputConfigWindow::Event(EventInfo &info) {
case EVENT_CHANGED: {
if(info.control == &Resistance) {
config::input.axis_resistance = Resistance.GetPos();
ResistanceLabel.SetText("Resistance: %d%%", uint(config::input.axis_resistance));
ResistanceLabel.SetText("Joypad axis resistance: %d%%", uint(config::input.axis_resistance));
} else if(info.control == &Selected) {
switch(Selected.GetSelection()) {
case 0: AllowBadInput.Check(config::input.joypad1.allow_invalid_input); break;
case 1: AllowBadInput.Check(config::input.joypad2.allow_invalid_input); break;
}
UpdateButtonList();
}
} break;
case EVENT_DOUBLECLICKED: {
if(info.control == &ButtonList) {
int sel = ButtonList.GetSelection();
if(sel != -1)ButtonUpdateBegin(sel);
}
} break;
case EVENT_CLICKED: {
if(info.control == &ButtonUp) ButtonUpdate(BUTTON_UP);
if(info.control == &ButtonDown) ButtonUpdate(BUTTON_DOWN);
if(info.control == &ButtonLeft) ButtonUpdate(BUTTON_LEFT);
if(info.control == &ButtonRight) ButtonUpdate(BUTTON_RIGHT);
if(info.control == &ButtonA) ButtonUpdate(BUTTON_A);
if(info.control == &ButtonB) ButtonUpdate(BUTTON_B);
if(info.control == &ButtonX) ButtonUpdate(BUTTON_X);
if(info.control == &ButtonY) ButtonUpdate(BUTTON_Y);
if(info.control == &ButtonL) ButtonUpdate(BUTTON_L);
if(info.control == &ButtonR) ButtonUpdate(BUTTON_R);
if(info.control == &ButtonSelect)ButtonUpdate(BUTTON_SELECT);
if(info.control == &ButtonStart) ButtonUpdate(BUTTON_START);
if(info.control == &AllowBadInput) {
if(info.control == &ButtonUpdate) {
int sel = ButtonList.GetSelection();
if(sel != -1)ButtonUpdateBegin(sel);
} else if(info.control == &ButtonClear) {
int sel = ButtonList.GetSelection();
if(sel != -1) {
ButtonUpdateBegin(sel);
button_update.id = uiInput->keymap.esc;
ButtonUpdateEnd();
}
} else if(info.control == &AllowBadInput) {
switch(Selected.GetSelection()) {
case 0:
config::input.joypad1.allow_invalid_input.toggle();
@ -61,31 +78,53 @@ bool InputConfigWindow::Event(EventInfo &info) {
const char *InputConfigWindow::GetCaption(uint button) {
switch(button) {
case BUTTON_UP: return "Up";
case BUTTON_DOWN: return "Down";
case BUTTON_LEFT: return "Left";
case BUTTON_RIGHT: return "Right";
case BUTTON_A: return "A";
case BUTTON_B: return "B";
case BUTTON_X: return "X";
case BUTTON_Y: return "Y";
case BUTTON_L: return "L";
case BUTTON_R: return "R";
case BUTTON_SELECT: return "Select";
case BUTTON_START: return "Start";
case SNES::JOYPAD_UP: return "Up";
case SNES::JOYPAD_DOWN: return "Down";
case SNES::JOYPAD_LEFT: return "Left";
case SNES::JOYPAD_RIGHT: return "Right";
case SNES::JOYPAD_A: return "A";
case SNES::JOYPAD_B: return "B";
case SNES::JOYPAD_X: return "X";
case SNES::JOYPAD_Y: return "Y";
case SNES::JOYPAD_L: return "L";
case SNES::JOYPAD_R: return "R";
case SNES::JOYPAD_SELECT: return "Select";
case SNES::JOYPAD_START: return "Start";
}
return "";
}
void InputConfigWindow::ButtonUpdate(uint button) {
void InputConfigWindow::UpdateButtonList() {
ButtonList.DeleteAllItems();
uint device = Selected.GetSelection();
char t[512], tmp[512];
string str, part;
#define add(__label, __bn) \
strcpy(tmp, uiInput->keymaptostring(uiInput->get_keymap(device, SNES::JOYPAD_##__bn))); \
split(part, " | ", tmp); \
replace(part[0], "keynone", "<none>"); \
if(count(part) < 2)strcpy(part[1], "<none>"); \
sprintf(t, #__label "|%s|%s", strptr(part[0]), strptr(part[1])); \
ButtonList.AddItem(t);
add(Up, UP); add(Down, DOWN); add(Left, LEFT); add(Right, RIGHT);
add(Y, Y); add(X, X); add(B, B); add(A, A);
add(L, L); add(R, R); add(Select, SELECT); add(Start, START);
#undef add
}
void InputConfigWindow::ButtonUpdateBegin(uint button) {
if(button_update.active == true)return;
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
//convert Up, Down, Left, Right, Y, X, B, A, L, R, Select, Start
//to B, Y, Select, Start, Up, Down, Left, Right, A, X, L, R
uint translate_table[12] = { 4, 5, 6, 7, 1, 9, 0, 8, 10, 11, 2, 3 };
button_update.active = true;
button_update.controller = Selected.GetSelection();
button_update.button = button;
button_update.button = translate_table[button];
Message.SetText("Press button or key for 'Controller %d::%s', "
Message.SetText("Press key or button for 'Controller %d::%s', "
"or press escape to clear button assignment.",
button_update.controller + 1, GetCaption(button_update.button));
SetFocus(Message.hwnd);
@ -103,40 +142,7 @@ uint old_id, id = button_update.id;
//escape key was pressed, clear key + joy mapping
id = Input::JOYKEY_NONE;
} else {
switch(button_update.controller) {
case 0:
switch(button_update.button) {
case BUTTON_UP: old_id = config::input.joypad1.up; break;
case BUTTON_DOWN: old_id = config::input.joypad1.down; break;
case BUTTON_LEFT: old_id = config::input.joypad1.left; break;
case BUTTON_RIGHT: old_id = config::input.joypad1.right; break;
case BUTTON_A: old_id = config::input.joypad1.a; break;
case BUTTON_B: old_id = config::input.joypad1.b; break;
case BUTTON_X: old_id = config::input.joypad1.x; break;
case BUTTON_Y: old_id = config::input.joypad1.y; break;
case BUTTON_L: old_id = config::input.joypad1.l; break;
case BUTTON_R: old_id = config::input.joypad1.r; break;
case BUTTON_SELECT: old_id = config::input.joypad1.select; break;
case BUTTON_START: old_id = config::input.joypad1.start; break;
}
break;
case 1:
switch(button_update.button) {
case BUTTON_UP: old_id = config::input.joypad2.up; break;
case BUTTON_DOWN: old_id = config::input.joypad2.down; break;
case BUTTON_LEFT: old_id = config::input.joypad2.left; break;
case BUTTON_RIGHT: old_id = config::input.joypad2.right; break;
case BUTTON_A: old_id = config::input.joypad2.a; break;
case BUTTON_B: old_id = config::input.joypad2.b; break;
case BUTTON_X: old_id = config::input.joypad2.x; break;
case BUTTON_Y: old_id = config::input.joypad2.y; break;
case BUTTON_L: old_id = config::input.joypad2.l; break;
case BUTTON_R: old_id = config::input.joypad2.r; break;
case BUTTON_SELECT: old_id = config::input.joypad2.select; break;
case BUTTON_START: old_id = config::input.joypad2.start; break;
}
break;
}
old_id = uiInput->get_keymap(button_update.controller, button_update.button);
if(id & Input::JOYFLAG) {
//joypad key was pressed
@ -159,48 +165,19 @@ uint old_id, id = button_update.id;
id &= Input::JOYKEYMASK;
}
switch(button_update.controller) {
case 0:
switch(button_update.button) {
case BUTTON_UP: config::input.joypad1.up = id; break;
case BUTTON_DOWN: config::input.joypad1.down = id; break;
case BUTTON_LEFT: config::input.joypad1.left = id; break;
case BUTTON_RIGHT: config::input.joypad1.right = id; break;
case BUTTON_A: config::input.joypad1.a = id; break;
case BUTTON_B: config::input.joypad1.b = id; break;
case BUTTON_X: config::input.joypad1.x = id; break;
case BUTTON_Y: config::input.joypad1.y = id; break;
case BUTTON_L: config::input.joypad1.l = id; break;
case BUTTON_R: config::input.joypad1.r = id; break;
case BUTTON_SELECT: config::input.joypad1.select = id; break;
case BUTTON_START: config::input.joypad1.start = id; break;
}
break;
case 1:
switch(button_update.button) {
case BUTTON_UP: config::input.joypad2.up = id; break;
case BUTTON_DOWN: config::input.joypad2.down = id; break;
case BUTTON_LEFT: config::input.joypad2.left = id; break;
case BUTTON_RIGHT: config::input.joypad2.right = id; break;
case BUTTON_A: config::input.joypad2.a = id; break;
case BUTTON_B: config::input.joypad2.b = id; break;
case BUTTON_X: config::input.joypad2.x = id; break;
case BUTTON_Y: config::input.joypad2.y = id; break;
case BUTTON_L: config::input.joypad2.l = id; break;
case BUTTON_R: config::input.joypad2.r = id; break;
case BUTTON_SELECT: config::input.joypad2.select = id; break;
case BUTTON_START: config::input.joypad2.start = id; break;
}
break;
}
uiInput->set_keymap(button_update.controller, button_update.button, id);
Message.SetText("Button updated. Select another button to update.");
int sel = ButtonList.GetSelection();
UpdateButtonList();
ButtonList.SetSelection(sel);
}
void InputConfigWindow::Show() {
Selected.SetSelection(0);
AllowBadInput.Check(config::input.joypad1.allow_invalid_input);
Message.SetText("Select button to update.");
UpdateButtonList();
Window::Show();
}
@ -217,60 +194,36 @@ void InputConfigWindow::Setup() {
Header.SetFont(global::font_header);
int x = 15, y = 30;
ResistanceDesc.Create(this, "visible|sunken|vscroll|multiline|readonly", x, y, 460, 45,
"Joypad axis resistance: (75% = default)\r\n"
"Controls how much force needs to be applied to an analog "
"joypad axis in any given direction to trigger a button press. (continued)\r\n\r\n"
"Example: With a resistance of 10% (minimum), one would barely need to tap "
"left to trigger a left button press. However, with a resistance of 90% "
"(maximum), one would need to push the axis as far to the left as possible to "
"trigger a left button press.\r\n\r\n"
"Generally, a lower resistance will work better when trying to input combos (eg "
"in fighting games), whereas a higher resistance will prevent accidental button "
"presses.\r\n\r\n"
"This setting only applies when the controller is in analog input mode.\r\n\r\n"
"Because it is possible to use multiple real controllers for a single emulated "
"SNES controller, there is only one global axis resistance setting. This setting "
"will thusly affect all joypads connected to this computer."
);
y += 45;
ResistanceLabel.Create(this, "visible", x, y + 3, 100, 15);
ResistanceLabel.SetText("Resistance: %d%%", uint(config::input.axis_resistance));
Resistance.Create(this, "visible", x + 100, y, 360, 25);
ResistanceLabel.Create(this, "visible", x, y + 3, 150, 15);
ResistanceLabel.SetText("Joypad axis resistance: %d%%", uint(config::input.axis_resistance));
Resistance.Create(this, "visible", x + 150, y, 310, 25);
Resistance.SetRange(10, 90);
Resistance.SetPos(config::input.axis_resistance);
y += 25;
Separator.Create(this, "visible|sunken", x, y + 5, 460, 3);
y += 15;
SelectLabel.Create(this, "visible", x, y + 3, 150, 15, "Select controller to configure:");
Selected.Create(this, "visible", x + 150, y, 100, 200);
Selected.AddItem("Controller 1");
Selected.AddItem("Controller 2");
y += 25;
Separator.Create(this, "visible|sunken", x, y + 1, 460, 3);
y += 9;
Message.Create(this, "visible", x, y, 460, 15);
y += 20;
ButtonL.Create (this, "visible", x + 100, y, 40, 25, "L");
ButtonR.Create (this, "visible", x + 205, y, 40, 25, "R");
ButtonList.Create(this, "visible|edge", x, y, 265, 195);
ButtonList.AddColumn(Listview::LEFT, 61, "Button");
ButtonList.AddColumn(Listview::LEFT, 100, "Key Mapping");
ButtonList.AddColumn(Listview::LEFT, 100, "Joypad Mapping");
ButtonUpdate.Create(this, "visible", x + 270, y, 92, 25, "Update");
ButtonClear.Create(this, "visible", x + 270 + 98, y, 92, 25, "Clear");
y += 200;
ButtonUp.Create (this, "visible", x + 40, y + 15, 40, 25, "Up");
ButtonLeft.Create (this, "visible", x, y + 40, 40, 25, "Left");
ButtonRight.Create (this, "visible", x + 80, y + 40, 40, 25, "Right");
ButtonDown.Create (this, "visible", x + 40, y + 65, 40, 25, "Down");
ButtonSelect.Create(this, "visible", x + 130, y + 55, 40, 25, "Select");
ButtonStart.Create (this, "visible", x + 180, y + 55, 40, 25, "Start");
ButtonX.Create (this, "visible", x + 270, y + 15, 40, 25, "X");
ButtonY.Create (this, "visible", x + 230, y + 40, 40, 25, "Y");
ButtonA.Create (this, "visible", x + 310, y + 40, 40, 25, "A");
ButtonB.Create (this, "visible", x + 270, y + 65, 40, 25, "B");
AllowBadInput.Create(this, "visible", x, y + 95, 460, 15,
"Allow up+down and left+right button combinations (not recommended -- can cause bugs)");
AllowBadInput.Create(this, "visible", x, y, 460, 15,
"Allow up+down and left+right button combinations (not recommended -- can trigger bugs)");
y += 15;
}
InputConfigWindow::InputConfigWindow() {

View File

@ -1,17 +1,15 @@
class InputConfigWindow : public Window {
public:
Label Header;
Editbox ResistanceDesc;
Label ResistanceLabel;
Slider Resistance;
Label Separator;
Label SelectLabel;
Combobox Selected;
Label Separator;
Label Message;
Button ButtonL, ButtonR;
Button ButtonUp, ButtonDown, ButtonLeft, ButtonRight;
Button ButtonSelect, ButtonStart;
Button ButtonA, ButtonB, ButtonX, ButtonY;
Listview ButtonList;
Button ButtonUpdate;
Button ButtonClear;
Checkbox AllowBadInput;
struct {
@ -21,19 +19,13 @@ struct {
uint id;
} button_update;
enum {
BUTTON_L, BUTTON_R,
BUTTON_UP, BUTTON_DOWN, BUTTON_LEFT, BUTTON_RIGHT,
BUTTON_SELECT, BUTTON_START,
BUTTON_A, BUTTON_B, BUTTON_X, BUTTON_Y,
};
bool Event(EventInfo &info);
void Show();
void Hide();
const char *GetCaption(uint button);
void ButtonUpdate(uint button);
void UpdateButtonList();
void ButtonUpdateBegin(uint button);
void ButtonUpdateEnd();
void Setup();

View File

@ -23,12 +23,9 @@ void RasterSettingsWindow::Setup() {
Header.SetFont(global::font_header);
int x = 15, y = 30;
ScanlineDesc.Create(this, "visible|sunken|multiline|readonly", x, y, 460, 45,
"Scanline Intensity Adjust: (0% = no scanlines, 100% = full scanlines)\r\n"
"This setting will affect all video modes. However, scanlines are only applied "
"if current video profile has hardware scanlines enabled, and render height >= 448."
);
y += 50;
ScanlineLabel.Create(this, "visible", x, y, 460, 15,
"Scanline intensity adjust: (0% = no scanlines, 100% = full scanlines)");
y += 20;
PScanlineLabel.Create(this, "visible", x, y, 100, 15);
PScanlineLabel.SetText("Progressive: %d%%", uint(config::video.pscanline_intensity));

View File

@ -1,7 +1,7 @@
class RasterSettingsWindow : public Window {
public:
Label Header;
Editbox ScanlineDesc;
Label ScanlineLabel;
Label PScanlineLabel;
Slider PScanlineSlider;
Label IScanlineLabel;

View File

@ -27,8 +27,8 @@ bool SettingsWindow::Event(EventInfo &info) {
void SettingsWindow::Show() {
settings.show_active_panel();
SetFocus(Panel.hwnd);
Window::Show();
Panel.Focus();
}
void SettingsWindow::Hide() {
@ -39,7 +39,7 @@ void SettingsWindow::Hide() {
void SettingsWindow::Setup() {
Panel.Create(this, "visible|edge", 5, 5, 150, 360,
"Video Settings|"
"Color Adjust|"
"Color Adjustment|"
"Raster Settings|"
"|"
"Input Configuration|"

View File

@ -3,12 +3,12 @@ bool VideoSettingsWindow::Event(EventInfo &info) {
case EVENT_CHANGED:
case EVENT_CLICKED: {
if(info.control == &VideoProfile) {
LoadSettings(VideoProfile.GetSelection());
} else if(info.control == &WinProfile) {
if(info.control == &WinProfile) {
config::video.profile_windowed_default = WinProfile.GetSelection();
} else if(info.control == &FullProfile) {
config::video.profile_fullscreen_default = FullProfile.GetSelection();
} else if(info.control == &VideoProfile) {
LoadSettings(VideoProfile.GetSelection());
} else if(info.control == &ApplySettings) {
SaveSettings(VideoProfile.GetSelection());
} else if(info.control == &SelectProfile) {
@ -74,9 +74,9 @@ char t[64 + 1];
}
void VideoSettingsWindow::Show() {
VideoProfile.SetSelection(config::video.profile);
WinProfile.SetSelection(config::video.profile_windowed_default);
FullProfile.SetSelection(config::video.profile_fullscreen_default);
VideoProfile.SetSelection(config::video.profile);
LoadSettings(config::video.profile);
Window::Show();
}
@ -86,12 +86,6 @@ void VideoSettingsWindow::Setup() {
Header.SetFont(global::font_header);
int x = 15, y = 30;
VideoProfileLabel.Create(this, "visible", x, y + 3, 135, 15, "Video profile to configure:");
VideoProfile.Create(this, "visible", x + 135, y, 90, 200,
"Profile 0|Profile 1|Profile 2|Profile 3|Profile 4|"
"Profile 5|Profile 6|Profile 7|Profile 8|Profile 9");
y += 25;
WinProfileLabel.Create(this, "visible", x, y + 3, 135, 15, "Default windowed profile:");
WinProfile.Create(this, "visible", x + 135, y, 90, 200,
"Profile 0|Profile 1|Profile 2|Profile 3|Profile 4|"
@ -103,16 +97,22 @@ int x = 15, y = 30;
"Profile 5|Profile 6|Profile 7|Profile 8|Profile 9");
y += 25;
VideoProfileLabel.Create(this, "visible", x, y + 3, 135, 15, "Video profile to configure:");
VideoProfile.Create(this, "visible", x + 135, y, 90, 200,
"Profile 0|Profile 1|Profile 2|Profile 3|Profile 4|"
"Profile 5|Profile 6|Profile 7|Profile 8|Profile 9");
y += 25;
Separator1.Create(this, "visible|sunken", x, y + 5, 460, 3);
y += 15;
SoftwareFilterLabel.Create(this, "visible", x, y + 3, 85, 15, "Software filter:");
SoftwareFilter.Create(this, "visible", x + 85, y, 140, 200,
"Direct|NTSC|HQ2x|Scale2x");
"None|NTSC|HQ2x|Scale2x");
HardwareFilterLabel.Create(this, "visible", x + 235, y + 3, 85, 15, "Hardware filter:");
HardwareFilter.Create(this, "visible", x + 320, y, 140, 200,
"Pixel|Bilinear");
"None|Bilinear");
y += 25;
VideoStandardLabel.Create(this, "visible", x, y + 3, 85, 15, "Video standard:");

View File

@ -1,12 +1,12 @@
class VideoSettingsWindow : public Window {
public:
Label Header;
Label VideoProfileLabel;
Combobox VideoProfile;
Label WinProfileLabel;
Combobox WinProfile;
Label FullProfileLabel;
Combobox FullProfile;
Label VideoProfileLabel;
Combobox VideoProfile;
Label Separator1;
Label SoftwareFilterLabel;
Combobox SoftwareFilter;

View File

@ -44,10 +44,7 @@ MENU_SETTINGS,
MENU_SETTINGS_FRAMESKIP_7,
MENU_SETTINGS_FRAMESKIP_8,
MENU_SETTINGS_FRAMESKIP_9,
MENU_SETTINGS_VIDEO_OPTIONS,
MENU_SETTINGS_VIDEO_OPTIONS_USEVRAM,
MENU_SETTINGS_VIDEO_OPTIONS_TRIPLEBUF,
MENU_SETTINGS_VIDEO_OPTIONS_SHOWFPS,
MENU_SETTINGS_SHOWFPS,
//---
MENU_SETTINGS_MUTE,
//---

View File

@ -171,21 +171,10 @@ bool MainWindow::Event(EventInfo &info) {
SetFrameskip(info.control_id - MENU_SETTINGS_FRAMESKIP_0);
} break;
case MENU_SETTINGS_VIDEO_OPTIONS_USEVRAM: {
config::video.use_vram.toggle();
event::set_video_profile(config::video.profile);
CheckMenuItem(MENU_SETTINGS_VIDEO_OPTIONS_USEVRAM, config::video.use_vram);
} break;
case MENU_SETTINGS_VIDEO_OPTIONS_TRIPLEBUF: {
config::video.triple_buffering.toggle();
CheckMenuItem(MENU_SETTINGS_VIDEO_OPTIONS_TRIPLEBUF, config::video.triple_buffering);
} break;
case MENU_SETTINGS_VIDEO_OPTIONS_SHOWFPS: {
case MENU_SETTINGS_SHOWFPS: {
config::misc.show_fps.toggle();
SetWindowText(hwnd, BSNES_TITLE);
CheckMenuItem(MENU_SETTINGS_VIDEO_OPTIONS_SHOWFPS, config::misc.show_fps);
CheckMenuItem(MENU_SETTINGS_SHOWFPS, config::misc.show_fps);
} break;
case MENU_SETTINGS_MUTE: {
@ -286,11 +275,7 @@ char t[128];
AddMenuItem(MENU_SETTINGS_FRAMESKIP_9, "&9");
EndMenuGroup();
AddMenuGroup("&Video Options");
AddMenuItem(MENU_SETTINGS_VIDEO_OPTIONS_USEVRAM, "Use &Video Memory Surface");
AddMenuItem(MENU_SETTINGS_VIDEO_OPTIONS_TRIPLEBUF, "Use &Triple Buffering");
AddMenuItem(MENU_SETTINGS_VIDEO_OPTIONS_SHOWFPS, "&Show FPS");
EndMenuGroup();
AddMenuItem(MENU_SETTINGS_SHOWFPS, "&Show FPS");
AddMenuSeparator();
AddMenuItem(MENU_SETTINGS_MUTE, "&Mute Sound Output");
@ -299,20 +284,15 @@ char t[128];
AddMenuGroup("&Speed Regulation");
AddMenuItem(MENU_SETTINGS_SPEED_REGULATION_ENABLE, "&Enable");
AddMenuSeparator();
sprintf(t, "&Slowest (%d%%, %dhz)", uint(100.0 * (double(config::system.speed_slowest) / 32000.0)),
uint(config::system.speed_slowest));
sprintf(t, "&Slowest (%d%%)", uint(100.0 * (double(config::system.speed_slowest) / 32000.0)));
AddMenuItem(MENU_SETTINGS_SPEED_REGULATION_SLOWEST, t);
sprintf(t, "&Slow (%d%%, %dhz)", uint(100.0 * (double(config::system.speed_slow) / 32000.0)),
uint(config::system.speed_slow));
sprintf(t, "&Slow (%d%%)", uint(100.0 * (double(config::system.speed_slow) / 32000.0)));
AddMenuItem(MENU_SETTINGS_SPEED_REGULATION_SLOW, t);
sprintf(t, "&Normal (%d%%, %dhz)", uint(100.0 * (double(config::system.speed_normal) / 32000.0)),
uint(config::system.speed_normal));
sprintf(t, "&Normal (%d%%)", uint(100.0 * (double(config::system.speed_normal) / 32000.0)));
AddMenuItem(MENU_SETTINGS_SPEED_REGULATION_NORMAL, t);
sprintf(t, "&Fast (%d%%, %dhz)", uint(100.0 * (double(config::system.speed_fast) / 32000.0)),
uint(config::system.speed_fast));
sprintf(t, "&Fast (%d%%)", uint(100.0 * (double(config::system.speed_fast) / 32000.0)));
AddMenuItem(MENU_SETTINGS_SPEED_REGULATION_FAST, t);
sprintf(t, "&Fastest (%d%%, %dhz)", uint(100.0 * (double(config::system.speed_fastest) / 32000.0)),
uint(config::system.speed_fastest));
sprintf(t, "&Fastest (%d%%)", uint(100.0 * (double(config::system.speed_fastest) / 32000.0)));
AddMenuItem(MENU_SETTINGS_SPEED_REGULATION_FASTEST, t);
EndMenuGroup();
@ -331,9 +311,7 @@ char t[128];
ShowMenu();
CheckMenuItem(MENU_SETTINGS_VIDEO_OPTIONS_USEVRAM, config::video.use_vram);
CheckMenuItem(MENU_SETTINGS_VIDEO_OPTIONS_TRIPLEBUF, config::video.triple_buffering);
CheckMenuItem(MENU_SETTINGS_VIDEO_OPTIONS_SHOWFPS, config::misc.show_fps);
CheckMenuItem(MENU_SETTINGS_SHOWFPS, config::misc.show_fps);
CheckMenuItem(MENU_SETTINGS_MUTE, config::snes.mute);
CheckMenuItem(MENU_SETTINGS_SPEED_REGULATION_ENABLE, config::system.regulate_speed);