mirror of https://github.com/bsnes-emu/bsnes.git
Update to v073r04 release.
I've merged the bgameboy GUI into the bsnes project, as it's only ~3KB and it means I don't have to keep manually editing and copying two projects around. You can set ui := ui-gameboy to build bgameboy as a standalone, and ui := ui to build the bsnes you are used to. I will be polishing it to allow changing the binary output name, not building the SNES portions when not needed, etc in time. So that'll end bgameboy standalone releases, at least for now. If it ever gets important enough to split back out again I can, but I prefer it this way. bgameboy was never meant to be mainstream anyway, just a component for bsnes.
This commit is contained in:
parent
4dbce5a0b2
commit
1c6a8543cd
|
@ -94,6 +94,6 @@ clean: ui_clean
|
|||
-@$(call delete,*.manifest)
|
||||
|
||||
archive-all:
|
||||
tar -cjf bsnes.tar.bz2 data gameboy launcher libco nall obj out phoenix ruby snes ui Makefile cc.bat clean.bat sync.sh
|
||||
tar -cjf bsnes.tar.bz2 data gameboy launcher libco nall obj out phoenix ruby snes ui ui-gameboy Makefile cc.bat clean.bat sync.sh
|
||||
|
||||
help:;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
namespace SNES {
|
||||
namespace Info {
|
||||
static const char Name[] = "bsnes";
|
||||
static const char Version[] = "073.03";
|
||||
static const char Version[] = "073.04";
|
||||
static const unsigned SerializerVersion = 16;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,3 @@ test -d phoenix/nall && rm -r phoenix/nall
|
|||
rm -r phoenix/test*
|
||||
rm -r phoenix/*.sh
|
||||
rm -r phoenix/*.bat
|
||||
|
||||
test -d gameboy && rm -r gameboy
|
||||
cp -r ../bgameboy/gameboy ./gameboy
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
ui_objects := ui-main ui-utility
|
||||
ui_objects += ruby phoenix
|
||||
|
||||
# platform
|
||||
ifeq ($(platform),x)
|
||||
phoenix_compile = $(call compile,-DPHOENIX_GTK `pkg-config --cflags gtk+-2.0`)
|
||||
link += `pkg-config --libs gtk+-2.0`
|
||||
# phoenix_compile = $(call compile,-DPHOENIX_QT `pkg-config --cflags QtCore QtGui`)
|
||||
# link += `pkg-config --libs QtCore QtGui`
|
||||
|
||||
ruby := video.glx video.xv video.sdl
|
||||
ruby += audio.alsa audio.openal audio.oss audio.pulseaudio audio.pulseaudiosimple audio.ao
|
||||
ruby += input.sdl input.x
|
||||
|
||||
link += $(if $(findstring audio.openal,$(ruby)),-lopenal)
|
||||
else ifeq ($(platform),osx)
|
||||
phoenix_compile = $(call compile,-DPHOENIX_QT)
|
||||
link +=
|
||||
|
||||
ruby :=
|
||||
ruby += audio.openal
|
||||
ruby += input.carbon
|
||||
|
||||
link += $(if $(findstring audio.openal,$(ruby)),-framework OpenAL)
|
||||
else ifeq ($(platform),win)
|
||||
phoenix_compile = $(call compile,-DPHOENIX_WINDOWS)
|
||||
link +=
|
||||
|
||||
ruby := video.direct3d video.wgl video.directdraw video.gdi
|
||||
ruby += audio.directsound audio.xaudio2
|
||||
ruby += input.rawinput input.directinput
|
||||
|
||||
link += $(if $(findstring audio.openal,$(ruby)),-lopenal32)
|
||||
endif
|
||||
|
||||
# ruby
|
||||
rubyflags := $(if $(finstring .sdl,$(ruby)),`sdl-config --cflags`)
|
||||
|
||||
link += $(if $(findstring .sdl,$(ruby)),`sdl-config --libs`)
|
||||
link += $(if $(findstring video.direct3d,$(ruby)),-ld3d9)
|
||||
link += $(if $(findstring video.directdraw,$(ruby)),-lddraw)
|
||||
link += $(if $(findstring video.glx,$(ruby)),-lGL)
|
||||
link += $(if $(findstring video.wgl,$(ruby)),-lopengl32)
|
||||
link += $(if $(findstring video.xv,$(ruby)),-lXv)
|
||||
link += $(if $(findstring audio.alsa,$(ruby)),-lasound)
|
||||
link += $(if $(findstring audio.ao,$(ruby)),-lao)
|
||||
link += $(if $(findstring audio.directsound,$(ruby)),-ldsound)
|
||||
link += $(if $(findstring audio.pulseaudio,$(ruby)),-lpulse)
|
||||
link += $(if $(findstring audio.pulseaudiosimple,$(ruby)),-lpulse-simple)
|
||||
link += $(if $(findstring audio.xaudio2,$(ruby)),-lole32)
|
||||
link += $(if $(findstring input.directinput,$(ruby)),-ldinput8 -ldxguid)
|
||||
link += $(if $(findstring input.rawinput,$(ruby)),-ldinput8 -ldxguid)
|
||||
|
||||
rubydef := $(foreach c,$(subst .,_,$(call strupper,$(ruby))),-D$c)
|
||||
|
||||
# rules
|
||||
objects := $(ui_objects) $(objects)
|
||||
|
||||
obj/ui-main.o: $(ui)/main.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwildcard,$(ui)/*); $(phoenix_compile)
|
||||
obj/ui-utility.o: $(ui)/utility/utility.cpp $(call rwildcard,$(ui)/utility/*); $(phoenix_compile)
|
||||
|
||||
obj/ruby.o: ruby/ruby.cpp $(call rwildcard,ruby/*)
|
||||
$(call compile,$(rubydef) $(rubyflags))
|
||||
|
||||
obj/phoenix.o: phoenix/phoenix.cpp $(call rwildcard,phoenix/*)
|
||||
$(phoenix_compile)
|
||||
|
||||
# targets
|
||||
ui_build:;
|
||||
|
||||
ui_clean:;
|
|
@ -0,0 +1,32 @@
|
|||
#include <nall/file.hpp>
|
||||
#include <nall/foreach.hpp>
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/string.hpp>
|
||||
#include <nall/gameboy/cartridge.hpp>
|
||||
using namespace nall;
|
||||
|
||||
#include <ruby/ruby.hpp>
|
||||
using namespace ruby;
|
||||
|
||||
#include <phoenix/phoenix.hpp>
|
||||
using namespace phoenix;
|
||||
|
||||
#include <gameboy/gameboy.hpp>
|
||||
|
||||
#include "interface.hpp"
|
||||
|
||||
#include "general/main-window.hpp"
|
||||
|
||||
#include "utility/utility.hpp"
|
||||
|
||||
struct Application {
|
||||
bool quit;
|
||||
|
||||
Font proportionalFont;
|
||||
Font proportionalFontBold;
|
||||
Font monospaceFont;
|
||||
|
||||
void main(int argc, char **argv);
|
||||
};
|
||||
|
||||
extern Application application;
|
|
@ -0,0 +1,83 @@
|
|||
MainWindow mainWindow;
|
||||
|
||||
void MainWindow::create() {
|
||||
Window::create(128, 128, 160 * 2, 144 * 2, { GameBoy::Info::Name, " v", GameBoy::Info::Version });
|
||||
setDefaultFont(application.proportionalFont);
|
||||
setFont(application.proportionalFontBold);
|
||||
|
||||
system.create(*this, "System");
|
||||
systemLoadCartridge.create(system, "Load Cartridge ...");
|
||||
systemSeparator1.create(system);
|
||||
systemPower.create(system, "Power Cycle");
|
||||
|
||||
settings.create(*this, "Settings");
|
||||
settingsVideoSync.create(settings, "Synchronize Video");
|
||||
settingsVideoSync.setChecked(true);
|
||||
|
||||
tools.create(*this, "Tools");
|
||||
toolsSaveState.create(tools, "Save State");
|
||||
toolsSaveState1.create(toolsSaveState, "Slot 1");
|
||||
toolsSaveState2.create(toolsSaveState, "Slot 2");
|
||||
toolsSaveState3.create(toolsSaveState, "Slot 3");
|
||||
toolsSaveState4.create(toolsSaveState, "Slot 4");
|
||||
toolsSaveState5.create(toolsSaveState, "Slot 5");
|
||||
toolsLoadState.create(tools, "Load State");
|
||||
toolsLoadState1.create(toolsLoadState, "Slot 1");
|
||||
toolsLoadState2.create(toolsLoadState, "Slot 2");
|
||||
toolsLoadState3.create(toolsLoadState, "Slot 3");
|
||||
toolsLoadState4.create(toolsLoadState, "Slot 4");
|
||||
toolsLoadState5.create(toolsLoadState, "Slot 5");
|
||||
toolsSeparator1.create(tools);
|
||||
toolsTraceCPU.create(tools, "Trace CPU");
|
||||
|
||||
help.create(*this, "Help");
|
||||
helpAbout.create(help, "About ...");
|
||||
|
||||
viewport.create(*this, 0, 0, 160 * 2, 144 * 2);
|
||||
|
||||
setMenuVisible(true);
|
||||
setStatusVisible(true);
|
||||
|
||||
onClose = []() {
|
||||
application.quit = true;
|
||||
return false;
|
||||
};
|
||||
|
||||
systemLoadCartridge.onTick = []() {
|
||||
string filename = OS::fileOpen(mainWindow, "Game Boy cartridges\t*.gb,*.gbc", "/media/sdb1/root/gameboy_images/");
|
||||
if(filename != "") utility.loadCartridge(filename);
|
||||
};
|
||||
|
||||
systemPower.onTick = []() {
|
||||
if(GameBoy::cartridge.loaded()) GameBoy::system.power();
|
||||
};
|
||||
|
||||
settingsVideoSync.onTick = []() {
|
||||
video.set(Video::Synchronize, mainWindow.settingsVideoSync.checked());
|
||||
};
|
||||
|
||||
toolsSaveState1.onTick = []() { utility.saveState(1); };
|
||||
toolsSaveState2.onTick = []() { utility.saveState(2); };
|
||||
toolsSaveState3.onTick = []() { utility.saveState(3); };
|
||||
toolsSaveState4.onTick = []() { utility.saveState(4); };
|
||||
toolsSaveState5.onTick = []() { utility.saveState(5); };
|
||||
|
||||
toolsLoadState1.onTick = []() { utility.loadState(1); };
|
||||
toolsLoadState2.onTick = []() { utility.loadState(2); };
|
||||
toolsLoadState3.onTick = []() { utility.loadState(3); };
|
||||
toolsLoadState4.onTick = []() { utility.loadState(4); };
|
||||
toolsLoadState5.onTick = []() { utility.loadState(5); };
|
||||
|
||||
toolsTraceCPU.onTick = []() {
|
||||
GameBoy::cpu.trace = mainWindow.toolsTraceCPU.checked();
|
||||
};
|
||||
|
||||
helpAbout.onTick = []() {
|
||||
MessageWindow::information(mainWindow, {
|
||||
"bgameboy\n\n",
|
||||
"Version: ", GameBoy::Info::Version, "\n",
|
||||
"Author: byuu\n",
|
||||
"Homepage: http://byuu.org/"
|
||||
});
|
||||
};
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
struct MainWindow : Window {
|
||||
Menu system;
|
||||
MenuItem systemLoadCartridge;
|
||||
MenuSeparator systemSeparator1;
|
||||
MenuItem systemPower;
|
||||
|
||||
Menu settings;
|
||||
MenuCheckItem settingsVideoSync;
|
||||
|
||||
Menu tools;
|
||||
Menu toolsSaveState;
|
||||
MenuItem toolsSaveState1;
|
||||
MenuItem toolsSaveState2;
|
||||
MenuItem toolsSaveState3;
|
||||
MenuItem toolsSaveState4;
|
||||
MenuItem toolsSaveState5;
|
||||
Menu toolsLoadState;
|
||||
MenuItem toolsLoadState1;
|
||||
MenuItem toolsLoadState2;
|
||||
MenuItem toolsLoadState3;
|
||||
MenuItem toolsLoadState4;
|
||||
MenuItem toolsLoadState5;
|
||||
MenuSeparator toolsSeparator1;
|
||||
MenuCheckItem toolsTraceCPU;
|
||||
|
||||
Menu help;
|
||||
MenuItem helpAbout;
|
||||
|
||||
Viewport viewport;
|
||||
|
||||
void create();
|
||||
};
|
||||
|
||||
extern MainWindow mainWindow;
|
|
@ -0,0 +1,55 @@
|
|||
Interface interface;
|
||||
|
||||
void Interface::video_refresh(const uint8_t *data) {
|
||||
uint32_t *buffer;
|
||||
unsigned pitch;
|
||||
if(video.lock(buffer, pitch, 160, 144)) {
|
||||
for(unsigned y = 0; y < 144; y++) {
|
||||
uint32_t *line = buffer + y * (pitch >> 2);
|
||||
const uint8_t *source = data + y * 160;
|
||||
for(unsigned x = 0; x < 160; x++) {
|
||||
uint32_t color = *source++;
|
||||
*line++ = (color << 16) | (color << 8) | (color << 0);
|
||||
}
|
||||
}
|
||||
video.unlock();
|
||||
video.refresh();
|
||||
}
|
||||
|
||||
static unsigned frameCounter = 0;
|
||||
static time_t timeCounter = time(0);
|
||||
|
||||
frameCounter++;
|
||||
time_t currentTime = time(0);
|
||||
if(currentTime != timeCounter) {
|
||||
timeCounter = currentTime;
|
||||
mainWindow.setStatusText({ "FPS: ", frameCounter });
|
||||
frameCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Interface::audio_sample(signed left, signed right) {
|
||||
}
|
||||
|
||||
void Interface::input_poll() {
|
||||
input.poll(inputState);
|
||||
}
|
||||
|
||||
bool Interface::input_poll(unsigned id) {
|
||||
switch(id) {
|
||||
case GameBoy::Input::Up: return inputState[keyboard(0)[Keyboard::Up]];
|
||||
case GameBoy::Input::Down: return inputState[keyboard(0)[Keyboard::Down]];
|
||||
case GameBoy::Input::Left: return inputState[keyboard(0)[Keyboard::Left]];
|
||||
case GameBoy::Input::Right: return inputState[keyboard(0)[Keyboard::Right]];
|
||||
case GameBoy::Input::B: return inputState[keyboard(0)[Keyboard::Z]];
|
||||
case GameBoy::Input::A: return inputState[keyboard(0)[Keyboard::X]];
|
||||
case GameBoy::Input::Select: return inputState[keyboard(0)[Keyboard::Apostrophe]];
|
||||
case GameBoy::Input::Start: return inputState[keyboard(0)[Keyboard::Return]];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Interface::message(const string &text) {
|
||||
MessageWindow::information(mainWindow, text);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
struct Interface : public GameBoy::Interface {
|
||||
int16_t inputState[Scancode::Limit];
|
||||
|
||||
void video_refresh(const uint8_t *data);
|
||||
void audio_sample(signed left, signed right);
|
||||
void input_poll();
|
||||
bool input_poll(unsigned id);
|
||||
|
||||
void message(const string &text);
|
||||
};
|
||||
|
||||
extern Interface interface;
|
|
@ -0,0 +1,59 @@
|
|||
#include "base.hpp"
|
||||
Application application;
|
||||
|
||||
#include "interface.cpp"
|
||||
|
||||
#include "general/main-window.cpp"
|
||||
|
||||
void Application::main(int argc, char **argv) {
|
||||
quit = false;
|
||||
|
||||
#if defined(PHOENIX_WINDOWS)
|
||||
proportionalFont.create("Tahoma", 8);
|
||||
proportionalFontBold.create("Tahoma", 8, Font::Style::Bold);
|
||||
monospaceFont.create("Courier New", 8);
|
||||
#else
|
||||
proportionalFont.create("Sans", 8);
|
||||
proportionalFontBold.create("Sans", 8, Font::Style::Bold);
|
||||
monospaceFont.create("Liberation Mono", 8);
|
||||
#endif
|
||||
|
||||
mainWindow.create();
|
||||
mainWindow.setVisible();
|
||||
OS::run();
|
||||
|
||||
#if defined(PHOENIX_WINDOWS)
|
||||
video.driver("Direct3D");
|
||||
#else
|
||||
video.driver("OpenGL");
|
||||
#endif
|
||||
video.set(Video::Handle, (uintptr_t)mainWindow.viewport.handle());
|
||||
video.set(Video::Synchronize, true);
|
||||
video.set(Video::Filter, (unsigned)0);
|
||||
video.init();
|
||||
|
||||
#if defined(PHOENIX_WINDOWS)
|
||||
input.driver("RawInput");
|
||||
#else
|
||||
input.driver("SDL");
|
||||
#endif
|
||||
input.set(Input::Handle, (uintptr_t)mainWindow.viewport.handle());
|
||||
input.init();
|
||||
|
||||
GameBoy::system.init(&interface);
|
||||
|
||||
while(quit == false) {
|
||||
OS::run();
|
||||
|
||||
if(GameBoy::cartridge.loaded()) {
|
||||
do {
|
||||
GameBoy::system.run();
|
||||
} while(GameBoy::scheduler.exit_reason() != GameBoy::Scheduler::ExitReason::FrameEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
application.main(argc, argv);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
#include "../base.hpp"
|
||||
Utility utility;
|
||||
|
||||
void Utility::loadCartridge(const char *filename) {
|
||||
file fp;
|
||||
if(fp.open(filename, file::mode::read)) {
|
||||
unsigned size = fp.size();
|
||||
uint8_t *data = new uint8_t[size];
|
||||
fp.read(data, size);
|
||||
fp.close();
|
||||
|
||||
cartridge.basename = nall::basename(filename);
|
||||
print(cartridge.basename, "\n");
|
||||
|
||||
GameBoyCartridge info(data, size);
|
||||
GameBoy::cartridge.load(info.xml, data, size);
|
||||
delete[] data;
|
||||
GameBoy::system.power();
|
||||
}
|
||||
}
|
||||
|
||||
bool Utility::saveState(unsigned slot) {
|
||||
GameBoy::system.runtosave();
|
||||
serializer s = GameBoy::system.serialize();
|
||||
|
||||
file fp;
|
||||
if(fp.open(string(cartridge.basename, "-", slot, ".bst"), file::mode::write)) {
|
||||
fp.write(s.data(), s.size());
|
||||
fp.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Utility::loadState(unsigned slot) {
|
||||
file fp;
|
||||
if(fp.open(string(cartridge.basename, "-", slot, ".bst"), file::mode::read)) {
|
||||
unsigned size = fp.size();
|
||||
uint8_t *data = new uint8_t[size];
|
||||
fp.read(data, size);
|
||||
fp.close();
|
||||
serializer s(data, size);
|
||||
return GameBoy::system.unserialize(s);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
struct Utility {
|
||||
struct Cartridge {
|
||||
string basename;
|
||||
} cartridge;
|
||||
|
||||
void loadCartridge(const char *filename);
|
||||
bool saveState(unsigned slot);
|
||||
bool loadState(unsigned slot);
|
||||
};
|
||||
|
||||
extern Utility utility;
|
Loading…
Reference in New Issue