rev |
line source |
nuclear@0
|
1 /* This file implements all calls made to dos-specific code using SDL
|
nuclear@0
|
2 * Don't ask why ...
|
nuclear@0
|
3 */
|
nuclear@0
|
4
|
nuclear@0
|
5 #include <stdlib.h>
|
nuclear@0
|
6 #include <assert.h>
|
nuclear@0
|
7 #include <SDL.h>
|
nuclear@24
|
8 #include "wvga.h"
|
nuclear@0
|
9 #include "conio.h"
|
nuclear@0
|
10 #include "mouse.h"
|
nuclear@34
|
11 #include "keyb.h"
|
nuclear@0
|
12 #include "timer.h"
|
nuclear@0
|
13
|
nuclear@0
|
14 static void proc_events(void);
|
nuclear@0
|
15
|
nuclear@34
|
16 static void init_sdl()
|
nuclear@34
|
17 {
|
nuclear@35
|
18 const SDL_version *ver;
|
nuclear@35
|
19
|
nuclear@34
|
20 if(!SDL_WasInit(SDL_INIT_EVERYTHING)) {
|
nuclear@34
|
21 SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
|
nuclear@35
|
22
|
nuclear@35
|
23 if((ver = SDL_Linked_Version())) {
|
nuclear@35
|
24 printf("SDL %d.%d.%d initialized\n", ver->major, ver->minor, ver->patch);
|
nuclear@35
|
25 }
|
nuclear@34
|
26 }
|
nuclear@34
|
27 }
|
nuclear@34
|
28
|
nuclear@24
|
29 /* ----- graphics (wvga.c implementation) ----- */
|
nuclear@0
|
30 static SDL_Surface *fbsurf;
|
nuclear@35
|
31 static int scale = 3;
|
nuclear@0
|
32
|
nuclear@24
|
33 int set_video_mode(int mode)
|
nuclear@0
|
34 {
|
nuclear@0
|
35 int resx = 320, resy = 200;
|
nuclear@9
|
36 unsigned int sdl_flags = SDL_HWPALETTE;
|
nuclear@28
|
37 char *env;
|
nuclear@0
|
38
|
nuclear@0
|
39 if(getenv("DOSEMU_DOUBLESIZE")) {
|
nuclear@28
|
40 scale = 2;
|
nuclear@0
|
41 }
|
nuclear@0
|
42
|
nuclear@28
|
43 if((env = getenv("DOSEMU_SCALE"))) {
|
nuclear@28
|
44 int n = atoi(env);
|
nuclear@28
|
45 if(n > 0) {
|
nuclear@28
|
46 scale = n;
|
nuclear@28
|
47 }
|
nuclear@28
|
48 }
|
nuclear@28
|
49 resx *= scale;
|
nuclear@28
|
50 resy *= scale;
|
nuclear@28
|
51
|
nuclear@9
|
52 if(getenv("DOSEMU_FULLSCREEN")) {
|
nuclear@9
|
53 sdl_flags |= SDL_FULLSCREEN;
|
nuclear@9
|
54 }
|
nuclear@9
|
55
|
nuclear@34
|
56 init_sdl();
|
nuclear@34
|
57
|
nuclear@0
|
58 switch(mode) {
|
nuclear@0
|
59 case 0x13:
|
nuclear@9
|
60 if(!(fbsurf = SDL_SetVideoMode(resx, resy, 8, sdl_flags))) {
|
nuclear@0
|
61 fprintf(stderr, "failed to set video mode\n");
|
nuclear@0
|
62 abort();
|
nuclear@0
|
63 }
|
nuclear@25
|
64 SDL_WM_SetCaption("Deepstone", 0);
|
nuclear@28
|
65 /*SDL_ShowCursor(0);*/
|
nuclear@34
|
66 /*SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);*/
|
nuclear@0
|
67 break;
|
nuclear@0
|
68
|
nuclear@0
|
69 case 3:
|
nuclear@0
|
70 SDL_ShowCursor(1);
|
nuclear@11
|
71 SDL_EnableKeyRepeat(0, 0);
|
nuclear@0
|
72 SDL_Quit();
|
nuclear@0
|
73 break;
|
nuclear@0
|
74
|
nuclear@0
|
75 default:
|
nuclear@0
|
76 break;
|
nuclear@0
|
77 }
|
nuclear@24
|
78
|
nuclear@24
|
79 return 0;
|
nuclear@0
|
80 }
|
nuclear@0
|
81
|
nuclear@24
|
82 void set_palette(int idx, int *col, int count)
|
nuclear@24
|
83 {
|
nuclear@24
|
84 int i;
|
nuclear@24
|
85
|
nuclear@24
|
86 for(i=0; i<count; i++) {
|
nuclear@24
|
87 set_pal_entry(idx + i, col[0], col[1], col[2]);
|
nuclear@24
|
88 col += 3;
|
nuclear@24
|
89 }
|
nuclear@24
|
90 }
|
nuclear@24
|
91
|
nuclear@24
|
92 void set_pal_entry(int idx, int r, int g, int b)
|
nuclear@0
|
93 {
|
nuclear@0
|
94 SDL_Color col;
|
nuclear@0
|
95 col.r = r;
|
nuclear@0
|
96 col.g = g;
|
nuclear@0
|
97 col.b = b;
|
nuclear@0
|
98
|
nuclear@24
|
99 if(SDL_SetPalette(fbsurf, SDL_LOGPAL | SDL_PHYSPAL, &col, idx, 1) != 1) {
|
nuclear@0
|
100 fprintf(stderr, "set_palette failed to set the required color\n");
|
nuclear@0
|
101 }
|
nuclear@0
|
102 }
|
nuclear@0
|
103
|
nuclear@24
|
104 void copy_frame(void *pixels)
|
nuclear@0
|
105 {
|
nuclear@24
|
106 unsigned char *frame = (unsigned char*)pixels;
|
nuclear@24
|
107
|
nuclear@0
|
108 if(SDL_MUSTLOCK(fbsurf)) {
|
nuclear@0
|
109 SDL_LockSurface(fbsurf);
|
nuclear@0
|
110 }
|
nuclear@0
|
111
|
nuclear@28
|
112 if(scale > 1) {
|
nuclear@28
|
113 int i, j, xsz, ysz;
|
nuclear@28
|
114 unsigned char *dest = fbsurf->pixels;
|
nuclear@0
|
115
|
nuclear@28
|
116 xsz = 320 * scale;
|
nuclear@28
|
117 ysz = 200 * scale;
|
nuclear@28
|
118
|
nuclear@28
|
119 for(i=0; i<ysz; i++) {
|
nuclear@28
|
120 for(j=0; j<xsz; j++) {
|
nuclear@28
|
121 *dest++ = frame[(i / scale) * 320 + (j / scale)];
|
nuclear@0
|
122 }
|
nuclear@0
|
123 }
|
nuclear@0
|
124 } else {
|
nuclear@0
|
125 memcpy(fbsurf->pixels, frame, 64000);
|
nuclear@0
|
126 }
|
nuclear@0
|
127
|
nuclear@0
|
128 if(SDL_MUSTLOCK(fbsurf)) {
|
nuclear@0
|
129 SDL_UnlockSurface(fbsurf);
|
nuclear@0
|
130 }
|
nuclear@0
|
131 SDL_Flip(fbsurf);
|
nuclear@34
|
132
|
nuclear@34
|
133
|
nuclear@34
|
134 /* also print fps every second ... */
|
nuclear@34
|
135 {
|
nuclear@34
|
136 static long prev_fps, num_frames;
|
nuclear@34
|
137 long msec, dt;
|
nuclear@34
|
138
|
nuclear@34
|
139 msec = get_msec();
|
nuclear@34
|
140 dt = msec - prev_fps;
|
nuclear@34
|
141 if(dt >= 1000) {
|
nuclear@34
|
142 float fps = (float)num_frames / ((float)dt / 1000.0f);
|
nuclear@34
|
143 printf("framerate: %.1f \r", fps);
|
nuclear@34
|
144 fflush(stdout);
|
nuclear@34
|
145 num_frames = 0;
|
nuclear@34
|
146 prev_fps = msec;
|
nuclear@34
|
147 } else {
|
nuclear@34
|
148 num_frames++;
|
nuclear@34
|
149 }
|
nuclear@34
|
150 }
|
nuclear@0
|
151 }
|
nuclear@0
|
152
|
nuclear@0
|
153 void wait_vsync(void)
|
nuclear@0
|
154 {
|
nuclear@0
|
155 }
|
nuclear@0
|
156
|
nuclear@0
|
157 /* ----- event handling (conio.h) ----- */
|
nuclear@0
|
158 static SDL_Event *keybev;
|
nuclear@0
|
159 static int mousex, mousey, bnmask;
|
nuclear@0
|
160
|
nuclear@34
|
161 static int keystate[256];
|
nuclear@34
|
162 static int num_pressed;
|
nuclear@34
|
163
|
nuclear@0
|
164 int kbhit(void)
|
nuclear@0
|
165 {
|
nuclear@0
|
166 if(!keybev) {
|
nuclear@0
|
167 proc_events();
|
nuclear@0
|
168 }
|
nuclear@0
|
169 return keybev != 0;
|
nuclear@0
|
170 }
|
nuclear@0
|
171
|
nuclear@9
|
172 int getch(void)
|
nuclear@0
|
173 {
|
nuclear@9
|
174 int res;
|
nuclear@0
|
175
|
nuclear@0
|
176 while(!keybev) {
|
nuclear@0
|
177 SDL_Event ev;
|
nuclear@0
|
178 SDL_WaitEvent(&ev);
|
nuclear@0
|
179 SDL_PushEvent(&ev);
|
nuclear@0
|
180 proc_events();
|
nuclear@0
|
181 }
|
nuclear@0
|
182 res = keybev->key.keysym.sym;
|
nuclear@0
|
183 keybev = 0;
|
nuclear@0
|
184 return res;
|
nuclear@0
|
185 }
|
nuclear@0
|
186
|
nuclear@34
|
187 /* ----- improved event handling (keyb.h) ---- */
|
nuclear@34
|
188
|
nuclear@34
|
189 int kb_init(int bufsz)
|
nuclear@34
|
190 {
|
nuclear@34
|
191 init_sdl();
|
nuclear@34
|
192
|
nuclear@34
|
193 return 0;
|
nuclear@34
|
194 }
|
nuclear@34
|
195
|
nuclear@34
|
196 void kb_shutdown(void)
|
nuclear@34
|
197 {
|
nuclear@34
|
198 }
|
nuclear@34
|
199
|
nuclear@34
|
200 int kb_getkey(void)
|
nuclear@34
|
201 {
|
nuclear@34
|
202 int res = -1;
|
nuclear@34
|
203
|
nuclear@34
|
204 proc_events();
|
nuclear@34
|
205 if(keybev) {
|
nuclear@34
|
206 res = keybev->key.keysym.sym;
|
nuclear@34
|
207 keybev = 0;
|
nuclear@34
|
208 }
|
nuclear@34
|
209 return res;
|
nuclear@34
|
210 }
|
nuclear@34
|
211
|
nuclear@34
|
212 int kb_isdown(int key)
|
nuclear@34
|
213 {
|
nuclear@34
|
214 if(key == KB_ANY) {
|
nuclear@34
|
215 return num_pressed;
|
nuclear@34
|
216 }
|
nuclear@34
|
217 return keystate[key];
|
nuclear@34
|
218 }
|
nuclear@34
|
219
|
nuclear@0
|
220 /* mouse handling (mouse.c implementation) */
|
nuclear@34
|
221 static unsigned long last_mouse_hide_time;
|
nuclear@34
|
222
|
nuclear@0
|
223 int have_mouse(void)
|
nuclear@0
|
224 {
|
nuclear@0
|
225 return 1;
|
nuclear@0
|
226 }
|
nuclear@0
|
227
|
nuclear@34
|
228 void set_mouse(int x, int y)
|
nuclear@34
|
229 {
|
nuclear@36
|
230 SDL_ShowCursor(0);
|
nuclear@36
|
231 last_mouse_hide_time = get_msec();
|
nuclear@34
|
232
|
nuclear@34
|
233 SDL_WarpMouse(x * scale, y * scale);
|
nuclear@34
|
234 mousex = x;
|
nuclear@34
|
235 mousey = y;
|
nuclear@34
|
236 }
|
nuclear@34
|
237
|
nuclear@0
|
238 int read_mouse(int *xp, int *yp)
|
nuclear@0
|
239 {
|
nuclear@0
|
240 if(xp) *xp = mousex;
|
nuclear@0
|
241 if(yp) *yp = mousey;
|
nuclear@0
|
242 return bnmask;
|
nuclear@0
|
243 }
|
nuclear@0
|
244
|
nuclear@0
|
245 static void proc_events(void)
|
nuclear@0
|
246 {
|
nuclear@0
|
247 static SDL_Event ev;
|
nuclear@0
|
248
|
nuclear@34
|
249 if(last_mouse_hide_time > 0 && get_msec() - last_mouse_hide_time > 3000) {
|
nuclear@34
|
250 last_mouse_hide_time = 0;
|
nuclear@34
|
251 SDL_ShowCursor(1);
|
nuclear@34
|
252 }
|
nuclear@34
|
253
|
nuclear@0
|
254 while(SDL_PollEvent(&ev)) {
|
nuclear@0
|
255 switch(ev.type) {
|
nuclear@0
|
256 case SDL_KEYDOWN:
|
nuclear@34
|
257 {
|
nuclear@34
|
258 int key = ev.key.keysym.sym;
|
nuclear@34
|
259
|
nuclear@34
|
260 if(!keybev) {
|
nuclear@34
|
261 keybev = &ev;
|
nuclear@34
|
262 }
|
nuclear@34
|
263
|
nuclear@34
|
264 if(!keystate[key]) {
|
nuclear@34
|
265 keystate[key] = 1;
|
nuclear@34
|
266 num_pressed++;
|
nuclear@34
|
267 }
|
nuclear@34
|
268 }
|
nuclear@34
|
269 break;
|
nuclear@34
|
270
|
nuclear@34
|
271 case SDL_KEYUP:
|
nuclear@34
|
272 {
|
nuclear@34
|
273 int key = ev.key.keysym.sym;
|
nuclear@34
|
274
|
nuclear@34
|
275 if(keystate[key]) {
|
nuclear@34
|
276 keystate[key] = 0;
|
nuclear@34
|
277 if(--num_pressed < 0) {
|
nuclear@34
|
278 num_pressed = 0;
|
nuclear@34
|
279 }
|
nuclear@34
|
280 }
|
nuclear@34
|
281 }
|
nuclear@34
|
282 break;
|
nuclear@0
|
283
|
nuclear@0
|
284 case SDL_MOUSEMOTION:
|
nuclear@28
|
285 mousex = ev.motion.x / scale;
|
nuclear@28
|
286 mousey = ev.motion.y / scale;
|
nuclear@0
|
287 break;
|
nuclear@0
|
288
|
nuclear@0
|
289 case SDL_MOUSEBUTTONDOWN:
|
nuclear@0
|
290 case SDL_MOUSEBUTTONUP:
|
nuclear@0
|
291 {
|
nuclear@0
|
292 int mask = 0;
|
nuclear@0
|
293 switch(ev.button.button) {
|
nuclear@0
|
294 case SDL_BUTTON_LEFT:
|
nuclear@0
|
295 mask = MOUSE_LEFT;
|
nuclear@0
|
296 break;
|
nuclear@0
|
297 case SDL_BUTTON_MIDDLE:
|
nuclear@0
|
298 mask = MOUSE_MIDDLE;
|
nuclear@0
|
299 break;
|
nuclear@0
|
300 case SDL_BUTTON_RIGHT:
|
nuclear@0
|
301 mask = MOUSE_RIGHT;
|
nuclear@0
|
302 default:
|
nuclear@0
|
303 break;
|
nuclear@0
|
304 }
|
nuclear@0
|
305 if(!mask) {
|
nuclear@0
|
306 break;
|
nuclear@0
|
307 }
|
nuclear@0
|
308
|
nuclear@0
|
309 if(ev.button.state == SDL_PRESSED) {
|
nuclear@0
|
310 bnmask |= mask;
|
nuclear@0
|
311 } else {
|
nuclear@0
|
312 bnmask &= ~mask;
|
nuclear@0
|
313 }
|
nuclear@0
|
314 }
|
nuclear@0
|
315 break;
|
nuclear@0
|
316
|
nuclear@0
|
317 default:
|
nuclear@0
|
318 break;
|
nuclear@0
|
319 }
|
nuclear@0
|
320 }
|
nuclear@0
|
321 }
|
nuclear@0
|
322
|
nuclear@0
|
323 /* ---- timer.c implementation ---- */
|
nuclear@0
|
324 static Uint32 start_time;
|
nuclear@0
|
325
|
nuclear@0
|
326 void init_timer(int res_hz)
|
nuclear@0
|
327 {
|
nuclear@34
|
328 init_sdl();
|
nuclear@0
|
329 reset_timer();
|
nuclear@0
|
330 }
|
nuclear@0
|
331
|
nuclear@0
|
332 void reset_timer(void)
|
nuclear@0
|
333 {
|
nuclear@0
|
334 start_time = SDL_GetTicks();
|
nuclear@34
|
335 printf("resetting timer: %u, %lu\n", start_time, get_msec());
|
nuclear@0
|
336 }
|
nuclear@0
|
337
|
nuclear@0
|
338 unsigned long get_msec(void)
|
nuclear@0
|
339 {
|
nuclear@34
|
340 Uint32 ticks = SDL_GetTicks();
|
nuclear@34
|
341 return (unsigned long)(ticks - start_time);
|
nuclear@0
|
342 }
|