Hrm... Seems to work, except for 32-bit -> 32-bit <_<

This commit is contained in:
Themaister 2011-04-21 13:12:45 +02:00
parent 8d7cf23b40
commit 6713272809
6 changed files with 66 additions and 9 deletions

View File

@ -108,6 +108,9 @@ static const bool fullscreen = false; // To start in Fullscreen or not
static const unsigned fullscreen_x = 0; // Fullscreen resolution. A value of 0 uses the desktop resolution. static const unsigned fullscreen_x = 0; // Fullscreen resolution. A value of 0 uses the desktop resolution.
static const unsigned fullscreen_y = 0; static const unsigned fullscreen_y = 0;
// Force 16-bit colors.
static const bool force_16bit = false;
// Video VSYNC (recommended) // Video VSYNC (recommended)
static const bool vsync = true; static const bool vsync = true;

View File

@ -86,6 +86,7 @@ struct settings
float msg_pos_x; float msg_pos_x;
float msg_pos_y; float msg_pos_y;
bool force_16bit;
} video; } video;
struct struct

View File

@ -907,7 +907,7 @@ static void* gl_init(const video_info_t *video, const input_driver_t **input, vo
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, video->vsync ? 1 : 0); SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, video->vsync ? 1 : 0);
if (!SDL_SetVideoMode(video->width, video->height, 0, SDL_OPENGL | SDL_RESIZABLE | (video->fullscreen ? SDL_FULLSCREEN : 0))) if (!SDL_SetVideoMode(video->width, video->height, g_settings.video.force_16bit ? 16 : 0, SDL_OPENGL | SDL_RESIZABLE | (video->fullscreen ? SDL_FULLSCREEN : 0)))
return NULL; return NULL;
// Remove that ugly mouse :D // Remove that ugly mouse :D

View File

