diff --git a/bsnes/phoenix/gtk/font.cpp b/bsnes/phoenix/gtk/font.cpp index 7f8e5e5f..2ef52431 100755 --- a/bsnes/phoenix/gtk/font.cpp +++ b/bsnes/phoenix/gtk/font.cpp @@ -1,7 +1,7 @@ bool Font::create(const char *name, unsigned size, Font::Style style) { font->font = pango_font_description_new(); pango_font_description_set_family(font->font, name); - pango_font_description_set_absolute_size(font->font, size * PANGO_SCALE); + pango_font_description_set_size(font->font, size * PANGO_SCALE); pango_font_description_set_style(font->font, (style & Style::Italic) == Style::Italic ? PANGO_STYLE_OBLIQUE : PANGO_STYLE_NORMAL); pango_font_description_set_weight(font->font, (style & Style::Bold) == Style::Bold ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL); return true; diff --git a/bsnes/phoenix/gtk/gtk.hpp b/bsnes/phoenix/gtk/gtk.hpp index 5f0835f2..58560866 100755 --- a/bsnes/phoenix/gtk/gtk.hpp +++ b/bsnes/phoenix/gtk/gtk.hpp @@ -83,6 +83,7 @@ struct Window : Widget { nall::function onClose; void create(unsigned x, unsigned y, unsigned width, unsigned height, const char *text = ""); void setGeometry(unsigned x, unsigned y, unsigned width, unsigned height); + void setDefaultFont(Font &font); void setFont(Font &font); void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue); void setTitle(const char *text); @@ -148,6 +149,7 @@ struct HorizontalSlider : Widget { struct Label : Widget { void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = ""); + void setText(const char *text); }; struct ListBox : Widget { diff --git a/bsnes/phoenix/gtk/label.cpp b/bsnes/phoenix/gtk/label.cpp index 37db6f77..a5beedd5 100755 --- a/bsnes/phoenix/gtk/label.cpp +++ b/bsnes/phoenix/gtk/label.cpp @@ -1,7 +1,12 @@ void Label::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) { object->widget = gtk_label_new(text); - gtk_misc_set_alignment(GTK_MISC(object->widget), 0.0, 0.0); + gtk_misc_set_alignment(GTK_MISC(object->widget), 0.0, 0.5); gtk_widget_set_size_request(object->widget, width, height); + if(parent.window->defaultFont) setFont(*parent.window->defaultFont); gtk_fixed_put(GTK_FIXED(parent.object->formContainer), object->widget, x, y); gtk_widget_show(object->widget); } + +void Label::setText(const char *text) { + gtk_label_set_text(GTK_LABEL(object->widget), text); +} diff --git a/bsnes/phoenix/gtk/window.cpp b/bsnes/phoenix/gtk/window.cpp index 9b4c8519..378410b0 100755 --- a/bsnes/phoenix/gtk/window.cpp +++ b/bsnes/phoenix/gtk/window.cpp @@ -40,11 +40,14 @@ void Window::setGeometry(unsigned x, unsigned y, unsigned width, unsigned height gtk_widget_set_size_request(object->formContainer, width, height); } -void Window::setFont(Font &font) { - Widget::setFont(font); +void Window::setDefaultFont(Font &font) { window->defaultFont = &font; } +void Window::setFont(Font &font) { + Widget_setFont(object->status, font.font->font); +} + void Window::setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue) { GdkColor color; color.pixel = (red << 16) | (green << 8) | (blue << 0); diff --git a/bsnes/phoenix/windows/label.cpp b/bsnes/phoenix/windows/label.cpp index f6939273..d21850d7 100755 --- a/bsnes/phoenix/windows/label.cpp +++ b/bsnes/phoenix/windows/label.cpp @@ -1,6 +1,6 @@ void Label::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) { widget->window = CreateWindow( - L"STATIC", L"", + L"phoenix_label", L"", WS_CHILD | WS_VISIBLE, x, y, width, height, parent.widget->window, (HMENU)object->id, GetModuleHandle(0), 0 @@ -13,3 +13,53 @@ void Label::create(Window &parent, unsigned x, unsigned y, unsigned width, unsig void Label::setText(const char *text) { SetWindowText(widget->window, utf16_t(text)); } + +//all of this for want of a STATIC SS_VCENTER flag ... +LRESULT CALLBACK Label_WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { + Window *window_ptr = (Window*)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA); + if(!window_ptr) return DefWindowProc(hwnd, msg, wparam, lparam); + Label *label_ptr = (Label*)GetWindowLongPtr(hwnd, GWLP_USERDATA); + if(!label_ptr) return DefWindowProc(hwnd, msg, wparam, lparam); + Window &window = *window_ptr; + Label &label = *label_ptr; + + switch(msg) { + case WM_ERASEBKGND: { + if(window.window->brush == 0) break; + RECT rc; + GetClientRect(window.widget->window, &rc); + PAINTSTRUCT ps; + BeginPaint(window.widget->window, &ps); + FillRect(ps.hdc, &rc, window.window->brush); + EndPaint(window.widget->window, &ps); + return TRUE; + } + + case WM_PAINT: { + PAINTSTRUCT ps; + BeginPaint(hwnd, &ps); + SelectObject(ps.hdc, label.widget->font); + if(window.window->brush) { + SetBkColor(ps.hdc, window.window->brushColor); + } else { + SetBkColor(ps.hdc, GetSysColor(COLOR_3DFACE)); + } + RECT rc; + GetClientRect(hwnd, &rc); + unsigned length = GetWindowTextLength(hwnd) + 1; + wchar_t text[length]; + GetWindowText(hwnd, text, length + 1); + text[length] = 0; + DrawText(ps.hdc, text, -1, &rc, DT_CALCRECT | DT_END_ELLIPSIS); + unsigned height = rc.bottom; + GetClientRect(hwnd, &rc); + rc.top = (rc.bottom - height) / 2; + rc.bottom = rc.top + height; + DrawText(ps.hdc, text, -1, &rc, DT_LEFT | DT_END_ELLIPSIS); + EndPaint(hwnd, &ps); + InvalidateRect(hwnd, 0, false); + } + } + + return DefWindowProc(hwnd, msg, wparam, lparam); +} diff --git a/bsnes/phoenix/windows/object.cpp b/bsnes/phoenix/windows/object.cpp index 3bc4d87f..64e8ac87 100755 --- a/bsnes/phoenix/windows/object.cpp +++ b/bsnes/phoenix/windows/object.cpp @@ -16,6 +16,7 @@ struct Action::Data { struct Widget::Data { HWND window; + HFONT font; }; struct Window::Data { diff --git a/bsnes/phoenix/windows/phoenix-amd64.Manifest b/bsnes/phoenix/windows/phoenix-amd64.Manifest new file mode 100755 index 00000000..9be6de2b --- /dev/null +++ b/bsnes/phoenix/windows/phoenix-amd64.Manifest @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/bsnes/phoenix/windows/phoenix.Manifest b/bsnes/phoenix/windows/phoenix-x86.Manifest similarity index 100% rename from bsnes/phoenix/windows/phoenix.Manifest rename to bsnes/phoenix/windows/phoenix-x86.Manifest diff --git a/bsnes/phoenix/windows/phoenix.rc b/bsnes/phoenix/windows/phoenix.rc index 89fb8dc2..e511903c 100755 --- a/bsnes/phoenix/windows/phoenix.rc +++ b/bsnes/phoenix/windows/phoenix.rc @@ -1 +1,7 @@ -1 24 "phoenix.Manifest" +#ifdef ARCH_X86 +1 24 "phoenix-x86.Manifest" +#endif + +#ifdef ARCH_AMD64 +1 24 "phoenix-amd64.Manifest" +#endif diff --git a/bsnes/phoenix/windows/widget.cpp b/bsnes/phoenix/windows/widget.cpp index f724dd0c..439d761a 100755 --- a/bsnes/phoenix/windows/widget.cpp +++ b/bsnes/phoenix/windows/widget.cpp @@ -1,4 +1,5 @@ void Widget::setFont(Font &font) { + widget->font = font.font->font; SendMessage(widget->window, WM_SETFONT, (WPARAM)font.font->font, 0); } @@ -31,4 +32,5 @@ Widget::Widget() { os.objects.append(this); widget = new Widget::Data; widget->window = 0; + widget->font = os.os->proportionalFont; } diff --git a/bsnes/phoenix/windows/window.cpp b/bsnes/phoenix/windows/window.cpp index d671f3ef..2cab0ad9 100755 --- a/bsnes/phoenix/windows/window.cpp +++ b/bsnes/phoenix/windows/window.cpp @@ -18,8 +18,11 @@ void Window::create(unsigned x, unsigned y, unsigned width, unsigned height, con SetWindowLongPtr(widget->window, GWLP_USERDATA, (LONG_PTR)this); } -void Window::setFont(Font &font) { +void Window::setDefaultFont(Font &font) { window->defaultFont = font.font->font; +} + +void Window::setFont(Font &font) { SendMessage(window->status, WM_SETFONT, (WPARAM)window->defaultFont, 0); } diff --git a/bsnes/phoenix/windows/windows.cpp b/bsnes/phoenix/windows/windows.cpp index 8f0fa83f..97194fcc 100755 --- a/bsnes/phoenix/windows/windows.cpp +++ b/bsnes/phoenix/windows/windows.cpp @@ -214,7 +214,7 @@ static LRESULT CALLBACK OS_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM FillRect(ps.hdc, &rc, window.window->brush); EndPaint(window.widget->window, &ps); return TRUE; - }; + } case WM_CTLCOLORBTN: case WM_CTLCOLORSTATIC: { @@ -378,13 +378,25 @@ OS::OS() { wc.cbWndExtra = 0; wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1); wc.hCursor = LoadCursor(0, IDC_ARROW); - wc.hIcon = LoadIcon(0, IDI_APPLICATION); + wc.hIcon = LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(2)); wc.hInstance = GetModuleHandle(0); wc.lpfnWndProc = OS_windowProc; wc.lpszClassName = L"phoenix_window"; wc.lpszMenuName = 0; wc.style = CS_HREDRAW | CS_VREDRAW; RegisterClass(&wc); + + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1); + wc.hCursor = LoadCursor(0, IDC_ARROW); + wc.hIcon = LoadIcon(0, IDI_APPLICATION); + wc.hInstance = GetModuleHandle(0); + wc.lpfnWndProc = Label_WindowProc; + wc.lpszClassName = L"phoenix_label"; + wc.lpszMenuName = 0; + wc.style = CS_HREDRAW | CS_VREDRAW; + RegisterClass(&wc); } } diff --git a/bsnes/phoenix/windows/windows.hpp b/bsnes/phoenix/windows/windows.hpp index 78329cc6..63223e75 100755 --- a/bsnes/phoenix/windows/windows.hpp +++ b/bsnes/phoenix/windows/windows.hpp @@ -94,6 +94,7 @@ struct Window : Widget { static Window None; nall::function onClose; void create(unsigned x, unsigned y, unsigned width, unsigned height, const char *text = ""); + void setDefaultFont(Font &font); void setFont(Font &font); void setGeometry(unsigned x, unsigned y, unsigned width, unsigned height); void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue); diff --git a/bsnes/snes/snes.hpp b/bsnes/snes/snes.hpp index c6067666..92c662ea 100755 --- a/bsnes/snes/snes.hpp +++ b/bsnes/snes/snes.hpp @@ -1,7 +1,7 @@ namespace SNES { namespace Info { static const char Name[] = "bsnes"; - static const char Version[] = "068.18"; + static const char Version[] = "068.19"; static const unsigned SerializerVersion = 13; } } diff --git a/bsnes/ui-phoenix/Makefile b/bsnes/ui-phoenix/Makefile index 3d219c88..51791800 100755 --- a/bsnes/ui-phoenix/Makefile +++ b/bsnes/ui-phoenix/Makefile @@ -1,5 +1,6 @@ -ui_objects := ui-main ui-general ui-cartridge +ui_objects := ui-main ui-general ui-settings ui-utility ui-cartridge ui_objects += ruby phoenix +ui_objects += $(if $(call streq,$(platform),win),resource) # platform ifeq ($(platform),x) @@ -18,6 +19,7 @@ else ifeq ($(platform),osx) link += $(if $(findstring audio.openal,$(ruby)),-framework OpenAL) else ifeq ($(platform),win) + arch := -DARCH_X86 flags += -DPHOENIX_WINDOWS link += @@ -51,13 +53,20 @@ rubydef := $(foreach c,$(subst .,_,$(call strupper,$(ruby))),-D$c) # rules objects := $(ui_objects) $(objects) -obj/ui-main.o: $(ui)/main.cpp $(call rwildcard,$(ui)/*) -obj/ui-general.o: $(ui)/general/general.cpp $(call rwildcard,$(ui)/general/*) -obj/ui-cartridge.o: $(ui)/cartridge/cartridge.cpp $(call rwildcard,$(ui)/cartridge/*) +obj/ui-main.o: $(ui)/main.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwildcard,$(ui)/*) +obj/ui-general.o: $(ui)/general/general.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwildcard,$(ui)/general/*) +obj/ui-settings.o: $(ui)/settings/settings.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwildcard,$(ui)/settings/*) +obj/ui-utility.o: $(ui)/utility/utility.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwildcard,$(ui)/utility/*) +obj/ui-cartridge.o: $(ui)/cartridge/cartridge.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwildcard,$(ui)/cartridge/*) + obj/ruby.o: ruby/ruby.cpp $(call rwildcard,ruby/*) $(call compile,$(rubydef) $(rubyflags)) + obj/phoenix.o: phoenix/phoenix.cpp $(call rwildcard,phoenix/*) +obj/resource.o: $(ui)/resource.rc + windres $(ui)/resource.rc obj/resource.o $(arch) + # targets ui_build:; diff --git a/bsnes/ui-phoenix/base.hpp b/bsnes/ui-phoenix/base.hpp index 835c8f16..8a2647b1 100755 --- a/bsnes/ui-phoenix/base.hpp +++ b/bsnes/ui-phoenix/base.hpp @@ -15,11 +15,26 @@ using namespace phoenix; #include "interface.hpp" #include "general/general.hpp" +#include "settings/settings.hpp" +#include "utility/utility.hpp" #include "cartridge/cartridge.hpp" struct Application { + Font font; bool quit; void main(int argc, char **argv); }; extern Application application; + +struct Style { + enum : unsigned { + #if defined(PHOENIX_WINDOWS) + SliderHeight = 25, + #elif defined(PHOENIX_GTK) + SliderHeight = 22, + #elif defined(PHOENIX_QT) + SliderHeight = 22, + #endif + }; +}; diff --git a/bsnes/ui-phoenix/cartridge/cartridge.cpp b/bsnes/ui-phoenix/cartridge/cartridge.cpp index 3cb747d4..db37ec53 100755 --- a/bsnes/ui-phoenix/cartridge/cartridge.cpp +++ b/bsnes/ui-phoenix/cartridge/cartridge.cpp @@ -1,9 +1,25 @@ #include "../base.hpp" Cartridge cartridge; -bool Cartridge::loadNormal(string filename) { - if(file::exists(filename) == false) return false; +bool Cartridge::loadNormal(const char *filename) { + unload(); + if(loadCartridge(SNES::memory::cartrom, baseXML, baseName = filename) == false) return false; + SNES::cartridge.load(SNES::Cartridge::Mode::Normal, lstring() << baseXML); + loadMemory(SNES::memory::cartram, baseName, ".srm"); + loadMemory(SNES::memory::cartrtc, baseName, ".rtc"); + utility.setTitle(notdir(nall::basename(baseName))); + return true; +} +void Cartridge::unload() { + if(SNES::cartridge.loaded() == false) return; + saveMemory(SNES::memory::cartram, baseName, ".srm"); + saveMemory(SNES::memory::cartrtc, baseName, ".rtc"); + SNES::cartridge.unload(); +} + +bool Cartridge::loadCartridge(SNES::MappedRAM &memory, string &XML, const char *filename) { + if(file::exists(filename) == false) return false; file fp; if(fp.open(filename, file::mode_read) == false) return false; @@ -16,19 +32,30 @@ bool Cartridge::loadNormal(string filename) { fp.read(data, size); fp.close(); - SNES::memory::cartrom.copy(data, size); - - string baseXML = snes_information(data, size).xml_memory_map; - SNES::cartridge.load(SNES::Cartridge::Mode::Normal, lstring() << baseXML); + memory.copy(data, size); + XML = snes_information(data, size).xml_memory_map; delete[] data; - - filename = string(nall::basename(filename), ".srm"); - if(SNES::memory::cartram.size() && file::exists(filename)) { - if(fp.open(filename, file::mode_read)) { - fp.read(SNES::memory::cartram.data(), min(fp.size(), SNES::memory::cartram.size())); - fp.close(); - } - } - + return true; +} + +bool Cartridge::loadMemory(SNES::MappedRAM &memory, string filename, const char *extension) { + if(memory.size() == 0 || memory.size() == ~0) return true; + filename = string(nall::basename(filename), extension); + if(file::exists(filename) == false) return false; + file fp; + if(fp.open(filename, file::mode_read)) { + fp.read(memory.data(), min(memory.size(), fp.size())); + fp.close(); + } + return true; +} + +bool Cartridge::saveMemory(SNES::MappedRAM &memory, string filename, const char *extension) { + if(memory.size() == 0 || memory.size() == ~0) return true; + filename = string(nall::basename(filename), extension); + file fp; + if(fp.open(filename, file::mode_write) == false) return false; + fp.write(memory.data(), memory.size()); + fp.close(); return true; } diff --git a/bsnes/ui-phoenix/cartridge/cartridge.hpp b/bsnes/ui-phoenix/cartridge/cartridge.hpp index 58958c30..b27a4400 100755 --- a/bsnes/ui-phoenix/cartridge/cartridge.hpp +++ b/bsnes/ui-phoenix/cartridge/cartridge.hpp @@ -1,5 +1,14 @@ struct Cartridge { - bool loadNormal(string filename); + bool loadNormal(const char *filename); + void unload(); + +private: + string baseName, slotAName, slotBName; + string baseXML, slotAXML, slotBXML; + + bool loadCartridge(SNES::MappedRAM &memory, string &XML, const char *filename); + bool loadMemory(SNES::MappedRAM &memory, string filename, const char *extension); + bool saveMemory(SNES::MappedRAM &memory, string filename, const char *extension); }; extern Cartridge cartridge; diff --git a/bsnes/ui-phoenix/data/bsnes.ico b/bsnes/ui-phoenix/data/bsnes.ico new file mode 100755 index 00000000..54acded4 Binary files /dev/null and b/bsnes/ui-phoenix/data/bsnes.ico differ diff --git a/bsnes/ui-phoenix/general/main-window.cpp b/bsnes/ui-phoenix/general/main-window.cpp index c30838ea..6fdb492d 100755 --- a/bsnes/ui-phoenix/general/main-window.cpp +++ b/bsnes/ui-phoenix/general/main-window.cpp @@ -1,19 +1,39 @@ MainWindow mainWindow; void MainWindow::create() { - Window::create(256, 256, 595, 448, string(SNES::Info::Name, " v", SNES::Info::Version)); -//setBackgroundColor(0, 0, 0); + statusFont.create("Sans", 8, Font::Style::Bold); + Window::create(120, 120, 595, 448, string(SNES::Info::Name, " v", SNES::Info::Version)); + setDefaultFont(application.font); + setFont(statusFont); + setBackgroundColor(0, 0, 0); system.create(*this, "System"); + systemLoadCartridge.create(system, "Load Cartridge ..."); + systemSeparator.create(system); systemQuit.create(system, "Quit"); - systemQuit.onTick = []() { application.quit = true; }; setMenuVisible(true); settings.create(*this, "Settings"); + settingsVideo.create(settings, "Video Settings ..."); tools.create(*this, "Tools"); help.create(*this, "Help"); viewport.create(*this, 0, 0, 595, 448); setStatusVisible(true); - setVisible(true); - onClose = []() { application.quit = true; return false; }; + + systemLoadCartridge.onTick = []() { + utility.loadCartridgeNormal(); + }; + + systemQuit.onTick = []() { + application.quit = true; + }; + + settingsVideo.onTick = []() { + videoSettingsWindow.setVisible(); + }; + + onClose = []() { + application.quit = true; + return false; + }; } diff --git a/bsnes/ui-phoenix/general/main-window.hpp b/bsnes/ui-phoenix/general/main-window.hpp index 17dbc9fc..daa72dab 100755 --- a/bsnes/ui-phoenix/general/main-window.hpp +++ b/bsnes/ui-phoenix/general/main-window.hpp @@ -1,10 +1,13 @@ struct MainWindow : Window { + Font statusFont; Menu system; + MenuItem systemLoadCartridge; + MenuSeparator systemSeparator; MenuItem systemQuit; Menu settings; + MenuItem settingsVideo; Menu tools; Menu help; - Viewport viewport; void create(); diff --git a/bsnes/ui-phoenix/interface.cpp b/bsnes/ui-phoenix/interface.cpp index 3ccc9a64..faec8ab5 100755 --- a/bsnes/ui-phoenix/interface.cpp +++ b/bsnes/ui-phoenix/interface.cpp @@ -8,19 +8,66 @@ const uint8_t Palette::gammaRamp[32] = { 0xc8, 0xd0, 0xd8, 0xe0, 0xe8, 0xf0, 0xf8, 0xff, }; +uint8_t Palette::contrastAdjust(uint8_t input) { + signed contrast = Palette::contrast - 100; + signed result = input - contrast + (2 * contrast * input + 127) / 255; + return max(0, min(255, result)); +} + +uint8_t Palette::brightnessAdjust(uint8_t input) { + signed brightness = Palette::brightness - 100; + signed result = input + brightness; + return max(0, min(255, result)); +} + +uint8_t Palette::gammaAdjust(uint8_t input) { + signed result = (signed)(pow(((double)input / 255.0), (double)gamma / 100.0) * 255.0 + 0.5); + return max(0, min(255, result)); +} + void Palette::update() { for(unsigned i = 0; i < 32768; i++) { - unsigned r = gammaRamp[(i >> 10) & 31]; - unsigned g = gammaRamp[(i >> 5) & 31]; - unsigned b = gammaRamp[(i >> 0) & 31]; - //r = (r << 3) | (r >> 2); - //g = (g << 3) | (g >> 2); - //b = (b << 3) | (b >> 2); + unsigned r = (i >> 10) & 31; + unsigned g = (i >> 5) & 31; + unsigned b = (i >> 0) & 31; + + r = (r << 3) | (r >> 2); + g = (g << 3) | (g >> 2); + b = (b << 3) | (b >> 2); + + if(useGammaRamp) { + r = gammaRamp[r >> 3]; + g = gammaRamp[g >> 3]; + b = gammaRamp[b >> 3]; + } + + if(contrast != 100) { + r = contrastAdjust(r); + g = contrastAdjust(g); + b = contrastAdjust(b); + } + + if(brightness != 100) { + r = brightnessAdjust(r); + g = brightnessAdjust(g); + b = brightnessAdjust(b); + } + + if(gamma != 100) { + r = gammaAdjust(r); + g = gammaAdjust(g); + b = gammaAdjust(b); + } + color[i] = (r << 16) | (g << 8) | (b << 0); } } Palette::Palette() { + contrast = 100; + brightness = 100; + gamma = 100; + useGammaRamp = true; update(); } diff --git a/bsnes/ui-phoenix/interface.hpp b/bsnes/ui-phoenix/interface.hpp index d383b7d6..f12eca1a 100755 --- a/bsnes/ui-phoenix/interface.hpp +++ b/bsnes/ui-phoenix/interface.hpp @@ -1,6 +1,13 @@ struct Palette { static const uint8_t gammaRamp[32]; uint32_t color[32768]; + unsigned contrast; + unsigned brightness; + unsigned gamma; + bool useGammaRamp; + uint8_t contrastAdjust(uint8_t); + uint8_t brightnessAdjust(uint8_t); + uint8_t gammaAdjust(uint8_t); void update(); Palette(); }; diff --git a/bsnes/ui-phoenix/main.cpp b/bsnes/ui-phoenix/main.cpp index 3f1802ff..ea06263a 100755 --- a/bsnes/ui-phoenix/main.cpp +++ b/bsnes/ui-phoenix/main.cpp @@ -2,11 +2,29 @@ #include "interface.cpp" Application application; +#if defined(PLATFORM_WIN) +static string VideoDriver = "Direct3D"; +static string AudioDriver = "XAudio2"; +static string InputDriver = "RawInput"; +#elif defined(PLATFORM_X) +static string VideoDriver = "OpenGL"; +static string AudioDriver = "ALSA"; +static string InputDriver = "SDL"; +#endif + void Application::main(int argc, char **argv) { + #if defined(PHOENIX_WINDOWS) + font.create("Tahoma", 8); + #else + font.create("Sans", 8); + #endif + mainWindow.create(); + videoSettingsWindow.create(); + mainWindow.setVisible(); while(os.pending()) os.run(); - video.driver("OpenGL"); + video.driver(VideoDriver); video.set(Video::Handle, mainWindow.viewport.handle()); video.set(Video::Synchronize, false); video.set(Video::Filter, (unsigned)Video::FilterLinear); @@ -16,7 +34,7 @@ void Application::main(int argc, char **argv) { video.init(); } - audio.driver("ALSA"); + audio.driver(AudioDriver); audio.set(Audio::Handle, mainWindow.viewport.handle()); audio.set(Audio::Synchronize, false); audio.set(Audio::Frequency, (unsigned)32000); @@ -26,7 +44,7 @@ void Application::main(int argc, char **argv) { audio.init(); } - input.driver("SDL"); + input.driver(InputDriver); input.set(Input::Handle, mainWindow.viewport.handle()); if(input.init() == false) { MessageWindow::critical(mainWindow, "Failed to initialize input."); @@ -41,7 +59,7 @@ void Application::main(int argc, char **argv) { } while(quit == false) { - if(os.pending()) os.run(); + while(os.pending()) os.run(); if(SNES::cartridge.loaded()) { SNES::system.run(); @@ -50,6 +68,7 @@ void Application::main(int argc, char **argv) { } } + cartridge.unload(); mainWindow.setVisible(false); while(os.pending()) os.run(); SNES::system.term(); diff --git a/bsnes/ui-phoenix/resource.rc b/bsnes/ui-phoenix/resource.rc new file mode 100755 index 00000000..f8b1b389 --- /dev/null +++ b/bsnes/ui-phoenix/resource.rc @@ -0,0 +1,9 @@ +#ifdef ARCH_X86 +1 24 "../phoenix/windows/phoenix-x86.Manifest" +#endif + +#ifdef ARCH_AMD64 +1 24 "../phoenix/windows/phoenix-amd64.Manifest" +#endif + +2 ICON DISCARDABLE "data/bsnes.ico" diff --git a/bsnes/ui-phoenix/settings/settings.cpp b/bsnes/ui-phoenix/settings/settings.cpp new file mode 100755 index 00000000..81b4513d --- /dev/null +++ b/bsnes/ui-phoenix/settings/settings.cpp @@ -0,0 +1,2 @@ +#include "../base.hpp" +#include "video.cpp" diff --git a/bsnes/ui-phoenix/settings/settings.hpp b/bsnes/ui-phoenix/settings/settings.hpp new file mode 100755 index 00000000..1e7c33c5 --- /dev/null +++ b/bsnes/ui-phoenix/settings/settings.hpp @@ -0,0 +1 @@ +#include "video.hpp" diff --git a/bsnes/ui-phoenix/settings/video.cpp b/bsnes/ui-phoenix/settings/video.cpp new file mode 100755 index 00000000..97321f5c --- /dev/null +++ b/bsnes/ui-phoenix/settings/video.cpp @@ -0,0 +1,49 @@ +VideoSettingsWindow videoSettingsWindow; + +void VideoSettingsWindow::create() { + Window::create(0, 0, 256, 256, "Video Settings"); + setDefaultFont(application.font); + + unsigned x = 5, y = 5; + + contrastLabel.create (*this, x, y, 80, Style::SliderHeight, "Contrast:"); + contrastValue.create (*this, x + 80, y, 50, Style::SliderHeight, "100%"); + contrastSlider.create (*this, x + 130, y, 300, Style::SliderHeight, 201); y += Style::SliderHeight; + + brightnessLabel.create (*this, x, y, 80, Style::SliderHeight, "Brightness:"); + brightnessValue.create (*this, x + 80, y, 40, Style::SliderHeight, "100%"); + brightnessSlider.create(*this, x + 130, y, 300, Style::SliderHeight, 201); y += Style::SliderHeight; + + gammaLabel.create (*this, x, y, 80, Style::SliderHeight, "Gamma:"); + gammaValue.create (*this, x + 80, y, 50, Style::SliderHeight, "100%"); + gammaSlider.create (*this, x + 130, y, 300, Style::SliderHeight, 201); y += Style::SliderHeight + 5; + + gammaRampCheck.create (*this, x, y, 430, 15, "Enable NTSC gamma ramp simulation"); y += 15; + + setGeometry(0, 0, 440, y + 5); + + contrastSlider.setPosition(100); + brightnessSlider.setPosition(100); + gammaSlider.setPosition(100); + gammaRampCheck.setChecked(); + + contrastSlider.onChange = brightnessSlider.onChange = gammaSlider.onChange = gammaRampCheck.onTick = + { &VideoSettingsWindow::adjust, this }; + + onClose = []() { + videoSettingsWindow.setVisible(false); + return false; + }; +} + +void VideoSettingsWindow::adjust() { + contrastValue.setText(string(contrastSlider.position(), "%")); + brightnessValue.setText(string(brightnessSlider.position(), "%")); + gammaValue.setText(string(gammaSlider.position(), "%")); + + palette.contrast = contrastSlider.position(); + palette.brightness = brightnessSlider.position(); + palette.gamma = gammaSlider.position(); + palette.useGammaRamp = gammaRampCheck.checked(); + palette.update(); +} diff --git a/bsnes/ui-phoenix/settings/video.hpp b/bsnes/ui-phoenix/settings/video.hpp new file mode 100755 index 00000000..007894b5 --- /dev/null +++ b/bsnes/ui-phoenix/settings/video.hpp @@ -0,0 +1,17 @@ +struct VideoSettingsWindow : Window { + Label contrastLabel; + Label contrastValue; + HorizontalSlider contrastSlider; + Label brightnessLabel; + Label brightnessValue; + HorizontalSlider brightnessSlider; + Label gammaLabel; + Label gammaValue; + HorizontalSlider gammaSlider; + CheckBox gammaRampCheck; + + void create(); + void adjust(); +}; + +extern VideoSettingsWindow videoSettingsWindow; diff --git a/bsnes/ui-phoenix/utility/utility.cpp b/bsnes/ui-phoenix/utility/utility.cpp new file mode 100755 index 00000000..e1e8faf7 --- /dev/null +++ b/bsnes/ui-phoenix/utility/utility.cpp @@ -0,0 +1,18 @@ +#include "../base.hpp" +Utility utility; + +void Utility::setTitle(const char *text) { + if(*text) { + mainWindow.setTitle(string(text, " - ", SNES::Info::Name, " v", SNES::Info::Version)); + } else { + mainWindow.setTitle(string(SNES::Info::Name, " v", SNES::Info::Version)); + } +} + +void Utility::loadCartridgeNormal() { + string filename = os.fileOpen(mainWindow, "SNES cartridges\t*.sfc\nAll files\t*", "/media/sdb1/root/snes_roms"); + if(filename != "") { + cartridge.loadNormal(filename); + SNES::system.power(); + } +} diff --git a/bsnes/ui-phoenix/utility/utility.hpp b/bsnes/ui-phoenix/utility/utility.hpp new file mode 100755 index 00000000..9a25a7a1 --- /dev/null +++ b/bsnes/ui-phoenix/utility/utility.hpp @@ -0,0 +1,7 @@ +struct Utility { + void setTitle(const char *text); + + void loadCartridgeNormal(); +}; + +extern Utility utility;