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 void *fb_begin_frame(void)
|
nuclear@2
|
65 {
|
nuclear@2
|
66 if(!surf) return 0;
|
nuclear@2
|
67
|
nuclear@2
|
68 if(scalebuf) {
|
nuclear@2
|
69 return scalebuf;
|
nuclear@2
|
70 }
|
nuclear@2
|
71
|
nuclear@2
|
72 if(SDL_MUSTLOCK(surf)) {
|
nuclear@2
|
73 SDL_LockSurface(surf);
|
nuclear@2
|
74 }
|
nuclear@2
|
75 return surf->pixels;
|
nuclear@2
|
76 }
|
nuclear@2
|
77
|
nuclear@2
|
78 void fb_end_frame(void)
|
nuclear@2
|
79 {
|
nuclear@2
|
80 if(scalebuf) {
|
nuclear@2
|
81 int i, j, k;
|
nuclear@2
|
82 unsigned char *dest;
|
nuclear@2
|
83
|
nuclear@2
|
84 if(SDL_MUSTLOCK(surf)) {
|
nuclear@2
|
85 SDL_LockSurface(surf);
|
nuclear@2
|
86 }
|
nuclear@2
|
87 dest = surf->pixels;
|
nuclear@2
|
88
|
nuclear@2
|
89 for(i=0; i<surf->h; i++) {
|
nuclear@2
|
90 int y = i / scale;
|
nuclear@2
|
91 unsigned char *scan = scalebuf + y * fb_width * pixbytes;
|
nuclear@2
|
92
|
nuclear@2
|
93 for(j=0; j<surf->w; j++) {
|
nuclear@2
|
94 int x = j / scale;
|
nuclear@2
|
95
|
nuclear@2
|
96 for(k=0; k<pixbytes; k++) {
|
nuclear@2
|
97 *dest++ = scan[x * pixbytes + k];
|
nuclear@2
|
98 }
|
nuclear@2
|
99 }
|
nuclear@2
|
100 }
|
nuclear@2
|
101 }
|
nuclear@2
|
102
|
nuclear@2
|
103 if(SDL_MUSTLOCK(surf)) {
|
nuclear@2
|
104 SDL_UnlockSurface(surf);
|
nuclear@2
|
105 }
|
nuclear@2
|
106
|
nuclear@2
|
107 SDL_Flip(surf);
|
nuclear@2
|
108 }
|
nuclear@2
|
109
|
nuclear@2
|
110 void fb_set_palette_range(int start, int count, int *colors)
|
nuclear@2
|
111 {
|
nuclear@2
|
112 int i, *col = colors;
|
nuclear@2
|
113 SDL_Colour sdlcol[256];
|
nuclear@2
|
114
|
nuclear@2
|
115 for(i=0; i<count; i++) {
|
nuclear@2
|
116 sdlcol[i].r = *col++;
|
nuclear@2
|
117 sdlcol[i].g = *col++;
|
nuclear@2
|
118 sdlcol[i].b = *col++;
|
nuclear@2
|
119 }
|
nuclear@2
|
120
|
nuclear@2
|
121 SDL_SetPalette(surf, SDL_LOGPAL | SDL_PHYSPAL, sdlcol, start, count);
|
nuclear@2
|
122 }
|
nuclear@2
|
123
|
nuclear@2
|
124 int fb_process_events(void)
|
nuclear@2
|
125 {
|
nuclear@2
|
126 SDL_Event ev;
|
nuclear@2
|
127
|
nuclear@2
|
128 while(SDL_PollEvent(&ev)) {
|
nuclear@2
|
129 switch(ev.type) {
|
nuclear@2
|
130 case SDL_QUIT:
|
nuclear@2
|
131 return -1;
|
nuclear@2
|
132
|
nuclear@2
|
133 case SDL_KEYDOWN:
|
nuclear@2
|
134 case SDL_KEYUP:
|
nuclear@2
|
135 {
|
nuclear@2
|
136 int key = ev.key.keysym.sym;
|
nuclear@2
|
137 int state = ev.key.state == SDL_PRESSED;
|
nuclear@2
|
138
|
nuclear@2
|
139 if(key < 256) {
|
nuclear@2
|
140 fb_inp.key[key] = state;
|
nuclear@2
|
141 }
|
nuclear@2
|
142 if(fb_cb.keyb) {
|
nuclear@4
|
143 if(fb_cb.keyb(key, state, fb_cb.keyb_data) == -1) {
|
nuclear@4
|
144 return -1;
|
nuclear@4
|
145 }
|
nuclear@2
|
146 } else {
|
nuclear@2
|
147 if(key == SDLK_ESCAPE) {
|
nuclear@2
|
148 return -1;
|
nuclear@2
|
149 }
|
nuclear@2
|
150 }
|
nuclear@2
|
151 }
|
nuclear@2
|
152 break;
|
nuclear@2
|
153
|
nuclear@2
|
154 case SDL_MOUSEBUTTONDOWN:
|
nuclear@2
|
155 case SDL_MOUSEBUTTONUP:
|
nuclear@2
|
156 {
|
nuclear@2
|
157 int state = ev.button.state == SDL_PRESSED;
|
nuclear@2
|
158 fb_inp.mx = ev.motion.x / scale;
|
nuclear@2
|
159 fb_inp.my = ev.motion.y / scale;
|
nuclear@2
|
160 fb_inp.mbutton[ev.button.which] = state;
|
nuclear@2
|
161
|
nuclear@2
|
162 if(fb_cb.button) {
|
nuclear@4
|
163 if(fb_cb.button(ev.button.which, state, fb_inp.mx, fb_inp.my, fb_cb.button_data) == -1) {
|
nuclear@4
|
164 return -1;
|
nuclear@4
|
165 }
|
nuclear@2
|
166 }
|
nuclear@2
|
167 }
|
nuclear@2
|
168 break;
|
nuclear@2
|
169
|
nuclear@2
|
170 case SDL_MOUSEMOTION:
|
nuclear@2
|
171 fb_inp.mx = ev.motion.x / scale;
|
nuclear@2
|
172 fb_inp.my = ev.motion.y / scale;
|
nuclear@2
|
173 if(fb_cb.motion) {
|
nuclear@4
|
174 if(fb_cb.motion(fb_inp.mx, fb_inp.my, fb_cb.motion_data) == -1) {
|
nuclear@4
|
175 return -1;
|
nuclear@4
|
176 }
|
nuclear@2
|
177 }
|
nuclear@2
|
178 break;
|
nuclear@2
|
179 }
|
nuclear@2
|
180 }
|
nuclear@2
|
181
|
nuclear@2
|
182 return 0;
|
nuclear@2
|
183 }
|
nuclear@2
|
184
|
nuclear@2
|
185 unsigned long fb_get_time(void)
|
nuclear@2
|
186 {
|
nuclear@2
|
187 return SDL_GetTicks();
|
nuclear@2
|
188 }
|
nuclear@2
|
189
|
nuclear@2
|
190 #endif /* FBLIB_SDL */
|