deepstone

annotate 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
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 }