dos3d
diff dosemu/dosemu.c @ 0:f04884489bad
dos3d initial import
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 21 Nov 2011 06:14:01 +0200 |
parents | |
children | bce78aaafc68 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dosemu/dosemu.c Mon Nov 21 06:14:01 2011 +0200 1.3 @@ -0,0 +1,221 @@ 1.4 +/* 1.5 +256-color 3D graphics hack for real-mode DOS. 1.6 +Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org> 1.7 + 1.8 +This program is free software: you can redistribute it and/or modify 1.9 +it under the terms of the GNU General Public License as published by 1.10 +the Free Software Foundation, either version 3 of the License, or 1.11 +(at your option) any later version. 1.12 + 1.13 +This program is distributed in the hope that it will be useful, 1.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 1.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1.16 +GNU General Public License for more details. 1.17 + 1.18 +You should have received a copy of the GNU General Public License 1.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 1.20 +*/ 1.21 + 1.22 +/* This file implements all calls made to dos-specific code using SDL 1.23 + * Don't ask why ... 1.24 + */ 1.25 + 1.26 +#include <stdlib.h> 1.27 +#include <assert.h> 1.28 +#include <SDL.h> 1.29 +#include "vga.h" 1.30 +#include "conio.h" 1.31 +#include "mouse.h" 1.32 +#include "timer.h" 1.33 + 1.34 +static void proc_events(void); 1.35 + 1.36 +/* ----- graphics (vga.c implementation) ----- */ 1.37 +static SDL_Surface *fbsurf; 1.38 + 1.39 +#define DOUBLESZ (fbsurf->w != 320) 1.40 + 1.41 +void set_video_mode(int mode) 1.42 +{ 1.43 + int resx = 320, resy = 200; 1.44 + 1.45 + if(getenv("DOSEMU_DOUBLESIZE")) { 1.46 + resx *= 2; 1.47 + resy *= 2; 1.48 + } 1.49 + 1.50 + switch(mode) { 1.51 + case 0x13: 1.52 + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER); 1.53 + if(!(fbsurf = SDL_SetVideoMode(resx, resy, 8, SDL_HWPALETTE))) { 1.54 + fprintf(stderr, "failed to set video mode\n"); 1.55 + abort(); 1.56 + } 1.57 + SDL_ShowCursor(0); 1.58 + break; 1.59 + 1.60 + case 3: 1.61 + SDL_ShowCursor(1); 1.62 + SDL_Quit(); 1.63 + break; 1.64 + 1.65 + default: 1.66 + break; 1.67 + } 1.68 +} 1.69 + 1.70 +void set_palette(unsigned char c, unsigned char r, unsigned char g, unsigned char b) 1.71 +{ 1.72 + SDL_Color col; 1.73 + col.r = r; 1.74 + col.g = g; 1.75 + col.b = b; 1.76 + 1.77 + if(SDL_SetPalette(fbsurf, SDL_LOGPAL | SDL_PHYSPAL, &col, c, 1) != 1) { 1.78 + fprintf(stderr, "set_palette failed to set the required color\n"); 1.79 + } 1.80 +} 1.81 + 1.82 +void copy_frame(unsigned char *frame) 1.83 +{ 1.84 + if(SDL_MUSTLOCK(fbsurf)) { 1.85 + SDL_LockSurface(fbsurf); 1.86 + } 1.87 + 1.88 + if(DOUBLESZ) { 1.89 + int i, j; 1.90 + Uint16 *dest = fbsurf->pixels; 1.91 + 1.92 + for(i=0; i<200; i++) { 1.93 + for(j=0; j<320; j++) { 1.94 + Uint16 twopix = ((Uint16)*frame << 8) | (Uint16)*frame; 1.95 + dest[j] = dest[j + 320] = twopix; 1.96 + frame++; 1.97 + } 1.98 + dest += fbsurf->pitch; 1.99 + } 1.100 + } else { 1.101 + memcpy(fbsurf->pixels, frame, 64000); 1.102 + } 1.103 + 1.104 + if(SDL_MUSTLOCK(fbsurf)) { 1.105 + SDL_UnlockSurface(fbsurf); 1.106 + } 1.107 + SDL_Flip(fbsurf); 1.108 +} 1.109 + 1.110 +void wait_vsync(void) 1.111 +{ 1.112 +} 1.113 + 1.114 +/* ----- event handling (conio.h) ----- */ 1.115 +static SDL_Event *keybev; 1.116 +static int mousex, mousey, bnmask; 1.117 + 1.118 +int kbhit(void) 1.119 +{ 1.120 + if(!keybev) { 1.121 + proc_events(); 1.122 + } 1.123 + return keybev != 0; 1.124 +} 1.125 + 1.126 +char getch(void) 1.127 +{ 1.128 + char res; 1.129 + 1.130 + while(!keybev) { 1.131 + SDL_Event ev; 1.132 + SDL_WaitEvent(&ev); 1.133 + SDL_PushEvent(&ev); 1.134 + proc_events(); 1.135 + } 1.136 + res = keybev->key.keysym.sym; 1.137 + keybev = 0; 1.138 + return res; 1.139 +} 1.140 + 1.141 +/* mouse handling (mouse.c implementation) */ 1.142 +int have_mouse(void) 1.143 +{ 1.144 + return 1; 1.145 +} 1.146 + 1.147 +int read_mouse(int *xp, int *yp) 1.148 +{ 1.149 + if(xp) *xp = mousex; 1.150 + if(yp) *yp = mousey; 1.151 + return bnmask; 1.152 +} 1.153 + 1.154 +static void proc_events(void) 1.155 +{ 1.156 + static SDL_Event ev; 1.157 + 1.158 + while(SDL_PollEvent(&ev)) { 1.159 + switch(ev.type) { 1.160 + case SDL_KEYDOWN: 1.161 + keybev = &ev; 1.162 + return; 1.163 + 1.164 + case SDL_MOUSEMOTION: 1.165 + mousex = ev.motion.x; 1.166 + mousey = ev.motion.y; 1.167 + 1.168 + if(DOUBLESZ) { 1.169 + mousex /= 2; 1.170 + mousey /= 2; 1.171 + } 1.172 + break; 1.173 + 1.174 + case SDL_MOUSEBUTTONDOWN: 1.175 + case SDL_MOUSEBUTTONUP: 1.176 + { 1.177 + int mask = 0; 1.178 + switch(ev.button.button) { 1.179 + case SDL_BUTTON_LEFT: 1.180 + mask = MOUSE_LEFT; 1.181 + break; 1.182 + case SDL_BUTTON_MIDDLE: 1.183 + mask = MOUSE_MIDDLE; 1.184 + break; 1.185 + case SDL_BUTTON_RIGHT: 1.186 + mask = MOUSE_RIGHT; 1.187 + default: 1.188 + break; 1.189 + } 1.190 + if(!mask) { 1.191 + break; 1.192 + } 1.193 + 1.194 + if(ev.button.state == SDL_PRESSED) { 1.195 + bnmask |= mask; 1.196 + } else { 1.197 + bnmask &= ~mask; 1.198 + } 1.199 + } 1.200 + break; 1.201 + 1.202 + default: 1.203 + break; 1.204 + } 1.205 + } 1.206 +} 1.207 + 1.208 +/* ---- timer.c implementation ---- */ 1.209 +static Uint32 start_time; 1.210 + 1.211 +void init_timer(int res_hz) 1.212 +{ 1.213 + reset_timer(); 1.214 +} 1.215 + 1.216 +void reset_timer(void) 1.217 +{ 1.218 + start_time = SDL_GetTicks(); 1.219 +} 1.220 + 1.221 +unsigned long get_msec(void) 1.222 +{ 1.223 + return (unsigned long)(SDL_GetTicks() - start_time); 1.224 +}