dos3d

view dosemu/dosemu.c @ 9:bce78aaafc68

foo
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 26 Nov 2011 03:59:48 +0200
parents f04884489bad
children 0909996838ff
line source
1 /*
2 256-color 3D graphics hack for real-mode DOS.
3 Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
19 /* This file implements all calls made to dos-specific code using SDL
20 * Don't ask why ...
21 */
23 #include <stdlib.h>
24 #include <assert.h>
25 #include <SDL.h>
26 #include "vga.h"
27 #include "conio.h"
28 #include "mouse.h"
29 #include "timer.h"
31 static void proc_events(void);
33 /* ----- graphics (vga.c implementation) ----- */
34 static SDL_Surface *fbsurf;
36 #define DOUBLESZ (fbsurf->w != 320)
38 void set_video_mode(int mode)
39 {
40 int resx = 320, resy = 200;
41 unsigned int sdl_flags = SDL_HWPALETTE;
43 if(getenv("DOSEMU_DOUBLESIZE")) {
44 resx *= 2;
45 resy *= 2;
46 }
48 if(getenv("DOSEMU_FULLSCREEN")) {
49 sdl_flags |= SDL_FULLSCREEN;
50 }
52 switch(mode) {
53 case 0x13:
54 SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
55 if(!(fbsurf = SDL_SetVideoMode(resx, resy, 8, sdl_flags))) {
56 fprintf(stderr, "failed to set video mode\n");
57 abort();
58 }
59 SDL_ShowCursor(0);
60 break;
62 case 3:
63 SDL_ShowCursor(1);
64 SDL_Quit();
65 break;
67 default:
68 break;
69 }
70 }
72 void set_palette(unsigned char c, unsigned char r, unsigned char g, unsigned char b)
73 {
74 SDL_Color col;
75 col.r = r;
76 col.g = g;
77 col.b = b;
79 if(SDL_SetPalette(fbsurf, SDL_LOGPAL | SDL_PHYSPAL, &col, c, 1) != 1) {
80 fprintf(stderr, "set_palette failed to set the required color\n");
81 }
82 }
84 void copy_frame(unsigned char *frame)
85 {
86 if(SDL_MUSTLOCK(fbsurf)) {
87 SDL_LockSurface(fbsurf);
88 }
90 if(DOUBLESZ) {
91 int i, j;
92 Uint16 *dest = fbsurf->pixels;
94 for(i=0; i<200; i++) {
95 for(j=0; j<320; j++) {
96 Uint16 twopix = ((Uint16)*frame << 8) | (Uint16)*frame;
97 dest[j] = dest[j + 320] = twopix;
98 frame++;
99 }
100 dest += fbsurf->pitch;
101 }
102 } else {
103 memcpy(fbsurf->pixels, frame, 64000);
104 }
106 if(SDL_MUSTLOCK(fbsurf)) {
107 SDL_UnlockSurface(fbsurf);
108 }
109 SDL_Flip(fbsurf);
110 }
112 void wait_vsync(void)
113 {
114 }
116 /* ----- event handling (conio.h) ----- */
117 static SDL_Event *keybev;
118 static int mousex, mousey, bnmask;
120 int kbhit(void)
121 {
122 if(!keybev) {
123 proc_events();
124 }
125 return keybev != 0;
126 }
128 int getch(void)
129 {
130 int res;
132 while(!keybev) {
133 SDL_Event ev;
134 SDL_WaitEvent(&ev);
135 SDL_PushEvent(&ev);
136 proc_events();
137 }
138 res = keybev->key.keysym.sym;
139 keybev = 0;
140 return res;
141 }
143 /* mouse handling (mouse.c implementation) */
144 int have_mouse(void)
145 {
146 return 1;
147 }
149 int read_mouse(int *xp, int *yp)
150 {
151 if(xp) *xp = mousex;
152 if(yp) *yp = mousey;
153 return bnmask;
154 }
156 static void proc_events(void)
157 {
158 static SDL_Event ev;
160 while(SDL_PollEvent(&ev)) {
161 switch(ev.type) {
162 case SDL_KEYDOWN:
163 keybev = &ev;
164 return;
166 case SDL_MOUSEMOTION:
167 mousex = ev.motion.x;
168 mousey = ev.motion.y;
170 if(DOUBLESZ) {
171 mousex /= 2;
172 mousey /= 2;
173 }
174 break;
176 case SDL_MOUSEBUTTONDOWN:
177 case SDL_MOUSEBUTTONUP:
178 {
179 int mask = 0;
180 switch(ev.button.button) {
181 case SDL_BUTTON_LEFT:
182 mask = MOUSE_LEFT;
183 break;
184 case SDL_BUTTON_MIDDLE:
185 mask = MOUSE_MIDDLE;
186 break;
187 case SDL_BUTTON_RIGHT:
188 mask = MOUSE_RIGHT;
189 default:
190 break;
191 }
192 if(!mask) {
193 break;
194 }
196 if(ev.button.state == SDL_PRESSED) {
197 bnmask |= mask;
198 } else {
199 bnmask &= ~mask;
200 }
201 }
202 break;
204 default:
205 break;
206 }
207 }
208 }
210 /* ---- timer.c implementation ---- */
211 static Uint32 start_time;
213 void init_timer(int res_hz)
214 {
215 reset_timer();
216 }
218 void reset_timer(void)
219 {
220 start_time = SDL_GetTicks();
221 }
223 unsigned long get_msec(void)
224 {
225 return (unsigned long)(SDL_GetTicks() - start_time);
226 }