deepstone

view dosemu/dosemu.c @ 28:11d14f688485

added clipping
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 22 Sep 2013 06:38:08 +0300
parents 5ff8ce78059a
children c6406e4aa0fb
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 "timer.h"
13 static void proc_events(void);
15 /* ----- graphics (wvga.c implementation) ----- */
16 static SDL_Surface *fbsurf;
17 static int scale = 1;
19 int set_video_mode(int mode)
20 {
21 int resx = 320, resy = 200;
22 unsigned int sdl_flags = SDL_HWPALETTE;
23 char *env;
25 if(getenv("DOSEMU_DOUBLESIZE")) {
26 scale = 2;
27 }
29 if((env = getenv("DOSEMU_SCALE"))) {
30 int n = atoi(env);
31 if(n > 0) {
32 scale = n;
33 }
34 }
35 resx *= scale;
36 resy *= scale;
38 if(getenv("DOSEMU_FULLSCREEN")) {
39 sdl_flags |= SDL_FULLSCREEN;
40 }
42 switch(mode) {
43 case 0x13:
44 SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
45 if(!(fbsurf = SDL_SetVideoMode(resx, resy, 8, sdl_flags))) {
46 fprintf(stderr, "failed to set video mode\n");
47 abort();
48 }
49 SDL_WM_SetCaption("Deepstone", 0);
50 /*SDL_ShowCursor(0);*/
51 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
52 break;
54 case 3:
55 SDL_ShowCursor(1);
56 SDL_EnableKeyRepeat(0, 0);
57 SDL_Quit();
58 break;
60 default:
61 break;
62 }
64 return 0;
65 }
67 void set_palette(int idx, int *col, int count)
68 {
69 int i;
71 for(i=0; i<count; i++) {
72 set_pal_entry(idx + i, col[0], col[1], col[2]);
73 col += 3;
74 }
75 }
77 void set_pal_entry(int idx, int r, int g, int b)
78 {
79 SDL_Color col;
80 col.r = r;
81 col.g = g;
82 col.b = b;
84 if(SDL_SetPalette(fbsurf, SDL_LOGPAL | SDL_PHYSPAL, &col, idx, 1) != 1) {
85 fprintf(stderr, "set_palette failed to set the required color\n");
86 }
87 }
89 void copy_frame(void *pixels)
90 {
91 unsigned char *frame = (unsigned char*)pixels;
93 if(SDL_MUSTLOCK(fbsurf)) {
94 SDL_LockSurface(fbsurf);
95 }
97 if(scale > 1) {
98 int i, j, xsz, ysz;
99 unsigned char *dest = fbsurf->pixels;
101 xsz = 320 * scale;
102 ysz = 200 * scale;
104 for(i=0; i<ysz; i++) {
105 for(j=0; j<xsz; j++) {
106 *dest++ = frame[(i / scale) * 320 + (j / scale)];
107 }
108 }
109 } else {
110 memcpy(fbsurf->pixels, frame, 64000);
111 }
113 if(SDL_MUSTLOCK(fbsurf)) {
114 SDL_UnlockSurface(fbsurf);
115 }
116 SDL_Flip(fbsurf);
117 }
119 void wait_vsync(void)
120 {
121 }
123 /* ----- event handling (conio.h) ----- */
124 static SDL_Event *keybev;
125 static int mousex, mousey, bnmask;
127 int kbhit(void)
128 {
129 if(!keybev) {
130 proc_events();
131 }
132 return keybev != 0;
133 }
135 int getch(void)
136 {
137 int res;
139 while(!keybev) {
140 SDL_Event ev;
141 SDL_WaitEvent(&ev);
142 SDL_PushEvent(&ev);
143 proc_events();
144 }
145 res = keybev->key.keysym.sym;
146 keybev = 0;
147 return res;
148 }
150 /* mouse handling (mouse.c implementation) */
151 int have_mouse(void)
152 {
153 return 1;
154 }
156 int read_mouse(int *xp, int *yp)
157 {
158 if(xp) *xp = mousex;
159 if(yp) *yp = mousey;
160 return bnmask;
161 }
163 static void proc_events(void)
164 {
165 static SDL_Event ev;
167 while(SDL_PollEvent(&ev)) {
168 switch(ev.type) {
169 case SDL_KEYDOWN:
170 keybev = &ev;
171 return;
173 case SDL_MOUSEMOTION:
174 mousex = ev.motion.x / scale;
175 mousey = ev.motion.y / scale;
176 break;
178 case SDL_MOUSEBUTTONDOWN:
179 case SDL_MOUSEBUTTONUP:
180 {
181 int mask = 0;
182 switch(ev.button.button) {
183 case SDL_BUTTON_LEFT:
184 mask = MOUSE_LEFT;
185 break;
186 case SDL_BUTTON_MIDDLE:
187 mask = MOUSE_MIDDLE;
188 break;
189 case SDL_BUTTON_RIGHT:
190 mask = MOUSE_RIGHT;
191 default:
192 break;
193 }
194 if(!mask) {
195 break;
196 }
198 if(ev.button.state == SDL_PRESSED) {
199 bnmask |= mask;
200 } else {
201 bnmask &= ~mask;
202 }
203 }
204 break;
206 default:
207 break;
208 }
209 }
210 }
212 /* ---- timer.c implementation ---- */
213 static Uint32 start_time;
215 void init_timer(int res_hz)
216 {
217 reset_timer();
218 }
220 void reset_timer(void)
221 {
222 start_time = SDL_GetTicks();
223 }
225 unsigned long get_msec(void)
226 {
227 return (unsigned long)(SDL_GetTicks() - start_time);
228 }