mirror of https://github.com/bsnes-emu/bsnes.git
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:
parent
ea95eaca3c
commit
6227974bf6
|
@ -41,6 +41,9 @@ ifeq ($(compiler),)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
c := $(compiler) -std=gnu99
|
||||||
|
cpp := $(subst cc,++,$(compiler)) -std=gnu++0x
|
||||||
|
|
||||||
ifeq ($(prefix),)
|
ifeq ($(prefix),)
|
||||||
prefix := /usr/local
|
prefix := /usr/local
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -9,8 +9,9 @@ struct context {
|
||||||
unsigned height;
|
unsigned height;
|
||||||
unsigned count;
|
unsigned count;
|
||||||
|
|
||||||
bool endian;
|
bool endian; //0 = lsb, 1 = msb
|
||||||
unsigned depth;
|
bool order; //0 = linear, 1 = planar
|
||||||
|
unsigned depth; //1 - 24bpp
|
||||||
|
|
||||||
unsigned blockWidth;
|
unsigned blockWidth;
|
||||||
unsigned blockHeight;
|
unsigned blockHeight;
|
||||||
|
@ -51,21 +52,61 @@ struct context {
|
||||||
return result;
|
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(",");
|
lstring list = expression.split(",");
|
||||||
for(auto &item : list) {
|
for(auto &item : list) {
|
||||||
item.trim();
|
item.trim();
|
||||||
if(item.wildcard("f(?*) *")) {
|
if(item.wildcard("f(?*) ?*")) {
|
||||||
lstring part = item.split<1>(" ");
|
item.ltrim<1>("f(");
|
||||||
part[0].trim("f(", ")");
|
lstring part = item.split<1>(") ");
|
||||||
unsigned length = decimal(part[0].trim());
|
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++) {
|
for(unsigned n = 0; n < length; n++) {
|
||||||
string fn = part[1];
|
string fn = part[1];
|
||||||
fn.replace("n", decimal(n));
|
fn.replace("n", decimal(n));
|
||||||
|
fn.replace("o", decimal(offset));
|
||||||
fn.replace("p", decimal(buffer.size()));
|
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));
|
buffer.append(eval(item));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,6 +128,7 @@ struct context {
|
||||||
if(part[0] == "count") count = eval(part[1]);
|
if(part[0] == "count") count = eval(part[1]);
|
||||||
|
|
||||||
if(part[0] == "endian") endian = 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] == "depth") depth = eval(part[1]);
|
||||||
|
|
||||||
if(part[0] == "blockWidth") blockWidth = eval(part[1]);
|
if(part[0] == "blockWidth") blockWidth = eval(part[1]);
|
||||||
|
@ -144,6 +186,7 @@ struct context {
|
||||||
count = 0;
|
count = 0;
|
||||||
|
|
||||||
endian = 1;
|
endian = 1;
|
||||||
|
order = 0;
|
||||||
depth = 1;
|
depth = 1;
|
||||||
|
|
||||||
blockWidth = 1;
|
blockWidth = 1;
|
||||||
|
|
|
@ -6,13 +6,15 @@ namespace mosaic {
|
||||||
struct parser {
|
struct parser {
|
||||||
image canvas;
|
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.allocate(width, height);
|
||||||
canvas.clear(ctx.paddingColor);
|
canvas.clear(ctx.paddingColor);
|
||||||
parse(1, stream, offset, ctx, width, height);
|
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;
|
if(stream.readonly) return false;
|
||||||
parse(0, stream, offset, ctx, canvas.width, canvas.height);
|
parse(0, stream, offset, ctx, canvas.width, canvas.height);
|
||||||
return true;
|
return true;
|
||||||
|
@ -36,39 +38,45 @@ private:
|
||||||
buffer[addr] = data;
|
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;
|
stream.endian = ctx.endian;
|
||||||
unsigned canvasWidth = width / (ctx.mosaicWidth * ctx.tileWidth * ctx.blockWidth + ctx.paddingWidth);
|
unsigned canvasWidth = width / (ctx.mosaicWidth * ctx.tileWidth * ctx.blockWidth + ctx.paddingWidth);
|
||||||
unsigned canvasHeight = height / (ctx.mosaicHeight * ctx.tileHeight * ctx.blockHeight + ctx.paddingHeight);
|
unsigned canvasHeight = height / (ctx.mosaicHeight * ctx.tileHeight * ctx.blockHeight + ctx.paddingHeight);
|
||||||
|
unsigned bitsPerBlock = ctx.depth * ctx.blockWidth * ctx.blockHeight;
|
||||||
|
|
||||||
unsigned objectOffset = 0;
|
unsigned objectOffset = 0;
|
||||||
for(unsigned objectY = 0; objectY < canvasHeight; objectY++) {
|
for(unsigned objectY = 0; objectY < canvasHeight; objectY++) {
|
||||||
for(unsigned objectX = 0; objectX < canvasWidth; objectX++) {
|
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 objectIX = objectX * ctx.objectWidth();
|
||||||
unsigned objectIY = objectY * ctx.objectHeight();
|
unsigned objectIY = objectY * ctx.objectHeight();
|
||||||
|
objectOffset++;
|
||||||
|
|
||||||
unsigned mosaicOffset = 0;
|
unsigned mosaicOffset = 0;
|
||||||
for(unsigned mosaicY = 0; mosaicY < ctx.mosaicHeight; mosaicY++) {
|
for(unsigned mosaicY = 0; mosaicY < ctx.mosaicHeight; mosaicY++) {
|
||||||
for(unsigned mosaicX = 0; mosaicX < ctx.mosaicWidth; mosaicX++) {
|
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 mosaicIX = (mosaicData % ctx.mosaicWidth) * (ctx.tileWidth * ctx.blockWidth);
|
||||||
unsigned mosaicIY = (mosaicData / ctx.mosaicWidth) * (ctx.tileHeight * ctx.blockHeight);
|
unsigned mosaicIY = (mosaicData / ctx.mosaicWidth) * (ctx.tileHeight * ctx.blockHeight);
|
||||||
|
mosaicOffset++;
|
||||||
|
|
||||||
unsigned tileOffset = 0;
|
unsigned tileOffset = 0;
|
||||||
for(unsigned tileY = 0; tileY < ctx.tileHeight; tileY++) {
|
for(unsigned tileY = 0; tileY < ctx.tileHeight; tileY++) {
|
||||||
for(unsigned tileX = 0; tileX < ctx.tileWidth; tileX++) {
|
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 tileIX = (tileData % ctx.tileWidth) * ctx.blockWidth;
|
||||||
unsigned tileIY = (tileData / ctx.tileWidth) * ctx.blockHeight;
|
unsigned tileIY = (tileData / ctx.tileWidth) * ctx.blockHeight;
|
||||||
|
tileOffset++;
|
||||||
|
|
||||||
unsigned blockOffset = 0;
|
unsigned blockOffset = 0;
|
||||||
for(unsigned blockY = 0; blockY < ctx.blockHeight; blockY++) {
|
for(unsigned blockY = 0; blockY < ctx.blockHeight; blockY++) {
|
||||||
for(unsigned blockX = 0; blockX < ctx.blockWidth; blockX++) {
|
for(unsigned blockX = 0; blockX < ctx.blockWidth; blockX++) {
|
||||||
if(import) {
|
if(load) {
|
||||||
unsigned palette = 0;
|
unsigned palette = 0;
|
||||||
for(unsigned n = 0; n < ctx.depth; n++) {
|
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(
|
write(
|
||||||
|
@ -76,14 +84,16 @@ private:
|
||||||
objectIY + mosaicIY + tileIY + blockY,
|
objectIY + mosaicIY + tileIY + blockY,
|
||||||
ctx.palette(palette, palette)
|
ctx.palette(palette, palette)
|
||||||
);
|
);
|
||||||
} else {
|
} else /* save */ {
|
||||||
uint32_t palette = read(
|
uint32_t palette = read(
|
||||||
objectIX + mosaicIX + tileIX + blockX,
|
objectIX + mosaicIX + tileIX + blockX,
|
||||||
objectIY + mosaicIY + tileIY + blockY
|
objectIY + mosaicIY + tileIY + blockY
|
||||||
);
|
);
|
||||||
|
|
||||||
for(unsigned n = 0; n < ctx.depth; n++) {
|
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;
|
palette >>= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
@ -19,7 +19,15 @@ Window Window::None;
|
||||||
//Geometry
|
//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 };
|
return { x, ",", y, ",", width, ",", height };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {}
|
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 {
|
struct Position {
|
||||||
signed x, y;
|
signed x, y;
|
||||||
inline Position() : x(0), y(0) {}
|
inline Position() : x(0), y(0) {}
|
||||||
|
@ -68,6 +59,17 @@ struct Size {
|
||||||
inline Size(unsigned width, unsigned height) : width(width), height(height) {}
|
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 {
|
struct Font {
|
||||||
nall::string description;
|
nall::string description;
|
||||||
Geometry geometry(const nall::string &text);
|
Geometry geometry(const nall::string &text);
|
||||||
|
|
|
@ -165,13 +165,16 @@ void pOS::initialize() {
|
||||||
char **argvp = argv;
|
char **argvp = argv;
|
||||||
gtk_init(&argc, &argvp);
|
gtk_init(&argc, &argvp);
|
||||||
|
|
||||||
gtk_rc_parse_string(
|
gtk_rc_parse_string(R"(
|
||||||
"style \"phoenix-gtk\"\n"
|
style "phoenix-gtk"
|
||||||
"{\n"
|
{
|
||||||
" GtkComboBox::appears-as-list = 1\n"
|
GtkWindow::resize-grip-width = 0
|
||||||
" GtkTreeView::vertical-separator = 0\n"
|
GtkWindow::resize-grip-height = 0
|
||||||
"}\n"
|
GtkTreeView::vertical-separator = 0
|
||||||
//"class \"GtkComboBox\" style \"phoenix-gtk\"\n"
|
GtkComboBox::appears-as-list = 1
|
||||||
"class \"GtkTreeView\" style \"phoenix-gtk\"\n"
|
}
|
||||||
);
|
class "GtkWindow" style "phoenix-gtk"
|
||||||
|
class "GtkTreeView" style "phoenix-gtk"
|
||||||
|
# class "GtkComboBox" style "phoenix-gtk"
|
||||||
|
)");
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ unsigned pHorizontalScrollBar::position() {
|
||||||
void pHorizontalScrollBar::setLength(unsigned length) {
|
void pHorizontalScrollBar::setLength(unsigned length) {
|
||||||
locked = true;
|
locked = true;
|
||||||
length += length == 0;
|
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);
|
gtk_range_set_increments(GTK_RANGE(gtkWidget), 1, length >> 3);
|
||||||
locked = false;
|
locked = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ unsigned pHorizontalSlider::position() {
|
||||||
|
|
||||||
void pHorizontalSlider::setLength(unsigned length) {
|
void pHorizontalSlider::setLength(unsigned length) {
|
||||||
length += length == 0;
|
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);
|
gtk_range_set_increments(GTK_RANGE(gtkWidget), 1, length >> 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ unsigned pVerticalScrollBar::position() {
|
||||||
void pVerticalScrollBar::setLength(unsigned length) {
|
void pVerticalScrollBar::setLength(unsigned length) {
|
||||||
locked = true;
|
locked = true;
|
||||||
length += length == 0;
|
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);
|
gtk_range_set_increments(GTK_RANGE(gtkWidget), 1, length >> 3);
|
||||||
locked = false;
|
locked = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ unsigned pVerticalSlider::position() {
|
||||||
|
|
||||||
void pVerticalSlider::setLength(unsigned length) {
|
void pVerticalSlider::setLength(unsigned length) {
|
||||||
length += length == 0;
|
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);
|
gtk_range_set_increments(GTK_RANGE(gtkWidget), 1, length >> 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ static gint Window_close(GtkWidget *widget, GdkEvent *event, Window *window) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean Window_expose(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);
|
cairo_t *context = gdk_cairo_create(widget->window);
|
||||||
|
|
||||||
Color color = window->backgroundColor();
|
Color color = window->backgroundColor();
|
||||||
|
@ -241,6 +242,10 @@ void pWindow::constructor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_window_set_resizable(GTK_WINDOW(widget), true);
|
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_set_app_paintable(widget, true);
|
||||||
gtk_widget_add_events(widget, GDK_CONFIGURE);
|
gtk_widget_add_events(widget, GDK_CONFIGURE);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef PHOENIX_HPP
|
#ifndef PHOENIX_HPP
|
||||||
#define PHOENIX_HPP
|
#define PHOENIX_HPP
|
||||||
|
|
||||||
|
#include <nall/platform.hpp>
|
||||||
#include <nall/array.hpp>
|
#include <nall/array.hpp>
|
||||||
#include <nall/config.hpp>
|
#include <nall/config.hpp>
|
||||||
#include <nall/function.hpp>
|
#include <nall/function.hpp>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
** Meta object code from reading C++ file 'platform.moc.hpp'
|
** 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)
|
** by: The Qt Meta Object Compiler version 62 (Qt 4.6.3)
|
||||||
**
|
**
|
||||||
** WARNING! All changes made in this file will be lost!
|
** WARNING! All changes made in this file will be lost!
|
||||||
|
|
|
@ -4,7 +4,8 @@ void pCanvas::setSize(const Size &size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void pCanvas::update() {
|
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();
|
qtCanvas->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
#include "widget/vertical-slider.cpp"
|
#include "widget/vertical-slider.cpp"
|
||||||
#include "widget/viewport.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 void OS_processDialogMessage(MSG&);
|
||||||
static LRESULT CALLBACK OS_windowProc(HWND, UINT, WPARAM, LPARAM);
|
static LRESULT CALLBACK OS_windowProc(HWND, UINT, WPARAM, LPARAM);
|
||||||
|
|
||||||
|
@ -150,7 +150,10 @@ void pOS::processEvents() {
|
||||||
|
|
||||||
void OS_processDialogMessage(MSG &msg) {
|
void OS_processDialogMessage(MSG &msg) {
|
||||||
if(msg.message == WM_KEYDOWN || msg.message == WM_KEYUP) {
|
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)) {
|
if(!IsDialogMessage(GetForegroundWindow(), &msg)) {
|
||||||
|
@ -217,14 +220,14 @@ void pOS::initialize() {
|
||||||
RegisterClass(&wc);
|
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) {
|
if(msg == WM_KEYDOWN) {
|
||||||
GUITHREADINFO info;
|
GUITHREADINFO info;
|
||||||
memset(&info, 0, sizeof(GUITHREADINFO));
|
memset(&info, 0, sizeof(GUITHREADINFO));
|
||||||
info.cbSize = sizeof(GUITHREADINFO);
|
info.cbSize = sizeof(GUITHREADINFO);
|
||||||
GetGUIThreadInfo(GetCurrentThreadId(), &info);
|
GetGUIThreadInfo(GetCurrentThreadId(), &info);
|
||||||
Object *object = (Object*)GetWindowLongPtr(info.hwndFocus, GWLP_USERDATA);
|
Object *object = (Object*)GetWindowLongPtr(info.hwndFocus, GWLP_USERDATA);
|
||||||
if(object == 0) return;
|
if(object == nullptr) return false;
|
||||||
if(dynamic_cast<ListView*>(object)) {
|
if(dynamic_cast<ListView*>(object)) {
|
||||||
ListView &listView = (ListView&)*object;
|
ListView &listView = (ListView&)*object;
|
||||||
if(wparam == VK_RETURN) {
|
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(wparam == VK_RETURN) {
|
||||||
if(lineEdit.onActivate) lineEdit.onActivate();
|
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) {
|
static LRESULT CALLBACK OS_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||||
|
|
|
@ -18,9 +18,9 @@ rubylink += $(if $(findstring input.directinput,$(ruby)),-ldinput8 -ldxguid)
|
||||||
rubylink += $(if $(findstring input.rawinput,$(ruby)),-ldinput8 -ldxguid)
|
rubylink += $(if $(findstring input.rawinput,$(ruby)),-ldinput8 -ldxguid)
|
||||||
|
|
||||||
ifeq ($(platform),x)
|
ifeq ($(platform),x)
|
||||||
rubylink += $(if $(findstring audio.openal,$(ruby)),-lopenal)
|
rubylink += $(if $(findstring audio.openal,$(ruby)),-lopenal)
|
||||||
else ifeq ($(platform),osx)
|
else ifeq ($(platform),osx)
|
||||||
rubylink += $(if $(findstring audio.openal,$(ruby)),-framework OpenAL)
|
rubylink += $(if $(findstring audio.openal,$(ruby)),-framework OpenAL)
|
||||||
else ifeq ($(platform),win)
|
else ifeq ($(platform),win)
|
||||||
rubylink += $(if $(findstring audio.openal,$(ruby)),-lopenal32)
|
rubylink += $(if $(findstring audio.openal,$(ruby)),-lopenal32)
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -5,7 +5,7 @@ void Justifier::enter() {
|
||||||
while(true) {
|
while(true) {
|
||||||
unsigned next = cpu.vcounter() * 1364 + cpu.hcounter();
|
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));
|
bool offscreen = (x < 0 || y < 0 || x >= 256 || y >= (ppu.overscan() ? 240 : 225));
|
||||||
|
|
||||||
if(offscreen == false) {
|
if(offscreen == false) {
|
||||||
|
@ -20,23 +20,19 @@ void Justifier::enter() {
|
||||||
if(next < prev) {
|
if(next < prev) {
|
||||||
int nx1 = interface->inputPoll(port, Input::Device::Justifier, 0, (unsigned)Input::JustifierID::X);
|
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);
|
int ny1 = interface->inputPoll(port, Input::Device::Justifier, 0, (unsigned)Input::JustifierID::Y);
|
||||||
nx1 += x1;
|
nx1 += player1.x;
|
||||||
ny1 += y1;
|
ny1 += player1.y;
|
||||||
x1 = max(-16, min(256 + 16, nx1));
|
player1.x = max(-16, min(256 + 16, nx1));
|
||||||
y1 = max(-16, min(240 + 16, ny1));
|
player1.y = max(-16, min(240 + 16, ny1));
|
||||||
|
}
|
||||||
|
|
||||||
if(chained == true) {
|
if(next < prev && chained) {
|
||||||
int nx2 = interface->inputPoll(port, Input::Device::Justifiers, 1, (unsigned)Input::JustifierID::X);
|
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);
|
int ny2 = interface->inputPoll(port, Input::Device::Justifiers, 1, (unsigned)Input::JustifierID::Y);
|
||||||
nx2 += x2;
|
nx2 += player2.x;
|
||||||
ny2 += y2;
|
ny2 += player2.y;
|
||||||
x2 = max(-16, min(256 + 16, nx2));
|
player2.x = max(-16, min(256 + 16, nx2));
|
||||||
y2 = max(-16, min(240 + 16, ny2));
|
player2.y = 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prev = next;
|
prev = next;
|
||||||
|
@ -48,12 +44,13 @@ uint2 Justifier::data() {
|
||||||
if(counter >= 32) return 1;
|
if(counter >= 32) return 1;
|
||||||
|
|
||||||
if(counter == 0) {
|
if(counter == 0) {
|
||||||
trigger1 = interface->inputPoll(port, Input::Device::Justifier, 0, (unsigned)Input::JustifierID::Trigger);
|
player1.trigger = interface->inputPoll(port, Input::Device::Justifier, 0, (unsigned)Input::JustifierID::Trigger);
|
||||||
start1 = interface->inputPoll(port, Input::Device::Justifier, 0, (unsigned)Input::JustifierID::Start);
|
player1.start = 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);
|
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++) {
|
switch(counter++) {
|
||||||
|
@ -84,10 +81,10 @@ uint2 Justifier::data() {
|
||||||
case 22: return 0;
|
case 22: return 0;
|
||||||
case 23: return 1;
|
case 23: return 1;
|
||||||
|
|
||||||
case 24: return trigger1;
|
case 24: return player1.trigger;
|
||||||
case 25: return trigger2;
|
case 25: return player2.trigger;
|
||||||
case 26: return start1;
|
case 26: return player1.start;
|
||||||
case 27: return start2;
|
case 27: return player2.start;
|
||||||
case 28: return active;
|
case 28: return active;
|
||||||
|
|
||||||
case 29: return 0;
|
case 29: return 0;
|
||||||
|
@ -109,23 +106,23 @@ Justifier::Justifier(bool port, bool chained) : Controller(port), chained(chaine
|
||||||
counter = 0;
|
counter = 0;
|
||||||
active = 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) {
|
if(chained == false) {
|
||||||
x1 = 256 / 2;
|
player2.x = -1;
|
||||||
y1 = 240 / 2;
|
player2.y = -1;
|
||||||
x2 = -1;
|
|
||||||
y2 = -1;
|
|
||||||
} else {
|
} else {
|
||||||
x1 = 256 / 2 - 16;
|
player1.x -= 16;
|
||||||
y1 = 240 / 2;
|
player2.x += 16;
|
||||||
x2 = 256 / 2 + 16;
|
|
||||||
y2 = 240 / 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trigger1 = false;
|
|
||||||
trigger2 = false;
|
|
||||||
|
|
||||||
start1 = false;
|
|
||||||
start2 = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,8 +10,8 @@ struct Justifier : Controller {
|
||||||
unsigned counter;
|
unsigned counter;
|
||||||
|
|
||||||
bool active;
|
bool active;
|
||||||
signed x1, x2;
|
struct Player {
|
||||||
signed y1, y2;
|
signed x, y;
|
||||||
bool trigger1, trigger2;
|
bool trigger, start;
|
||||||
bool start1, start2;
|
} player1, player2;
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,10 +35,6 @@ void SuperScope::enter() {
|
||||||
x = max(-16, min(256 + 16, nx));
|
x = max(-16, min(256 + 16, nx));
|
||||||
y = max(-16, min(240 + 16, ny));
|
y = max(-16, min(240 + 16, ny));
|
||||||
offscreen = (x < 0 || y < 0 || x >= 256 || y >= (ppu.overscan() ? 240 : 225));
|
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;
|
prev = next;
|
||||||
|
|
|
@ -107,9 +107,9 @@ void Video::update() {
|
||||||
case Input::Device::Justifiers:
|
case Input::Device::Justifiers:
|
||||||
if(dynamic_cast<Justifier*>(input.port2)) {
|
if(dynamic_cast<Justifier*>(input.port2)) {
|
||||||
Justifier &device = (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;
|
if(device.chained == false) break;
|
||||||
draw_cursor(0x02e0, device.x2, device.y2);
|
draw_cursor(0x02e0, device.player2.x, device.player2.y);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,33 +10,23 @@ ui_objects += $(if $(call streq,$(platform),win),resource)
|
||||||
|
|
||||||
# platform
|
# platform
|
||||||
ifeq ($(platform),x)
|
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 := video.glx video.xv video.sdl
|
||||||
ruby += audio.alsa audio.openal audio.oss audio.pulseaudio audio.pulseaudiosimple audio.ao
|
ruby += audio.alsa audio.openal audio.oss audio.pulseaudio audio.pulseaudiosimple audio.ao
|
||||||
ruby += input.sdl input.x
|
ruby += input.sdl input.x
|
||||||
else ifeq ($(platform),osx)
|
else ifeq ($(platform),osx)
|
||||||
phoenix_compile = $(call compile,-DPHOENIX_QT)
|
|
||||||
link +=
|
|
||||||
|
|
||||||
ruby :=
|
ruby :=
|
||||||
ruby += audio.openal
|
ruby += audio.openal
|
||||||
ruby += input.carbon
|
ruby += input.carbon
|
||||||
else ifeq ($(platform),win)
|
else ifeq ($(platform),win)
|
||||||
phoenix_compile = $(call compile,-DPHOENIX_WINDOWS)
|
|
||||||
link +=
|
|
||||||
|
|
||||||
ruby := video.direct3d video.wgl video.directdraw video.gdi
|
ruby := video.direct3d video.wgl video.directdraw video.gdi
|
||||||
ruby += audio.directsound audio.xaudio2
|
ruby += audio.directsound audio.xaudio2
|
||||||
ruby += input.rawinput input.directinput
|
ruby += input.rawinput input.directinput
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# phoenix
|
||||||
|
include phoenix/Makefile
|
||||||
|
link += $(phoenixlink)
|
||||||
|
|
||||||
# ruby
|
# ruby
|
||||||
include ruby/Makefile
|
include ruby/Makefile
|
||||||
link += $(rubylink)
|
link += $(rubylink)
|
||||||
|
@ -59,7 +49,7 @@ obj/ruby.o: ruby/ruby.cpp $(call rwildcard,ruby/*)
|
||||||
$(call compile,$(rubyflags))
|
$(call compile,$(rubyflags))
|
||||||
|
|
||||||
obj/phoenix.o: phoenix/phoenix.cpp $(call rwildcard,phoenix/*)
|
obj/phoenix.o: phoenix/phoenix.cpp $(call rwildcard,phoenix/*)
|
||||||
$(phoenix_compile)
|
$(call compile,$(phoenixflags))
|
||||||
|
|
||||||
obj/resource.o: $(ui)/resource.rc
|
obj/resource.o: $(ui)/resource.rc
|
||||||
# windres --target=pe-i386 $(ui)/resource.rc obj/resource.o
|
# windres --target=pe-i386 $(ui)/resource.rc obj/resource.o
|
||||||
|
|
|
@ -27,7 +27,7 @@ void Application::run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Application::Application(int argc, char **argv) {
|
Application::Application(int argc, char **argv) {
|
||||||
title = "bsnes v084.04";
|
title = "bsnes v084.05";
|
||||||
|
|
||||||
application = this;
|
application = this;
|
||||||
quit = false;
|
quit = false;
|
||||||
|
|
Loading…
Reference in New Issue