dos3d

view dosemu/dosemu.c @ 12:c29a6e024950

merged
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 28 Nov 2011 05:03:22 +0200
parents bce78aaafc68
children
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 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 }
72 }
74 void set_palette(unsigned char c, unsigned char r, unsigned char g, unsigned char b)
75 {
76 SDL_Color col;
77 col.r = r;
78 col.g = g;
79 col.b = b;
81 if(SDL_SetPalette(fbsurf, SDL_LOGPAL | SDL_PHYSPAL, &col, c, 1) != 1) {
82 fprintf(stderr, "set_palette failed to set the required color\n");
83 }
84 }
86 void copy_frame(unsigned char *frame)
87 {
88 if(SDL_MUSTLOCK(fbsurf)) {
89 SDL_LockSurface(fbsurf);
90 }
92 if(DOUBLESZ) {
93 int i, j;
94 Uint16 *dest = fbsurf->pixels;
96 for(i=0; i<200; i++) {
97 for(j=0; j<320; j++) {
98 Uint16 twopix = ((Uint16)*frame << 8) | (Uint16)*frame;
99 dest[j] = dest[j + 320] = twopix;
100 frame++;
101 }
102 dest += fbsurf->pitch;
103 }
104 } else {
105 memcpy(fbsurf->pixels, frame, 64000);
106 }
108 if(SDL_MUSTLOCK(fbsurf)) {
109 SDL_UnlockSurface(fbsurf);
110 }
111 SDL_Flip(fbsurf);
112 }
114 void wait_vsync(void)
115 {
116 }
118 /* ----- event handling (conio.h) ----- */
119 static SDL_Event *keybev;
120 static int mousex, mousey, bnmask;
122 int kbhit(void)
123 {
124 if(!keybev) {
125 proc_events();
126 }
127 return keybev != 0;
128 }
130 int getch(void)
131 {
132 int res;
134 while(!keybev) {
135 SDL_Event ev;
136 SDL_WaitEvent(&ev);
137 SDL_PushEvent(&ev);
138 proc_events();
139 }
140 res = keybev->key.keysym.sym;
141 keybev = 0;
142 return res;
143 }
145 /* mouse handling (mouse.c implementation) */
146 int have_mouse(void)
147 {
148 return 1;
149 }
151 int read_mouse(int *xp, int *yp)
152 {
153 if(xp) *xp = mousex;
154 if(yp) *yp = mousey;
155 return bnmask;
156 }
158 static void proc_events(void)
159 {
160 static SDL_Event ev;
162 while(SDL_PollEvent(&ev)) {
163 switch(ev.type) {
164 case SDL_KEYDOWN:
165 keybev = &ev;
166 return;
168 case SDL_MOUSEMOTION:
169 mousex = ev.motion.x;
170 mousey = ev.motion.y;
172 if(DOUBLESZ) {
173 mousex /= 2;
174 mousey /= 2;
175 }
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 }