mirror of https://github.com/bsnes-emu/bsnes.git
Update to bsnes v025 release.
bsnes is exactly three years old today. I've posted a new version which adds DSP-3 and DSP-4 special chip support. The DSP-3 is used by SD Gundam GX, and the DSP-4 is used by Top Gear 3000. Please note that the DSP-3 is not fully emulated, thusly SD Gundam GX is not fully playable. Also, due to lack of timing emulation with the DSP-4, the Top Gear 3000 track sometimes flickers in split screen mode. However, it is believed that Top Gear 3000 is fully playable. I should also note that I have started on SuperFX emulation, as some will inevitably see said code in my source releases. What I have now is nothing more than a skeleton implementation, and absolutely nothing using it is playable yet. I am making absolutely no promises that I will ever be able to emulate this chip. It will take at least several months of work, and even then, the speed will probably be too slow to reach 60fps on any system, but ... I'm working on it. While I have no way to run tests on the actual SuperFX hardware, I will do the best I can to emulate the chip accurately. I will be emulating the caching and cycle delays as best I can, but the information I have on this chip is extremely limited, so don't expect miracles. Lastly, as promised, I have released the special chips I have personally emulated to the public domain. See license.txt for more information if interested. I cannot release the special chips whose code I did not write to the public domain, but all of that is already available under the GPLv2 (from ZSNES) or the SNES9x license. Changelog: - Added DSP-3 support, thanks to John Weidman, Kris Bleakley, Lancer, z80 gaiden - Added DSP-4 support, thanks to Dreamer Nom, John Weidman, Kris Bleakley, Nach, z80 gaiden - Started on support for SuperFX, no games playable as chip emulation is less than 1% complete - Unsupported special chips will now display an alert - Missing stbios.bin file when loading Sufami Turbo cartridges will now display an alert - Video settings now saved separately for windowed and fullscreen mode - Advanced option video<.mode>.synchronize can be enabled for vsync, but will cause sound crackling - Added menu option to toggle FPS counter - Minor source code cleanup
This commit is contained in:
parent
d1fcddee9c
commit
85fa3cc968
37
license.txt
37
license.txt
|
@ -52,12 +52,35 @@ Further, respective source code files are labeled with their correct licensing
|
|||
information in the header. The lack of such a header indicates said file falls
|
||||
under the bsnes license.
|
||||
|
||||
HQ2x Filter, author: MaxST, license: LGPL
|
||||
JMA, author: NSRT Team, license: GPL (*)
|
||||
libco, author: byuu, license: public domain
|
||||
libui, author: byuu, license: public domain
|
||||
NTSC Filter, author: blargg, license: LGPL
|
||||
S-DD1, author: Andreas Naive, license: public domain
|
||||
zlib, license: zlib license
|
||||
HQ2x filter, author: MaxST, license: LGPL
|
||||
JMA decompressor, author: NSRT Team, license: GPL (*)
|
||||
NTSC filter, author: blargg, license: LGPL
|
||||
zlib decompressor, license: zlib license
|
||||
|
||||
(*) bsnes has received an exemption from the copyright holder to use this work.
|
||||
|
||||
The software also includes works which have been released to the public domain,
|
||||
which are not bound to any licensing agreements. Below is a complete list of all
|
||||
such software.
|
||||
|
||||
libco, author: byuu
|
||||
libui, author: byuu
|
||||
OBC-1 emu, author: byuu
|
||||
S-DD1 emu, author: Andreas Naive
|
||||
S-RTC emu, author: byuu
|
||||
|
||||
Any software listed above as exemptions may be relicensed individually from
|
||||
bsnes under their respective terms. However, no bsnes licensed portions can be
|
||||
combined with such a derivative work.
|
||||
|
||||
The software also includes the work of other copyright holders, which is
|
||||
licensed under the terms of the bsnes license, with permission to do so from the
|
||||
respective authors. Below is a complete list of all such software.
|
||||
|
||||
Cx4 emu, authors: anomie, Overload, zsKnight, Nach
|
||||
DSP-1 emu, authors: Overload, John Weidman, Neviksti, Andreas Naive
|
||||
DSP-2 emu, author: Overload
|
||||
DSP-3 emu, authors: John Weidman, Kris Bleakley, Lancer, z80 gaiden
|
||||
DSP-4 emu, authors: Dreamer Nom, John Weidman, Kris Bleakley, Nach, z80 gaiden
|
||||
S-DSP emu, author: blargg
|
||||
ST-010 emu, authors: John Weidman, Matthew Kendora, Overload, Feather
|
||||
|
|
14
readme.txt
14
readme.txt
|
@ -1,5 +1,5 @@
|
|||
bsnes
|
||||
Version 0.024
|
||||
Version 0.025
|
||||
Author: byuu
|
||||
|
||||
--------
|
||||
|
@ -17,7 +17,7 @@ Please see license.txt for important licensing information.
|
|||
Shortcut Keys:
|
||||
--------------
|
||||
Esc - Toggle menubar visibility
|
||||
F11 - Toggle fullscreen
|
||||
F11 - Toggle fullscreen mode
|
||||
|
||||
------------------
|
||||
Known Limitations:
|
||||
|
@ -66,16 +66,10 @@ Coprocessor used only by the following games:
|
|||
- Momotarou Densetsu Happy
|
||||
- Super Power League 4
|
||||
|
||||
DSP-3
|
||||
Coprocessor used only by SD Gundam GX
|
||||
|
||||
DSP-4
|
||||
Coprocessor used only by Top Gear 3000
|
||||
|
||||
ST011
|
||||
ST-011
|
||||
SETA DSP used only by Quick-move Shogi Match with Nidan Rank-holder Morita
|
||||
|
||||
ST018
|
||||
ST-018
|
||||
SETA RISC CPU used only by Quick-move Shogi Match with Nidan Rank-holder Morita 2
|
||||
|
||||
BS-X (Broadcast Satellite)
|
||||
|
|
23
src/Makefile
23
src/Makefile
|
@ -81,7 +81,7 @@ endif
|
|||
ifeq ($(PLATFORM),win-mingw4-lui)
|
||||
OS = win
|
||||
CC = mingw32-gcc-sjlj
|
||||
CFLAGS = -mwindows -O3 -fomit-frame-pointer -DPLATFORM_WIN -DCOMPILER_GCC -DPROCESSOR_X86 -DUI_LUI
|
||||
CFLAGS = -mconsole -O3 -fomit-frame-pointer -DPLATFORM_WIN -DCOMPILER_GCC -DPROCESSOR_X86 -DUI_LUI
|
||||
AS = nasm
|
||||
ASFLAGS = -f win32 -DWIN32
|
||||
LIBS = -ld3d9 -lddraw -ldsound -ldinput8 -ldxguid -luuid -lkernel32 -luser32 -lgdi32 -lshell32 -lwinmm -lcomdlg32 -lcomctl32
|
||||
|
@ -154,8 +154,8 @@ OBJECTS = main.$(OBJ) $(LIBCO).$(OBJ) $(LIBUI).$(OBJ) \
|
|||
libstring.$(OBJ) \
|
||||
reader.$(OBJ) cart.$(OBJ) cheat.$(OBJ) memory.$(OBJ) bmemory.$(OBJ) \
|
||||
cpu.$(OBJ) scpu.$(OBJ) smp.$(OBJ) ssmp.$(OBJ) bdsp.$(OBJ) ppu.$(OBJ) \
|
||||
bppu.$(OBJ) snes.$(OBJ) srtc.$(OBJ) sdd1.$(OBJ) c4.$(OBJ) dsp1.$(OBJ) \
|
||||
dsp2.$(OBJ) obc1.$(OBJ) st010.$(OBJ)
|
||||
bppu.$(OBJ) snes.$(OBJ) superfx.$(OBJ) srtc.$(OBJ) sdd1.$(OBJ) c4.$(OBJ) \
|
||||
dsp1.$(OBJ) dsp2.$(OBJ) dsp3.$(OBJ) dsp4.$(OBJ) obc1.$(OBJ) st010.$(OBJ)
|
||||
|
||||
ifeq ($(GZIP_SUPPORT),true)
|
||||
OBJECTS += adler32.$(OBJ) compress.$(OBJ) crc32.$(OBJ) deflate.$(OBJ) \
|
||||
|
@ -259,13 +259,16 @@ snes.$(OBJ): snes/snes.cpp snes/* snes/scheduler/* snes/video/* snes/audio/* sne
|
|||
#####################
|
||||
### special chips ###
|
||||
#####################
|
||||
srtc.$(OBJ) : chip/srtc/srtc.cpp chip/srtc/*
|
||||
sdd1.$(OBJ) : chip/sdd1/sdd1.cpp chip/sdd1/*
|
||||
c4.$(OBJ) : chip/c4/c4.cpp chip/c4/*
|
||||
dsp1.$(OBJ) : chip/dsp1/dsp1.cpp chip/dsp1/*
|
||||
dsp2.$(OBJ) : chip/dsp2/dsp2.cpp chip/dsp2/*
|
||||
obc1.$(OBJ) : chip/obc1/obc1.cpp chip/obc1/*
|
||||
st010.$(OBJ): chip/st010/st010.cpp chip/st010/*
|
||||
superfx.$(OBJ): chip/superfx/superfx.cpp chip/superfx/* chip/superfx/core/* chip/superfx/memory/*
|
||||
srtc.$(OBJ) : chip/srtc/srtc.cpp chip/srtc/*
|
||||
sdd1.$(OBJ) : chip/sdd1/sdd1.cpp chip/sdd1/*
|
||||
c4.$(OBJ) : chip/c4/c4.cpp chip/c4/*
|
||||
dsp1.$(OBJ) : chip/dsp1/dsp1.cpp chip/dsp1/*
|
||||
dsp2.$(OBJ) : chip/dsp2/dsp2.cpp chip/dsp2/*
|
||||
dsp3.$(OBJ) : chip/dsp3/dsp3.cpp chip/dsp3/*
|
||||
dsp4.$(OBJ) : chip/dsp4/dsp4.cpp chip/dsp4/*
|
||||
obc1.$(OBJ) : chip/obc1/obc1.cpp chip/obc1/*
|
||||
st010.$(OBJ) : chip/st010/st010.cpp chip/st010/*
|
||||
|
||||
############
|
||||
### zlib ###
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define BSNES_VERSION "0.024"
|
||||
#define BSNES_VERSION "0.025"
|
||||
#define BSNES_TITLE "bsnes v" BSNES_VERSION
|
||||
|
||||
#define MEMCORE bMemBus
|
||||
|
|
|
@ -10,18 +10,24 @@
|
|||
|
||||
Cartridge cartridge;
|
||||
|
||||
void Cartridge::load_begin(uint cart_type) {
|
||||
void Cartridge::load_begin(CartridgeType cart_type) {
|
||||
if(loaded() == true)return;
|
||||
|
||||
info.type = cart_type;
|
||||
|
||||
info.srtc = false;
|
||||
info.sdd1 = false;
|
||||
info.c4 = false;
|
||||
info.dsp1 = false;
|
||||
info.dsp2 = false;
|
||||
info.obc1 = false;
|
||||
info.st010 = false;
|
||||
info.superfx = false;
|
||||
info.sa1 = false;
|
||||
info.srtc = false;
|
||||
info.sdd1 = false;
|
||||
info.c4 = false;
|
||||
info.dsp1 = false;
|
||||
info.dsp2 = false;
|
||||
info.dsp3 = false;
|
||||
info.dsp4 = false;
|
||||
info.obc1 = false;
|
||||
info.st010 = false;
|
||||
info.st011 = false;
|
||||
info.st018 = false;
|
||||
|
||||
info.dsp1_mapper = 0;
|
||||
|
||||
|
@ -30,7 +36,6 @@ void Cartridge::load_begin(uint cart_type) {
|
|||
strcpy(info.name, "");
|
||||
strcpy(info.pcb, "");
|
||||
info.region = NTSC;
|
||||
info.cart_mmio = false;
|
||||
|
||||
info.rom_size = 0;
|
||||
info.ram_size = 0;
|
||||
|
@ -93,15 +98,15 @@ bool Cartridge::load_end() {
|
|||
}
|
||||
|
||||
switch(info.type) {
|
||||
case CART_NORMAL: {
|
||||
case CartridgeNormal: {
|
||||
load_rom_normal();
|
||||
load_ram_normal();
|
||||
} break;
|
||||
case CART_ST: {
|
||||
case CartridgeSufamiTurbo: {
|
||||
load_rom_st();
|
||||
load_ram_st();
|
||||
} break;
|
||||
case CART_STDUAL: {
|
||||
case CartridgeSufamiTurboDual: {
|
||||
load_rom_stdual();
|
||||
load_ram_stdual();
|
||||
} break;
|
||||
|
@ -118,13 +123,13 @@ bool Cartridge::unload() {
|
|||
r_mem->unload_cart();
|
||||
|
||||
switch(info.type) {
|
||||
case CART_NORMAL: {
|
||||
case CartridgeNormal: {
|
||||
save_ram_normal();
|
||||
} break;
|
||||
case CART_ST: {
|
||||
case CartridgeSufamiTurbo: {
|
||||
save_ram_st();
|
||||
} break;
|
||||
case CART_STDUAL: {
|
||||
case CartridgeSufamiTurboDual: {
|
||||
save_ram_stdual();
|
||||
} break;
|
||||
}
|
||||
|
|
|
@ -15,10 +15,10 @@ db_item dbi;
|
|||
|
||||
//
|
||||
|
||||
enum {
|
||||
CART_NORMAL,
|
||||
CART_ST,
|
||||
CART_STDUAL,
|
||||
enum CartridgeType {
|
||||
CartridgeNormal,
|
||||
CartridgeSufamiTurbo,
|
||||
CartridgeSufamiTurboDual,
|
||||
};
|
||||
|
||||
bool cart_loaded;
|
||||
|
@ -33,7 +33,7 @@ enum {
|
|||
ROM_SIZE = 0x17,
|
||||
RAM_SIZE = 0x18,
|
||||
REGION = 0x19,
|
||||
LICENSE = 0x1a,
|
||||
COMPANY = 0x1a,
|
||||
VERSION = 0x1b,
|
||||
ICKSUM = 0x1c,
|
||||
CKSUM = 0x1e,
|
||||
|
@ -78,16 +78,19 @@ struct {
|
|||
uint rom_size;
|
||||
uint ram_size;
|
||||
|
||||
//set to true for games that need cart MMIO mapping (c4, dsp-n, ...),
|
||||
//for games that map outside the standard MMIO range of $2000-$5fff
|
||||
bool cart_mmio;
|
||||
bool superfx;
|
||||
bool sa1;
|
||||
bool srtc;
|
||||
bool sdd1;
|
||||
bool c4;
|
||||
bool dsp1;
|
||||
bool dsp2;
|
||||
bool dsp3;
|
||||
bool dsp4;
|
||||
bool obc1;
|
||||
bool st010;
|
||||
bool st011;
|
||||
bool st018;
|
||||
|
||||
uint dsp1_mapper;
|
||||
|
||||
|
@ -114,7 +117,7 @@ struct {
|
|||
void read_header();
|
||||
|
||||
bool loaded() { return cart_loaded; }
|
||||
void load_begin(uint cart_type);
|
||||
void load_begin(CartridgeType cart_type);
|
||||
void load(const char *rom_fn);
|
||||
bool load_end();
|
||||
bool unload();
|
||||
|
|
|
@ -13,6 +13,7 @@ bool Cartridge::load_file(const char *fn, uint8 *&data, uint &size) {
|
|||
dprintf("* Loading \"%s\"...", fn);
|
||||
|
||||
if(fexists(fn) == false) {
|
||||
alert("Error: file '%s' not found!", fn);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,4 @@
|
|||
void Cartridge::read_header() {
|
||||
info.srtc = false;
|
||||
info.sdd1 = false;
|
||||
info.c4 = false;
|
||||
info.dsp1 = false;
|
||||
info.dsp2 = false;
|
||||
info.obc1 = false;
|
||||
|
||||
info.dsp1_mapper = 0;
|
||||
|
||||
if(info.header_index == 0x7fc0 && info.rom_size >= 0x401000) {
|
||||
info.mapper = EXLOROM;
|
||||
strcpy(info.pcb, "UNL-EXLOROM");
|
||||
|
@ -27,6 +18,16 @@ void Cartridge::read_header() {
|
|||
|
||||
uint8 mapper = rom[info.header_index + MAPPER];
|
||||
uint8 rom_type = rom[info.header_index + ROM_TYPE];
|
||||
uint8 company = rom[info.header_index + COMPANY];
|
||||
|
||||
if(mapper == 0x20 && (rom_type == 0x13 || rom_type == 0x14 || rom_type == 0x15 || rom_type == 0x1a)) {
|
||||
info.superfx = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x23 && (rom_type == 0x34 || rom_type == 0x35)) {
|
||||
info.sa1 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x35 && rom_type == 0x55) {
|
||||
info.srtc = true;
|
||||
}
|
||||
|
@ -43,7 +44,7 @@ uint8 rom_type = rom[info.header_index + ROM_TYPE];
|
|||
info.dsp1 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x30 && rom_type == 0x05) {
|
||||
if(mapper == 0x30 && rom_type == 0x05 && company != 0xb2) {
|
||||
info.dsp1 = true;
|
||||
}
|
||||
|
||||
|
@ -65,15 +66,28 @@ uint8 rom_type = rom[info.header_index + ROM_TYPE];
|
|||
info.dsp2 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x30 && rom_type == 0x05 && company == 0xb2) {
|
||||
info.dsp3 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x30 && rom_type == 0x03) {
|
||||
info.dsp4 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x30 && rom_type == 0x25) {
|
||||
info.obc1 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x30 && rom_type == 0xf6) {
|
||||
//TODO: both ST010 and ST011 share the same mapper + rom_type
|
||||
//need way to determine which is which
|
||||
//for now, default to supported ST010
|
||||
info.st010 = true;
|
||||
}
|
||||
|
||||
info.cart_mmio = info.c4 | info.dsp1 | info.dsp2 | info.obc1;
|
||||
if(mapper == 0x30 && rom_type == 0xf5) {
|
||||
info.st018 = true;
|
||||
}
|
||||
|
||||
if(rom[info.header_index + RAM_SIZE] & 7) {
|
||||
info.ram_size = 1024 << (rom[info.header_index + RAM_SIZE] & 7);
|
||||
|
@ -117,8 +131,8 @@ int32 score_lo = 0,
|
|||
if(rom[0x7fc0 + REGION] < 14)score_lo++;
|
||||
if(rom[0xffc0 + REGION] < 14)score_hi++;
|
||||
|
||||
if(rom[0x7fc0 + LICENSE] < 3)score_lo++;
|
||||
if(rom[0xffc0 + LICENSE] < 3)score_hi++;
|
||||
if(rom[0x7fc0 + COMPANY] < 3)score_lo++;
|
||||
if(rom[0xffc0 + COMPANY] < 3)score_hi++;
|
||||
|
||||
if(rom[0x7fc0 + RESH] & 0x80)score_lo += 2;
|
||||
if(rom[0xffc0 + RESH] & 0x80)score_hi += 2;
|
||||
|
|
|
@ -20,21 +20,11 @@ uint offset = 0;
|
|||
info.crc32 = crc32_calculate(rom, info.rom_size);
|
||||
|
||||
if(read_database() == true) {
|
||||
info.srtc = false;
|
||||
info.sdd1 = false;
|
||||
info.c4 = false;
|
||||
info.dsp1 = false;
|
||||
info.dsp2 = false;
|
||||
info.obc1 = false;
|
||||
|
||||
info.dsp1_mapper = 0;
|
||||
|
||||
info.header_index = 0xffc0;
|
||||
info.mapper = PCB;
|
||||
strcpy(info.name, dbi.name);
|
||||
strcpy(info.pcb, dbi.pcb);
|
||||
info.region = NTSC;
|
||||
info.cart_mmio = false;
|
||||
|
||||
info.rom_size = dbi.rom;
|
||||
info.ram_size = dbi.ram;
|
||||
|
|
Binary file not shown.
|
@ -106,6 +106,12 @@ pcb = "BSC-1A7M-10"
|
|||
rom = 24mbit
|
||||
ram = 512kbit
|
||||
|
||||
[0xcf98ddaa]
|
||||
name = "Super Mario World 2: Yoshi's Island (USA)"
|
||||
pcb = "SHVC-1CB5B-01"
|
||||
rom = 16mbit
|
||||
ram = 256kbit
|
||||
|
||||
[0x64a91e64]
|
||||
name = "Wanderers from Ys (USA) [!]"
|
||||
pcb = "SHVC-1A3B-12"
|
||||
|
|
|
@ -53,9 +53,9 @@ db_item dbi;
|
|||
dbi.ram = 0;
|
||||
|
||||
for(int i = 1; i < count(line); i++) {
|
||||
uint pos;
|
||||
if(strpos(line[i], ";", pos) == true) {
|
||||
strset(line[i], pos, 0);
|
||||
int pos = strpos(line[i], ";");
|
||||
if(pos >= 0) {
|
||||
strptr(line[i])[pos] = 0;
|
||||
}
|
||||
|
||||
if(line[i] == "")continue;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
::@make -r PLATFORM=win-mingw4-lui
|
||||
::@make -r PLATFORM=win-visualc-lui
|
||||
@make -r PLATFORM=win-visualc-lui GZIP_SUPPORT=true JMA_SUPPORT=true
|
||||
@move bsnes.exe ../bsnes.exe>nul
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
|
||||
#include "../../base.h"
|
||||
|
||||
C4 *c4;
|
||||
|
||||
#include "c4data.cpp"
|
||||
#include "c4fn.cpp"
|
||||
#include "c4oam.cpp"
|
||||
|
|
|
@ -93,4 +93,4 @@ public:
|
|||
C4();
|
||||
};
|
||||
|
||||
extern C4 *c4;
|
||||
extern C4 c4;
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include "../../base.h"
|
||||
|
||||
DSP1 *dsp1;
|
||||
|
||||
#include "dsp1emu.cpp"
|
||||
|
||||
void DSP1::init() {}
|
||||
|
|
|
@ -15,4 +15,4 @@ public:
|
|||
void write(uint16 addr, uint8 data);
|
||||
};
|
||||
|
||||
extern DSP1 *dsp1;
|
||||
extern DSP1 dsp1;
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include "../../base.h"
|
||||
|
||||
DSP2 *dsp2;
|
||||
|
||||
#include "dsp2_op.cpp"
|
||||
|
||||
void DSP2::init() {}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
class DSP2 {
|
||||
public:
|
||||
class DSP2 { public:
|
||||
struct {
|
||||
bool waiting_for_command;
|
||||
uint command;
|
||||
|
@ -40,4 +39,4 @@ struct {
|
|||
~DSP2();
|
||||
};
|
||||
|
||||
extern DSP2 *dsp2;
|
||||
extern DSP2 dsp2;
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
#include "../../base.h"
|
||||
|
||||
namespace DSP3i {
|
||||
#define bool8 bool
|
||||
#include "dsp3emu.c"
|
||||
#undef bool8
|
||||
};
|
||||
|
||||
void DSP3::init() {
|
||||
}
|
||||
|
||||
void DSP3::enable() {
|
||||
}
|
||||
|
||||
void DSP3::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void DSP3::reset() {
|
||||
DSP3i::DSP3_Reset();
|
||||
}
|
||||
|
||||
uint8 DSP3::read(uint16 addr) {
|
||||
DSP3i::dsp3_address = addr;
|
||||
DSP3i::DSP3GetByte();
|
||||
return DSP3i::dsp3_byte;
|
||||
}
|
||||
|
||||
void DSP3::write(uint16 addr, uint8 data) {
|
||||
DSP3i::dsp3_address = addr;
|
||||
DSP3i::dsp3_byte = data;
|
||||
DSP3i::DSP3SetByte();
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
class DSP3 { public:
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
uint8 read (uint16 addr);
|
||||
void write(uint16 addr, uint8 data);
|
||||
};
|
||||
|
||||
extern DSP3 dsp3;
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,51 @@
|
|||
#include "../../base.h"
|
||||
|
||||
namespace DSP4i {
|
||||
inline uint16 READ_WORD(uint8 *addr) {
|
||||
return (addr[0]) + (addr[1] << 8);
|
||||
}
|
||||
|
||||
inline uint32 READ_DWORD(uint8 *addr) {
|
||||
return (addr[0]) + (addr[1] << 8) + (addr[2] << 16) + (addr[3] << 24);
|
||||
}
|
||||
|
||||
inline void WRITE_WORD(uint8 *addr, uint16 data) {
|
||||
addr[0] = data;
|
||||
addr[1] = data >> 8;
|
||||
}
|
||||
|
||||
#define bool8 bool
|
||||
#include "dsp4emu.c"
|
||||
#undef bool8
|
||||
};
|
||||
|
||||
void DSP4::init() {
|
||||
}
|
||||
|
||||
void DSP4::enable() {
|
||||
}
|
||||
|
||||
void DSP4::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void DSP4::reset() {
|
||||
DSP4i::InitDSP4();
|
||||
}
|
||||
|
||||
uint8 DSP4::read(uint16 addr) {
|
||||
if(addr < 0xc000) {
|
||||
DSP4i::dsp4_address = addr;
|
||||
DSP4i::DSP4GetByte();
|
||||
return DSP4i::dsp4_byte;
|
||||
}
|
||||
return 0x80;
|
||||
}
|
||||
|
||||
void DSP4::write(uint16 addr, uint8 data) {
|
||||
if(addr < 0xc000) {
|
||||
DSP4i::dsp4_address = addr;
|
||||
DSP4i::dsp4_byte = data;
|
||||
DSP4i::DSP4SetByte();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
class DSP4 { public:
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
uint8 read (uint16 addr);
|
||||
void write(uint16 addr, uint8 data);
|
||||
};
|
||||
|
||||
extern DSP4 dsp4;
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,108 @@
|
|||
//DSP-4 emulator code
|
||||
//Copyright (c) 2004-2006 Dreamer Nom, John Weidman, Kris Bleakley, Nach, z80 gaiden
|
||||
|
||||
#ifndef DSP4EMU_H
|
||||
#define DSP4EMU_H
|
||||
|
||||
#undef TRUE
|
||||
#undef FALSE
|
||||
#define TRUE true
|
||||
#define FALSE false
|
||||
|
||||
struct DSP4_t
|
||||
{
|
||||
bool8 waiting4command;
|
||||
bool8 half_command;
|
||||
uint16 command;
|
||||
uint32 in_count;
|
||||
uint32 in_index;
|
||||
uint32 out_count;
|
||||
uint32 out_index;
|
||||
uint8 parameters[512];
|
||||
uint8 output[512];
|
||||
};
|
||||
|
||||
extern struct DSP4_t DSP4;
|
||||
|
||||
struct DSP4_vars_t
|
||||
{
|
||||
// op control
|
||||
int8 DSP4_Logic; // controls op flow
|
||||
|
||||
|
||||
// projection format
|
||||
int16 lcv; // loop-control variable
|
||||
int16 distance; // z-position into virtual world
|
||||
int16 raster; // current raster line
|
||||
int16 segments; // number of raster lines drawn
|
||||
|
||||
// 1.15.16 or 1.15.0 [sign, integer, fraction]
|
||||
int32 world_x; // line of x-projection in world
|
||||
int32 world_y; // line of y-projection in world
|
||||
int32 world_dx; // projection line x-delta
|
||||
int32 world_dy; // projection line y-delta
|
||||
int16 world_ddx; // x-delta increment
|
||||
int16 world_ddy; // y-delta increment
|
||||
int32 world_xenv; // world x-shaping factor
|
||||
int16 world_yofs; // world y-vertical scroll
|
||||
|
||||
int16 view_x1; // current viewer-x
|
||||
int16 view_y1; // current viewer-y
|
||||
int16 view_x2; // future viewer-x
|
||||
int16 view_y2; // future viewer-y
|
||||
int16 view_dx; // view x-delta factor
|
||||
int16 view_dy; // view y-delta factor
|
||||
int16 view_xofs1; // current viewer x-vertical scroll
|
||||
int16 view_yofs1; // current viewer y-vertical scroll
|
||||
int16 view_xofs2; // future viewer x-vertical scroll
|
||||
int16 view_yofs2; // future viewer y-vertical scroll
|
||||
int16 view_yofsenv; // y-scroll shaping factor
|
||||
int16 view_turnoff_x; // road turnoff data
|
||||
int16 view_turnoff_dx; // road turnoff delta factor
|
||||
|
||||
|
||||
// drawing area
|
||||
|
||||
int16 viewport_cx; // x-center of viewport window
|
||||
int16 viewport_cy; // y-center of render window
|
||||
int16 viewport_left; // x-left of viewport
|
||||
int16 viewport_right; // x-right of viewport
|
||||
int16 viewport_top; // y-top of viewport
|
||||
int16 viewport_bottom; // y-bottom of viewport
|
||||
|
||||
|
||||
// sprite structure
|
||||
|
||||
int16 sprite_x; // projected x-pos of sprite
|
||||
int16 sprite_y; // projected y-pos of sprite
|
||||
int16 sprite_attr; // obj attributes
|
||||
bool8 sprite_size; // sprite size: 8x8 or 16x16
|
||||
int16 sprite_clipy; // visible line to clip pixels off
|
||||
int16 sprite_count;
|
||||
|
||||
// generic projection variables designed for
|
||||
// two solid polygons + two polygon sides
|
||||
|
||||
int16 poly_clipLf[2][2]; // left clip boundary
|
||||
int16 poly_clipRt[2][2]; // right clip boundary
|
||||
int16 poly_ptr[2][2]; // HDMA structure pointers
|
||||
int16 poly_raster[2][2]; // current raster line below horizon
|
||||
int16 poly_top[2][2]; // top clip boundary
|
||||
int16 poly_bottom[2][2]; // bottom clip boundary
|
||||
int16 poly_cx[2][2]; // center for left/right points
|
||||
int16 poly_start[2]; // current projection points
|
||||
int16 poly_plane[2]; // previous z-plane distance
|
||||
|
||||
|
||||
// OAM
|
||||
int16 OAM_attr[16]; // OAM (size,MSB) data
|
||||
int16 OAM_index; // index into OAM table
|
||||
int16 OAM_bits; // offset into OAM table
|
||||
|
||||
int16 OAM_RowMax; // maximum number of tiles per 8 aligned pixels (row)
|
||||
int16 OAM_Row[32]; // current number of tiles per row
|
||||
};
|
||||
|
||||
extern struct DSP4_vars_t DSP4_vars;
|
||||
|
||||
#endif
|
|
@ -1,7 +1,5 @@
|
|||
#include "../../base.h"
|
||||
|
||||
OBC1 *obc1;
|
||||
|
||||
void OBC1::init() {}
|
||||
void OBC1::enable() {}
|
||||
|
||||
|
|
|
@ -17,4 +17,4 @@ struct {
|
|||
~OBC1();
|
||||
};
|
||||
|
||||
extern OBC1 *obc1;
|
||||
extern OBC1 obc1;
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include "../../base.h"
|
||||
|
||||
SDD1 *sdd1;
|
||||
|
||||
#include "sdd1emu.cpp"
|
||||
|
||||
void SDD1::init() {}
|
||||
|
|
|
@ -29,4 +29,4 @@ struct {
|
|||
SDD1();
|
||||
};
|
||||
|
||||
extern SDD1 *sdd1;
|
||||
extern SDD1 sdd1;
|
||||
|
|
|
@ -52,8 +52,6 @@
|
|||
|
||||
#include "../../base.h"
|
||||
|
||||
SRTC *srtc;
|
||||
|
||||
void SRTC::set_time() {
|
||||
time_t rawtime;
|
||||
tm *t;
|
||||
|
|
|
@ -49,4 +49,4 @@ struct {
|
|||
SRTC();
|
||||
};
|
||||
|
||||
extern SRTC *srtc;
|
||||
extern SRTC srtc;
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
#include "st010_data.h"
|
||||
#include "st010_op.cpp"
|
||||
|
||||
ST010 *st010;
|
||||
|
||||
int16 ST010::sin(int16 theta) {
|
||||
return sin_table[(theta >> 8) & 0xff];
|
||||
}
|
||||
|
|
|
@ -37,4 +37,4 @@ static const uint8 arctan[32][32];
|
|||
void write(uint16 addr, uint8 data);
|
||||
};
|
||||
|
||||
extern ST010 *st010;
|
||||
extern ST010 st010;
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
void op_unknown() {}
|
||||
|
||||
void op_00();
|
|
@ -0,0 +1,7 @@
|
|||
//STOP
|
||||
void SuperFX::op_00() {
|
||||
regs.sfr.g = 0;
|
||||
regs.sfr.b = 0;
|
||||
regs.sfr.alt1 = 0;
|
||||
regs.sfr.alt2 = 0;
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
uint8 SuperFX::mmio_read(uint16 addr) {
|
||||
switch(addr) {
|
||||
case 0x3000: return regs.r0.l;
|
||||
case 0x3001: return regs.r0.h;
|
||||
case 0x3002: return regs.r1.l;
|
||||
case 0x3003: return regs.r1.h;
|
||||
case 0x3004: return regs.r2.l;
|
||||
case 0x3005: return regs.r2.h;
|
||||
case 0x3006: return regs.r3.l;
|
||||
case 0x3007: return regs.r3.h;
|
||||
case 0x3008: return regs.r4.l;
|
||||
case 0x3009: return regs.r4.h;
|
||||
case 0x300a: return regs.r5.l;
|
||||
case 0x300b: return regs.r5.h;
|
||||
case 0x300c: return regs.r6.l;
|
||||
case 0x300d: return regs.r6.h;
|
||||
case 0x300e: return regs.r7.l;
|
||||
case 0x300f: return regs.r7.h;
|
||||
|
||||
case 0x3010: return regs.r8.l;
|
||||
case 0x3011: return regs.r8.h;
|
||||
case 0x3012: return regs.r9.l;
|
||||
case 0x3013: return regs.r9.h;
|
||||
case 0x3014: return regs.r10.l;
|
||||
case 0x3015: return regs.r10.h;
|
||||
case 0x3016: return regs.r11.l;
|
||||
case 0x3017: return regs.r11.h;
|
||||
case 0x3018: return regs.r12.l;
|
||||
case 0x3019: return regs.r12.h;
|
||||
case 0x301a: return regs.r13.l;
|
||||
case 0x301b: return regs.r13.h;
|
||||
case 0x301c: return regs.r14.l;
|
||||
case 0x301d: return regs.r14.h;
|
||||
case 0x301e: return regs.r15.l;
|
||||
case 0x301f: return regs.r15.h;
|
||||
|
||||
//0x3020 - 0x302f unused
|
||||
|
||||
case 0x3030: return regs.sfr;
|
||||
case 0x3031: return regs.sfr >> 8;
|
||||
case 0x3032: return 0x00; //unused
|
||||
case 0x3033: return 0x00; //BRAMR (write only)
|
||||
case 0x3034: return regs.pbr;
|
||||
case 0x3035: return 0x00; //unused
|
||||
case 0x3036: return regs.rombr;
|
||||
case 0x3037: return 0x00; //CFGR (write only)
|
||||
case 0x3038: return 0x00; //SCBR (write only)
|
||||
case 0x3039: return 0x00; //CLSR (write only)
|
||||
case 0x303a: return 0x00; //SCMR (write only)
|
||||
case 0x303b: return regs.vcr;
|
||||
case 0x303c: return regs.rambr;
|
||||
case 0x303d: return 0x00; //unused
|
||||
case 0x303e: return regs.cbr;
|
||||
case 0x303f: return regs.cbr >> 8;
|
||||
|
||||
//0x3040 - 0x30ff unused
|
||||
}
|
||||
|
||||
if(addr >= 0x3100 && addr <= 0x32ff) {
|
||||
return cache[addr - 0x3100];
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
void SuperFX::mmio_write(uint16 addr, uint8 data) {
|
||||
switch(addr) {
|
||||
case 0x3000: regs.r0.l = data; return;
|
||||
case 0x3001: regs.r0.h = data; return;
|
||||
case 0x3002: regs.r1.l = data; return;
|
||||
case 0x3003: regs.r1.h = data; return;
|
||||
case 0x3004: regs.r2.l = data; return;
|
||||
case 0x3005: regs.r2.h = data; return;
|
||||
case 0x3006: regs.r3.l = data; return;
|
||||
case 0x3007: regs.r3.h = data; return;
|
||||
case 0x3008: regs.r4.l = data; return;
|
||||
case 0x3009: regs.r4.h = data; return;
|
||||
case 0x300a: regs.r5.l = data; return;
|
||||
case 0x300b: regs.r5.h = data; return;
|
||||
case 0x300c: regs.r6.l = data; return;
|
||||
case 0x300d: regs.r6.h = data; return;
|
||||
case 0x300e: regs.r7.l = data; return;
|
||||
case 0x300f: regs.r7.h = data; return;
|
||||
|
||||
case 0x3010: regs.r8.l = data; return;
|
||||
case 0x3011: regs.r8.h = data; return;
|
||||
case 0x3012: regs.r9.l = data; return;
|
||||
case 0x3013: regs.r9.h = data; return;
|
||||
case 0x3014: regs.r10.l = data; return;
|
||||
case 0x3015: regs.r10.h = data; return;
|
||||
case 0x3016: regs.r11.l = data; return;
|
||||
case 0x3017: regs.r11.h = data; return;
|
||||
case 0x3018: regs.r12.l = data; return;
|
||||
case 0x3019: regs.r12.h = data; return;
|
||||
case 0x301a: regs.r13.l = data; return;
|
||||
case 0x301b: regs.r13.h = data; return;
|
||||
case 0x301c: regs.r14.l = data; return;
|
||||
case 0x301d: regs.r14.h = data; return;
|
||||
case 0x301e: regs.r15.l = data; return;
|
||||
case 0x301f: regs.r15.h = data; return;
|
||||
|
||||
//0x3020 - 0x302f unused
|
||||
|
||||
case 0x3030: regs.sfr.l = data & 0x7e; return; //mask invalid bits
|
||||
case 0x3031: regs.sfr.h = data & 0x9f; return; //mask invalid bits
|
||||
case 0x3032: return; //unused
|
||||
case 0x3033: regs.bramr = data; return;
|
||||
case 0x3034: regs.pbr = data; return;
|
||||
case 0x3035: return; //unused
|
||||
case 0x3036: return; //ROMBR (read only)
|
||||
case 0x3037: regs.cfgr = data; return;
|
||||
case 0x3038: regs.scbr = data; return;
|
||||
case 0x3039: regs.clsr = data; return;
|
||||
case 0x303a: regs.scmr = data; return;
|
||||
case 0x303b: return; //VCR (read only)
|
||||
case 0x303c: return; //RAMBR (read only)
|
||||
case 0x303d: return; //unused
|
||||
case 0x303e: return; //CBR low (read only)
|
||||
case 0x303f: return; //CBR high (read only)
|
||||
|
||||
//0x3040 - 0x30ff unused
|
||||
}
|
||||
|
||||
if(addr >= 0x3100 && addr <= 0x32ff) {
|
||||
cache[addr - 0x3100] = data;
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,174 @@
|
|||
struct Reg16 {
|
||||
union {
|
||||
uint16 w;
|
||||
struct { uint8 order_lsb2(l, h); };
|
||||
};
|
||||
|
||||
inline operator unsigned() const { return w; }
|
||||
inline unsigned operator=(const unsigned i) { return w = i; }
|
||||
|
||||
Reg16() : w(0) {}
|
||||
};
|
||||
|
||||
template<int bit> struct RegFlag8 {
|
||||
uint8 data;
|
||||
|
||||
inline operator bool() const { return data & bit; }
|
||||
inline bool operator=(const bool i) { i ? data |= bit : data &= ~bit; return i; }
|
||||
};
|
||||
|
||||
template<int bit> struct RegFlag16 {
|
||||
uint16 data;
|
||||
|
||||
inline operator bool() const { return data & bit; }
|
||||
inline bool operator=(const bool i) { i ? data |= bit : data &= ~bit; return i; }
|
||||
};
|
||||
|
||||
struct SFR {
|
||||
union {
|
||||
uint16 w;
|
||||
struct { uint8 order_lsb2(l, h); };
|
||||
RegFlag16<0x0002> z; //zero flag
|
||||
RegFlag16<0x0004> c; //carry flag
|
||||
RegFlag16<0x0008> s; //sign flag
|
||||
RegFlag16<0x0010> v; //overflow flag
|
||||
RegFlag16<0x0020> g; //go flag
|
||||
RegFlag16<0x0040> r; //ROM read using r14 flag
|
||||
RegFlag16<0x0100> alt1; //alternate instruction 1 flag
|
||||
RegFlag16<0x0200> alt2; //alternate instruction 2 flag
|
||||
RegFlag16<0x0400> il; //immediate lower 8-bit flag
|
||||
RegFlag16<0x0800> ih; //immediate upper 8-bit flag
|
||||
RegFlag16<0x1000> b; //WITH instruction flag
|
||||
RegFlag16<0x8000> irq; //interrupt flag
|
||||
};
|
||||
|
||||
inline operator unsigned() const { return w & 0x9f7e; } //invalid flag bits always return 0 when read
|
||||
inline unsigned operator=(const unsigned i) { return w = i & 0x9f7e; }
|
||||
|
||||
SFR() : w(0) {}
|
||||
};
|
||||
|
||||
struct RAMBR {
|
||||
union {
|
||||
uint8 b;
|
||||
RegFlag8<0x01> bank;
|
||||
};
|
||||
|
||||
inline operator unsigned() const { return b & 0x01; }
|
||||
inline unsigned operator=(const unsigned i) { return b = i & 0x01; }
|
||||
|
||||
RAMBR() : b(0) {}
|
||||
};
|
||||
|
||||
struct CBR {
|
||||
uint16 w;
|
||||
|
||||
inline operator unsigned() const { return w & 0xfff0; }
|
||||
inline unsigned operator=(const unsigned i) { return w = i & 0xfff0; }
|
||||
|
||||
CBR() : w(0) {}
|
||||
};
|
||||
|
||||
struct SCMR {
|
||||
union {
|
||||
uint8 b;
|
||||
RegFlag8<0x01> md0; //color mode low
|
||||
RegFlag8<0x02> md1; //color mode high
|
||||
RegFlag8<0x04> ht0; //height low
|
||||
RegFlag8<0x08> ran; //ram enable
|
||||
RegFlag8<0x10> ron; //rom enable
|
||||
RegFlag8<0x20> ht1; //height high
|
||||
};
|
||||
|
||||
inline operator unsigned() const { return b; }
|
||||
inline unsigned operator=(const unsigned i) { return b = i; }
|
||||
|
||||
SCMR() : b(0) {}
|
||||
};
|
||||
|
||||
struct BRAMR {
|
||||
union {
|
||||
uint8 b;
|
||||
RegFlag8<0x01> flag;
|
||||
};
|
||||
|
||||
inline operator unsigned() const { return b; }
|
||||
inline unsigned operator=(const unsigned i) { return b = i; }
|
||||
|
||||
BRAMR() : b(0) {}
|
||||
};
|
||||
|
||||
struct CFGR {
|
||||
union {
|
||||
uint8 b;
|
||||
RegFlag8<0x20> ms0; //multiplier speed selection
|
||||
RegFlag8<0x80> irq; //irq mask flag
|
||||
};
|
||||
|
||||
inline operator unsigned() const { return b; }
|
||||
inline unsigned operator=(const unsigned i) { return b = i; }
|
||||
|
||||
CFGR() : b(0) {}
|
||||
};
|
||||
|
||||
struct CLSR {
|
||||
union {
|
||||
uint8 b;
|
||||
RegFlag8<0x01> flag;
|
||||
};
|
||||
|
||||
inline operator unsigned() const { return b; }
|
||||
inline unsigned operator=(const unsigned i) { return b = i; }
|
||||
|
||||
CLSR() : b(0) {}
|
||||
};
|
||||
|
||||
struct POR {
|
||||
union {
|
||||
uint8 b;
|
||||
RegFlag8<0x01> transparent; //transparent flag
|
||||
RegFlag8<0x02> dither; //dither flag
|
||||
RegFlag8<0x04> highnibble; //high nibble flag
|
||||
RegFlag8<0x08> freezehigh; //freeze high flag
|
||||
RegFlag8<0x10> obj; //OBJ flag
|
||||
};
|
||||
|
||||
inline operator unsigned() const { return b; }
|
||||
inline unsigned operator=(const unsigned i) { return b = i; }
|
||||
|
||||
POR() : b(0) {}
|
||||
};
|
||||
|
||||
struct Regs {
|
||||
Reg16 r0; //default source/destination register
|
||||
Reg16 r1; //pixel plot X position register
|
||||
Reg16 r2; //pixel plot Y position register
|
||||
Reg16 r3;
|
||||
Reg16 r4; //lower 16-bit result of lmult
|
||||
Reg16 r5;
|
||||
Reg16 r6; //multiplier for fmult and lmult
|
||||
Reg16 r7; //fixed point texel X position for merge
|
||||
Reg16 r8; //fixed point texel Y position for merge
|
||||
Reg16 r9;
|
||||
Reg16 r10;
|
||||
Reg16 r11; //return address set by link
|
||||
Reg16 r12; //loop counter
|
||||
Reg16 r13; //loop point address
|
||||
Reg16 r14; //rom address for getb, getbh, getbl, getbs
|
||||
Reg16 r15; //program counter
|
||||
|
||||
SFR sfr; //status/flag register
|
||||
uint8 pbr; //program bank register
|
||||
uint8 rombr; //rom bank register
|
||||
RAMBR rambr; //ram bank register
|
||||
CBR cbr; //cache base register
|
||||
uint8 scbr; //screen base register
|
||||
SCMR scmr; //screen mode register
|
||||
BRAMR bramr; //backup ram register
|
||||
uint8 vcr; //version code register
|
||||
CFGR cfgr; //config register
|
||||
CLSR clsr; //clock select register
|
||||
|
||||
uint8 colr; //color register
|
||||
POR por; //plot option register
|
||||
} regs;
|
|
@ -0,0 +1,42 @@
|
|||
#include "../../base.h"
|
||||
|
||||
#include "core/op0x.cpp"
|
||||
|
||||
#include "memory/read.cpp"
|
||||
#include "memory/write.cpp"
|
||||
|
||||
void SuperFX::init() {
|
||||
}
|
||||
|
||||
void SuperFX::enable() {
|
||||
for(uint i = 0x3000; i <= 0x32ff; i++) {
|
||||
r_mem->set_mmio_mapper(i, this);
|
||||
}
|
||||
}
|
||||
|
||||
void SuperFX::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void SuperFX::reset() {
|
||||
regs.r0 = 0;
|
||||
regs.r1 = 0;
|
||||
regs.r2 = 0;
|
||||
regs.r3 = 0;
|
||||
regs.r4 = 0;
|
||||
regs.r5 = 0;
|
||||
regs.r6 = 0;
|
||||
regs.r7 = 0;
|
||||
regs.r8 = 0;
|
||||
regs.r9 = 0;
|
||||
regs.r10 = 0;
|
||||
regs.r11 = 0;
|
||||
regs.r12 = 0;
|
||||
regs.r13 = 0;
|
||||
regs.r14 = 0;
|
||||
regs.r15 = 0;
|
||||
|
||||
regs.sfr = 0;
|
||||
|
||||
memset(cache, 0, sizeof cache);
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
class SuperFX : public MMIO { public:
|
||||
#include "core/core.h"
|
||||
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
uint8 mmio_read (uint16 addr);
|
||||
void mmio_write(uint16 addr, uint8 data);
|
||||
|
||||
private:
|
||||
#include "regs.h"
|
||||
uint8 cache[512]; //cache RAM
|
||||
};
|
||||
|
||||
extern SuperFX superfx;
|
|
@ -1 +1,2 @@
|
|||
::@make PLATFORM=win-mingw4-lui clean
|
||||
@make PLATFORM=win-visualc-lui clean
|
||||
|
|
|
@ -83,8 +83,8 @@ inline uint32 sCPU::hdma_iaddr(uint8 i) {
|
|||
*****/
|
||||
|
||||
void sCPU::dma_transfertobusb(uint8 i, uint8 bbus) {
|
||||
if(cartridge.info.sdd1 == true && sdd1->dma_active() == true) {
|
||||
r_mem->write(0x2100 | bbus, sdd1->dma_read());
|
||||
if(cartridge.info.sdd1 == true && sdd1.dma_active() == true) {
|
||||
r_mem->write(0x2100 | bbus, sdd1.dma_read());
|
||||
} else {
|
||||
dma_transfer(0, bbus, dma_addr(i));
|
||||
}
|
||||
|
@ -111,8 +111,7 @@ void sCPU::dma_run() {
|
|||
dma_add_clocks(8);
|
||||
|
||||
if(cartridge.info.sdd1 == true) {
|
||||
sdd1->dma_begin(i, (channel[i].srcbank << 16) | (channel[i].srcaddr),
|
||||
channel[i].xfersize);
|
||||
sdd1.dma_begin(i, (channel[i].srcbank << 16) | (channel[i].srcaddr), channel[i].xfersize);
|
||||
}
|
||||
|
||||
if(tracer.enabled() == true && tracer.cpudma_enabled() == true) {
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
class sCPU : public CPU {
|
||||
public:
|
||||
class sCPU : public CPU { public:
|
||||
void enter();
|
||||
|
||||
public:
|
||||
#include "core/core.h"
|
||||
#include "dma/dma.h"
|
||||
#include "memory/memory.h"
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 4.2 KiB |
Binary file not shown.
Before Width: | Height: | Size: 20 KiB |
|
@ -33,11 +33,14 @@
|
|||
|
||||
#include "snes/snes.h"
|
||||
|
||||
#include "chip/superfx/superfx.h"
|
||||
#include "chip/srtc/srtc.h"
|
||||
#include "chip/sdd1/sdd1.h"
|
||||
#include "chip/c4/c4.h"
|
||||
#include "chip/dsp1/dsp1.h"
|
||||
#include "chip/dsp2/dsp2.h"
|
||||
#include "chip/dsp3/dsp3.h"
|
||||
#include "chip/dsp4/dsp4.h"
|
||||
#include "chip/obc1/obc1.h"
|
||||
#include "chip/st010/st010.h"
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@ void bMemBus::load_cart() {
|
|||
if(cartridge.info.c4) cart_map_c4();
|
||||
if(cartridge.info.dsp1) cart_map_dsp1();
|
||||
if(cartridge.info.dsp2) cart_map_dsp2();
|
||||
if(cartridge.info.dsp3) cart_map_dsp3();
|
||||
if(cartridge.info.dsp4) cart_map_dsp4();
|
||||
if(cartridge.info.obc1) cart_map_obc1();
|
||||
if(cartridge.info.st010)cart_map_st010();
|
||||
|
||||
|
@ -58,13 +60,19 @@ char t[256];
|
|||
dprintf("* Region : %s", (cartridge.info.region == Cartridge::NTSC) ? "NTSC" : "PAL");
|
||||
|
||||
strcpy(t, "");
|
||||
if(cartridge.info.srtc) strcat(t, "S-RTC, ");
|
||||
if(cartridge.info.sdd1) strcat(t, "S-DD1, ");
|
||||
if(cartridge.info.c4) strcat(t, "Cx4, ");
|
||||
if(cartridge.info.dsp1) strcat(t, "DSP-1, ");
|
||||
if(cartridge.info.dsp2) strcat(t, "DSP-2, ");
|
||||
if(cartridge.info.obc1) strcat(t, "OBC-1, ");
|
||||
if(cartridge.info.st010)strcat(t, "ST010, ");
|
||||
if(cartridge.info.superfx)strcat(t, "SuperFX, ");
|
||||
if(cartridge.info.sa1) strcat(t, "SA-1, ");
|
||||
if(cartridge.info.srtc) strcat(t, "S-RTC, ");
|
||||
if(cartridge.info.sdd1) strcat(t, "S-DD1, ");
|
||||
if(cartridge.info.c4) strcat(t, "Cx4, ");
|
||||
if(cartridge.info.dsp1) strcat(t, "DSP-1, ");
|
||||
if(cartridge.info.dsp2) strcat(t, "DSP-2, ");
|
||||
if(cartridge.info.dsp3) strcat(t, "DSP-3, ");
|
||||
if(cartridge.info.dsp4) strcat(t, "DSP-4, ");
|
||||
if(cartridge.info.obc1) strcat(t, "OBC-1, ");
|
||||
if(cartridge.info.st010) strcat(t, "ST010, ");
|
||||
if(cartridge.info.st011) strcat(t, "ST011, ");
|
||||
if(cartridge.info.st018) strcat(t, "ST018, ");
|
||||
strrtrim(t, ", ");
|
||||
dprintf("* Coprocessor(s) : %s", (strlen(t) == 0) ? "None" : t);
|
||||
dprintf("* Reset:%0.4x NMI[n]:%0.4x IRQ[n]:%0.4x BRK[n]:%0.4x COP[n]:%0.4x",
|
||||
|
|
|
@ -39,6 +39,10 @@ enum { TYPE_WRAM, TYPE_MMIO, TYPE_CART };
|
|||
void write_dsp1 (uint32 addr, uint8 data);
|
||||
uint8 read_dsp2 (uint32 addr);
|
||||
void write_dsp2 (uint32 addr, uint8 data);
|
||||
uint8 read_dsp3 (uint32 addr);
|
||||
void write_dsp3 (uint32 addr, uint8 data);
|
||||
uint8 read_dsp4 (uint32 addr);
|
||||
void write_dsp4 (uint32 addr, uint8 data);
|
||||
uint8 read_obc1 (uint32 addr);
|
||||
void write_obc1 (uint32 addr, uint8 data);
|
||||
uint8 read_st010 (uint32 addr);
|
||||
|
@ -52,6 +56,8 @@ enum { TYPE_WRAM, TYPE_MMIO, TYPE_CART };
|
|||
void cart_map_c4();
|
||||
void cart_map_dsp1();
|
||||
void cart_map_dsp2();
|
||||
void cart_map_dsp3();
|
||||
void cart_map_dsp4();
|
||||
void cart_map_obc1();
|
||||
void cart_map_st010();
|
||||
|
||||
|
|
|
@ -167,6 +167,30 @@ void bMemBus::cart_map_dsp2() {
|
|||
}
|
||||
}
|
||||
|
||||
void bMemBus::cart_map_dsp3() {
|
||||
//$[20-3f|a0-bf]:[8000-ffff]
|
||||
for(uint bank = 0x20; bank <= 0x3f; bank++) {
|
||||
for(uint page = 0x80; page <= 0xff; page++) {
|
||||
page_read [0x0000 + (bank << 8) + page] = &bMemBus::read_dsp3;
|
||||
page_read [0x8000 + (bank << 8) + page] = &bMemBus::read_dsp3;
|
||||
page_write[0x0000 + (bank << 8) + page] = &bMemBus::write_dsp3;
|
||||
page_write[0x8000 + (bank << 8) + page] = &bMemBus::write_dsp3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bMemBus::cart_map_dsp4() {
|
||||
//$[30-3f|b0-bf]:[8000-ffff]
|
||||
for(uint bank = 0x30; bank <= 0x3f; bank++) {
|
||||
for(uint page = 0x80; page <= 0xff; page++) {
|
||||
page_read [0x0000 + (bank << 8) + page] = &bMemBus::read_dsp4;
|
||||
page_read [0x8000 + (bank << 8) + page] = &bMemBus::read_dsp4;
|
||||
page_write[0x0000 + (bank << 8) + page] = &bMemBus::write_dsp4;
|
||||
page_write[0x8000 + (bank << 8) + page] = &bMemBus::write_dsp4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bMemBus::cart_map_obc1() {
|
||||
//$[00-3f|80-bf]:[6000-7fff]
|
||||
for(uint bank = 0x00; bank <= 0x3f; bank++) {
|
||||
|
|
|
@ -39,29 +39,35 @@ void bMemBus::write_ram(uint32 addr, uint8 data) {
|
|||
//
|
||||
|
||||
uint8 bMemBus::read_sdd1(uint32 addr) {
|
||||
addr = sdd1->offset(addr) % cartridge.info.rom_size;
|
||||
addr = sdd1.offset(addr) % cartridge.info.rom_size;
|
||||
return cartridge.rom[addr];
|
||||
}
|
||||
|
||||
void bMemBus::write_sdd1(uint32 addr, uint8 data) {
|
||||
if(cart_write_protect_enabled == true)return;
|
||||
addr = sdd1->offset(addr) % cartridge.info.rom_size;
|
||||
addr = sdd1.offset(addr) % cartridge.info.rom_size;
|
||||
cartridge.rom[addr] = data;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
uint8 bMemBus::read_c4 (uint32 addr) { return c4->read(addr); }
|
||||
void bMemBus::write_c4(uint32 addr, uint8 data) { c4->write(addr, data); }
|
||||
uint8 bMemBus::read_c4 (uint32 addr) { return c4.read(addr); }
|
||||
void bMemBus::write_c4(uint32 addr, uint8 data) { c4.write(addr, data); }
|
||||
|
||||
uint8 bMemBus::read_dsp1 (uint32 addr) { return dsp1->read(addr); }
|
||||
void bMemBus::write_dsp1(uint32 addr, uint8 data) { dsp1->write(addr, data); }
|
||||
uint8 bMemBus::read_dsp1 (uint32 addr) { return dsp1.read(addr); }
|
||||
void bMemBus::write_dsp1(uint32 addr, uint8 data) { dsp1.write(addr, data); }
|
||||
|
||||
uint8 bMemBus::read_dsp2 (uint32 addr) { return dsp2->read(addr); }
|
||||
void bMemBus::write_dsp2(uint32 addr, uint8 data) { dsp2->write(addr, data); }
|
||||
uint8 bMemBus::read_dsp2 (uint32 addr) { return dsp2.read(addr); }
|
||||
void bMemBus::write_dsp2(uint32 addr, uint8 data) { dsp2.write(addr, data); }
|
||||
|
||||
uint8 bMemBus::read_obc1 (uint32 addr) { return obc1->read(addr); }
|
||||
void bMemBus::write_obc1(uint32 addr, uint8 data) { obc1->write(addr, data); }
|
||||
uint8 bMemBus::read_dsp3 (uint32 addr) { return dsp3.read(addr); }
|
||||
void bMemBus::write_dsp3(uint32 addr, uint8 data) { dsp3.write(addr, data); }
|
||||
|
||||
uint8 bMemBus::read_st010 (uint32 addr) { return st010->read(addr); }
|
||||
void bMemBus::write_st010(uint32 addr, uint8 data) { st010->write(addr, data); }
|
||||
uint8 bMemBus::read_dsp4 (uint32 addr) { return dsp4.read(addr); }
|
||||
void bMemBus::write_dsp4(uint32 addr, uint8 data) { dsp4.write(addr, data); }
|
||||
|
||||
uint8 bMemBus::read_obc1 (uint32 addr) { return obc1.read(addr); }
|
||||
void bMemBus::write_obc1(uint32 addr, uint8 data) { obc1.write(addr, data); }
|
||||
|
||||
uint8 bMemBus::read_st010 (uint32 addr) { return st010.read(addr); }
|
||||
void bMemBus::write_st010(uint32 addr, uint8 data) { st010.write(addr, data); }
|
||||
|
|
|
@ -1,30 +1,33 @@
|
|||
bool bMemBus::cart_map_pcb(const char *pcb) {
|
||||
if(!strcmp(pcb, "SHVC-1A3B-01")) { cart_map_shvc_1a3b_13(); return true; }
|
||||
if(!strcmp(pcb, "SHVC-1A3B-11")) { cart_map_shvc_1a3b_13(); return true; }
|
||||
if(!strcmp(pcb, "SHVC-1A3B-12")) { cart_map_shvc_1a3b_13(); return true; }
|
||||
if(!strcmp(pcb, "SHVC-1A3B-13")) { cart_map_shvc_1a3b_13(); return true; }
|
||||
if(!strcmp(pcb, "SHVC-1CB5B-01")) { cart_map_shvc_1cb5b_20(); return true; }
|
||||
if(!strcmp(pcb, "SHVC-1CB5B-20")) { cart_map_shvc_1cb5b_20(); return true; }
|
||||
|
||||
if(!strcmp(pcb, "SHVC-1A3B-20")) { cart_map_shvc_1a3b_20(); return true; }
|
||||
if(!strcmp(pcb, "SHVC-1A3B-01")) { cart_map_shvc_1a3b_13(); return true; }
|
||||
if(!strcmp(pcb, "SHVC-1A3B-11")) { cart_map_shvc_1a3b_13(); return true; }
|
||||
if(!strcmp(pcb, "SHVC-1A3B-12")) { cart_map_shvc_1a3b_13(); return true; }
|
||||
if(!strcmp(pcb, "SHVC-1A3B-13")) { cart_map_shvc_1a3b_13(); return true; }
|
||||
|
||||
if(!strcmp(pcb, "SHVC-1A3M-10")) { cart_map_shvc_1a3m_30(); return true; }
|
||||
if(!strcmp(pcb, "SHVC-1A3M-20")) { cart_map_shvc_1a3m_30(); return true; }
|
||||
if(!strcmp(pcb, "SHVC-1A3M-21")) { cart_map_shvc_1a3m_30(); return true; }
|
||||
if(!strcmp(pcb, "SHVC-1A3M-30")) { cart_map_shvc_1a3m_30(); return true; }
|
||||
if(!strcmp(pcb, "SHVC-1A3B-20")) { cart_map_shvc_1a3b_20(); return true; }
|
||||
|
||||
if(!strcmp(pcb, "SHVC-1J3M-01")) { cart_map_shvc_1j3m_20(); return true; }
|
||||
if(!strcmp(pcb, "SHVC-1J3M-10")) { cart_map_shvc_1j3m_20(); return true; }
|
||||
if(!strcmp(pcb, "SHVC-1J3M-11")) { cart_map_shvc_1j3m_20(); return true; }
|
||||
if(!strcmp(pcb, "SHVC-1J3M-20")) { cart_map_shvc_1j3m_20(); return true; }
|
||||
if(!strcmp(pcb, "SHVC-1A3M-10")) { cart_map_shvc_1a3m_30(); return true; }
|
||||
if(!strcmp(pcb, "SHVC-1A3M-20")) { cart_map_shvc_1a3m_30(); return true; }
|
||||
if(!strcmp(pcb, "SHVC-1A3M-21")) { cart_map_shvc_1a3m_30(); return true; }
|
||||
if(!strcmp(pcb, "SHVC-1A3M-30")) { cart_map_shvc_1a3m_30(); return true; }
|
||||
|
||||
if(!strcmp(pcb, "BSC-1A5M-01")) { cart_map_bsc_1a5m_01(); return true; }
|
||||
if(!strcmp(pcb, "SHVC-1J3M-01")) { cart_map_shvc_1j3m_20(); return true; }
|
||||
if(!strcmp(pcb, "SHVC-1J3M-10")) { cart_map_shvc_1j3m_20(); return true; }
|
||||
if(!strcmp(pcb, "SHVC-1J3M-11")) { cart_map_shvc_1j3m_20(); return true; }
|
||||
if(!strcmp(pcb, "SHVC-1J3M-20")) { cart_map_shvc_1j3m_20(); return true; }
|
||||
|
||||
if(!strcmp(pcb, "BSC-1A7M-01")) { cart_map_bsc_1a7m_01(); return true; }
|
||||
if(!strcmp(pcb, "BSC-1A5M-01")) { cart_map_bsc_1a5m_01(); return true; }
|
||||
|
||||
if(!strcmp(pcb, "BSC-1A7M-10")) { cart_map_bsc_1a7m_10(); return true; }
|
||||
if(!strcmp(pcb, "BSC-1A7M-01")) { cart_map_bsc_1a7m_01(); return true; }
|
||||
|
||||
if(!strcmp(pcb, "STC-SOLO")) { cart_map_stc_solo(); return true; }
|
||||
if(!strcmp(pcb, "BSC-1A7M-10")) { cart_map_bsc_1a7m_10(); return true; }
|
||||
|
||||
if(!strcmp(pcb, "STC-DUAL")) { cart_map_stc_dual(); return true; }
|
||||
if(!strcmp(pcb, "STC-SOLO")) { cart_map_stc_solo(); return true; }
|
||||
|
||||
if(!strcmp(pcb, "STC-DUAL")) { cart_map_stc_dual(); return true; }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ enum {
|
|||
void cart_map_range(uint mode, uint8 bank_lo, uint8 bank_hi, uint16 addr_lo, uint16 addr_hi, uint type, uint offset = 0);
|
||||
|
||||
#define mapper(name) void cart_map_##name()
|
||||
mapper(shvc_1cb5b_20);
|
||||
mapper(shvc_1a3b_13);
|
||||
mapper(shvc_1a3b_20);
|
||||
mapper(shvc_1a3m_30);
|
||||
|
|
|
@ -1,3 +1,15 @@
|
|||
//SHVC-1CB5B-01
|
||||
//SHVC-1CB5B-20
|
||||
mapper(shvc_1cb5b_20) {
|
||||
cartridge.info.superfx = true; //TODO: make this more elegant
|
||||
|
||||
map(LINEAR, 0x00, 0x3f, 0x6000, 0x7fff, MAP_RAM);
|
||||
map(LINEAR, 0x00, 0x3f, 0x8000, 0xffff, MAP_ROM);
|
||||
map(LINEAR, 0x40, 0x5f, 0x0000, 0xffff, MAP_ROM);
|
||||
map(LINEAR, 0x70, 0x71, 0x0000, 0xffff, MAP_RAM);
|
||||
map(LINEAR, 0x80, 0xbf, 0x6000, 0x7fff, MAP_RAM);
|
||||
}
|
||||
|
||||
//SHVC-1A3B-01
|
||||
//SHVC-1A3B-11
|
||||
//SHVC-1A3B-12
|
||||
|
|
|
@ -1,6 +1,16 @@
|
|||
#include "../base.h"
|
||||
|
||||
SNES snes;
|
||||
SuperFX superfx;
|
||||
SRTC srtc;
|
||||
SDD1 sdd1;
|
||||
C4 c4;
|
||||
DSP1 dsp1;
|
||||
DSP2 dsp2;
|
||||
DSP3 dsp3;
|
||||
DSP4 dsp4;
|
||||
OBC1 obc1;
|
||||
ST010 st010;
|
||||
|
||||
#include "scheduler/scheduler.cpp"
|
||||
#include "tracer/tracer.cpp"
|
||||
|
@ -16,21 +26,16 @@ void SNES::runtoframe() {
|
|||
}
|
||||
|
||||
void SNES::init() {
|
||||
srtc = new SRTC();
|
||||
sdd1 = new SDD1();
|
||||
c4 = new C4();
|
||||
dsp1 = new DSP1();
|
||||
dsp2 = new DSP2();
|
||||
obc1 = new OBC1();
|
||||
st010 = new ST010();
|
||||
|
||||
srtc->init();
|
||||
sdd1->init();
|
||||
c4->init();
|
||||
dsp1->init();
|
||||
dsp2->init();
|
||||
obc1->init();
|
||||
st010->init();
|
||||
superfx.init();
|
||||
srtc.init();
|
||||
sdd1.init();
|
||||
c4.init();
|
||||
dsp1.init();
|
||||
dsp2.init();
|
||||
dsp3.init();
|
||||
dsp4.init();
|
||||
obc1.init();
|
||||
st010.init();
|
||||
|
||||
video_init();
|
||||
audio_init();
|
||||
|
@ -52,13 +57,16 @@ void SNES::power() {
|
|||
r_ppu->power();
|
||||
r_mem->power();
|
||||
|
||||
if(cartridge.info.srtc) srtc->power();
|
||||
if(cartridge.info.sdd1) sdd1->power();
|
||||
if(cartridge.info.c4) c4->power();
|
||||
if(cartridge.info.dsp1) dsp1->power();
|
||||
if(cartridge.info.dsp2) dsp2->power();
|
||||
if(cartridge.info.obc1) obc1->power();
|
||||
if(cartridge.info.st010)st010->power();
|
||||
if(cartridge.info.superfx)superfx.power();
|
||||
if(cartridge.info.srtc) srtc.power();
|
||||
if(cartridge.info.sdd1) sdd1.power();
|
||||
if(cartridge.info.c4) c4.power();
|
||||
if(cartridge.info.dsp1) dsp1.power();
|
||||
if(cartridge.info.dsp2) dsp2.power();
|
||||
if(cartridge.info.dsp3) dsp3.power();
|
||||
if(cartridge.info.dsp4) dsp4.power();
|
||||
if(cartridge.info.obc1) obc1.power();
|
||||
if(cartridge.info.st010) st010.power();
|
||||
|
||||
r_mem->flush_mmio_mappers();
|
||||
for(int i = 0x2100; i <= 0x213f; i++)r_mem->set_mmio_mapper(i, r_ppu);
|
||||
|
@ -68,13 +76,16 @@ void SNES::power() {
|
|||
for(int i = 0x4200; i <= 0x421f; i++)r_mem->set_mmio_mapper(i, r_cpu);
|
||||
for(int i = 0x4300; i <= 0x437f; i++)r_mem->set_mmio_mapper(i, r_cpu);
|
||||
|
||||
if(cartridge.info.srtc) srtc->enable();
|
||||
if(cartridge.info.sdd1) sdd1->enable();
|
||||
if(cartridge.info.c4) c4->enable();
|
||||
if(cartridge.info.dsp1) dsp1->enable();
|
||||
if(cartridge.info.dsp2) dsp2->enable();
|
||||
if(cartridge.info.obc1) obc1->enable();
|
||||
if(cartridge.info.st010)st010->enable();
|
||||
if(cartridge.info.superfx)superfx.enable();
|
||||
if(cartridge.info.srtc) srtc.enable();
|
||||
if(cartridge.info.sdd1) sdd1.enable();
|
||||
if(cartridge.info.c4) c4.enable();
|
||||
if(cartridge.info.dsp1) dsp1.enable();
|
||||
if(cartridge.info.dsp2) dsp2.enable();
|
||||
if(cartridge.info.dsp3) dsp3.enable();
|
||||
if(cartridge.info.dsp4) dsp4.enable();
|
||||
if(cartridge.info.obc1) obc1.enable();
|
||||
if(cartridge.info.st010) st010.enable();
|
||||
|
||||
video_update();
|
||||
}
|
||||
|
@ -88,13 +99,16 @@ void SNES::reset() {
|
|||
r_ppu->reset();
|
||||
r_mem->reset();
|
||||
|
||||
if(cartridge.info.srtc) srtc->reset();
|
||||
if(cartridge.info.sdd1) sdd1->reset();
|
||||
if(cartridge.info.c4) c4->reset();
|
||||
if(cartridge.info.dsp1) dsp1->reset();
|
||||
if(cartridge.info.dsp2) dsp2->reset();
|
||||
if(cartridge.info.obc1) obc1->reset();
|
||||
if(cartridge.info.st010)st010->reset();
|
||||
if(cartridge.info.superfx)superfx.reset();
|
||||
if(cartridge.info.srtc) srtc.reset();
|
||||
if(cartridge.info.sdd1) sdd1.reset();
|
||||
if(cartridge.info.c4) c4.reset();
|
||||
if(cartridge.info.dsp1) dsp1.reset();
|
||||
if(cartridge.info.dsp2) dsp2.reset();
|
||||
if(cartridge.info.dsp3) dsp3.reset();
|
||||
if(cartridge.info.dsp4) dsp4.reset();
|
||||
if(cartridge.info.obc1) obc1.reset();
|
||||
if(cartridge.info.st010) st010.reset();
|
||||
|
||||
video_update();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#define IDI_APP_ICON 100
|
||||
#define IDI_CONTROLLER 101
|
||||
#define IDI_APP_ICON 100
|
||||
|
||||
IDI_APP_ICON ICON DISCARDABLE "../data/bsnes.ico"
|
||||
IDI_CONTROLLER BITMAP DISCARDABLE "../data/snes_controller.bmp"
|
||||
IDI_APP_ICON ICON DISCARDABLE "../data/bsnes.ico"
|
||||
|
|
|
@ -26,46 +26,62 @@ IntegerSetting System::speed_fast (&config(), "system.speed_fast", "Fast
|
|||
IntegerSetting System::speed_fastest (&config(), "system.speed_fastest", "Fastest speed setting", IntegerSetting::Decimal, 200);
|
||||
|
||||
struct Video {
|
||||
static IntegerSetting synchronize;
|
||||
static IntegerSetting fullscreen;
|
||||
static IntegerSetting multiplier, aspect_correction, region;
|
||||
static IntegerSetting mode;
|
||||
struct Windowed {
|
||||
static IntegerSetting synchronize, aspect_correction;
|
||||
static IntegerSetting region, multiplier, hardware_filter, software_filter;
|
||||
} windowed;
|
||||
struct Fullscreen {
|
||||
static IntegerSetting synchronize, aspect_correction;
|
||||
static IntegerSetting region, multiplier, hardware_filter, software_filter;
|
||||
} fullscreen;
|
||||
static IntegerSetting aspect_ntsc_x, aspect_ntsc_y, aspect_pal_x, aspect_pal_y;
|
||||
static IntegerSetting hardware_filter, software_filter;
|
||||
static IntegerSetting frameskip;
|
||||
static IntegerSetting use_vram;
|
||||
} video;
|
||||
IntegerSetting Video::synchronize(&config(), "video.synchronize", "Synchronize to video refresh rate.", IntegerSetting::Boolean, false);
|
||||
IntegerSetting Video::fullscreen(0, "video.fullscreen", "", IntegerSetting::Boolean, false);
|
||||
IntegerSetting Video::multiplier(&config(), "video.multiplier", "Video output size multiplier (1-5x)\n"
|
||||
"1 = 1x (~256x224)\n"
|
||||
"2 = 2x (~512x448)\n"
|
||||
"etc.",
|
||||
IntegerSetting::Decimal, 2);
|
||||
IntegerSetting Video::aspect_correction(&config(), "video.aspect_correction",
|
||||
|
||||
//0 = windowed, 1 = fullscreen, 2 = exclusive
|
||||
IntegerSetting Video::mode(0, "video.mode", "Active video mode", IntegerSetting::Decimal, 0);
|
||||
|
||||
IntegerSetting Video::Windowed::synchronize(&config(), "video.windowed.synchronize", "Synchronize to video refresh rate", IntegerSetting::Boolean, false);
|
||||
IntegerSetting Video::Windowed::aspect_correction(&config(), "video.windowed.aspect_correction",
|
||||
"Correct video aspect ratio\n"
|
||||
"Formula: width = width * video.aspect_<region>_x / video.aspect_<region>_y",
|
||||
"Defaults assume display pixels are perfectly square\n"
|
||||
"Formula: width = width * video.aspect_<region>_x / video.aspect_<region>_y\n",
|
||||
IntegerSetting::Boolean, true);
|
||||
IntegerSetting Video::region(&config(), "video.region", "Video output region\n"
|
||||
IntegerSetting Video::Windowed::region(&config(), "video.windowed.region", "Video output region\n"
|
||||
"0 = NTSC, 1 = PAL",
|
||||
IntegerSetting::Decimal, 0);
|
||||
IntegerSetting Video::Windowed::multiplier(&config(), "video.windowed.multiplier", "Video output size multiplier (1-5x)\n"
|
||||
"1 = 1x (<= 320x240)\n"
|
||||
"2 = 2x (<= 640x480)\n"
|
||||
"etc.",
|
||||
IntegerSetting::Decimal, 2);
|
||||
IntegerSetting Video::Windowed::hardware_filter(&config(), "video.windowed.hardware_filter", "Video hardware filter\n"
|
||||
"0 = Point\n"
|
||||
"1 = Linear\n",
|
||||
IntegerSetting::Decimal, 1);
|
||||
IntegerSetting Video::Windowed::software_filter(&config(), "video.windowed.software_filter", "Video software filter\n"
|
||||
"0 = None\n"
|
||||
"1 = NTSC\n"
|
||||
"2 = HQ2x\n"
|
||||
"3 = Scale2x\n",
|
||||
IntegerSetting::Decimal, 0);
|
||||
|
||||
IntegerSetting Video::Fullscreen::synchronize (&config(), "video.fullscreen.synchronize", "", IntegerSetting::Boolean, false);
|
||||
IntegerSetting Video::Fullscreen::aspect_correction(&config(), "video.fullscreen.aspect_correction", "", IntegerSetting::Boolean, true);
|
||||
IntegerSetting Video::Fullscreen::region (&config(), "video.fullscreen.region", "", IntegerSetting::Decimal, 0);
|
||||
IntegerSetting Video::Fullscreen::multiplier (&config(), "video.fullscreen.multiplier", "", IntegerSetting::Decimal, 2);
|
||||
IntegerSetting Video::Fullscreen::hardware_filter (&config(), "video.fullscreen.hardware_filter", "", IntegerSetting::Decimal, 1);
|
||||
IntegerSetting Video::Fullscreen::software_filter (&config(), "video.fullscreen.software_filter", "", IntegerSetting::Decimal, 0);
|
||||
|
||||
IntegerSetting Video::aspect_ntsc_x(&config(), "video.aspect_ntsc_x", "", IntegerSetting::Decimal, 54);
|
||||
IntegerSetting Video::aspect_ntsc_y(&config(), "video.aspect_ntsc_y", "", IntegerSetting::Decimal, 47);
|
||||
IntegerSetting Video::aspect_pal_x (&config(), "video.aspect_pal_x", "", IntegerSetting::Decimal, 32);
|
||||
IntegerSetting Video::aspect_pal_y (&config(), "video.aspect_pal_y", "", IntegerSetting::Decimal, 23);
|
||||
|
||||
IntegerSetting Video::hardware_filter(&config(), "video.hardware_filter", "Video hardware filter\n"
|
||||
"0 = Point\n"
|
||||
"1 = Linear\n",
|
||||
IntegerSetting::Decimal, 1);
|
||||
IntegerSetting Video::software_filter(&config(), "video.software_filter", "Video software filter\n"
|
||||
"0 = None\n"
|
||||
"1 = NTSC\n"
|
||||
"2 = HQ2x\n"
|
||||
"3 = Scale2x\n",
|
||||
IntegerSetting::Decimal, 0);
|
||||
IntegerSetting Video::frameskip(0, "video.frameskip", "Video frameskip", IntegerSetting::Decimal, 0);
|
||||
IntegerSetting Video::use_vram(&config(), "video.use_vram", "Use Video RAM instead of System RAM", IntegerSetting::Boolean, true);
|
||||
IntegerSetting Video::use_vram(&config(), "video.use_vram", "Use Video RAM instead of System RAM when possible", IntegerSetting::Boolean, true);
|
||||
|
||||
struct Audio {
|
||||
static IntegerSetting synchronize;
|
||||
|
|
|
@ -1,5 +1,67 @@
|
|||
namespace event {
|
||||
|
||||
void load_video_settings() {
|
||||
video_settings.mode = config::video.mode;
|
||||
switch(video_settings.mode) { default:
|
||||
case 0: //windowed
|
||||
video_settings.aspect_correction = config::video.windowed.aspect_correction;
|
||||
video_settings.synchronize = config::video.windowed.synchronize;
|
||||
video_settings.region = config::video.windowed.region;
|
||||
video_settings.multiplier = config::video.windowed.multiplier;
|
||||
video_settings.hardware_filter = config::video.windowed.hardware_filter;
|
||||
video_settings.software_filter = config::video.windowed.software_filter;
|
||||
break;
|
||||
case 1: //fullscreen
|
||||
video_settings.aspect_correction = config::video.fullscreen.aspect_correction;
|
||||
video_settings.synchronize = config::video.fullscreen.synchronize;
|
||||
video_settings.region = config::video.fullscreen.region;
|
||||
video_settings.multiplier = config::video.fullscreen.multiplier;
|
||||
video_settings.hardware_filter = config::video.fullscreen.hardware_filter;
|
||||
video_settings.software_filter = config::video.fullscreen.software_filter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void update_aspect_correction(bool aspect_correction) {
|
||||
switch(config::video.mode) { default:
|
||||
case 0: config::video.windowed.aspect_correction = aspect_correction; break;
|
||||
case 1: config::video.fullscreen.aspect_correction = aspect_correction; break;
|
||||
}
|
||||
update_video_settings();
|
||||
}
|
||||
|
||||
void update_multiplier(uint multiplier) {
|
||||
switch(config::video.mode) { default:
|
||||
case 0: config::video.windowed.multiplier = multiplier; break;
|
||||
case 1: config::video.fullscreen.multiplier = multiplier; break;
|
||||
}
|
||||
update_video_settings();
|
||||
}
|
||||
|
||||
void update_region(uint region) {
|
||||
switch(config::video.mode) { default:
|
||||
case 0: config::video.windowed.region = region; break;
|
||||
case 1: config::video.fullscreen.region = region; break;
|
||||
}
|
||||
update_video_settings();
|
||||
}
|
||||
|
||||
void update_hardware_filter(uint hardware_filter) {
|
||||
switch(config::video.mode) { default:
|
||||
case 0: config::video.windowed.hardware_filter = hardware_filter; break;
|
||||
case 1: config::video.fullscreen.hardware_filter = hardware_filter; break;
|
||||
}
|
||||
update_video_settings();
|
||||
}
|
||||
|
||||
void update_software_filter(uint software_filter) {
|
||||
switch(config::video.mode) { default:
|
||||
case 0: config::video.windowed.software_filter = software_filter; break;
|
||||
case 1: config::video.fullscreen.software_filter = software_filter; break;
|
||||
}
|
||||
update_video_settings();
|
||||
}
|
||||
|
||||
void update_frame_counter() {
|
||||
if(r_ppu->status.frames_updated) {
|
||||
r_ppu->status.frames_updated = false;
|
||||
|
@ -10,49 +72,59 @@ void update_frame_counter() {
|
|||
}
|
||||
|
||||
void update_video_settings() {
|
||||
load_video_settings();
|
||||
|
||||
uint width = 256;
|
||||
uint height = config::video.region == 0 ? 224 : 239;
|
||||
uint multiplier = minmax<1, 5>(uint(config::video.multiplier));
|
||||
uint height = video_settings.region == 0 ? 224 : 239;
|
||||
uint multiplier = minmax<1, 5>(video_settings.multiplier);
|
||||
width *= multiplier;
|
||||
height *= multiplier;
|
||||
if(config::video.aspect_correction == true) {
|
||||
if(config::video.region == 0) { //NTSC
|
||||
if(video_settings.aspect_correction == true) {
|
||||
if(video_settings.region == 0) { //NTSC
|
||||
width = uint( double(width) * double(config::video.aspect_ntsc_x) / double(config::video.aspect_ntsc_y) );
|
||||
} else { //PAL
|
||||
width = uint( double(width) * double(config::video.aspect_pal_x) / double(config::video.aspect_pal_y) );
|
||||
}
|
||||
}
|
||||
|
||||
if(config::video.fullscreen) {
|
||||
//window_main.menu.hide();
|
||||
window_main.fullscreen();
|
||||
window_main.view.move((ui::get_screen_width() - width) / 2, (ui::get_screen_height() - height) / 2);
|
||||
window_main.view.resize(width, height);
|
||||
} else {
|
||||
//window_main.menu.show();
|
||||
switch(video_settings.mode) { default:
|
||||
case 0: //windowed
|
||||
window_main.unfullscreen();
|
||||
window_main.resize(width, height);
|
||||
window_main.view.move(0, 0);
|
||||
window_main.view.resize(width, height);
|
||||
break;
|
||||
case 1: //fullscreen
|
||||
window_main.fullscreen();
|
||||
window_main.view.move((ui::get_screen_width() - width) / 2, (ui::get_screen_height() - height) / 2);
|
||||
window_main.view.resize(width, height);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void update_raster_settings() {
|
||||
uint filter, standard;
|
||||
switch(uint(config::video.software_filter)) { default:
|
||||
switch(video_settings.software_filter) { default:
|
||||
case 0: filter = VIDEOFILTER_DIRECT; break;
|
||||
case 1: filter = VIDEOFILTER_NTSC; break;
|
||||
case 2: filter = VIDEOFILTER_HQ2X; break;
|
||||
case 3: filter = VIDEOFILTER_SCALE2X; break;
|
||||
}
|
||||
|
||||
switch(uint(config::video.region)) { default:
|
||||
switch(video_settings.region) { default:
|
||||
case 0: standard = SNES::VIDEOSTANDARD_NTSC; break;
|
||||
case 1: standard = SNES::VIDEOSTANDARD_PAL; break;
|
||||
}
|
||||
|
||||
snes.set_video_filter(filter);
|
||||
snes.set_video_standard(standard);
|
||||
|
||||
if(uiVideo) {
|
||||
uiVideo->settings.synchronize = video_settings.synchronize;
|
||||
uiVideo->settings.filter = video_settings.hardware_filter;
|
||||
uiVideo->update_settings();
|
||||
}
|
||||
|
||||
//update main window video mode checkbox settings
|
||||
window_main.update_menu_settings();
|
||||
}
|
||||
|
||||
void toggle_menu() {
|
||||
|
@ -61,7 +133,11 @@ void toggle_menu() {
|
|||
}
|
||||
|
||||
void toggle_fullscreen() {
|
||||
config::video.fullscreen = !config::video.fullscreen;
|
||||
if(config::video.mode != 1) { //switch to fullscreen mode if not already in it
|
||||
config::video.mode = 1;
|
||||
} else { //switch to windowed mode if already in fullscreen mode
|
||||
config::video.mode = 0;
|
||||
}
|
||||
update_video_settings();
|
||||
}
|
||||
|
||||
|
@ -99,9 +175,16 @@ char fn[PATH_MAX];
|
|||
if(load_rom(fn) == false)return;
|
||||
|
||||
if(cartridge.loaded() == true)cartridge.unload();
|
||||
cartridge.load_begin(Cartridge::CART_NORMAL);
|
||||
cartridge.load_begin(Cartridge::CartridgeNormal);
|
||||
cartridge.load(fn);
|
||||
cartridge.load_end();
|
||||
|
||||
//warn if unsupported hardware detected
|
||||
if(cartridge.info.superfx)alert("Warning: unsupported SuperFX chip detected.");
|
||||
if(cartridge.info.sa1) alert("Warning: unsupported SA-1 chip detected.");
|
||||
if(cartridge.info.st011) alert("Warning: unsupported ST011 chip detected.");
|
||||
if(cartridge.info.st018) alert("Warning: unsupported ST018 chip detected.");
|
||||
|
||||
snes.power();
|
||||
window_cheat_editor.refresh();
|
||||
}
|
||||
|
@ -111,7 +194,7 @@ char fn[PATH_MAX];
|
|||
if(load_rom(fn) == false)return;
|
||||
|
||||
if(cartridge.loaded() == true)cartridge.unload();
|
||||
cartridge.load_begin(Cartridge::CART_ST);
|
||||
cartridge.load_begin(Cartridge::CartridgeSufamiTurbo);
|
||||
cartridge.load(fn);
|
||||
cartridge.load_end();
|
||||
snes.power();
|
||||
|
@ -124,7 +207,7 @@ char fn_a[PATH_MAX], fn_b[PATH_MAX];
|
|||
if(load_rom(fn_b) == false)return;
|
||||
|
||||
if(cartridge.loaded() == true)cartridge.unload();
|
||||
cartridge.load_begin(Cartridge::CART_STDUAL);
|
||||
cartridge.load_begin(Cartridge::CartridgeSufamiTurboDual);
|
||||
cartridge.load(fn_a);
|
||||
cartridge.load(fn_b);
|
||||
cartridge.load_end();
|
||||
|
|
|
@ -1,12 +1,29 @@
|
|||
namespace event {
|
||||
|
||||
struct VideoSettings {
|
||||
uint mode;
|
||||
bool synchronize;
|
||||
bool aspect_correction;
|
||||
uint region;
|
||||
uint multiplier;
|
||||
uint hardware_filter;
|
||||
uint software_filter;
|
||||
} video_settings;
|
||||
void load_video_settings();
|
||||
|
||||
//change video settings for active video mode
|
||||
void update_aspect_correction(bool);
|
||||
void update_multiplier(uint);
|
||||
void update_region(uint);
|
||||
void update_hardware_filter(uint);
|
||||
void update_software_filter(uint);
|
||||
|
||||
void update_frame_counter();
|
||||
void update_video_settings();
|
||||
void update_raster_settings();
|
||||
void toggle_menu();
|
||||
void toggle_fullscreen();
|
||||
|
||||
bool load_rom(char *fn);
|
||||
bool load_rom(char*);
|
||||
void load_rom();
|
||||
void load_rom_st();
|
||||
void load_rom_stdual();
|
||||
|
|
|
@ -24,7 +24,11 @@ va_list args;
|
|||
va_start(args, s);
|
||||
vsprintf(str, s, args);
|
||||
va_end(args);
|
||||
#if defined(PLATFORM_WIN)
|
||||
MessageBox(0, str, "bsnes", MB_OK);
|
||||
#else
|
||||
fprintf(stdout, "%s\r\n", str);
|
||||
#endif
|
||||
}
|
||||
|
||||
void dprintf(const char *s, ...) {
|
||||
|
@ -104,12 +108,16 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
ui::init();
|
||||
config::config().load(config::filename);
|
||||
config::config().save(config::filename); //in case program crashes on first run, config file settings can be modified
|
||||
if(fexists(config::filename) == false) {
|
||||
//in case program crashes on first run, save config file
|
||||
//settings, so that they can be modified by hand ...
|
||||
config::config().save(config::filename);
|
||||
}
|
||||
init_snes();
|
||||
ui_init();
|
||||
|
||||
if(argc >= 2) {
|
||||
cartridge.load_begin(Cartridge::CART_NORMAL);
|
||||
cartridge.load_begin(Cartridge::CartridgeNormal);
|
||||
cartridge.load(argv[1]);
|
||||
cartridge.load_end();
|
||||
snes.power();
|
||||
|
|
|
@ -35,7 +35,7 @@ void ui_init() {
|
|||
window_advanced.setup();
|
||||
window_settings.setup();
|
||||
|
||||
event::update_video_settings();
|
||||
event::update_video_settings(); //call first time to resize main window and update menubar
|
||||
window_main.show();
|
||||
while(ui::events_pending()) { ui::run(); }
|
||||
|
||||
|
@ -68,7 +68,7 @@ void ui_init() {
|
|||
uiAudio->init();
|
||||
uiInput->init();
|
||||
|
||||
window_main.setup_menu();
|
||||
event::update_video_settings(); //call second time to update uiVideo->settings
|
||||
}
|
||||
|
||||
void ui_term() {
|
||||
|
|
|
@ -56,59 +56,68 @@ ui::Control *control = (ui::Control*)param;
|
|||
message(ui::Message::Close);
|
||||
}
|
||||
|
||||
if(control == &menu_settings_videomode_1x) { config::video.multiplier = 1; event::update_video_settings(); }
|
||||
if(control == &menu_settings_videomode_2x) { config::video.multiplier = 2; event::update_video_settings(); }
|
||||
if(control == &menu_settings_videomode_3x) { config::video.multiplier = 3; event::update_video_settings(); }
|
||||
if(control == &menu_settings_videomode_4x) { config::video.multiplier = 4; event::update_video_settings(); }
|
||||
if(control == &menu_settings_videomode_5x) { config::video.multiplier = 5; event::update_video_settings(); }
|
||||
if(locked == false) {
|
||||
//set locked to true to update below menu item check statuses without triggering events
|
||||
if(control == &menu_settings_videomode_1x) { event::update_multiplier(1); }
|
||||
if(control == &menu_settings_videomode_2x) { event::update_multiplier(2); }
|
||||
if(control == &menu_settings_videomode_3x) { event::update_multiplier(3); }
|
||||
if(control == &menu_settings_videomode_4x) { event::update_multiplier(4); }
|
||||
if(control == &menu_settings_videomode_5x) { event::update_multiplier(5); }
|
||||
|
||||
if(control == &menu_settings_videomode_aspect_correction) {
|
||||
config::video.aspect_correction = menu_settings_videomode_aspect_correction.checked();
|
||||
event::update_video_settings();
|
||||
if(control == &menu_settings_videomode_aspect_correction) {
|
||||
event::update_aspect_correction(menu_settings_videomode_aspect_correction.checked());
|
||||
}
|
||||
|
||||
if(control == &menu_settings_videomode_ntsc) { event::update_region(0); }
|
||||
if(control == &menu_settings_videomode_pal) { event::update_region(1); }
|
||||
|
||||
if(control == &menu_settings_videofilter_hwpoint) { event::update_hardware_filter(0); }
|
||||
if(control == &menu_settings_videofilter_hwlinear) { event::update_hardware_filter(1); }
|
||||
|
||||
if(control == &menu_settings_videofilter_swnone) { event::update_software_filter(0); }
|
||||
if(control == &menu_settings_videofilter_swntsc) { event::update_software_filter(1); }
|
||||
if(control == &menu_settings_videofilter_swhq2x) { event::update_software_filter(2); }
|
||||
if(control == &menu_settings_videofilter_swscale2x) { event::update_software_filter(3); }
|
||||
|
||||
if(control == &menu_settings_videoframeskip_0) { config::video.frameskip = 0; }
|
||||
if(control == &menu_settings_videoframeskip_1) { config::video.frameskip = 1; }
|
||||
if(control == &menu_settings_videoframeskip_2) { config::video.frameskip = 2; }
|
||||
if(control == &menu_settings_videoframeskip_3) { config::video.frameskip = 3; }
|
||||
if(control == &menu_settings_videoframeskip_4) { config::video.frameskip = 4; }
|
||||
if(control == &menu_settings_videoframeskip_5) { config::video.frameskip = 5; }
|
||||
if(control == &menu_settings_videoframeskip_6) { config::video.frameskip = 6; }
|
||||
if(control == &menu_settings_videoframeskip_7) { config::video.frameskip = 7; }
|
||||
if(control == &menu_settings_videoframeskip_8) { config::video.frameskip = 8; }
|
||||
if(control == &menu_settings_videoframeskip_9) { config::video.frameskip = 9; }
|
||||
|
||||
if(control == &menu_settings_mute) {
|
||||
config::snes.mute = menu_settings_mute.checked();
|
||||
}
|
||||
|
||||
if(control == &menu_settings_speedreg_enable) {
|
||||
config::system.regulate_speed = menu_settings_speedreg_enable.checked();
|
||||
}
|
||||
|
||||
if(control == &menu_settings_speedreg_slowest) { config::system.speed = 1; uiAudio->update_frequency(); }
|
||||
if(control == &menu_settings_speedreg_slow) { config::system.speed = 2; uiAudio->update_frequency(); }
|
||||
if(control == &menu_settings_speedreg_normal) { config::system.speed = 3; uiAudio->update_frequency(); }
|
||||
if(control == &menu_settings_speedreg_fast) { config::system.speed = 4; uiAudio->update_frequency(); }
|
||||
if(control == &menu_settings_speedreg_fastest) { config::system.speed = 5; uiAudio->update_frequency(); }
|
||||
}
|
||||
|
||||
if(control == &menu_settings_videomode_ntsc) { config::video.region = 0; event::update_raster_settings(); event::update_video_settings(); }
|
||||
if(control == &menu_settings_videomode_pal) { config::video.region = 1; event::update_raster_settings(); event::update_video_settings(); }
|
||||
|
||||
if(control == &menu_settings_videofilter_hwpoint) { config::video.hardware_filter = 0; uiVideo->update_hardware_filter(); }
|
||||
if(control == &menu_settings_videofilter_hwlinear) { config::video.hardware_filter = 1; uiVideo->update_hardware_filter(); }
|
||||
|
||||
if(control == &menu_settings_videofilter_swnone) { config::video.software_filter = 0; event::update_raster_settings(); }
|
||||
if(control == &menu_settings_videofilter_swntsc) { config::video.software_filter = 1; event::update_raster_settings(); }
|
||||
if(control == &menu_settings_videofilter_swhq2x) { config::video.software_filter = 2; event::update_raster_settings(); }
|
||||
if(control == &menu_settings_videofilter_swscale2x) { config::video.software_filter = 3; event::update_raster_settings(); }
|
||||
|
||||
if(control == &menu_settings_videoframeskip_0) { config::video.frameskip = 0; }
|
||||
if(control == &menu_settings_videoframeskip_1) { config::video.frameskip = 1; }
|
||||
if(control == &menu_settings_videoframeskip_2) { config::video.frameskip = 2; }
|
||||
if(control == &menu_settings_videoframeskip_3) { config::video.frameskip = 3; }
|
||||
if(control == &menu_settings_videoframeskip_4) { config::video.frameskip = 4; }
|
||||
if(control == &menu_settings_videoframeskip_5) { config::video.frameskip = 5; }
|
||||
if(control == &menu_settings_videoframeskip_6) { config::video.frameskip = 6; }
|
||||
if(control == &menu_settings_videoframeskip_7) { config::video.frameskip = 7; }
|
||||
if(control == &menu_settings_videoframeskip_8) { config::video.frameskip = 8; }
|
||||
if(control == &menu_settings_videoframeskip_9) { config::video.frameskip = 9; }
|
||||
|
||||
if(control == &menu_settings_mute) {
|
||||
config::snes.mute = menu_settings_mute.checked();
|
||||
}
|
||||
|
||||
if(control == &menu_settings_speedreg_enable) {
|
||||
config::system.regulate_speed = menu_settings_speedreg_enable.checked();
|
||||
}
|
||||
|
||||
if(control == &menu_settings_speedreg_slowest) { config::system.speed = 1; uiAudio->update_frequency(); }
|
||||
if(control == &menu_settings_speedreg_slow) { config::system.speed = 2; uiAudio->update_frequency(); }
|
||||
if(control == &menu_settings_speedreg_normal) { config::system.speed = 3; uiAudio->update_frequency(); }
|
||||
if(control == &menu_settings_speedreg_fast) { config::system.speed = 4; uiAudio->update_frequency(); }
|
||||
if(control == &menu_settings_speedreg_fastest) { config::system.speed = 5; uiAudio->update_frequency(); }
|
||||
|
||||
if(control == &menu_settings_config) { window_settings.show(); }
|
||||
|
||||
if(control == &menu_misc_logaudio) {
|
||||
(menu_misc_logaudio.checked() == true) ? snes.log_audio_enable() : snes.log_audio_disable();
|
||||
}
|
||||
|
||||
if(control == &menu_misc_showfps) {
|
||||
config::misc.show_frame_counter = menu_misc_showfps.checked();
|
||||
if(config::misc.show_frame_counter == false) {
|
||||
set_text(string() << BSNES_TITLE);
|
||||
}
|
||||
}
|
||||
|
||||
if(control == &menu_misc_about) {
|
||||
window_about.focus();
|
||||
}
|
||||
|
@ -122,6 +131,8 @@ ui::Control *control = (ui::Control*)param;
|
|||
void MainWindow::setup() {
|
||||
snesinterface.input_ready = bind(&MainWindow::input_ready, this);
|
||||
|
||||
locked = true;
|
||||
|
||||
ui::ControlGroup group;
|
||||
create(ui::Window::Center, 256, 224, BSNES_TITLE);
|
||||
set_background_color(0, 0, 0);
|
||||
|
@ -233,6 +244,7 @@ ui::ControlGroup group;
|
|||
|
||||
menu_misc.create(menu, "Misc");
|
||||
menu_misc_logaudio.create(menu_misc, "Log Audio Data");
|
||||
menu_misc_showfps.create(menu_misc, "Show FPS");
|
||||
menu_misc_sep1.create(menu_misc);
|
||||
menu_misc_about.create(menu_misc, "About ...");
|
||||
menu_misc.finish();
|
||||
|
@ -242,9 +254,12 @@ ui::ControlGroup group;
|
|||
view.set_background_color(0, 0, 0);
|
||||
}
|
||||
|
||||
void MainWindow::setup_menu() {
|
||||
config::video.multiplier = minmax<1, 5>(uint(config::video.multiplier));
|
||||
switch(uint(config::video.multiplier)) {
|
||||
void MainWindow::update_menu_settings() {
|
||||
locked = true;
|
||||
|
||||
event::load_video_settings();
|
||||
|
||||
switch(event::video_settings.multiplier) { default:
|
||||
case 1: menu_settings_videomode_1x.check(); break;
|
||||
case 2: menu_settings_videomode_2x.check(); break;
|
||||
case 3: menu_settings_videomode_3x.check(); break;
|
||||
|
@ -252,22 +267,19 @@ void MainWindow::setup_menu() {
|
|||
case 5: menu_settings_videomode_5x.check(); break;
|
||||
}
|
||||
|
||||
menu_settings_videomode_aspect_correction.check(config::video.aspect_correction);
|
||||
menu_settings_videomode_aspect_correction.check(event::video_settings.aspect_correction);
|
||||
|
||||
config::video.region = minmax<0, 1>(uint(config::video.region));
|
||||
switch(uint(config::video.region)) {
|
||||
switch(event::video_settings.region) { default:
|
||||
case 0: menu_settings_videomode_ntsc.check(); break;
|
||||
case 1: menu_settings_videomode_pal.check(); break;
|
||||
}
|
||||
|
||||
config::video.hardware_filter = minmax<0, 1>(uint(config::video.hardware_filter));
|
||||
switch(uint(config::video.hardware_filter)) {
|
||||
switch(event::video_settings.hardware_filter) { default:
|
||||
case 0: menu_settings_videofilter_hwpoint.check(); break;
|
||||
case 1: menu_settings_videofilter_hwlinear.check(); break;
|
||||
}
|
||||
|
||||
config::video.software_filter = minmax<0, 3>(uint(config::video.software_filter));
|
||||
switch(uint(config::video.software_filter)) {
|
||||
switch(event::video_settings.software_filter) { default:
|
||||
case 0: menu_settings_videofilter_swnone.check(); break;
|
||||
case 1: menu_settings_videofilter_swntsc.check(); break;
|
||||
case 2: menu_settings_videofilter_swhq2x.check(); break;
|
||||
|
@ -278,4 +290,8 @@ void MainWindow::setup_menu() {
|
|||
|
||||
menu_settings_speedreg_enable.check(config::system.regulate_speed);
|
||||
menu_settings_speedreg_normal.check();
|
||||
|
||||
menu_misc_showfps.check(config::misc.show_frame_counter);
|
||||
|
||||
locked = false;
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@ ui::MenuGroup menu_settings;
|
|||
ui::MenuItem menu_settings_config;
|
||||
ui::MenuGroup menu_misc;
|
||||
ui::MenuCheckItem menu_misc_logaudio;
|
||||
ui::MenuCheckItem menu_misc_showfps;
|
||||
ui::MenuSeparator menu_misc_sep1;
|
||||
ui::MenuItem menu_misc_about;
|
||||
|
||||
|
@ -65,7 +66,8 @@ ui::Container view;
|
|||
|
||||
bool input_ready();
|
||||
|
||||
bool locked;
|
||||
bool message(uint id, uintptr_t param = 0);
|
||||
void setup();
|
||||
void setup_menu();
|
||||
void update_menu_settings();
|
||||
} window_main;
|
||||
|
|
|
@ -87,7 +87,7 @@ HRESULT hr;
|
|||
device->SetVertexShader(NULL);
|
||||
device->SetFVF(D3DVERTEX);
|
||||
|
||||
update_hardware_filter();
|
||||
update_settings();
|
||||
|
||||
if(caps.stretchrect == true) {
|
||||
device->CreateOffscreenPlainSurface(1024, 1024, D3DFMT_R5G6B5,
|
||||
|
@ -104,10 +104,10 @@ HRESULT hr;
|
|||
return true;
|
||||
}
|
||||
|
||||
void VideoD3D::update_hardware_filter() {
|
||||
void VideoD3D::update_settings() {
|
||||
if(!device)return;
|
||||
|
||||
switch(uint(config::video.hardware_filter)) {
|
||||
switch(settings.filter) {
|
||||
case Video::FilterPoint:
|
||||
flags.filter = D3DTEXF_POINT;
|
||||
break;
|
||||
|
@ -230,7 +230,7 @@ void VideoD3D::refresh(uint r_width, uint r_height) {
|
|||
|
||||
device->EndScene();
|
||||
|
||||
if(config::video.synchronize == true) {
|
||||
if(settings.synchronize == true) {
|
||||
D3DRASTER_STATUS status;
|
||||
for(;;) {
|
||||
device->GetRasterStatus(0, &status);
|
||||
|
|
|
@ -43,7 +43,7 @@ struct {
|
|||
uint screen_height() { return GetSystemMetrics(SM_CYSCREEN); }
|
||||
|
||||
bool update_video_mode();
|
||||
void update_hardware_filter();
|
||||
void update_settings();
|
||||
|
||||
bool capture_screenshot();
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ void VideoDD::unlock() {
|
|||
}
|
||||
|
||||
void VideoDD::refresh(uint r_width, uint r_height) {
|
||||
if(config::video.synchronize == true) {
|
||||
if(settings.synchronize) {
|
||||
for(;;) {
|
||||
BOOL in_vblank;
|
||||
lpdd7->GetVerticalBlankStatus(&in_vblank);
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
#ifndef VIDEO_H
|
||||
#define VIDEO_H
|
||||
|
||||
class Video { public:
|
||||
|
||||
enum Filter {
|
||||
FilterPoint,
|
||||
#ifndef VIDEO_H
|
||||
#define VIDEO_H
|
||||
|
||||
class Video { public:
|
||||
|
||||
struct Settings {
|
||||
bool synchronize;
|
||||
uint filter;
|
||||
Settings() : synchronize(false), filter(0) {}
|
||||
} settings;
|
||||
|
||||
enum Filter {
|
||||
FilterPoint,
|
||||
FilterLinear,
|
||||
};
|
||||
};
|
||||
|
||||
virtual bool lock(uint16 *&data, uint &pitch) { return false; }
|
||||
virtual void unlock() {}
|
||||
|
@ -16,10 +22,10 @@ enum Filter {
|
|||
virtual void init() {}
|
||||
virtual void term() {}
|
||||
|
||||
virtual void update_hardware_filter() {}
|
||||
virtual void update_settings() {}
|
||||
|
||||
Video() {}
|
||||
virtual ~Video() {}
|
||||
} *uiVideo;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue