Mercurial > hg > forks > pwpunix
view pwplib/sdl.c @ 15:fa87f8897f21
Implement hacky and crummy SDL event handling in timer value fetching function; moved SDL general initialization into pwplib-unix.c.
Quitting via ESC now works, as does signal handling (shouldn't segfault when sent SIGINT etc.) to some degree.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sat, 22 May 2010 18:12:37 +0300 |
parents | e5049100f6ac |
children | c60e531d19cd |
line wrap: on
line source
/* * pwplib SDL (Simple Directmedia Layer) video "driver" * (C) Copyright 2010 ccr/TNSP^PWP <ccr@tnsp.org> * * Rasterization based on the prototype X11 driver by viznut/PWP * * This file and other changes are distributed under same * license as pwplib itself. */ #include "config.h" #ifdef DRIVE_SDL #include "pwplib.h" #include <SDL.h> #define PWP_WINNAME "pwplib" #define PWP_NCOLORS 256 struct { int width, height, vflags; SDL_Surface *screen; SDL_Color cols[PWP_NCOLORS]; Uint32 lookup[256]; } pwp_SDL; static void pwp_SDL_dump_rast_4x4() { Uint8 *dst = pwp_SDL.screen->pixels; Uint8 *src = pwplib.videobuf.d; int y; if (SDL_MUSTLOCK(pwp_SDL.screen) != 0) { if (SDL_LockSurface(pwp_SDL.screen) != 0) { SDL_Quit(); pwpwrite("SDL: Could not lock video surface!\n"); exit(1); } } for (y = pwplib.videobuf.height; y; y--) { int i; Uint8 *dsrc = dst; Uint32 *d = (Uint32 *)dst; Uint8 *s = src; for (i = pwplib.videobuf.width; i; i--) *d++ = pwp_SDL.lookup[*s++]; dst += pwp_SDL.screen->pitch; /* Optimization: memcpy the rasterized line 3 times below it */ for (i = 3; i; i--) { memcpy(dst, dsrc, pwp_SDL.screen->pitch); dst += pwp_SDL.screen->pitch; } src += pwplib.videobuf.width; } if (SDL_MUSTLOCK(pwp_SDL.screen) != 0) SDL_UnlockSurface(pwp_SDL.screen); SDL_Flip(pwp_SDL.screen); } static void rast2rgb(int n, int muller, int *r, int *g, int *b) { int fg = n & 15, bg = (n >> 4) & 15; static const char rgb[16 * 3] = { 0, 0, 0, 0, 0, 9, 0, 9, 0, 0, 9, 9, 9, 0, 0, 9, 0, 9, 9, 9, 0, 9, 9, 9, 6, 6, 6, 0, 0, 15, 0, 15, 0, 0, 15, 15, 15, 0, 0, 15, 0, 15, 15, 15, 0, 15, 15, 15 }; *r = (muller * (rgb[bg * 3 + 0] * 2 + rgb[fg * 3 + 0])) / 45; *g = (muller * (rgb[bg * 3 + 1] * 2 + rgb[fg * 3 + 1])) / 45; *b = (muller * (rgb[bg * 3 + 2] * 2 + rgb[fg * 3 + 2])) / 45; } int pwp_SDL_init(void) { int pal[PWP_NCOLORS * 3], i; /* Assume these settings for now */ pwp_SDL.vflags = 0; pwp_SDL.width = 640; pwp_SDL.height = 480; /* Set pwplib internal parameters */ pwplib.videobuf.width = pwp_SDL.width / 4; pwplib.videobuf.height = pwp_SDL.height / 8; pwplib.dump_rast = pwp_SDL_dump_rast_4x4; /* Initialize a indexed / paletted video surface */ pwp_SDL.screen = SDL_SetVideoMode(pwp_SDL.width, pwp_SDL.height, 8, pwp_SDL.vflags); if (pwp_SDL.screen == NULL) { pwpwrite("* SDL could not initialize video surface/mode.\n"); return 0; } fprintf(stderr, "\nSDL_surface: %d x %d, pitch=%d\n", pwp_SDL.screen->w, pwp_SDL.screen->h, pwp_SDL.screen->pitch); /* Set window caption, if any */ SDL_WM_SetCaption(PWP_WINNAME, PWP_WINNAME); /* Generate palette and rasterization lookup table */ for (i = 0; i < PWP_NCOLORS; i++) { int r, g, b; rast2rgb(i, 255, &r, &g, &b); pwp_SDL.cols[i].r = r; pwp_SDL.cols[i].g = g; pwp_SDL.cols[i].b = b; pwp_SDL.lookup[i] = i | (i << 8) | (i << 16) | (i << 24); } SDL_SetColors(pwp_SDL.screen, pwp_SDL.cols, 0, PWP_NCOLORS); pwpwrite("* SDL video\n"); return 1; } #endif