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