2018-11-16 00:42:29 +01:00
|
|
|
/*****************************************************************************\
|
|
|
|
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
|
|
|
This file is licensed under the Snes9x License.
|
|
|
|
For further information, consult the LICENSE file in the root directory.
|
|
|
|
\*****************************************************************************/
|
|
|
|
|
2020-07-05 00:53:38 +02:00
|
|
|
#include "gtk_compat.h"
|
2010-09-26 11:19:15 +02:00
|
|
|
#include <cairo.h>
|
2010-09-25 17:46:12 +02:00
|
|
|
#include "gtk_display.h"
|
|
|
|
#include "gtk_display_driver_gtk.h"
|
2020-07-05 00:53:38 +02:00
|
|
|
#include "snes9x.h"
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2020-07-01 00:28:10 +02:00
|
|
|
S9xGTKDisplayDriver::S9xGTKDisplayDriver(Snes9xWindow *window,
|
|
|
|
Snes9xConfig *config)
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
|
|
|
this->window = window;
|
|
|
|
this->config = config;
|
2020-07-05 00:53:38 +02:00
|
|
|
this->drawing_area = window->drawing_area;
|
2010-09-25 17:46:12 +02:00
|
|
|
}
|
|
|
|
|
2020-07-01 00:28:10 +02:00
|
|
|
void S9xGTKDisplayDriver::update(uint16_t *buffer, int width, int height, int stride_in_pixels)
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
|
|
|
if (width <= 0)
|
|
|
|
return;
|
2020-07-05 00:53:38 +02:00
|
|
|
S9xRect dst = S9xApplyAspect(width, height, drawing_area->get_width(), drawing_area->get_height());
|
2020-07-01 00:28:10 +02:00
|
|
|
output(buffer, stride_in_pixels * 2, dst.x, dst.y, width, height, dst.w, dst.h);
|
2010-09-25 17:46:12 +02:00
|
|
|
}
|
|
|
|
|
2020-07-01 00:28:10 +02:00
|
|
|
void S9xGTKDisplayDriver::output(void *src,
|
|
|
|
int src_pitch,
|
|
|
|
int x,
|
|
|
|
int y,
|
|
|
|
int width,
|
|
|
|
int height,
|
|
|
|
int dst_width,
|
|
|
|
int dst_height)
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
2010-11-18 13:31:27 +01:00
|
|
|
if (last_known_width != dst_width || last_known_height != dst_height)
|
|
|
|
{
|
2020-07-01 00:28:10 +02:00
|
|
|
clear();
|
2010-11-18 13:31:27 +01:00
|
|
|
|
|
|
|
last_known_width = dst_width;
|
|
|
|
last_known_height = dst_height;
|
|
|
|
}
|
|
|
|
|
2020-07-01 00:28:10 +02:00
|
|
|
cairo_t *cr = window->get_cairo();
|
2018-10-28 02:07:49 +02:00
|
|
|
cairo_surface_t *surface;
|
|
|
|
|
2020-07-01 00:28:10 +02:00
|
|
|
surface = cairo_image_surface_create_for_data((unsigned char *)src, CAIRO_FORMAT_RGB16_565, width, height, src_pitch);
|
2018-10-28 02:07:49 +02:00
|
|
|
|
2020-07-01 00:28:10 +02:00
|
|
|
cairo_set_source_surface(cr, surface, 0, 0);
|
2010-09-26 11:19:15 +02:00
|
|
|
|
2010-11-18 12:28:48 +01:00
|
|
|
if (width != dst_width || height != dst_height)
|
|
|
|
{
|
|
|
|
cairo_matrix_t matrix;
|
2020-07-01 00:28:10 +02:00
|
|
|
cairo_pattern_t *pattern = cairo_get_source(cr);
|
|
|
|
;
|
|
|
|
|
|
|
|
cairo_matrix_init_identity(&matrix);
|
|
|
|
cairo_matrix_scale(&matrix,
|
|
|
|
(double)width / (double)dst_width,
|
|
|
|
(double)height / (double)dst_height);
|
|
|
|
cairo_matrix_translate(&matrix, -x, -y);
|
|
|
|
cairo_pattern_set_matrix(pattern, &matrix);
|
|
|
|
cairo_pattern_set_filter(pattern,
|
|
|
|
Settings.BilinearFilter
|
|
|
|
? CAIRO_FILTER_BILINEAR
|
|
|
|
: CAIRO_FILTER_NEAREST);
|
2010-11-18 12:28:48 +01:00
|
|
|
}
|
|
|
|
|
2020-07-01 00:28:10 +02:00
|
|
|
cairo_rectangle(cr, x, y, dst_width, dst_height);
|
|
|
|
cairo_fill(cr);
|
2010-11-18 13:31:27 +01:00
|
|
|
|
2020-07-01 00:28:10 +02:00
|
|
|
cairo_surface_finish(surface);
|
|
|
|
cairo_surface_destroy(surface);
|
2018-10-28 02:07:49 +02:00
|
|
|
|
2020-07-01 00:28:10 +02:00
|
|
|
window->release_cairo();
|
|
|
|
window->set_mouseable_area(x, y, width, height);
|
2010-09-25 17:46:12 +02:00
|
|
|
}
|
|
|
|
|
2020-07-01 00:28:10 +02:00
|
|
|
int S9xGTKDisplayDriver::init()
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-07-01 00:28:10 +02:00
|
|
|
void S9xGTKDisplayDriver::deinit()
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-07-01 00:28:10 +02:00
|
|
|
void S9xGTKDisplayDriver::clear()
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
2020-07-05 00:53:38 +02:00
|
|
|
int width = drawing_area->get_width();
|
|
|
|
int height = drawing_area->get_height();
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2020-07-01 00:28:10 +02:00
|
|
|
cairo_t *cr = window->get_cairo();
|
2010-09-26 11:19:15 +02:00
|
|
|
|
2020-07-01 00:28:10 +02:00
|
|
|
cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
|
2010-09-25 17:46:12 +02:00
|
|
|
|
|
|
|
if (window->last_width <= 0 || window->last_height <= 0)
|
|
|
|
{
|
2020-07-01 00:28:10 +02:00
|
|
|
cairo_paint(cr);
|
|
|
|
window->release_cairo();
|
2010-09-26 11:19:15 +02:00
|
|
|
|
2010-09-25 17:46:12 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-05-14 21:59:51 +02:00
|
|
|
S9xRect dst;
|
|
|
|
dst.w = window->last_width;
|
|
|
|
dst.h = window->last_height;
|
|
|
|
get_filter_scale(dst.w, dst.h);
|
|
|
|
dst = S9xApplyAspect(dst.w, dst.h, width, height);
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2019-05-14 21:59:51 +02:00
|
|
|
if (dst.x > 0)
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
2020-07-01 00:28:10 +02:00
|
|
|
cairo_rectangle(cr, 0, dst.y, dst.x, dst.h);
|
2010-09-25 17:46:12 +02:00
|
|
|
}
|
2019-05-14 21:59:51 +02:00
|
|
|
if (dst.x + dst.w < width)
|
2010-09-26 11:19:15 +02:00
|
|
|
{
|
2020-07-01 00:28:10 +02:00
|
|
|
cairo_rectangle(cr, dst.x + dst.w, dst.y, width - (dst.x + dst.w), dst.h);
|
2010-09-26 11:19:15 +02:00
|
|
|
}
|
2019-05-14 21:59:51 +02:00
|
|
|
if (dst.y > 0)
|
2010-09-26 11:19:15 +02:00
|
|
|
{
|
2020-07-01 00:28:10 +02:00
|
|
|
cairo_rectangle(cr, 0, 0, width, dst.y);
|
2010-09-26 11:19:15 +02:00
|
|
|
}
|
2019-05-14 21:59:51 +02:00
|
|
|
if (dst.y + dst.h < height)
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
2020-07-01 00:28:10 +02:00
|
|
|
cairo_rectangle(cr, 0, dst.y + dst.h, width, height - (dst.y + dst.h));
|
2010-09-25 17:46:12 +02:00
|
|
|
}
|
|
|
|
|
2020-07-01 00:28:10 +02:00
|
|
|
cairo_fill(cr);
|
2010-09-25 17:46:12 +02:00
|
|
|
|
2020-07-01 00:28:10 +02:00
|
|
|
window->release_cairo();
|
2010-09-25 17:46:12 +02:00
|
|
|
}
|
|
|
|
|
2020-07-01 00:28:10 +02:00
|
|
|
void S9xGTKDisplayDriver::refresh(int width, int height)
|
2010-09-25 17:46:12 +02:00
|
|
|
{
|
2020-07-01 00:28:10 +02:00
|
|
|
clear();
|
|
|
|
}
|