diff --git a/gtk/src/gtk_display.cpp b/gtk/src/gtk_display.cpp index d631d219..0adfd405 100644 --- a/gtk/src/gtk_display.cpp +++ b/gtk/src/gtk_display.cpp @@ -628,284 +628,6 @@ internal_convert (void *src_buffer, return; } -static void -internal_convert_scale (void *src_buffer, - void *dst_buffer, - int src_pitch, - int dst_pitch, - int width, - int height, - int dest_width, - int dest_height, - int line_start, - int line_end, - int bpp) -{ - register uint32 x_fraction, y_fraction; - - x_fraction = (width * 0x10000) / dest_width; - y_fraction = (height * 0x10000) / dest_height; - - if (endianess == ENDIAN_MSB) - { - if (bpp == 15) - { - /* Format in fourcc is xrrrrrgg gggbbbbb */ - for (register int y = line_start; y < line_end; y++) - { - register uint8 *data = - (uint8 *) dst_buffer + y * dst_pitch; - register uint16 *snes = - (uint16 *) (((uint8 *) src_buffer) + ((y_fraction * y) >> 16) * src_pitch); - - register uint32 x_error = 0; - for (register int x = 0; x < dest_width; x++) - { - uint32 pixel = *snes; - *data++ = (pixel & 0x7c00) >> 8 | - (pixel & 0x0300) >> 8; /* Top 2 green, 5 red */ - *data++ = (pixel & 0x00c0) | - (pixel & 0x001f); /* Top 3 of last 4 green 5 blue */ - - x_error += x_fraction; - - while (x_error >= 0x10000) - { - snes++; - x_error -= 0x10000; - } - } - } - } - - else if (bpp == 16) - { - /* Format in fourcc is rrrrrggg gggbbbbb */ - for (register int y = line_start; y < line_end; y++) - { - register uint8 *data = - (uint8 *) dst_buffer + y * dst_pitch; - register uint16 *snes = - (uint16 *) (((uint8 *) src_buffer) + ((y_fraction * y) >> 16) * src_pitch); - - register uint32 x_error = 0; - for (register int x = 0; x < dest_width; x++) - { - uint32 pixel = *snes; - - *data++ = (pixel & 0x7c00) >> 7 | - (pixel & 0x0300) >> 7; /* 5 red, first 3 green */ - *data++ = (pixel & 0x00c0) | - (pixel & 0x001f); /* last 3 green, 5 blue */ - - x_error += x_fraction; - - while (x_error >= 0x10000) - { - snes++; - x_error -= 0x10000; - } - } - } - } - - else if (bpp == 24) - { - /* Format in fourcc is rrrrrrrr gggggggg bbbbbbbb */ - for (register int y = line_start; y < line_end; y++) - { - register uint8 *data = - (uint8 *) dst_buffer + y * dst_pitch; - - register uint16 *snes = - (uint16 *) (((uint8 *) src_buffer) + ((y_fraction * y) >> 16) * src_pitch); - - register uint32 x_error = 0; - for (register int x = 0; x < dest_width; x++) - { - uint32 pixel = *snes; - - *data++ = (pixel & 0x7c00) >> 7; /* Red */ - *data++ = (pixel & 0x03e0) >> 2; /* Green */ - *data++ = (pixel & 0x001f) << 3; /* Blue */ - - x_error += x_fraction; - - while (x_error >= 0x10000) - { - snes++; - x_error -= 0x10000; - } - } - } - } - - else if (bpp == 32) - { - /* Format in fourcc is xxxxxxxx rrrrrrrr gggggggg bbbbbbbb */ - for (register int y = line_start; y < line_end; y++) - { - register uint8 *data = - (uint8 *) dst_buffer + y * dst_pitch; - - register uint16 *snes = - (uint16 *) (((uint8 *) src_buffer) + ((y_fraction * y) >> 16) * src_pitch); - - register uint32 x_error = 0; - for (register int x = 0; x < dest_width; x++) - { - uint32 pixel = *snes; - - *data++ = 0xff; /* Null */ - *data++ = (pixel & 0x7c00) >> 7; /* Red */ - *data++ = (pixel & 0x03e0) >> 2; /* Green */ - *data++ = (pixel & 0x001f) << 3; /* Blue */ - - x_error += x_fraction; - - while (x_error >= 0x10000) - { - snes++; - x_error -= 0x10000; - } - } - } - } - } - - else /* Least significant byte first :-P */ - { - if (bpp == 15) - { - /* Format in fourcc is xrrrrrgg gggbbbbb */ - - for (register int y = line_start; y < line_end; y++) - { - register uint8 *data = - (uint8 *) dst_buffer + y * dst_pitch; - - register uint16 *snes = - (uint16 *) (((uint8 *) src_buffer) + ((y_fraction * y) >> 16) * src_pitch); - - register uint32 x_error = 0; - for (register int x = 0; x < dest_width; x++) - { - uint32 pixel = *snes; - *data++ = (pixel & 0x00c0) | - (pixel & 0x001f); /* Top 3 of last 4 green 5 blue */ - *data++ = (pixel & 0x7c00) >> 8 | - (pixel & 0x0300) >> 8; /* Top 2 green, 5 red */ - - x_error += x_fraction; - - while (x_error >= 0x10000) - { - snes++; - x_error -= 0x10000; - } - } - } - } - - else if (bpp == 16) - { - /* Format in fourcc is rrrrrggg gggbbbbb */ - for (register int y = line_start; y < line_end; y++) - { - register uint8 *data = - (uint8 *) dst_buffer + y * dst_pitch; - - register uint16 *snes = - (uint16 *) (((uint8 *) src_buffer) + ((y_fraction * y) >> 16) * src_pitch); - - register uint32 x_error = 0; - for (register int x = 0; x < dest_width; x++) - { - uint32 pixel = *snes; - - *data++ = (pixel & 0x00c0) | - (pixel & 0x001f); /* last 3 green, 5 blue */ - *data++ = (pixel & 0x7c00) >> 7 | - (pixel & 0x0300) >> 7; /* 5 red, first 3 green */ - - x_error += x_fraction; - - while (x_error >= 0x10000) - { - snes++; - x_error -= 0x10000; - } - } - } - } - - else if (bpp == 24) - { - /* Format in fourcc is rrrrrrrr gggggggg bbbbbbbb */ - for (register int y = line_start; y < line_end; y++) - { - register uint8 *data = - (uint8 *) dst_buffer + y * dst_pitch; - - register uint16 *snes = - (uint16 *) (((uint8 *) src_buffer) + ((y_fraction * y) >> 16) * src_pitch); - - register uint32 x_error = 0; - for (register int x = 0; x < dest_width; x++) - { - uint32 pixel = *snes; - - *data++ = (pixel & 0x001f) << 3; /* Blue */ - *data++ = (pixel & 0x03e0) >> 2; /* Green */ - *data++ = (pixel & 0x7c00) >> 7; /* Red */ - - x_error += x_fraction; - - while (x_error >= 0x10000) - { - snes++; - x_error -= 0x10000; - } - } - } - } - - else if (bpp == 32) - { - /* Format in fourcc is xxxxxxxx rrrrrrrr gggggggg bbbbbbbb */ - for (register int y = line_start; y < line_end; y++) - { - register uint8 *data = - (uint8 *) dst_buffer + y * dst_pitch; - - register uint16 *snes = - (uint16 *) (((uint8 *) src_buffer) + ((y_fraction * y) >> 16) * src_pitch); - - register uint32 x_error = 0; - for (register int x = 0; x < dest_width; x++) - { - uint32 pixel = *snes; - - *data++ = (pixel & 0x001f) << 3; /* Blue */ - *data++ = (pixel & 0x03e0) >> 2; /* Green */ - *data++ = (pixel & 0x7c00) >> 7; /* Red */ - *data++ = 0xff; /* Null */ - - x_error += x_fraction; - - while (x_error >= 0x10000) - { - snes++; - x_error -= 0x10000; - } - } - } - } - } - - return; -} - static void S9xForceHires (void *buffer, int pitch, @@ -1454,19 +1176,6 @@ thread_worker (gpointer data, job->inv_bmask, job->inv_gmask, job->bpp); - - case JOB_SCALE_AND_CONVERT: - internal_convert_scale (job->src_buffer, - job->dst_buffer, - job->src_pitch, - job->dst_pitch, - job->width, - job->height, - job->dst_width, - job->dst_height, - job->line_start, - job->line_end, - job->bpp); break; } @@ -1490,71 +1199,6 @@ create_thread_pool (void) return; } -static void -internal_threaded_convert_scale (void *src_buffer, - void *dst_buffer, - int src_pitch, - int dst_pitch, - int width, - int height, - int dst_width, - int dst_height, - int bpp) -{ - int i, flag; - - /* If the threadpool doesn't exist, create it */ - create_thread_pool (); - - for (i = 0; i < gui_config->num_threads - 1; i++) - { - job[i].operation_type = JOB_SCALE_AND_CONVERT; - job[i].src_buffer = (uint8 *) src_buffer; - job[i].src_pitch = src_pitch; - job[i].dst_buffer = (uint8 *) dst_buffer; - job[i].dst_pitch = dst_pitch; - job[i].width = width; - job[i].height = height; - job[i].dst_width = dst_width; - job[i].dst_height = dst_height; - job[i].line_start = i * (dst_height / gui_config->num_threads); - job[i].line_end = (i + 1) * (dst_height / gui_config->num_threads); - job[i].bpp = bpp; - job[i].complete = 0; - - g_thread_pool_push (pool, (gpointer) &(job[i]), NULL); - } - - job[i].operation_type = JOB_SCALE_AND_CONVERT; - job[i].src_buffer = (uint8 *) src_buffer; - job[i].src_pitch = src_pitch; - job[i].dst_buffer = (uint8 *) dst_buffer; - job[i].dst_pitch = dst_pitch; - job[i].width = width; - job[i].height = height; - job[i].dst_width = dst_width; - job[i].dst_height = dst_height; - job[i].line_start = i * (height / gui_config->num_threads); - job[i].line_end = dst_height; - job[i].bpp = bpp; - - thread_worker ((gpointer) &(job[i]), NULL); - - while (1) - { - flag = 1; - for (i = 0; i < gui_config->num_threads - 1; i++) - flag = flag && job[i].complete; - - if (flag) - break; - - sched_yield (); - } - - return; -} - static void internal_threaded_convert (void *src_buffer, void *dst_buffer, @@ -1863,42 +1507,6 @@ S9xConvertMask (void *src, return; } -void -S9xConvertScale (void *src, - void *dst, - int src_pitch, - int dst_pitch, - int width, - int height, - int dest_width, - int dest_height, - int bpp) -{ - if (gui_config->multithreading) - internal_threaded_convert_scale (src, - dst, - src_pitch, - dst_pitch, - width, - height, - dest_width, - dest_height, - bpp); - else - internal_convert_scale (src, - dst, - src_pitch, - dst_pitch, - width, - height, - dest_width, - dest_height, - 0, - dest_height, - bpp); - return; -} - void S9xDisplayRefresh (int width, int height) { diff --git a/gtk/src/gtk_display.h b/gtk/src/gtk_display.h index 460e39a9..0f30c004 100644 --- a/gtk/src/gtk_display.h +++ b/gtk/src/gtk_display.h @@ -80,16 +80,6 @@ void S9xConvert (void *src, int height, int bpp); -void S9xConvertScale (void *src, - void *dst, - int src_pitch, - int dst_pitch, - int width, - int height, - int dest_width, - int dest_height, - int bpp); - void S9xConvertMask (void *src, void *dst, int src_pitch, diff --git a/gtk/src/gtk_display_driver_gtk.cpp b/gtk/src/gtk_display_driver_gtk.cpp index b2406d67..cb5c1e32 100644 --- a/gtk/src/gtk_display_driver_gtk.cpp +++ b/gtk/src/gtk_display_driver_gtk.cpp @@ -77,10 +77,10 @@ S9xGTKDisplayDriver::output (void *src, int dst_width, int dst_height) { - if (dst_width > gdk_buffer_width || dst_height > gdk_buffer_height) + if (width > gdk_buffer_width || height > gdk_buffer_height) { - gdk_buffer_width = dst_width; - gdk_buffer_height = dst_height; + gdk_buffer_width = width; + gdk_buffer_height = height; gdk_pixbuf_unref (pixbuf); @@ -97,32 +97,32 @@ S9xGTKDisplayDriver::output (void *src, NULL); } - if (width != dst_width || height != dst_height) - { - S9xConvertScale (src, - padded_buffer[2], - src_pitch, - gdk_buffer_width * 3, - width, - height, - dst_width, dst_height, - 24); - } - else - { - S9xConvert (src, - padded_buffer[2], - src_pitch, - gdk_buffer_width * 3, - width, - height, - 24); - } + S9xConvert (src, + padded_buffer[2], + src_pitch, + gdk_buffer_width * 3, + width, + height, + 24); cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (drawing_area)); gdk_cairo_set_source_pixbuf (cr, pixbuf, x, y); + if (width != dst_width || height != dst_height) + { + cairo_matrix_t matrix; + 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, CAIRO_FILTER_NEAREST); + } + cairo_rectangle (cr, x, y, dst_width, dst_height); cairo_fill (cr); cairo_destroy (cr);