mirror of https://github.com/bsnes-emu/bsnes.git
Update to bsnes v016r52 release.
bsnes now builds with no warnings on Linux: http://byuu.cinnamonpirate.com/images/desktop082106.png However, input is not working unless you build the non- GTK+ port (see below for more info). I'm planning on releasing next weekend. This will likely be the last public WIP, unless something major is found before the weekend: byuu.cinnamonpirate.com/files/bsnes_v016_wip52.zip <- copy/paste link > If you can actually get it going fast in an all-in-one window like > that it'd be cool. I normally just punt and have the GUI separate > from the emulator output (GTK or Qt for the UI, SDL for the output) > but it'd be nice for my NEStopia port if I could make it "one piece" > like the Win32 original I can. Please take a look at my above sourcecode, and check your private messages for another note. Specifically, src/ui/video/sdl.cpp and src/ui/gtk/gtk_mainwindow.cpp. I am able to merge the SDL output into the GTK+ window by setting the environment variable "SDL_WINDOWID=%ld", GDK_WINDOW_XWINDOW(mydrawingbox->window). One important thing to note is that you must not initialize SDL video until the render window has been realized. Simply showing the window is not enough. You need to also clear all pending events in GTK+ after showing the window before calling SDL video init, or it will die. You can do that with this code: gtk_widget_show(mainwindow); while(gtk_events_pending() == true) { gtk_main_iteration_do(false); } However, one problem I am having is that by calling gtk_main_iteration_do(), it steals all SDL input, and I'm not able to poll any keypresses. This happens whether I embed the SDL video output into the GTK+ window or not. The only way to get SDL input is to ignore all GTK+ events, effectively freezing the window completely. I don't suppose you'd mind sharing how you got SDL input working with GTK+ with me?
This commit is contained in:
parent
0ed9edfcdb
commit
192e53bb87
|
@ -1,8 +1,8 @@
|
|||
uint8 spcram_read (uint16 addr);
|
||||
void spcram_write(uint16 addr, uint8 data);
|
||||
|
||||
inline uint8 port_read (uint8 port);
|
||||
inline void port_write(uint8 port, uint8 data);
|
||||
uint8 port_read (uint8 port);
|
||||
void port_write(uint8 port, uint8 data);
|
||||
|
||||
/*****
|
||||
* core APU bus functions
|
||||
|
|
|
@ -8,4 +8,4 @@ bool enabled;
|
|||
|
||||
inline void add_clocks(int clocks);
|
||||
inline void tick_timers();
|
||||
inline uint32 clocks_executed();
|
||||
uint32 clocks_executed();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define BSNES_VERSION "0.016.44"
|
||||
#define BSNES_VERSION "0.016.52"
|
||||
#define BSNES_TITLE "bsnes v" BSNES_VERSION
|
||||
|
||||
#define MEMCORE bMemBus
|
||||
|
@ -28,7 +28,7 @@
|
|||
|
||||
#if defined(PROCESSOR_X86)
|
||||
#define ARCH_LSB
|
||||
#elif defined(PROCESSOR_X86)
|
||||
#elif defined(PROCESSOR_X86_64)
|
||||
#define ARCH_LSB
|
||||
#elif defined(PROCESSOR_G5)
|
||||
#define ARCH_MSB
|
||||
|
|
|
@ -197,57 +197,21 @@ FileWriter ff(sram_fn);
|
|||
ff.write(sram, info.ram_size);
|
||||
}
|
||||
|
||||
uint Cartridge::mirror_realloc(uint8 *&data, uint size) {
|
||||
for(int i = 31; i >= 0; i--) {
|
||||
if(size & (1 << i)) {
|
||||
if(!(size & ~(1 << i))) { return 1 << i; }
|
||||
data = (uint8*)realloc(data, 2 << i);
|
||||
return 2 << i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint Cartridge::mirror(uint8 *&data, uint size) {
|
||||
uint r = mirror_realloc(data, size);
|
||||
|
||||
while(size < r) {
|
||||
uint i = 0;
|
||||
for(; i < 32; i++) { if(size & (1 << i))break; }
|
||||
uint masklo = 1 << i++;
|
||||
for(; i < 32; i++) { if(size & (1 << i))break; }
|
||||
uint maskhi = 1 << i;
|
||||
if(i > 31)break; //no mirroring necessary
|
||||
|
||||
while(masklo < maskhi) {
|
||||
uint start = size - masklo;
|
||||
memcpy(data + size, data + start, masklo);
|
||||
size += masklo;
|
||||
masklo <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void Cartridge::load_rom(Reader &rf) {
|
||||
uint8 *data = rf.read();
|
||||
uint size = rf.size();
|
||||
bool header = ((size & 0x7fff) == 0x0200);
|
||||
uint size = rf.size();
|
||||
bool header = ((size & 0x7fff) == 512);
|
||||
info.rom_size = size - (header ? 512 : 0);
|
||||
|
||||
base_rom = (uint8*)malloc(info.rom_size);
|
||||
memcpy(base_rom, data + (header ? 512 : 0), info.rom_size);
|
||||
SafeFree(data);
|
||||
if(info.rom_size & 0x7fff) {
|
||||
info.rom_size += 0x8000 - (info.rom_size & 0x7fff);
|
||||
}
|
||||
base_rom = rf.read(info.rom_size + (header ? 512 : 0));
|
||||
rom = base_rom + (header ? 512 : 0);
|
||||
|
||||
info.crc32 = 0xffffffff;
|
||||
for(int32 i = 0; i < info.rom_size; i++) {
|
||||
info.crc32 = crc32_adjust(info.crc32, base_rom[i]);
|
||||
info.crc32 = crc32_adjust(info.crc32, rom[i]);
|
||||
}
|
||||
info.crc32 = ~info.crc32;
|
||||
|
||||
info.rom_size = mirror(base_rom, info.rom_size);
|
||||
rom = base_rom;
|
||||
}
|
||||
|
||||
bool Cartridge::load(const char *fn) {
|
||||
|
|
|
@ -78,9 +78,6 @@ struct {
|
|||
uint header_index;
|
||||
} info;
|
||||
|
||||
uint mirror_realloc(uint8 *&data, uint size);
|
||||
uint mirror(uint8 *&data, uint size);
|
||||
|
||||
void load_rom(Reader &rf);
|
||||
void load_sram();
|
||||
void save_sram();
|
||||
|
|
Binary file not shown.
|
@ -1,7 +1,7 @@
|
|||
//Build OAM
|
||||
void C4::op00_00() {
|
||||
uint32 oamptr = ram[0x626] << 2;
|
||||
for(int32 i=0x1fd;i>oamptr && i>=0;i-=4) {
|
||||
for(int32 i = 0x1fd; i > oamptr && i >= 0; i -= 4) {
|
||||
//clear oam-to-be
|
||||
if(i >= 0)ram[i] = 0xe0;
|
||||
}
|
||||
|
@ -19,58 +19,55 @@ uint8 sprcount;
|
|||
|
||||
sprcount = 128 - ram[0x626];
|
||||
uint8 offset = (ram[0x626] & 3) * 2;
|
||||
for(int pri=0x30;pri>=0;pri-=0x10) {
|
||||
uint32 srcptr = 0x220;
|
||||
for(int i=ram[0x620];i>0 && sprcount>0;i--, srcptr+=16) {
|
||||
if((ram[srcptr + 4] & 0x30) != pri)continue;
|
||||
sprx = readw(srcptr) - globalx;
|
||||
spry = readw(srcptr + 2) - globaly;
|
||||
sprname = ram[srcptr + 5];
|
||||
sprattr = ram[srcptr + 4] | ram[srcptr + 6];
|
||||
uint32 srcptr = 0x220;
|
||||
for(int i = ram[0x620]; i > 0 && sprcount > 0; i--, srcptr += 16) {
|
||||
sprx = readw(srcptr) - globalx;
|
||||
spry = readw(srcptr + 2) - globaly;
|
||||
sprname = ram[srcptr + 5];
|
||||
sprattr = ram[srcptr + 4] | ram[srcptr + 6];
|
||||
|
||||
uint32 spraddr = readl(srcptr + 7);
|
||||
if(r_mem->read(spraddr)) {
|
||||
int16 x, y;
|
||||
for(int sprcnt=r_mem->read(spraddr++);sprcnt>0 && sprcount>0;sprcnt--, spraddr+=4) {
|
||||
x = (int8)r_mem->read(spraddr + 1);
|
||||
if(sprattr & 0x40) {
|
||||
x = -x - ((r_mem->read(spraddr) & 0x20) ? 16 : 8);
|
||||
uint32 spraddr = readl(srcptr + 7);
|
||||
if(r_mem->read(spraddr)) {
|
||||
int16 x, y;
|
||||
for(int sprcnt = r_mem->read(spraddr++); sprcnt > 0 && sprcount > 0; sprcnt--, spraddr += 4) {
|
||||
x = (int8)r_mem->read(spraddr + 1);
|
||||
if(sprattr & 0x40) {
|
||||
x = -x - ((r_mem->read(spraddr) & 0x20) ? 16 : 8);
|
||||
}
|
||||
x += sprx;
|
||||
if(x >= -16 && x <= 272) {
|
||||
y = (int8)r_mem->read(spraddr + 2);
|
||||
if(sprattr & 0x80) {
|
||||
y = -y - ((r_mem->read(spraddr) & 0x20) ? 16 : 8);
|
||||
}
|
||||
x += sprx;
|
||||
if(x >= -16 && x <= 272) {
|
||||
y = (int8)r_mem->read(spraddr + 2);
|
||||
if(sprattr & 0x80) {
|
||||
y = -y - ((r_mem->read(spraddr) & 0x20) ? 16 : 8);
|
||||
}
|
||||
y += spry;
|
||||
if(y >= -16 && y <= 224) {
|
||||
ram[oamptr ] = (uint8)x;
|
||||
ram[oamptr + 1] = (uint8)y;
|
||||
ram[oamptr + 2] = sprname + r_mem->read(spraddr + 3);
|
||||
ram[oamptr + 3] = sprattr ^ (r_mem->read(spraddr) & 0xc0);
|
||||
ram[oamptr2] &= ~(3 << offset);
|
||||
if(x & 0x100)ram[oamptr2] |= 1 << offset;
|
||||
if(r_mem->read(spraddr) & 0x20)ram[oamptr2] |= 2 << offset;
|
||||
oamptr += 4;
|
||||
sprcount--;
|
||||
offset = (offset + 2) & 6;
|
||||
if(!offset)oamptr2++;
|
||||
}
|
||||
y += spry;
|
||||
if(y >= -16 && y <= 224) {
|
||||
ram[oamptr ] = (uint8)x;
|
||||
ram[oamptr + 1] = (uint8)y;
|
||||
ram[oamptr + 2] = sprname + r_mem->read(spraddr + 3);
|
||||
ram[oamptr + 3] = sprattr ^ (r_mem->read(spraddr) & 0xc0);
|
||||
ram[oamptr2] &= ~(3 << offset);
|
||||
if(x & 0x100)ram[oamptr2] |= 1 << offset;
|
||||
if(r_mem->read(spraddr) & 0x20)ram[oamptr2] |= 2 << offset;
|
||||
oamptr += 4;
|
||||
sprcount--;
|
||||
offset = (offset + 2) & 6;
|
||||
if(!offset)oamptr2++;
|
||||
}
|
||||
}
|
||||
} else if(sprcount > 0) {
|
||||
ram[oamptr ] = (uint8)sprx;
|
||||
ram[oamptr + 1] = (uint8)spry;
|
||||
ram[oamptr + 2] = sprname;
|
||||
ram[oamptr + 3] = sprattr;
|
||||
ram[oamptr2] &= ~(3 << offset);
|
||||
if(sprx & 0x100)ram[oamptr2] |= 3 << offset;
|
||||
else ram[oamptr2] |= 2 << offset;
|
||||
oamptr += 4;
|
||||
sprcount--;
|
||||
offset = (offset + 2) & 6;
|
||||
if(!offset)oamptr2++;
|
||||
}
|
||||
} else if(sprcount > 0) {
|
||||
ram[oamptr ] = (uint8)sprx;
|
||||
ram[oamptr + 1] = (uint8)spry;
|
||||
ram[oamptr + 2] = sprname;
|
||||
ram[oamptr + 3] = sprattr;
|
||||
ram[oamptr2] &= ~(3 << offset);
|
||||
if(sprx & 0x100)ram[oamptr2] |= 3 << offset;
|
||||
else ram[oamptr2] |= 2 << offset;
|
||||
oamptr += 4;
|
||||
sprcount--;
|
||||
offset = (offset + 2) & 6;
|
||||
if(!offset)oamptr2++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -178,13 +175,11 @@ uint32 waveptr = read(0x1f83);
|
|||
uint16 mask1 = 0xc0c0;
|
||||
uint16 mask2 = 0x3f3f;
|
||||
|
||||
int32 i, j;
|
||||
int16 height, temp;
|
||||
for(j = 0; j < 0x10; j++) {
|
||||
for(int j = 0; j < 0x10; j++) {
|
||||
do {
|
||||
height = -((int8)ram[waveptr + 0xb00]) - 16;
|
||||
for(i = 0; i < 40; i++) {
|
||||
temp = readw(destptr + wave_data[i]) & mask2;
|
||||
int16 height = -((int8)read(waveptr + 0xb00)) - 16;
|
||||
for(int i = 0; i < 40; i++) {
|
||||
uint16 temp = readw(destptr + wave_data[i]) & mask2;
|
||||
if(height >= 0) {
|
||||
if(height < 8) {
|
||||
temp |= mask1 & readw(0xa00 + height * 2);
|
||||
|
@ -202,22 +197,22 @@ int16 height, temp;
|
|||
destptr += 16;
|
||||
|
||||
do {
|
||||
height = -((int8)ram[waveptr + 0xb00]) - 16;
|
||||
for(i = 0; i < 40; i++) {
|
||||
temp = readw(destptr + wave_data[i]) & mask2;
|
||||
int16 height = -((int8)read(waveptr + 0xb00)) - 16;
|
||||
for(int i = 0; i < 40; i++) {
|
||||
uint16 temp = readw(destptr + wave_data[i]) & mask2;
|
||||
if(height >= 0) {
|
||||
if(height < 8) {
|
||||
temp |= mask1 & readw(0xa10 + height * 2);
|
||||
} else {
|
||||
temp |= mask1 & 0xff00;
|
||||
}
|
||||
writew(destptr + wave_data[i], temp);
|
||||
height++;
|
||||
}
|
||||
waveptr = (waveptr + 1) & 0x7f;
|
||||
mask1 = (mask1 >> 2) | (mask1 << 6);
|
||||
mask2 = (mask2 >> 2) | (mask2 << 6);
|
||||
writew(destptr + wave_data[i], temp);
|
||||
height++;
|
||||
}
|
||||
waveptr = (waveptr + 1) & 0x7f;
|
||||
mask1 = (mask1 >> 2) | (mask1 << 6);
|
||||
mask2 = (mask2 >> 2) | (mask2 << 6);
|
||||
} while(mask1 != 0xc0c0);
|
||||
destptr += 16;
|
||||
}
|
||||
|
|
|
@ -20,11 +20,11 @@
|
|||
|
||||
#include "cpu/cpu.h"
|
||||
#include "cpu/scpu/scpu.h"
|
||||
#include "cpu/bcpu/bcpu.h"
|
||||
//#include "cpu/bcpu/bcpu.h"
|
||||
|
||||
#include "apu/apu.h"
|
||||
#include "apu/sapu/sapu.h"
|
||||
#include "apu/bapu/bapu.h"
|
||||
//#include "apu/bapu/bapu.h"
|
||||
|
||||
#include "dsp/dsp.h"
|
||||
#include "dsp/bdsp/bdsp.h"
|
||||
|
|
|
@ -70,7 +70,6 @@ typedef signed short int16;
|
|||
typedef signed long int32;
|
||||
typedef signed long long int64;
|
||||
|
||||
|
||||
/*****
|
||||
* templates
|
||||
*****/
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
;*****
|
||||
;libco_x86 : version 0.06 ~byuu (05/21/06)
|
||||
;libco_x86 : version 0.07 ~byuu (08/15/06)
|
||||
;cross-platform x86 implementation of libco
|
||||
;
|
||||
;context save/restore adheres to c/c++ ABI
|
||||
;for x86 win32, linux and freebsd
|
||||
;for x86 windows, linux and freebsd
|
||||
;
|
||||
;context saves esp+ebp+esi+edi+ebx
|
||||
;context ignores eax+ecx+edx
|
||||
|
@ -22,6 +22,7 @@ section .code
|
|||
;*****
|
||||
;linker-specific name decorations
|
||||
;*****
|
||||
%ifdef WIN32
|
||||
%define malloc _malloc
|
||||
%define free _free
|
||||
|
||||
|
@ -33,6 +34,7 @@ section .code
|
|||
%define co_jump @co_jump@4
|
||||
%define co_call @co_call@4
|
||||
%define co_return @co_return@0
|
||||
%endif
|
||||
|
||||
extern malloc
|
||||
extern free
|
||||
|
@ -47,7 +49,7 @@ global co_call
|
|||
global co_return
|
||||
|
||||
;*****
|
||||
;extern "C" void __fastcall co_init();
|
||||
;extern "C" void fastcall co_init();
|
||||
;*****
|
||||
|
||||
align 16
|
||||
|
@ -65,7 +67,7 @@ co_init:
|
|||
ret
|
||||
|
||||
;*****
|
||||
;extern "C" void __fastcall co_term();
|
||||
;extern "C" void fastcall co_term();
|
||||
;*****
|
||||
|
||||
align 16
|
||||
|
@ -73,7 +75,7 @@ co_term:
|
|||
ret
|
||||
|
||||
;*****
|
||||
;extern "C" thread_t __fastcall co_active();
|
||||
;extern "C" thread_t fastcall co_active();
|
||||
;return = eax
|
||||
;*****
|
||||
|
||||
|
@ -87,7 +89,7 @@ co_active:
|
|||
ret
|
||||
|
||||
;*****
|
||||
;extern "C" thread_t __fastcall co_create(thread_p coentry, unsigned int heapsize);
|
||||
;extern "C" thread_t fastcall co_create(thread_p coentry, unsigned int heapsize);
|
||||
;ecx = coentry
|
||||
;edx = heapsize
|
||||
;return = eax
|
||||
|
@ -107,8 +109,12 @@ co_create:
|
|||
;create heap space (stack + register storage)
|
||||
add edx,28 ;+8(esp+prev_call_context)+4(coentry)+16(stack_align)
|
||||
push ecx
|
||||
push edx
|
||||
|
||||
push edx
|
||||
call malloc
|
||||
add esp,4
|
||||
|
||||
pop edx
|
||||
pop ecx
|
||||
|
||||
|
@ -130,7 +136,7 @@ co_create:
|
|||
ret ;return allocated memory block as thread handle
|
||||
|
||||
;*****
|
||||
;extern "C" void __fastcall co_delete(thread_t cothread);
|
||||
;extern "C" void fastcall co_delete(thread_t cothread);
|
||||
;ecx = cothread
|
||||
;*****
|
||||
|
||||
|
@ -142,7 +148,7 @@ co_delete:
|
|||
ret
|
||||
|
||||
;*****
|
||||
;extern "C" void __fastcall co_jump(thread_t cothread);
|
||||
;extern "C" void fastcall co_jump(thread_t cothread);
|
||||
;ecx = cothread
|
||||
;*****
|
||||
|
||||
|
@ -166,7 +172,7 @@ co_jump:
|
|||
ret
|
||||
|
||||
;*****
|
||||
;extern "C" void __fastcall co_call(thread_t cothread);
|
||||
;extern "C" void fastcall co_call(thread_t cothread);
|
||||
;ecx = cothread
|
||||
;*****
|
||||
|
||||
|
@ -191,7 +197,7 @@ co_call:
|
|||
ret
|
||||
|
||||
;*****
|
||||
;extern "C" void __fastcall co_return();
|
||||
;extern "C" void fastcall co_return();
|
||||
;*****
|
||||
|
||||
align 16
|
||||
|
|
|
@ -34,10 +34,10 @@ void Control::Focus() { SetFocus(hwnd); }
|
|||
|
||||
void Control::Enable(bool do_enable) {
|
||||
if(do_enable == true) {
|
||||
SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_DISABLED);
|
||||
EnableWindow(hwnd, TRUE);
|
||||
state.ws &= ~WS_DISABLED;
|
||||
} else {
|
||||
SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) | WS_DISABLED);
|
||||
EnableWindow(hwnd, FALSE);
|
||||
state.ws |= WS_DISABLED;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,14 +66,16 @@ uint region = read(0xffd9) & 0x7f;
|
|||
rom_loaded = true;
|
||||
|
||||
//print cartridge info to debug console
|
||||
|
||||
char t[256];
|
||||
dprintf("* CRC32 : %0.8x", cartridge.info.crc32);
|
||||
dprintf("* Name : \"%s\"", cartridge.info.name);
|
||||
dprintf("* PCB : %s", cartridge.info.pcb);
|
||||
dprintf("* ROM Size : %dmbit", cartridge.info.rom_size / 1024 / 1024 * 8);
|
||||
dprintf("* RAM Size : %dkbit", cartridge.info.ram_size / 1024 * 8);
|
||||
calc_size(t, cartridge.info.rom_size);
|
||||
dprintf("* ROM Size : %s", t);
|
||||
calc_size(t, cartridge.info.ram_size);
|
||||
dprintf("* RAM Size : %s", t);
|
||||
dprintf("* Region : %s", (cartridge.info.region == Cartridge::NTSC) ? "NTSC" : "PAL");
|
||||
char t[256];
|
||||
|
||||
strcpy(t, "");
|
||||
if(cartridge.info.srtc)strcat(t, "S-RTC, ");
|
||||
if(cartridge.info.sdd1)strcat(t, "S-DD1, ");
|
||||
|
@ -124,22 +126,23 @@ void bMemBus::unload_cart() {
|
|||
*****************************************/
|
||||
|
||||
uint8 bMemBus::memory_type(uint32 addr) {
|
||||
uint8 bank;
|
||||
bank = addr >> 16;
|
||||
uint8 bank = addr >> 16;
|
||||
addr &= 0xffff;
|
||||
|
||||
if((bank >= 0x00 && bank <= 0x3f) || (bank >= 0x80 && bank <= 0xbf)) {
|
||||
if((bank & 0x40) == 0x00) {
|
||||
//$[00-3f|80-bf]:[0000-ffff]
|
||||
if(addr >= 0x0000 && addr <= 0x1fff)return TYPE_WRAM;
|
||||
if(addr >= 0x2000 && addr <= 0x5fff)return TYPE_MMIO;
|
||||
return TYPE_CART;
|
||||
}
|
||||
|
||||
if((bank >= 0x40 && bank <= 0x7d) || (bank >= 0xc0 && bank <= 0xff)) {
|
||||
return TYPE_CART;
|
||||
if((bank & 0xfe) == 0x7e) {
|
||||
//$[7e-7f]:[0000-ffff]
|
||||
return TYPE_WRAM;
|
||||
}
|
||||
|
||||
//(bank >= 0x7e && bank <= 0x7f)
|
||||
return TYPE_WRAM;
|
||||
//$[40-7d|c0-ff]:[0000-ffff]
|
||||
return TYPE_CART;
|
||||
}
|
||||
|
||||
uint8 bMemBus::read(uint32 addr) {
|
||||
|
@ -209,7 +212,7 @@ void bMemBus::cart_map_system() {
|
|||
|
||||
void bMemBus::power() {
|
||||
cart_write_protect(true);
|
||||
memset(wram, 0xff, 0x020000);
|
||||
memset(wram, 0x55, 0x020000);
|
||||
reset();
|
||||
}
|
||||
|
||||
|
|
|
@ -55,6 +55,15 @@ enum { TYPE_WRAM, TYPE_MMIO, TYPE_CART };
|
|||
void power();
|
||||
void reset();
|
||||
|
||||
//load_cart() helper
|
||||
void calc_size(char *t, uint size) {
|
||||
if(size < 1024) { sprintf(t, "%dbit", size); return; }
|
||||
size /= 1024;
|
||||
if(size < 1024) { sprintf(t, "%dkbit", size); return; }
|
||||
size /= 1024;
|
||||
sprintf(t, "%dmbit", size);
|
||||
}
|
||||
|
||||
bMemBus();
|
||||
~bMemBus();
|
||||
};
|
||||
|
|
|
@ -15,22 +15,8 @@
|
|||
* $[80-bf]:[2000-5fff] MMIO
|
||||
*****/
|
||||
void bMemBus::cart_map_generic(uint type) {
|
||||
uint32 P0_size, P1_size, ROM_mask, ROM_size, SRAM_size;
|
||||
ROM_size = cartridge.info.rom_size;
|
||||
SRAM_size = cartridge.info.ram_size;
|
||||
|
||||
//calculate highest power of 2, which is the size of the first ROM chip
|
||||
P0_size = 0x800000;
|
||||
while(!(ROM_size & P0_size))P0_size >>= 1;
|
||||
P1_size = ROM_size - P0_size;
|
||||
|
||||
if(ROM_size == P0_size) {
|
||||
//cart only contains one ROM chip
|
||||
ROM_mask = (P0_size - 1);
|
||||
} else {
|
||||
//cart contains two ROM chips
|
||||
ROM_mask = (P0_size + P0_size - 1);
|
||||
}
|
||||
uint rom_size = cartridge.info.rom_size;
|
||||
uint ram_size = cartridge.info.ram_size;
|
||||
|
||||
for(uint page = 0x0000; page <= 0xffff; page++) {
|
||||
if(memory_type(page << 8) != TYPE_CART)continue;
|
||||
|
@ -51,10 +37,10 @@ uint32 P0_size, P1_size, ROM_mask, ROM_size, SRAM_size;
|
|||
//HiROM SRAM region
|
||||
//$[20-3f|a0-bf]:[6000-7fff]
|
||||
if((bank & 0x7f) >= 0x20 && (bank & 0x7f) <= 0x3f && (addr & 0xe000) == 0x6000) {
|
||||
if(SRAM_size == 0)continue;
|
||||
if(ram_size == 0)continue;
|
||||
|
||||
addr = ((bank & 0x7f) - 0x20) * 0x2000 + ((addr & 0xffff) - 0x6000);
|
||||
addr %= SRAM_size;
|
||||
addr %= ram_size;
|
||||
page_handle[page] = cartridge.sram + addr;
|
||||
page_read [page] = &bMemBus::read_ram;
|
||||
page_write [page] = &bMemBus::write_ram;
|
||||
|
@ -65,12 +51,12 @@ uint32 P0_size, P1_size, ROM_mask, ROM_size, SRAM_size;
|
|||
//$[70-7f|f0-ff]:[0000-7fff]
|
||||
//Note: WRAM is remapped over $[7e-7f]:[0000-ffff]
|
||||
if(bank >= 0x70 && bank <= 0x7f && (addr & 0x8000) == 0x0000) {
|
||||
if(SRAM_size == 0)continue;
|
||||
if(ram_size == 0)continue;
|
||||
|
||||
if(type == Cartridge::LOROM || !(bank & 0x80)) {
|
||||
//HiROM maps $[f0-ff]:[0000-7fff] to ROM
|
||||
addr = ((bank & 0x7f) - 0x70) * 0x8000 + (addr & 0x7fff);
|
||||
addr %= SRAM_size;
|
||||
addr %= ram_size;
|
||||
page_handle[page] = cartridge.sram + addr;
|
||||
page_read [page] = &bMemBus::read_ram;
|
||||
page_write [page] = &bMemBus::write_ram;
|
||||
|
@ -82,18 +68,12 @@ uint32 P0_size, P1_size, ROM_mask, ROM_size, SRAM_size;
|
|||
switch(type) {
|
||||
|
||||
case Cartridge::LOROM: {
|
||||
addr = (bank & 0x7f) * 0x8000 + (addr & 0x7fff);
|
||||
addr &= ROM_mask;
|
||||
if(addr >= P0_size) {
|
||||
addr = P0_size + (addr & (P1_size - 1));
|
||||
}
|
||||
addr = (bank & 0x7f) * 0x8000 + (addr & 0x7fff);
|
||||
addr = mirror(rom_size, addr);
|
||||
} break;
|
||||
|
||||
case Cartridge::HIROM: {
|
||||
addr &= ROM_mask;
|
||||
if(addr >= P0_size) {
|
||||
addr = P0_size + (addr & (P1_size - 1));
|
||||
}
|
||||
addr = mirror(rom_size, addr);
|
||||
} break;
|
||||
|
||||
case Cartridge::EXLOROM: {
|
||||
|
@ -103,13 +83,13 @@ uint32 P0_size, P1_size, ROM_mask, ROM_size, SRAM_size;
|
|||
} else {
|
||||
addr &= 0x3fffff;
|
||||
}
|
||||
addr %= ROM_size;
|
||||
addr = mirror(rom_size, addr);
|
||||
} break;
|
||||
|
||||
case Cartridge::EXHIROM: {
|
||||
addr &= 0x3fffff;
|
||||
addr += (bank < 0x80) ? 0x400000 : 0x000000;
|
||||
addr %= ROM_size;
|
||||
addr = mirror(rom_size, addr);
|
||||
} break;
|
||||
|
||||
}
|
||||
|
|
|
@ -1,3 +1,16 @@
|
|||
uint bMemBus::mirror(uint size, uint pos) {
|
||||
if(size == 0)return 0;
|
||||
if(pos < size)return pos;
|
||||
|
||||
uint mask = 1 << 31;
|
||||
while(!(pos & mask))mask >>= 1;
|
||||
if(size <= (pos & mask)) {
|
||||
return mirror(size, pos - mask);
|
||||
} else {
|
||||
return mask + mirror(size - mask, pos - mask);
|
||||
}
|
||||
}
|
||||
|
||||
void bMemBus::cart_map_range(
|
||||
uint mode,
|
||||
uint8 bank_lo, uint8 bank_hi,
|
||||
|
@ -33,7 +46,7 @@ uint8 page_hi = (addr_hi >> 8) & 255;
|
|||
for(uint page = page_lo; page <= page_hi; page++) {
|
||||
uint16 n = (bank << 8) + page;
|
||||
|
||||
page_handle[n] = data + index;
|
||||
page_handle[n] = data + mirror(size, index);
|
||||
if(size) { index = (index + 256) % size; }
|
||||
|
||||
switch(type) {
|
||||
|
|
|
@ -14,6 +14,7 @@ enum {
|
|||
MAP_OBC1,
|
||||
};
|
||||
|
||||
uint mirror(uint size, uint pos);
|
||||
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()
|
||||
|
|
|
@ -6,7 +6,6 @@ void bPPU::run() {}
|
|||
|
||||
void bPPU::scanline() {
|
||||
line.y = r_cpu->vcounter();
|
||||
line.width = (regs.hires) ? 512 : 256;
|
||||
line.interlace = r_cpu->interlace();
|
||||
line.interlace_field = r_cpu->interlace_field();
|
||||
|
||||
|
@ -89,8 +88,8 @@ void bPPU::power() {
|
|||
region = snes->region();
|
||||
|
||||
//$2100
|
||||
regs.display_disabled = 0;
|
||||
regs.display_brightness = 0;
|
||||
regs.display_disabled = 1;
|
||||
regs.display_brightness = 15;
|
||||
|
||||
//$2101
|
||||
regs.oam_basesize = 0;
|
||||
|
@ -99,12 +98,12 @@ void bPPU::power() {
|
|||
|
||||
//$2102-$2103
|
||||
regs.oam_baseaddr = 0x0000;
|
||||
regs.oam_addr = 0x0000;
|
||||
regs.oam_addr = regs.oam_baseaddr << 1;
|
||||
regs.oam_priority = false;
|
||||
regs.oam_firstsprite = 0x00;
|
||||
regs.oam_firstsprite = 0;
|
||||
|
||||
//$2104
|
||||
regs.oam_latchdata = 0x00;
|
||||
regs.oam_latchdata = 0x00;
|
||||
|
||||
//$2105
|
||||
regs.bg_tilesize[BG1] = 0;
|
||||
|
@ -113,7 +112,6 @@ void bPPU::power() {
|
|||
regs.bg_tilesize[BG4] = 0;
|
||||
regs.bg3_priority = 0;
|
||||
regs.bg_mode = 0;
|
||||
regs.hires = false;
|
||||
|
||||
//$2106
|
||||
regs.mosaic_size = 0;
|
||||
|
@ -205,10 +203,10 @@ void bPPU::power() {
|
|||
regs.window2_invert [COL] = false;
|
||||
|
||||
//$2126-$2129
|
||||
regs.window1_left = 0;
|
||||
regs.window1_right = 0;
|
||||
regs.window2_left = 0;
|
||||
regs.window2_right = 0;
|
||||
regs.window1_left = 0x00;
|
||||
regs.window1_right = 0x00;
|
||||
regs.window2_left = 0x00;
|
||||
regs.window2_right = 0x00;
|
||||
|
||||
//$212a-$212b
|
||||
regs.window_mask[BG1] = 0;
|
||||
|
@ -245,7 +243,8 @@ void bPPU::power() {
|
|||
//$2130
|
||||
regs.color_mask = 0;
|
||||
regs.colorsub_mask = 0;
|
||||
regs.addsub_mode = 0;
|
||||
regs.addsub_mode = false;
|
||||
regs.direct_color = false;
|
||||
|
||||
//$2131
|
||||
regs.color_mode = 0;
|
||||
|
@ -304,7 +303,6 @@ void bPPU::reset() {
|
|||
regs.bg_y[2] = 0;
|
||||
regs.bg_y[3] = 0;
|
||||
|
||||
line.width = 256;
|
||||
clear_tiledata_cache();
|
||||
}
|
||||
|
||||
|
@ -377,62 +375,25 @@ bPPU::bPPU() {
|
|||
init_tiledata_cache();
|
||||
|
||||
for(int l = 0; l < 16; l++) {
|
||||
mosaic_table[l] = (uint16*)malloc(4096 * 2);
|
||||
for(int i = 0; i < 4096; i++) {
|
||||
mosaic_table[l][i] = (i / (l + 1)) * (l + 1);
|
||||
}
|
||||
}
|
||||
|
||||
light_table = (uint16*)malloc(16 * 32768 * 2);
|
||||
uint16 *ptr = (uint16*)light_table;
|
||||
for(int l = 0; l < 16; l++) {
|
||||
int r, g, b;
|
||||
#if 0
|
||||
double y, cb, cr;
|
||||
double kr = 0.2126, kb = 0.0722, kg = (1.0 - kr - kb);
|
||||
for(int i = 0; i < 32768; i++) {
|
||||
if(l == 0) { *ptr++ = 0; continue; }
|
||||
if(l == 15) { *ptr++ = i; continue; }
|
||||
|
||||
r = (i ) & 31;
|
||||
g = (i >> 5) & 31;
|
||||
b = (i >> 10) & 31;
|
||||
|
||||
y = (double)r * kr + (double)g * kg + (double)b * kb;
|
||||
cb = ((double)b - y) / (2.0 - 2.0 * kb);
|
||||
cr = ((double)r - y) / (2.0 - 2.0 * kr);
|
||||
|
||||
y *= (double)l / 15.0;
|
||||
cb *= (double)l / 15.0;
|
||||
cr *= (double)l / 15.0;
|
||||
|
||||
r = y + cr * (2.0 - 2.0 * kr);
|
||||
b = y + cb * (2.0 - 2.0 * kb);
|
||||
g = (y - b * kb - r * kr) / kg;
|
||||
|
||||
r = minmax<0, 31>(r);
|
||||
g = minmax<0, 31>(g);
|
||||
b = minmax<0, 31>(b);
|
||||
|
||||
*ptr++ = (r) | (g << 5) | (b << 10);
|
||||
}
|
||||
#else
|
||||
double m = (double)l / 15.0;
|
||||
for(int i = 0; i < 32768; i++) {
|
||||
if(l == 0) { *ptr++ = 0; continue; }
|
||||
if(l == 15) { *ptr++ = i; continue; }
|
||||
|
||||
r = (i ) & 31;
|
||||
g = (i >> 5) & 31;
|
||||
b = (i >> 10) & 31;
|
||||
|
||||
r = minmax<0, 31>((int)((double)r * m));
|
||||
g = minmax<0, 31>((int)((double)g * m));
|
||||
b = minmax<0, 31>((int)((double)b * m));
|
||||
r = minmax<0, 31>( (int)((double)r * m + 0.5) );
|
||||
g = minmax<0, 31>( (int)((double)g * m + 0.5) );
|
||||
b = minmax<0, 31>( (int)((double)b * m + 0.5) );
|
||||
|
||||
*ptr++ = (r) | (g << 5) | (b << 10);
|
||||
light_table[l][i] = (b << 10) | (g << 5) | (r);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -440,10 +401,4 @@ bPPU::~bPPU() {
|
|||
SafeFree(vram);
|
||||
SafeFree(oam);
|
||||
SafeFree(cgram);
|
||||
|
||||
for(int i = 0; i < 16; i++) {
|
||||
SafeFree(mosaic_table[i]);
|
||||
}
|
||||
|
||||
SafeFree(light_table);
|
||||
}
|
||||
|
|
|
@ -8,10 +8,9 @@ enum { BG1 = 0, BG2 = 1, BG3 = 2, BG4 = 3, OAM = 4, BACK = 5, COL = 5 };
|
|||
enum { SC_32x32 = 0, SC_64x32 = 1, SC_32x64 = 2, SC_64x64 = 3 };
|
||||
|
||||
struct {
|
||||
uint32 y;
|
||||
uint32 width;
|
||||
bool interlace;
|
||||
bool interlace_field;
|
||||
uint y;
|
||||
bool interlace;
|
||||
bool interlace_field;
|
||||
} line;
|
||||
|
||||
struct {
|
||||
|
@ -43,7 +42,6 @@ struct {
|
|||
bool bg_tilesize[4];
|
||||
bool bg3_priority;
|
||||
uint8 bg_mode;
|
||||
bool hires;
|
||||
|
||||
//$2106
|
||||
uint8 mosaic_size;
|
||||
|
@ -227,8 +225,8 @@ struct {
|
|||
|
||||
#include "bppu_render.h"
|
||||
|
||||
uint16 *light_table;
|
||||
uint16 *mosaic_table[16];
|
||||
uint16 light_table[16][32768];
|
||||
uint16 mosaic_table[16][4096];
|
||||
void render_line();
|
||||
|
||||
void update_oam_status();
|
||||
|
@ -240,7 +238,7 @@ uint16 *mosaic_table[16];
|
|||
void power();
|
||||
void reset();
|
||||
|
||||
bool scanline_is_hires() { return (regs.pseudo_hires || regs.hires); }
|
||||
bool scanline_is_hires() { return (regs.pseudo_hires || regs.bg_mode == 5 || regs.bg_mode == 6); }
|
||||
|
||||
bPPU();
|
||||
~bPPU();
|
||||
|
|
|
@ -147,7 +147,6 @@ void bPPU::mmio_w2105(uint8 value) {
|
|||
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);
|
||||
}
|
||||
|
||||
//MOSAIC
|
||||
|
|
|
@ -45,7 +45,7 @@ Mode 0: ->
|
|||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
|
||||
BG4B, BG3B, OAM0, BG4A, BG3A, OAM1, BG2B, BG1B, OAM2, BG2A, BG1A, OAM3
|
||||
*/
|
||||
inline void bPPU::render_line_mode0() {
|
||||
void bPPU::render_line_mode0() {
|
||||
render_line_bg(BG1, COLORDEPTH_4, 8, 11);
|
||||
render_line_bg(BG2, COLORDEPTH_4, 7, 10);
|
||||
render_line_bg(BG3, COLORDEPTH_4, 2, 5);
|
||||
|
@ -62,7 +62,7 @@ Mode 1 (pri=0): ->
|
|||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
|
||||
BG3B, OAM0, BG3A, OAM1, BG2B, BG1B, OAM2, BG2A, BG1A, OAM3
|
||||
*/
|
||||
inline void bPPU::render_line_mode1() {
|
||||
void bPPU::render_line_mode1() {
|
||||
if(regs.bg3_priority) {
|
||||
render_line_bg(BG1, COLORDEPTH_16, 5, 8);
|
||||
render_line_bg(BG2, COLORDEPTH_16, 4, 7);
|
||||
|
@ -81,7 +81,7 @@ Mode 2: ->
|
|||
1, 2, 3, 4, 5, 6, 7, 8
|
||||
BG2B, OAM0, BG1B, OAM1, BG2A, OAM2, BG1A, OAM3
|
||||
*/
|
||||
inline void bPPU::render_line_mode2() {
|
||||
void bPPU::render_line_mode2() {
|
||||
render_line_bg(BG1, COLORDEPTH_16, 3, 7);
|
||||
render_line_bg(BG2, COLORDEPTH_16, 1, 5);
|
||||
render_line_oam(2, 4, 6, 8);
|
||||
|
@ -92,7 +92,7 @@ Mode 3: ->
|
|||
1, 2, 3, 4, 5, 6, 7, 8
|
||||
BG2B, OAM0, BG1B, OAM1, BG2A, OAM2, BG1A, OAM3
|
||||
*/
|
||||
inline void bPPU::render_line_mode3() {
|
||||
void bPPU::render_line_mode3() {
|
||||
render_line_bg(BG1, COLORDEPTH_256, 3, 7);
|
||||
render_line_bg(BG2, COLORDEPTH_16, 1, 5);
|
||||
render_line_oam(2, 4, 6, 8);
|
||||
|
@ -103,7 +103,7 @@ Mode 4: ->
|
|||
1, 2, 3, 4, 5, 6, 7, 8
|
||||
BG2B, OAM0, BG1B, OAM1, BG2A, OAM2, BG1A, OAM3
|
||||
*/
|
||||
inline void bPPU::render_line_mode4() {
|
||||
void bPPU::render_line_mode4() {
|
||||
render_line_bg(BG1, COLORDEPTH_256, 3, 7);
|
||||
render_line_bg(BG2, COLORDEPTH_4, 1, 5);
|
||||
render_line_oam(2, 4, 6, 8);
|
||||
|
@ -114,7 +114,7 @@ Mode 5: ->
|
|||
1, 2, 3, 4, 5, 6, 7, 8
|
||||
BG2B, OAM0, BG1B, OAM1, BG2A, OAM2, BG1A, OAM3
|
||||
*/
|
||||
inline void bPPU::render_line_mode5() {
|
||||
void bPPU::render_line_mode5() {
|
||||
render_line_bg(BG1, COLORDEPTH_16, 3, 7);
|
||||
render_line_bg(BG2, COLORDEPTH_4, 1, 5);
|
||||
render_line_oam(2, 4, 6, 8);
|
||||
|
@ -125,7 +125,7 @@ Mode 6: ->
|
|||
1, 2, 3, 4, 5, 6
|
||||
OAM0, BG1B, OAM1, OAM2, BG1A, OAM3
|
||||
*/
|
||||
inline void bPPU::render_line_mode6() {
|
||||
void bPPU::render_line_mode6() {
|
||||
render_line_bg(BG1, COLORDEPTH_16, 2, 5);
|
||||
render_line_oam(1, 3, 4, 6);
|
||||
}
|
||||
|
@ -139,7 +139,7 @@ Mode 7 EXTBG: ->
|
|||
1, 2, 3, 4, 5, 6, 7
|
||||
BG2B, OAM0, BG1n, OAM1, BG2A, OAM2, OAM3
|
||||
*/
|
||||
inline void bPPU::render_line_mode7() {
|
||||
void bPPU::render_line_mode7() {
|
||||
if(regs.mode7_extbg == false) {
|
||||
render_line_mode7(BG1, 2, 2);
|
||||
render_line_oam(1, 3, 4, 5);
|
||||
|
@ -151,7 +151,7 @@ inline void bPPU::render_line_mode7() {
|
|||
}
|
||||
|
||||
void bPPU::render_line() {
|
||||
if(regs.display_disabled == true || regs.display_brightness == 0) {
|
||||
if(regs.display_disabled == true) {
|
||||
memset(output + (line.y * 1024), 0, 1024);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -88,12 +88,8 @@ void render_line_mode7(uint8 bg, uint8 pri0_pos, uint8 pri1_pos);
|
|||
inline uint16 addsub(uint32 x, uint32 y, bool halve);
|
||||
|
||||
//bppu_render_line.cpp
|
||||
enum { BLENDTYPE_BACK = 0, BLENDTYPE_MAIN = 1, BLENDTYPE_SUB = 2, BLENDTYPE_COMBINE = 3 };
|
||||
|
||||
inline uint16 get_palette(uint8 index);
|
||||
inline uint16 get_direct_color(uint8 p, uint8 t);
|
||||
inline uint16 get_pixel_normal(uint32 x);
|
||||
inline uint16 get_pixel_swap(uint32 x);
|
||||
inline uint16 get_pixel_lores(uint32 x);
|
||||
inline uint16 get_pixel_hires(uint32 x);
|
||||
inline void render_line_output();
|
||||
inline void render_line_output();
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
//called once at the start of every rendered scanline
|
||||
void bPPU::update_bg_info() {
|
||||
uint hires = (regs.bg_mode == 5 || regs.bg_mode == 6);
|
||||
uint width = (!hires) ? 256 : 512;
|
||||
|
||||
for(int bg = 0; bg < 4; bg++) {
|
||||
bg_info[bg].th = (regs.bg_tilesize[bg]) ? 4 : 3;
|
||||
bg_info[bg].tw = (regs.hires) ? 4 : bg_info[bg].th;
|
||||
bg_info[bg].tw = (hires) ? 4 : bg_info[bg].th;
|
||||
|
||||
bg_info[bg].mx = (bg_info[bg].th == 4) ? (line.width << 1) : line.width;
|
||||
bg_info[bg].mx = (bg_info[bg].th == 4) ? (width << 1) : width;
|
||||
bg_info[bg].my = bg_info[bg].mx;
|
||||
if(regs.bg_scsize[bg] & 0x01)bg_info[bg].mx <<= 1;
|
||||
if(regs.bg_scsize[bg] & 0x02)bg_info[bg].my <<= 1;
|
||||
|
@ -66,20 +69,22 @@ uint16 tile_mask = 0x0fff >> color_depth; //0x0fff, 0x07ff, 0x03ff
|
|||
//index is a tile number count to add to base tile number
|
||||
uint tiledata_index = regs.bg_tdaddr[bg] >> (4 + color_depth);
|
||||
|
||||
uint8 *bg_td = (uint8*)bg_tiledata[color_depth];
|
||||
uint8 *bg_td_state = (uint8*)bg_tiledata_state[color_depth];
|
||||
uint8 *bg_td = bg_tiledata[color_depth];
|
||||
uint8 *bg_td_state = bg_tiledata_state[color_depth];
|
||||
|
||||
uint8 tile_width = bg_info[bg].tw;
|
||||
uint8 tile_height = bg_info[bg].th;
|
||||
uint16 mask_x = bg_info[bg].mx; //screen width mask
|
||||
uint16 mask_y = bg_info[bg].my; //screen height mask
|
||||
|
||||
uint16 x = 0;
|
||||
uint16 y = regs.bg_y[bg];
|
||||
uint16 hscroll = regs.bg_hofs[bg];
|
||||
uint16 vscroll = regs.bg_vofs[bg];
|
||||
|
||||
if(regs.hires) {
|
||||
uint hires = (regs.bg_mode == 5 || regs.bg_mode == 6);
|
||||
uint width = (!hires) ? 256 : 512;
|
||||
|
||||
if(hires) {
|
||||
hscroll <<= 1;
|
||||
if(regs.interlace) {
|
||||
vscroll <<= 1;
|
||||
|
@ -87,7 +92,7 @@ uint16 vscroll = regs.bg_vofs[bg];
|
|||
}
|
||||
}
|
||||
|
||||
uint16 *mtable = (uint16*)mosaic_table[(regs.mosaic_enabled[bg]) ? regs.mosaic_size : 0];
|
||||
uint16 *mtable = mosaic_table[(regs.mosaic_enabled[bg]) ? regs.mosaic_size : 0];
|
||||
|
||||
uint16 hval, vval;
|
||||
uint16 t, tile_pri, tile_num;
|
||||
|
@ -102,8 +107,8 @@ bool is_opt_mode = (config::ppu.opt_enable == true) && (regs.bg_mode == 2 || r
|
|||
uint8 *wt_main = window[bg].main;
|
||||
uint8 *wt_sub = window[bg].sub;
|
||||
|
||||
int32 prev_x = -1, prev_y = -1;
|
||||
for(x = 0; x < line.width; x++) {
|
||||
uint16 prev_x = 0xffff, prev_y = 0xffff;
|
||||
for(uint16 x = 0; x < width; x++) {
|
||||
hoffset = mtable[x] + hscroll;
|
||||
voffset = y + vscroll;
|
||||
|
||||
|
@ -148,18 +153,18 @@ int32 prev_x = -1, prev_y = -1;
|
|||
|
||||
t = bg_get_tile(bg, hoffset, voffset);
|
||||
|
||||
mirror_y = bool(t & 0x8000);
|
||||
mirror_x = bool(t & 0x4000);
|
||||
mirror_y = !!(t & 0x8000);
|
||||
mirror_x = !!(t & 0x4000);
|
||||
|
||||
tile_pri = (t & 0x2000) ? pri1_pos : pri0_pos;
|
||||
tile_num = t;
|
||||
|
||||
if(tile_width == 4) { //16x16 horizontal tile mirroring
|
||||
if(bool(hoffset & 8) != mirror_x)tile_num++;
|
||||
if(!!(hoffset & 8) != mirror_x)tile_num++;
|
||||
}
|
||||
|
||||
if(tile_height == 4) { //16x16 vertical tile mirroring
|
||||
if(bool(voffset & 8) != mirror_y)tile_num += 16;
|
||||
if(!!(voffset & 8) != mirror_y)tile_num += 16;
|
||||
}
|
||||
|
||||
tile_num &= 0x03ff;
|
||||
|
@ -176,7 +181,7 @@ int32 prev_x = -1, prev_y = -1;
|
|||
ypos = voffset & 7;
|
||||
if(mirror_y)ypos ^= 7; //invert y tile pos
|
||||
|
||||
tile_ptr = (uint8*)bg_td + (tile_num * 64) + (ypos * 8);
|
||||
tile_ptr = bg_td + (tile_num * 64) + (ypos * 8);
|
||||
}
|
||||
|
||||
xpos = hoffset & 7;
|
||||
|
@ -189,7 +194,7 @@ int32 prev_x = -1, prev_y = -1;
|
|||
col = get_palette(col + pal_index);
|
||||
}
|
||||
|
||||
if(!regs.hires) {
|
||||
if(!hires) {
|
||||
if(bg_enabled == true && !wt_main[x]) { setpixel_main(x); }
|
||||
if(bgsub_enabled == true && !wt_sub[x]) { setpixel_sub(x); }
|
||||
} else {
|
||||
|
|
|
@ -99,9 +99,9 @@ uint8 *dest;
|
|||
#undef render_bg_tile_line_4bpp
|
||||
#undef render_bg_tile_line_8bpp
|
||||
|
||||
inline void bPPU::clear_pixel_cache() {
|
||||
void bPPU::clear_pixel_cache() {
|
||||
uint16 main = get_palette(0);
|
||||
uint16 sub = (regs.pseudo_hires || regs.hires) ? main : regs.color_rgb;
|
||||
uint16 sub = (regs.pseudo_hires || regs.bg_mode == 5 || regs.bg_mode == 6) ? main : regs.color_rgb;
|
||||
uint32 i = 255;
|
||||
do {
|
||||
pixel_cache[i].src_main = main;
|
||||
|
|
|
@ -81,33 +81,24 @@ uint8 bg_sub;
|
|||
return src_main;
|
||||
}
|
||||
|
||||
inline uint16 bPPU::get_pixel_lores(uint32 x) {
|
||||
return get_pixel_normal(x);
|
||||
}
|
||||
|
||||
inline uint16 bPPU::get_pixel_hires(uint32 x) {
|
||||
if(x & 1) {
|
||||
return get_pixel_normal(x >> 1);
|
||||
} else {
|
||||
return get_pixel_swap(x >> 1);
|
||||
}
|
||||
}
|
||||
|
||||
inline void bPPU::render_line_output() {
|
||||
uint16 *ptr = (uint16*)output + (line.y * 1024) +
|
||||
((line.interlace && line.interlace_field) ? 512 : 0);
|
||||
uint16 *ltable = (uint16*)light_table + (regs.display_brightness << 15);
|
||||
if(!regs.pseudo_hires && !regs.hires) {
|
||||
uint16 *ptr = (uint16*)output + (line.y * 1024) +
|
||||
((line.interlace && line.interlace_field) ? 512 : 0);
|
||||
uint16 *luma = light_table[regs.display_brightness];
|
||||
if(!regs.pseudo_hires && regs.bg_mode != 5 && regs.bg_mode != 6) {
|
||||
for(int x = 0; x < 256; x++) {
|
||||
*ptr++ = *(ltable + get_pixel_lores(x));
|
||||
*ptr++ = luma[get_pixel_normal(x)];
|
||||
}
|
||||
} else {
|
||||
uint32 curr, prev = 0;
|
||||
for(int x = 0; x < 512; x++) {
|
||||
curr = *(ltable + get_pixel_hires(x));
|
||||
for(int x = 0; x < 256; x++) {
|
||||
curr = luma[get_pixel_swap(x)];
|
||||
*ptr++ = (prev + curr - ((prev ^ curr) & 0x0421)) >> 1;
|
||||
prev = curr;
|
||||
|
||||
curr = luma[get_pixel_normal(x)];
|
||||
*ptr++ = (prev + curr - ((prev ^ curr) & 0x0421)) >> 1;
|
||||
prev = curr;
|
||||
//*ptr++ = *(ltable + get_pixel_hires(x));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ enum { NTSC = 0, PAL = 1 };
|
|||
|
||||
//system functions
|
||||
virtual inline void run();
|
||||
virtual inline void runtoframe();
|
||||
virtual void runtoframe();
|
||||
|
||||
virtual void init();
|
||||
virtual void term();
|
||||
|
|
216
src/ui/Makefile
216
src/ui/Makefile
|
@ -1,90 +1,127 @@
|
|||
ifeq ($(PLATFORM),win-visualc)
|
||||
CC = cl
|
||||
CXX = cl
|
||||
# bsnes makefile
|
||||
|
||||
##################################
|
||||
### platform-specific settings ###
|
||||
##################################
|
||||
|
||||
ifeq ($(PLATFORM),x-gcc-gtk)
|
||||
OS = unix
|
||||
CC = gcc
|
||||
CFLAGS = -O3 -fomit-frame-pointer -ffast-math -DPLATFORM_X -DCOMPILER_GCC -DPROCESSOR_X86 -DUI_GTK `pkg-config --cflags gtk+-2.0` `sdl-config --cflags`
|
||||
AS = nasm
|
||||
RM = del
|
||||
OBJ = obj
|
||||
CFLAGS = /nologo /O2 /arch:SSE2 /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86
|
||||
COMPILE = $(CC) $(CFLAGS) /c
|
||||
ASSEMBLE = $(AS) -f win32
|
||||
LINK =
|
||||
LIBS = kernel32.lib user32.lib gdi32.lib winmm.lib comdlg32.lib comctl32.lib \
|
||||
d3d9.lib d3dx9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib
|
||||
ASFLAGS = -f elf
|
||||
LIBS = `pkg-config --libs gtk+-2.0` `sdl-config --libs`
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),win-visualc)
|
||||
OS = win
|
||||
CC = cl
|
||||
CFLAGS = /nologo /O2 /arch:SSE2 /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_WIN
|
||||
AS = nasm
|
||||
ASFLAGS = -f win32 -DWIN32
|
||||
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),win-visualc-wip)
|
||||
OS = win
|
||||
CC = cl
|
||||
CXX = cl
|
||||
CFLAGS = /nologo /O2 /GL /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_WIN
|
||||
AS = nasm
|
||||
RM = del
|
||||
OBJ = obj
|
||||
CFLAGS = /nologo /O2 /GL /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86
|
||||
COMPILE = $(CC) $(CFLAGS) /c
|
||||
ASSEMBLE = $(AS) -f win32
|
||||
ASFLAGS = -f win32 -DWIN32
|
||||
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib
|
||||
LINK = /link /LTCG
|
||||
LIBS = kernel32.lib user32.lib gdi32.lib winmm.lib comdlg32.lib comctl32.lib \
|
||||
d3d9.lib d3dx9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),win-visualc-pgi)
|
||||
OS = win
|
||||
CC = cl
|
||||
CXX = cl
|
||||
CFLAGS = /nologo /O2 /GL /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_WIN
|
||||
AS = nasm
|
||||
RM = del
|
||||
OBJ = obj
|
||||
CFLAGS = /nologo /O2 /GL /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86
|
||||
COMPILE = $(CC) $(CFLAGS) /c
|
||||
ASSEMBLE = $(AS) -f win32
|
||||
ASFLAGS = -f win32 -DWIN32
|
||||
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib
|
||||
LINK = /link /PGD:bsnes.pgd /LTCG:PGINSTRUMENT
|
||||
LIBS = kernel32.lib user32.lib gdi32.lib winmm.lib comdlg32.lib comctl32.lib \
|
||||
d3d9.lib d3dx9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),win-visualc-pgo)
|
||||
OS = win
|
||||
CC = cl
|
||||
CXX = cl
|
||||
CFLAGS = /nologo /O2 /GL /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_WIN
|
||||
AS = nasm
|
||||
RM = del
|
||||
OBJ = obj
|
||||
CFLAGS = /nologo /O2 /arch:SSE2 /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86
|
||||
COMPILE = $(CC) $(CFLAGS) /c
|
||||
ASSEMBLE = $(AS) -f win32
|
||||
ASFLAGS = -f win32 -DWIN32
|
||||
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib
|
||||
LINK = /link /PGD:bsnes.pgd /LTCG:PGOPTIMIZE
|
||||
LIBS = kernel32.lib user32.lib gdi32.lib winmm.lib comdlg32.lib comctl32.lib \
|
||||
d3d9.lib d3dx9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),win-visualc-sdl)
|
||||
OS = win
|
||||
CC = cl
|
||||
CXX = cl
|
||||
CFLAGS = /nologo /O2 /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_SDL
|
||||
AS = nasm
|
||||
RM = del
|
||||
OBJ = obj
|
||||
CFLAGS = /nologo /O2 /DPLATFORM_SDL /DCOMPILER_VISUALC /DPROCESSOR_X86
|
||||
COMPILE = $(CC) $(CFLAGS) /c
|
||||
ASSEMBLE = $(AS) -f win32
|
||||
LINK =
|
||||
LIBS = kernel32.lib user32.lib gdi32.lib winmm.lib comdlg32.lib comctl32.lib \
|
||||
sdlmain.lib sdl.lib
|
||||
ASFLAGS = -f win32 -DWIN32
|
||||
LIBS = sdlmain.lib sdl.lib dsound.lib
|
||||
endif
|
||||
|
||||
OBJS = main.$(OBJ) \
|
||||
libco.$(OBJ) libstring.$(OBJ) libconfig.$(OBJ) \
|
||||
reader.$(OBJ) cart.$(OBJ) cheat.$(OBJ) \
|
||||
memory.$(OBJ) bmemory.$(OBJ) \
|
||||
cpu.$(OBJ) scpu.$(OBJ) bcpu.$(OBJ) \
|
||||
apu.$(OBJ) sapu.$(OBJ) bapu.$(OBJ) \
|
||||
bdsp.$(OBJ) \
|
||||
ppu.$(OBJ) bppu.$(OBJ) \
|
||||
snes.$(OBJ) \
|
||||
srtc.$(OBJ) sdd1.$(OBJ) c4.$(OBJ) dsp1.$(OBJ) dsp2.$(OBJ) obc1.$(OBJ)
|
||||
# adler32.$(OBJ) compress.$(OBJ) crc32.$(OBJ) deflate.$(OBJ) gzio.$(OBJ) inffast.$(OBJ) \
|
||||
# inflate.$(OBJ) inftrees.$(OBJ) ioapi.$(OBJ) trees.$(OBJ) unzip.$(OBJ) zip.$(OBJ) zutil.$(OBJ) \
|
||||
# jma.$(OBJ) jcrc32.$(OBJ) lzmadec.$(OBJ) 7zlzma.$(OBJ) iiostrm.$(OBJ) inbyte.$(OBJ) lzma.$(OBJ) winout.$(OBJ)
|
||||
#####################################
|
||||
### compiler / assembler switches ###
|
||||
#####################################
|
||||
|
||||
ifeq ($(CC),gcc)
|
||||
OUT = -obsnes
|
||||
CXX = g++
|
||||
OBJ = o
|
||||
COBJFLAG = -c
|
||||
endif
|
||||
|
||||
ifeq ($(CC),cl)
|
||||
OUT = /Febsnes.exe
|
||||
CXX = cl
|
||||
OBJ = obj
|
||||
COBJFLAG = /c
|
||||
endif
|
||||
|
||||
ifeq ($(AS),nasm)
|
||||
ASOBJFLAG = -o
|
||||
endif
|
||||
|
||||
###################
|
||||
### OS switches ###
|
||||
###################
|
||||
|
||||
ifeq ($(OS),unix)
|
||||
RM = rm -f
|
||||
endif
|
||||
|
||||
ifeq ($(OS),win)
|
||||
RM = del
|
||||
LIBS += kernel32.lib user32.lib gdi32.lib winmm.lib comdlg32.lib comctl32.lib
|
||||
endif
|
||||
|
||||
#########################
|
||||
### begin compilation ###
|
||||
#########################
|
||||
|
||||
OBJS = main.$(OBJ) \
|
||||
libco.$(OBJ) libstring.$(OBJ) libconfig.$(OBJ) \
|
||||
reader.$(OBJ) cart.$(OBJ) cheat.$(OBJ) \
|
||||
memory.$(OBJ) bmemory.$(OBJ) \
|
||||
cpu.$(OBJ) scpu.$(OBJ) \
|
||||
apu.$(OBJ) sapu.$(OBJ) \
|
||||
bdsp.$(OBJ) \
|
||||
ppu.$(OBJ) bppu.$(OBJ) \
|
||||
snes.$(OBJ) \
|
||||
srtc.$(OBJ) sdd1.$(OBJ) c4.$(OBJ) dsp1.$(OBJ) dsp2.$(OBJ) obc1.$(OBJ)
|
||||
#adler32.$(OBJ) compress.$(OBJ) crc32.$(OBJ) deflate.$(OBJ) gzio.$(OBJ) inffast.$(OBJ) \
|
||||
#inflate.$(OBJ) inftrees.$(OBJ) ioapi.$(OBJ) trees.$(OBJ) unzip.$(OBJ) zip.$(OBJ) zutil.$(OBJ) \
|
||||
#jma.$(OBJ) jcrc32.$(OBJ) lzmadec.$(OBJ) 7zlzma.$(OBJ) iiostrm.$(OBJ) inbyte.$(OBJ) lzma.$(OBJ) winout.$(OBJ)
|
||||
|
||||
ifeq ($(OS),win)
|
||||
ifeq ($(CC),cl)
|
||||
OBJS += bsnes.res
|
||||
endif
|
||||
endif
|
||||
|
||||
all: $(OBJS)
|
||||
rc /r /fobsnes.res bsnes.rc
|
||||
$(CC) /Febsnes.exe $(CFLAGS) $(OBJS) bsnes.res $(LIBS) $(LINK)
|
||||
$(CXX) $(OUT) $(CFLAGS) $(OBJS) $(LIBS) $(LINK)
|
||||
# mt -nologo -manifest bsnes.exe.manifest -outputresource:bsnes.exe;1
|
||||
|
||||
clean:
|
||||
|
@ -99,117 +136,120 @@ clean:
|
|||
#########################
|
||||
### platform-specific ###
|
||||
#########################
|
||||
main.$(OBJ): *.cpp *.h video/* audio/* input/* ../config/* win/* win/settings/* win/debugger/*
|
||||
$(COMPILE) main.cpp
|
||||
main.$(OBJ): *.cpp *.h video/* audio/* input/* ../config/* win/* win/settings/* win/debugger/* sdl/*
|
||||
$(CXX) $(CFLAGS) $(COBJFLAG) main.cpp
|
||||
|
||||
bsnes.res: bsnes.rc
|
||||
rc /r /fobsnes.res bsnes.rc
|
||||
|
||||
#################
|
||||
### libraries ###
|
||||
#################
|
||||
libco.$(OBJ): ../lib/*
|
||||
$(ASSEMBLE) -o libco.$(OBJ) ../lib/libco_x86.asm
|
||||
# $(COMPILE) /Folibco.obj ../lib/libco_win32.cpp
|
||||
$(AS) $(ASFLAGS) $(ASOBJFLAG) libco.$(OBJ) ../lib/libco_x86.asm
|
||||
# $(CXX) $(CFLAGS) $(COBJFLAG) /Folibco.$(OBJ) ../lib/libco_win32.cpp
|
||||
|
||||
libstring.$(OBJ): ../lib/*.cpp ../lib/*.h
|
||||
$(COMPILE) ../lib/libstring.cpp
|
||||
$(CXX) $(CFLAGS) $(COBJFLAG) ../lib/libstring.cpp
|
||||
|
||||
libconfig.$(OBJ): ../lib/*.cpp ../lib/*.h
|
||||
$(COMPILE) ../lib/libconfig.cpp
|
||||
$(CXX) $(CFLAGS) $(COBJFLAG) ../lib/libconfig.cpp
|
||||
|
||||
##############
|
||||
### memory ###
|
||||
##############
|
||||
memory.$(OBJ): ../memory/memory.cpp ../memory/memory.h
|
||||
$(COMPILE) ../memory/memory.cpp
|
||||
$(CXX) $(CFLAGS) $(COBJFLAG) ../memory/memory.cpp
|
||||
|
||||
bmemory.$(OBJ): ../memory/bmemory/* ../memory/bmemory/mapper/*
|
||||
$(COMPILE) ../memory/bmemory/bmemory.cpp
|
||||
$(CXX) $(CFLAGS) $(COBJFLAG) ../memory/bmemory/bmemory.cpp
|
||||
|
||||
###########
|
||||
### cpu ###
|
||||
###########
|
||||
cpu.$(OBJ): ../cpu/*
|
||||
$(COMPILE) ../cpu/cpu.cpp
|
||||
$(CXX) $(CFLAGS) $(COBJFLAG) ../cpu/cpu.cpp
|
||||
|
||||
scpu.$(OBJ): ../cpu/scpu/* ../cpu/scpu/core/* ../cpu/scpu/dma/* ../cpu/scpu/memory/* ../cpu/scpu/mmio/* ../cpu/scpu/timing/*
|
||||
$(COMPILE) ../cpu/scpu/scpu.cpp
|
||||
$(CXX) $(CFLAGS) $(COBJFLAG) ../cpu/scpu/scpu.cpp
|
||||
|
||||
bcpu.$(OBJ): ../cpu/bcpu/*
|
||||
$(COMPILE) ../cpu/bcpu/bcpu.cpp
|
||||
$(CXX) $(CFLAGS) $(COBJFLAG) ../cpu/bcpu/bcpu.cpp
|
||||
|
||||
###########
|
||||
### apu ###
|
||||
###########
|
||||
apu.$(OBJ): ../apu/*
|
||||
$(COMPILE) ../apu/apu.cpp
|
||||
$(CXX) $(CFLAGS) $(COBJFLAG) ../apu/apu.cpp
|
||||
|
||||
sapu.$(OBJ): ../apu/sapu/* ../apu/sapu/core/* ../apu/sapu/memory/* ../apu/sapu/timing/*
|
||||
$(COMPILE) ../apu/sapu/sapu.cpp
|
||||
$(CXX) $(CFLAGS) $(COBJFLAG) ../apu/sapu/sapu.cpp
|
||||
|
||||
bapu.$(OBJ): ../apu/bapu/*
|
||||
$(COMPILE) ../apu/bapu/bapu.cpp
|
||||
$(CXX) $(CFLAGS) $(COBJFLAG) ../apu/bapu/bapu.cpp
|
||||
|
||||
###########
|
||||
### dsp ###
|
||||
###########
|
||||
bdsp.$(OBJ): ../dsp/bdsp/*
|
||||
$(COMPILE) ../dsp/bdsp/bdsp.cpp
|
||||
$(CXX) $(CFLAGS) $(COBJFLAG) ../dsp/bdsp/bdsp.cpp
|
||||
|
||||
###########
|
||||
### ppu ###
|
||||
###########
|
||||
ppu.$(OBJ): ../ppu/*.cpp ../ppu/*.h
|
||||
$(COMPILE) ../ppu/ppu.cpp
|
||||
$(CXX) $(CFLAGS) $(COBJFLAG) ../ppu/ppu.cpp
|
||||
|
||||
bppu.$(OBJ): ../ppu/bppu/*
|
||||
$(COMPILE) ../ppu/bppu/bppu.cpp
|
||||
$(CXX) $(CFLAGS) $(COBJFLAG) ../ppu/bppu/bppu.cpp
|
||||
|
||||
#################
|
||||
### utilities ###
|
||||
#################
|
||||
reader.$(OBJ): ../reader/*.cpp ../reader/*.h
|
||||
$(COMPILE) ../reader/reader.cpp
|
||||
$(CXX) $(CFLAGS) $(COBJFLAG) ../reader/reader.cpp
|
||||
|
||||
cart.$(OBJ): ../cart/*.cpp ../cart/*.h
|
||||
$(COMPILE) ../cart/cart.cpp
|
||||
$(CXX) $(CFLAGS) $(COBJFLAG) ../cart/cart.cpp
|
||||
|
||||
cheat.$(OBJ): ../cheat/*.cpp ../cheat/*.h
|
||||
$(COMPILE) ../cheat/cheat.cpp
|
||||
$(CXX) $(CFLAGS) $(COBJFLAG) ../cheat/cheat.cpp
|
||||
|
||||
############
|
||||
### snes ###
|
||||
############
|
||||
snes.$(OBJ): ../snes/* ../snes/video/* ../snes/audio/* ../snes/input/*
|
||||
$(COMPILE) ../snes/snes.cpp
|
||||
$(CXX) $(CFLAGS) $(COBJFLAG) ../snes/snes.cpp
|
||||
|
||||
#####################
|
||||
### special chips ###
|
||||
#####################
|
||||
srtc.$(OBJ): ../chip/srtc/*
|
||||
$(COMPILE) ../chip/srtc/srtc.cpp
|
||||
$(CXX) $(CFLAGS) $(COBJFLAG) ../chip/srtc/srtc.cpp
|
||||
|
||||
sdd1.$(OBJ): ../chip/sdd1/*
|
||||
$(COMPILE) ../chip/sdd1/sdd1.cpp
|
||||
$(CXX) $(CFLAGS) $(COBJFLAG) ../chip/sdd1/sdd1.cpp
|
||||
|
||||
c4.$(OBJ): ../chip/c4/*
|
||||
$(COMPILE) ../chip/c4/c4.cpp
|
||||
$(CXX) $(CFLAGS) $(COBJFLAG) ../chip/c4/c4.cpp
|
||||
|
||||
dsp1.$(OBJ): ../chip/dsp1/*
|
||||
$(COMPILE) ../chip/dsp1/dsp1.cpp
|
||||
$(CXX) $(CFLAGS) $(COBJFLAG) ../chip/dsp1/dsp1.cpp
|
||||
|
||||
dsp2.$(OBJ): ../chip/dsp2/*
|
||||
$(COMPILE) ../chip/dsp2/dsp2.cpp
|
||||
$(CXX) $(CFLAGS) $(COBJFLAG) ../chip/dsp2/dsp2.cpp
|
||||
|
||||
obc1.$(OBJ): ../chip/obc1/*
|
||||
$(COMPILE) ../chip/obc1/obc1.cpp
|
||||
$(CXX) $(CFLAGS) $(COBJFLAG) ../chip/obc1/obc1.cpp
|
||||
|
||||
############
|
||||
### zlib ###
|
||||
############
|
||||
adler32.$(OBJ): ../reader/zlib/*.c ../reader/zlib/*.h
|
||||
$(COMPILE) ../reader/zlib/*.c
|
||||
$(CC) $(CFLAGS) $(COBJFLAG) ../reader/zlib/*.c
|
||||
|
||||
###########
|
||||
### jma ###
|
||||
###########
|
||||
jma.$(OBJ): ../reader/jma/*.cpp ../reader/jma/*.h
|
||||
$(COMPILE) ../reader/jma/*.cpp
|
||||
$(CXX) $(CFLAGS) $(COBJFLAG) ../reader/jma/*.cpp
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
class Audio {
|
||||
public:
|
||||
uint frequency;
|
||||
virtual void run(uint32 sample) = 0;
|
||||
virtual void set_frequency(uint new_freq) = 0;
|
||||
virtual void clear_audio() = 0;
|
||||
virtual void init() = 0;
|
||||
virtual void term() = 0;
|
||||
virtual void run(uint32 sample) {}
|
||||
virtual void set_frequency(uint new_freq) {}
|
||||
virtual void clear_audio() {}
|
||||
virtual void init() {}
|
||||
virtual void term() {}
|
||||
|
||||
Audio() : frequency(32000) {}
|
||||
} *uiAudio;
|
||||
|
|
|
@ -4,7 +4,7 @@ void AudioDS::run(uint32 sample) {
|
|||
if(data.buffer_pos >= data.samples_per_frame) {
|
||||
uint32 pos, size;
|
||||
void *buffer;
|
||||
if(bool(config::system.regulate_speed) == true) {
|
||||
if(config::system.regulate_speed == true) {
|
||||
for(;;) {
|
||||
dsb_b->GetCurrentPosition(&pos, 0);
|
||||
data.read_buffer = pos / data.buffer_size;
|
||||
|
@ -62,7 +62,7 @@ void AudioDS::init() {
|
|||
data.buffer_size = data.samples_per_frame * 4;
|
||||
|
||||
DirectSoundCreate(0, &ds, 0);
|
||||
ds->SetCooperativeLevel(wMain.hwnd, DSSCL_PRIORITY);
|
||||
ds->SetCooperativeLevel(hwnd, DSSCL_PRIORITY);
|
||||
|
||||
memset(&dsbd, 0, sizeof(dsbd));
|
||||
dsbd.dwSize = sizeof(dsbd);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
class AudioDS : public Audio {
|
||||
public:
|
||||
HWND hwnd;
|
||||
LPDIRECTSOUND ds;
|
||||
LPDIRECTSOUNDBUFFER dsb_p, dsb_b;
|
||||
DSBUFFERDESC dsbd;
|
||||
|
@ -21,7 +22,8 @@ struct {
|
|||
void init();
|
||||
void term();
|
||||
|
||||
AudioDS() {
|
||||
AudioDS(HWND handle = 0) {
|
||||
hwnd = (handle) ? handle : GetDesktopWindow();
|
||||
ds = 0;
|
||||
dsb_p = 0;
|
||||
dsb_b = 0;
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
#!/bin/sh
|
||||
gmake PLATFORM=x-gcc-gtk
|
|
@ -0,0 +1,2 @@
|
|||
#!/bin/sh
|
||||
gmake PLATFORM=x-gcc-gtk clean
|
|
@ -1,9 +1,15 @@
|
|||
namespace config {
|
||||
|
||||
struct System {
|
||||
static Setting video, audio, input;
|
||||
|
||||
static Setting regulate_speed;
|
||||
static Setting speed_slowest, speed_slow, speed_normal, speed_fast, speed_fastest;
|
||||
} system;
|
||||
Setting System::video(&config_file, "system.video", "Video hardware interface", "");
|
||||
Setting System::audio(&config_file, "system.audio", "Audio hardware interface", "");
|
||||
Setting System::input(&config_file, "system.input", "Input hardware interface", "");
|
||||
|
||||
Setting System::regulate_speed(&config_file, "system.regulate_speed", "Regulate speed to 60hz (NTSC) / 50hz (PAL)", true, Setting::TRUE_FALSE);
|
||||
Setting System::speed_slowest (&config_file, "system.speed_slowest", "Slowest speed setting (in hz)", 16000, Setting::DEC);
|
||||
Setting System::speed_slow (&config_file, "system.speed_slow", "Slow speed setting", 24000, Setting::DEC);
|
||||
|
@ -12,19 +18,14 @@ Setting System::speed_fast (&config_file, "system.speed_fast", "Fast spee
|
|||
Setting System::speed_fastest (&config_file, "system.speed_fastest", "Fastest speed setting", 64000, Setting::DEC);
|
||||
|
||||
struct Video {
|
||||
static Setting renderer;
|
||||
static Setting profile, fullscreen;
|
||||
static Setting profile;
|
||||
static Setting profile_0, profile_1, profile_2, profile_3;
|
||||
static Setting profile_4, profile_5, profile_6, profile_7;
|
||||
|
||||
static Setting use_vram, triple_buffering;
|
||||
static Setting use_vram;
|
||||
static Setting pscanline_intensity, iscanline_intensity;
|
||||
} 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", "", 2, Setting::DEC);
|
||||
Setting Video::fullscreen(0, "video.fullscreen", "", false, Setting::TRUE_FALSE);
|
||||
|
||||
/* software_filter
|
||||
* hardware_filter
|
||||
|
@ -45,18 +46,17 @@ Setting Video::profile_0(&config_file, "video.profile_0", "Video profile 0-7 con
|
|||
"Please use bsnes GUI configuration editor to modify video profile settings\n"
|
||||
"Format: software_filter;hardware_filter;video_standard;multiplier-1;correct_aspect_ratio;\n"
|
||||
" enable_scanlines;manual_render_size;render_width;render_height;\n"
|
||||
" resolution_width;resolution_height;refresh_rate;triple_buffering"
|
||||
"", "0;0;0;0;false;false;false;256;224;0;0;0;false");
|
||||
Setting Video::profile_1(&config_file, "video.profile_1", "", "0;0;0;1;false;false;false;512;448;0;0;0;false");
|
||||
Setting Video::profile_2(&config_file, "video.profile_2", "", "0;1;0;1;true;false;false;597;448;0;0;0;false");
|
||||
Setting Video::profile_3(&config_file, "video.profile_3", "", "0;1;0;2;true;false;false;896;672;0;0;0;false");
|
||||
Setting Video::profile_4(&config_file, "video.profile_4", "", "0;1;0;3;true;false;false;1195;896;0;0;0;false");
|
||||
Setting Video::profile_5(&config_file, "video.profile_5", "", "0;0;0;0;false;false;false;256;224;0;0;0;false");
|
||||
Setting Video::profile_6(&config_file, "video.profile_6", "", "0;0;0;0;false;false;false;256;224;0;0;0;false");
|
||||
Setting Video::profile_7(&config_file, "video.profile_7", "", "0;0;0;0;false;false;false;256;224;0;0;0;false");
|
||||
" fullscreen;triple_buffering;resolution_width;resolution_height;refresh_rate"
|
||||
"", "0;0;0;0;false;false;false;256;224;false;false;0;0;0");
|
||||
Setting Video::profile_1(&config_file, "video.profile_1", "", "0;0;0;1;false;false;false;512;448;false;false;0;0;0");
|
||||
Setting Video::profile_2(&config_file, "video.profile_2", "", "0;1;0;1;true;false;false;597;448;false;false;0;0;0");
|
||||
Setting Video::profile_3(&config_file, "video.profile_3", "", "0;1;0;2;true;false;false;896;672;false;false;0;0;0");
|
||||
Setting Video::profile_4(&config_file, "video.profile_4", "", "0;1;0;3;true;false;false;1195;896;false;false;0;0;0");
|
||||
Setting Video::profile_5(&config_file, "video.profile_5", "", "0;1;0;1;true;false;false;597;448;true;false;0;0;0");
|
||||
Setting Video::profile_6(&config_file, "video.profile_6", "", "0;1;0;2;true;false;false;896;672;true;false;0;0;0");
|
||||
Setting Video::profile_7(&config_file, "video.profile_7", "", "0;1;0;3;true;false;false;1195;896;true;false;0;0;0");
|
||||
|
||||
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);
|
||||
Setting Video::pscanline_intensity(&config_file, "video.pscanline_intensity",
|
||||
"Progressive scanline intensity\n"
|
||||
"Value is percentage of intensity from 0 to 100", 30, Setting::DEC);
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
void bSNES::set_status(uint32 new_status) { run_status = new_status; }
|
||||
uint32 bSNES::get_status() { return run_status; }
|
||||
|
||||
void bSNES::run() {
|
||||
if(cartridge.loaded() == false)return;
|
||||
|
||||
switch(run_status) {
|
||||
case RUN:
|
||||
SNES::runtoframe();
|
||||
return;
|
||||
case STOP:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void bSNES::video_run() {
|
||||
if(r_ppu->status.frames_updated == true) {
|
||||
char t[256];
|
||||
r_ppu->status.frames_updated = false;
|
||||
sprintf(t, "%s : %d fps", BSNES_TITLE, r_ppu->status.frames_executed);
|
||||
gtk_window_set_title(GTK_WINDOW(main_window.window), t);
|
||||
}
|
||||
|
||||
uiVideo->redraw();
|
||||
}
|
||||
|
||||
void bSNES::sound_run(uint32 data) {
|
||||
uiAudio->run(data);
|
||||
}
|
||||
|
||||
uint16 *bSNES::video_lock(uint &pitch) {
|
||||
return uiVideo->lock(pitch);
|
||||
}
|
||||
|
||||
void bSNES::video_unlock() {
|
||||
uiVideo->unlock();
|
||||
}
|
||||
|
||||
void bSNES::poll_input(uint8 type) {
|
||||
uiInput->poll(type);
|
||||
}
|
||||
|
||||
bool bSNES::get_input_status(uint8 device, uint8 button) {
|
||||
return uiInput->get_status(device, button);
|
||||
}
|
||||
|
||||
void bSNES::notify(uint32 message, uint32 param1, uint32 param2) {}
|
||||
bSNES::bSNES() { run_status = STOP; }
|
|
@ -0,0 +1,22 @@
|
|||
class bSNES : public SNES {
|
||||
private:
|
||||
uint32 run_status;
|
||||
|
||||
public:
|
||||
enum { STOP = 0, RUN };
|
||||
void run();
|
||||
void video_run();
|
||||
void sound_run(uint32 data);
|
||||
|
||||
uint16 *video_lock(uint &pitch);
|
||||
void video_unlock();
|
||||
|
||||
void set_status(uint32 status);
|
||||
uint32 get_status();
|
||||
|
||||
void poll_input(uint8 type);
|
||||
bool get_input_status(uint8 device, uint8 button);
|
||||
|
||||
void notify(uint32 message, uint32 param1, uint32 param2);
|
||||
bSNES();
|
||||
} *bsnes;
|
|
@ -0,0 +1,192 @@
|
|||
const char about_text[4096] = ""
|
||||
"bsnes -- version " BSNES_VERSION "\r\n"
|
||||
"Author: byuu\r\n"
|
||||
"Project began: October 14th, 2004\r\n"
|
||||
"\r\n\r\n"
|
||||
"Contributors:\r\n"
|
||||
" anomie, blargg, DMV27, GIGO, kode54, Nach,\r\n"
|
||||
" Overload, Richard Bannister, TRAC, zones";
|
||||
|
||||
struct MainWindow {
|
||||
GtkWidget *window;
|
||||
GtkWidget *box;
|
||||
|
||||
GtkWidget *menu;
|
||||
GtkWidget *menu_file, *menu_file_item;
|
||||
GtkWidget *menu_file_loadrom;
|
||||
GtkWidget *menu_file_unloadrom;
|
||||
GtkWidget *menu_file_separator1;
|
||||
GtkWidget *menu_file_reset;
|
||||
GtkWidget *menu_file_power;
|
||||
GtkWidget *menu_file_separator2;
|
||||
GtkWidget *menu_file_quit;
|
||||
GtkWidget *menu_help, *menu_help_item;
|
||||
GtkWidget *menu_help_about;
|
||||
|
||||
GdkColor render_bg;
|
||||
GtkWidget *render;
|
||||
|
||||
GtkWidget *fileopen;
|
||||
GtkWidget *aboutbox;
|
||||
} main_window;
|
||||
|
||||
void init_main_window();
|
||||
void menu_main_window(const char *item);
|
||||
void term_main_window();
|
||||
void load_rom();
|
||||
void cancel_load_rom();
|
||||
void unload_rom();
|
||||
void snes_reset();
|
||||
void snes_power();
|
||||
void close_aboutbox();
|
||||
|
||||
void init_main_window() {
|
||||
MainWindow *w = &main_window;
|
||||
|
||||
//
|
||||
//create window
|
||||
//
|
||||
w->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title(GTK_WINDOW(w->window), BSNES_TITLE);
|
||||
gtk_window_set_resizable(GTK_WINDOW(w->window), false);
|
||||
g_signal_connect(G_OBJECT(w->window), "destroy", G_CALLBACK(term_main_window), 0);
|
||||
|
||||
//
|
||||
//create widget container
|
||||
//
|
||||
w->box = gtk_vbox_new(false, 0);
|
||||
gtk_container_add(GTK_CONTAINER(w->window), w->box);
|
||||
gtk_widget_show(w->box);
|
||||
|
||||
//
|
||||
//create menu
|
||||
//
|
||||
w->menu = gtk_menu_bar_new();
|
||||
gtk_widget_show(w->menu);
|
||||
|
||||
w->menu_file = gtk_menu_new();
|
||||
w->menu_file_item = gtk_menu_item_new_with_label("File");
|
||||
gtk_widget_show(w->menu_file_item);
|
||||
|
||||
#define add_item(menu, item, label, id) \
|
||||
item = gtk_menu_item_new_with_label(label); \
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); \
|
||||
g_signal_connect_swapped(G_OBJECT(item), "activate", G_CALLBACK(menu_main_window), (gpointer)id); \
|
||||
gtk_widget_show(item)
|
||||
#define add_separator(menu, item) \
|
||||
item = gtk_separator_menu_item_new(); \
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); \
|
||||
gtk_widget_show(item)
|
||||
|
||||
add_item (w->menu_file, w->menu_file_loadrom, "Load ROM", "file.loadrom");
|
||||
add_item (w->menu_file, w->menu_file_unloadrom, "Unload ROM", "file.unloadrom");
|
||||
add_separator(w->menu_file, w->menu_file_separator1);
|
||||
add_item (w->menu_file, w->menu_file_reset, "Reset", "file.reset");
|
||||
add_item (w->menu_file, w->menu_file_power, "Power (Hard Reset)", "file.power");
|
||||
add_separator(w->menu_file, w->menu_file_separator2);
|
||||
add_item (w->menu_file, w->menu_file_quit, "Quit", "file.quit");
|
||||
|
||||
w->menu_help = gtk_menu_new();
|
||||
w->menu_help_item = gtk_menu_item_new_with_label("Help");
|
||||
gtk_widget_show(w->menu_help_item);
|
||||
|
||||
add_item (w->menu_help, w->menu_help_about, "About", "help.about");
|
||||
|
||||
gtk_menu_item_set_submenu(GTK_MENU_ITEM(w->menu_file_item), w->menu_file);
|
||||
gtk_menu_item_set_submenu(GTK_MENU_ITEM(w->menu_help_item), w->menu_help);
|
||||
|
||||
gtk_menu_bar_append(GTK_MENU_BAR(w->menu), w->menu_file_item);
|
||||
gtk_menu_bar_append(GTK_MENU_BAR(w->menu), w->menu_help_item);
|
||||
|
||||
#undef add_item
|
||||
#undef add_separator
|
||||
|
||||
//
|
||||
//create render widget
|
||||
//
|
||||
w->render_bg.pixel = 0;
|
||||
w->render_bg.red = 0;
|
||||
w->render_bg.green = 0;
|
||||
w->render_bg.blue = 0;
|
||||
|
||||
w->render = gtk_drawing_area_new();
|
||||
gtk_widget_set_size_request(w->render, 256, 224);
|
||||
gtk_widget_modify_bg(w->render, GTK_STATE_NORMAL, &w->render_bg);
|
||||
gtk_widget_show(w->render);
|
||||
|
||||
//
|
||||
//pack widgets
|
||||
//
|
||||
gtk_box_pack_start(GTK_BOX(w->box), w->menu, false, false, 0);
|
||||
gtk_box_pack_end(GTK_BOX(w->box), w->render, true, true, 0);
|
||||
|
||||
//
|
||||
//display window
|
||||
//
|
||||
gtk_widget_show(w->window);
|
||||
|
||||
while(gtk_events_pending() == true) {
|
||||
gtk_main_iteration_do(false);
|
||||
}
|
||||
|
||||
//
|
||||
//initializations
|
||||
//
|
||||
w->fileopen = 0;
|
||||
}
|
||||
|
||||
void menu_main_window(const char *item) {
|
||||
MainWindow *w = &main_window;
|
||||
|
||||
if(!strcmp(item, "file.loadrom")) {
|
||||
if(!w->fileopen) {
|
||||
w->fileopen = gtk_file_selection_new("Load ROM");
|
||||
g_signal_connect_swapped(G_OBJECT(w->fileopen), "destroy", G_CALLBACK(cancel_load_rom), 0);
|
||||
g_signal_connect_swapped(G_OBJECT(GTK_FILE_SELECTION(w->fileopen)->ok_button), "clicked", G_CALLBACK(load_rom), 0);
|
||||
g_signal_connect_swapped(G_OBJECT(GTK_FILE_SELECTION(w->fileopen)->cancel_button), "clicked", G_CALLBACK(gtk_widget_destroy), (gpointer)w->fileopen);
|
||||
}
|
||||
gtk_widget_show(w->fileopen);
|
||||
} else if(!strcmp(item, "file.unloadrom")) {
|
||||
if(cartridge.loaded() == true) { cartridge.unload(); }
|
||||
gtk_window_set_title(GTK_WINDOW(w->window), BSNES_TITLE);
|
||||
gdk_window_invalidate_rect(GDK_WINDOW(w->render->window), 0, true);
|
||||
} else if(!strcmp(item, "file.reset")) {
|
||||
bsnes->reset();
|
||||
} else if(!strcmp(item, "file.power")) {
|
||||
bsnes->power();
|
||||
} else if(!strcmp(item, "file.quit")) {
|
||||
term_main_window();
|
||||
} else if(!strcmp(item, "help.about")) {
|
||||
if(!w->aboutbox) {
|
||||
w->aboutbox = gtk_message_dialog_new(0, (GtkDialogFlags)0, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, about_text);
|
||||
gtk_window_set_title(GTK_WINDOW(w->aboutbox), "About bsnes...");
|
||||
g_signal_connect_swapped(G_OBJECT(w->aboutbox), "destroy", G_CALLBACK(close_aboutbox), 0);
|
||||
g_signal_connect_swapped(G_OBJECT(w->aboutbox), "response", G_CALLBACK(gtk_widget_destroy), (gpointer)w->aboutbox);
|
||||
}
|
||||
gtk_widget_show(w->aboutbox);
|
||||
}
|
||||
}
|
||||
|
||||
void term_main_window() {
|
||||
running = false;
|
||||
}
|
||||
|
||||
void load_rom() {
|
||||
if(!main_window.fileopen)return;
|
||||
|
||||
const char *fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION(main_window.fileopen));
|
||||
gtk_widget_hide(main_window.fileopen);
|
||||
|
||||
if(cartridge.loaded() == true) { cartridge.unload(); }
|
||||
if(cartridge.load(fn) == false) { return; }
|
||||
|
||||
bsnes->power();
|
||||
}
|
||||
|
||||
void cancel_load_rom() {
|
||||
main_window.fileopen = 0;
|
||||
}
|
||||
|
||||
void close_aboutbox() {
|
||||
main_window.aboutbox = 0;
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
#include "main.h"
|
||||
|
||||
#include "bsnes.h"
|
||||
#include "gtk_mainwindow.cpp"
|
||||
#include "bsnes.cpp"
|
||||
|
||||
#include "../video/gtk.h"
|
||||
#include "../video/gtk.cpp"
|
||||
#include "../video/sdl.h"
|
||||
#include "../video/sdl.cpp"
|
||||
|
||||
#ifdef PLATFORM_WIN
|
||||
#include "../audio/dsound.h"
|
||||
#include "../audio/dsound.cpp"
|
||||
#endif
|
||||
|
||||
#include "../input/sdl.h"
|
||||
#include "../input/sdl.cpp"
|
||||
|
||||
void alert(char *s, ...) {
|
||||
char str[4096];
|
||||
va_list args;
|
||||
va_start(args, s);
|
||||
vsprintf(str, s, args);
|
||||
va_end(args);
|
||||
#ifdef PLATFORM_WIN
|
||||
MessageBox(0, str, "bsnes", MB_OK);
|
||||
#else
|
||||
fprintf(stdout, "%s\r\n", str);
|
||||
#endif
|
||||
}
|
||||
|
||||
void dprintf(char *s, ...) {
|
||||
char str[4096];
|
||||
va_list args;
|
||||
va_start(args, s);
|
||||
vsprintf(str, s, args);
|
||||
va_end(args);
|
||||
fprintf(stdout, "%s\r\n", str);
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_WIN
|
||||
int __stdcall WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) {
|
||||
int argc = __argc;
|
||||
char **argv = __argv;
|
||||
#else
|
||||
int main(int argc, char *argv[]) {
|
||||
#endif
|
||||
gtk_init(&argc, &argv);
|
||||
init_main_window();
|
||||
|
||||
config_file.load("bsnes.cfg");
|
||||
init_snes();
|
||||
uiVideo = new VideoSDL((void*)GDK_WINDOW_XWINDOW(main_window.render->window));
|
||||
uiAudio = new Audio();
|
||||
uiInput = new InputSDL((void*)GDK_WINDOW_XWINDOW(main_window.render->window));
|
||||
uiVideo->init();
|
||||
uiAudio->init();
|
||||
uiInput->init();
|
||||
|
||||
//will not run if cartridge not loaded
|
||||
bsnes->set_status(bSNES::RUN);
|
||||
|
||||
if(argc >= 2 && cartridge.load(argv[1]) == true) {
|
||||
snes->power();
|
||||
}
|
||||
|
||||
while(running == true) {
|
||||
bsnes->run();
|
||||
|
||||
while(gtk_events_pending() == true) {
|
||||
gtk_main_iteration_do(false);
|
||||
}
|
||||
|
||||
SDL_Event event;
|
||||
while(SDL_PollEvent(&event)) {
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
config_file.save("bsnes.cfg");
|
||||
cartridge.unload();
|
||||
uiVideo->term();
|
||||
uiAudio->term();
|
||||
uiInput->term();
|
||||
SafeDelete(uiVideo);
|
||||
SafeDelete(uiAudio);
|
||||
SafeDelete(uiInput);
|
||||
term_snes();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
#include <gdk/gdkx.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
bool running = true; //set to false to terminate main program loop
|
|
@ -16,7 +16,7 @@ struct joypad {
|
|||
keymap key; //this must be initialized by init()
|
||||
bool8 keystate[4096];
|
||||
|
||||
virtual void poll() = 0;
|
||||
virtual void poll() {}
|
||||
virtual void poll(uint8 device);
|
||||
virtual void init();
|
||||
virtual void term();
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
void InputSDL::poll(uint8 device) {
|
||||
Input::poll(device);
|
||||
}
|
||||
|
||||
void InputSDL::poll() {
|
||||
memcpy(keystate, SDL_GetKeyState(0), SDLK_LAST);
|
||||
}
|
||||
|
||||
void InputSDL::init() {
|
||||
#include "sdl_keymap.cpp"
|
||||
Input::init();
|
||||
}
|
||||
|
||||
void InputSDL::term() {
|
||||
Input::term();
|
||||
}
|
||||
|
||||
InputSDL::InputSDL(void *handle) {
|
||||
window = handle;
|
||||
|
||||
//
|
||||
//SDL hack
|
||||
//Put SDL output into main GTK+ window, rather than
|
||||
//creating a new window for SDL output.
|
||||
//
|
||||
if(window) {
|
||||
char t[64];
|
||||
sprintf(t, "SDL_WINDOWID=%ld", window);
|
||||
#if defined(COMPILER_GCC)
|
||||
putenv(t);
|
||||
#elif defined(COMPILER_VISUALC)
|
||||
_putenv(t);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
InputSDL::~InputSDL() {}
|
|
@ -0,0 +1,13 @@
|
|||
class InputSDL : public Input {
|
||||
private:
|
||||
void *window;
|
||||
|
||||
public:
|
||||
void poll();
|
||||
void poll(uint8 device);
|
||||
void init();
|
||||
void term();
|
||||
|
||||
InputSDL(void *handle = 0);
|
||||
~InputSDL();
|
||||
};
|
|
@ -0,0 +1,37 @@
|
|||
key.esc = SDLK_ESCAPE;
|
||||
|
||||
key.up = SDLK_UP;
|
||||
key.down = SDLK_DOWN;
|
||||
key.left = SDLK_LEFT;
|
||||
key.right = SDLK_RIGHT;
|
||||
|
||||
key.a = SDLK_a;
|
||||
key.b = SDLK_b;
|
||||
key.c = SDLK_c;
|
||||
key.d = SDLK_d;
|
||||
key.e = SDLK_e;
|
||||
key.f = SDLK_f;
|
||||
key.g = SDLK_g;
|
||||
key.h = SDLK_h;
|
||||
key.i = SDLK_i;
|
||||
key.j = SDLK_j;
|
||||
key.k = SDLK_k;
|
||||
key.l = SDLK_l;
|
||||
key.m = SDLK_m;
|
||||
key.n = SDLK_n;
|
||||
key.o = SDLK_o;
|
||||
key.p = SDLK_p;
|
||||
key.q = SDLK_q;
|
||||
key.r = SDLK_r;
|
||||
key.s = SDLK_s;
|
||||
key.t = SDLK_t;
|
||||
key.u = SDLK_u;
|
||||
key.v = SDLK_v;
|
||||
key.w = SDLK_w;
|
||||
key.x = SDLK_x;
|
||||
key.y = SDLK_y;
|
||||
key.z = SDLK_z;
|
||||
|
||||
key.lshift = SDLK_LSHIFT;
|
||||
key.rshift = SDLK_RSHIFT;
|
||||
key.enter = SDLK_RETURN;
|
|
@ -22,9 +22,11 @@ void term_snes();
|
|||
* platform abstraction layer
|
||||
*****/
|
||||
|
||||
#if defined(PLATFORM_WIN)
|
||||
#if defined(UI_WIN)
|
||||
#include "win/main.cpp"
|
||||
#elif defined(PLATFORM_SDL)
|
||||
#elif defined(UI_GTK)
|
||||
#include "gtk/main.cpp"
|
||||
#elif defined(UI_SDL)
|
||||
#include "sdl/main.cpp"
|
||||
#else
|
||||
#error "unsupported platform"
|
||||
|
|
|
@ -22,7 +22,9 @@ void bSNES::video_run() {
|
|||
render();
|
||||
}
|
||||
|
||||
void bSNES::sound_run(uint32 data) {}
|
||||
void bSNES::sound_run(uint32 data) {
|
||||
uiAudio->run(data);
|
||||
}
|
||||
|
||||
uint16 *bSNES::video_lock(uint &pitch) {
|
||||
if(SDL_MUSTLOCK(screen)) {
|
||||
|
@ -49,57 +51,12 @@ void bSNES::video_unlock() {
|
|||
*** Input functions ***
|
||||
***********************/
|
||||
|
||||
//It would appear that keystate does not need to be released
|
||||
//after calling SDL_GetKeyState... doing so causes libSDL
|
||||
//to throw error messages about a bad free call to stdout...
|
||||
void bSNES::poll_input(uint8 type) {
|
||||
uint8 *keystate = SDL_GetKeyState(0);
|
||||
joypad1.up = keystate[(int)config::input.joypad1.up];
|
||||
joypad1.down = keystate[(int)config::input.joypad1.down];
|
||||
joypad1.left = keystate[(int)config::input.joypad1.left];
|
||||
joypad1.right = keystate[(int)config::input.joypad1.right];
|
||||
joypad1.select = keystate[(int)config::input.joypad1.select];
|
||||
joypad1.start = keystate[(int)config::input.joypad1.start];
|
||||
joypad1.y = keystate[(int)config::input.joypad1.y];
|
||||
joypad1.b = keystate[(int)config::input.joypad1.b];
|
||||
joypad1.x = keystate[(int)config::input.joypad1.x];
|
||||
joypad1.a = keystate[(int)config::input.joypad1.a];
|
||||
joypad1.l = keystate[(int)config::input.joypad1.l];
|
||||
joypad1.r = keystate[(int)config::input.joypad1.r];
|
||||
|
||||
//It's impossible to hold both up+down, or left+right down
|
||||
//at the same time on a directional pad; and besides, allowing
|
||||
//this to happen causes glitches in many SNES games.
|
||||
if(joypad1.up) joypad1.down = 0;
|
||||
if(joypad1.left)joypad1.right = 0;
|
||||
uiInput->poll(type);
|
||||
}
|
||||
|
||||
bool bSNES::get_input_status(uint8 device, uint8 button) {
|
||||
switch(device) {
|
||||
case DEV_JOYPAD1:
|
||||
switch(button) {
|
||||
case JOYPAD_UP: return joypad1.up;
|
||||
case JOYPAD_DOWN: return joypad1.down;
|
||||
case JOYPAD_LEFT: return joypad1.left;
|
||||
case JOYPAD_RIGHT: return joypad1.right;
|
||||
case JOYPAD_A: return joypad1.a;
|
||||
case JOYPAD_B: return joypad1.b;
|
||||
case JOYPAD_X: return joypad1.x;
|
||||
case JOYPAD_Y: return joypad1.y;
|
||||
case JOYPAD_L: return joypad1.l;
|
||||
case JOYPAD_R: return joypad1.r;
|
||||
case JOYPAD_SELECT:return joypad1.select;
|
||||
case JOYPAD_START: return joypad1.start;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bJoypad::bJoypad() {
|
||||
up = down = left = right = false;
|
||||
a = b = x = y = false;
|
||||
l = r = select = start = false;
|
||||
return uiInput->get_status(device, button);
|
||||
}
|
||||
|
||||
void bSNES::notify(uint32 message, uint32 param1, uint32 param2) {}
|
||||
|
|
|
@ -1,15 +1,6 @@
|
|||
class bJoypad {
|
||||
public:
|
||||
bool up, down, left, right;
|
||||
bool a, b, x, y;
|
||||
bool l, r, select, start;
|
||||
bJoypad();
|
||||
};
|
||||
|
||||
class bSNES : public SNES {
|
||||
private:
|
||||
uint32 run_status;
|
||||
bJoypad joypad1, joypad2;
|
||||
|
||||
public:
|
||||
enum { STOP = 0, RUN };
|
||||
|
|
|
@ -4,13 +4,21 @@
|
|||
#include "render.cpp"
|
||||
#include "bsnes.cpp"
|
||||
|
||||
#ifdef PLATFORM_WIN
|
||||
#include "../audio/dsound.h"
|
||||
#include "../audio/dsound.cpp"
|
||||
#endif
|
||||
|
||||
#include "../input/sdl.h"
|
||||
#include "../input/sdl.cpp"
|
||||
|
||||
void alert(char *s, ...) {
|
||||
char str[4096];
|
||||
va_list args;
|
||||
va_start(args, s);
|
||||
vsprintf(str, s, args);
|
||||
va_end(args);
|
||||
#ifdef _WIN32
|
||||
#ifdef PLATFORM_WIN
|
||||
MessageBox(0, str, "bsnes", MB_OK);
|
||||
#else
|
||||
fprintf(stdout, "%s\r\n", str);
|
||||
|
@ -27,7 +35,7 @@ va_list args;
|
|||
}
|
||||
|
||||
void center_window() {
|
||||
#ifdef _WIN32
|
||||
#ifdef PLATFORM_WIN
|
||||
HWND hwnd;
|
||||
RECT rc;
|
||||
int x, y;
|
||||
|
@ -39,13 +47,13 @@ int x, y;
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef PLATFORM_WIN
|
||||
int __stdcall WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) {
|
||||
int argc = __argc;
|
||||
char **argv = __argv;
|
||||
SDL_SetModuleHandle(GetModuleHandle(0));
|
||||
#else
|
||||
int SDL_main(int argc, char *argv[]) {
|
||||
int main(int argc, char *argv[]) {
|
||||
#endif
|
||||
|
||||
SDL_Event event;
|
||||
|
@ -59,6 +67,15 @@ SDL_Event event;
|
|||
|
||||
init_snes();
|
||||
|
||||
#ifdef PLATFORM_WIN
|
||||
uiAudio = new AudioDS();
|
||||
#else
|
||||
uiAudio = new Audio();
|
||||
#endif
|
||||
uiInput = new InputSDL();
|
||||
uiAudio->init();
|
||||
uiInput->init();
|
||||
|
||||
if(cartridge.load(argv[1]) == false) {
|
||||
alert("Failed to load image. Usage: bsnes_sdl <filename.smc>");
|
||||
goto _end;
|
||||
|
@ -73,7 +90,7 @@ SDL_Event event;
|
|||
screen_rect.h = 224;
|
||||
|
||||
screen = SDL_SetVideoMode(screen_rect.w, screen_rect.h, 16,
|
||||
SDL_HWSURFACE | ((config::video.fullscreen) ? SDL_FULLSCREEN : 0));
|
||||
SDL_HWSURFACE | (0 ? SDL_FULLSCREEN : 0));
|
||||
if(!screen) { alert("Failed to initialize SDL"); goto _end; }
|
||||
|
||||
backbuffer = SDL_CreateRGBSurface(SDL_HWSURFACE, 512, 448, 16, 0xf800, 0x07e0, 0x001f, 0x0000);
|
||||
|
@ -115,6 +132,10 @@ int cursor_status;
|
|||
_end:
|
||||
config_file.save("bsnes_sdl.cfg");
|
||||
cartridge.unload();
|
||||
uiAudio->term();
|
||||
uiInput->term();
|
||||
SafeDelete(uiAudio);
|
||||
SafeDelete(uiInput);
|
||||
term_snes();
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#ifdef _WIN32
|
||||
#ifdef PLATFORM_WIN
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ HRESULT hr;
|
|||
presentation.Flags = D3DPRESENTFLAG_VIDEO;
|
||||
presentation.SwapEffect = (settings.triple_buffering == true) ?
|
||||
D3DSWAPEFFECT_FLIP : D3DSWAPEFFECT_DISCARD;
|
||||
presentation.hDeviceWindow = wMain.hwnd;
|
||||
presentation.hDeviceWindow = hwnd;
|
||||
presentation.BackBufferCount = (settings.triple_buffering == true) ? 2 : 1;
|
||||
presentation.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||||
presentation.MultiSampleQuality = 0;
|
||||
|
@ -26,7 +26,7 @@ HRESULT hr;
|
|||
D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||
presentation.FullScreen_RefreshRateInHz = settings.refresh_rate;
|
||||
|
||||
if(bool(config::video.fullscreen) == false) {
|
||||
if(settings.fullscreen == false) {
|
||||
presentation.Windowed = true;
|
||||
presentation.BackBufferFormat = D3DFMT_UNKNOWN;
|
||||
presentation.BackBufferWidth = 0;
|
||||
|
@ -38,7 +38,7 @@ HRESULT hr;
|
|||
presentation.BackBufferHeight = settings.resolution_height;
|
||||
}
|
||||
|
||||
hr = lpd3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wMain.hwnd,
|
||||
hr = lpd3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
|
||||
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentation, &device);
|
||||
if(hr != D3D_OK) {
|
||||
alert("Failed to create Direct3D9 device");
|
||||
|
@ -328,6 +328,8 @@ void VideoD3D::update() {
|
|||
}
|
||||
|
||||
bool VideoD3D::capture_screenshot() {
|
||||
if(!d3dx || !pD3DXSaveSurfaceToFileA) { return false; }
|
||||
|
||||
//fill both backbuffers with currently rendered image
|
||||
redraw();
|
||||
redraw();
|
||||
|
@ -358,8 +360,7 @@ uint32 format;
|
|||
format = D3DXIFF_PNG;
|
||||
}
|
||||
|
||||
D3DXSaveSurfaceToFile(fn, static_cast<D3DXIMAGE_FILEFORMAT>(format),
|
||||
temp_surface, NULL, NULL);
|
||||
pD3DXSaveSurfaceToFileA(fn, format, temp_surface, NULL, NULL);
|
||||
temp_surface->Release();
|
||||
return true;
|
||||
}
|
||||
|
@ -379,7 +380,9 @@ void VideoD3D::term() {
|
|||
SafeRelease(lpd3d);
|
||||
}
|
||||
|
||||
VideoD3D::VideoD3D() {
|
||||
VideoD3D::VideoD3D(HWND handle) {
|
||||
hwnd = handle;
|
||||
|
||||
vertex_buffer = 0;
|
||||
surface = 0;
|
||||
texture = 0;
|
||||
|
@ -388,6 +391,56 @@ VideoD3D::VideoD3D() {
|
|||
scanline[2] = 0;
|
||||
device = 0;
|
||||
lpd3d = 0;
|
||||
|
||||
//Below code dynamically loads d3dx9 DLL at runtime
|
||||
//to map D3DXSaveSurfaceToFileA function, used to
|
||||
//capture screenshots.
|
||||
//
|
||||
//We are forced to link against this DLL dynamically
|
||||
//because Microsoft decided that releasing 10+ versions
|
||||
//of this DLL, all with different filenames, rather than
|
||||
//making one DLL that was backwards-compatible.
|
||||
//
|
||||
//As a result of this blatant stupidity, if the application
|
||||
//statically links against d3dx9.lib, then the application
|
||||
//will then *require* the version of the d3dx9 DLL included
|
||||
//with the DX9 SDK used to build said application.
|
||||
//
|
||||
//And since most end users generally have not downloaded
|
||||
//every single bimonthly DX9 update, the application will
|
||||
//completely fail to load when it cannot find said dx9 DLL.
|
||||
//
|
||||
//Hillariously enough, most (if not all) of the d3dx9
|
||||
//functionality appears to be backwards-compatible anyway,
|
||||
//including this function.
|
||||
//
|
||||
//Therefore, as a workaround, we search through all possible
|
||||
//DLL filenames. If a d3dx9 DLL is found, we dynamically map
|
||||
//the D3DXSaveSurfaceToFileA function. Otherwise, screenshot
|
||||
//support will fail silently.
|
||||
//
|
||||
//The benefit to this approach is that it allows all users
|
||||
//to run this application, without explicitly requiring said
|
||||
//d3dx9 DLL to run the application at all.
|
||||
|
||||
d3dx = 0;
|
||||
pD3DXSaveSurfaceToFileA = 0;
|
||||
|
||||
for(int i = 0; i < 256; i++) {
|
||||
char t[256];
|
||||
sprintf(t, "d3dx9_%d.dll", i);
|
||||
d3dx = LoadLibrary(t);
|
||||
if(d3dx) { break; }
|
||||
}
|
||||
if(!d3dx) { d3dx = LoadLibrary("d3dx9.dll"); }
|
||||
if(!d3dx) { return; }
|
||||
|
||||
pD3DXSaveSurfaceToFileA = (HRESULT(WINAPI*)(LPCSTR, DWORD, LPDIRECT3DSURFACE9, CONST PALETTEENTRY*, CONST RECT*))
|
||||
GetProcAddress(d3dx, "D3DXSaveSurfaceToFileA");
|
||||
}
|
||||
|
||||
VideoD3D::~VideoD3D() {
|
||||
if(d3dx)FreeLibrary(d3dx);
|
||||
}
|
||||
|
||||
#undef D3DVERTEX
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include <d3d9.h>
|
||||
#include <d3dx9.h>
|
||||
|
||||
class VideoD3D : public Video {
|
||||
public:
|
||||
HWND hwnd;
|
||||
LPDIRECT3D9 lpd3d;
|
||||
LPDIRECT3DDEVICE9 device;
|
||||
LPDIRECT3DVERTEXBUFFER9 vertex_buffer, *vertex_ptr;
|
||||
|
@ -14,6 +14,10 @@ D3DCAPS9 d3dcaps;
|
|||
LPDIRECT3DTEXTURE9 texture, scanline[3];
|
||||
LPDIRECT3DSURFACE9 surface, temp_surface;
|
||||
|
||||
HINSTANCE d3dx;
|
||||
HRESULT (WINAPI *pD3DXSaveSurfaceToFileA)(LPCSTR, DWORD, LPDIRECT3DSURFACE9, CONST PALETTEENTRY*, CONST RECT*);
|
||||
enum { D3DXIFF_BMP = 0, D3DXIFF_JPG = 1, D3DXIFF_PNG = 3 };
|
||||
|
||||
struct d3dvertex {
|
||||
float x, y, z, rhw; //screen coords
|
||||
uint32 color; //diffuse color
|
||||
|
@ -58,5 +62,6 @@ struct {
|
|||
void redraw();
|
||||
void update();
|
||||
|
||||
VideoD3D();
|
||||
VideoD3D(HWND handle = 0);
|
||||
~VideoD3D();
|
||||
};
|
||||
|
|
|
@ -7,17 +7,17 @@ bool VideoDD::update_video_profile() {
|
|||
lpdd->QueryInterface(IID_IDirectDraw7, (void**)&lpdd7);
|
||||
SafeRelease(lpdd);
|
||||
|
||||
if(bool(config::video.fullscreen) == true) {
|
||||
lpdd7->SetCooperativeLevel(wMain.hwnd, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE);
|
||||
if(settings.fullscreen == true) {
|
||||
lpdd7->SetCooperativeLevel(hwnd, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE);
|
||||
lpdd7->SetDisplayMode(settings.resolution_width, settings.resolution_height, 16, settings.refresh_rate, 0);
|
||||
} else {
|
||||
lpdd7->SetCooperativeLevel(wMain.hwnd, DDSCL_NORMAL);
|
||||
lpdd7->SetCooperativeLevel(hwnd, DDSCL_NORMAL);
|
||||
}
|
||||
|
||||
create_presentation();
|
||||
|
||||
lpdd7->CreateClipper(0, &clipper, 0);
|
||||
clipper->SetHWnd(0, wMain.hwnd);
|
||||
clipper->SetHWnd(0, hwnd);
|
||||
screen->SetClipper(clipper);
|
||||
|
||||
create_render_target();
|
||||
|
@ -101,7 +101,7 @@ DDBLTFX fx;
|
|||
backbuffer->Blt(0, 0, 0, DDBLT_WAIT | DDBLT_COLORFILL, &fx);
|
||||
surface->Blt (0, 0, 0, DDBLT_WAIT | DDBLT_COLORFILL, &fx);
|
||||
|
||||
if(bool(config::video.fullscreen) == true) {
|
||||
if(settings.fullscreen == true) {
|
||||
screen->Flip(0, DDFLIP_WAIT);
|
||||
backbuffer->Blt(0, 0, 0, DDBLT_WAIT | DDBLT_COLORFILL, &fx);
|
||||
screen->Flip(0, DDFLIP_WAIT);
|
||||
|
@ -113,7 +113,7 @@ void VideoDD::create_presentation() {
|
|||
memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
|
||||
ddsd.dwSize = sizeof(DDSURFACEDESC2);
|
||||
|
||||
if(bool(config::video.fullscreen) == true) {
|
||||
if(settings.fullscreen == true) {
|
||||
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
|
||||
ddsd.dwBackBufferCount = (settings.triple_buffering == true) ? 2 : 1;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
|
||||
|
@ -149,14 +149,14 @@ RECT rd, rs;
|
|||
snes->get_video_info(&vi);
|
||||
SetRect(&rs, 0, 0, vi.width, vi.height);
|
||||
|
||||
if(bool(config::video.fullscreen) == true) {
|
||||
if(settings.fullscreen == true) {
|
||||
SetRect(&rd, settings.rx, settings.ry, settings.rx + settings.rw, settings.ry + settings.rh);
|
||||
backbuffer->Blt(&rd, surface, &rs, DDBLT_WAIT, 0);
|
||||
hr = screen->Flip(0, DDFLIP_WAIT);
|
||||
} else {
|
||||
POINT p = { 0, 0 };
|
||||
ClientToScreen(wMain.hwnd, &p);
|
||||
GetClientRect(wMain.hwnd, &rd);
|
||||
ClientToScreen(hwnd, &p);
|
||||
GetClientRect(hwnd, &rd);
|
||||
OffsetRect(&rd, p.x, p.y);
|
||||
|
||||
hr = screen->Blt(&rd, surface, &rs, DDBLT_WAIT, 0);
|
||||
|
@ -184,7 +184,9 @@ void VideoDD::term() {
|
|||
SafeRelease(lpdd);
|
||||
}
|
||||
|
||||
VideoDD::VideoDD() {
|
||||
VideoDD::VideoDD(HWND handle) {
|
||||
hwnd = handle;
|
||||
|
||||
lpdd = 0;
|
||||
lpdd7 = 0;
|
||||
screen = 0;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
class VideoDD : public Video {
|
||||
private:
|
||||
HWND hwnd;
|
||||
LPDIRECTDRAW lpdd;
|
||||
LPDIRECTDRAW7 lpdd7;
|
||||
LPDIRECTDRAWSURFACE7 screen, backbuffer;
|
||||
|
@ -29,5 +30,5 @@ public:
|
|||
void redraw();
|
||||
void update();
|
||||
|
||||
VideoDD();
|
||||
VideoDD(HWND handle);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
//WARNING: GTK video renderer is currently broken
|
||||
//Renderer is displaying incorrect colors
|
||||
|
||||
uint16 *VideoGTK::lock(uint &pitch) {
|
||||
pitch = 512;
|
||||
return (uint16*)buffer;
|
||||
}
|
||||
|
||||
void VideoGTK::unlock() {}
|
||||
|
||||
void VideoGTK::redraw() {
|
||||
uint8 *dest = gdkbuffer;
|
||||
uint16 *src = buffer;
|
||||
uint z = 256 * 224;
|
||||
while(z--) {
|
||||
uint32 p = *src++;
|
||||
*(uint32*)dest = ((p & 0xf800) << 8) | ((p & 0x07e0) << 5) | ((p & 0x001f) << 3);
|
||||
dest += 3;
|
||||
}
|
||||
gdk_draw_rgb_image(GDK_DRAWABLE(widget->window), gc, 0, 0, 256, 224, GDK_RGB_DITHER_NONE, gdkbuffer, 768);
|
||||
}
|
||||
|
||||
void VideoGTK::update() { redraw(); }
|
||||
|
||||
void VideoGTK::init() {
|
||||
buffer = (uint16*)malloc(256 * 224 * 2);
|
||||
gdkbuffer = (uint8*) malloc(256 * 224 * 3);
|
||||
}
|
||||
|
||||
void VideoGTK::term() {
|
||||
SafeFree(buffer);
|
||||
SafeFree(gdkbuffer);
|
||||
}
|
||||
|
||||
VideoGTK::VideoGTK(GtkWidget *output_widget) {
|
||||
widget = output_widget;
|
||||
gc = gdk_gc_new(GDK_DRAWABLE(output_widget->window));
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#include <gtk/gtk.h>
|
||||
|
||||
class VideoGTK : public Video {
|
||||
private:
|
||||
GtkWidget *widget;
|
||||
GdkGC *gc;
|
||||
uint16 *buffer;
|
||||
uint8 *gdkbuffer;
|
||||
|
||||
public:
|
||||
uint16 *lock(uint &pitch);
|
||||
void unlock();
|
||||
|
||||
uint screen_width() { return 1152; }
|
||||
uint screen_height() { return 864; }
|
||||
|
||||
void redraw();
|
||||
void update();
|
||||
void init();
|
||||
void term();
|
||||
|
||||
VideoGTK(GtkWidget *output_widget);
|
||||
};
|
|
@ -0,0 +1,45 @@
|
|||
uint16 *VideoSDL::lock(uint &pitch) {
|
||||
if(SDL_MUSTLOCK(backbuffer)) { SDL_LockSurface(backbuffer); }
|
||||
pitch = backbuffer->pitch;
|
||||
return (uint16*)backbuffer->pixels;
|
||||
}
|
||||
|
||||
void VideoSDL::unlock() {
|
||||
if(SDL_MUSTLOCK(backbuffer)) { SDL_UnlockSurface(backbuffer); }
|
||||
}
|
||||
|
||||
void VideoSDL::redraw() {
|
||||
SDL_BlitSurface(backbuffer, 0, screen, 0);
|
||||
SDL_UpdateRect(screen, 0, 0, 256, 224);
|
||||
}
|
||||
|
||||
void VideoSDL::update() { redraw(); }
|
||||
|
||||
void VideoSDL::init() {
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
atexit(SDL_Quit);
|
||||
|
||||
screen = SDL_SetVideoMode(256, 224, 16, SDL_HWSURFACE);
|
||||
backbuffer = SDL_CreateRGBSurface(SDL_HWSURFACE, 512, 448, 16, 0xf800, 0x07e0, 0x001f, 0x0000);
|
||||
}
|
||||
|
||||
void VideoSDL::term() {}
|
||||
|
||||
VideoSDL::VideoSDL(void *handle) {
|
||||
window = handle;
|
||||
|
||||
//
|
||||
//SDL hack
|
||||
//Put SDL output into main GTK+ window, rather than
|
||||
//creating a new window for SDL output.
|
||||
//
|
||||
if(window) {
|
||||
char t[64];
|
||||
sprintf(t, "SDL_WINDOWID=%ld", window);
|
||||
#if defined(COMPILER_GCC)
|
||||
putenv(t);
|
||||
#elif defined(COMPILER_VISUALC)
|
||||
_putenv(t);
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#include <SDL.h>
|
||||
|
||||
class VideoSDL : public Video {
|
||||
private:
|
||||
void *window;
|
||||
SDL_Surface *screen, *backbuffer;
|
||||
|
||||
public:
|
||||
uint16 *lock(uint &pitch);
|
||||
void unlock();
|
||||
|
||||
uint screen_width() { return 1152; }
|
||||
uint screen_height() { return 864; }
|
||||
|
||||
void redraw();
|
||||
void update();
|
||||
void init();
|
||||
void term();
|
||||
|
||||
VideoSDL(void *handle = 0);
|
||||
};
|
|
@ -25,10 +25,11 @@ int i = 0;
|
|||
v->manual_render_size = strmatch(part[i++], "true");
|
||||
v->render_width = strdec(part[i++]);
|
||||
v->render_height = strdec(part[i++]);
|
||||
v->fullscreen = strmatch(part[i++], "true");
|
||||
v->triple_buffering = strmatch(part[i++], "true");
|
||||
v->resolution_width = strdec(part[i++]);
|
||||
v->resolution_height = strdec(part[i++]);
|
||||
v->refresh_rate = strdec(part[i++]);
|
||||
v->triple_buffering = strmatch(part[i++], "true");
|
||||
|
||||
if(v->render_width < 256)v->render_width = 256;
|
||||
if(v->render_height < 224)v->render_height = 224;
|
||||
|
@ -50,10 +51,11 @@ VideoSettings *v = &video_settings[profile];
|
|||
sprintf(part, "%s", v->manual_render_size ? "true" : "false"); strcat(line, part); strcat(line, ";");
|
||||
sprintf(part, "%d", v->render_width); strcat(line, part); strcat(line, ";");
|
||||
sprintf(part, "%d", v->render_height); strcat(line, part); strcat(line, ";");
|
||||
sprintf(part, "%s", v->fullscreen ? "true" : "false"); strcat(line, part); strcat(line, ";");
|
||||
sprintf(part, "%s", v->triple_buffering ? "true" : "false"); strcat(line, part); strcat(line, ";");
|
||||
sprintf(part, "%d", v->resolution_width); strcat(line, part); strcat(line, ";");
|
||||
sprintf(part, "%d", v->resolution_height); strcat(line, part); strcat(line, ";");
|
||||
sprintf(part, "%d", v->refresh_rate); strcat(line, part); strcat(line, ";");
|
||||
sprintf(part, "%s", v->triple_buffering ? "true" : "false"); strcat(line, part);
|
||||
sprintf(part, "%d", v->refresh_rate); strcat(line, part);
|
||||
|
||||
switch(profile) {
|
||||
case 0: config::video.profile_0.sset(strptr(line)); break;
|
||||
|
@ -90,11 +92,13 @@ VideoSettings *v = &video_settings[profile];
|
|||
}
|
||||
}
|
||||
|
||||
settings.hardware_filter = v->hardware_filter;
|
||||
settings.fullscreen = v->fullscreen;
|
||||
settings.triple_buffering = v->triple_buffering;
|
||||
|
||||
settings.hardware_filter = v->hardware_filter;
|
||||
settings.enable_scanlines = v->enable_scanlines;
|
||||
|
||||
if((bool)config::video.fullscreen == true) {
|
||||
if(v->fullscreen == true) {
|
||||
settings.resolution_width = (v->resolution_width) ? v->resolution_width : screen_width();
|
||||
settings.resolution_height = (v->resolution_height) ? v->resolution_height : screen_height();
|
||||
settings.refresh_rate = v->refresh_rate;
|
||||
|
|
|
@ -13,10 +13,11 @@ struct VideoSettings {
|
|||
bool manual_render_size;
|
||||
uint render_width;
|
||||
uint render_height;
|
||||
bool fullscreen;
|
||||
bool triple_buffering;
|
||||
uint resolution_width;
|
||||
uint resolution_height;
|
||||
uint refresh_rate;
|
||||
bool triple_buffering;
|
||||
} video_settings[8];
|
||||
|
||||
void load_video_settings(uint profile);
|
||||
|
@ -30,8 +31,10 @@ struct {
|
|||
uint render_width;
|
||||
uint render_height;
|
||||
|
||||
uint hardware_filter;
|
||||
bool fullscreen;
|
||||
bool triple_buffering;
|
||||
|
||||
uint hardware_filter;
|
||||
bool enable_scanlines;
|
||||
|
||||
uint resolution_width;
|
||||
|
@ -48,8 +51,8 @@ struct {
|
|||
virtual uint screen_width() = 0;
|
||||
virtual uint screen_height() = 0;
|
||||
|
||||
virtual bool update_video_profile() = 0;
|
||||
virtual void clear_video() = 0;
|
||||
virtual bool update_video_profile() { return true; }
|
||||
virtual void clear_video() {}
|
||||
|
||||
virtual void pause_enable() {}
|
||||
virtual void pause_disable() {}
|
||||
|
|
|
@ -55,7 +55,7 @@ uint8 r = 0x00;
|
|||
r = r_mem->read(addr);
|
||||
} break;
|
||||
case SPCRAM:
|
||||
r = r_apu->spcram_read(addr & 0xffff);
|
||||
r = r_apu->spcram[addr & 0xffff];
|
||||
break;
|
||||
case VRAM:
|
||||
r = r_ppu->vram_read(addr & 0xffff);
|
||||
|
@ -80,7 +80,7 @@ void Debugger::write(uint8 mode, uint32 addr, uint8 data) {
|
|||
r_mem->cart_write_protect(true);
|
||||
break;
|
||||
case SPCRAM:
|
||||
r_apu->spcram_write(addr & 0xffff, data);
|
||||
r_apu->spcram[addr & 0xffff] = data;
|
||||
break;
|
||||
case VRAM:
|
||||
r_ppu->vram_write(addr & 0xffff, data);
|
||||
|
|
|
@ -107,7 +107,7 @@ bool MemoryEditor::Event(EventInfo &info) {
|
|||
|
||||
case EVENT_CHANGED:
|
||||
case EVENT_CLICKED: {
|
||||
if(info.control == &Mode) {
|
||||
if(info.control == &Mode && info.event_id == EVENT_CHANGED) {
|
||||
switch(Mode.GetSelection()) {
|
||||
case 0:
|
||||
status.mode = Debugger::DRAM;
|
||||
|
@ -147,7 +147,7 @@ bool MemoryEditor::Event(EventInfo &info) {
|
|||
}
|
||||
|
||||
Refresh();
|
||||
} else if(info.control == &Goto) {
|
||||
} else if(info.control == &GotoAddr) {
|
||||
char t[16 + 1];
|
||||
GotoAddr.GetText(t, 16);
|
||||
status.addr = strhex(t) & status.mask;
|
||||
|
@ -247,9 +247,9 @@ void MemoryEditor::Setup() {
|
|||
SetWindowLong(View.hwnd, GWL_WNDPROC, (long)NSMemoryEditor::wndproc_new_memory_view);
|
||||
|
||||
Mode.Create(this, "visible", 405, 5, 90, 200, "DRAM|ROM|SRAM|SPCRAM|VRAM|OAM|CGRAM");
|
||||
GotoAddr.Create(this, "visible|edge", 405, 26, 55, 20, "000000");
|
||||
GotoLabel.Create(this, "visible", 405, 26 + 4, 35, 15, "Goto:");
|
||||
GotoAddr.Create(this, "visible|edge", 440, 26, 55, 20, "000000");
|
||||
GotoAddr.SetFont(global::fwf);
|
||||
Goto.Create(this, "visible", 460, 26, 35, 20, "Go");
|
||||
|
||||
OffsetLabel.Create(this, "visible", 405, 50, 90, 15, "Offset: Data:");
|
||||
Offset.Create(this, "visible|edge", 405, 65, 55, 20, "000000");
|
||||
|
|
|
@ -12,8 +12,8 @@ class MemoryEditor : public Window {
|
|||
public:
|
||||
Editbox View;
|
||||
Combobox Mode;
|
||||
Label GotoLabel;
|
||||
Editbox GotoAddr;
|
||||
Button Goto;
|
||||
Label OffsetLabel;
|
||||
Editbox Offset;
|
||||
Editbox Data;
|
||||
|
|
|
@ -30,7 +30,7 @@ void set_video_profile(uint profile) {
|
|||
uiVideo->update_video_settings();
|
||||
|
||||
string t;
|
||||
if(bool(config::video.fullscreen) == true) {
|
||||
if(uiVideo->settings.fullscreen == true) {
|
||||
strcpy(t, "topmost|popup");
|
||||
if(wMain.Visible())strcat(t, "|visible");
|
||||
wMain.HideMenu();
|
||||
|
@ -57,12 +57,21 @@ string t;
|
|||
}
|
||||
|
||||
void toggle_fullscreen() {
|
||||
config::video.fullscreen.toggle();
|
||||
if(bool(config::video.fullscreen) == true) {
|
||||
wSettings.Hide();
|
||||
wAbout.Hide();
|
||||
debugger.deactivate();
|
||||
bool fullscreen = !uiVideo->settings.fullscreen;
|
||||
uint i;
|
||||
for(i = 0; i < 8; i++) {
|
||||
if(video_settings[i].fullscreen == fullscreen)break;
|
||||
}
|
||||
|
||||
if(i <= 7) {
|
||||
if(fullscreen == true) {
|
||||
wSettings.Hide();
|
||||
wAbout.Hide();
|
||||
debugger.deactivate();
|
||||
}
|
||||
config::video.profile = i;
|
||||
}
|
||||
|
||||
event::set_video_profile(config::video.profile);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,13 +12,17 @@
|
|||
|
||||
#include "../video/d3d.h"
|
||||
#include "../video/ddraw.h"
|
||||
//#include "../video/sdl.h"
|
||||
#include "../audio/dsound.h"
|
||||
#include "../input/dinput.h"
|
||||
//#include "../input/sdl.h"
|
||||
|
||||
#include "../video/d3d.cpp"
|
||||
#include "../video/ddraw.cpp"
|
||||
//#include "../video/sdl.cpp"
|
||||
#include "../audio/dsound.cpp"
|
||||
#include "../input/dinput.cpp"
|
||||
//#include "../input/sdl.cpp"
|
||||
|
||||
#include "event.cpp"
|
||||
#include "ui.cpp"
|
||||
|
|
|
@ -85,7 +85,7 @@ int x = 15, y = 30;
|
|||
GammaSlider.SetPos(int32(config::snes.gamma));
|
||||
y += 75;
|
||||
|
||||
GammaRamp.Create(this, "visible", x, y, 475, 15, "Half Gamma Adjust (darkens image, helps prevent washed out colors)");
|
||||
GammaRamp.Create(this, "visible", x, y, 475, 15, "Half gamma adjust (darkens image, helps prevent washed out colors)");
|
||||
GammaRamp.Check(config::snes.gamma_ramp);
|
||||
y += 15;
|
||||
Sepia.Create(this, "visible", x, y, 475, 15, "Sepia");
|
||||
|
@ -94,7 +94,7 @@ int x = 15, y = 30;
|
|||
Grayscale.Create(this, "visible", x, y, 475, 15, "Grayscale");
|
||||
Grayscale.Check(config::snes.grayscale);
|
||||
y += 15;
|
||||
Invert.Create(this, "visible", x, y, 475, 15, "Invert Colors");
|
||||
Invert.Create(this, "visible", x, y, 475, 15, "Invert colors");
|
||||
Invert.Check(config::snes.invert);
|
||||
y += 20;
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@ bool VideoSettingsWindow::Event(EventInfo &info) {
|
|||
SaveSettings(VideoProfile.GetSelection());
|
||||
} else if(info.control == &SelectProfile) {
|
||||
event::set_video_profile(VideoProfile.GetSelection());
|
||||
} else if(info.control == &ManualRenderSize || info.control == &Fullscreen) {
|
||||
UpdateControls();
|
||||
}
|
||||
} break;
|
||||
|
||||
|
@ -17,6 +19,19 @@ bool VideoSettingsWindow::Event(EventInfo &info) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void VideoSettingsWindow::UpdateControls() {
|
||||
bool r = ManualRenderSize.Checked();
|
||||
Multiplier.Enable(!r);
|
||||
FixAspectRatio.Enable(!r);
|
||||
RenderWidth.Enable(r);
|
||||
RenderHeight.Enable(r);
|
||||
|
||||
r = Fullscreen.Checked();
|
||||
FullResWidth.Enable(r);
|
||||
FullResHeight.Enable(r);
|
||||
FullResHz.Enable(r);
|
||||
}
|
||||
|
||||
void VideoSettingsWindow::LoadSettings(uint profile) {
|
||||
load_video_settings(profile);
|
||||
|
||||
|
@ -30,10 +45,13 @@ VideoSettings *v = &video_settings[profile];
|
|||
ManualRenderSize.Check(v->manual_render_size);
|
||||
RenderWidth.SetText("%d", v->render_width);
|
||||
RenderHeight.SetText("%d", v->render_height);
|
||||
Fullscreen.Check(v->fullscreen);
|
||||
TripleBuffering.Check(v->triple_buffering);
|
||||
FullResWidth.SetText("%d", v->resolution_width);
|
||||
FullResHeight.SetText("%d", v->resolution_height);
|
||||
FullResHz.SetText("%d", v->refresh_rate);
|
||||
TripleBuffering.Check(v->triple_buffering);
|
||||
|
||||
UpdateControls();
|
||||
}
|
||||
|
||||
void VideoSettingsWindow::SaveSettings(uint profile) {
|
||||
|
@ -50,13 +68,14 @@ char t[64 + 1];
|
|||
v->render_width = strdec(t);
|
||||
RenderHeight.GetText(t, 64);
|
||||
v->render_height = strdec(t);
|
||||
v->fullscreen = Fullscreen.Checked();
|
||||
v->triple_buffering = TripleBuffering.Checked();
|
||||
FullResWidth.GetText(t, 64);
|
||||
v->resolution_width = strdec(t);
|
||||
FullResHeight.GetText(t, 64);
|
||||
v->resolution_height = strdec(t);
|
||||
FullResHz.GetText(t, 64);
|
||||
v->refresh_rate = strdec(t);
|
||||
v->triple_buffering = TripleBuffering.Checked();
|
||||
|
||||
//update config file line entry
|
||||
save_video_settings(profile);
|
||||
|
@ -107,9 +126,8 @@ int x = 15, y = 30;
|
|||
|
||||
FixAspectRatio.Create(this, "visible|auto", x, y, 460, 16, "Correct aspect ratio");
|
||||
Scanlines.Create(this, "visible|auto", x, y + 15, 460, 15, "Enable hardware scanlines");
|
||||
ManualRenderSize.Create(this, "visible|auto", x, y + 30, 460, 15,
|
||||
"Manual render screen size (ignores correct aspect ratio and multiplier settings)");
|
||||
y += 45;
|
||||
ManualRenderSize.Create(this, "visible|auto", x, y + 30, 460, 15, "Manual render screen size");
|
||||
y += 47;
|
||||
|
||||
RenderWidthLabel.Create(this, "visible", x, y + 3, 90, 15, "Render width:");
|
||||
RenderWidth.Create(this, "visible|edge", x + 90, y, 50, 20);
|
||||
|
@ -117,19 +135,20 @@ int x = 15, y = 30;
|
|||
RenderHeight.Create(this, "visible|edge", x + 240, y, 50, 20);
|
||||
y += 25;
|
||||
|
||||
Separator1.Create(this, "visible|sunken", x, y, 460, 3);
|
||||
Separator2.Create(this, "visible|sunken", x, y, 460, 3);
|
||||
y += 8;
|
||||
|
||||
Fullscreen.Create(this, "visible|auto", x, y, 460, 16, "Fullscreen");
|
||||
TripleBuffering.Create(this, "visible|auto", x, y + 15, 460, 15, "Triple buffering (buggy, causes sound desync)");
|
||||
y += 35;
|
||||
|
||||
FullResWidthLabel.Create(this, "visible", x, y + 3, 90, 15, "Resolution width:");
|
||||
FullResWidth.Create(this, "visible|edge", x + 90, y, 50, 20);
|
||||
FullResHeightLabel.Create(this, "visible", x + 150, y + 3, 90, 15, "Resolution height:");
|
||||
FullResHeight.Create(this, "visible|edge", x + 240, y, 50, 20);
|
||||
FullResHzLabel.Create(this, "visible", x + 300, y + 3, 70, 15, "Refresh rate:");
|
||||
FullResHz.Create(this, "visible|edge", x + 370, y, 50, 20);
|
||||
y += 22;
|
||||
|
||||
TripleBuffering.Create(this, "visible|auto", x, y, 460, 15, "Triple buffering (buggy, causes sound desync)");
|
||||
y += 20;
|
||||
y += 27;
|
||||
|
||||
ApplySettings.Create(this, "visible", x, y, 120, 25, "Apply settings");
|
||||
SelectProfile.Create(this, "visible", x + 125, y, 120, 25, "Set as active profile");
|
||||
|
|
|
@ -20,17 +20,19 @@ Editbox RenderWidth;
|
|||
Label RenderHeightLabel;
|
||||
Editbox RenderHeight;
|
||||
Label Separator2;
|
||||
Checkbox Fullscreen;
|
||||
Checkbox TripleBuffering;
|
||||
Label FullResWidthLabel;
|
||||
Editbox FullResWidth;
|
||||
Label FullResHeightLabel;
|
||||
Editbox FullResHeight;
|
||||
Label FullResHzLabel;
|
||||
Editbox FullResHz;
|
||||
Checkbox TripleBuffering;
|
||||
Button ApplySettings;
|
||||
Button SelectProfile;
|
||||
|
||||
bool Event(EventInfo &info);
|
||||
void UpdateControls();
|
||||
|
||||
void LoadSettings(uint profile);
|
||||
void SaveSettings(uint profile);
|
||||
|
|
|
@ -31,13 +31,28 @@ long height;
|
|||
init_settings();
|
||||
init_debugger();
|
||||
|
||||
if(strmatch(config::video.renderer.sget(), "dd")) {
|
||||
uiVideo = new VideoDD();
|
||||
if(!stricmp(config::system.video.sget(), "dd")) {
|
||||
uiVideo = new VideoDD(wMain.hwnd);
|
||||
//} else if(!stricmp(config::system.video.sget(), "sdl")) {
|
||||
// uiVideo = new VideoSDL((void*)wMain.hwnd);
|
||||
} else {
|
||||
uiVideo = new VideoD3D();
|
||||
uiVideo = new VideoD3D(wMain.hwnd);
|
||||
}
|
||||
uiAudio = new AudioDS();
|
||||
uiInput = new InputDI();
|
||||
|
||||
if(!stricmp(config::system.audio.sget(), "none")) {
|
||||
uiAudio = new Audio();
|
||||
} else {
|
||||
uiAudio = new AudioDS(wMain.hwnd);
|
||||
}
|
||||
|
||||
if(!stricmp(config::system.input.sget(), "none")) {
|
||||
uiInput = new Input();
|
||||
//} else if(!stricmp(config::system.input.sget(), "sdl")) {
|
||||
// uiInput = new InputSDL((void*)wMain.hwnd);
|
||||
} else {
|
||||
uiInput = new InputDI();
|
||||
}
|
||||
|
||||
uiVideo->init();
|
||||
uiAudio->init();
|
||||
uiInput->init();
|
||||
|
@ -56,6 +71,7 @@ void term_ui() {
|
|||
uiVideo->term();
|
||||
uiAudio->term();
|
||||
uiInput->term();
|
||||
|
||||
SafeDelete(uiVideo);
|
||||
SafeDelete(uiAudio);
|
||||
SafeDelete(uiInput);
|
||||
|
|
|
@ -45,12 +45,11 @@ bool MainWindow::Event(EventInfo &info) {
|
|||
uint id = info.control_id;
|
||||
bool ctrl = uiInput->keydown(key->lctrl) || uiInput->keydown(key->rctrl);
|
||||
if(id == key->esc) {
|
||||
if(bool(config::video.fullscreen) == false) {
|
||||
if(uiVideo->settings.fullscreen == false) {
|
||||
ShowMenu(!MenuVisible());
|
||||
Center();
|
||||
} else {
|
||||
config::video.fullscreen = false;
|
||||
event::set_video_profile(config::video.profile);
|
||||
event::toggle_fullscreen();
|
||||
}
|
||||
} else if(id == key->f11) {
|
||||
event::toggle_fullscreen();
|
||||
|
|
Loading…
Reference in New Issue