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@2
|
158 fb_cb.keyb(key, state, fb_cb.keyb_data);
|
nuclear@2
|
159 } else {
|
nuclear@2
|
160 if(key == SDLK_ESCAPE) {
|
nuclear@2
|
161 return -1;
|
nuclear@2
|
162 }
|
nuclear@2
|
163 }
|
nuclear@2
|
164 }
|
nuclear@2
|
165 break;
|
nuclear@2
|
166
|
nuclear@2
|
167 case SDL_MOUSEBUTTONDOWN:
|
nuclear@2
|
168 case SDL_MOUSEBUTTONUP:
|
nuclear@2
|
169 {
|
nuclear@2
|
170 int state = ev.button.state == SDL_PRESSED;
|
nuclear@2
|
171 fb_inp.mx = ev.motion.x / scale;
|
nuclear@2
|
172 fb_inp.my = ev.motion.y / scale;
|
nuclear@2
|
173 fb_inp.mbutton[ev.button.which] = state;
|
nuclear@2
|
174
|
nuclear@2
|
175 if(fb_cb.button) {
|
nuclear@2
|
176 fb_cb.button(ev.button.which, state, fb_inp.mx, fb_inp.my, fb_cb.button_data);
|
nuclear@2
|
177 }
|
nuclear@2
|
178 }
|
nuclear@2
|
179 break;
|
nuclear@2
|
180
|
nuclear@2
|
181 case SDL_MOUSEMOTION:
|
nuclear@2
|
182 fb_inp.mx = ev.motion.x / scale;
|
nuclear@2
|
183 fb_inp.my = ev.motion.y / scale;
|
nuclear@2
|
184 if(fb_cb.motion) {
|
nuclear@2
|
185 fb_cb.motion(fb_inp.mx, fb_inp.my, fb_cb.motion_data);
|
nuclear@2
|
186 }
|
nuclear@2
|
187 break;
|
nuclear@2
|
188 }
|
nuclear@2
|
189 }
|
nuclear@2
|
190
|
nuclear@2
|
191 return 0;
|
nuclear@2
|
192 }
|
nuclear@2
|
193
|
nuclear@2
|
194 unsigned long fb_get_time(void)
|
nuclear@2
|
195 {
|
nuclear@2
|
196 return SDL_GetTicks();
|
nuclear@2
|
197 }
|
nuclear@2
|
198
|
nuclear@2
|
199 #endif /* FBLIB_SDL */
|