# HG changeset patch # User Michael Pavone # Date 1432173911 25200 # Node ID 019d27995e32c60a95afa07f5321a67d8f321333 # Parent eaba6789f3161a99ec75a57df84b965aef1851ed Upgrade to SDL 2.0 and drop support for the non-OpenGL render path diff -r eaba6789f316 -r 019d27995e32 Makefile --- a/Makefile Wed May 20 10:35:03 2015 -0700 +++ b/Makefile Wed May 20 19:05:11 2015 -0700 @@ -2,14 +2,10 @@ OS:=$(shell uname -s) endif -ifdef NOGL -LIBS=sdl +ifeq ($(OS),Darwin) +LIBS=sdl2 glew else -ifeq ($(OS),Darwin) -LIBS=sdl glew -else -LIBS=sdl glew gl -endif +LIBS=sdl2 glew gl endif ifdef DEBUG diff -r eaba6789f316 -r 019d27995e32 blastem.c --- a/blastem.c Wed May 20 10:35:03 2015 -0700 +++ b/blastem.c Wed May 20 19:05:11 2015 -0700 @@ -1263,7 +1263,7 @@ fps = 50; } if (!headless) { - render_init(width, height, title, fps, fullscreen, use_gl); + render_init(width, height, title, fps, fullscreen); } vdp_context v_context; genesis_context gen; diff -r eaba6789f316 -r 019d27995e32 render.h --- a/render.h Wed May 20 10:35:03 2015 -0700 +++ b/render.h Wed May 20 19:05:11 2015 -0700 @@ -18,8 +18,7 @@ uint32_t render_map_color(uint8_t r, uint8_t g, uint8_t b); void render_alloc_surfaces(vdp_context * context); -uint8_t render_depth(); -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); void render_context(vdp_context * context); void render_wait_quit(vdp_context * context); void render_wait_psg(psg_context * context); diff -r eaba6789f316 -r 019d27995e32 render_sdl.c --- a/render_sdl.c Wed May 20 10:35:03 2015 -0700 +++ b/render_sdl.c Wed May 20 19:05:11 2015 -0700 @@ -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 @@ 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 @@ } 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); - } + 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); - } - 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; + uint32_t flags = SDL_WINDOW_OPENGL; + -#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; - } + 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; } - screen = SDL_SetVideoMode(width, height, 32, flags); - if (!screen) { - fprintf(stderr, "Unable to get SDL surface: %s\n", SDL_GetError()); + 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); } - 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_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); } -#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); - } + if (!GLEW_VERSION_2_0) { + fputs("BlastEm requires at least OpenGL 2.0, but it is unavailable\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); } } } - 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 @@ 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 @@ 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 @@ 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 @@ } 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 @@ 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; diff -r eaba6789f316 -r 019d27995e32 stateview.c --- a/stateview.c Wed May 20 10:35:03 2015 -0700 +++ b/stateview.c Wed May 20 19:05:11 2015 -0700 @@ -87,7 +87,7 @@ height = height < 240 ? (width/320) * 240 : height; vdp_context context; - render_init(width, height, "GST State Viewer", 60, 0, 0); + render_init(width, height, "GST State Viewer", 60, 0); init_vdp_context(&context, 0); vdp_load_gst(&context, state_file); vdp_run_to_vblank(&context); diff -r eaba6789f316 -r 019d27995e32 vdp.c --- a/vdp.c Wed May 20 10:35:03 2015 -0700 +++ b/vdp.c Wed May 20 19:05:11 2015 -0700 @@ -62,10 +62,8 @@ memset(context->framebuf, 0, FRAMEBUF_ENTRIES * (32 / 8)); context->evenbuf = malloc(FRAMEBUF_ENTRIES * (32 / 8)); memset(context->evenbuf, 0, FRAMEBUF_ENTRIES * (32 / 8)); - context->b32 = 1; } else { render_alloc_surfaces(context); - context->b32 = render_depth() == 32; } context->framebuf = context->oddbuf; context->linebuf = malloc(LINEBUF_SIZE + SCROLL_BUFFER_SIZE*2); @@ -788,20 +786,14 @@ return; } render_map(context->col_2, context->tmp_buf_b, context->buf_b_off+8, context); - uint16_t *dst; - uint32_t *dst32; + uint32_t *dst; uint8_t *sprite_buf, *plane_a, *plane_b; int plane_a_off, plane_b_off; if (col) { col-=2; - if (context->b32) { - dst32 = context->framebuf; - dst32 += line * 320 + col * 8; - } else { - dst = context->framebuf; - dst += line * 320 + col * 8; - } + dst = context->framebuf; + dst += line * 320 + col * 8; sprite_buf = context->linebuf + col * 8; uint8_t a_src, src; if (context->flags & FLAG_WINDOW) { @@ -859,11 +851,7 @@ } else { outpixel = colors[pixel]; } - if (context->b32) { - *(dst32++) = outpixel; - } else { - *(dst++) = outpixel; - } + *(dst++) = outpixel; //*dst = (context->cram[pixel & 0x3F] & 0xEEE) | ((pixel & BUF_BIT_PRIORITY) ? FBUF_BIT_PRIORITY : 0) | src; } } else { @@ -890,11 +878,7 @@ } else { outpixel = context->colors[pixel & 0x3F]; } - if (context->b32) { - *(dst32++) = outpixel; - } else { - *(dst++) = outpixel; - } + *(dst++) = outpixel; } } } @@ -1445,20 +1429,11 @@ } } if (starti >= 0) { - if (context->b32) { - uint32_t color = context->colors[context->regs[REG_BG_COLOR]]; - uint32_t * start = context->framebuf; - start += starti; - for (int i = 0; i < 2; i++) { - *(start++) = color; - } - } else { - uint16_t color = context->colors[context->regs[REG_BG_COLOR]]; - uint16_t * start = context->framebuf; - start += starti; - for (int i = 0; i < 2; i++) { - *(start++) = color; - } + uint32_t color = context->colors[context->regs[REG_BG_COLOR]]; + uint32_t * start = context->framebuf; + start += starti; + for (int i = 0; i < 2; i++) { + *(start++) = color; } } } diff -r eaba6789f316 -r 019d27995e32 vgmplay.c --- a/vgmplay.c Wed May 20 10:35:03 2015 -0700 +++ b/vgmplay.c Wed May 20 19:05:11 2015 -0700 @@ -142,7 +142,7 @@ uint32_t fps = 60; config = load_config(argv[0]); - render_init(320, 240, "vgm play", 60, 0, 0); + render_init(320, 240, "vgm play", 60, 0); uint32_t opts = 0; if (argc >= 3 && !strcmp(argv[2], "-y")) {