eobish

annotate src/fblibsdl.c @ 4:ce0548d24918

mostly works
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 18 Jan 2015 13:30:30 +0200
parents cdbcae5b3b98
children 6a350c554e46
rev   line source
nuclear@2 1 #ifdef FBLIB_SDL
nuclear@2 2 #include <stdio.h>
nuclear@2 3 #include <stdlib.h>
nuclear@2 4 #include <string.h>
nuclear@2 5 #include <SDL/SDL.h>
nuclear@2 6 #include "fblib.h"
nuclear@2 7 #include "fblibimp.h"
nuclear@2 8
nuclear@2 9 static int scale;
nuclear@2 10 static SDL_Surface *surf;
nuclear@2 11 static unsigned char *scalebuf; /* only if scale != 1 */
nuclear@2 12 static int pixbytes; /* pixel size in bytes */
nuclear@2 13
nuclear@2 14 int fb_init(int width, int height, int bpp)
nuclear@2 15 {
nuclear@2 16 static int sdlinit_done;
nuclear@2 17 char *env, title[64];
nuclear@2 18
nuclear@2 19 if((env = getenv("FBLIB_SCALE"))) {
nuclear@2 20 scale = atoi(env);
nuclear@2 21 }
nuclear@2 22 if(!scale) scale = 1;
nuclear@2 23
nuclear@2 24 fb_width = width;
nuclear@2 25 fb_height = height;
nuclear@2 26 fb_bpp = bpp;
nuclear@2 27
nuclear@2 28 pixbytes = (bpp + 7) / 8;
nuclear@2 29
nuclear@2 30 if(!sdlinit_done) {
nuclear@2 31 if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) == -1) {
nuclear@2 32 fprintf(stderr, "failed to initialize SDL!\n");
nuclear@2 33 return -1;
nuclear@2 34 }
nuclear@2 35 sdlinit_done = 1;
nuclear@2 36 }
nuclear@2 37
nuclear@2 38 if(!(surf = SDL_SetVideoMode(width * scale, height * scale, bpp, SDL_SWSURFACE))) {
nuclear@2 39 fprintf(stderr, "failed to set video mode\n");
nuclear@2 40 return -1;
nuclear@2 41 }
nuclear@2 42 sprintf(title, "fblib window (%dx)", scale);
nuclear@2 43 SDL_WM_SetCaption(title, 0);
nuclear@2 44
nuclear@2 45 if(scale != 1) {
nuclear@2 46 if(!(scalebuf = malloc(width * height * pixbytes))) {
nuclear@2 47 fprintf(stderr, "failed to allocate back buffer\n");
nuclear@2 48 SDL_Quit();
nuclear@2 49 return -1;
nuclear@2 50 }
nuclear@2 51 } else {
nuclear@2 52 scalebuf = 0;
nuclear@2 53 }
nuclear@2 54
nuclear@2 55 return 0;
nuclear@2 56 }
nuclear@2 57
nuclear@2 58 void fb_shutdown(void)
nuclear@2 59 {
nuclear@2 60 free(scalebuf);
nuclear@2 61 SDL_Quit();
nuclear@2 62 }
nuclear@2 63
nuclear@2 64 int fb_get_width(void)
nuclear@2 65 {
nuclear@2 66 return fb_width;
nuclear@2 67 }
nuclear@2 68
nuclear@2 69 int fb_get_height(void)
nuclear@2 70 {
nuclear@2 71 return fb_height;
nuclear@2 72 }
nuclear@2 73
nuclear@2 74 int fb_get_bpp(void)
nuclear@2 75 {
nuclear@2 76 return fb_bpp;
nuclear@2 77 }
nuclear@2 78
nuclear@2 79 void *fb_begin_frame(void)
nuclear@2 80 {
nuclear@2 81 if(!surf) return 0;
nuclear@2 82
nuclear@2 83 if(scalebuf) {
nuclear@2 84 return scalebuf;
nuclear@2 85 }
nuclear@2 86
nuclear@2 87 if(SDL_MUSTLOCK(surf)) {
nuclear@2 88 SDL_LockSurface(surf);
nuclear@2 89 }
nuclear@2 90 return surf->pixels;
nuclear@2 91 }
nuclear@2 92
nuclear@2 93 void fb_end_frame(void)
nuclear@2 94 {
nuclear@2 95 if(scalebuf) {
nuclear@2 96 int i, j, k;
nuclear@2 97 unsigned char *dest;
nuclear@2 98
nuclear@2 99 if(SDL_MUSTLOCK(surf)) {
nuclear@2 100 SDL_LockSurface(surf);
nuclear@2 101 }
nuclear@2 102 dest = surf->pixels;
nuclear@2 103
nuclear@2 104 for(i=0; i<surf->h; i++) {
nuclear@2 105 int y = i / scale;
nuclear@2 106 unsigned char *scan = scalebuf + y * fb_width * pixbytes;
nuclear@2 107
nuclear@2 108 for(j=0; j<surf->w; j++) {
nuclear@2 109 int x = j / scale;
nuclear@2 110
nuclear@2 111 for(k=0; k<pixbytes; k++) {
nuclear@2 112 *dest++ = scan[x * pixbytes + k];
nuclear@2 113 }
nuclear@2 114 }
nuclear@2 115 }
nuclear@2 116 }
nuclear@2 117
nuclear@2 118 if(SDL_MUSTLOCK(surf)) {
nuclear@2 119 SDL_UnlockSurface(surf);
nuclear@2 120 }
nuclear@2 121
nuclear@2 122 SDL_Flip(surf);
nuclear@2 123 }
nuclear@2 124
nuclear@2 125 void fb_set_palette_range(int start, int count, int *colors)
nuclear@2 126 {
nuclear@2 127 int i, *col = colors;
nuclear@2 128 SDL_Colour sdlcol[256];
nuclear@2 129
nuclear@2 130 for(i=0; i<count; i++) {
nuclear@2 131 sdlcol[i].r = *col++;
nuclear@2 132 sdlcol[i].g = *col++;
nuclear@2 133 sdlcol[i].b = *col++;
nuclear@2 134 }
nuclear@2 135
nuclear@2 136 SDL_SetPalette(surf, SDL_LOGPAL | SDL_PHYSPAL, sdlcol, start, count);
nuclear@2 137 }
nuclear@2 138
nuclear@2 139 int fb_process_events(void)
nuclear@2 140 {
nuclear@2 141 SDL_Event ev;
nuclear@2 142
nuclear@2 143 while(SDL_PollEvent(&ev)) {
nuclear@2 144 switch(ev.type) {
nuclear@2 145 case SDL_QUIT:
nuclear@2 146 return -1;
nuclear@2 147
nuclear@2 148 case SDL_KEYDOWN:
nuclear@2 149 case SDL_KEYUP:
nuclear@2 150 {
nuclear@2 151 int key = ev.key.keysym.sym;
nuclear@2 152 int state = ev.key.state == SDL_PRESSED;
nuclear@2 153
nuclear@2 154 if(key < 256) {
nuclear@2 155 fb_inp.key[key] = state;
nuclear@2 156 }
nuclear@2 157 if(fb_cb.keyb) {
nuclear@4 158 if(fb_cb.keyb(key, state, fb_cb.keyb_data) == -1) {
nuclear@4 159 return -1;
nuclear@4 160 }
nuclear@2 161 } else {
nuclear@2 162 if(key == SDLK_ESCAPE) {
nuclear@2 163 return -1;
nuclear@2 164 }
nuclear@2 165 }
nuclear@2 166 }
nuclear@2 167 break;
nuclear@2 168
nuclear@2 169 case SDL_MOUSEBUTTONDOWN:
nuclear@2 170 case SDL_MOUSEBUTTONUP:
nuclear@2 171 {
nuclear@2 172 int state = ev.button.state == SDL_PRESSED;
nuclear@2 173 fb_inp.mx = ev.motion.x / scale;
nuclear@2 174 fb_inp.my = ev.motion.y / scale;
nuclear@2 175 fb_inp.mbutton[ev.button.which] = state;
nuclear@2 176
nuclear@2 177 if(fb_cb.button) {
nuclear@4 178 if(fb_cb.button(ev.button.which, state, fb_inp.mx, fb_inp.my, fb_cb.button_data) == -1) {
nuclear@4 179 return -1;
nuclear@4 180 }
nuclear@2 181 }
nuclear@2 182 }
nuclear@2 183 break;
nuclear@2 184
nuclear@2 185 case SDL_MOUSEMOTION:
nuclear@2 186 fb_inp.mx = ev.motion.x / scale;
nuclear@2 187 fb_inp.my = ev.motion.y / scale;
nuclear@2 188 if(fb_cb.motion) {
nuclear@4 189 if(fb_cb.motion(fb_inp.mx, fb_inp.my, fb_cb.motion_data) == -1) {
nuclear@4 190 return -1;
nuclear@4 191 }
nuclear@2 192 }
nuclear@2 193 break;
nuclear@2 194 }
nuclear@2 195 }
nuclear@2 196
nuclear@2 197 return 0;
nuclear@2 198 }
nuclear@2 199
nuclear@2 200 unsigned long fb_get_time(void)
nuclear@2 201 {
nuclear@2 202 return SDL_GetTicks();
nuclear@2 203 }
nuclear@2 204
nuclear@2 205 #endif /* FBLIB_SDL */