Linux (gtk):
- Remove gtk pixbuf usage on drawing DS screens, use only Cairo. - Use transformation matrix to handle touchscreen coordinates. - Adapt RGB555-to-RGBA8888 conversion code from Cocoa port, should result in brighter colour. - Re-enable fullscreen menu item on start.
This commit is contained in:
parent
4fec0a060e
commit
2fe8cb330d
|
@ -84,10 +84,7 @@
|
|||
|
||||
#define EMULOOP_PRIO (G_PRIORITY_HIGH_IDLE + 20 + 1)
|
||||
|
||||
#define SCREENS_PIXEL_SIZE (256*192*2)
|
||||
#define SCREEN_BYTES_PER_PIXEL 3
|
||||
#define GAP_SIZE 64
|
||||
#define GAP_COLOR (0x000000)
|
||||
|
||||
static int gtk_fps_limiter_disabled;
|
||||
static int draw_count;
|
||||
|
@ -262,10 +259,11 @@ static const char *ui_description =
|
|||
" <menuitem action='pri_interp_5xbrz'/>"
|
||||
" </menu>"
|
||||
" <menu action='InterpolationMenu'>"
|
||||
" <menuitem action='interp_fast'/>"
|
||||
" <menuitem action='interp_nearest'/>"
|
||||
" <menuitem action='interp_tiles'/>"
|
||||
" <menuitem action='interp_good'/>"
|
||||
" <menuitem action='interp_bilinear'/>"
|
||||
" <menuitem action='interp_hyper'/>"
|
||||
" <menuitem action='interp_best'/>"
|
||||
" </menu>"
|
||||
" <menu action='HudMenu'>"
|
||||
#ifdef HAVE_LIBAGG
|
||||
|
@ -392,8 +390,8 @@ static const GtkActionEntry action_entries[] = {
|
|||
{ "RotationMenu", NULL, "_Rotation" },
|
||||
{ "OrientationMenu", NULL, "LCDs _Layout" },
|
||||
{ "WinsizeMenu", NULL, "_Window Size" },
|
||||
{ "PriInterpolationMenu", NULL, "Primary _Interpolation" },
|
||||
{ "InterpolationMenu", NULL, "S_econdary Interpolation" },
|
||||
{ "PriInterpolationMenu", NULL, "Video _Filter" },
|
||||
{ "InterpolationMenu", NULL, "S_econdary Video Filter" },
|
||||
{ "HudMenu", NULL, "_HUD" },
|
||||
#ifndef HAVE_LIBAGG
|
||||
{ "hud_notsupported", NULL, "HUD support not compiled" },
|
||||
|
@ -459,10 +457,11 @@ static const GtkRadioActionEntry pri_interpolation_entries[] = {
|
|||
};
|
||||
|
||||
static const GtkRadioActionEntry interpolation_entries[] = {
|
||||
{ "interp_nearest", NULL, "_Nearest", NULL, NULL, GDK_INTERP_NEAREST},
|
||||
{ "interp_tiles", NULL, "_Tiles", NULL, NULL, GDK_INTERP_TILES},
|
||||
{ "interp_bilinear", NULL, "_Bilinear", NULL, NULL, GDK_INTERP_BILINEAR},
|
||||
{ "interp_hyper", NULL, "_Hyper", NULL, NULL, GDK_INTERP_HYPER},
|
||||
{ "interp_fast", NULL, "_Fast", NULL, NULL, CAIRO_FILTER_FAST },
|
||||
{ "interp_nearest", NULL, "_Nearest-neighbor", NULL, NULL, CAIRO_FILTER_NEAREST },
|
||||
{ "interp_good", NULL, "_Good", NULL, NULL, CAIRO_FILTER_GOOD },
|
||||
{ "interp_bilinear", NULL, "_Bilinear", NULL, NULL, CAIRO_FILTER_BILINEAR },
|
||||
{ "interp_best", NULL, "B_est", NULL, NULL, CAIRO_FILTER_BEST },
|
||||
};
|
||||
|
||||
static const GtkRadioActionEntry rotation_entries[] = {
|
||||
|
@ -763,7 +762,7 @@ uint SPUMode = SPUMODE_DUALASYNC;
|
|||
uint Frameskip = 0;
|
||||
uint autoFrameskipMax = 0;
|
||||
bool autoframeskip = true;
|
||||
GdkInterpType Interpolation = GDK_INTERP_NEAREST;
|
||||
cairo_filter_t Interpolation = CAIRO_FILTER_NEAREST;
|
||||
|
||||
static GtkWidget *pWindow;
|
||||
static GtkWidget *pStatusBar;
|
||||
|
@ -774,11 +773,8 @@ static GtkUIManager *ui_manager;
|
|||
struct nds_screen_t {
|
||||
guint gap_size;
|
||||
gint rotation_angle;
|
||||
guint orientation;
|
||||
gint touch_x;
|
||||
gint touch_y;
|
||||
gint touch_width;
|
||||
gint touch_height;
|
||||
orientation_enum orientation;
|
||||
cairo_matrix_t touch_matrix;
|
||||
gboolean swap;
|
||||
};
|
||||
|
||||
|
@ -1412,9 +1408,6 @@ static void UpdateDrawingAreaAspect()
|
|||
H = screen_size[nds_screen.orientation].width;
|
||||
}
|
||||
|
||||
// The gap is added after filtering
|
||||
video.SetSourceSize(W, H);
|
||||
|
||||
if (nds_screen.orientation != ORIENT_SINGLE) {
|
||||
if (nds_screen.orientation == ORIENT_VERTICAL) {
|
||||
if ((nds_screen.rotation_angle == 0 || nds_screen.rotation_angle == 180)) {
|
||||
|
@ -1455,7 +1448,7 @@ static void SetWinsize(GtkAction *action, GtkRadioAction *current)
|
|||
|
||||
static void SetOrientation(GtkAction *action, GtkRadioAction *current)
|
||||
{
|
||||
nds_screen.orientation = gtk_radio_action_get_current_value(current);
|
||||
nds_screen.orientation = (orientation_enum)gtk_radio_action_get_current_value(current);
|
||||
UpdateDrawingAreaAspect();
|
||||
}
|
||||
|
||||
|
@ -1468,230 +1461,189 @@ static int ConfigureDrawingArea(GtkWidget *widget, GdkEventConfigure *event, gpo
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
// Adapted from Cocoa port
|
||||
static const uint8_t bits5to8[] = {
|
||||
0x00, 0x08, 0x10, 0x19, 0x21, 0x29, 0x31, 0x3A,
|
||||
0x42, 0x4A, 0x52, 0x5A, 0x63, 0x6B, 0x73, 0x7B,
|
||||
0x84, 0x8C, 0x94, 0x9C, 0xA5, 0xAD, 0xB5, 0xBD,
|
||||
0xC5, 0xCE, 0xD6, 0xDE, 0xE6, 0xEF, 0xF7, 0xFF
|
||||
};
|
||||
|
||||
static inline void gpu_screen_to_rgb(guchar * rgb, int size, int pixelsize)
|
||||
static inline uint32_t RGB555ToRGBA8888(const uint16_t color16)
|
||||
{
|
||||
gint rot = nds_screen.rotation_angle;
|
||||
gint height, width;
|
||||
u16 gpu_pixel;
|
||||
u32 offset;
|
||||
return (bits5to8[((color16 >> 0) & 0x001F)] << 0) |
|
||||
(bits5to8[((color16 >> 5) & 0x001F)] << 8) |
|
||||
(bits5to8[((color16 >> 10) & 0x001F)] << 16) |
|
||||
0xFF000000;
|
||||
}
|
||||
|
||||
width = screen_size[nds_screen.orientation].width;
|
||||
height = screen_size[nds_screen.orientation].height;
|
||||
// Adapted from Cocoa port
|
||||
static inline void RGB555ToRGBA8888Buffer(const uint16_t *__restrict__ srcBuffer, uint32_t *__restrict__ destBuffer, size_t pixelCount)
|
||||
{
|
||||
const uint32_t *__restrict__ destBufferEnd = destBuffer + pixelCount;
|
||||
|
||||
while (destBuffer < destBufferEnd)
|
||||
{
|
||||
*destBuffer++ = RGB555ToRGBA8888(*srcBuffer++);
|
||||
}
|
||||
}
|
||||
|
||||
for (gint i = 0; i < width; i++) {
|
||||
for (gint j = 0; j < height; j++) {
|
||||
gint row = j, col = i;
|
||||
static inline void gpu_screen_to_rgb(u32* dst)
|
||||
{
|
||||
RGB555ToRGBA8888Buffer((u16*)GPU_screen, dst, 256 * 384);
|
||||
}
|
||||
|
||||
if (i >= 256) {
|
||||
col = i - 256;
|
||||
row = j + 192;
|
||||
}
|
||||
if (nds_screen.swap)
|
||||
row = (row + 192) % 384;
|
||||
static inline void drawScreen(cairo_t* cr, u32* buf, gint w, gint h) {
|
||||
cairo_surface_t* surf = cairo_image_surface_create_for_data((u8*)buf, CAIRO_FORMAT_RGB24, w, h, w * 4);
|
||||
cairo_set_source_surface(cr, surf, 0, 0);
|
||||
cairo_pattern_set_filter(cairo_get_source(cr), Interpolation);
|
||||
cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_PAD);
|
||||
cairo_rectangle(cr, 0, 0, w, h);
|
||||
cairo_fill(cr);
|
||||
cairo_surface_destroy(surf);
|
||||
}
|
||||
|
||||
gpu_pixel = *((u16 *) & GPU_screen[(col + row * 256) << 1]);
|
||||
static inline void drawTopScreen(cairo_t* cr, u32* buf, gint w, gint h, gint gap, gint rotation_angle, bool swap, orientation_enum orientation) {
|
||||
if (orientation == ORIENT_SINGLE && swap) {
|
||||
return;
|
||||
}
|
||||
cairo_save(cr);
|
||||
switch (orientation) {
|
||||
case ORIENT_VERTICAL:
|
||||
if (swap) {
|
||||
cairo_translate(cr, 0, h + gap);
|
||||
}
|
||||
break;
|
||||
case ORIENT_HORIZONTAL:
|
||||
if (swap) {
|
||||
cairo_translate(cr, w, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
drawScreen(cr, buf, w, h);
|
||||
cairo_restore(cr);
|
||||
}
|
||||
|
||||
if (rot == 0 || rot == 180)
|
||||
offset = i * pixelsize + j * pixelsize * width;
|
||||
else
|
||||
offset = j * pixelsize + (width - i - 1) * pixelsize * height;
|
||||
|
||||
if (rot == 90 || rot == 180)
|
||||
offset = size - offset - pixelsize;
|
||||
|
||||
*(rgb + offset + 0) = ((gpu_pixel >> 0) & 0x1f) << 3;
|
||||
*(rgb + offset + 1) = ((gpu_pixel >> 5) & 0x1f) << 3;
|
||||
*(rgb + offset + 2) = ((gpu_pixel >> 10) & 0x1f) << 3;
|
||||
}
|
||||
}
|
||||
static inline void drawBottomScreen(cairo_t* cr, u32* buf, gint w, gint h, gint gap, gint rotation_angle, bool swap, orientation_enum orientation) {
|
||||
if (orientation == ORIENT_SINGLE && !swap) {
|
||||
return;
|
||||
}
|
||||
cairo_save(cr);
|
||||
switch (orientation) {
|
||||
case ORIENT_VERTICAL:
|
||||
if (!swap) {
|
||||
cairo_translate(cr, 0, h + gap);
|
||||
}
|
||||
break;
|
||||
case ORIENT_HORIZONTAL:
|
||||
if (!swap) {
|
||||
cairo_translate(cr, w, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Store the inverted matrix for converting touchscreen coordinates
|
||||
cairo_get_matrix(cr, &nds_screen.touch_matrix);
|
||||
drawScreen(cr, buf, w, h);
|
||||
cairo_restore(cr);
|
||||
}
|
||||
|
||||
/* Drawing callback */
|
||||
static gboolean ExposeDrawingArea (GtkWidget *widget, GdkEventExpose *event, gpointer data)
|
||||
{
|
||||
GdkPixbuf *resizedPixbuf, *drawPixbuf;
|
||||
cairo_t *cr;
|
||||
GdkWindow *window;
|
||||
|
||||
gfloat vratio, hratio, nscreen_ratio;
|
||||
gint daW, daH, imgW, imgH, screenW, screenH, gapW, gapH;
|
||||
gint primaryOffsetX, primaryOffsetY, secondaryOffsetX, secondaryOffsetY;
|
||||
const gboolean gap_vertical = ((nds_screen.orientation == ORIENT_VERTICAL) ^ (nds_screen.rotation_angle == 90 || nds_screen.rotation_angle == 270));
|
||||
|
||||
window = gtk_widget_get_window(GTK_WIDGET(pDrawingArea));
|
||||
GdkWindow* window = gtk_widget_get_window(widget);
|
||||
gint daW, daH;
|
||||
#if GTK_CHECK_VERSION(2,24,0)
|
||||
daW = gdk_window_get_width(window);
|
||||
daH = gdk_window_get_height(window);
|
||||
daW = gdk_window_get_width(window);
|
||||
daH = gdk_window_get_height(window);
|
||||
#else
|
||||
gdk_drawable_get_size(window, &daW, &daH);
|
||||
gdk_drawable_get_size(window, &daW, &daH);
|
||||
#endif
|
||||
|
||||
if (nds_screen.rotation_angle == 0 || nds_screen.rotation_angle == 180) {
|
||||
imgW = screen_size[nds_screen.orientation].width;
|
||||
imgH = screen_size[nds_screen.orientation].height;
|
||||
} else {
|
||||
imgH = screen_size[nds_screen.orientation].width;
|
||||
imgW = screen_size[nds_screen.orientation].height;
|
||||
}
|
||||
#ifdef HAVE_LIBAGG
|
||||
osd->update();
|
||||
DrawHUD();
|
||||
osd->clear();
|
||||
#endif
|
||||
|
||||
if (nds_screen.orientation != ORIENT_VERTICAL) {
|
||||
gapH = 0;
|
||||
gapW = 0;
|
||||
} else if (gap_vertical) {
|
||||
gapH = nds_screen.gap_size;
|
||||
gapW = 0;
|
||||
} else {
|
||||
gapH = 0;
|
||||
gapW = nds_screen.gap_size;
|
||||
}
|
||||
gpu_screen_to_rgb(video.GetSrcBufferPtr());
|
||||
|
||||
hratio = (float)daW / (float)(imgW + gapW);
|
||||
vratio = (float)daH / (float)(imgH + gapH);
|
||||
hratio = MIN(hratio, vratio);
|
||||
vratio = hratio;
|
||||
u32* fbuf = video.RunFilter();
|
||||
gint dstW = video.GetDstWidth();
|
||||
gint dstH = video.GetDstHeight();
|
||||
// Convert from RGBA to BGRX
|
||||
CACHE_ALIGN u32 conv_buf[dstW * dstH];
|
||||
for (u32 *p = conv_buf, *pe = conv_buf + dstW * dstH; p < pe; p++)
|
||||
{
|
||||
*p = __builtin_bswap32(*fbuf++) >> 8;
|
||||
}
|
||||
|
||||
primaryOffsetX = (daW-(int)(hratio*(float)(imgW+gapW)))/2;
|
||||
primaryOffsetY = (daH-(int)(vratio*(float)(imgH+gapH)))/2;
|
||||
gint dstScale = dstW * 2 / 256; // Actual scale * 2 to handle 1.5x filters
|
||||
|
||||
gint gap = nds_screen.orientation == ORIENT_VERTICAL ? nds_screen.gap_size * dstScale / 2 : 0;
|
||||
gint imgW, imgH;
|
||||
if (nds_screen.rotation_angle == 0 || nds_screen.rotation_angle == 180) {
|
||||
imgW = screen_size[nds_screen.orientation].width * dstScale / 2;
|
||||
imgH = screen_size[nds_screen.orientation].height * dstScale / 2 + gap;
|
||||
} else {
|
||||
imgH = screen_size[nds_screen.orientation].width * dstScale / 2;
|
||||
imgW = screen_size[nds_screen.orientation].height * dstScale / 2 + gap;
|
||||
}
|
||||
|
||||
nscreen_ratio = nds_screen.orientation == ORIENT_SINGLE ? 1 : 0.5;
|
||||
if (gap_vertical) {
|
||||
screenW = (int)(hratio*(float)(imgW));
|
||||
screenH = (int)(vratio*(float)(imgH)*nscreen_ratio);
|
||||
secondaryOffsetX = primaryOffsetX;
|
||||
secondaryOffsetY = primaryOffsetY + screenH + (int)(vratio * (float)gapH);
|
||||
} else {
|
||||
screenW = (int)(hratio*(float)(imgW)*nscreen_ratio);
|
||||
screenH = (int)(vratio*(float)(imgH));
|
||||
secondaryOffsetX = primaryOffsetX + screenW + (int)(hratio * (float)gapW);
|
||||
secondaryOffsetY = primaryOffsetY;
|
||||
}
|
||||
// Calculate scale to fit display area to window
|
||||
gfloat hratio = (gfloat)daW / (gfloat)imgW;
|
||||
gfloat vratio = (gfloat)daH / (gfloat)imgH;
|
||||
hratio = MIN(hratio, vratio);
|
||||
vratio = hratio;
|
||||
|
||||
if ((nds_screen.swap) ^
|
||||
((nds_screen.orientation == ORIENT_VERTICAL && (nds_screen.rotation_angle == 90 || nds_screen.rotation_angle == 180)) ||
|
||||
(nds_screen.orientation == ORIENT_HORIZONTAL && (nds_screen.rotation_angle == 180 || nds_screen.rotation_angle == 270)))) {
|
||||
nds_screen.touch_x = primaryOffsetX;
|
||||
nds_screen.touch_y = primaryOffsetY;
|
||||
} else if (nds_screen.orientation != ORIENT_SINGLE) {
|
||||
nds_screen.touch_x = secondaryOffsetX;
|
||||
nds_screen.touch_y = secondaryOffsetY;
|
||||
} else {
|
||||
nds_screen.touch_x = -1;
|
||||
nds_screen.touch_y = -1;
|
||||
}
|
||||
nds_screen.touch_width = screenW;
|
||||
nds_screen.touch_height = screenH;
|
||||
cairo_t* cr = gdk_cairo_create(window);
|
||||
|
||||
osd->update();
|
||||
DrawHUD();
|
||||
// Scale to window size at center of area
|
||||
cairo_translate(cr, daW / 2, daH / 2);
|
||||
cairo_scale(cr, hratio, vratio);
|
||||
// Rotate area
|
||||
cairo_rotate(cr, M_PI / 180 * nds_screen.rotation_angle);
|
||||
// Translate area to top-left corner
|
||||
if (nds_screen.rotation_angle == 0 || nds_screen.rotation_angle == 180) {
|
||||
cairo_translate(cr, -imgW / 2, -imgH / 2);
|
||||
} else {
|
||||
cairo_translate(cr, -imgH / 2, -imgW / 2);
|
||||
}
|
||||
// Draw both screens
|
||||
drawTopScreen(cr, conv_buf, dstW, dstH / 2, gap, nds_screen.rotation_angle, nds_screen.swap, nds_screen.orientation);
|
||||
drawBottomScreen(cr, conv_buf + dstW * dstH / 2, dstW, dstH / 2, gap, nds_screen.rotation_angle, nds_screen.swap, nds_screen.orientation);
|
||||
// Draw gap
|
||||
cairo_set_source_rgb(cr, 0.3, 0.3, 0.3);
|
||||
cairo_rectangle(cr, 0, dstH / 2, dstW, gap);
|
||||
cairo_fill(cr);
|
||||
// Correct the touchscreen matrix
|
||||
cairo_matrix_scale(&nds_screen.touch_matrix, (double)dstScale / 2, (double)dstScale / 2);
|
||||
cairo_matrix_invert(&nds_screen.touch_matrix);
|
||||
|
||||
gpu_screen_to_rgb((u8*)video.GetSrcBufferPtr(), imgW*imgH*4, 4);
|
||||
|
||||
u32* fbuf = video.RunFilter();
|
||||
int dstW = video.GetDstWidth();
|
||||
int dstH = video.GetDstHeight();
|
||||
int dstScale = (dstH / imgH); // Assumed to be integer
|
||||
int dstGapH = gapH * dstScale;
|
||||
int dstGapW = gapW * dstScale;
|
||||
//Convert to 24-bit
|
||||
guchar dsurf24[(dstW+dstGapW)*(dstH+dstGapH)*SCREEN_BYTES_PER_PIXEL];
|
||||
gint i=0, k=0, x, y;
|
||||
// Top half
|
||||
for (x = 0; x < dstH / 2; x++) {
|
||||
// Left half
|
||||
for (y = 0; y < dstW / 2; y++, i++) {
|
||||
*(u32*) &(dsurf24[k]) = fbuf[i];
|
||||
k += 3;
|
||||
}
|
||||
// Vertical gap
|
||||
for(y = 0; y < dstGapW; y++) {
|
||||
*(u32*) &(dsurf24[k]) = GAP_COLOR;
|
||||
k += 3;
|
||||
}
|
||||
// Right half
|
||||
for (y = 0; y < dstW / 2; y++, i++) {
|
||||
*(u32*) &(dsurf24[k]) = fbuf[i];
|
||||
k += 3;
|
||||
}
|
||||
}
|
||||
// Horizontal gap
|
||||
for (x = 0; x < dstGapH; x++) {
|
||||
for(y = 0; y < dstW + dstGapW; y++) {
|
||||
*(u32*) &(dsurf24[k]) = GAP_COLOR;
|
||||
k += 3;
|
||||
}
|
||||
}
|
||||
// Bottom half
|
||||
for (x = 0; x < dstH / 2; x++) {
|
||||
// Left half
|
||||
for (y = 0; y < dstW / 2; y++, i++) {
|
||||
*(u32*) &(dsurf24[k]) = fbuf[i];
|
||||
k += 3;
|
||||
}
|
||||
// Mid gap
|
||||
for(y = 0; y < dstGapW; y++) {
|
||||
*(u32*) &(dsurf24[k]) = GAP_COLOR;
|
||||
k += 3;
|
||||
}
|
||||
// Right half
|
||||
for (y = 0; y < dstW / 2; y++, i++) {
|
||||
*(u32*) &(dsurf24[k]) = fbuf[i];
|
||||
k += 3;
|
||||
}
|
||||
}
|
||||
|
||||
drawPixbuf = gdk_pixbuf_new_from_data(dsurf24, GDK_COLORSPACE_RGB,
|
||||
FALSE, 8, dstW + dstGapW, dstH + dstGapH, (dstW + dstGapW) * SCREEN_BYTES_PER_PIXEL, NULL, NULL);
|
||||
cairo_destroy(cr);
|
||||
draw_count++;
|
||||
|
||||
resizedPixbuf = gdk_pixbuf_scale_simple(drawPixbuf, hratio*(imgW+gapW), vratio*(imgH+gapH),
|
||||
Interpolation);
|
||||
g_object_unref(drawPixbuf);
|
||||
drawPixbuf = resizedPixbuf;
|
||||
|
||||
cr = gdk_cairo_create(widget->window);
|
||||
gdk_cairo_set_source_pixbuf(cr, drawPixbuf, 0, 0);
|
||||
|
||||
if (nds_screen.orientation != ORIENT_SINGLE) {
|
||||
gdk_cairo_set_source_pixbuf(cr, drawPixbuf, primaryOffsetX, primaryOffsetY);
|
||||
}
|
||||
|
||||
g_object_unref(drawPixbuf); //drawPixbuf was never unref'd, so its ref count stayed above 0 and it was never freed
|
||||
|
||||
cairo_paint(cr);
|
||||
cairo_destroy(cr);
|
||||
draw_count++;
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/////////////////////////////// KEYS AND STYLUS UPDATE ///////////////////////////////////////
|
||||
|
||||
static gboolean rotoscaled_touchpos(gint x, gint y, gboolean start)
|
||||
{
|
||||
double devX, devY;
|
||||
u16 EmuX, EmuY;
|
||||
gint X, Y;
|
||||
|
||||
if (nds_screen.touch_x == -1 || nds_screen.touch_y == -1) {
|
||||
if (nds_screen.orientation == ORIENT_SINGLE && !nds_screen.swap) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (nds_screen.rotation_angle == 0 || nds_screen.rotation_angle == 180) {
|
||||
X = (x - nds_screen.touch_x) * 256 / nds_screen.touch_width;
|
||||
Y = (y - nds_screen.touch_y) * 192 / nds_screen.touch_height;
|
||||
} else {
|
||||
X = (y - nds_screen.touch_y) * 256 / nds_screen.touch_height;
|
||||
Y = (x - nds_screen.touch_x) * 192 / nds_screen.touch_width;
|
||||
}
|
||||
devX = x;
|
||||
devY = y;
|
||||
cairo_matrix_transform_point(&nds_screen.touch_matrix, &devX, &devY);
|
||||
X = devX;
|
||||
Y = devY;
|
||||
|
||||
if (nds_screen.rotation_angle == 180 || nds_screen.rotation_angle == 270) {
|
||||
X = 255 - X;
|
||||
}
|
||||
|
||||
if (nds_screen.rotation_angle == 90 || nds_screen.rotation_angle == 180) {
|
||||
Y = 191 - Y;
|
||||
}
|
||||
|
||||
LOG("X=%d, Y=%d\n",x,y);
|
||||
LOG("X=%d, Y=%d\n", X, Y);
|
||||
|
||||
if (!start || (X >= 0 && Y >= 0 && X < 256 && Y < 192)) {
|
||||
EmuX = CLAMP(X, 0, 255);
|
||||
|
@ -2073,13 +2025,13 @@ static void Printscreen()
|
|||
GdkPixbuf *screenshot;
|
||||
gchar *filename, *filen;
|
||||
GError *error = NULL;
|
||||
u8 *rgb;
|
||||
u8 rgb[256 * 384 * 4];
|
||||
static int seq = 0;
|
||||
gint H, W;
|
||||
|
||||
rgb = (u8 *) malloc(SCREENS_PIXEL_SIZE*SCREEN_BYTES_PER_PIXEL);
|
||||
if (!rgb)
|
||||
return;
|
||||
//rgb = (u8 *) malloc(SCREENS_PIXEL_SIZE*SCREEN_BYTES_PER_PIXEL);
|
||||
//if (!rgb)
|
||||
// return;
|
||||
|
||||
if (nds_screen.rotation_angle == 0 || nds_screen.rotation_angle == 180) {
|
||||
W = screen_size[nds_screen.orientation].width;
|
||||
|
@ -2089,14 +2041,14 @@ static void Printscreen()
|
|||
H = screen_size[nds_screen.orientation].width;
|
||||
}
|
||||
|
||||
gpu_screen_to_rgb(rgb, W*H*SCREEN_BYTES_PER_PIXEL, 3);
|
||||
gpu_screen_to_rgb((u32*)rgb);
|
||||
screenshot = gdk_pixbuf_new_from_data(rgb,
|
||||
GDK_COLORSPACE_RGB,
|
||||
FALSE,
|
||||
TRUE,
|
||||
8,
|
||||
W,
|
||||
H,
|
||||
W*SCREEN_BYTES_PER_PIXEL,
|
||||
W * 4,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
|
@ -2111,7 +2063,7 @@ static void Printscreen()
|
|||
seq++;
|
||||
}
|
||||
|
||||
free(rgb);
|
||||
//free(rgb);
|
||||
g_object_unref(screenshot);
|
||||
g_free(filename);
|
||||
g_free(filen);
|
||||
|
@ -2178,7 +2130,7 @@ static void Modify_PriInterpolation(GtkAction *action, GtkRadioAction *current)
|
|||
|
||||
static void Modify_Interpolation(GtkAction *action, GtkRadioAction *current)
|
||||
{
|
||||
Interpolation = (GdkInterpType)gtk_radio_action_get_current_value(current);
|
||||
Interpolation = (cairo_filter_t)gtk_radio_action_get_current_value(current);
|
||||
}
|
||||
|
||||
static void Modify_SPUMode(GtkAction *action, GtkRadioAction *current)
|
||||
|
@ -2379,7 +2331,6 @@ gboolean EmuLoop(gpointer data)
|
|||
|
||||
_updateDTools();
|
||||
gtk_widget_queue_draw( pDrawingArea );
|
||||
osd->clear();
|
||||
avout_x264.updateVideo((u16*)GPU_screen);
|
||||
|
||||
if (gtk_fps_limiter_disabled || keys_latch & KEYMASK_(KEY_BOOST - 1)) {
|
||||
|
@ -2890,7 +2841,7 @@ common_gtk_main( class configured_features *my_config)
|
|||
gtk_action_group_add_radio_actions(action_group, savet_entries, G_N_ELEMENTS(savet_entries),
|
||||
my_config->savetype, G_CALLBACK(changesavetype), NULL);
|
||||
gtk_action_group_add_radio_actions(action_group, interpolation_entries, G_N_ELEMENTS(interpolation_entries),
|
||||
GDK_INTERP_NEAREST, G_CALLBACK(Modify_Interpolation), NULL);
|
||||
Interpolation, G_CALLBACK(Modify_Interpolation), NULL);
|
||||
gtk_action_group_add_radio_actions(action_group, pri_interpolation_entries, G_N_ELEMENTS(pri_interpolation_entries),
|
||||
VideoFilterTypeID_None, G_CALLBACK(Modify_PriInterpolation), NULL);
|
||||
gtk_action_group_add_radio_actions(action_group, spumode_entries, G_N_ELEMENTS(spumode_entries),
|
||||
|
@ -2916,7 +2867,6 @@ common_gtk_main( class configured_features *my_config)
|
|||
gtk_action_set_sensitive(gtk_action_group_get_action(action_group, "printscreen"), FALSE);
|
||||
gtk_action_set_sensitive(gtk_action_group_get_action(action_group, "cheatlist"), FALSE);
|
||||
gtk_action_set_sensitive(gtk_action_group_get_action(action_group, "cheatsearch"), FALSE);
|
||||
gtk_action_set_sensitive(gtk_action_group_get_action(action_group, "fullscreen"), FALSE);
|
||||
|
||||
gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
|
||||
|
||||
|
|
Loading…
Reference in New Issue