# HG changeset patch # User John Tsiombikas # Date 1396741404 -10800 # Node ID 5fcf72837b69eeada6cd1812a4a2b136b8a72e72 # Parent 18bdbcbaee81e9ab636898d88cf6f48e4b455474 fixed the dosemu bit diff -r 18bdbcbaee81 -r 5fcf72837b69 .clang_complete --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.clang_complete Sun Apr 06 02:43:24 2014 +0300 @@ -0,0 +1,3 @@ +-Isrc +-Isrc/stl +-Isrc/dosemu diff -r 18bdbcbaee81 -r 5fcf72837b69 .hgignore --- a/.hgignore Sun Apr 06 01:12:50 2014 +0300 +++ b/.hgignore Sun Apr 06 02:43:24 2014 +0300 @@ -1,4 +1,5 @@ \.o$ +\.d$ \.swp$ \.obj$ \.exe$ diff -r 18bdbcbaee81 -r 5fcf72837b69 GNUmakefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GNUmakefile Sun Apr 06 02:43:24 2014 +0300 @@ -0,0 +1,34 @@ +modelobj = src/main.o src/min3d.o src/m3drast.o src/logger.o +rendobj = src/rend.o src/vmath.o +scnobj = src/scene.o src/object.o +sysobj = src/dosemu/dosemu.o +obj = $(modelobj) $(rendobj) $(scnobj) $(sysobj) +dep = $(obj:.o=.d) +bin = rayzor + +dbg = -g +#opt = -O3 -ffast-math +inc = -Isrc -Isrc/stl -Isrc/dosemu + +CFLAGS = -pedantic -Wall $(dbg) $(opt) `pkg-config --cflags sdl` $(inc) +CXXFLAGS = $(CFLAGS) +LDFLAGS = `pkg-config --libs sdl` -lm + +$(bin): $(obj) + $(CXX) -o $@ $(obj) $(LDFLAGS) + +-include $(dep) + +%.d: %.c + @$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@ + +%.d: %.cc + @$(CPP) $(CXXFLAGS) $< -MM -MT $(@:.d=.o) >$@ + +.PHONY: clean +clean: + rm -f $(obj) $(bin) + +.PHONY: cleandep +cleandep: + rm -f $(dep) diff -r 18bdbcbaee81 -r 5fcf72837b69 src/dosemu/dosemu.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dosemu/dosemu.c Sun Apr 06 02:43:24 2014 +0300 @@ -0,0 +1,463 @@ +/* This file implements all calls made to dos-specific code using SDL */ +#include +#include +#include +#ifdef DOSEMU_CAPTURE +#include +#endif +#include "gfx.h" +#include "mouse.h" +#include "keyb.h" +#include "timer.h" + +static void proc_events(void); +static void capture_frame(unsigned char *frame); + +static void init_sdl() +{ + const SDL_version *ver; + + if(!SDL_WasInit(SDL_INIT_EVERYTHING)) { + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER); + + if((ver = SDL_Linked_Version())) { + printf("SDL %d.%d.%d initialized\n", ver->major, ver->minor, ver->patch); + } + } +} + +/* ----- graphics (gfx.c (vbe) implementation) ----- */ +static SDL_Surface *fbsurf; +static int scale = 1; +static int frames_to_capture; + +static struct { + unsigned char r, g, b; +} palette[256]; + + +void *set_video_mode(int xsz, int ysz, int bpp) +{ + unsigned int sdl_flags = bpp <= 8 ? SDL_HWPALETTE : 0; + char *env; + + if(getenv("DOSEMU_DOUBLESIZE")) { + scale = 2; + } + + if((env = getenv("DOSEMU_SCALE"))) { + int n = atoi(env); + if(n > 0) { + scale = n; + } + } + xsz *= scale; + ysz *= scale; + + if(getenv("DOSEMU_FULLSCREEN")) { + sdl_flags |= SDL_FULLSCREEN; + } + + init_sdl(); + + if(!(fbsurf = SDL_SetVideoMode(xsz, ysz, bpp, sdl_flags))) { + fprintf(stderr, "failed to set video mode\n"); + abort(); + } + SDL_WM_SetCaption("Rayzor", 0); + /*SDL_ShowCursor(0);*/ + + return fbsurf->pixels; +} + +int set_text_mode(void) +{ + SDL_ShowCursor(1); + SDL_EnableKeyRepeat(0, 0); + SDL_Quit(); + return 0; +} + +int get_color_depth(void) +{ + return fbsurf->format->BitsPerPixel; +} + +static int count_bits(unsigned int x) +{ + int i, count = 0; + for(i=0; i<32; i++) { + if(x & 1) { + count++; + } + x >>= 1; + } + return count; +} + +int get_color_bits(int *rbits, int *gbits, int *bbits) +{ + *rbits = count_bits(fbsurf->format->Rmask); + *gbits = count_bits(fbsurf->format->Gmask); + *bbits = count_bits(fbsurf->format->Bmask); + return *rbits + *gbits + *bbits; +} + +int get_color_shift(int *rshift, int *gshift, int *bshift) +{ + *rshift = fbsurf->format->Rshift; + *gshift = fbsurf->format->Gshift; + *bshift = fbsurf->format->Bshift; + return 0; +} + +int get_color_mask(unsigned int *rmask, unsigned int *gmask, unsigned int *bmask) +{ + *rmask = fbsurf->format->Rmask; + *gmask = fbsurf->format->Gmask; + *bmask = fbsurf->format->Bmask; + return 0; +} + + +void set_palette(int idx, int r, int g, int b) +{ + SDL_Color col; + col.r = r; + col.g = g; + col.b = b; + + if(SDL_SetPalette(fbsurf, SDL_LOGPAL | SDL_PHYSPAL, &col, idx, 1) != 1) { + fprintf(stderr, "set_palette failed to set the required color\n"); + } + + palette[idx].r = r; + palette[idx].g = g; + palette[idx].b = b; +} + +static int copy_frame_called; + +void copy_frame(void *pixels) +{ + unsigned char *frame = (unsigned char*)pixels; + copy_frame_called = 1; + + if(SDL_MUSTLOCK(fbsurf)) { + SDL_LockSurface(fbsurf); + } + + if(pixels) { + if(scale > 1) { + int i, j, xsz, ysz; + unsigned char *dest = fbsurf->pixels; + + xsz = fbsurf->w * scale; + ysz = fbsurf->h * scale; + + for(i=0; iw + (j / scale)]; + } + } + } else { + int num_pixels = fbsurf->w * fbsurf->h; + memcpy(fbsurf->pixels, frame, num_pixels * fbsurf->format->BytesPerPixel); + } + } + + if(SDL_MUSTLOCK(fbsurf)) { + SDL_UnlockSurface(fbsurf); + } + + SDL_Flip(fbsurf); + + if(frames_to_capture > 0) { + capture_frame(pixels); + --frames_to_capture; + } + + /* also print fps every second ... */ + { + static long prev_fps, num_frames; + long msec, dt; + + msec = get_msec(); + dt = msec - prev_fps; + if(dt >= 1000) { + float fps = (float)num_frames / ((float)dt / 1000.0f); + printf("framerate: %.1f \r", fps); + fflush(stdout); + num_frames = 0; + prev_fps = msec; + } else { + num_frames++; + } + } +} + +#define spin_delay(ms) \ + do { \ + unsigned int end = SDL_GetTicks() + ms; \ + while((prev_msec = SDL_GetTicks()) < end); \ + } while(0) + +#define FRAME_INTERVAL (1000/70) + +void wait_vsync(void) +{ + static int prev_msec; + int msec, dt, tleft; + + if(!copy_frame_called) { + copy_frame(0); + copy_frame_called = 0; + } + + msec = SDL_GetTicks(); + + dt = msec - prev_msec; + + tleft = FRAME_INTERVAL - dt; + if(tleft > 0) { + int coarse = tleft & 0xfffffff8; + tleft = tleft & 7; + + if(coarse) { + SDL_Delay(coarse); + } + if(tleft) { + spin_delay(tleft); + } else { + prev_msec = SDL_GetTicks(); + } + } else { + prev_msec = msec; + } +} + +static int cap_count = 0; +void begin_capture(int frames) +{ + frames_to_capture = frames; +} + +void end_capture(void) +{ + cap_count = 0; + frames_to_capture = 0; +} + +#define NUMPIX (fbsurf->w * fbsurf->h) +static void capture_frame(unsigned char *frame) +{ +#ifdef DOSEMU_CAPTURE + static unsigned char rgbpix[NUMPIX * 4]; + char fname[32]; + int i; + unsigned char *src, *dest; + + sprintf(fname, "frame%04d.png", cap_count++); + + src = frame; + dest = rgbpix; + + for(i=0; iw, fbsurf->h, IMG_FMT_RGBA32); +#endif +} + + +/* ----- event handling (conio.h) ----- */ +static SDL_Event *keybev; +static int mousex, mousey, bnmask; + +static int keystate[256]; +static int num_pressed; + +int kbhit(void) +{ + if(!keybev) { + proc_events(); + } + return keybev != 0; +} + +int getch(void) +{ + int res; + + while(!keybev) { + SDL_Event ev; + SDL_WaitEvent(&ev); + SDL_PushEvent(&ev); + proc_events(); + } + res = keybev->key.keysym.sym; + keybev = 0; + return res; +} + +/* ----- improved event handling (keyb.h) ---- */ + +int kb_init(int bufsz) +{ + init_sdl(); + + return 0; +} + +void kb_shutdown(void) +{ +} + +int kb_getkey(void) +{ + int res = -1; + + proc_events(); + if(keybev) { + res = keybev->key.keysym.sym; + keybev = 0; + } + return res; +} + +int kb_isdown(int key) +{ + if(key == KB_ANY) { + return num_pressed; + } + return keystate[key]; +} + +/* mouse handling (mouse.c implementation) */ +static unsigned long last_mouse_hide_time; + +int have_mouse(void) +{ + return 1; +} + +void set_mouse(int x, int y) +{ + SDL_ShowCursor(0); + last_mouse_hide_time = get_msec(); + + SDL_WarpMouse(x * scale, y * scale); + mousex = x; + mousey = y; +} + +int read_mouse(int *xp, int *yp) +{ + if(xp) *xp = mousex; + if(yp) *yp = mousey; + return bnmask; +} + +static void proc_events(void) +{ + static SDL_Event ev; + + if(last_mouse_hide_time > 0 && get_msec() - last_mouse_hide_time > 3000) { + last_mouse_hide_time = 0; + SDL_ShowCursor(1); + } + + while(SDL_PollEvent(&ev)) { + switch(ev.type) { + case SDL_KEYDOWN: + { + int key = ev.key.keysym.sym; + + if(!keybev) { + keybev = &ev; + } + + if(!keystate[key]) { + keystate[key] = 1; + num_pressed++; + } + } + break; + + case SDL_KEYUP: + { + int key = ev.key.keysym.sym; + + if(keystate[key]) { + keystate[key] = 0; + if(--num_pressed < 0) { + num_pressed = 0; + } + } + } + break; + + case SDL_MOUSEMOTION: + mousex = ev.motion.x / scale; + mousey = ev.motion.y / scale; + break; + + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + { + int mask = 0; + switch(ev.button.button) { + case SDL_BUTTON_LEFT: + mask = MOUSE_LEFT; + break; + case SDL_BUTTON_MIDDLE: + mask = MOUSE_MIDDLE; + break; + case SDL_BUTTON_RIGHT: + mask = MOUSE_RIGHT; + default: + break; + } + if(!mask) { + break; + } + + if(ev.button.state == SDL_PRESSED) { + bnmask |= mask; + } else { + bnmask &= ~mask; + } + } + break; + + default: + break; + } + } +} + +/* ---- timer.c implementation ---- */ +static Uint32 start_time; + +void init_timer(int res_hz) +{ + init_sdl(); + reset_timer(); +} + +void reset_timer(void) +{ + start_time = SDL_GetTicks(); + printf("resetting timer: %u, %lu\n", start_time, get_msec()); +} + +unsigned long get_msec(void) +{ + Uint32 ticks = SDL_GetTicks(); + return (unsigned long)(ticks - start_time); +} diff -r 18bdbcbaee81 -r 5fcf72837b69 src/gfx.c --- a/src/gfx.c Sun Apr 06 01:12:50 2014 +0300 +++ b/src/gfx.c Sun Apr 06 02:43:24 2014 +0300 @@ -138,6 +138,11 @@ vbe_set_palette(idx, col, 1, pal_bits); } +void wait_vsync(void) +{ + /* TODO */ +} + static unsigned int make_mask(int sz, int pos) { unsigned int i, mask = 0; diff -r 18bdbcbaee81 -r 5fcf72837b69 src/gfx.h --- a/src/gfx.h Sun Apr 06 01:12:50 2014 +0300 +++ b/src/gfx.h Sun Apr 06 02:43:24 2014 +0300 @@ -15,6 +15,8 @@ void set_palette(int idx, int r, int g, int b); +void wait_vsync(void); + #ifdef __cplusplus } #endif diff -r 18bdbcbaee81 -r 5fcf72837b69 src/m3dimpl.h --- a/src/m3dimpl.h Sun Apr 06 01:12:50 2014 +0300 +++ b/src/m3dimpl.h Sun Apr 06 02:43:24 2014 +0300 @@ -25,6 +25,16 @@ int mmode; /* matrix mode */ struct min3d_mstack mstack[2]; + + const float *vert_array; + const float *norm_array; + const float *col_array; + const float *tc_array; + + /* immediate mode state */ + float cur_color[4]; + float cur_normal[3]; + float cur_texcoord[2]; }; extern struct min3d_context *m3dctx; diff -r 18bdbcbaee81 -r 5fcf72837b69 src/m3drast.c --- a/src/m3drast.c Sun Apr 06 01:12:50 2014 +0300 +++ b/src/m3drast.c Sun Apr 06 02:43:24 2014 +0300 @@ -3,6 +3,17 @@ void draw_point(struct min3d_vertex *v) { + int x = v->pos[0] + 0.5; + int y = v->pos[1] + 0.5; + int xsz = m3dctx->cbuf->xsz; + unsigned char *ptr = m3dctx->cbuf->pixels + (y * xsz + x) * 3; + + int r = (int)(v->color[0] * 255.0); + int g = (int)(v->color[1] * 255.0); + int b = (int)(v->color[2] * 255.0); + ptr[0] = r > 255 ? 255 : r; + ptr[1] = g > 255 ? 255 : g; + ptr[2] = b > 255 ? 255 : b; } void draw_line(struct min3d_vertex *v) diff -r 18bdbcbaee81 -r 5fcf72837b69 src/main.cc --- a/src/main.cc Sun Apr 06 01:12:50 2014 +0300 +++ b/src/main.cc Sun Apr 06 02:43:24 2014 +0300 @@ -85,6 +85,7 @@ } swap_buffers(); + wait_vsync(); } #define PACK_RGB(r, g, b) \ @@ -133,14 +134,14 @@ static void handle_keyboard() { - if(!kb_isdown(KB_ANY)) - return; + int key; - int c = kb_getkey(); - switch(c) { - case 27: - quit = true; - return; + while((key = kb_getkey()) != -1) { + switch(key) { + case 27: + quit = true; + return; + } } } diff -r 18bdbcbaee81 -r 5fcf72837b69 src/min3d.c --- a/src/min3d.c Sun Apr 06 01:12:50 2014 +0300 +++ b/src/min3d.c Sun Apr 06 02:43:24 2014 +0300 @@ -1,4 +1,6 @@ #include +#include +#include #include "min3d.h" #include "m3dimpl.h" @@ -233,11 +235,36 @@ } /* drawing */ -void m3d_draw(int prim, const float *varr, int vcount) +void m3d_vertex_array(const float *varr) +{ + m3dctx->vert_array = varr; +} + +void m3d_normal_array(const float *narr) +{ + m3dctx->norm_array = narr; +} + +void m3d_color_array(const float *carr) +{ + m3dctx->col_array = carr; +} + +void m3d_texcoord_array(const float *tcarr) +{ + m3dctx->tc_array = tcarr; +} + + +void m3d_draw(int prim, int vcount) { int i; struct min3d_vertex v[4]; struct min3d_vertex resv[16]; + const float *varr = m3dctx->vert_array; + const float *carr = m3dctx->col_array; + + if(!varr) return; for(i=0; icur_color[0]; + v[idx].color[1] = carr ? *carr++ : m3dctx->cur_color[1]; + v[idx].color[2] = carr ? *carr++ : m3dctx->cur_color[2]; if(idx == prim - 1) { int resnum = proc_prim(prim, resv, v); @@ -264,7 +294,7 @@ } } -void m3d_draw_indexed(int prim, const float *varr, const int *idxarr, int icount) +void m3d_draw_indexed(int prim, const int *idxarr, int icount) { /* TODO */ } diff -r 18bdbcbaee81 -r 5fcf72837b69 src/min3d.h --- a/src/min3d.h Sun Apr 06 01:12:50 2014 +0300 +++ b/src/min3d.h Sun Apr 06 02:43:24 2014 +0300 @@ -61,8 +61,13 @@ void m3d_perspective(float vfov, float aspect, float znear, float zfar); /* drawing */ -void m3d_draw(int prim, const float *varr, int vcount); -void m3d_draw_indexed(int prim, const float *varr, const int *idxarr, int icount); +void m3d_vertex_array(const float *varr); +void m3d_normal_array(const float *narr); +void m3d_color_array(const float *carr); +void m3d_texcoord_array(const float *tcarr); + +void m3d_draw(int prim, int vcount); +void m3d_draw_indexed(int prim, const int *idxarr, int icount); /* TODO immediate mode */ diff -r 18bdbcbaee81 -r 5fcf72837b69 src/object.cc --- a/src/object.cc Sun Apr 06 01:12:50 2014 +0300 +++ b/src/object.cc Sun Apr 06 02:43:24 2014 +0300 @@ -49,5 +49,7 @@ } } - m3d_draw(M3D_POINTS, &varr->x, num_verts); + m3d_vertex_array(&varr->x); + m3d_draw(M3D_POINTS, num_verts); + m3d_vertex_array(0); } diff -r 18bdbcbaee81 -r 5fcf72837b69 src/scene.cc --- a/src/scene.cc Sun Apr 06 01:12:50 2014 +0300 +++ b/src/scene.cc Sun Apr 06 02:43:24 2014 +0300 @@ -1,3 +1,4 @@ +#include #include "scene.h" Scene::Scene()