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.
This commit is contained in:
Tim Allen 2011-12-18 14:19:45 +11:00
parent ea95eaca3c
commit 6227974bf6
23 changed files with 241 additions and 118 deletions

View File

@ -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

View File

@ -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<unsigned> &buffer, const string &expression) {
inline void eval(array<unsigned> &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;

View File

@ -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;
}
}

21
bsnes/phoenix/Makefile Executable file
View File

@ -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

View File

@ -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 };
}

View File

@ -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);

View File

@ -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"
)");
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);

View File

@ -1,6 +1,7 @@
#ifndef PHOENIX_HPP
#define PHOENIX_HPP
#include <nall/platform.hpp>
#include <nall/array.hpp>
#include <nall/config.hpp>
#include <nall/function.hpp>

View File

@ -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!

View File

@ -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();
}

View File

@ -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<ListView*>(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<TextEdit*>(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) {

View File

@ -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

View File

@ -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

View File

@ -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;
};

View File

@ -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;

View File

@ -107,9 +107,9 @@ void Video::update() {
case Input::Device::Justifiers:
if(dynamic_cast<Justifier*>(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;
}

View File

@ -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

View File

@ -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;