From 6227974bf68907cbeef021ed03f07adb60463a32 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Sun, 18 Dec 2011 14:19:45 +1100 Subject: [PATCH] Update to v084r05 release. (note: before the post announcing this release, there had been a discussion of a performance optimisation that made the Super Scope emulation a lot faster, but caused problems for the Justifier perpheral) byuu says: Spent a good two hours trying things to no avail. I was trying to allow the CPU to run ahead, and sync on accesses to $4016/4017/4201/4213, but that doesn't work because the controllers have access to strobe IObit at will. The codebase is really starting to get difficult to work with. I am guessing because the days of massive development are long over, and the code is starting to age. Jonas' fix works 98% of the time, but there's still a few missed shots here and there. So that's not going to work either. So ... I give up. I've disabled the speed hack, so that it works 100% of the time. Did the same for the Super Scope: it may not have the same problem, but I like consistency and don't feel like taking the chance. This doesn't affect the mouse, since the mouse does not latch the counters to indicate its X/Y position. Speed hit is 92->82fps (accuracy profile), but only for Super Scope and Justifier games. But ... at least it works now. Slow and working is better than fast and broken. I appreciate the help in researching the issue, Jonas and krom. Also pulled in phoenix/Makefile, which simplifies ui/Makefile. Linux port defaults to GTK+ now. I can't get QGtkStyle to look good on Debian. --- bsnes/nall/Makefile | 3 + bsnes/nall/mosaic/context.hpp | 61 +++++++++++--- bsnes/nall/mosaic/parser.hpp | 30 ++++--- bsnes/phoenix/Makefile | 21 +++++ bsnes/phoenix/core/core.cpp | 10 ++- bsnes/phoenix/core/core.hpp | 20 ++--- bsnes/phoenix/gtk/platform.cpp | 21 ++--- .../gtk/widget/horizontal-scroll-bar.cpp | 2 +- .../phoenix/gtk/widget/horizontal-slider.cpp | 2 +- .../gtk/widget/vertical-scroll-bar.cpp | 2 +- bsnes/phoenix/gtk/widget/vertical-slider.cpp | 2 +- bsnes/phoenix/gtk/window.cpp | 5 ++ bsnes/phoenix/phoenix.hpp | 1 + bsnes/phoenix/qt/platform.moc | 2 +- bsnes/phoenix/qt/widget/canvas.cpp | 3 +- bsnes/phoenix/windows/platform.cpp | 51 +++++++++++- bsnes/ruby/Makefile | 6 +- bsnes/snes/controller/justifier/justifier.cpp | 79 +++++++++---------- bsnes/snes/controller/justifier/justifier.hpp | 8 +- .../snes/controller/superscope/superscope.cpp | 4 - bsnes/snes/system/video.cpp | 4 +- bsnes/ui/Makefile | 20 ++--- bsnes/ui/main.cpp | 2 +- 23 files changed, 241 insertions(+), 118 deletions(-) create mode 100755 bsnes/phoenix/Makefile diff --git a/bsnes/nall/Makefile b/bsnes/nall/Makefile index a542beeb..c1437d14 100755 --- a/bsnes/nall/Makefile +++ b/bsnes/nall/Makefile @@ -41,6 +41,9 @@ ifeq ($(compiler),) endif endif +c := $(compiler) -std=gnu99 +cpp := $(subst cc,++,$(compiler)) -std=gnu++0x + ifeq ($(prefix),) prefix := /usr/local endif diff --git a/bsnes/nall/mosaic/context.hpp b/bsnes/nall/mosaic/context.hpp index 60857ea0..2d8c71ca 100755 --- a/bsnes/nall/mosaic/context.hpp +++ b/bsnes/nall/mosaic/context.hpp @@ -9,8 +9,9 @@ struct context { unsigned height; unsigned count; - bool endian; - unsigned depth; + bool endian; //0 = lsb, 1 = msb + bool order; //0 = linear, 1 = planar + unsigned depth; //1 - 24bpp unsigned blockWidth; unsigned blockHeight; @@ -51,21 +52,61 @@ struct context { return result; } - inline void eval(array &buffer, const string &expression) { + inline void eval(array &buffer, const string &expression_) { + string expression = expression_; + bool function = false; + for(auto &c : expression) { + if(c == '(') function = true; + if(c == ')') function = false; + if(c == ',' && function == true) c = ';'; + } + lstring list = expression.split(","); for(auto &item : list) { item.trim(); - if(item.wildcard("f(?*) *")) { - lstring part = item.split<1>(" "); - part[0].trim("f(", ")"); - unsigned length = decimal(part[0].trim()); + if(item.wildcard("f(?*) ?*")) { + item.ltrim<1>("f("); + lstring part = item.split<1>(") "); + lstring args = part[0].split<3>(";"); + for(auto &item : args) item.trim(); + + unsigned length = eval(args(0, "0")); + unsigned offset = eval(args(1, "0")); + unsigned stride = eval(args(2, "0")); + if(args.size() < 2) offset = buffer.size(); + if(args.size() < 3) stride = 1; + for(unsigned n = 0; n < length; n++) { string fn = part[1]; fn.replace("n", decimal(n)); + fn.replace("o", decimal(offset)); fn.replace("p", decimal(buffer.size())); - buffer.append(eval(fn)); + buffer.resize(offset + 1); + buffer[offset] = eval(fn); + offset += stride; } - } else if(item != "") { + } else if(item.wildcard("base64*")) { + unsigned offset = 0; + item.ltrim<1>("base64"); + if(item.wildcard("(?*) *")) { + item.ltrim<1>("("); + lstring part = item.split<1>(") "); + offset = eval(part[0]); + item = part(1, ""); + } + item.trim(); + for(auto &c : item) { + if(c >= 'A' && c <= 'Z') buffer.append(offset + c - 'A' + 0); + if(c >= 'a' && c <= 'z') buffer.append(offset + c - 'a' + 26); + if(c >= '0' && c <= '9') buffer.append(offset + c - '0' + 52); + if(c == '-') buffer.append(offset + 62); + if(c == '_') buffer.append(offset + 63); + } + } else if(item.wildcard("file *")) { + item.ltrim<1>("file "); + item.trim(); + //... + } else if(item.empty() == false) { buffer.append(eval(item)); } } @@ -87,6 +128,7 @@ struct context { if(part[0] == "count") count = eval(part[1]); if(part[0] == "endian") endian = eval(part[1]); + if(part[0] == "order") order = eval(part[1]); if(part[0] == "depth") depth = eval(part[1]); if(part[0] == "blockWidth") blockWidth = eval(part[1]); @@ -144,6 +186,7 @@ struct context { count = 0; endian = 1; + order = 0; depth = 1; blockWidth = 1; diff --git a/bsnes/nall/mosaic/parser.hpp b/bsnes/nall/mosaic/parser.hpp index fcf29f65..b2c0b8ef 100755 --- a/bsnes/nall/mosaic/parser.hpp +++ b/bsnes/nall/mosaic/parser.hpp @@ -6,13 +6,15 @@ namespace mosaic { struct parser { image canvas; - inline void importData(bitstream &stream, uint64_t offset, context &ctx, unsigned width, unsigned height) { + //export from bitstream to canvas + inline void load(bitstream &stream, uint64_t offset, context &ctx, unsigned width, unsigned height) { canvas.allocate(width, height); canvas.clear(ctx.paddingColor); parse(1, stream, offset, ctx, width, height); } - inline bool exportData(bitstream &stream, uint64_t offset, context &ctx) { + //import from canvas to bitstream + inline bool save(bitstream &stream, uint64_t offset, context &ctx) { if(stream.readonly) return false; parse(0, stream, offset, ctx, canvas.width, canvas.height); return true; @@ -36,39 +38,45 @@ private: buffer[addr] = data; } - inline void parse(bool import, bitstream &stream, uint64_t offset, context &ctx, unsigned width, unsigned height) { + inline void parse(bool load, bitstream &stream, uint64_t offset, context &ctx, unsigned width, unsigned height) { stream.endian = ctx.endian; unsigned canvasWidth = width / (ctx.mosaicWidth * ctx.tileWidth * ctx.blockWidth + ctx.paddingWidth); unsigned canvasHeight = height / (ctx.mosaicHeight * ctx.tileHeight * ctx.blockHeight + ctx.paddingHeight); + unsigned bitsPerBlock = ctx.depth * ctx.blockWidth * ctx.blockHeight; unsigned objectOffset = 0; for(unsigned objectY = 0; objectY < canvasHeight; objectY++) { for(unsigned objectX = 0; objectX < canvasWidth; objectX++) { - if(objectOffset++ >= ctx.count && ctx.count > 0) break; + if(objectOffset >= ctx.count && ctx.count > 0) break; unsigned objectIX = objectX * ctx.objectWidth(); unsigned objectIY = objectY * ctx.objectHeight(); + objectOffset++; unsigned mosaicOffset = 0; for(unsigned mosaicY = 0; mosaicY < ctx.mosaicHeight; mosaicY++) { for(unsigned mosaicX = 0; mosaicX < ctx.mosaicWidth; mosaicX++) { - unsigned mosaicData = ctx.mosaic(mosaicOffset++, 0); + unsigned mosaicData = ctx.mosaic(mosaicOffset, mosaicOffset); unsigned mosaicIX = (mosaicData % ctx.mosaicWidth) * (ctx.tileWidth * ctx.blockWidth); unsigned mosaicIY = (mosaicData / ctx.mosaicWidth) * (ctx.tileHeight * ctx.blockHeight); + mosaicOffset++; unsigned tileOffset = 0; for(unsigned tileY = 0; tileY < ctx.tileHeight; tileY++) { for(unsigned tileX = 0; tileX < ctx.tileWidth; tileX++) { - unsigned tileData = ctx.tile(tileOffset++, 0); + unsigned tileData = ctx.tile(tileOffset, tileOffset); unsigned tileIX = (tileData % ctx.tileWidth) * ctx.blockWidth; unsigned tileIY = (tileData / ctx.tileWidth) * ctx.blockHeight; + tileOffset++; unsigned blockOffset = 0; for(unsigned blockY = 0; blockY < ctx.blockHeight; blockY++) { for(unsigned blockX = 0; blockX < ctx.blockWidth; blockX++) { - if(import) { + if(load) { unsigned palette = 0; for(unsigned n = 0; n < ctx.depth; n++) { - palette |= stream.read(offset + ctx.block(blockOffset++, 0)) << n; + unsigned index = blockOffset++; + if(ctx.order == 1) index = (index % ctx.depth) * ctx.blockWidth * ctx.blockHeight + (index / ctx.depth); + palette |= stream.read(offset + ctx.block(index, index)) << n; } write( @@ -76,14 +84,16 @@ private: objectIY + mosaicIY + tileIY + blockY, ctx.palette(palette, palette) ); - } else { + } else /* save */ { uint32_t palette = read( objectIX + mosaicIX + tileIX + blockX, objectIY + mosaicIY + tileIY + blockY ); for(unsigned n = 0; n < ctx.depth; n++) { - stream.write(offset + ctx.block(blockOffset++, 0), palette & 1); + unsigned index = blockOffset++; + if(ctx.order == 1) index = (index % ctx.depth) * ctx.blockWidth * ctx.blockHeight + (index / ctx.depth); + stream.write(offset + ctx.block(index, index), palette & 1); palette >>= 1; } } diff --git a/bsnes/phoenix/Makefile b/bsnes/phoenix/Makefile new file mode 100755 index 00000000..074fa4fe --- /dev/null +++ b/bsnes/phoenix/Makefile @@ -0,0 +1,21 @@ +ifeq ($(platform),x) + ifeq ($(phoenix),) + phoenix := gtk + endif + + ifeq ($(phoenix),gtk) + phoenixflags := -DPHOENIX_GTK `pkg-config --cflags gtk+-2.0` + phoenixlink := `pkg-config --libs gtk+-2.0` + endif + + ifeq ($(phoenix),qt) + phoenixflags := -DPHOENIX_QT `pkg-config --cflags QtCore QtGui` + phoenixlink := `pkg-config --libs QtCore QtGui` + endif +else ifeq ($(platform),win) + phoenixflags := -DPHOENIX_WINDOWS + phoenixlink := -lkernel32 -luser32 -lgdi32 -ladvapi32 -lole32 -lcomctl32 -lcomdlg32 +else + phoenixflags := -DPHOENIX_REFERENCE + phoenixlink := +endif diff --git a/bsnes/phoenix/core/core.cpp b/bsnes/phoenix/core/core.cpp index f46a568c..f4396c3f 100755 --- a/bsnes/phoenix/core/core.cpp +++ b/bsnes/phoenix/core/core.cpp @@ -19,7 +19,15 @@ Window Window::None; //Geometry //======== -string Geometry::text() { +Position Geometry::position() const { + return { x, y }; +} + +Size Geometry::size() const { + return { width, height }; +} + +string Geometry::text() const { return { x, ",", y, ",", width, ",", height }; } diff --git a/bsnes/phoenix/core/core.hpp b/bsnes/phoenix/core/core.hpp index 0e8ad591..1e3d53ff 100755 --- a/bsnes/phoenix/core/core.hpp +++ b/bsnes/phoenix/core/core.hpp @@ -47,15 +47,6 @@ struct Color { inline Color(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha = 255) : red(red), green(green), blue(blue), alpha(alpha) {} }; -struct Geometry { - signed x, y; - unsigned width, height; - nall::string text(); - inline Geometry() : x(0), y(0), width(0), height(0) {} - inline Geometry(signed x, signed y, unsigned width, unsigned height) : x(x), y(y), width(width), height(height) {} - Geometry(const nall::string &text); -}; - struct Position { signed x, y; inline Position() : x(0), y(0) {} @@ -68,6 +59,17 @@ struct Size { inline Size(unsigned width, unsigned height) : width(width), height(height) {} }; +struct Geometry { + signed x, y; + unsigned width, height; + Position position() const; + Size size() const; + nall::string text() const; + inline Geometry() : x(0), y(0), width(0), height(0) {} + inline Geometry(signed x, signed y, unsigned width, unsigned height) : x(x), y(y), width(width), height(height) {} + Geometry(const nall::string &text); +}; + struct Font { nall::string description; Geometry geometry(const nall::string &text); diff --git a/bsnes/phoenix/gtk/platform.cpp b/bsnes/phoenix/gtk/platform.cpp index 4cfbf912..6801aef3 100755 --- a/bsnes/phoenix/gtk/platform.cpp +++ b/bsnes/phoenix/gtk/platform.cpp @@ -165,13 +165,16 @@ void pOS::initialize() { char **argvp = argv; gtk_init(&argc, &argvp); - gtk_rc_parse_string( - "style \"phoenix-gtk\"\n" - "{\n" - " GtkComboBox::appears-as-list = 1\n" - " GtkTreeView::vertical-separator = 0\n" - "}\n" - //"class \"GtkComboBox\" style \"phoenix-gtk\"\n" - "class \"GtkTreeView\" style \"phoenix-gtk\"\n" - ); + gtk_rc_parse_string(R"( + style "phoenix-gtk" + { + GtkWindow::resize-grip-width = 0 + GtkWindow::resize-grip-height = 0 + GtkTreeView::vertical-separator = 0 + GtkComboBox::appears-as-list = 1 + } + class "GtkWindow" style "phoenix-gtk" + class "GtkTreeView" style "phoenix-gtk" + # class "GtkComboBox" style "phoenix-gtk" + )"); } diff --git a/bsnes/phoenix/gtk/widget/horizontal-scroll-bar.cpp b/bsnes/phoenix/gtk/widget/horizontal-scroll-bar.cpp index f05255c4..0d765e92 100755 --- a/bsnes/phoenix/gtk/widget/horizontal-scroll-bar.cpp +++ b/bsnes/phoenix/gtk/widget/horizontal-scroll-bar.cpp @@ -15,7 +15,7 @@ unsigned pHorizontalScrollBar::position() { void pHorizontalScrollBar::setLength(unsigned length) { locked = true; length += length == 0; - gtk_range_set_range(GTK_RANGE(gtkWidget), 0, length - 1); + gtk_range_set_range(GTK_RANGE(gtkWidget), 0, max(1u, length - 1)); gtk_range_set_increments(GTK_RANGE(gtkWidget), 1, length >> 3); locked = false; } diff --git a/bsnes/phoenix/gtk/widget/horizontal-slider.cpp b/bsnes/phoenix/gtk/widget/horizontal-slider.cpp index 9913d72d..2d19bae6 100755 --- a/bsnes/phoenix/gtk/widget/horizontal-slider.cpp +++ b/bsnes/phoenix/gtk/widget/horizontal-slider.cpp @@ -14,7 +14,7 @@ unsigned pHorizontalSlider::position() { void pHorizontalSlider::setLength(unsigned length) { length += length == 0; - gtk_range_set_range(GTK_RANGE(gtkWidget), 0, length - 1); + gtk_range_set_range(GTK_RANGE(gtkWidget), 0, max(1u, length - 1)); gtk_range_set_increments(GTK_RANGE(gtkWidget), 1, length >> 3); } diff --git a/bsnes/phoenix/gtk/widget/vertical-scroll-bar.cpp b/bsnes/phoenix/gtk/widget/vertical-scroll-bar.cpp index aba60d3a..e3bde589 100755 --- a/bsnes/phoenix/gtk/widget/vertical-scroll-bar.cpp +++ b/bsnes/phoenix/gtk/widget/vertical-scroll-bar.cpp @@ -15,7 +15,7 @@ unsigned pVerticalScrollBar::position() { void pVerticalScrollBar::setLength(unsigned length) { locked = true; length += length == 0; - gtk_range_set_range(GTK_RANGE(gtkWidget), 0, length - 1); + gtk_range_set_range(GTK_RANGE(gtkWidget), 0, max(1u, length - 1)); gtk_range_set_increments(GTK_RANGE(gtkWidget), 1, length >> 3); locked = false; } diff --git a/bsnes/phoenix/gtk/widget/vertical-slider.cpp b/bsnes/phoenix/gtk/widget/vertical-slider.cpp index b1148410..3c68489e 100755 --- a/bsnes/phoenix/gtk/widget/vertical-slider.cpp +++ b/bsnes/phoenix/gtk/widget/vertical-slider.cpp @@ -14,7 +14,7 @@ unsigned pVerticalSlider::position() { void pVerticalSlider::setLength(unsigned length) { length += length == 0; - gtk_range_set_range(GTK_RANGE(gtkWidget), 0, length - 1); + gtk_range_set_range(GTK_RANGE(gtkWidget), 0, max(1u, length - 1)); gtk_range_set_increments(GTK_RANGE(gtkWidget), 1, length >> 3); } diff --git a/bsnes/phoenix/gtk/window.cpp b/bsnes/phoenix/gtk/window.cpp index 13943689..3b7f54fe 100755 --- a/bsnes/phoenix/gtk/window.cpp +++ b/bsnes/phoenix/gtk/window.cpp @@ -6,6 +6,7 @@ static gint Window_close(GtkWidget *widget, GdkEvent *event, Window *window) { } static gboolean Window_expose(GtkWidget *widget, GdkEvent *event, Window *window) { + if(window->state.backgroundColorOverride == false) return false; cairo_t *context = gdk_cairo_create(widget->window); Color color = window->backgroundColor(); @@ -241,6 +242,10 @@ void pWindow::constructor() { } gtk_window_set_resizable(GTK_WINDOW(widget), true); + #if GTK_MAJOR_VERSION >= 3 + gtk_window_set_has_resize_grip(GTK_WINDOW(widget), false); + #endif + gtk_widget_set_app_paintable(widget, true); gtk_widget_add_events(widget, GDK_CONFIGURE); diff --git a/bsnes/phoenix/phoenix.hpp b/bsnes/phoenix/phoenix.hpp index 543ff18b..33903fea 100755 --- a/bsnes/phoenix/phoenix.hpp +++ b/bsnes/phoenix/phoenix.hpp @@ -1,6 +1,7 @@ #ifndef PHOENIX_HPP #define PHOENIX_HPP +#include #include #include #include diff --git a/bsnes/phoenix/qt/platform.moc b/bsnes/phoenix/qt/platform.moc index 6e90cebf..059a846c 100755 --- a/bsnes/phoenix/qt/platform.moc +++ b/bsnes/phoenix/qt/platform.moc @@ -1,7 +1,7 @@ /**************************************************************************** ** Meta object code from reading C++ file 'platform.moc.hpp' ** -** Created: Sun Dec 11 12:26:40 2011 +** Created: Tue Dec 13 07:23:09 2011 ** by: The Qt Meta Object Compiler version 62 (Qt 4.6.3) ** ** WARNING! All changes made in this file will be lost! diff --git a/bsnes/phoenix/qt/widget/canvas.cpp b/bsnes/phoenix/qt/widget/canvas.cpp index 560e43a3..387f16dd 100755 --- a/bsnes/phoenix/qt/widget/canvas.cpp +++ b/bsnes/phoenix/qt/widget/canvas.cpp @@ -4,7 +4,8 @@ void pCanvas::setSize(const Size &size) { } void pCanvas::update() { - memcpy(qtImage->bits(), canvas.state.data, canvas.state.width * canvas.state.height * sizeof(uint32_t)); + uint32_t *dp = (uint32_t*)qtImage->bits(), *sp = (uint32_t*)canvas.state.data; + for(unsigned n = 0; n < canvas.state.width * canvas.state.height; n++) *dp++ = 0xff000000 | *sp++; qtCanvas->update(); } diff --git a/bsnes/phoenix/windows/platform.cpp b/bsnes/phoenix/windows/platform.cpp index b910e8a7..ce97ed3f 100755 --- a/bsnes/phoenix/windows/platform.cpp +++ b/bsnes/phoenix/windows/platform.cpp @@ -31,7 +31,7 @@ #include "widget/vertical-slider.cpp" #include "widget/viewport.cpp" -static void OS_keyboardProc(HWND, UINT, WPARAM, LPARAM); +static bool OS_keyboardProc(HWND, UINT, WPARAM, LPARAM); static void OS_processDialogMessage(MSG&); static LRESULT CALLBACK OS_windowProc(HWND, UINT, WPARAM, LPARAM); @@ -150,7 +150,10 @@ void pOS::processEvents() { void OS_processDialogMessage(MSG &msg) { if(msg.message == WM_KEYDOWN || msg.message == WM_KEYUP) { - OS_keyboardProc(msg.hwnd, msg.message, msg.wParam, msg.lParam); + if(OS_keyboardProc(msg.hwnd, msg.message, msg.wParam, msg.lParam)) { + DispatchMessage(&msg); + return; + } } if(!IsDialogMessage(GetForegroundWindow(), &msg)) { @@ -217,14 +220,14 @@ void pOS::initialize() { RegisterClass(&wc); } -static void OS_keyboardProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { +static bool OS_keyboardProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { if(msg == WM_KEYDOWN) { GUITHREADINFO info; memset(&info, 0, sizeof(GUITHREADINFO)); info.cbSize = sizeof(GUITHREADINFO); GetGUIThreadInfo(GetCurrentThreadId(), &info); Object *object = (Object*)GetWindowLongPtr(info.hwndFocus, GWLP_USERDATA); - if(object == 0) return; + if(object == nullptr) return false; if(dynamic_cast(object)) { ListView &listView = (ListView&)*object; if(wparam == VK_RETURN) { @@ -235,8 +238,48 @@ static void OS_keyboardProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { if(wparam == VK_RETURN) { if(lineEdit.onActivate) lineEdit.onActivate(); } + } else if(dynamic_cast(object)) { + TextEdit &textEdit = (TextEdit&)*object; + if(wparam == 'A' && GetKeyState(VK_CONTROL) < 0) { + //Ctrl+A = select all text + //note: this is not a standard accelerator on Windows + Edit_SetSel(textEdit.p.hwnd, 0, ~0); + return true; + } else if(wparam == 'V' && GetKeyState(VK_CONTROL) < 0) { + //Ctrl+V = paste text + //note: this formats Unix (LF) and OS9 (CR) line-endings to Windows (CR+LF) line-endings + //this is necessary as the EDIT control only supports Windows line-endings + OpenClipboard(hwnd); + HANDLE handle = GetClipboardData(CF_UNICODETEXT); + if(handle) { + wchar_t *text = (wchar_t*)GlobalLock(handle); + if(text) { + string data = (const char*)utf8_t(text); + data.replace("\r\n", "\n"); + data.replace("\r", "\n"); + data.replace("\n", "\r\n"); + GlobalUnlock(handle); + utf16_t output(data); + HGLOBAL resource = GlobalAlloc(GMEM_MOVEABLE, (wcslen(output) + 1) * sizeof(wchar_t)); + if(resource) { + wchar_t *write = (wchar_t*)GlobalLock(resource); + if(write) { + wcscpy(write, output); + GlobalUnlock(write); + if(SetClipboardData(CF_UNICODETEXT, resource) == FALSE) { + GlobalFree(resource); + } + } + } + } + } + CloseClipboard(); + return false; + } } } + + return false; } static LRESULT CALLBACK OS_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { diff --git a/bsnes/ruby/Makefile b/bsnes/ruby/Makefile index 1231bcd5..c651cacc 100755 --- a/bsnes/ruby/Makefile +++ b/bsnes/ruby/Makefile @@ -18,9 +18,9 @@ rubylink += $(if $(findstring input.directinput,$(ruby)),-ldinput8 -ldxguid) rubylink += $(if $(findstring input.rawinput,$(ruby)),-ldinput8 -ldxguid) ifeq ($(platform),x) -rubylink += $(if $(findstring audio.openal,$(ruby)),-lopenal) + rubylink += $(if $(findstring audio.openal,$(ruby)),-lopenal) else ifeq ($(platform),osx) -rubylink += $(if $(findstring audio.openal,$(ruby)),-framework OpenAL) + rubylink += $(if $(findstring audio.openal,$(ruby)),-framework OpenAL) else ifeq ($(platform),win) -rubylink += $(if $(findstring audio.openal,$(ruby)),-lopenal32) + rubylink += $(if $(findstring audio.openal,$(ruby)),-lopenal32) endif diff --git a/bsnes/snes/controller/justifier/justifier.cpp b/bsnes/snes/controller/justifier/justifier.cpp index 8b2d3ee4..62079166 100755 --- a/bsnes/snes/controller/justifier/justifier.cpp +++ b/bsnes/snes/controller/justifier/justifier.cpp @@ -5,7 +5,7 @@ void Justifier::enter() { while(true) { unsigned next = cpu.vcounter() * 1364 + cpu.hcounter(); - signed x = (active == 0 ? x1 : x2), y = (active == 0 ? y1 : y2); + signed x = (active == 0 ? player1.x : player2.x), y = (active == 0 ? player1.y : player2.y); bool offscreen = (x < 0 || y < 0 || x >= 256 || y >= (ppu.overscan() ? 240 : 225)); if(offscreen == false) { @@ -20,23 +20,19 @@ void Justifier::enter() { if(next < prev) { int nx1 = interface->inputPoll(port, Input::Device::Justifier, 0, (unsigned)Input::JustifierID::X); int ny1 = interface->inputPoll(port, Input::Device::Justifier, 0, (unsigned)Input::JustifierID::Y); - nx1 += x1; - ny1 += y1; - x1 = max(-16, min(256 + 16, nx1)); - y1 = max(-16, min(240 + 16, ny1)); + nx1 += player1.x; + ny1 += player1.y; + player1.x = max(-16, min(256 + 16, nx1)); + player1.y = max(-16, min(240 + 16, ny1)); + } - if(chained == true) { - int nx2 = interface->inputPoll(port, Input::Device::Justifiers, 1, (unsigned)Input::JustifierID::X); - int ny2 = interface->inputPoll(port, Input::Device::Justifiers, 1, (unsigned)Input::JustifierID::Y); - nx2 += x2; - ny2 += y2; - x2 = max(-16, min(256 + 16, nx2)); - y2 = max(-16, min(240 + 16, ny2)); - } - } else { - //sleep until PPU counters are close to latch position - unsigned diff = abs((signed)y - cpu.vcounter()); - if(diff >= 2) step((diff - 2) * 1364); + if(next < prev && chained) { + int nx2 = interface->inputPoll(port, Input::Device::Justifiers, 1, (unsigned)Input::JustifierID::X); + int ny2 = interface->inputPoll(port, Input::Device::Justifiers, 1, (unsigned)Input::JustifierID::Y); + nx2 += player2.x; + ny2 += player2.y; + player2.x = max(-16, min(256 + 16, nx2)); + player2.y = max(-16, min(240 + 16, ny2)); } prev = next; @@ -48,12 +44,13 @@ uint2 Justifier::data() { if(counter >= 32) return 1; if(counter == 0) { - trigger1 = interface->inputPoll(port, Input::Device::Justifier, 0, (unsigned)Input::JustifierID::Trigger); - start1 = interface->inputPoll(port, Input::Device::Justifier, 0, (unsigned)Input::JustifierID::Start); - if(chained) { - trigger2 = interface->inputPoll(port, Input::Device::Justifiers, 1, (unsigned)Input::JustifierID::Trigger); - start2 = interface->inputPoll(port, Input::Device::Justifiers, 1, (unsigned)Input::JustifierID::Start); - } + player1.trigger = interface->inputPoll(port, Input::Device::Justifier, 0, (unsigned)Input::JustifierID::Trigger); + player1.start = interface->inputPoll(port, Input::Device::Justifier, 0, (unsigned)Input::JustifierID::Start); + } + + if(counter == 0 && chained) { + player2.trigger = interface->inputPoll(port, Input::Device::Justifiers, 1, (unsigned)Input::JustifierID::Trigger); + player2.start = interface->inputPoll(port, Input::Device::Justifiers, 1, (unsigned)Input::JustifierID::Start); } switch(counter++) { @@ -84,10 +81,10 @@ uint2 Justifier::data() { case 22: return 0; case 23: return 1; - case 24: return trigger1; - case 25: return trigger2; - case 26: return start1; - case 27: return start2; + case 24: return player1.trigger; + case 25: return player2.trigger; + case 26: return player1.start; + case 27: return player2.start; case 28: return active; case 29: return 0; @@ -109,23 +106,23 @@ Justifier::Justifier(bool port, bool chained) : Controller(port), chained(chaine counter = 0; active = 0; + player1.x = 256 / 2; + player1.y = 240 / 2; + player1.trigger = false; + player2.start = false; + + player2.x = 256 / 2; + player2.y = 240 / 2; + player2.trigger = false; + player2.start = false; + if(chained == false) { - x1 = 256 / 2; - y1 = 240 / 2; - x2 = -1; - y2 = -1; + player2.x = -1; + player2.y = -1; } else { - x1 = 256 / 2 - 16; - y1 = 240 / 2; - x2 = 256 / 2 + 16; - y2 = 240 / 2; + player1.x -= 16; + player2.x += 16; } - - trigger1 = false; - trigger2 = false; - - start1 = false; - start2 = false; } #endif diff --git a/bsnes/snes/controller/justifier/justifier.hpp b/bsnes/snes/controller/justifier/justifier.hpp index 82591471..f927acf6 100755 --- a/bsnes/snes/controller/justifier/justifier.hpp +++ b/bsnes/snes/controller/justifier/justifier.hpp @@ -10,8 +10,8 @@ struct Justifier : Controller { unsigned counter; bool active; - signed x1, x2; - signed y1, y2; - bool trigger1, trigger2; - bool start1, start2; + struct Player { + signed x, y; + bool trigger, start; + } player1, player2; }; diff --git a/bsnes/snes/controller/superscope/superscope.cpp b/bsnes/snes/controller/superscope/superscope.cpp index e97a2ff5..12068f05 100755 --- a/bsnes/snes/controller/superscope/superscope.cpp +++ b/bsnes/snes/controller/superscope/superscope.cpp @@ -35,10 +35,6 @@ void SuperScope::enter() { x = max(-16, min(256 + 16, nx)); y = max(-16, min(240 + 16, ny)); offscreen = (x < 0 || y < 0 || x >= 256 || y >= (ppu.overscan() ? 240 : 225)); - } else { - //sleep until PPU counters are close to latch position - unsigned diff = abs((signed)y - cpu.vcounter()); - if(diff >= 2) step((diff - 2) * 1364); } prev = next; diff --git a/bsnes/snes/system/video.cpp b/bsnes/snes/system/video.cpp index 9666f194..1d6020eb 100755 --- a/bsnes/snes/system/video.cpp +++ b/bsnes/snes/system/video.cpp @@ -107,9 +107,9 @@ void Video::update() { case Input::Device::Justifiers: if(dynamic_cast(input.port2)) { Justifier &device = (Justifier&)*input.port2; - draw_cursor(0x001f, device.x1, device.y1); + draw_cursor(0x001f, device.player1.x, device.player1.y); if(device.chained == false) break; - draw_cursor(0x02e0, device.x2, device.y2); + draw_cursor(0x02e0, device.player2.x, device.player2.y); } break; } diff --git a/bsnes/ui/Makefile b/bsnes/ui/Makefile index 846c6ffa..8270f408 100755 --- a/bsnes/ui/Makefile +++ b/bsnes/ui/Makefile @@ -10,33 +10,23 @@ ui_objects += $(if $(call streq,$(platform),win),resource) # platform ifeq ($(platform),x) - ifeq ($(phoenix),gtk) - phoenix_compile = $(call compile,-DPHOENIX_GTK `pkg-config --cflags gtk+-2.0`) - link += `pkg-config --libs gtk+-2.0` - else - phoenix_compile = $(call compile,-DPHOENIX_QT `pkg-config --cflags QtCore QtGui`) - link += `pkg-config --libs QtCore QtGui` - endif - 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 else ifeq ($(platform),osx) - phoenix_compile = $(call compile,-DPHOENIX_QT) - link += - ruby := ruby += audio.openal ruby += input.carbon 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 endif +# phoenix +include phoenix/Makefile +link += $(phoenixlink) + # ruby include ruby/Makefile link += $(rubylink) @@ -59,7 +49,7 @@ obj/ruby.o: ruby/ruby.cpp $(call rwildcard,ruby/*) $(call compile,$(rubyflags)) obj/phoenix.o: phoenix/phoenix.cpp $(call rwildcard,phoenix/*) - $(phoenix_compile) + $(call compile,$(phoenixflags)) obj/resource.o: $(ui)/resource.rc # windres --target=pe-i386 $(ui)/resource.rc obj/resource.o diff --git a/bsnes/ui/main.cpp b/bsnes/ui/main.cpp index d664af28..76984cf4 100755 --- a/bsnes/ui/main.cpp +++ b/bsnes/ui/main.cpp @@ -27,7 +27,7 @@ void Application::run() { } Application::Application(int argc, char **argv) { - title = "bsnes v084.04"; + title = "bsnes v084.05"; application = this; quit = false;