From 5b85e48cd1e203b626e0f9a39ff9207501559b23 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Tue, 31 Mar 2020 20:33:03 +0400 Subject: [PATCH] sdl2: add software render support --- src/sdl2/main.c | 120 +++++++++++++++++++++++++++++++++++++----------- src/system.h | 25 ++++++++++ 2 files changed, 117 insertions(+), 28 deletions(-) create mode 100644 src/system.h diff --git a/src/sdl2/main.c b/src/sdl2/main.c index 673b5f9..0babe5e 100644 --- a/src/sdl2/main.c +++ b/src/sdl2/main.c @@ -20,9 +20,12 @@ #include "music.h" // S_initmusic S_updatemusic S_donemusic #include "render.h" // R_init R_draw R_done +#define TITLE_STR "DooM 2D (SDL2)" + static int quit = 0; static SDL_Window *window; static SDL_GLContext context; +static SDL_Surface *surf; /* --- error.h --- */ @@ -70,38 +73,66 @@ void ERR_quit (void) { /* --- system.h --- */ -int Y_set_videomode (int w, int h, int flags) { +static int Y_set_videomode_opengl (int w, int h, int fullscreen) { assert(w > 0); assert(h > 0); - Uint32 f = SDL_WINDOW_HIDDEN; - if (flags & SYSTEM_USE_FULLSCREEN) { - f = f | SDL_WINDOW_FULLSCREEN; + Uint32 flags = SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL; + flags |= fullscreen ? SDL_WINDOW_FULLSCREEN : 0; + // TODO set context version and type + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + int x = SDL_WINDOWPOS_CENTERED; + int y = SDL_WINDOWPOS_CENTERED; + SDL_Window *win = SDL_CreateWindow(TITLE_STR, x, y, w, h, flags); + if (win != NULL) { + SDL_GLContext ctx = SDL_GL_CreateContext(win); + if (ctx != NULL) { + Y_unset_videomode(); + window = win; + context = ctx; + SDL_GL_MakeCurrent(window, context); + SDL_ShowWindow(window); + } else { + SDL_DestroyWindow(win); + win = NULL; + } } - int res = 0; + return win != NULL; +} + +static int Y_set_videomode_software (int w, int h, int fullscreen) { + assert(w > 0); + assert(h > 0); int x = SDL_WINDOWPOS_CENTERED; int y = SDL_WINDOWPOS_CENTERED; - if (flags & SYSTEM_USE_OPENGL) { - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_Window *win = SDL_CreateWindow("Doom 2D (SDL2)", x, y, w, h, f | SDL_WINDOW_OPENGL); - if (win != NULL) { - SDL_GLContext ctx = SDL_GL_CreateContext(win); - if (ctx != NULL) { - Y_unset_videomode(); - window = win; - context = ctx; - SDL_GL_MakeCurrent(window, context); - SDL_ShowWindow(window); - res = 1; - } else { - SDL_DestroyWindow(win); - } + Uint32 flags = SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL; + flags |= fullscreen ? SDL_WINDOW_FULLSCREEN : 0; + SDL_Window *win = SDL_CreateWindow(TITLE_STR, x, y, w, h, flags); + if (win != NULL) { + SDL_Surface *s = SDL_CreateRGBSurface(0, w, h, 8, 0, 0, 0, 0); + if (s != NULL) { + Y_unset_videomode(); + window = win; + surf = s; + SDL_ShowWindow(window); + } else { + SDL_DestroyWindow(win); + win = NULL; } + } + return win != NULL; +} + +int Y_set_videomode (int w, int h, int flags) { + assert(w > 0); + assert(h > 0); + int fullscreen = (flags & SYSTEM_USE_FULLSCREEN) != 0; + if (flags & SYSTEM_USE_OPENGL) { + return Y_set_videomode_opengl(w, h, fullscreen); } else { - // TODO software + return Y_set_videomode_software(w, h, fullscreen); } - return res; } int Y_videomode_setted (void) { @@ -115,6 +146,10 @@ void Y_unset_videomode (void) { SDL_GL_DeleteContext(context); context = NULL; } + if (surf != NULL) { + SDL_FreeSurface(surf); + surf = NULL; + } SDL_DestroyWindow(window); window = NULL; } @@ -132,24 +167,53 @@ int Y_get_fullscreen (void) { } void Y_swap_buffers (void) { + assert(window != NULL); assert(context != NULL); SDL_GL_SwapWindow(window); } void Y_get_buffer (byte **buf, int *w, int *h, int *pitch) { - // TODO + assert(window != NULL); + assert(surf != NULL); + *buf = surf->pixels; + *w = surf->w; + *h = surf->h; + *pitch = surf->pitch; } void Y_set_vga_palette (byte *vgapal) { - // TODO + assert(window != NULL); + assert(surf != NULL); + int i; + byte *p = vgapal; + SDL_Color colors[256]; + for (i = 0; i < 256; i++) { + colors[i] = (SDL_Color) { + .r = p[0] * 255 / 63, + .g = p[1] * 255 / 63, + .b = p[2] * 255 / 63 + }; + p += 3; + } + SDL_SetPaletteColors(surf->format->palette, colors, 0, 256); } void Y_repaint_rect (int x, int y, int w, int h) { - // TODO + assert(window != NULL); + assert(surf != NULL); + SDL_Surface *s = SDL_GetWindowSurface(window); + SDL_Rect r = (SDL_Rect) { + .x = x, + .y = y, + .w = w, + .h = h + }; + SDL_BlitSurface(surf, &r, s, &r); + SDL_UpdateWindowSurfaceRects(window, &r, 1); } void Y_repaint (void) { - // TODO + Y_repaint_rect(0, 0, surf->w, surf->h); } /* --- main --- */ diff --git a/src/system.h b/src/system.h new file mode 100644 index 0000000..37d2854 --- /dev/null +++ b/src/system.h @@ -0,0 +1,25 @@ +#ifndef SYSTEM_H_INCLUDED +#define SYSTEM_H_INCLUDED + +#include "glob.h" + +#define SYSTEM_USE_OPENGL (1 << 0) +#define SYSTEM_USE_FULLSCREEN (1 << 1) + +/* common video subsystem routines */ +int Y_set_videomode (int w, int h, int flags); +int Y_videomode_setted (void); +void Y_unset_videomode (void); +int Y_set_fullscreen (int yes); +int Y_get_fullscreen (void); + +/* hardware specific rendering */ +void Y_swap_buffers (void); + +/* software specific rendering */ +void Y_get_buffer (byte **buf, int *w, int *h, int *pitch); +void Y_set_vga_palette (byte *vgapal); +void Y_repaint_rect (int x, int y, int w, int h); +void Y_repaint (void); + +#endif /* SYSTEM_H_INCLUDED */ \ No newline at end of file -- 2.29.2