@ -29,6 +29,7 @@ struct sdl_video
{ {
SDL_Surface *screen, *buffer; SDL_Surface *screen, *buffer;
bool quitting; bool quitting;
bool rgb32;
}; };
static void sdl_gfx_free(void *data) static void sdl_gfx_free(void *data)
@ -59,7 +60,7 @@ static void* sdl_gfx_init(const video_info_t *video, const input_driver_t **inpu
unsigned full_y = video_info->current_h; unsigned full_y = video_info->current_h;
SSNES_LOG("Detecting desktop resolution %ux%u.\n", full_x, full_y); SSNES_LOG("Detecting desktop resolution %ux%u.\n", full_x, full_y);
vid->screen = SDL_SetVideoMode(video->width, video->height, 15, SDL_HWSURFACE | SDL_DOUBLEBUF | (video->fullscreen ? SDL_FULLSCREEN : 0)); vid->screen = SDL_SetVideoMode(video->width, video->height, (g_settings.video.force_16bit || !video->rgb32) ? 15 : 32, SDL_HWSURFACE | SDL_DOUBLEBUF | (video->fullscreen ? SDL_FULLSCREEN : 0));
if (!vid->screen) if (!vid->screen)
{ {
SSNES_ERR("Failed to init SDL surface.\n"); SSNES_ERR("Failed to init SDL surface.\n");
@ -67,8 +68,14 @@ static void* sdl_gfx_init(const video_info_t *video, const input_driver_t **inpu
} }
SDL_ShowCursor(SDL_DISABLE); SDL_ShowCursor(SDL_DISABLE);
vid->buffer = SDL_CreateRGBSurface(SDL_SWSURFACE, 256 * video->input_scale, 256 * video->input_scale, 15,
0x7c00, 0x03e0, 0x001f, 0); if (g_settings.video.force_16bit || !video->rgb32)
vid->buffer = SDL_CreateRGBSurface(SDL_SWSURFACE, 256 * video->input_scale, 256 * video->input_scale, 15,
0x7c00, 0x03e0, 0x001f, 0);
else
vid->buffer = SDL_CreateRGBSurface(SDL_SWSURFACE, 256 * video->input_scale, 256 * video->input_scale, 32,
0, 0, 0, 0);
if (!vid->buffer) if (!vid->buffer)
{ {
SSNES_ERR("SDL_CreateRGBSurface failed: %s\n", SDL_GetError()); SSNES_ERR("SDL_CreateRGBSurface failed: %s\n", SDL_GetError());
@ -85,6 +92,8 @@ static void* sdl_gfx_init(const video_info_t *video, const input_driver_t **inpu
else else
*input = NULL; *input = NULL;
vid->rgb32 = video->rgb32;
return vid; return vid;
error: error:
@ -92,6 +101,27 @@ error:
return NULL; return NULL;
} }
static inline uint16_t conv_pixel(uint32_t pix)
{
uint16_t r = (pix & 0xf8000000) >> 17;
uint16_t g = (pix & 0x00f80000) >> 14;
uint16_t b = (pix & 0x0000f800) >> 11;
return r | g | b;
}
static void convert_32bit_15bit(uint16_t *out, unsigned outpitch, const uint32_t *input, unsigned width, unsigned height, unsigned pitch)
{
for (unsigned y = 0; y < height; y++)
{
for (unsigned x = 0; x < width; x++)
{
out[x] = conv_pixel(input[x]);
}
out += outpitch >> 1;
input += pitch >> 2;
}
}
static bool sdl_gfx_frame(void *data, const void* frame, unsigned width, unsigned height, unsigned pitch, const char *msg) static bool sdl_gfx_frame(void *data, const void* frame, unsigned width, unsigned height, unsigned pitch, const char *msg)
{ {
(void)msg; (void)msg;
@ -101,11 +131,30 @@ static bool sdl_gfx_frame(void *data, const void* frame, unsigned width, unsigne
SDL_LockSurface(vid->buffer); SDL_LockSurface(vid->buffer);
// :( // :(
for (unsigned y = 0; y < height; y++) // 15-bit -> 15-bit
if (!vid->rgb32)
{ {
uint16_t *dest = (uint16_t*)vid->buffer->pixels + ((y * vid->buffer->pitch) >> 1); for (unsigned y = 0; y < height; y++)
const uint16_t *src = (const uint16_t*)frame + ((y * pitch) >> 1); {
memcpy(dest, src, width * sizeof(uint16_t)); uint16_t *dest = (uint16_t*)vid->buffer->pixels + ((y * vid->buffer->pitch) >> 1);
const uint16_t *src = (const uint16_t*)frame + ((y * pitch) >> 1);
memcpy(dest, src, width * sizeof(uint16_t));
}
}
// 32-bit -> 15-bit
else if (vid->rgb32 && g_settings.video.force_16bit)
{
convert_32bit_15bit(vid->buffer->pixels, vid->buffer->pitch, frame, width, height, pitch);
}
// 32-bit -> 32-bit
else
{
for (unsigned y = 0; y < height; y++)
{
uint32_t *dest = (uint32_t*)vid->buffer->pixels + ((y * vid->buffer->pitch) >> 2);
const uint32_t *src = (const uint32_t*)frame + ((y * pitch) >> 2);
memcpy(dest, src, width * sizeof(uint32_t));
}
} }
if (SDL_MUSTLOCK(vid->buffer)) if (SDL_MUSTLOCK(vid->buffer))
@ -126,7 +175,6 @@ static bool sdl_gfx_frame(void *data, const void* frame, unsigned width, unsigne
}; };
SDL_SoftStretch(vid->buffer, &src, vid->screen, &dest); SDL_SoftStretch(vid->buffer, &src, vid->screen, &dest);
SDL_UpdateRect(vid->screen, dest.x, dest.y, dest.w, dest.h);
char buf[128]; char buf[128];
if (gfx_window_title(buf, sizeof(buf))) if (gfx_window_title(buf, sizeof(buf)))

View File

@ -108,6 +108,7 @@ static void set_defaults(void)
g_settings.video.fullscreen = fullscreen; g_settings.video.fullscreen = fullscreen;
g_settings.video.fullscreen_x = fullscreen_x; g_settings.video.fullscreen_x = fullscreen_x;
g_settings.video.fullscreen_y = fullscreen_y; g_settings.video.fullscreen_y = fullscreen_y;
g_settings.video.force_16bit = force_16bit;
g_settings.video.vsync = vsync; g_settings.video.vsync = vsync;
g_settings.video.smooth = video_smooth; g_settings.video.smooth = video_smooth;
g_settings.video.force_aspect = force_aspect; g_settings.video.force_aspect = force_aspect;
@ -285,6 +286,7 @@ static void parse_config_file(void)
CONFIG_GET_INT(video.fullscreen_x, "video_fullscreen_x"); CONFIG_GET_INT(video.fullscreen_x, "video_fullscreen_x");
CONFIG_GET_INT(video.fullscreen_y, "video_fullscreen_y"); CONFIG_GET_INT(video.fullscreen_y, "video_fullscreen_y");
CONFIG_GET_BOOL(video.fullscreen, "video_fullscreen"); CONFIG_GET_BOOL(video.fullscreen, "video_fullscreen");
CONFIG_GET_BOOL(video.force_16bit, "video_force_16bit");
CONFIG_GET_BOOL(video.vsync, "video_vsync"); CONFIG_GET_BOOL(video.vsync, "video_vsync");
CONFIG_GET_BOOL(video.smooth, "video_smooth"); CONFIG_GET_BOOL(video.smooth, "video_smooth");
CONFIG_GET_BOOL(video.force_aspect, "video_force_aspect"); CONFIG_GET_BOOL(video.force_aspect, "video_force_aspect");

View File

@ -16,6 +16,9 @@
# Start in fullscreen. Can be changed at runtime. # Start in fullscreen. Can be changed at runtime.
# video_fullscreen = false # video_fullscreen = false
# Force 16-bit colors. Apparently some video cards in use today have troubles with 32-bit ...
# video_force_16bit = false
# Video vsync. # Video vsync.
# video_vsync = true # video_vsync = true