diff options
author | =?UTF-8?q?Higor=20Eur=C3=ADpedes?= <heuripedes@gmail.com> | 2015-07-26 13:05:05 -0700 |
---|---|---|
committer | =?UTF-8?q?Higor=20Eur=C3=ADpedes?= <heuripedes@gmail.com> | 2015-07-26 13:05:05 -0700 |
commit | 711f53c6685783e5effb17e493450ed5d09b3aa1 (patch) | |
tree | 412d873318c61c96c5483c187f5a42b78fb89ccd | |
parent | 6c280f3b1f8e072f86fc41b371cf616be1483030 (diff) |
Add pure SDL2 renderer
-rwxr-xr-x[-rw-r--r--] | render_sdl.c | 127 |
1 files changed, 110 insertions, 17 deletions
diff --git a/render_sdl.c b/render_sdl.c index 82f8b12..a80acc4 100644..100755 --- a/render_sdl.c +++ b/render_sdl.c @@ -15,7 +15,14 @@ #include <GL/glew.h> 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; |