deepstone

view src/dosemu/dosemu.c @ 36:e234f2a4b6fa

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