From 6cd595a305c71f0540a3ecf4c4038891a7eba762 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Tue, 17 Jun 2014 19:01:01 -0700 Subject: Partially working switch to having a vcounter and hslot counter in the context rather than trying to derive them from the cycle count. This should allow for more accurate handling of mid screen mode switches. Interrupt timing is broken currently though --- render_sdl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'render_sdl.c') diff --git a/render_sdl.c b/render_sdl.c index e5f5c96..9f635a8 100644 --- a/render_sdl.c +++ b/render_sdl.c @@ -364,7 +364,7 @@ void render_context_gl(vdp_context * context) glBindTexture(GL_TEXTURE_2D, (context->regs[REG_MODE_4] & BIT_INTERLACE) ? textures[1] : textures[2]); glUniform1i(un_textures[1], 1); - glUniform1f(un_width, context->latched_mode & BIT_H40 ? 320.0f : 256.0f); + glUniform1f(un_width, context->regs[REG_MODE_4] & BIT_H40 ? 320.0f : 256.0f); glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); glVertexAttribPointer(at_pos, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat[2]), (void *)0); -- cgit v1.2.3 From 60b9f591475238df486ee45d25e888e417ac8e91 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Thu, 1 Jan 2015 17:36:23 -0800 Subject: Avoid calling atexit(SDL_Quit) until after OpenGL initialization to avoid a segfault on exit when using fglrx --- render_sdl.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'render_sdl.c') diff --git a/render_sdl.c b/render_sdl.c index 9f635a8..f50c476 100644 --- a/render_sdl.c +++ b/render_sdl.c @@ -220,8 +220,6 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError()); exit(1); } - atexit(SDL_Quit); - atexit(render_close_audio); printf("width: %d, height: %d\n", width, height); uint32_t flags = SDL_ANYFORMAT; @@ -250,10 +248,12 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full screen = SDL_SetVideoMode(width, height, 32, flags); if (!screen) { fprintf(stderr, "Unable to get SDL surface: %s\n", SDL_GetError()); + SDL_Quit(); exit(1); } if (!use_gl && screen->format->BytesPerPixel != 2 && screen->format->BytesPerPixel != 4) { fprintf(stderr, "BlastEm requires a 16-bit or 32-bit surface, SDL returned a %d-bit surface\n", screen->format->BytesPerPixel * 8); + SDL_Quit(); exit(1); } #ifndef DISABLE_OPENGL @@ -263,10 +263,12 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full GLenum res = glewInit(); if (res != GLEW_OK) { fprintf(stderr, "Initialization of GLEW failed with code %d\n", res); + SDL_Quit(); exit(1); } if (!GLEW_VERSION_2_0) { fputs("OpenGL 2.0 is unable, falling back to standard SDL rendering\n", stderr); + SDL_Quit(); exit(1); } float aspect = (float)width / height; @@ -327,6 +329,7 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full if (SDL_OpenAudio(&desired, &actual) < 0) { fprintf(stderr, "Unable to open SDL audio: %s\n", SDL_GetError()); + SDL_Quit(); exit(1); } buffer_samples = actual.samples; @@ -345,6 +348,9 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full } } SDL_JoystickEventState(SDL_ENABLE); + + atexit(SDL_Quit); + atexit(render_close_audio); } #ifndef DISABLE_OPENGL void render_context_gl(vdp_context * context) -- cgit v1.2.3 From 863ea0b3f8b8879ac3092f391a68dc95d0d04de2 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Wed, 20 May 2015 19:05:11 -0700 Subject: Upgrade to SDL 2.0 and drop support for the non-OpenGL render path --- render_sdl.c | 287 ++++++++++++++++++----------------------------------------- 1 file changed, 87 insertions(+), 200 deletions(-) (limited to 'render_sdl.c') diff --git a/render_sdl.c b/render_sdl.c index f50c476..53a0e2f 100644 --- a/render_sdl.c +++ b/render_sdl.c @@ -11,14 +11,12 @@ #include "io.h" #include "util.h" -#ifndef DISABLE_OPENGL #include -#endif -SDL_Surface *screen; +SDL_Window *main_window; +SDL_GLContext *main_context; uint8_t render_dbg = 0; uint8_t debug_pal = 0; -uint8_t render_gl = 1; uint32_t last_frame = 0; @@ -92,14 +90,9 @@ int render_num_joysticks() uint32_t render_map_color(uint8_t r, uint8_t g, uint8_t b) { - if (render_gl) { - return 255 << 24 | r << 16 | g << 8 | b; - } else { - return SDL_MapRGB(screen->format, r, g, b); - } + return 255 << 24 | r << 16 | g << 8 | b; } -#ifndef DISABLE_OPENGL GLuint textures[3], buffers[2], vshader, fshader, program, un_textures[2], un_width, at_pos; GLfloat vertex_data[] = { @@ -153,139 +146,108 @@ GLuint load_shader(char * fname, GLenum shader_type) } return ret; } -#endif void render_alloc_surfaces(vdp_context * context) { -#ifndef DISABLE_OPENGL - if (render_gl) { - context->oddbuf = context->framebuf = malloc(512 * 256 * 4 * 2); - memset(context->oddbuf, 0, 512 * 256 * 4 * 2); - context->evenbuf = ((char *)context->oddbuf) + 512 * 256 * 4; - glGenTextures(3, textures); - for (int i = 0; i < 3; i++) - { - glBindTexture(GL_TEXTURE_2D, textures[i]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - if (i < 2) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 512, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, i ? context->evenbuf : context->oddbuf); - } else { - uint32_t blank = 255 << 24; - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_BGRA, GL_UNSIGNED_BYTE, &blank); - } - } - glGenBuffers(2, buffers); - glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(element_data), element_data, GL_STATIC_DRAW); - vshader = load_shader(tern_find_ptr_default(config, "videovertex_shader", "default.v.glsl"), GL_VERTEX_SHADER); - fshader = load_shader(tern_find_ptr_default(config, "videofragment_shader", "default.f.glsl"), GL_FRAGMENT_SHADER); - program = glCreateProgram(); - glAttachShader(program, vshader); - glAttachShader(program, fshader); - glLinkProgram(program); - GLint link_status; - glGetProgramiv(program, GL_LINK_STATUS, &link_status); - if (!link_status) { - fputs("Failed to link shader program\n", stderr); - exit(1); + context->oddbuf = context->framebuf = malloc(512 * 256 * 4 * 2); + memset(context->oddbuf, 0, 512 * 256 * 4 * 2); + context->evenbuf = ((char *)context->oddbuf) + 512 * 256 * 4; + glGenTextures(3, textures); + for (int i = 0; i < 3; i++) + { + glBindTexture(GL_TEXTURE_2D, textures[i]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + if (i < 2) { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 512, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, i ? context->evenbuf : context->oddbuf); + } else { + uint32_t blank = 255 << 24; + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_BGRA, GL_UNSIGNED_BYTE, &blank); } - un_textures[0] = glGetUniformLocation(program, "textures[0]"); - un_textures[1] = glGetUniformLocation(program, "textures[1]"); - un_width = glGetUniformLocation(program, "width"); - at_pos = glGetAttribLocation(program, "pos"); - } else { -#endif - context->oddbuf = context->framebuf = malloc(320 * 240 * screen->format->BytesPerPixel * 2); - context->evenbuf = ((char *)context->oddbuf) + 320 * 240 * screen->format->BytesPerPixel; -#ifndef DISABLE_OPENGL } -#endif -} - -uint8_t render_depth() -{ - return screen->format->BytesPerPixel * 8; + glGenBuffers(2, buffers); + glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(element_data), element_data, GL_STATIC_DRAW); + vshader = load_shader(tern_find_ptr_default(config, "videovertex_shader", "default.v.glsl"), GL_VERTEX_SHADER); + fshader = load_shader(tern_find_ptr_default(config, "videofragment_shader", "default.f.glsl"), GL_FRAGMENT_SHADER); + program = glCreateProgram(); + glAttachShader(program, vshader); + glAttachShader(program, fshader); + glLinkProgram(program); + GLint link_status; + glGetProgramiv(program, GL_LINK_STATUS, &link_status); + if (!link_status) { + fputs("Failed to link shader program\n", stderr); + exit(1); + } + un_textures[0] = glGetUniformLocation(program, "textures[0]"); + un_textures[1] = glGetUniformLocation(program, "textures[1]"); + un_width = glGetUniformLocation(program, "width"); + at_pos = glGetAttribLocation(program, "pos"); } char * caption = NULL; -void render_init(int width, int height, char * title, uint32_t fps, uint8_t fullscreen, uint8_t use_gl) +void render_init(int width, int height, char * title, uint32_t fps, uint8_t fullscreen) { if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) < 0) { fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError()); exit(1); } printf("width: %d, height: %d\n", width, height); - uint32_t flags = SDL_ANYFORMAT; - -#ifndef DISABLE_OPENGL - if (use_gl) - { - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - flags = SDL_OPENGL; - if (fullscreen) { - flags |= SDL_FULLSCREEN; - } - } else { -#else - { -#endif - if (fullscreen) { - flags |= SDL_FULLSCREEN | SDL_HWSURFACE | SDL_DOUBLEBUF; - } else { - flags |= SDL_SWSURFACE; - } + uint32_t flags = SDL_WINDOW_OPENGL; + + + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + if (fullscreen) { + flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; + SDL_DisplayMode mode; + //TODO: Multiple monitor support + SDL_GetCurrentDisplayMode(0, &mode); + //the SDL2 migration guide suggests setting width and height to 0 when using SDL_WINDOW_FULLSCREEN_DESKTOP + //but that doesn't seem to work right when using OpenGL, at least on Linux anyway + width = mode.w; + height = mode.h; + } + main_window = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, flags); + if (!main_window) { + fprintf(stderr, "Unable to create SDL window: %s\n", SDL_GetError()); + SDL_Quit(); + exit(1); } - screen = SDL_SetVideoMode(width, height, 32, flags); - if (!screen) { - fprintf(stderr, "Unable to get SDL surface: %s\n", SDL_GetError()); + SDL_GetWindowSize(main_window, &width, &height); + printf("Window created with size: %d x %d\n", width, height); + main_context = SDL_GL_CreateContext(main_window); + GLenum res = glewInit(); + if (res != GLEW_OK) { + fprintf(stderr, "Initialization of GLEW failed with code %d\n", res); SDL_Quit(); exit(1); } - if (!use_gl && screen->format->BytesPerPixel != 2 && screen->format->BytesPerPixel != 4) { - fprintf(stderr, "BlastEm requires a 16-bit or 32-bit surface, SDL returned a %d-bit surface\n", screen->format->BytesPerPixel * 8); + if (!GLEW_VERSION_2_0) { + fputs("BlastEm requires at least OpenGL 2.0, but it is unavailable\n", stderr); SDL_Quit(); exit(1); } -#ifndef DISABLE_OPENGL - //TODO: fallback on standard rendering if OpenGL 2.0 is unavailable or if init fails - if (use_gl) - { - GLenum res = glewInit(); - if (res != GLEW_OK) { - fprintf(stderr, "Initialization of GLEW failed with code %d\n", res); - SDL_Quit(); - exit(1); - } - if (!GLEW_VERSION_2_0) { - fputs("OpenGL 2.0 is unable, falling back to standard SDL rendering\n", stderr); - SDL_Quit(); - exit(1); - } - float aspect = (float)width / height; - if (fabs(aspect - 4.0/3.0) > 0.01 && strcmp(tern_find_ptr_default(config, "videoaspect", "normal"), "stretch")) { - for (int i = 0; i < 4; i++) - { - if (aspect > 4.0/3.0) { - vertex_data[i*2] *= (4.0/3.0)/aspect; - } else { - vertex_data[i*2+1] *= aspect/(4.0/3.0); - } + float aspect = (float)width / height; + if (fabs(aspect - 4.0/3.0) > 0.01 && strcmp(tern_find_ptr_default(config, "videoaspect", "normal"), "stretch")) { + for (int i = 0; i < 4; i++) + { + if (aspect > 4.0/3.0) { + vertex_data[i*2] *= (4.0/3.0)/aspect; + } else { + vertex_data[i*2+1] *= aspect/(4.0/3.0); } } } - render_gl = use_gl; -#endif - SDL_WM_SetCaption(title, title); caption = title; min_delay = 0; for (int i = 0; i < 100; i++) { @@ -341,8 +303,8 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full num_joysticks = MAX_JOYSTICKS; } for (int i = 0; i < num_joysticks; i++) { - printf("Joystick %d: %s\n", i, SDL_JoystickName(i)); SDL_Joystick * joy = joysticks[i] = SDL_JoystickOpen(i); + printf("Joystick %d: %s\n", i, SDL_JoystickName(joy)); if (joy) { printf("\tNum Axes: %d\n\tNum Buttons: %d\n\tNum Hats: %d\n", SDL_JoystickNumAxes(joy), SDL_JoystickNumButtons(joy), SDL_JoystickNumHats(joy)); } @@ -352,9 +314,11 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full atexit(SDL_Quit); atexit(render_close_audio); } -#ifndef DISABLE_OPENGL -void render_context_gl(vdp_context * context) + +void render_context(vdp_context * context) { + last_frame = SDL_GetTicks(); + glBindTexture(GL_TEXTURE_2D, textures[context->framebuf == context->oddbuf ? 0 : 1]); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 320, 240, GL_BGRA, GL_UNSIGNED_BYTE, context->framebuf);; @@ -381,81 +345,7 @@ void render_context_gl(vdp_context * context) glDisableVertexAttribArray(at_pos); - SDL_GL_SwapBuffers(); - if (context->regs[REG_MODE_4] & BIT_INTERLACE) - { - context->framebuf = context->framebuf == context->oddbuf ? context->evenbuf : context->oddbuf; - } -} -#endif - -uint32_t blankbuf[320*240]; - -void render_context(vdp_context * context) -{ - uint16_t *buf_16; - uint32_t *buf_32; - uint8_t b,g,r; - last_frame = SDL_GetTicks(); -#ifndef DISABLE_OPENGL - if (render_gl) - { - render_context_gl(context); - return; - } -#endif - if (SDL_MUSTLOCK(screen)) { - if (SDL_LockSurface(screen) < 0) { - return; - } - } - uint16_t repeat_x = screen->clip_rect.w / 320; - uint16_t repeat_y = screen->clip_rect.h / 240; - if (repeat_x > repeat_y) { - repeat_x = repeat_y; - } else { - repeat_y = repeat_x; - } - int othermask = repeat_y >> 1; - - if (screen->format->BytesPerPixel == 2) { - uint16_t *otherbuf = (context->regs[REG_MODE_4] & BIT_INTERLACE) ? context->evenbuf : (uint16_t *)blankbuf; - uint16_t * oddbuf = context->oddbuf; - buf_16 = (uint16_t *)screen->pixels; - for (int y = 0; y < 240; y++) { - for (int i = 0; i < repeat_y; i++,buf_16 += screen->pitch/2) { - uint16_t *line = buf_16; - uint16_t *src_line = (i & othermask ? otherbuf : oddbuf) + y * 320; - for (int x = 0; x < 320; x++) { - uint16_t color = *(src_line++); - for (int j = 0; j < repeat_x; j++) { - *(line++) = color; - } - } - } - } - } else { - uint32_t *otherbuf = (context->regs[REG_MODE_4] & BIT_INTERLACE) ? context->evenbuf : (uint32_t *)blankbuf; - uint32_t * oddbuf = context->oddbuf; - buf_32 = (uint32_t *)screen->pixels; - for (int y = 0; y < 240; y++) { - for (int i = 0; i < repeat_y; i++,buf_32 += screen->pitch/4) { - uint32_t *line = buf_32; - uint32_t *src_line = (i & othermask ? otherbuf : oddbuf) + y * 320; - for (int x = 0; x < 320; x++) { - uint32_t color = *(src_line++); - for (int j = 0; j < repeat_x; j++) { - *(line++) = color; - } - } - } - } - } - if ( SDL_MUSTLOCK(screen) ) { - SDL_UnlockSurface(screen); - } - //SDL_UpdateRect(screen, 0, 0, screen->clip_rect.w, screen->clip_rect.h); - SDL_Flip(screen); + SDL_GL_SwapWindow(main_window); if (context->regs[REG_MODE_4] & BIT_INTERLACE) { context->framebuf = context->framebuf == context->oddbuf ? context->evenbuf : context->oddbuf; @@ -568,8 +458,6 @@ int wait_render_frame(vdp_context * context, int frame_limit) } render_context(context); - - //TODO: Figure out why this causes segfaults frame_counter++; if ((last_frame - start) > 1000) { if (start && (last_frame-start)) { @@ -577,8 +465,7 @@ int wait_render_frame(vdp_context * context, int frame_limit) fps_caption = malloc(strlen(caption) + strlen(" - 1000.1 fps") + 1); } sprintf(fps_caption, "%s - %.1f fps", caption, ((float)frame_counter) / (((float)(last_frame-start)) / 1000.0)); - SDL_WM_SetCaption(fps_caption, caption); - fflush(stdout); + SDL_SetWindowTitle(main_window, fps_caption); } start = last_frame; frame_counter = 0; -- cgit v1.2.3 From 93a29403d334c8dd1253221fd4588209a706f500 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Thu, 28 May 2015 22:31:21 -0700 Subject: Get windows build compiling again post-merge --- render_sdl.c | 1 + 1 file changed, 1 insertion(+) (limited to 'render_sdl.c') diff --git a/render_sdl.c b/render_sdl.c index 53a0e2f..38b7ed4 100644 --- a/render_sdl.c +++ b/render_sdl.c @@ -5,6 +5,7 @@ */ #include #include +#include #include #include "render.h" #include "blastem.h" -- cgit v1.2.3 From 66aedc9c1a87c8811be4dba263dbcd7ec026cc70 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Thu, 28 May 2015 23:04:49 -0700 Subject: Fix crash bug in windows build --- render_sdl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'render_sdl.c') diff --git a/render_sdl.c b/render_sdl.c index 38b7ed4..9de86dd 100644 --- a/render_sdl.c +++ b/render_sdl.c @@ -107,7 +107,7 @@ const GLushort element_data[] = {0, 1, 2, 3}; GLuint load_shader(char * fname, GLenum shader_type) { - char * parts[] = {getenv("HOME"), "/.config/blastem/shaders/", fname}; + char * parts[] = {get_home_dir(), "/.config/blastem/shaders/", fname}; char * shader_path = alloc_concat_m(3, parts); FILE * f = fopen(shader_path, "r"); free(shader_path); -- cgit v1.2.3 From 0be7e726ad839d36d50db630b24ea0f1dc141c08 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Sun, 5 Jul 2015 14:21:34 -0700 Subject: WIP changes to support reading cart memory map from ROM DB --- render_sdl.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'render_sdl.c') diff --git a/render_sdl.c b/render_sdl.c index 9de86dd..82f8b12 100644 --- a/render_sdl.c +++ b/render_sdl.c @@ -173,8 +173,10 @@ void render_alloc_surfaces(vdp_context * context) glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(element_data), element_data, GL_STATIC_DRAW); - vshader = load_shader(tern_find_ptr_default(config, "videovertex_shader", "default.v.glsl"), GL_VERTEX_SHADER); - fshader = load_shader(tern_find_ptr_default(config, "videofragment_shader", "default.f.glsl"), GL_FRAGMENT_SHADER); + tern_val def = {.ptrval = "default.v.glsl"}; + vshader = load_shader(tern_find_path_default(config, "video\0vertex_shader\0", def).ptrval, GL_VERTEX_SHADER); + def.ptrval = "default.f.glsl"; + fshader = load_shader(tern_find_path_default(config, "video\0fragment_shader\0", def).ptrval, GL_FRAGMENT_SHADER); program = glCreateProgram(); glAttachShader(program, vshader); glAttachShader(program, fshader); @@ -239,7 +241,8 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full exit(1); } float aspect = (float)width / height; - if (fabs(aspect - 4.0/3.0) > 0.01 && strcmp(tern_find_ptr_default(config, "videoaspect", "normal"), "stretch")) { + tern_val def = {.ptrval = "normal"}; + if (fabs(aspect - 4.0/3.0) > 0.01 && strcmp(tern_find_path_default(config, "video\0aspect\0", def).ptrval, "stretch")) { for (int i = 0; i < 4; i++) { if (aspect > 4.0/3.0) { @@ -272,7 +275,7 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full audio_ready = SDL_CreateCond(); SDL_AudioSpec desired, actual; - char * rate_str = tern_find_ptr(config, "audiorate"); + char * rate_str = tern_find_path(config, "audio\0rate\0").ptrval; int rate = rate_str ? atoi(rate_str) : 0; if (!rate) { rate = 48000; @@ -280,7 +283,7 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full desired.freq = rate; desired.format = AUDIO_S16SYS; desired.channels = 2; - char * samples_str = tern_find_ptr(config, "audiobuffer"); + char * samples_str = tern_find_path(config, "audio\0buffer\0").ptrval; int samples = samples_str ? atoi(samples_str) : 0; if (!samples) { samples = 512; -- cgit v1.2.3 From 80ff833dd8ad011b579bff26ac654819e6735bce Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Sat, 25 Jul 2015 18:22:07 -0700 Subject: Use a new fatal_error function instead of calling fprintf and exit for fatal errors. This new function more gracefully handles the case in which BlastEm was not started from a terminal or disconnected from ther terminal (Windows). --- render_sdl.c | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) (limited to 'render_sdl.c') diff --git a/render_sdl.c b/render_sdl.c index 82f8b12..1b25052 100644 --- a/render_sdl.c +++ b/render_sdl.c @@ -184,8 +184,7 @@ void render_alloc_surfaces(vdp_context * context) GLint link_status; glGetProgramiv(program, GL_LINK_STATUS, &link_status); if (!link_status) { - fputs("Failed to link shader program\n", stderr); - exit(1); + fatal_error("Failed to link shader program\n"); } un_textures[0] = glGetUniformLocation(program, "textures[0]"); un_textures[1] = glGetUniformLocation(program, "textures[1]"); @@ -198,9 +197,9 @@ char * caption = NULL; void render_init(int width, int height, char * title, uint32_t fps, uint8_t fullscreen) { if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) < 0) { - fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError()); - exit(1); + fatal_error("Unable to init SDL: %s\n", SDL_GetError()); } + atexit(SDL_Quit); printf("width: %d, height: %d\n", width, height); uint32_t flags = SDL_WINDOW_OPENGL; @@ -222,23 +221,17 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full } main_window = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, flags); if (!main_window) { - fprintf(stderr, "Unable to create SDL window: %s\n", SDL_GetError()); - SDL_Quit(); - exit(1); + fatal_error("Unable to create SDL window: %s\n", SDL_GetError()); } SDL_GetWindowSize(main_window, &width, &height); printf("Window created with size: %d x %d\n", width, height); main_context = SDL_GL_CreateContext(main_window); GLenum res = glewInit(); if (res != GLEW_OK) { - fprintf(stderr, "Initialization of GLEW failed with code %d\n", res); - SDL_Quit(); - exit(1); + fatal_error("Initialization of GLEW failed with code %d\n", res); } if (!GLEW_VERSION_2_0) { - fputs("BlastEm requires at least OpenGL 2.0, but it is unavailable\n", stderr); - SDL_Quit(); - exit(1); + fatal_error("BlastEm requires at least OpenGL 2.0, but it is unavailable\n"); } float aspect = (float)width / height; tern_val def = {.ptrval = "normal"}; @@ -294,9 +287,7 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full desired.userdata = NULL; if (SDL_OpenAudio(&desired, &actual) < 0) { - fprintf(stderr, "Unable to open SDL audio: %s\n", SDL_GetError()); - SDL_Quit(); - exit(1); + fatal_error("Unable to open SDL audio: %s\n", SDL_GetError()); } buffer_samples = actual.samples; sample_rate = actual.freq; @@ -315,7 +306,6 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full } SDL_JoystickEventState(SDL_ENABLE); - atexit(SDL_Quit); atexit(render_close_audio); } @@ -530,4 +520,18 @@ uint32_t render_sample_rate() return sample_rate; } +void render_errorbox(char *title, char *message) +{ + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title, message, NULL); +} + +void render_warnbox(char *title, char *message) +{ + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_WARNING, title, message, NULL); +} + +void render_infobox(char *title, char *message) +{ + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, title, message, NULL); +} -- cgit v1.2.3 From 711f53c6685783e5effb17e493450ed5d09b3aa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=3D=3FUTF-8=3Fq=3FHigor=3D20Eur=3DC3=3DADpedes=3F=3D?= Date: Sun, 26 Jul 2015 13:05:05 -0700 Subject: Add pure SDL2 renderer --- render_sdl.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 110 insertions(+), 17 deletions(-) mode change 100644 => 100755 render_sdl.c (limited to 'render_sdl.c') diff --git a/render_sdl.c b/render_sdl.c old mode 100644 new mode 100755 index 82f8b12..a80acc4 --- a/render_sdl.c +++ b/render_sdl.c @@ -15,7 +15,14 @@ #include SDL_Window *main_window; +#ifdef DISABLE_OPENGL +SDL_Renderer *main_renderer; +SDL_Texture *main_texture; +SDL_Rect main_clip; +#else SDL_GLContext *main_context; +#endif + uint8_t render_dbg = 0; uint8_t debug_pal = 0; @@ -153,6 +160,11 @@ void render_alloc_surfaces(vdp_context * context) context->oddbuf = context->framebuf = malloc(512 * 256 * 4 * 2); memset(context->oddbuf, 0, 512 * 256 * 4 * 2); context->evenbuf = ((char *)context->oddbuf) + 512 * 256 * 4; + +#ifdef DISABLE_OPENGL + /* height=480 to fit interlaced output */ + main_texture = SDL_CreateTexture(main_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 320, 480); +#else glGenTextures(3, textures); for (int i = 0; i < 3; i++) { @@ -191,10 +203,20 @@ void render_alloc_surfaces(vdp_context * context) un_textures[1] = glGetUniformLocation(program, "textures[1]"); un_width = glGetUniformLocation(program, "width"); at_pos = glGetAttribLocation(program, "pos"); +#endif } char * caption = NULL; +static void render_quit() +{ + render_close_audio(); +#ifdef DISABLE_OPENGL + SDL_DestroyTexture(main_texture); +#endif + SDL_Quit(); +} + void render_init(int width, int height, char * title, uint32_t fps, uint8_t fullscreen) { if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) < 0) { @@ -202,14 +224,9 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full exit(1); } printf("width: %d, height: %d\n", width, height); - uint32_t flags = SDL_WINDOW_OPENGL; + uint32_t flags = 0; - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); if (fullscreen) { flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; SDL_DisplayMode mode; @@ -220,14 +237,31 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full width = mode.w; height = mode.h; } + +#ifdef DISABLE_OPENGL + SDL_CreateWindowAndRenderer(width, height, flags, &main_window, &main_renderer); + + if (!main_window || !main_renderer) { + fprintf(stderr, "unable to create SDL window: %s\n", SDL_GetError()); + SDL_Quit(); + exit(1); + } + main_clip.x = main_clip.y = 0; + main_clip.w = width; + main_clip.h = height; +#else + flags |= SDL_WINDOW_OPENGL; + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); main_window = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, flags); if (!main_window) { fprintf(stderr, "Unable to create SDL window: %s\n", SDL_GetError()); SDL_Quit(); exit(1); } - SDL_GetWindowSize(main_window, &width, &height); - printf("Window created with size: %d x %d\n", width, height); main_context = SDL_GL_CreateContext(main_window); GLenum res = glewInit(); if (res != GLEW_OK) { @@ -240,18 +274,36 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full SDL_Quit(); exit(1); } - float aspect = (float)width / height; +#endif + SDL_GetWindowSize(main_window, &width, &height); + printf("Window created with size: %d x %d\n", width, height); + float src_aspect = 4.0/3.0; + float aspect = (float)width / height; tern_val def = {.ptrval = "normal"}; - if (fabs(aspect - 4.0/3.0) > 0.01 && strcmp(tern_find_path_default(config, "video\0aspect\0", def).ptrval, "stretch")) { + int stretch = fabs(aspect - src_aspect) > 0.01 && !strcmp(tern_find_path_default(config, "video\0aspect\0", def).ptrval, "stretch"); + +#ifdef DISABLE_OPENGL + if (!stretch) { + float scale_x = (float)width / 320.0; + float scale_y = (float)height / 240.0; + float scale = scale_x > scale_y ? scale_y : scale_x; + main_clip.w = 320.0 * scale; + main_clip.h = 240.0 * scale; + main_clip.x = (width - main_clip.w) / 2; + main_clip.y = (height - main_clip.h) / 2; + } +#else + if (!stretch) { for (int i = 0; i < 4; i++) { - if (aspect > 4.0/3.0) { - vertex_data[i*2] *= (4.0/3.0)/aspect; + if (aspect > src_aspect) { + vertex_data[i*2] *= src_aspect/aspect; } else { - vertex_data[i*2+1] *= aspect/(4.0/3.0); + vertex_data[i*2+1] *= aspect/src_aspect; } } } +#endif caption = title; min_delay = 0; for (int i = 0; i < 100; i++) { @@ -315,14 +367,54 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full } SDL_JoystickEventState(SDL_ENABLE); - atexit(SDL_Quit); - atexit(render_close_audio); + atexit(render_quit); } void render_context(vdp_context * context) { + int width = context->regs[REG_MODE_4] & BIT_H40 ? 320.0f : 256.0f; + int height = 240; + last_frame = SDL_GetTicks(); - +#ifdef DISABLE_OPENGL + SDL_Rect area; + + area.x = area.y = 0; + area.w = width; + area.h = height; + + if (context->regs[REG_MODE_4] & BIT_INTERLACE) + { + unsigned skip; + uint32_t *src = (uint32_t*)context->framebuf; + uint8_t *dst; + int i; + + area.h *= 2; + + SDL_LockTexture(main_texture, &area, (void**)&dst, &skip); + + if (context->framebuf == context->evenbuf) + dst += skip; + + skip *= 2; + + for (i = 0; i < 240; ++i) + { + memcpy(dst, src, width*sizeof(uint32_t)); + src += 320; + dst += skip; + } + + SDL_UnlockTexture(main_texture); + } + else /* possibly faster path for non-interlaced output */ + SDL_UpdateTexture(main_texture, &area, context->framebuf, 320*sizeof(uint32_t)); + + SDL_RenderClear(main_renderer); + SDL_RenderCopy(main_renderer, main_texture, &area, &main_clip); + SDL_RenderPresent(main_renderer); +#else glBindTexture(GL_TEXTURE_2D, textures[context->framebuf == context->oddbuf ? 0 : 1]); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 320, 240, GL_BGRA, GL_UNSIGNED_BYTE, context->framebuf);; @@ -338,7 +430,7 @@ void render_context(vdp_context * context) glBindTexture(GL_TEXTURE_2D, (context->regs[REG_MODE_4] & BIT_INTERLACE) ? textures[1] : textures[2]); glUniform1i(un_textures[1], 1); - glUniform1f(un_width, context->regs[REG_MODE_4] & BIT_H40 ? 320.0f : 256.0f); + glUniform1f(un_width, width); glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); glVertexAttribPointer(at_pos, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat[2]), (void *)0); @@ -350,6 +442,7 @@ void render_context(vdp_context * context) glDisableVertexAttribArray(at_pos); SDL_GL_SwapWindow(main_window); +#endif if (context->regs[REG_MODE_4] & BIT_INTERLACE) { context->framebuf = context->framebuf == context->oddbuf ? context->evenbuf : context->oddbuf; -- cgit v1.2.3 From 4755aa94deb0a8fb90bf74033d370e9370d69ca2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=3D=3FUTF-8=3Fq=3FHigor=3D20Eur=3DC3=3DADpedes=3F=3D?= Date: Sun, 26 Jul 2015 13:08:22 -0700 Subject: Use SDL2 renderer as a fallback --- render_sdl.c | 275 +++++++++++++++++++++++++++++++---------------------------- 1 file changed, 146 insertions(+), 129 deletions(-) (limited to 'render_sdl.c') diff --git a/render_sdl.c b/render_sdl.c index a80acc4..b20808e 100755 --- a/render_sdl.c +++ b/render_sdl.c @@ -12,19 +12,19 @@ #include "io.h" #include "util.h" +#ifndef DISABLE_OPENGL #include +#endif SDL_Window *main_window; -#ifdef DISABLE_OPENGL SDL_Renderer *main_renderer; SDL_Texture *main_texture; SDL_Rect main_clip; -#else SDL_GLContext *main_context; -#endif uint8_t render_dbg = 0; uint8_t debug_pal = 0; +uint8_t render_gl = 1; uint32_t last_frame = 0; @@ -101,6 +101,7 @@ uint32_t render_map_color(uint8_t r, uint8_t g, uint8_t b) return 255 << 24 | r << 16 | g << 8 | b; } +#ifndef DISABLE_OPENGL GLuint textures[3], buffers[2], vshader, fshader, program, un_textures[2], un_width, at_pos; GLfloat vertex_data[] = { @@ -154,6 +155,7 @@ GLuint load_shader(char * fname, GLenum shader_type) } return ret; } +#endif void render_alloc_surfaces(vdp_context * context) { @@ -161,48 +163,52 @@ void render_alloc_surfaces(vdp_context * context) memset(context->oddbuf, 0, 512 * 256 * 4 * 2); context->evenbuf = ((char *)context->oddbuf) + 512 * 256 * 4; -#ifdef DISABLE_OPENGL - /* height=480 to fit interlaced output */ - main_texture = SDL_CreateTexture(main_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 320, 480); -#else - glGenTextures(3, textures); - for (int i = 0; i < 3; i++) - { - glBindTexture(GL_TEXTURE_2D, textures[i]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - if (i < 2) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 512, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, i ? context->evenbuf : context->oddbuf); - } else { - uint32_t blank = 255 << 24; - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_BGRA, GL_UNSIGNED_BYTE, &blank); +#ifndef DISABLE_OPENGL + if (render_gl) { + glGenTextures(3, textures); + for (int i = 0; i < 3; i++) + { + glBindTexture(GL_TEXTURE_2D, textures[i]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + if (i < 2) { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 512, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, i ? context->evenbuf : context->oddbuf); + } else { + uint32_t blank = 255 << 24; + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_BGRA, GL_UNSIGNED_BYTE, &blank); + } } + glGenBuffers(2, buffers); + glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(element_data), element_data, GL_STATIC_DRAW); + tern_val def = {.ptrval = "default.v.glsl"}; + vshader = load_shader(tern_find_path_default(config, "video\0vertex_shader\0", def).ptrval, GL_VERTEX_SHADER); + def.ptrval = "default.f.glsl"; + fshader = load_shader(tern_find_path_default(config, "video\0fragment_shader\0", def).ptrval, GL_FRAGMENT_SHADER); + program = glCreateProgram(); + glAttachShader(program, vshader); + glAttachShader(program, fshader); + glLinkProgram(program); + GLint link_status; + glGetProgramiv(program, GL_LINK_STATUS, &link_status); + if (!link_status) { + fputs("Failed to link shader program\n", stderr); + exit(1); + } + un_textures[0] = glGetUniformLocation(program, "textures[0]"); + un_textures[1] = glGetUniformLocation(program, "textures[1]"); + un_width = glGetUniformLocation(program, "width"); + at_pos = glGetAttribLocation(program, "pos"); + } else { +#endif + /* height=480 to fit interlaced output */ + main_texture = SDL_CreateTexture(main_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 320, 480); +#ifndef DISABLE_OPENGL } - glGenBuffers(2, buffers); - glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(element_data), element_data, GL_STATIC_DRAW); - tern_val def = {.ptrval = "default.v.glsl"}; - vshader = load_shader(tern_find_path_default(config, "video\0vertex_shader\0", def).ptrval, GL_VERTEX_SHADER); - def.ptrval = "default.f.glsl"; - fshader = load_shader(tern_find_path_default(config, "video\0fragment_shader\0", def).ptrval, GL_FRAGMENT_SHADER); - program = glCreateProgram(); - glAttachShader(program, vshader); - glAttachShader(program, fshader); - glLinkProgram(program); - GLint link_status; - glGetProgramiv(program, GL_LINK_STATUS, &link_status); - if (!link_status) { - fputs("Failed to link shader program\n", stderr); - exit(1); - } - un_textures[0] = glGetUniformLocation(program, "textures[0]"); - un_textures[1] = glGetUniformLocation(program, "textures[1]"); - un_width = glGetUniformLocation(program, "width"); - at_pos = glGetAttribLocation(program, "pos"); #endif } @@ -238,18 +244,9 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full height = mode.h; } -#ifdef DISABLE_OPENGL - SDL_CreateWindowAndRenderer(width, height, flags, &main_window, &main_renderer); + render_gl = 0; - if (!main_window || !main_renderer) { - fprintf(stderr, "unable to create SDL window: %s\n", SDL_GetError()); - SDL_Quit(); - exit(1); - } - main_clip.x = main_clip.y = 0; - main_clip.w = width; - main_clip.h = height; -#else +#ifndef DISABLE_OPENGL flags |= SDL_WINDOW_OPENGL; SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); @@ -266,15 +263,30 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full GLenum res = glewInit(); if (res != GLEW_OK) { fprintf(stderr, "Initialization of GLEW failed with code %d\n", res); - SDL_Quit(); - exit(1); + SDL_DestroyWindow(main_window); } - if (!GLEW_VERSION_2_0) { - fputs("BlastEm requires at least OpenGL 2.0, but it is unavailable\n", stderr); - SDL_Quit(); - exit(1); + + if (GLEW_VERSION_2_0) { + render_gl = 1; } + else { + SDL_DestroyWindow(main_window); + fputs("OpenGL 2.0 is unavailable, falling back to SDL2 renderer\n", stderr); #endif + SDL_CreateWindowAndRenderer(width, height, flags, &main_window, &main_renderer); + + if (!main_window || !main_renderer) { + fprintf(stderr, "unable to create SDL window: %s\n", SDL_GetError()); + SDL_Quit(); + exit(1); + } + main_clip.x = main_clip.y = 0; + main_clip.w = width; + main_clip.h = height; +#ifndef DISABLE_OPENGL + } +#endif + SDL_GetWindowSize(main_window, &width, &height); printf("Window created with size: %d x %d\n", width, height); float src_aspect = 4.0/3.0; @@ -282,28 +294,31 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full tern_val def = {.ptrval = "normal"}; int stretch = fabs(aspect - src_aspect) > 0.01 && !strcmp(tern_find_path_default(config, "video\0aspect\0", def).ptrval, "stretch"); -#ifdef DISABLE_OPENGL - if (!stretch) { - float scale_x = (float)width / 320.0; - float scale_y = (float)height / 240.0; - float scale = scale_x > scale_y ? scale_y : scale_x; - main_clip.w = 320.0 * scale; - main_clip.h = 240.0 * scale; - main_clip.x = (width - main_clip.w) / 2; - main_clip.y = (height - main_clip.h) / 2; - } -#else if (!stretch) { - for (int i = 0; i < 4; i++) - { - if (aspect > src_aspect) { - vertex_data[i*2] *= src_aspect/aspect; - } else { - vertex_data[i*2+1] *= aspect/src_aspect; +#ifndef DISABLE_OPENGL + if (render_gl) { + for (int i = 0; i < 4; i++) + { + if (aspect > src_aspect) { + vertex_data[i*2] *= src_aspect/aspect; + } else { + vertex_data[i*2+1] *= aspect/src_aspect; + } } + } else { +#endif + float scale_x = (float)width / 320.0; + float scale_y = (float)height / 240.0; + float scale = scale_x > scale_y ? scale_y : scale_x; + main_clip.w = 320.0 * scale; + main_clip.h = 240.0 * scale; + main_clip.x = (width - main_clip.w) / 2; + main_clip.y = (height - main_clip.h) / 2; +#ifndef DISABLE_OPENGL } - } #endif + } + caption = title; min_delay = 0; for (int i = 0; i < 100; i++) { @@ -376,75 +391,77 @@ void render_context(vdp_context * context) int height = 240; last_frame = SDL_GetTicks(); -#ifdef DISABLE_OPENGL - SDL_Rect area; +#ifndef DISABLE_OPENGL + if (render_gl) { + glBindTexture(GL_TEXTURE_2D, textures[context->framebuf == context->oddbuf ? 0 : 1]); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 320, 240, GL_BGRA, GL_UNSIGNED_BYTE, context->framebuf);; - area.x = area.y = 0; - area.w = width; - area.h = height; + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); - if (context->regs[REG_MODE_4] & BIT_INTERLACE) - { - unsigned skip; - uint32_t *src = (uint32_t*)context->framebuf; - uint8_t *dst; - int i; + glUseProgram(program); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, textures[0]); + glUniform1i(un_textures[0], 0); - area.h *= 2; + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, (context->regs[REG_MODE_4] & BIT_INTERLACE) ? textures[1] : textures[2]); + glUniform1i(un_textures[1], 1); - SDL_LockTexture(main_texture, &area, (void**)&dst, &skip); + glUniform1f(un_width, width); - if (context->framebuf == context->evenbuf) - dst += skip; + glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); + glVertexAttribPointer(at_pos, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat[2]), (void *)0); + glEnableVertexAttribArray(at_pos); - skip *= 2; + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); + glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void *)0); - for (i = 0; i < 240; ++i) - { - memcpy(dst, src, width*sizeof(uint32_t)); - src += 320; - dst += skip; - } + glDisableVertexAttribArray(at_pos); - SDL_UnlockTexture(main_texture); - } - else /* possibly faster path for non-interlaced output */ - SDL_UpdateTexture(main_texture, &area, context->framebuf, 320*sizeof(uint32_t)); + SDL_GL_SwapWindow(main_window); + } else { +#endif + SDL_Rect area; - SDL_RenderClear(main_renderer); - SDL_RenderCopy(main_renderer, main_texture, &area, &main_clip); - SDL_RenderPresent(main_renderer); -#else - glBindTexture(GL_TEXTURE_2D, textures[context->framebuf == context->oddbuf ? 0 : 1]); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 320, 240, GL_BGRA, GL_UNSIGNED_BYTE, context->framebuf);; + area.x = area.y = 0; + area.w = width; + area.h = height; - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); + if (context->regs[REG_MODE_4] & BIT_INTERLACE) { + unsigned skip; + uint32_t *src = (uint32_t*)context->framebuf; + uint8_t *dst; + int i; - glUseProgram(program); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, textures[0]); - glUniform1i(un_textures[0], 0); + area.h *= 2; - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, (context->regs[REG_MODE_4] & BIT_INTERLACE) ? textures[1] : textures[2]); - glUniform1i(un_textures[1], 1); + SDL_LockTexture(main_texture, &area, (void**)&dst, &skip); - glUniform1f(un_width, width); + if (context->framebuf == context->evenbuf) + dst += skip; - glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); - glVertexAttribPointer(at_pos, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat[2]), (void *)0); - glEnableVertexAttribArray(at_pos); + skip *= 2; - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); - glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void *)0); + for (i = 0; i < 240; ++i) { + memcpy(dst, src, width*sizeof(uint32_t)); + src += 320; + dst += skip; + } - glDisableVertexAttribArray(at_pos); + SDL_UnlockTexture(main_texture); + } + else /* possibly faster path for non-interlaced output */ + SDL_UpdateTexture(main_texture, &area, context->framebuf, 320*sizeof(uint32_t)); - SDL_GL_SwapWindow(main_window); + SDL_RenderClear(main_renderer); + SDL_RenderCopy(main_renderer, main_texture, &area, &main_clip); + SDL_RenderPresent(main_renderer); +#ifndef DISABLE_OPENGL + } #endif - if (context->regs[REG_MODE_4] & BIT_INTERLACE) - { + + if (context->regs[REG_MODE_4] & BIT_INTERLACE) { context->framebuf = context->framebuf == context->oddbuf ? context->evenbuf : context->oddbuf; } } -- cgit v1.2.3 From ddf40125853bc97a5122a1f4e740a6ba6ae526c3 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Sun, 26 Jul 2015 13:33:48 -0700 Subject: Minor cleanup --- render_sdl.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'render_sdl.c') diff --git a/render_sdl.c b/render_sdl.c index 8a4b20d..a2f094e 100755 --- a/render_sdl.c +++ b/render_sdl.c @@ -126,14 +126,14 @@ GLuint load_shader(char * fname, GLenum shader_type) f = fopen(shader_path, "r"); free(shader_path); if (!f) { - fprintf(stderr, "Failed to open shader file %s for reading\n", fname); + warning("Failed to open shader file %s for reading\n", fname); return 0; } } long fsize = file_size(f); GLchar * text = malloc(fsize); if (fread(text, 1, fsize, f) != fsize) { - fprintf(stderr, "Error reading from shader file %s\n", fname); + warning("Error reading from shader file %s\n", fname); free(text); return 0; } @@ -144,11 +144,10 @@ GLuint load_shader(char * fname, GLenum shader_type) GLint compile_status, loglen; glGetShaderiv(ret, GL_COMPILE_STATUS, &compile_status); if (!compile_status) { - fprintf(stderr, "Shader %s failed to compile\n", fname); glGetShaderiv(ret, GL_INFO_LOG_LENGTH, &loglen); text = malloc(loglen); glGetShaderInfoLog(ret, loglen, NULL, text); - fputs(text, stderr); + warning("Shader %s failed to compile:\n%s\n", fname, text); free(text); glDeleteShader(ret); return 0; @@ -259,22 +258,19 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full main_context = SDL_GL_CreateContext(main_window); GLenum res = glewInit(); if (res != GLEW_OK) { - fprintf(stderr, "Initialization of GLEW failed with code %d\n", res); + warning("Initialization of GLEW failed with code %d\n", res); } - if (GLEW_VERSION_2_0) { + if (res == GLEW_OK && GLEW_VERSION_2_0) { render_gl = 1; - } - else { + } else { SDL_DestroyWindow(main_window); - fputs("OpenGL 2.0 is unavailable, falling back to SDL2 renderer\n", stderr); + warning("OpenGL 2.0 is unavailable, falling back to SDL2 renderer\n", stderr); #endif SDL_CreateWindowAndRenderer(width, height, flags, &main_window, &main_renderer); if (!main_window || !main_renderer) { - fprintf(stderr, "unable to create SDL window: %s\n", SDL_GetError()); - SDL_Quit(); - exit(1); + fatal_error("unable to create SDL window: %s\n", SDL_GetError()); } main_clip.x = main_clip.y = 0; main_clip.w = width; -- cgit v1.2.3