2013-03-15 13:11:33 +00:00
|
|
|
namespace phoenix {
|
|
|
|
|
Update to v093r02 release.
byuu says:
Changelog:
- nall: fixed major memory leak in string class
- ruby: video shaders support #define-based settings now
- phoenix/GTK+: support > 256x256 icons for window / task bar / alt-tab
- sfc: remove random/ and config/, merge into system/
- ethos: delete higan.png (48x48), replace with higan512.png (512x512)
as new higan.png
- ethos: default gamma to 100% (no color adjustment)
- ethos: use "Video Shaders/Display Emulation/" instead of "Video
Shaders/Emulation/"
- use g++ instead of g++-4.7 (g++ -v must be >= 4.7)
- use -std=c++11 instead of -std=gnu++11
- applied a few patches from Debian upstream to make their packaging job
easier
So because colors are normalized in GLSL, I won't be able to offer video
shaders absolute color literals. We will have to perform basic color
conversion inside the core.
As such, the current plan is to create some sort of Emulator::Settings
interface. With that, I'll connect an option for color correction, which
will be on by default. For FC/SFC, that will mean gamma correction
(darker / stronger colors), and for GB/GBC/GBA, it will mean simulating
the weird brightness levels of the displays. I am undecided on whether
to use pea soup green for the GB or not. By not doing so, it'll be
easier for the display emulation shader to do it.
2013-11-09 11:45:54 +00:00
|
|
|
static GdkColor CreateColor(uint8_t r, uint8_t g, uint8_t b) {
|
|
|
|
GdkColor color;
|
|
|
|
color.pixel = (r << 16) | (g << 8) | (b << 0);
|
|
|
|
color.red = (r << 8) | (r << 0);
|
|
|
|
color.green = (g << 8) | (g << 0);
|
|
|
|
color.blue = (b << 8) | (b << 0);
|
|
|
|
return color;
|
|
|
|
}
|
|
|
|
|
2013-05-02 11:25:45 +00:00
|
|
|
static GdkPixbuf* CreatePixbuf(const nall::image& image, bool scale = false) {
|
2012-01-15 08:29:57 +00:00
|
|
|
nall::image gdkImage = image;
|
2012-06-18 10:13:51 +00:00
|
|
|
gdkImage.transform(0, 32, 255u << 24, 255u << 0, 255u << 8, 255u << 16);
|
2013-11-28 10:29:01 +00:00
|
|
|
if(scale) gdkImage.scale(15, 15);
|
2012-01-15 08:29:57 +00:00
|
|
|
|
2013-05-02 11:25:45 +00:00
|
|
|
GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, gdkImage.width, gdkImage.height);
|
2012-01-15 08:29:57 +00:00
|
|
|
memcpy(gdk_pixbuf_get_pixels(pixbuf), gdkImage.data, gdkImage.width * gdkImage.height * 4);
|
2012-06-18 10:13:51 +00:00
|
|
|
|
|
|
|
return pixbuf;
|
|
|
|
}
|
|
|
|
|
2013-05-02 11:25:45 +00:00
|
|
|
static GtkImage* CreateImage(const nall::image& image, bool scale = false) {
|
|
|
|
GdkPixbuf* pixbuf = CreatePixbuf(image, scale);
|
|
|
|
GtkImage* gtkImage = (GtkImage*)gtk_image_new_from_pixbuf(pixbuf);
|
2012-01-15 08:29:57 +00:00
|
|
|
g_object_unref(pixbuf);
|
|
|
|
return gtkImage;
|
|
|
|
}
|
|
|
|
|
2013-07-29 09:42:45 +00:00
|
|
|
static lstring DropPaths(GtkSelectionData* data) {
|
|
|
|
gchar** uris = gtk_selection_data_get_uris(data);
|
|
|
|
if(uris == nullptr) return {};
|
|
|
|
|
|
|
|
lstring paths;
|
|
|
|
for(unsigned n = 0; uris[n] != nullptr; n++) {
|
|
|
|
gchar* pathname = g_filename_from_uri(uris[n], nullptr, nullptr);
|
|
|
|
if(pathname == nullptr) continue;
|
|
|
|
|
|
|
|
string path = pathname;
|
|
|
|
g_free(pathname);
|
2013-12-03 10:01:59 +00:00
|
|
|
if(directory::exists(path) && !path.endsWith("/")) path.append("/");
|
2013-07-29 09:42:45 +00:00
|
|
|
paths.append(path);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_strfreev(uris);
|
|
|
|
return paths;
|
|
|
|
}
|
|
|
|
|
2013-11-28 10:29:01 +00:00
|
|
|
static Position GetDisplacement(Sizable* sizable) {
|
|
|
|
Position position;
|
|
|
|
while(sizable->state.parent) {
|
|
|
|
Position displacement = sizable->state.parent->p.displacement();
|
|
|
|
position.x += displacement.x;
|
|
|
|
position.y += displacement.y;
|
|
|
|
sizable = sizable->state.parent;
|
|
|
|
}
|
|
|
|
return position;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Layout* GetParentWidgetLayout(Sizable* sizable) {
|
|
|
|
while(sizable) {
|
|
|
|
if(sizable->state.parent && dynamic_cast<TabFrame*>(sizable->state.parent)) return (Layout*)sizable;
|
|
|
|
sizable = sizable->state.parent;
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Widget* GetParentWidget(Sizable* sizable) {
|
|
|
|
while(sizable) {
|
|
|
|
if(sizable->state.parent && dynamic_cast<TabFrame*>(sizable->state.parent)) return (Widget*)sizable->state.parent;
|
|
|
|
sizable = sizable->state.parent;
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2012-01-15 08:29:57 +00:00
|
|
|
static Keyboard::Keycode Keysym(unsigned keysym) {
|
|
|
|
switch(keysym) {
|
|
|
|
case GDK_Escape: return Keyboard::Keycode::Escape;
|
|
|
|
case GDK_F1: return Keyboard::Keycode::F1;
|
|
|
|
case GDK_F2: return Keyboard::Keycode::F2;
|
|
|
|
case GDK_F3: return Keyboard::Keycode::F3;
|
|
|
|
case GDK_F4: return Keyboard::Keycode::F4;
|
|
|
|
case GDK_F5: return Keyboard::Keycode::F5;
|
|
|
|
case GDK_F6: return Keyboard::Keycode::F6;
|
|
|
|
case GDK_F7: return Keyboard::Keycode::F7;
|
|
|
|
case GDK_F8: return Keyboard::Keycode::F8;
|
|
|
|
case GDK_F9: return Keyboard::Keycode::F9;
|
|
|
|
case GDK_F10: return Keyboard::Keycode::F10;
|
|
|
|
case GDK_F11: return Keyboard::Keycode::F11;
|
|
|
|
case GDK_F12: return Keyboard::Keycode::F12;
|
|
|
|
|
|
|
|
case GDK_Print: return Keyboard::Keycode::PrintScreen;
|
|
|
|
//Keyboard::Keycode::SysRq
|
|
|
|
case GDK_Scroll_Lock: return Keyboard::Keycode::ScrollLock;
|
|
|
|
case GDK_Pause: return Keyboard::Keycode::Pause;
|
|
|
|
//Keyboard::Keycode::Break
|
|
|
|
|
|
|
|
case GDK_Insert: return Keyboard::Keycode::Insert;
|
|
|
|
case GDK_Delete: return Keyboard::Keycode::Delete;
|
|
|
|
case GDK_Home: return Keyboard::Keycode::Home;
|
|
|
|
case GDK_End: return Keyboard::Keycode::End;
|
|
|
|
case GDK_Prior: return Keyboard::Keycode::PageUp;
|
|
|
|
case GDK_Next: return Keyboard::Keycode::PageDown;
|
|
|
|
|
|
|
|
case GDK_Up: return Keyboard::Keycode::Up;
|
|
|
|
case GDK_Down: return Keyboard::Keycode::Down;
|
|
|
|
case GDK_Left: return Keyboard::Keycode::Left;
|
|
|
|
case GDK_Right: return Keyboard::Keycode::Right;
|
|
|
|
|
|
|
|
case GDK_grave: return Keyboard::Keycode::Grave;
|
|
|
|
case GDK_1: return Keyboard::Keycode::Number1;
|
|
|
|
case GDK_2: return Keyboard::Keycode::Number2;
|
|
|
|
case GDK_3: return Keyboard::Keycode::Number3;
|
|
|
|
case GDK_4: return Keyboard::Keycode::Number4;
|
|
|
|
case GDK_5: return Keyboard::Keycode::Number5;
|
|
|
|
case GDK_6: return Keyboard::Keycode::Number6;
|
|
|
|
case GDK_7: return Keyboard::Keycode::Number7;
|
|
|
|
case GDK_8: return Keyboard::Keycode::Number8;
|
|
|
|
case GDK_9: return Keyboard::Keycode::Number9;
|
|
|
|
case GDK_0: return Keyboard::Keycode::Number0;
|
|
|
|
case GDK_minus: return Keyboard::Keycode::Minus;
|
|
|
|
case GDK_equal: return Keyboard::Keycode::Equal;
|
|
|
|
case GDK_BackSpace: return Keyboard::Keycode::Backspace;
|
|
|
|
|
|
|
|
case GDK_asciitilde: return Keyboard::Keycode::Tilde;
|
|
|
|
case GDK_exclam: return Keyboard::Keycode::Exclamation;
|
|
|
|
case GDK_at: return Keyboard::Keycode::At;
|
|
|
|
case GDK_numbersign: return Keyboard::Keycode::Pound;
|
|
|
|
case GDK_dollar: return Keyboard::Keycode::Dollar;
|
|
|
|
case GDK_percent: return Keyboard::Keycode::Percent;
|
|
|
|
case GDK_asciicircum: return Keyboard::Keycode::Power;
|
|
|
|
case GDK_ampersand: return Keyboard::Keycode::Ampersand;
|
|
|
|
case GDK_asterisk: return Keyboard::Keycode::Asterisk;
|
|
|
|
case GDK_parenleft: return Keyboard::Keycode::ParenthesisLeft;
|
|
|
|
case GDK_parenright: return Keyboard::Keycode::ParenthesisRight;
|
|
|
|
case GDK_underscore: return Keyboard::Keycode::Underscore;
|
|
|
|
case GDK_plus: return Keyboard::Keycode::Plus;
|
|
|
|
|
|
|
|
case GDK_bracketleft: return Keyboard::Keycode::BracketLeft;
|
|
|
|
case GDK_bracketright: return Keyboard::Keycode::BracketRight;
|
|
|
|
case GDK_backslash: return Keyboard::Keycode::Backslash;
|
|
|
|
case GDK_semicolon: return Keyboard::Keycode::Semicolon;
|
|
|
|
case GDK_apostrophe: return Keyboard::Keycode::Apostrophe;
|
|
|
|
case GDK_comma: return Keyboard::Keycode::Comma;
|
|
|
|
case GDK_period: return Keyboard::Keycode::Period;
|
|
|
|
case GDK_slash: return Keyboard::Keycode::Slash;
|
|
|
|
|
|
|
|
case GDK_braceleft: return Keyboard::Keycode::BraceLeft;
|
|
|
|
case GDK_braceright: return Keyboard::Keycode::BraceRight;
|
|
|
|
case GDK_bar: return Keyboard::Keycode::Pipe;
|
|
|
|
case GDK_colon: return Keyboard::Keycode::Colon;
|
|
|
|
case GDK_quotedbl: return Keyboard::Keycode::Quote;
|
|
|
|
case GDK_less: return Keyboard::Keycode::CaretLeft;
|
|
|
|
case GDK_greater: return Keyboard::Keycode::CaretRight;
|
|
|
|
case GDK_question: return Keyboard::Keycode::Question;
|
|
|
|
|
|
|
|
case GDK_Tab: return Keyboard::Keycode::Tab;
|
|
|
|
case GDK_Caps_Lock: return Keyboard::Keycode::CapsLock;
|
|
|
|
case GDK_Return: return Keyboard::Keycode::Return;
|
|
|
|
case GDK_Shift_L: return Keyboard::Keycode::ShiftLeft;
|
|
|
|
case GDK_Shift_R: return Keyboard::Keycode::ShiftRight;
|
|
|
|
case GDK_Control_L: return Keyboard::Keycode::ControlLeft;
|
|
|
|
case GDK_Control_R: return Keyboard::Keycode::ControlRight;
|
|
|
|
case GDK_Super_L: return Keyboard::Keycode::SuperLeft;
|
|
|
|
case GDK_Super_R: return Keyboard::Keycode::SuperRight;
|
|
|
|
case GDK_Alt_L: return Keyboard::Keycode::AltLeft;
|
|
|
|
case GDK_Alt_R: return Keyboard::Keycode::AltRight;
|
|
|
|
case GDK_space: return Keyboard::Keycode::Space;
|
|
|
|
case GDK_Menu: return Keyboard::Keycode::Menu;
|
|
|
|
|
|
|
|
case GDK_A: return Keyboard::Keycode::A;
|
|
|
|
case GDK_B: return Keyboard::Keycode::B;
|
|
|
|
case GDK_C: return Keyboard::Keycode::C;
|
|
|
|
case GDK_D: return Keyboard::Keycode::D;
|
|
|
|
case GDK_E: return Keyboard::Keycode::E;
|
|
|
|
case GDK_F: return Keyboard::Keycode::F;
|
|
|
|
case GDK_G: return Keyboard::Keycode::G;
|
|
|
|
case GDK_H: return Keyboard::Keycode::H;
|
|
|
|
case GDK_I: return Keyboard::Keycode::I;
|
|
|
|
case GDK_J: return Keyboard::Keycode::J;
|
|
|
|
case GDK_K: return Keyboard::Keycode::K;
|
|
|
|
case GDK_L: return Keyboard::Keycode::L;
|
|
|
|
case GDK_M: return Keyboard::Keycode::M;
|
|
|
|
case GDK_N: return Keyboard::Keycode::N;
|
|
|
|
case GDK_O: return Keyboard::Keycode::O;
|
|
|
|
case GDK_P: return Keyboard::Keycode::P;
|
|
|
|
case GDK_Q: return Keyboard::Keycode::Q;
|
|
|
|
case GDK_R: return Keyboard::Keycode::R;
|
|
|
|
case GDK_S: return Keyboard::Keycode::S;
|
|
|
|
case GDK_T: return Keyboard::Keycode::T;
|
|
|
|
case GDK_U: return Keyboard::Keycode::U;
|
|
|
|
case GDK_V: return Keyboard::Keycode::V;
|
|
|
|
case GDK_W: return Keyboard::Keycode::W;
|
|
|
|
case GDK_X: return Keyboard::Keycode::X;
|
|
|
|
case GDK_Y: return Keyboard::Keycode::Y;
|
|
|
|
case GDK_Z: return Keyboard::Keycode::Z;
|
|
|
|
|
|
|
|
case GDK_a: return Keyboard::Keycode::a;
|
|
|
|
case GDK_b: return Keyboard::Keycode::b;
|
|
|
|
case GDK_c: return Keyboard::Keycode::c;
|
|
|
|
case GDK_d: return Keyboard::Keycode::d;
|
|
|
|
case GDK_e: return Keyboard::Keycode::e;
|
|
|
|
case GDK_f: return Keyboard::Keycode::f;
|
|
|
|
case GDK_g: return Keyboard::Keycode::g;
|
|
|
|
case GDK_h: return Keyboard::Keycode::h;
|
|
|
|
case GDK_i: return Keyboard::Keycode::i;
|
|
|
|
case GDK_j: return Keyboard::Keycode::j;
|
|
|
|
case GDK_k: return Keyboard::Keycode::k;
|
|
|
|
case GDK_l: return Keyboard::Keycode::l;
|
|
|
|
case GDK_m: return Keyboard::Keycode::m;
|
|
|
|
case GDK_n: return Keyboard::Keycode::n;
|
|
|
|
case GDK_o: return Keyboard::Keycode::o;
|
|
|
|
case GDK_p: return Keyboard::Keycode::p;
|
|
|
|
case GDK_q: return Keyboard::Keycode::q;
|
|
|
|
case GDK_r: return Keyboard::Keycode::r;
|
|
|
|
case GDK_s: return Keyboard::Keycode::s;
|
|
|
|
case GDK_t: return Keyboard::Keycode::t;
|
|
|
|
case GDK_u: return Keyboard::Keycode::u;
|
|
|
|
case GDK_v: return Keyboard::Keycode::v;
|
|
|
|
case GDK_w: return Keyboard::Keycode::w;
|
|
|
|
case GDK_x: return Keyboard::Keycode::x;
|
|
|
|
case GDK_y: return Keyboard::Keycode::y;
|
|
|
|
case GDK_z: return Keyboard::Keycode::z;
|
|
|
|
|
|
|
|
case GDK_Num_Lock: return Keyboard::Keycode::NumLock;
|
|
|
|
case GDK_KP_Divide: return Keyboard::Keycode::Divide;
|
|
|
|
case GDK_KP_Multiply: return Keyboard::Keycode::Multiply;
|
|
|
|
case GDK_KP_Subtract: return Keyboard::Keycode::Subtract;
|
|
|
|
case GDK_KP_Add: return Keyboard::Keycode::Add;
|
|
|
|
case GDK_KP_Enter: return Keyboard::Keycode::Enter;
|
|
|
|
case GDK_KP_Decimal: return Keyboard::Keycode::Point;
|
|
|
|
|
|
|
|
case GDK_KP_1: return Keyboard::Keycode::Keypad1;
|
|
|
|
case GDK_KP_2: return Keyboard::Keycode::Keypad2;
|
|
|
|
case GDK_KP_3: return Keyboard::Keycode::Keypad3;
|
|
|
|
case GDK_KP_4: return Keyboard::Keycode::Keypad4;
|
|
|
|
case GDK_KP_5: return Keyboard::Keycode::Keypad5;
|
|
|
|
case GDK_KP_6: return Keyboard::Keycode::Keypad6;
|
|
|
|
case GDK_KP_7: return Keyboard::Keycode::Keypad7;
|
|
|
|
case GDK_KP_8: return Keyboard::Keycode::Keypad8;
|
|
|
|
case GDK_KP_9: return Keyboard::Keycode::Keypad9;
|
|
|
|
case GDK_KP_0: return Keyboard::Keycode::Keypad0;
|
|
|
|
|
|
|
|
case GDK_KP_Home: return Keyboard::Keycode::KeypadHome;
|
|
|
|
case GDK_KP_End: return Keyboard::Keycode::KeypadEnd;
|
|
|
|
case GDK_KP_Page_Up: return Keyboard::Keycode::KeypadPageUp;
|
|
|
|
case GDK_KP_Page_Down: return Keyboard::Keycode::KeypadPageDown;
|
|
|
|
case GDK_KP_Up: return Keyboard::Keycode::KeypadUp;
|
|
|
|
case GDK_KP_Down: return Keyboard::Keycode::KeypadDown;
|
|
|
|
case GDK_KP_Left: return Keyboard::Keycode::KeypadLeft;
|
|
|
|
case GDK_KP_Right: return Keyboard::Keycode::KeypadRight;
|
|
|
|
case GDK_KP_Begin: return Keyboard::Keycode::KeypadCenter;
|
|
|
|
case GDK_KP_Insert: return Keyboard::Keycode::KeypadInsert;
|
|
|
|
case GDK_KP_Delete: return Keyboard::Keycode::KeypadDelete;
|
|
|
|
}
|
|
|
|
return Keyboard::Keycode::None;
|
|
|
|
}
|
2013-03-15 13:11:33 +00:00
|
|
|
|
|
|
|
}
|