eobish

view src/fblibsdl.c @ 2:cdbcae5b3b98

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