Mercurial > repos > blastem
diff render_sdl.c @ 1077:1a66d5165ea7
Cleanup the separation of render backend and VDP code in preparation for having extra debug windows. Make determination of H40/H32 based on number of lines in each mode.
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 22 Aug 2016 09:46:18 -0700 |
parents | 3a0f684891ae |
children | c15896605bf2 |
line wrap: on
line diff
--- a/render_sdl.c Fri Aug 12 09:39:39 2016 -0700 +++ b/render_sdl.c Mon Aug 22 09:46:18 2016 -0700 @@ -16,9 +16,12 @@ #include <GL/glew.h> #endif +#define MAX_EVENT_POLL_PER_FRAME 2 + SDL_Window *main_window; SDL_Renderer *main_renderer; -SDL_Texture *main_texture; +SDL_Texture **sdl_textures; +uint8_t num_textures; SDL_Rect main_clip; SDL_GLContext *main_context; @@ -168,19 +171,20 @@ } #endif -void render_alloc_surfaces(vdp_context * context) +uint32_t texture_buf[512 * 256]; +void render_alloc_surfaces() { static uint8_t texture_init; - 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; if (texture_init) { return; } + sdl_textures= malloc(sizeof(SDL_Texture *) * 2); + num_textures = 2; texture_init = 1; #ifndef DISABLE_OPENGL if (render_gl) { + sdl_textures[0] = sdl_textures[1] = NULL; glGenTextures(3, textures); for (int i = 0; i < 3; i++) { @@ -190,7 +194,7 @@ 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); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 512, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, texture_buf); } else { uint32_t blank = 255 << 24; glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_BGRA, GL_UNSIGNED_BYTE, &blank); @@ -221,27 +225,26 @@ 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); + + //height=480 to fit interlaced output + sdl_textures[0] = sdl_textures[1] = SDL_CreateTexture(main_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 320, 480); #ifndef DISABLE_OPENGL } #endif } -void render_free_surfaces(vdp_context *context) -{ - free(context->framebuf); -} - char * caption = NULL; char * fps_caption = NULL; static void render_quit() { render_close_audio(); -#ifdef DISABLE_OPENGL - SDL_DestroyTexture(main_texture); -#endif + for (int i = 0; i < num_textures; i++) + { + if (sdl_textures[i]) { + SDL_DestroyTexture(sdl_textures[i]); + } + } } void render_init(int width, int height, char * title, uint32_t fps, uint8_t fullscreen) @@ -356,6 +359,7 @@ } #endif } + render_alloc_surfaces(); def.ptrval = "off"; scanlines = !strcmp(tern_find_path_default(config, "video\0scanlines\0", def).ptrval, "on"); @@ -419,16 +423,57 @@ fps_caption = NULL; } -void render_context(vdp_context * context) +uint32_t *locked_pixels; +uint32_t locked_pitch; +uint32_t *render_get_framebuffer(uint8_t which, int *pitch) { - int width = context->regs[REG_MODE_4] & BIT_H40 ? 320.0f : 256.0f; - int height = 240; +#ifndef DISABLE_OPENGL + if (render_gl && which <= FRAMEBUFFER_EVEN) { + *pitch = 320 * sizeof(uint32_t); //TODO: change this to LINEBUF_SIZE once border rendering is added + return texture_buf; + } else { +#endif + if (which >= num_textures) { + warning("Request for invalid framebuffer number %d\n", which); + return NULL; + } + void *pixels; + if (SDL_LockTexture(sdl_textures[which], NULL, &pixels, pitch) < 0) { + warning("Failed to lock texture: %s\n", SDL_GetError()); + return NULL; + } + static uint8_t last; + if (which <= FRAMEBUFFER_EVEN) { + locked_pixels = pixels; + if (which == FRAMEBUFFER_EVEN) { + pixels += *pitch; + } + locked_pitch = *pitch; + if (which != last) { + *pitch *= 2; + } + last = which; + } + return pixels; +#ifndef DISABLE_OPENGL + } +#endif +} - last_frame = SDL_GetTicks(); +uint8_t events_processed; +#ifdef __ANDROID__ +#define FPS_INTERVAL 10000 +#else +#define FPS_INTERVAL 1000 +#endif + +void render_framebuffer_updated(uint8_t which, int width) +{ + static uint8_t last; #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);; + if (render_gl && which <= FRAMEBUFFER_EVEN) { + glBindTexture(GL_TEXTURE_2D, textures[which]); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 320, 240, GL_BGRA, GL_UNSIGNED_BYTE, texture_buf); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); @@ -439,7 +484,7 @@ glUniform1i(un_textures[0], 0); glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, textures[(context->regs[REG_MODE_4] & BIT_INTERLACE) ? 1 : scanlines ? 2 : 0]); + glBindTexture(GL_TEXTURE_2D, textures[last != which ? 1 : scanlines ? 2 : 0]); glUniform1i(un_textures[1], 1); glUniform1f(un_width, width); @@ -456,48 +501,60 @@ SDL_GL_SwapWindow(main_window); } else { #endif - 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; + uint32_t height = 240; + if (which <= FRAMEBUFFER_EVEN && last != which) { + uint8_t *cur_dst = (uint8_t *)locked_pixels; + uint8_t *cur_saved = (uint8_t *)texture_buf; + uint32_t dst_off = which == FRAMEBUFFER_EVEN ? 0 : locked_pitch; + uint32_t src_off = which == FRAMEBUFFER_EVEN ? locked_pitch : 0; + for (int i = 0; i < 240; ++i) + { + //copy saved line from other field + memcpy(cur_dst + dst_off, cur_saved, locked_pitch); + //save line from this field to buffer for next frame + memcpy(cur_saved, cur_dst + src_off, locked_pitch); + cur_dst += locked_pitch * 2; + cur_saved += locked_pitch; } - - SDL_UnlockTexture(main_texture); + height = 480; } - 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_UnlockTexture(sdl_textures[which]); + SDL_Rect src_clip = { + .x = 0, + .y = 0, + .w = width, + .h = height + }; + SDL_RenderCopy(main_renderer, sdl_textures[which], &src_clip, &main_clip); SDL_RenderPresent(main_renderer); #ifndef DISABLE_OPENGL } #endif - - if (context->regs[REG_MODE_4] & BIT_INTERLACE) { - context->framebuf = context->framebuf == context->oddbuf ? context->evenbuf : context->oddbuf; + if (which <= FRAMEBUFFER_EVEN) { + last = which; + static uint32_t frame_counter, start; + frame_counter++; + last_frame= SDL_GetTicks(); + if ((last_frame - start) > FPS_INTERVAL) { + if (start && (last_frame-start)) { + #ifdef __ANDROID__ + info_message("%s - %.1f fps", caption, ((float)frame_counter) / (((float)(last_frame-start)) / 1000.0)); + #else + if (!fps_caption) { + fps_caption = malloc(strlen(caption) + strlen(" - 100000000.1 fps") + 1); + } + sprintf(fps_caption, "%s - %.1f fps", caption, ((float)frame_counter) / (((float)(last_frame-start)) / 1000.0)); + SDL_SetWindowTitle(main_window, fps_caption); + #endif + } + start = last_frame; + frame_counter = 0; + } } + if (!events_processed) { + process_events(); + } + events_processed = 0; } void render_wait_quit(vdp_context * context) @@ -505,20 +562,6 @@ SDL_Event event; while(SDL_WaitEvent(&event)) { switch (event.type) { - case SDL_KEYDOWN: - if (event.key.keysym.sym == SDLK_LEFTBRACKET) { - render_dbg++; - if (render_dbg == 4) { - render_dbg = 0; - } - render_context(context); - } else if(event.key.keysym.sym == SDLK_RIGHTBRACKET) { - debug_pal++; - if (debug_pal == 4) { - debug_pal = 0; - } - } - break; case SDL_QUIT: return; } @@ -720,60 +763,16 @@ return 0; } -uint32_t frame_counter = 0; -uint32_t start = 0; -#ifdef __ANDROID__ -#define FPS_INTERVAL 10000 -#else -#define FPS_INTERVAL 1000 -#endif -int wait_render_frame(vdp_context * context, int frame_limit) -{ - SDL_Event event; - int ret = 0; - while(SDL_PollEvent(&event)) { - ret = handle_event(&event); - } - if (frame_limit) { - //TODO: Adjust frame delay so we actually get 60 FPS rather than 62.5 FPS - uint32_t current = SDL_GetTicks(); - uint32_t desired = last_frame + frame_delay; - if (current < desired) { - uint32_t delay = last_frame + frame_delay - current; - if (delay > min_delay) { - SDL_Delay((delay/min_delay)*min_delay); - } - while ((desired) >= SDL_GetTicks()) { - } - } - } - render_context(context); - - frame_counter++; - if ((last_frame - start) > FPS_INTERVAL) { - if (start && (last_frame-start)) { -#ifdef __ANDROID__ - info_message("%s - %.1f fps", caption, ((float)frame_counter) / (((float)(last_frame-start)) / 1000.0)); -#else - if (!fps_caption) { - fps_caption = malloc(strlen(caption) + strlen(" - 100000000.1 fps") + 1); - } - sprintf(fps_caption, "%s - %.1f fps", caption, ((float)frame_counter) / (((float)(last_frame-start)) / 1000.0)); - SDL_SetWindowTitle(main_window, fps_caption); -#endif - } - start = last_frame; - frame_counter = 0; - } - return ret; -} - void process_events() { + if (events_processed > MAX_EVENT_POLL_PER_FRAME) { + return; + } SDL_Event event; while(SDL_PollEvent(&event)) { handle_event(&event); } + events_processed++; } void render_wait_psg(psg_context * context)