From f05dc678f0a33f632b79d6267e1bbcef7c9f8475 Mon Sep 17 00:00:00 2001 From: Bradley Bell Date: Fri, 19 Jan 2001 03:34:09 +0000 Subject: [PATCH] This commit was generated by cvs2svn to compensate for changes in r5, which included commits to RCS files with non-trunk default branches. --- 2d/2dsline.c | 18 +- 2d/bitblt.c | 12 +- 2d/box.c | 4 +- 2d/canvas.c | 6 +- 2d/diff | 648 ++++++------ 2d/gpixel.c | 10 +- 2d/line.c | 4 +- 2d/linear.h | 12 +- 2d/pixel.c | 4 +- README | 253 +++-- arch/Makefile.am | 21 +- arch/Makefile.in | 189 ++-- arch/dos/Makefile.am | 20 + arch/dos/Makefile.in | 307 ++++++ arch/dos/cdrom.c | 77 ++ arch/dos/digi.c | 810 ++++++++++++++ arch/dos/disk.c | 3 +- arch/dos/dosgr.c | 23 +- arch/dos/dpmi.c | 87 +- arch/dos/findfile.c | 95 ++ arch/dos/include/joy.h | 6 +- arch/dos/include/key.h | 6 +- arch/dos/include/mouse.h | 6 +- arch/dos/init.c | 65 +- arch/dos/joyc.c | 16 +- arch/dos/joydefs.c | 15 +- arch/dos/key.c | 15 +- arch/dos/mouse.c | 12 +- arch/dos/vesa.c | 14 +- arch/dos_dpmi.c | 398 +++++++ arch/dos_findfile.c | 95 ++ arch/dos_init.c | 370 +++++++ arch/dos_ipx.c | 753 +++++++++++++ arch/dos_modex.asm | 829 +++++++++++++++ arch/dos_timer.asm | 496 +++++++++ arch/dos_tweak.inc | 258 +++++ arch/dos_vesa.c | 140 +++ arch/dos_vgaregs.inc | 62 ++ arch/linux/Makefile.am | 4 + arch/linux/Makefile.in | 4 +- arch/linux/findfile.c | 5 + arch/linux/init.c | 5 + arch/linux/ipx_bsd.c | 2 + arch/linux/ipx_lin.c | 4 + arch/linux/ipx_udp.c | 2 + arch/linux/linuxnet.c | 2 + arch/linux_findfile.c | 58 + arch/linux_init.c | 51 + arch/linux_ipx_bsd.c | 230 ++++ arch/linux_ipx_lin.c | 218 ++++ arch/linux_ipx_udp.c | 593 +++++++++++ arch/linux_net.c | 368 +++++++ arch/sdl/Makefile.in | 2 +- arch/sdl_init.c | 32 + arch/sdl_timer.c | 15 + conf.h.in | 29 +- configure | 451 ++++---- configure.in | 123 ++- copying | 21 + djgpp.bat | 1 + djgpp.sh | 6 + include/d.bat | 4 +- include/d_io.h | 2 +- include/dtypes.inc | 50 +- include/gr.h | 2 +- include/grdef.h | 6 +- include/lst.bat | 2 +- include/m.bat | 2 +- include/psmacros.inc | 660 ++++++------ include/pstypes.h | 18 +- include/pstypes.inc | 50 +- include/strutil.h | 9 +- include/test.lnk | 10 +- include/timer.h | 12 +- input/Makefile.am | 28 +- input/Makefile.in | 193 ++-- input/dos_joy2.asm | 471 ++++++++ input/dos_joyc.c | 657 ++++++++++++ input/dos_joydefs.c | 419 ++++++++ input/dos_key.c | 584 ++++++++++ input/dos_mouse.c | 604 +++++++++++ input/ggi/Makefile.in | 2 +- input/ggi_event.c | 131 +++ input/ggi_init.c | 11 + input/ggi_key.c | 498 +++++++++ input/ggi_mouse.c | 161 +++ input/linux/Makefile.in | 2 +- input/linux_joydefs.c | 240 +++++ input/linux_joystick.c | 379 +++++++ input/sdl/Makefile.in | 2 +- input/sdl_event.c | 58 + input/sdl_key.c | 621 +++++++++++ input/sdl_mouse.c | 238 +++++ main/Makefile.am | 17 +- main/Makefile.in | 25 +- main/config.c | 10 +- main/console.c | 8 +- main/digi.h | 6 +- main/gamerend.c | 4 +- main/inferno.c | 28 - main/inferno.ini | 94 +- main/kconfig.c | 4 +- main/kludge.c | 8 +- main/link.bat | 1 + main/multi.c | 2 +- main/network.c | 3 +- maths/vecmat.c | 8 +- misc/d_io.c | 10 +- misc/dos_disk.h | 6 + misc/strutil.c | 8 + readme.txt | 150 +-- sound/Makefile.am | 3 +- sound/Makefile.in | 8 +- sound/dos_cdrom.c | 80 ++ sound/dos_digi.c | 813 ++++++++++++++ sound/sdl_cdrom.c | 4 + sound/sdl_digi.c | 4 + unused/bios/d.bat | 2 +- unused/bios/dd.bat | 2 +- unused/bios/joy.asm | 504 ++++----- unused/bios/key.asm | 1812 +++++++++++++++---------------- unused/bios/keys.inc | 568 +++++----- unused/bios/make0000.bat | 10 +- unused/bios/make0001.bat | 10 +- unused/bios/make0100.bat | 10 +- unused/bios/mouse.asm | 632 +++++------ unused/bios/oldkey.asm | 2120 ++++++++++++++++++------------------- unused/bios/rbaudio.new | 1472 ++++++++++++------------- unused/bios/testk.lnk | 8 +- unused/bios/testm.lnk | 8 +- unused/bios/timer.asm | 1102 +++++++++---------- unused/bios/x | 6 +- unused/bios/x.bat | 2 +- unused/bios/y.bat | 22 +- unused/vga/dd.bat | 2 +- unused/vga/framebuf.jas | 638 +++++------ unused/vga/modex.asm | 1540 +++++++++++++-------------- unused/vga/tweak.inc | 470 ++++---- unused/vga/vesa.asm | 1850 ++++++++++++++++---------------- unused/vga/vga.jas | 1220 ++++++++++----------- unused/vga/vgaregs.inc | 84 +- unused/vga/xyz.bat | 20 +- unused/win95/dd.bat | 2 +- unused/win95/winckpit.asm | 256 ++--- video/Makefile.am | 2 +- video/Makefile.in | 7 +- video/dos_gr.c | 728 +++++++++++++ 147 files changed, 22007 insertions(+), 8917 deletions(-) create mode 100644 arch/dos/Makefile.am create mode 100644 arch/dos/Makefile.in create mode 100644 arch/dos/cdrom.c create mode 100644 arch/dos/digi.c create mode 100644 arch/dos/findfile.c create mode 100644 arch/dos_dpmi.c create mode 100644 arch/dos_findfile.c create mode 100644 arch/dos_init.c create mode 100644 arch/dos_ipx.c create mode 100644 arch/dos_modex.asm create mode 100644 arch/dos_timer.asm create mode 100644 arch/dos_tweak.inc create mode 100644 arch/dos_vesa.c create mode 100644 arch/dos_vgaregs.inc create mode 100644 arch/linux_findfile.c create mode 100644 arch/linux_init.c create mode 100644 arch/linux_ipx_bsd.c create mode 100644 arch/linux_ipx_lin.c create mode 100644 arch/linux_ipx_udp.c create mode 100644 arch/linux_net.c create mode 100644 arch/sdl_init.c create mode 100644 arch/sdl_timer.c create mode 100644 copying create mode 100644 djgpp.bat create mode 100644 djgpp.sh create mode 100644 input/dos_joy2.asm create mode 100644 input/dos_joyc.c create mode 100644 input/dos_joydefs.c create mode 100644 input/dos_key.c create mode 100644 input/dos_mouse.c create mode 100644 input/ggi_event.c create mode 100644 input/ggi_init.c create mode 100644 input/ggi_key.c create mode 100644 input/ggi_mouse.c create mode 100644 input/linux_joydefs.c create mode 100644 input/linux_joystick.c create mode 100644 input/sdl_event.c create mode 100644 input/sdl_key.c create mode 100644 input/sdl_mouse.c create mode 100644 main/link.bat create mode 100644 misc/dos_disk.h create mode 100644 sound/dos_cdrom.c create mode 100644 sound/dos_digi.c create mode 100644 video/dos_gr.c diff --git a/2d/2dsline.c b/2d/2dsline.c index 6e28cfd8..558e2637 100644 --- a/2d/2dsline.c +++ b/2d/2dsline.c @@ -19,7 +19,7 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #include "gr.h" #include "grdef.h" -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ #include "modex.h" #include "vesa.h" #endif @@ -98,13 +98,13 @@ void gr_linear_darken(ubyte * dest, int darkening_level, int count, ubyte * fade void gr_uscanline( int x1, int x2, int y ) { if (Gr_scanline_darkening_level >= GR_FADE_LEVELS ) { -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ switch(TYPE) { case BM_LINEAR: #endif gr_linear_stosd( DATA + ROWSIZE*y + x1, (unsigned char)COLOR, x2-x1+1); -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ break; case BM_MODEX: gr_modex_uscanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR ); @@ -115,13 +115,13 @@ void gr_uscanline( int x1, int x2, int y ) } #endif } else { -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ switch(TYPE) { case BM_LINEAR: #endif gr_linear_darken( DATA + ROWSIZE*y + x1, Gr_scanline_darkening_level, x2-x1+1, gr_fade_table); -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ break; case BM_MODEX: gr_modex_uscanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR ); @@ -147,13 +147,13 @@ void gr_scanline( int x1, int x2, int y ) if (x2 > MAXX) x2 = MAXX; if (Gr_scanline_darkening_level >= GR_FADE_LEVELS ) { -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ switch(TYPE) { case BM_LINEAR: #endif gr_linear_stosd( DATA + ROWSIZE*y + x1, (unsigned char)COLOR, x2-x1+1); -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ break; case BM_MODEX: gr_modex_uscanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR ); @@ -164,13 +164,13 @@ void gr_scanline( int x1, int x2, int y ) } #endif } else { -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ switch(TYPE) { case BM_LINEAR: #endif gr_linear_darken( DATA + ROWSIZE*y + x1, Gr_scanline_darkening_level, x2-x1+1, gr_fade_table); -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ break; case BM_MODEX: gr_modex_uscanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR ); diff --git a/2d/bitblt.c b/2d/bitblt.c index 40177b0b..3efdc777 100644 --- a/2d/bitblt.c +++ b/2d/bitblt.c @@ -141,7 +141,7 @@ void gr_ubitmap00m( int x, int y, grs_bitmap *bm ) //" jne alignstart " //"aligned4: " -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ // From Linear to ModeX void gr_bm_ubitblt01(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest) { @@ -310,7 +310,7 @@ void gr_ubitmap( int x, int y, grs_bitmap *bm ) Win32_BlitLinearToDirectX_bm(bm, 0, 0, bm->bm_w, bm->bm_h, x, y, 0); return; #endif -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ case BM_SVGA: if ( bm->bm_flags & BM_FLAG_RLE ) gr_bm_ubitblt0x_rle(bm->bm_w, bm->bm_h, x, y, 0, 0, bm, &grd_curcanv->cv_bitmap, 0 ); @@ -365,7 +365,7 @@ void gr_ubitmapm( int x, int y, grs_bitmap *bm ) Win32_BlitLinearToDirectX_bm(bm, 0, 0, bm->bm_w, bm->bm_h, x, y, 1); return; #endif -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ case BM_SVGA: gr_ubitmapGENERICm(x, y, bm); return; @@ -383,7 +383,7 @@ void gr_ubitmapm( int x, int y, grs_bitmap *bm ) } -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ // From linear to SVGA void gr_bm_ubitblt02(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest) { @@ -480,7 +480,7 @@ void gr_bm_ubitblt20(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * } } -#endif // __MSDOS__ +#endif // __ENV_DJGPP__ //@extern int Interlacing_on; // From Linear to Linear @@ -631,7 +631,7 @@ void gr_bm_ubitblt(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * sr gr_bm_ubitblt0x_rle(w, h, dx, dy, sx, sy, src, dest, 0 ); return; } -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ if ( (src->bm_type == BM_LINEAR) && (dest->bm_type == BM_SVGA )) { gr_bm_ubitblt02( w, h, dx, dy, sx, sy, src, dest ); diff --git a/2d/box.c b/2d/box.c index 54b4aaeb..019838a1 100644 --- a/2d/box.c +++ b/2d/box.c @@ -100,7 +100,7 @@ void gr_ubox(int left,int top,int right,int bot) if (TYPE==BM_LINEAR) gr_ubox0( left, top, right, bot ); -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ else if ( TYPE == BM_MODEX ) gr_ubox12( left, top, right, bot ); #endif @@ -114,7 +114,7 @@ void gr_box(int left,int top,int right,int bot) if (TYPE==BM_LINEAR) gr_box0( left, top, right, bot ); -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ else if ( TYPE == BM_MODEX ) gr_box12( left, top, right, bot ); #endif diff --git a/2d/canvas.c b/2d/canvas.c index befb02c3..3956c371 100644 --- a/2d/canvas.c +++ b/2d/canvas.c @@ -21,7 +21,7 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #include "gr.h" #include "grdef.h" -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ #include "modex.h" #include "vesa.h" #endif @@ -69,7 +69,7 @@ void gr_init_canvas(grs_canvas *canv, unsigned char * pixdata, int pixtype, int canv->cv_font_bg_color = 0; -#ifndef __MSDOS__ +#ifndef __ENV_DJGPP__ wreal = w; #else wreal = (pixtype == BM_MODEX) ? w / 4 : w; @@ -103,7 +103,7 @@ int gr_wait_for_retrace = 1; void gr_show_canvas( grs_canvas *canv ) { -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ if (canv->cv_bitmap.bm_type == BM_MODEX ) gr_modex_setstart( canv->cv_bitmap.bm_x, canv->cv_bitmap.bm_y, gr_wait_for_retrace ); diff --git a/2d/diff b/2d/diff index 2dff4f73..28b32c1c 100644 --- a/2d/diff +++ b/2d/diff @@ -1,354 +1,354 @@ 13a14 -> #include +> #include 23c24 -< #include "mem.h" +< #include "mem.h" --- -> #include "u_mem.h" +> #include "u_mem.h" 31a33 -> #include "bitmap.h" +> #include "bitmap.h" 133a136 -> +> 135a139,156 -> //hack to allow color codes to be embedded in strings -MPM -> //note we subtract one from color, since 255 is "transparent" so it'll never be used, and 0 would otherwise end the string. -> //function must already have orig_color var set (or they could be passed as args...) -> //perhaps some sort of recursive orig_color type thing would be better, but that would be way too much trouble for little gain -> int gr_message_color_level=1; -> #define CHECK_EMBEDDED_COLORS() if ((*text_ptr >= 0x01) && (*text_ptr <= 0x03)) { \ -> text_ptr++; \ -> if (*text_ptr){ \ -> if (gr_message_color_level >= *(text_ptr-1)) \ -> FG_COLOR = *text_ptr - 1; \ -> text_ptr++; \ -> } \ -> } \ -> else if ((*text_ptr >= 0x04) && (*text_ptr <= 0x06)){ \ -> if (gr_message_color_level >= *text_ptr - 3) \ -> FG_COLOR=orig_color; \ -> text_ptr++; \ -> } +> //hack to allow color codes to be embedded in strings -MPM +> //note we subtract one from color, since 255 is "transparent" so it'll never be used, and 0 would otherwise end the string. +> //function must already have orig_color var set (or they could be passed as args...) +> //perhaps some sort of recursive orig_color type thing would be better, but that would be way too much trouble for little gain +> int gr_message_color_level=1; +> #define CHECK_EMBEDDED_COLORS() if ((*text_ptr >= 0x01) && (*text_ptr <= 0x03)) { \ +> text_ptr++; \ +> if (*text_ptr){ \ +> if (gr_message_color_level >= *(text_ptr-1)) \ +> FG_COLOR = *text_ptr - 1; \ +> text_ptr++; \ +> } \ +> } \ +> else if ((*text_ptr >= 0x04) && (*text_ptr <= 0x06)){ \ +> if (gr_message_color_level >= *text_ptr - 3) \ +> FG_COLOR=orig_color; \ +> text_ptr++; \ +> } 359c380 -< +< --- -> #ifdef __ENV_MSDOS__ +> #ifdef __ENV_MSDOS__ 749a771 -> #endif +> #endif 975a998 -> #ifndef OGL +> #ifndef OGL 1049a1073,1336 -> #else // OGL -> -> #include "../main/inferno.h" -> #include "ogl_init.h" -> #include "args.h" -> //font handling routines for OpenGL - Added 9/25/99 Matthew Mueller - they are here instead of in arch/ogl because they use all these defines -> -> int pow2ize(int x);//from ogl.c -> -> int get_font_total_width(grs_font * font){ -> if (font->ft_flags & FT_PROPORTIONAL){ -> int i,w=0,c=font->ft_minchar; -> for (i=0;c<=font->ft_maxchar;i++,c++){ -> if (font->ft_widths[i]<0) -> Error("heh?\n"); -> w+=font->ft_widths[i]; -> } -> return w; -> }else{ -> return font->ft_w*(font->ft_maxchar-font->ft_minchar+1); -> } -> } -> void ogl_font_choose_size(grs_font * font,int gap,int *rw,int *rh){ -> int nchars = font->ft_maxchar-font->ft_minchar+1; -> int r,x,y,nc=0,smallest=999999,smallr=-1,tries; -> int smallprop=10000; -> int h,w; -> for (h=32;h<=256;h*=2){ -> // h=pow2ize(font->ft_h*rows+gap*(rows-1)); -> if (font->ft_h>h)continue; -> r=(h/(font->ft_h+gap)); -> w=pow2ize((get_font_total_width(font)+(nchars-r)*gap)/r); -> tries=0; -> do { -> if (tries) -> w=pow2ize(w+1); -> if(tries>3){ -> mprintf((0,"failed to fit (%ix%i, %ic)\n",w,h,nc)); -> break; -> } -> nc=0; -> y=0; -> while(y+font->ft_h<=h){ -> x=0; -> while (x if (nc==nchars) -> break; -> if (font->ft_flags & FT_PROPORTIONAL){ -> if (x+font->ft_widths[nc]+gap>w)break; -> x+=font->ft_widths[nc++]+gap; -> }else{ -> if (x+font->ft_w+gap>w)break; -> x+=font->ft_w+gap; -> nc++; -> } -> } -> if (nc==nchars) -> break; -> y+=font->ft_h+gap; -> } -> -> tries++; -> }while(nc!=nchars); -> if (nc!=nchars) -> continue; -> mprintf((0,"fit: %ix%i %i tries\n",w,h,tries)); -> -> if (w*h==smallest){//this gives squarer sizes priority (ie, 128x128 would be better than 512*32) -> if (w>=h){ -> if (w/h smallprop=w/h; -> smallest++;//hack -> } -> }else{ -> if (h/w smallprop=h/w; -> smallest++;//hack -> } -> } -> } -> if (w*h smallr=1; -> smallest=w*h; -> *rw=w; -> *rh=h; -> } -> } -> if (smallr<=0) -> Error("couldn't fit font?\n"); -> mprintf((0,"using %ix%i\n",*rw,*rh)); -> printf("using %ix%i\n",*rw,*rh); -> -> } -> -> void ogl_init_font(grs_font * font){ -> int nchars = font->ft_maxchar-font->ft_minchar+1; -> int i,w,h,tw,th,x,y,curx=0,cury=0; -> char *fp; -> // char data[32*32*4]; -> char *data; -> int gap=0;//having a gap just wastes ram, since we don't filter text textures at all. -> // char s[2]; -> ogl_font_choose_size(font,gap,&tw,&th); -> data=malloc(tw*th); -> gr_init_bitmap(&font->ft_parent_bitmap,BM_LINEAR,0,0,tw,th,tw,data); -> -> font->ft_parent_bitmap.gltexture=ogl_get_free_texture(); -> -> font->ft_bitmaps=(grs_bitmap*)malloc( nchars * sizeof(grs_bitmap)); -> mprintf((0,"ogl_init_font %s, %s, nchars=%i, (%ix%i tex)\n",(font->ft_flags & FT_PROPORTIONAL)?"proportional":"fixedwidth",(font->ft_flags & FT_COLOR)?"color":"mono",nchars,tw,th)); -> // s[1]=0; -> h=font->ft_h; -> // sleep(5); -> -> for(i=0;i // s[0]=font->ft_minchar+i; -> // gr_get_string_size(s,&w,&h,&aw); -> if (font->ft_flags & FT_PROPORTIONAL) -> w=font->ft_widths[i]; -> else -> w=font->ft_w; -> // mprintf((0,"char %i(%ix%i): ",i,w,h)); -> if (w<1 || w>256){ -> mprintf((0,"grr\n"));continue; -> } -> if (curx+w+gap>tw){ -> cury+=h+gap; -> curx=0; -> } -> if (cury+h>th) -> Error("font doesn't really fit (%i/%i)?\n",i,nchars); -> if (font->ft_flags & FT_COLOR) { -> if (font->ft_flags & FT_PROPORTIONAL) -> fp = font->ft_chars[i]; -> else -> fp = font->ft_data + i * w*h; -> for (y=0;y for (x=0;x font->ft_parent_bitmap.bm_data[curx+x+(cury+y)*tw]=fp[x+y*w]; -> } -> -> // gr_init_bitmap(&font->ft_bitmaps[i],BM_LINEAR,0,0,w,h,w,font->); -> }else{ -> int BitMask,bits=0,white=gr_find_closest_color(63,63,63); -> // if (w*h>sizeof(data)) -> // Error("ogl_init_font: toobig\n"); -> if (font->ft_flags & FT_PROPORTIONAL) -> fp = font->ft_chars[i]; -> else -> fp = font->ft_data + i * BITS_TO_BYTES(w)*h; -> for (y=0;y BitMask=0; -> for (x=0; x< w; x++ ) -> { -> if (BitMask==0) { -> bits = *fp++; -> BitMask = 0x80; -> } -> -> if (bits & BitMask) -> font->ft_parent_bitmap.bm_data[curx+x+(cury+y)*tw]=white; -> else -> font->ft_parent_bitmap.bm_data[curx+x+(cury+y)*tw]=255; -> BitMask >>= 1; -> } -> } -> } -> gr_init_sub_bitmap(&font->ft_bitmaps[i],&font->ft_parent_bitmap,curx,cury,w,h); -> -> curx+=w+gap; -> } -> if (!(font->ft_flags & FT_COLOR)) { -> //use GL_INTENSITY instead of GL_RGB -> if (ogl_intensity4_ok){ -> font->ft_parent_bitmap.gltexture->internalformat=GL_INTENSITY4; -> font->ft_parent_bitmap.gltexture->format=GL_LUMINANCE; -> }else if (ogl_luminance4_alpha4_ok){ -> font->ft_parent_bitmap.gltexture->internalformat=GL_LUMINANCE4_ALPHA4; -> font->ft_parent_bitmap.gltexture->format=GL_LUMINANCE_ALPHA; -> }else if (ogl_rgba2_ok){ -> font->ft_parent_bitmap.gltexture->internalformat=GL_RGBA2; -> font->ft_parent_bitmap.gltexture->format=GL_RGBA; -> }else{ -> font->ft_parent_bitmap.gltexture->internalformat=ogl_rgba_format; -> font->ft_parent_bitmap.gltexture->format=GL_RGBA; -> } -> } -> ogl_loadbmtexture_m(&font->ft_parent_bitmap,0); -> } -> -> int ogl_internal_string(int x, int y, char *s ) -> { -> ubyte * text_ptr, * next_row, * text_ptr1; -> int width, spacing,letter; -> int xx,yy; -> int orig_color=FG_COLOR;//to allow easy reseting to default string color with colored strings -MPM -> -> next_row = s; -> -> yy = y; -> -> if (grd_curscreen->sc_canvas.cv_bitmap.bm_type != BM_OGL) -> Error("carp.\n"); -> while (next_row != NULL) -> { -> text_ptr1 = next_row; -> next_row = NULL; -> -> text_ptr = text_ptr1; -> -> xx = x; -> -> if (xx==0x8000) //centered -> xx = get_centered_x(text_ptr); -> -> while (*text_ptr) -> { -> if (*text_ptr == '\n' ) -> { -> next_row = &text_ptr[1]; -> yy += FHEIGHT; -> break; -> } -> -> letter = *text_ptr-FMINCHAR; -> -> get_char_width(text_ptr[0],text_ptr[1],&width,&spacing); -> -> if (!INFONT(letter) || *text_ptr<=0x06) { //not in font, draw as space -> CHECK_EMBEDDED_COLORS() else{ -> xx += spacing; -> text_ptr++; -> } -> continue; -> } -> -> // ogl_ubitblt(FONT->ft_bitmaps[letter].bm_w,FONT->ft_bitmaps[letter].bm_h,xx,yy,0,0,&FONT->ft_bitmaps[letter],NULL); -> // if (*text_ptr>='0' && *text_ptr<='9'){ -> printf("%p\n",&FONT->ft_bitmaps[letter]); -> if (FFLAGS&FT_COLOR) -> gr_ubitmapm(xx,yy,&FONT->ft_bitmaps[letter]); -> else{ -> if (grd_curcanv->cv_bitmap.bm_type==BM_OGL) -> ogl_ubitmapm_c(xx,yy,&FONT->ft_bitmaps[letter],FG_COLOR); -> else -> Error("ogl_internal_string: non-color string to non-ogl dest\n"); -> // gr_ubitmapm(xx,yy,&FONT->ft_bitmaps[letter]);//ignores color.. -> } -> //} -> -> xx += spacing; -> -> text_ptr++; -> } -> -> } -> return 0; -> } -> int gr_internal_color_string(int x, int y, char *s ){ -> return ogl_internal_string(x,y,s); -> } -> -> #endif // OGL -> +> #else // OGL +> +> #include "../main/inferno.h" +> #include "ogl_init.h" +> #include "args.h" +> //font handling routines for OpenGL - Added 9/25/99 Matthew Mueller - they are here instead of in arch/ogl because they use all these defines +> +> int pow2ize(int x);//from ogl.c +> +> int get_font_total_width(grs_font * font){ +> if (font->ft_flags & FT_PROPORTIONAL){ +> int i,w=0,c=font->ft_minchar; +> for (i=0;c<=font->ft_maxchar;i++,c++){ +> if (font->ft_widths[i]<0) +> Error("heh?\n"); +> w+=font->ft_widths[i]; +> } +> return w; +> }else{ +> return font->ft_w*(font->ft_maxchar-font->ft_minchar+1); +> } +> } +> void ogl_font_choose_size(grs_font * font,int gap,int *rw,int *rh){ +> int nchars = font->ft_maxchar-font->ft_minchar+1; +> int r,x,y,nc=0,smallest=999999,smallr=-1,tries; +> int smallprop=10000; +> int h,w; +> for (h=32;h<=256;h*=2){ +> // h=pow2ize(font->ft_h*rows+gap*(rows-1)); +> if (font->ft_h>h)continue; +> r=(h/(font->ft_h+gap)); +> w=pow2ize((get_font_total_width(font)+(nchars-r)*gap)/r); +> tries=0; +> do { +> if (tries) +> w=pow2ize(w+1); +> if(tries>3){ +> mprintf((0,"failed to fit (%ix%i, %ic)\n",w,h,nc)); +> break; +> } +> nc=0; +> y=0; +> while(y+font->ft_h<=h){ +> x=0; +> while (x if (nc==nchars) +> break; +> if (font->ft_flags & FT_PROPORTIONAL){ +> if (x+font->ft_widths[nc]+gap>w)break; +> x+=font->ft_widths[nc++]+gap; +> }else{ +> if (x+font->ft_w+gap>w)break; +> x+=font->ft_w+gap; +> nc++; +> } +> } +> if (nc==nchars) +> break; +> y+=font->ft_h+gap; +> } +> +> tries++; +> }while(nc!=nchars); +> if (nc!=nchars) +> continue; +> mprintf((0,"fit: %ix%i %i tries\n",w,h,tries)); +> +> if (w*h==smallest){//this gives squarer sizes priority (ie, 128x128 would be better than 512*32) +> if (w>=h){ +> if (w/h smallprop=w/h; +> smallest++;//hack +> } +> }else{ +> if (h/w smallprop=h/w; +> smallest++;//hack +> } +> } +> } +> if (w*h smallr=1; +> smallest=w*h; +> *rw=w; +> *rh=h; +> } +> } +> if (smallr<=0) +> Error("couldn't fit font?\n"); +> mprintf((0,"using %ix%i\n",*rw,*rh)); +> printf("using %ix%i\n",*rw,*rh); +> +> } +> +> void ogl_init_font(grs_font * font){ +> int nchars = font->ft_maxchar-font->ft_minchar+1; +> int i,w,h,tw,th,x,y,curx=0,cury=0; +> char *fp; +> // char data[32*32*4]; +> char *data; +> int gap=0;//having a gap just wastes ram, since we don't filter text textures at all. +> // char s[2]; +> ogl_font_choose_size(font,gap,&tw,&th); +> data=malloc(tw*th); +> gr_init_bitmap(&font->ft_parent_bitmap,BM_LINEAR,0,0,tw,th,tw,data); +> +> font->ft_parent_bitmap.gltexture=ogl_get_free_texture(); +> +> font->ft_bitmaps=(grs_bitmap*)malloc( nchars * sizeof(grs_bitmap)); +> mprintf((0,"ogl_init_font %s, %s, nchars=%i, (%ix%i tex)\n",(font->ft_flags & FT_PROPORTIONAL)?"proportional":"fixedwidth",(font->ft_flags & FT_COLOR)?"color":"mono",nchars,tw,th)); +> // s[1]=0; +> h=font->ft_h; +> // sleep(5); +> +> for(i=0;i // s[0]=font->ft_minchar+i; +> // gr_get_string_size(s,&w,&h,&aw); +> if (font->ft_flags & FT_PROPORTIONAL) +> w=font->ft_widths[i]; +> else +> w=font->ft_w; +> // mprintf((0,"char %i(%ix%i): ",i,w,h)); +> if (w<1 || w>256){ +> mprintf((0,"grr\n"));continue; +> } +> if (curx+w+gap>tw){ +> cury+=h+gap; +> curx=0; +> } +> if (cury+h>th) +> Error("font doesn't really fit (%i/%i)?\n",i,nchars); +> if (font->ft_flags & FT_COLOR) { +> if (font->ft_flags & FT_PROPORTIONAL) +> fp = font->ft_chars[i]; +> else +> fp = font->ft_data + i * w*h; +> for (y=0;y for (x=0;x font->ft_parent_bitmap.bm_data[curx+x+(cury+y)*tw]=fp[x+y*w]; +> } +> +> // gr_init_bitmap(&font->ft_bitmaps[i],BM_LINEAR,0,0,w,h,w,font->); +> }else{ +> int BitMask,bits=0,white=gr_find_closest_color(63,63,63); +> // if (w*h>sizeof(data)) +> // Error("ogl_init_font: toobig\n"); +> if (font->ft_flags & FT_PROPORTIONAL) +> fp = font->ft_chars[i]; +> else +> fp = font->ft_data + i * BITS_TO_BYTES(w)*h; +> for (y=0;y BitMask=0; +> for (x=0; x< w; x++ ) +> { +> if (BitMask==0) { +> bits = *fp++; +> BitMask = 0x80; +> } +> +> if (bits & BitMask) +> font->ft_parent_bitmap.bm_data[curx+x+(cury+y)*tw]=white; +> else +> font->ft_parent_bitmap.bm_data[curx+x+(cury+y)*tw]=255; +> BitMask >>= 1; +> } +> } +> } +> gr_init_sub_bitmap(&font->ft_bitmaps[i],&font->ft_parent_bitmap,curx,cury,w,h); +> +> curx+=w+gap; +> } +> if (!(font->ft_flags & FT_COLOR)) { +> //use GL_INTENSITY instead of GL_RGB +> if (ogl_intensity4_ok){ +> font->ft_parent_bitmap.gltexture->internalformat=GL_INTENSITY4; +> font->ft_parent_bitmap.gltexture->format=GL_LUMINANCE; +> }else if (ogl_luminance4_alpha4_ok){ +> font->ft_parent_bitmap.gltexture->internalformat=GL_LUMINANCE4_ALPHA4; +> font->ft_parent_bitmap.gltexture->format=GL_LUMINANCE_ALPHA; +> }else if (ogl_rgba2_ok){ +> font->ft_parent_bitmap.gltexture->internalformat=GL_RGBA2; +> font->ft_parent_bitmap.gltexture->format=GL_RGBA; +> }else{ +> font->ft_parent_bitmap.gltexture->internalformat=ogl_rgba_format; +> font->ft_parent_bitmap.gltexture->format=GL_RGBA; +> } +> } +> ogl_loadbmtexture_m(&font->ft_parent_bitmap,0); +> } +> +> int ogl_internal_string(int x, int y, char *s ) +> { +> ubyte * text_ptr, * next_row, * text_ptr1; +> int width, spacing,letter; +> int xx,yy; +> int orig_color=FG_COLOR;//to allow easy reseting to default string color with colored strings -MPM +> +> next_row = s; +> +> yy = y; +> +> if (grd_curscreen->sc_canvas.cv_bitmap.bm_type != BM_OGL) +> Error("carp.\n"); +> while (next_row != NULL) +> { +> text_ptr1 = next_row; +> next_row = NULL; +> +> text_ptr = text_ptr1; +> +> xx = x; +> +> if (xx==0x8000) //centered +> xx = get_centered_x(text_ptr); +> +> while (*text_ptr) +> { +> if (*text_ptr == '\n' ) +> { +> next_row = &text_ptr[1]; +> yy += FHEIGHT; +> break; +> } +> +> letter = *text_ptr-FMINCHAR; +> +> get_char_width(text_ptr[0],text_ptr[1],&width,&spacing); +> +> if (!INFONT(letter) || *text_ptr<=0x06) { //not in font, draw as space +> CHECK_EMBEDDED_COLORS() else{ +> xx += spacing; +> text_ptr++; +> } +> continue; +> } +> +> // ogl_ubitblt(FONT->ft_bitmaps[letter].bm_w,FONT->ft_bitmaps[letter].bm_h,xx,yy,0,0,&FONT->ft_bitmaps[letter],NULL); +> // if (*text_ptr>='0' && *text_ptr<='9'){ +> printf("%p\n",&FONT->ft_bitmaps[letter]); +> if (FFLAGS&FT_COLOR) +> gr_ubitmapm(xx,yy,&FONT->ft_bitmaps[letter]); +> else{ +> if (grd_curcanv->cv_bitmap.bm_type==BM_OGL) +> ogl_ubitmapm_c(xx,yy,&FONT->ft_bitmaps[letter],FG_COLOR); +> else +> Error("ogl_internal_string: non-color string to non-ogl dest\n"); +> // gr_ubitmapm(xx,yy,&FONT->ft_bitmaps[letter]);//ignores color.. +> } +> //} +> +> xx += spacing; +> +> text_ptr++; +> } +> +> } +> return 0; +> } +> int gr_internal_color_string(int x, int y, char *s ){ +> return ogl_internal_string(x,y,s); +> } +> +> #endif // OGL +> 1118a1406 -> #ifdef __ENV_MSDOS__ +> #ifdef __ENV_MSDOS__ 1123a1412 -> #endif +> #endif 1248a1538,1539 -> #define swapshort(a) (a) -> #define swapint(a) (a) +> #define swapshort(a) (a) +> #define swapint(a) (a) 1251a1543 -> old_grs_font *oldfont; +> old_grs_font *oldfont; 1284c1576,1578 -< font = (grs_font *) malloc(datasize); +< font = (grs_font *) malloc(datasize); --- -> oldfont = (old_grs_font *) malloc(datasize); -> font = (grs_font *) malloc(sizeof(grs_font)); -> font->oldfont = oldfont; +> oldfont = (old_grs_font *) malloc(datasize); +> font = (grs_font *) malloc(sizeof(grs_font)); +> font->oldfont = oldfont; 1288c1582,1590 -< cfread(font,1,datasize,fontfile); +< cfread(font,1,datasize,fontfile); --- -> cfread(oldfont,1,datasize,fontfile); -> font->ft_flags=swapshort(oldfont->ft_flags); -> font->ft_w=swapshort(oldfont->ft_w); -> font->ft_h=swapshort(oldfont->ft_h); -> font->ft_baseline=swapshort(oldfont->ft_baseline); -> font->ft_maxchar=oldfont->ft_maxchar; -> font->ft_minchar=oldfont->ft_minchar; -> font->ft_bytewidth=swapshort(oldfont->ft_bytewidth); -> +> cfread(oldfont,1,datasize,fontfile); +> font->ft_flags=swapshort(oldfont->ft_flags); +> font->ft_w=swapshort(oldfont->ft_w); +> font->ft_h=swapshort(oldfont->ft_h); +> font->ft_baseline=swapshort(oldfont->ft_baseline); +> font->ft_maxchar=oldfont->ft_maxchar; +> font->ft_minchar=oldfont->ft_minchar; +> font->ft_bytewidth=swapshort(oldfont->ft_bytewidth); +> 1307c1609 -< font->ft_widths = (short *) (((int) font->ft_widths) + ((ubyte *) font)); +< font->ft_widths = (short *) (((int) font->ft_widths) + ((ubyte *) font)); --- -> font->ft_widths = (short *) (((int) oldfont->ft_widths) + ((ubyte *) oldfont)); +> font->ft_widths = (short *) (((int) oldfont->ft_widths) + ((ubyte *) oldfont)); 1311c1613 -< font->ft_widths[i] = SWAPSHORT(font->ft_widths[i]); +< font->ft_widths[i] = SWAPSHORT(font->ft_widths[i]); --- -> font->ft_widths[i] = swapshort(oldfont->ft_widths[i]); +> font->ft_widths[i] = swapshort(oldfont->ft_widths[i]); 1314c1616 -< font->ft_data = ((int) font->ft_data) + ((ubyte *) font); +< font->ft_data = ((int) font->ft_data) + ((ubyte *) font); --- -> font->ft_data = ((int) oldfont->ft_data) + ((ubyte *) oldfont); +> font->ft_data = ((int) oldfont->ft_data) + ((ubyte *) oldfont); 1330c1632 -< font->ft_data = ((unsigned char *) font) + sizeof(*font); +< font->ft_data = ((unsigned char *) font) + sizeof(*font); --- -> font->ft_data = ((unsigned char *) oldfont) + sizeof(*oldfont); +> font->ft_data = ((unsigned char *) oldfont) + sizeof(*oldfont); 1339c1641 -< font->ft_kerndata = ((int) font->ft_kerndata) + ((ubyte *) font); +< font->ft_kerndata = ((int) font->ft_kerndata) + ((ubyte *) font); --- -> font->ft_kerndata = swapint(((int) oldfont->ft_kerndata) + ((ubyte *) oldfont)); +> font->ft_kerndata = swapint(((int) oldfont->ft_kerndata) + ((ubyte *) oldfont)); 1386a1689,1692 -> -> #ifdef OGL -> ogl_init_font(font); -> #endif +> +> #ifdef OGL +> ogl_init_font(font); +> #endif diff --git a/2d/gpixel.c b/2d/gpixel.c index 736c97a5..d1e0b686 100644 --- a/2d/gpixel.c +++ b/2d/gpixel.c @@ -16,20 +16,20 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #include "gr.h" #include "grdef.h" -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ #include "modex.h" #include "vesa.h" #endif unsigned char gr_ugpixel( grs_bitmap * bitmap, int x, int y ) { -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ switch(bitmap->bm_type) { case BM_LINEAR: #endif return bitmap->bm_data[ bitmap->bm_rowsize*y + x ]; -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ case BM_MODEX: x += bitmap->bm_x; y += bitmap->bm_y; @@ -50,13 +50,13 @@ unsigned char gr_ugpixel( grs_bitmap * bitmap, int x, int y ) unsigned char gr_gpixel( grs_bitmap * bitmap, int x, int y ) { if ((x<0) || (y<0) || (x>=bitmap->bm_w) || (y>=bitmap->bm_h)) return 0; -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ switch(bitmap->bm_type) { case BM_LINEAR: #endif return bitmap->bm_data[ bitmap->bm_rowsize*y + x ]; -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ case BM_MODEX: x += bitmap->bm_x; y += bitmap->bm_y; diff --git a/2d/line.c b/2d/line.c index 3b28ed3f..b9f34f63 100644 --- a/2d/line.c +++ b/2d/line.c @@ -26,7 +26,7 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #include "clip.h" -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ #include "modex.h" #endif #ifdef OGL @@ -279,7 +279,7 @@ int gr_uline(fix _a1, fix _b1, fix _a2, fix _b2) gr_linear_line( a1, b1, a2, b2 ); #endif return 0; -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ case BM_MODEX: modex_line_x1 = a1+XOFFSET; modex_line_y1 = b1+YOFFSET; diff --git a/2d/linear.h b/2d/linear.h index 811f11c6..8f0e9734 100644 --- a/2d/linear.h +++ b/2d/linear.h @@ -291,8 +291,8 @@ static inline void modex_copy_column_m(ubyte * src, ubyte * dest, int num_pixels "addl %%edx, %%edi;" "decl %%ecx;" "jne 0b" - : : "S" (src), "D" (dest), "c" (num_pixels), "b" (src_rowsize), "d" (dest_rowsize) - : "%eax", "%ecx", "%esi", "%edi"); + : "=c" (num_pixels), "=S" (src), "=D" (dest) : "S" (src), "D" (dest), "c" (num_pixels), "b" (src_rowsize), "d" (dest_rowsize) + : "%eax"); } static inline void modex_copy_scanline( ubyte * src, ubyte * dest, int npixels ) { @@ -325,8 +325,8 @@ static inline void modex_copy_scanline( ubyte * src, ubyte * dest, int npixels ) " decl %%ebx;" " jne 2b;" "3:" - : : "S" (src), "D" (dest), "c" (npixels) - : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi"); + : "=c" (npixels), "=S" (src), "=D" (dest): "S" (src), "D" (dest), "c" (npixels) + : "%eax", "%ebx", "%edx"); } static inline void modex_copy_scanline_2x( ubyte * src, ubyte * dest, int npixels ) { @@ -359,8 +359,8 @@ static inline void modex_copy_scanline_2x( ubyte * src, ubyte * dest, int npixel " decl %%ebx;" " jne 2b;" "3:" - : : "S" (src), "D" (dest), "c" (npixels) - : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi"); + : "=c" (npixels), "=S" (src), "=D" (dest): "S" (src), "D" (dest), "c" (npixels) + : "%eax", "%ebx", "%edx"); } #elif defined _MSC_VER diff --git a/2d/pixel.c b/2d/pixel.c index ab5cbf6c..a0c9951b 100644 --- a/2d/pixel.c +++ b/2d/pixel.c @@ -41,7 +41,7 @@ void gr_upixel( int x, int y ) case BM_LINEAR: DATA[ ROWSIZE*y+x ] = COLOR; return; -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ case BM_MODEX: gr_modex_setplane( (x+XOFFSET) & 3 ); gr_video_memory[(ROWSIZE * (y+YOFFSET)) + ((x+XOFFSET)>>2)] = COLOR; @@ -73,7 +73,7 @@ inline void gr_bm_upixel( grs_bitmap * bm, int x, int y, unsigned char color ) case BM_LINEAR: bm->bm_data[ bm->bm_rowsize*y+x ] = color; return; -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ case BM_MODEX: x += bm->bm_x; y += bm->bm_y; diff --git a/README b/README index d78a083e..73c52cc6 100644 --- a/README +++ b/README @@ -1,96 +1,157 @@ -Ok folks, this is the d2x port of descent 2. -At this stage most of descent 2 works under linux: - -Known bugs/unintentional features/missing stuff: -* Serial support doesn't work. (UDP and IPX networking does) -* Movies (unlikely ever to be supported) -* Sound glitches (due to stuff I haven't implemented) -* The mouse support is at the same level as it was in d1x (as in, it kind of works) -* Something went screwy with the control config system, it kinda got "d1xed"... -* OpenGL leaks memory like it is going out of fashion. It leaked about 64meg in a few minutes for me. I need to debug this =) - -Basically, to compile this under linux: -You need the SDL 1.0 or greater, and a thread-safe X server. -Do a ./autogen.sh then a make. Cross your fingers and pray, it worked on my machine. - -For OpenGL support, try building with --with-opengl. Your mileage may vary (but basically, you need an accelerated Mesa sitting somewhere where I can see it)... The OpenGL support isn't perfect, but it works... - -There are two ways to report bugs and give feedback: -1) Get on the descent-source mailing list by sending an email to majordomo@warpcore.org with the body as: "subscribe descent-source ". Discussions about the source code in general are available here, and is the main list that d2x and d1x, a similar project for descent 1 is discussed on. Patches and questions can be posted there, as well. - -2) Send feedback directly to me, peterhawkins@ozemail.com.au. I'll try to get back to you ASAP, depending on real-life concerns =) - - -/* THE OLD README FOLLOWS */ -Legal Stuff: - -THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX -SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO -END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A -ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS -IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS -SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE -FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE -CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS -AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. -COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. - -We make no warranties as to the usability or correctness of this code. - -============================================ -Message from Matt Toschlog & Mike Kulas: - -Descent fans: - -Here, finally, is the source for Descent II. We've been so busy with -Descent 3, Mercenary, FreeSpace, FreeSpace 2, and several other -projects that we haven't given much thought to this old code. But we -know that many of you are eager to get it, so here you go. - -We were amazed and impressed at the cool things people did with -the Descent source we released a few years ago. It touches us -deeply how devoted some people are to the Descent series, and we -look forward to seeing what people can do with this Descent II -source. - -Matt Toschlog Mike Kulas -Outrage Entertainment Volition, Inc. - -============================================ - -About the Source Code: - -Included is almost all the source code to Descent 2, ver. 1.2. We removed -all code to which we did not own the copyright. This mainly involved low- -level sound and modem code and the movie code. - -The Descent Network has agreed to provide a list of mirror locations where -this code can be downloaded. The location is: - -http://www.descent2.com/ddn/sources/descent2 - -The following tools were used in the development of Descent: -Watcom C/C++, version 9.5 -Microsoft Macro Assembler, version 6.1x -Opus Make, version 6.01 - -Have fun with the code! -Parallax Software Corporation -12/14/1999 - - -As Packaged the code currently will not compile. Some code had to be removed -to release it, therefore you will get some missing file errors when building. - -Much of this code is very close to the Descent 1 source code. Many people have -put effort into porting that code, so if you are interested in porting D2, you -should be able to take advantage of some of that work. - -A few good web sites to check out are: - -The D1X Project: -http://d1x.warpcore.org - -The Descent Network: -http://www.descent-network.com - +=========== +D2X +=========== + + +Linux: +====== + +Required tools: +* GCC 2.95 +* SDL 1.0 (get it from http://www.devolution.com/~slouken/projects/SDL/) +* NASM 0.98 (OPTIONAL but RECOMMENDED, not sure, try your linux distribution) +* A thread safe X server. +* Make, sed, etc... + + +Build instructions: +Install all of the components above. Next, from the d2x directory: + +./configure +(./configure --help will show you the available options) +For OpenGL support, try configuring with --with-opengl. Your mileage may vary +(but basically, you need an accelerated Mesa sitting somewhere where d2x cab + see it)... The OpenGL support isn't perfect, but it works... + +make + +Hopefully d2x will build. Do not be concerned about warnings, they are fairly +unimportant. + + +Known bugs/issues: +* Serial support doesn't work. (UDP and IPX networking does) +* Movies (unlikely ever to be supported) +* Sound glitches (due to stuff I haven't implemented) +* The mouse support is at the same level as it was in d1x (as in, it kind of works) +* Something went screwy with the control config system, it kinda got "d1xed"... +* OpenGL leaks memory like it is going out of fashion. It leaked about 64meg in a few minutes for me. I need to debug this =) + + +MS-DOS: +======= + +Required tools: +* DJGPP v2 +The following DJGPP packages are ALL REQUIRED (newer versions are ok)! +v2/ +djdev203.zip +v2gnu/ +bnu281b.zip gcc2952b.zip mak3781b.zip bsh1147b.zip sed302b.zip +m4-14b.zip acnf213b.zip gwk304b.zip txt20b.zip grep22b.zip dif272b.zip +So many packages are needed to support the autoconf build system that d2x +uses. (Sorry! =) +* NASM v0.98 or better is REQUIRED + + +Build instructions: +Install all of the djgpp packages above. Make sure that DJGPP is properly +configure (see the DJGPP docs for more information). +Make a copy of bash.exe in your djgpp bin/ directory. Call it "sh.exe". This +step is VERY IMPORTANT (otherwise all the scripts will fail). + +Now, run the following from the d2x directory: +djgpp.bat +make + +Hopefully things will work out and the package will build correctly for you. + +Known bugs/issues: +* Serial and network support missing. +* Sound support missing. +* Movie support missing + + + +Reporting bugs/feedback: +======================== + +There are two ways to report bugs and give feedback: +1) Get on the descent-source mailing list by sending an email to majordomo@warpcore.org with the body as: "subscribe descent-source ". Discussions about the source code in general are available here, and is the main list that d2x and d1x, a similar project for descent 1 is discussed on. Patches and questions can be posted there, as well. + +2) Send feedback directly to me, peterhawkins@ozemail.com.au. I'll try to get back to you ASAP, depending on real-life concerns =) + + +/* THE OLD README FOLLOWS */ +Legal Stuff: + +THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. + +We make no warranties as to the usability or correctness of this code. + +============================================ +Message from Matt Toschlog & Mike Kulas: + +Descent fans: + +Here, finally, is the source for Descent II. We've been so busy with +Descent 3, Mercenary, FreeSpace, FreeSpace 2, and several other +projects that we haven't given much thought to this old code. But we +know that many of you are eager to get it, so here you go. + +We were amazed and impressed at the cool things people did with +the Descent source we released a few years ago. It touches us +deeply how devoted some people are to the Descent series, and we +look forward to seeing what people can do with this Descent II +source. + +Matt Toschlog Mike Kulas +Outrage Entertainment Volition, Inc. + +============================================ + +About the Source Code: + +Included is almost all the source code to Descent 2, ver. 1.2. We removed +all code to which we did not own the copyright. This mainly involved low- +level sound and modem code and the movie code. + +The Descent Network has agreed to provide a list of mirror locations where +this code can be downloaded. The location is: + +http://www.descent2.com/ddn/sources/descent2 + +The following tools were used in the development of Descent: +Watcom C/C++, version 9.5 +Microsoft Macro Assembler, version 6.1x +Opus Make, version 6.01 + +Have fun with the code! +Parallax Software Corporation +12/14/1999 + + +As Packaged the code currently will not compile. Some code had to be removed +to release it, therefore you will get some missing file errors when building. + +Much of this code is very close to the Descent 1 source code. Many people have +put effort into porting that code, so if you are interested in porting D2, you +should be able to take advantage of some of that work. + +A few good web sites to check out are: + +The D1X Project: +http://d1x.warpcore.org + +The Descent Network: +http://www.descent-network.com + diff --git a/arch/Makefile.am b/arch/Makefile.am index 4f88f13a..8c4c8992 100644 --- a/arch/Makefile.am +++ b/arch/Makefile.am @@ -1,5 +1,20 @@ -SUBDIRS = linux sdl noinst_LIBRARIES = libarch.a +INCLUDES = -I $(top_srcdir)/includes -I $(top_srcdir)/main -libarch_a_SOURCES = -libarch_a_LIBADD = sdl/init.o sdl/timer.o linux/ipx_bsd.o linux/ipx_lin.o linux/ipx_udp.o linux/linuxnet.o linux/init.o linux/findfile.o +libarch_a_SOURCES = \ +dos_init.c dos_vesa.c dos_findfile.c dos_dpmi.c dos_ipx.c \ +linux_init.c linux_findfile.c linux_net.c linux_ipx_bsd.c \ +linux_ipx_lin.c linux_ipx_udp.c \ +sdl_init.c sdl_timer.c + + + +if ENV_DJGPP + SUFFIXES = .asm + %.o: %.asm + $(NASM) $(NASMFLAGS) $< -o $@ + + libarch_a_SOURCES += dos_timer.asm dos_modex.asm + libarch_a_LIBADD += dos_timer.o dos_modex.o + dos_init.c: dos_timer.o dos_modex.o +endif diff --git a/arch/Makefile.in b/arch/Makefile.in index 7398866b..367b0023 100644 --- a/arch/Makefile.in +++ b/arch/Makefile.in @@ -68,11 +68,11 @@ RANLIB = @RANLIB@ SDL_LIBS = @SDL_LIBS@ VERSION = @VERSION@ -SUBDIRS = linux sdl noinst_LIBRARIES = libarch.a +INCLUDES = -I $(top_srcdir)/includes -I $(top_srcdir)/main + +libarch_a_SOURCES = dos_init.c dos_vesa.c dos_findfile.c dos_dpmi.c dos_ipx.c linux_init.c linux_findfile.c linux_net.c linux_ipx_bsd.c linux_ipx_lin.c linux_ipx_udp.c sdl_init.c sdl_timer.c -libarch_a_SOURCES = -libarch_a_LIBADD = sdl/init.o sdl/timer.o linux/ipx_bsd.o linux/ipx_lin.o linux/ipx_udp.o linux/linuxnet.o linux/init.o linux/findfile.o mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../conf.h CONFIG_CLEAN_FILES = @@ -83,11 +83,14 @@ DEFS = @DEFS@ -I. -I$(srcdir) -I.. CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ -libarch_a_DEPENDENCIES = sdl/init.o sdl/timer.o linux/ipx_bsd.o \ -linux/ipx_lin.o linux/ipx_udp.o linux/linuxnet.o linux/init.o \ -linux/findfile.o -libarch_a_OBJECTS = +libarch_a_LIBADD = +libarch_a_OBJECTS = dos_init.o dos_vesa.o dos_findfile.o dos_dpmi.o \ +dos_ipx.o linux_init.o linux_findfile.o linux_net.o linux_ipx_bsd.o \ +linux_ipx_lin.o linux_ipx_udp.o sdl_init.o sdl_timer.o AR = ar +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ DIST_COMMON = Makefile.am Makefile.in @@ -95,6 +98,11 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP_ENV = --best +DEP_FILES = .deps/dos_dpmi.P .deps/dos_findfile.P .deps/dos_init.P \ +.deps/dos_ipx.P .deps/dos_vesa.P .deps/linux_findfile.P \ +.deps/linux_init.P .deps/linux_ipx_bsd.P .deps/linux_ipx_lin.P \ +.deps/linux_ipx_udp.P .deps/linux_net.P .deps/sdl_init.P \ +.deps/sdl_timer.P SOURCES = $(libarch_a_SOURCES) OBJECTS = $(libarch_a_OBJECTS) @@ -139,61 +147,6 @@ libarch.a: $(libarch_a_OBJECTS) $(libarch_a_DEPENDENCIES) $(AR) cru libarch.a $(libarch_a_OBJECTS) $(libarch_a_LIBADD) $(RANLIB) libarch.a -# This directory's subdirectories are mostly independent; you can cd -# into them and run `make' without going through this Makefile. -# To change the values of `make' variables: instead of editing Makefiles, -# (1) if the variable is set in `config.status', edit `config.status' -# (which will cause the Makefiles to be regenerated when you run `make'); -# (2) otherwise, pass the desired values on the `make' command line. - -@SET_MAKE@ - -all-recursive install-data-recursive install-exec-recursive \ -installdirs-recursive install-recursive uninstall-recursive \ -check-recursive installcheck-recursive info-recursive dvi-recursive: - @set fnord $(MAKEFLAGS); amf=$$2; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ - fi; test -z "$$fail" - -mostlyclean-recursive clean-recursive distclean-recursive \ -maintainer-clean-recursive: - @set fnord $(MAKEFLAGS); amf=$$2; \ - dot_seen=no; \ - rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ - rev="$$subdir $$rev"; \ - test "$$subdir" = "." && dot_seen=yes; \ - done; \ - test "$$dot_seen" = "no" && rev=". $$rev"; \ - target=`echo $@ | sed s/-recursive//`; \ - for subdir in $$rev; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ - done && test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done - tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) @@ -204,14 +157,9 @@ ID: $(HEADERS) $(SOURCES) $(LISP) here=`pwd` && cd $(srcdir) \ && mkid -f$$here/ID $$unique $(LISP) -TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) tags=; \ here=`pwd`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ - fi; \ - done; \ list='$(SOURCES) $(HEADERS)'; \ unique=`for i in $$list; do echo $$i; done | \ awk ' { files[$$0] = 1; } \ @@ -248,41 +196,62 @@ distdir: $(DISTFILES) || cp -p $$d/$$file $(distdir)/$$file || :; \ fi; \ done - for subdir in $(SUBDIRS); do \ - if test "$$subdir" = .; then :; else \ - test -d $(distdir)/$$subdir \ - || mkdir $(distdir)/$$subdir \ - || exit 1; \ - chmod 777 $(distdir)/$$subdir; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \ - || exit 1; \ - fi; \ - done + +DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) + +-include $(DEP_FILES) + +mostlyclean-depend: + +clean-depend: + +distclean-depend: + -rm -rf .deps + +maintainer-clean-depend: + +%.o: %.c + @echo '$(COMPILE) -c $<'; \ + $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-cp .deps/$(*F).pp .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm .deps/$(*F).pp + +%.lo: %.c + @echo '$(LTCOMPILE) -c $<'; \ + $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ + < .deps/$(*F).pp > .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm -f .deps/$(*F).pp info-am: -info: info-recursive +info: info-am dvi-am: -dvi: dvi-recursive +dvi: dvi-am check-am: all-am -check: check-recursive +check: check-am installcheck-am: -installcheck: installcheck-recursive +installcheck: installcheck-am install-exec-am: -install-exec: install-exec-recursive +install-exec: install-exec-am install-data-am: -install-data: install-data-recursive +install-data: install-data-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -install: install-recursive +install: install-am uninstall-am: -uninstall: uninstall-recursive +uninstall: uninstall-am all-am: Makefile $(LIBRARIES) -all-redirect: all-recursive +all-redirect: all-am install-strip: $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install -installdirs: installdirs-recursive -installdirs-am: +installdirs: mostlyclean-generic: @@ -295,45 +264,51 @@ distclean-generic: maintainer-clean-generic: mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \ - mostlyclean-tags mostlyclean-generic + mostlyclean-tags mostlyclean-depend mostlyclean-generic -mostlyclean: mostlyclean-recursive +mostlyclean: mostlyclean-am -clean-am: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \ - mostlyclean-am +clean-am: clean-noinstLIBRARIES clean-compile clean-tags clean-depend \ + clean-generic mostlyclean-am -clean: clean-recursive +clean: clean-am distclean-am: distclean-noinstLIBRARIES distclean-compile \ - distclean-tags distclean-generic clean-am + distclean-tags distclean-depend distclean-generic \ + clean-am -distclean: distclean-recursive +distclean: distclean-am maintainer-clean-am: maintainer-clean-noinstLIBRARIES \ maintainer-clean-compile maintainer-clean-tags \ - maintainer-clean-generic distclean-am + maintainer-clean-depend maintainer-clean-generic \ + distclean-am @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." -maintainer-clean: maintainer-clean-recursive +maintainer-clean: maintainer-clean-am .PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \ clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \ mostlyclean-compile distclean-compile clean-compile \ -maintainer-clean-compile install-data-recursive \ -uninstall-data-recursive install-exec-recursive \ -uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \ -all-recursive check-recursive installcheck-recursive info-recursive \ -dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \ -maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ -distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ +maintainer-clean-compile tags mostlyclean-tags distclean-tags \ +clean-tags maintainer-clean-tags distdir mostlyclean-depend \ +distclean-depend clean-depend maintainer-clean-depend info-am info \ dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ install-exec install-data-am install-data install-am install \ -uninstall-am uninstall all-redirect all-am all installdirs-am \ -installdirs mostlyclean-generic distclean-generic clean-generic \ +uninstall-am uninstall all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean +@ENV_DJGPP_TRUE@ SUFFIXES = .asm +@ENV_DJGPP_TRUE@ %.o: %.asm +@ENV_DJGPP_TRUE@ $(NASM) $(NASMFLAGS) $< -o $@ + +@ENV_DJGPP_TRUE@ libarch_a_SOURCES += dos_timer.asm dos_modex.asm +@ENV_DJGPP_TRUE@ libarch_a_LIBADD += dos_timer.o dos_modex.o +@ENV_DJGPP_TRUE@ dos_init.c: dos_timer.o dos_modex.o + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/arch/dos/Makefile.am b/arch/dos/Makefile.am new file mode 100644 index 00000000..80b046e4 --- /dev/null +++ b/arch/dos/Makefile.am @@ -0,0 +1,20 @@ +if ENV_DJGPP + +noinst_LIBRARIES = libarchdos.a +INCLUDES = -I $(top_srcdir)/includes -Iinclude -I $(top_srcdir)/main -I$(top_srcdir)/input/sdl/include + +libarchdos_a_SOURCES = init.c dpmi.c findfile.c vesa.c + + +if USE_ASM + SUFFIXES = .asm + %.o: %.asm + $(NASM) $(NASMFLAGS) $< -o $@ + + libarchdos_a_SOURCES += timer.asm modex.asm + libarchdos_a_LIBADD += timer.o modex.o + init.c: timer.o modex.o +endif + + +endif diff --git a/arch/dos/Makefile.in b/arch/dos/Makefile.in new file mode 100644 index 00000000..785002a9 --- /dev/null +++ b/arch/dos/Makefile.in @@ -0,0 +1,307 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = ../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +CC = @CC@ +CFLAGS = @CFLAGS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +NASM = @NASM@ +NASMFLAGS = @NASMFLAGS@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +SDL_LIBS = @SDL_LIBS@ +VERSION = @VERSION@ + +@ENV_DJGPP_TRUE@noinst_LIBRARIES = libarchdos.a +@ENV_DJGPP_TRUE@INCLUDES = -I $(top_srcdir)/includes -Iinclude -I $(top_srcdir)/main -I$(top_srcdir)/input/sdl/include + +@ENV_DJGPP_TRUE@libarchdos_a_SOURCES = init.c dpmi.c findfile.c vesa.c +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../../conf.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I../.. +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +libarchdos_a_LIBADD = +@ENV_DJGPP_TRUE@libarchdos_a_OBJECTS = init.o dpmi.o findfile.o vesa.o +AR = ar +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +DEP_FILES = .deps/dpmi.P .deps/findfile.P .deps/init.P .deps/vesa.P +SOURCES = $(libarchdos_a_SOURCES) +OBJECTS = $(libarchdos_a_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .o .s +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu arch/dos/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-noinstLIBRARIES: + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +distclean-noinstLIBRARIES: + +maintainer-clean-noinstLIBRARIES: + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +libarchdos.a: $(libarchdos_a_OBJECTS) $(libarchdos_a_DEPENDENCIES) + -rm -f libarchdos.a + $(AR) cru libarchdos.a $(libarchdos_a_OBJECTS) $(libarchdos_a_LIBADD) + $(RANLIB) libarchdos.a + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = arch/dos + +distdir: $(DISTFILES) + here=`cd $(top_builddir) && pwd`; \ + top_distdir=`cd $(top_distdir) && pwd`; \ + distdir=`cd $(distdir) && pwd`; \ + cd $(top_srcdir) \ + && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu arch/dos/Makefile + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + +DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) + +-include $(DEP_FILES) + +mostlyclean-depend: + +clean-depend: + +distclean-depend: + -rm -rf .deps + +maintainer-clean-depend: + +%.o: %.c + @echo '$(COMPILE) -c $<'; \ + $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-cp .deps/$(*F).pp .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm .deps/$(*F).pp + +%.lo: %.c + @echo '$(LTCOMPILE) -c $<'; \ + $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ + < .deps/$(*F).pp > .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm -f .deps/$(*F).pp +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: +uninstall: uninstall-am +all-am: Makefile $(LIBRARIES) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \ + mostlyclean-tags mostlyclean-depend mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-noinstLIBRARIES clean-compile clean-tags clean-depend \ + clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-noinstLIBRARIES distclean-compile \ + distclean-tags distclean-depend distclean-generic \ + clean-am + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-noinstLIBRARIES \ + maintainer-clean-compile maintainer-clean-tags \ + maintainer-clean-depend maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \ +clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile tags mostlyclean-tags distclean-tags \ +clean-tags maintainer-clean-tags distdir mostlyclean-depend \ +distclean-depend clean-depend maintainer-clean-depend info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ +install-exec install-data-am install-data install-am install \ +uninstall-am uninstall all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +@ENV_DJGPP_TRUE@@USE_ASM_TRUE@ SUFFIXES = .asm +@ENV_DJGPP_TRUE@@USE_ASM_TRUE@ %.o: %.asm +@ENV_DJGPP_TRUE@@USE_ASM_TRUE@ $(NASM) $(NASMFLAGS) $< -o $@ + +@ENV_DJGPP_TRUE@@USE_ASM_TRUE@ libarchdos_a_SOURCES += timer.asm modex.asm +@ENV_DJGPP_TRUE@@USE_ASM_TRUE@ libarchdos_a_LIBADD += timer.o modex.o +@ENV_DJGPP_TRUE@@USE_ASM_TRUE@ init.c: timer.o modex.o + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/arch/dos/cdrom.c b/arch/dos/cdrom.c new file mode 100644 index 00000000..7d92839a --- /dev/null +++ b/arch/dos/cdrom.c @@ -0,0 +1,77 @@ +/* DPH: This is the file where all the stub functions go. The aim is to have nothing in here ,eventually */ +#include +#include +#include +#include "pstypes.h" +#include "error.h" +#include "args.h" + + +extern int Redbook_playing; +static int initialised = 0; + +void RBAExit() +{ +} + +void RBAInit() +{ + +} + +int RBAEnabled() +{ + return 1; +} + +void RBARegisterCD() +{ + +} + +int RBAPlayTrack(int a) +{ +return 0; +} + +void RBAStop() +{ +} + +void RBASetVolume(int a) +{ + +} + +void RBAPause() +{ +} + +void RBAResume() +{ +} + +int RBAGetNumberOfTracks() +{ +return 0; +} + +int RBAPlayTracks(int tracknum,int something) +{ +return -1; +} + +int RBAGetTrackNum() +{ +return -1; +} + +int RBAPeekPlayStatus() +{ + return -1; +} + +int CD_blast_mixer() +{ + return 0; +} diff --git a/arch/dos/digi.c b/arch/dos/digi.c new file mode 100644 index 00000000..d224d970 --- /dev/null +++ b/arch/dos/digi.c @@ -0,0 +1,810 @@ +// SDL digital audio support + +#include +#include +#include +#include + +#include "pstypes.h" +#include "error.h" +#include "mono.h" +#include "fix.h" +#include "vecmat.h" +#include "gr.h" // needed for piggy.h +#include "piggy.h" +#include "digi.h" +#include "sounds.h" +#include "wall.h" +#include "newdemo.h" +#include "kconfig.h" + +int digi_sample_rate=11025; +int digi_timer_rate = 9943; // rate for the timer to go off to handle the driver system (120 Hz) + +//edited 05/17/99 Matt Mueller - added ifndef NO_ASM +//added on 980905 by adb to add inline fixmul for mixer on i386 +#ifndef NO_ASM +#ifdef __i386__ +#define do_fixmul(x,y) \ +({ \ + int _ax, _dx; \ + asm("imull %2\n\tshrdl %3,%1,%0" \ + : "=a"(_ax), "=d"(_dx) \ + : "rm"(y), "i"(16), "0"(x)); \ + _ax; \ +}) +extern inline fix fixmul(fix x, fix y) { return do_fixmul(x,y); } +#endif +#endif +//end edit by adb +//end edit -MM + +//changed on 980905 by adb to increase number of concurrent sounds +#define MAX_SOUND_SLOTS 32 +//end changes by adb +#define SOUND_BUFFER_SIZE 512 + +#define MIN_VOLUME 10 + +/* This table is used to add two sound values together and pin + * the value to avoid overflow. (used with permission from ARDI) + * DPH: Taken from SDL/src/SDL_mixer.c. + */ +static const unsigned char mix8[] = +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, + 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, + 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, + 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, + 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, + 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, + 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, + 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, + 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, + 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, + 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, + 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, + 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, + 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, + 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, + 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; + +#define SOF_USED 1 // Set if this sample is used +#define SOF_PLAYING 2 // Set if this sample is playing on a channel +#define SOF_LINK_TO_OBJ 4 // Sound is linked to a moving object. If object dies, then finishes play and quits. +#define SOF_LINK_TO_POS 8 // Sound is linked to segment, pos +#define SOF_PLAY_FOREVER 16 // Play forever (or until level is stopped), otherwise plays once + +typedef struct sound_object { + short signature; // A unique signature to this sound + ubyte flags; // Used to tell if this slot is used and/or currently playing, and how long. + fix max_volume; // Max volume that this sound is playing at + fix max_distance; // The max distance that this sound can be heard at... + int volume; // Volume that this sound is playing at + int pan; // Pan value that this sound is playing at + int handle; // What handle this sound is playing on. Valid only if SOF_PLAYING is set. + short soundnum; // The sound number that is playing + union { + struct { + short segnum; // Used if SOF_LINK_TO_POS field is used + short sidenum; + vms_vector position; + }pos; + struct { + short objnum; // Used if SOF_LINK_TO_OBJ field is used + short objsignature; + }obj; + }link; +} sound_object; +#define lp_segnum link.pos.segnum +#define lp_sidenum link.pos.sidenum +#define lp_position link.pos.position + +#define lo_objnum link.obj.objnum +#define lo_objsignature link.obj.objsignature + +#define MAX_SOUND_OBJECTS 16 +sound_object SoundObjects[MAX_SOUND_OBJECTS]; +short next_signature=0; + +//added/changed on 980905 by adb to make sfx volume work, on 990221 by adb changed F1_0 to F1_0 / 2 +#define SOUND_MAX_VOLUME (F1_0 / 2) + +int digi_volume = SOUND_MAX_VOLUME; +//end edit by adb + +int digi_lomem = 0; + +static int digi_initialised = 0; + +struct sound_slot { + int soundno; + int playing; // Is there a sample playing on this channel? + int looped; // Play this sample looped? + fix pan; // 0 = far left, 1 = far right + fix volume; // 0 = nothing, 1 = fully on + //changed on 980905 by adb from char * to unsigned char * + unsigned char *samples; + //end changes by adb + unsigned int length; // Length of the sample + unsigned int position; // Position we are at at the moment. +} SoundSlots[MAX_SOUND_SLOTS]; + +static int digi_sounds_initialized = 0; + +//added on 980905 by adb to add rotating/volume based sound kill system +static int digi_max_channels = 16; +static int next_handle = 0; +int SampleHandles[32]; +void reset_sounds_on_channel(int channel); +//end edit by adb + +void digi_reset_digi_sounds(void); + +/* Audio mixing callback */ +//changed on 980905 by adb to cleanup, add pan support and optimize mixer +static void audio_mixcallback(void *userdata, unsigned char *stream, int len) +{ + unsigned char *streamend = stream + len; + struct sound_slot *sl; + + for (sl = SoundSlots; sl < SoundSlots + MAX_SOUND_SLOTS; sl++) + { + if (sl->playing) + { + unsigned char *sldata = sl->samples + sl->position, *slend = sl->samples + sl->length; + unsigned char *sp = stream; + signed char v; + fix vl, vr; + int x; + + if ((x = sl->pan) & 0x8000) + { + vl = 0x20000 - x * 2; + vr = 0x10000; + } + else + { + vl = 0x10000; + vr = x * 2; + } + vl = fixmul(vl, (x = sl->volume)); + vr = fixmul(vr, x); + while (sp < streamend) + { + if (sldata == slend) + { + if (!sl->looped) + { + sl->playing = 0; + break; + } + sldata = sl->samples; + } + v = *(sldata++) - 0x80; + *(sp++) = mix8[ *sp + fixmul(v, vl) + 0x80 ]; + *(sp++) = mix8[ *sp + fixmul(v, vr) + 0x80 ]; + } + sl->position = sldata - sl->samples; + } + } +} +//end changes by adb + +/* Initialise audio devices. */ +int digi_init() +{ + + return 1; +} + +/* Toggle audio */ +void digi_reset() { } + +/* Shut down audio */ +void digi_close() +{ + if (!digi_initialised) return; + digi_initialised = 0; +} + +/* Find the sound which actually equates to a sound number */ +int digi_xlat_sound(int soundno) +{ + if ( soundno < 0 ) return -1; + + if ( digi_lomem ) { + soundno = AltSounds[soundno]; + if ( soundno == 255 ) return -1; + } + return Sounds[soundno]; +} + +static int get_free_slot() +{ + int i; + for (i=0; i= 0) && (SoundSlots[SampleHandles[next_handle]].playing) ) + { + if ( (SoundSlots[SampleHandles[next_handle]].volume > digi_volume) && (ntries= digi_max_channels ) + next_handle = 0; + ntries++; + goto TryNextChannel; + } + //mprintf(( 0, "[SS:%d]", next_handle )); + SoundSlots[SampleHandles[next_handle]].playing = 0; + SampleHandles[next_handle] = -1; + } + //end edit by adb + + slot = get_free_slot(); + if (slot<0) return -1; + + SoundSlots[slot].soundno = soundnum; + SoundSlots[slot].samples = GameSounds[soundnum].data; + SoundSlots[slot].length = GameSounds[soundnum].length; + SoundSlots[slot].volume = fixmul(digi_volume, volume); + SoundSlots[slot].pan = pan; + SoundSlots[slot].position = 0; + SoundSlots[slot].looped = 0; + SoundSlots[slot].playing = 1; + + //added on 980905 by adb to add sound kill system from original sos digi.c + reset_sounds_on_channel(slot); + SampleHandles[next_handle] = slot; + next_handle++; + if ( next_handle >= digi_max_channels ) + next_handle = 0; + //end edit by adb + + return slot; +} + + //added on 980905 by adb to add sound kill system from original sos digi.c +void reset_sounds_on_channel( int channel ) +{ + int i; + + for (i=0; i -1 ) { + *volume = max_volume - fixdiv(path_distance,max_distance); + //mprintf( (0, "Sound path distance %.2f, volume is %d / %d\n", f2fl(distance), *volume, max_volume )); + if (*volume > 0 ) { + angle_from_ear = vm_vec_delta_ang_norm(&listener->rvec,&vector_to_sound,&listener->uvec); + fix_sincos(angle_from_ear,&sinang,&cosang); + //mprintf( (0, "volume is %.2f\n", f2fl(*volume) )); + if (Config_channels_reversed) cosang *= -1; + *pan = (cosang + F1_0)/2; + } else { + *volume = 0; + } + } + } +} + +int digi_link_sound_to_object2( int org_soundnum, short objnum, int forever, fix max_volume, fix max_distance ) +{ + int i,volume,pan; + object * objp; + int soundnum; + + soundnum = digi_xlat_sound(org_soundnum); + + if ( max_volume < 0 ) return -1; +// if ( max_volume > F1_0 ) max_volume = F1_0; + + if (!digi_initialised) return -1; + if (soundnum < 0 ) return -1; + if (GameSounds[soundnum].data==NULL) { + Int3(); + return -1; + } + if ((objnum<0)||(objnum>Highest_object_index)) + return -1; + + if ( !forever ) { + // Hack to keep sounds from building up... + digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, &Objects[objnum].pos, Objects[objnum].segnum, max_volume,&volume, &pan, max_distance ); + digi_play_sample_3d( org_soundnum, pan, volume, 0 ); + return -1; + } + + for (i=0; iorient, &Viewer->pos, Viewer->segnum, + &objp->pos, objp->segnum, SoundObjects[i].max_volume, + &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); + + if (!forever || SoundObjects[i].volume >= MIN_VOLUME) + digi_start_sound_object(i); + + return SoundObjects[i].signature; +} + +int digi_link_sound_to_object( int soundnum, short objnum, int forever, fix max_volume ) +{ return digi_link_sound_to_object2( soundnum, objnum, forever, max_volume, 256*F1_0); } + +int digi_link_sound_to_pos2( int org_soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume, fix max_distance ) +{ + int i, volume, pan; + int soundnum; + + soundnum = digi_xlat_sound(org_soundnum); + + if ( max_volume < 0 ) return -1; +// if ( max_volume > F1_0 ) max_volume = F1_0; + + if (!digi_initialised) return -1; + if (soundnum < 0 ) return -1; + if (GameSounds[soundnum].data==NULL) { + Int3(); + return -1; + } + + if ((segnum<0)||(segnum>Highest_segment_index)) + return -1; + + if ( !forever ) { + // Hack to keep sounds from building up... + digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, pos, segnum, max_volume, &volume, &pan, max_distance ); + digi_play_sample_3d( org_soundnum, pan, volume, 0 ); + return -1; + } + + for (i=0; iorient, &Viewer->pos, Viewer->segnum, + &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum, + SoundObjects[i].max_volume, + &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); + + if (!forever || SoundObjects[i].volume >= MIN_VOLUME) + digi_start_sound_object(i); + + return SoundObjects[i].signature; +} + +int digi_link_sound_to_pos( int soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume ) +{ + return digi_link_sound_to_pos2( soundnum, segnum, sidenum, pos, forever, max_volume, F1_0 * 256 ); +} + +void digi_kill_sound_linked_to_segment( int segnum, int sidenum, int soundnum ) +{ + int i,killed; + + soundnum = digi_xlat_sound(soundnum); + + if (!digi_initialised) return; + + killed = 0; + + for (i=0; i 1 ) { + mprintf( (1, "ERROR: More than 1 sounds were deleted from seg %d\n", segnum )); + } +} + +void digi_kill_sound_linked_to_object( int objnum ) +{ + int i,killed; + + if (!digi_initialised) return; + + killed = 0; + + for (i=0; i 1 ) { + mprintf( (1, "ERROR: More than 1 sounds were deleted from object %d\n", objnum )); + } +} + +void digi_sync_sounds() +{ + int i; + int oldvolume, oldpan; + + if (!digi_initialised) return; + + for (i=0; iorient, &Viewer->pos, Viewer->segnum, + &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum, + SoundObjects[i].max_volume, + &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); + + } else if ( SoundObjects[i].flags & SOF_LINK_TO_OBJ ) { + object * objp; + + objp = &Objects[SoundObjects[i].lo_objnum]; + + if ((objp->type==OBJ_NONE) || (objp->signature!=SoundObjects[i].lo_objsignature)) { + // The object that this is linked to is dead, so just end this sound if it is looping. + if ( (SoundObjects[i].flags & SOF_PLAYING) && (SoundObjects[i].flags & SOF_PLAY_FOREVER)) { + SoundSlots[SoundObjects[i].handle].playing = 0; + } + SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound + continue; // Go on to next sound... + } else { + digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, + &objp->pos, objp->segnum, SoundObjects[i].max_volume, + &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); + } + } + + if (oldvolume != SoundObjects[i].volume) { + if ( SoundObjects[i].volume < MIN_VOLUME ) { + // Sound is too far away, so stop it from playing. + if ((SoundObjects[i].flags & SOF_PLAYING)&&(SoundObjects[i].flags & SOF_PLAY_FOREVER)) { + SoundSlots[SoundObjects[i].handle].playing = 0; + SoundObjects[i].flags &= ~SOF_PLAYING; // Mark sound as not playing + } + } else { + if (!(SoundObjects[i].flags & SOF_PLAYING)) { + digi_start_sound_object(i); + } else { + SoundSlots[SoundObjects[i].handle].volume = fixmuldiv(SoundObjects[i].volume,digi_volume,F1_0); + } + } + } + + if (oldpan != SoundObjects[i].pan) { + if (SoundObjects[i].flags & SOF_PLAYING) + SoundSlots[SoundObjects[i].handle].pan = SoundObjects[i].pan; + } + } + } +} + +void digi_init_sounds() +{ + int i; + + if (!digi_initialised) return; + + digi_reset_digi_sounds(); + + for (i=0; i SOUND_MAX_VOLUME ) + digi_volume = SOUND_MAX_VOLUME; + else if ( dvolume < 0 ) + digi_volume = 0; + else + digi_volume = dvolume; + + if ( !digi_initialised ) return; + + digi_sync_sounds(); +} +//end edit by adb + +void digi_set_volume( int dvolume, int mvolume ) { } + +int digi_is_sound_playing(int soundno) +{ + int i; + + soundno = digi_xlat_sound(soundno); + + for (i = 0; i < MAX_SOUND_SLOTS; i++) + //changed on 980905 by adb: added SoundSlots[i].playing && + if (SoundSlots[i].playing && SoundSlots[i].soundno == soundno) + //end changes by adb + return 1; + return 0; +} + + +void digi_pause_all() { } +void digi_resume_all() { } +void digi_stop_all() { } + + //added on 980905 by adb to make sound channel setting work +void digi_set_max_channels(int n) { + digi_max_channels = n; + + if ( digi_max_channels < 1 ) + digi_max_channels = 1; + if ( digi_max_channels > (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS) ) + digi_max_channels = (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS); + + if ( !digi_initialised ) return; + + digi_reset_digi_sounds(); +} + +int digi_get_max_channels() { + return digi_max_channels; +} +// end edit by adb + +void digi_reset_digi_sounds() { + int i; + + for (i=0; i< MAX_SOUND_SLOTS; i++) + SoundSlots[i].playing=0; + + //added on 980905 by adb to reset sound kill system + memset(SampleHandles, 255, sizeof(SampleHandles)); + next_handle = 0; + //end edit by adb +} + + +// MIDI stuff follows. +//added/killed on 11/25/98 by Matthew Mueller +//void digi_set_midi_volume( int mvolume ) { } +//void digi_play_midi_song( char * filename, char * melodic_bank, char * drum_bank, int loop ) {} +//void digi_stop_current_song() +//{ +//#ifdef HMIPLAY +// char buf[10]; +// +// sprintf(buf,"s"); +// send_ipc(buf); +//#endif +//} +//end this section kill - MM diff --git a/arch/dos/disk.c b/arch/dos/disk.c index 13088eb6..0d18ecf8 100644 --- a/arch/dos/disk.c +++ b/arch/dos/disk.c @@ -1,6 +1,7 @@ +#include #include #include -#include "types.h" +#include "pstypes.h" #include "error.h" unsigned long getdiskfree() { diff --git a/arch/dos/dosgr.c b/arch/dos/dosgr.c index 3d7fec02..24724d68 100644 --- a/arch/dos/dosgr.c +++ b/arch/dos/dosgr.c @@ -1,5 +1,7 @@ // Graphics functions for DOS. +#include + #include #include #include @@ -15,8 +17,6 @@ #include "modex.h" #include "error.h" -#include "gamefont.h" - #ifdef __DJGPP__ #include #endif @@ -52,6 +52,7 @@ typedef struct screen_save { screen_save gr_saved_screen; int gr_show_screen_info = 0; +extern int VGA_current_mode; void gr_set_cellheight( ubyte height ) { @@ -244,8 +245,8 @@ int isvga() regs.w.ax = 0x1a00; int386( 0x10, ®s, ®s ); - if ( regs.h.al == 0x1a ) - return 1; + if ( regs.h.al == 0x1a ) + return 1; return 0; } @@ -414,7 +415,7 @@ return 0; grd_curscreen->sc_mode = mode; grd_curscreen->sc_w = w; grd_curscreen->sc_h = h; - grd_curscreen->sc_aspect = fixdiv(grd_curscreen->sc_w*3,grd_curscreen->sc_h*4); + grd_curscreen->sc_aspect = fixdiv(grd_curscreen->sc_w*3,grd_curscreen->sc_h*4); grd_curscreen->sc_canvas.cv_bitmap.bm_x = 0; grd_curscreen->sc_canvas.cv_bitmap.bm_y = 0; grd_curscreen->sc_canvas.cv_bitmap.bm_w = w; @@ -422,22 +423,24 @@ return 0; grd_curscreen->sc_canvas.cv_bitmap.bm_rowsize = r; grd_curscreen->sc_canvas.cv_bitmap.bm_type = t; grd_curscreen->sc_canvas.cv_bitmap.bm_data = (unsigned char *)data; + VGA_current_mode = mode; gr_set_current_canvas(NULL); //gr_enable_default_palette_loading(); - gamefont_choose_game_font(w,h); +// gamefont_choose_game_font(w,h); return 0; } -int gr_init(int mode) +int gr_init(void) { int org_gamma; int retcode; + int mode = SM(320,200); // Only do this function once! if (gr_installed==1) - return 1; + return 3; #ifdef __DJGPP__ if (!__djgpp_nearptr_enable()) { @@ -464,7 +467,7 @@ int gr_init(int mode) // Save the current text screen mode if (gr_save_mode()==1) - return 1; + return 2; #ifndef NOGRAPH // Save the current palette, and fade it out to black. @@ -573,7 +576,7 @@ int gr_check_mode(u_int32_t mode) // case SM_640x480V15: return gr_vesa_setmode( 0x110 ); // case SM_800x600V15: return gr_vesa_setmode( 0x113 ); } - return 11; + return 11; } /* Palette Stuff Starts Here... */ diff --git a/arch/dos/dpmi.c b/arch/dos/dpmi.c index 8cb2a2ff..9bd503c4 100644 --- a/arch/dos/dpmi.c +++ b/arch/dos/dpmi.c @@ -10,84 +10,10 @@ CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. */ -/* - * $Source: /cvs/cvsroot/d2x/arch/dos/dpmi.c,v $ - * $Revision: 1.1.1.1 $ - * $Author: bradleyb $ - * $Date: 2001-01-19 03:30:15 $ - * - * Routines that access DPMI services... - * - * $Log: not supported by cvs2svn $ - * Revision 1.1.1.1 1999/06/14 21:58:16 donut - * Import of d1x 1.37 source. - * - * Revision 1.19 1995/02/23 09:02:57 john - * Fixed bug with dos_selector. - * - * Revision 1.18 1995/02/02 11:10:22 john - * Made real mode calls have a 2K stack. - * - * Revision 1.17 1995/01/14 19:20:28 john - * Added function to set a selector's base address. - * - * Revision 1.16 1994/12/14 16:11:40 john - * Locked down the memory referenced by GETDS. - * - * Revision 1.15 1994/12/06 16:08:06 john - * MAde memory checking return better results. - * - * Revision 1.14 1994/12/05 23:34:54 john - * Made dpmi_init lock down GETDS and chain_intr. - * - * Revision 1.13 1994/11/28 21:19:02 john - * Made memory checking a bit better. - * - * Revision 1.12 1994/11/28 20:22:18 john - * Added some variables that return the amount of available - * memory. - * - * Revision 1.11 1994/11/15 18:27:21 john - * *** empty log message *** - * - * Revision 1.10 1994/11/15 18:26:45 john - * Added verbose flag. - * - * Revision 1.9 1994/10/27 19:54:37 john - * Added unlock region function,. - * - * Revision 1.8 1994/10/05 16:17:31 john - * Took out locked down message. - * - * Revision 1.7 1994/10/03 17:21:20 john - * Added the code that allocates a 1K DOS buffer. - * - * Revision 1.6 1994/09/29 18:29:40 john - * Shorted mem info printout - * - * Revision 1.5 1994/09/27 11:54:35 john - * Added DPMI init function. - * - * Revision 1.4 1994/09/19 14:50:43 john - * Took out mono debug. - * - * Revision 1.3 1994/09/19 14:41:23 john - * Fixed some bugs with allocating selectors. - * - * Revision 1.2 1994/08/24 18:53:51 john - * Made Cyberman read like normal mouse; added dpmi module; moved - * mouse from assembly to c. Made mouse buttons return time_down. - * - * Revision 1.1 1994/08/24 10:22:34 john - * Initial revision - * - * - */ - - -#ifdef RCS -static char rcsid[] = "$Id: dpmi.c,v 1.1.1.1 2001-01-19 03:30:15 bradleyb Exp $"; -#endif + + +#include +#ifdef __ENV_DJGPP__ #ifdef __DJGPP__ #define _BORLAND_DOS_REGS 1 @@ -100,15 +26,13 @@ static char rcsid[] = "$Id: dpmi.c,v 1.1.1.1 2001-01-19 03:30:15 bradleyb Exp $" int _crt0_startup_flags=_CRT0_FLAG_NONMOVE_SBRK+_CRT0_FLAG_FILL_SBRK_MEMORY+_CRT0_FLAG_FILL_DEADBEEF+_CRT0_FLAG_NEARPTR+_CRT0_FLAG_NO_LFN; #endif -#include #include #include #include #include #include -#include -#include "types.h" +#include "pstypes.h" #include "mono.h" #include "error.h" #include "u_dpmi.h" @@ -471,3 +395,4 @@ int dpmi_set_pm_handler(unsigned intnum, void far * isr ) return 1; } +#endif // __ENV_DJGPP__ diff --git a/arch/dos/findfile.c b/arch/dos/findfile.c new file mode 100644 index 00000000..4db5c8cb --- /dev/null +++ b/arch/dos/findfile.c @@ -0,0 +1,95 @@ +/* +THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. +*/ + + +#include +#ifdef __ENV_DJGPP__ + +#include +#include + +#include "findfile.h" + + +// Global Variables ---------------------------------------------------------- + +static int _FileFindFlag = 0; +static struct find_t _FileFindStruct; + + + +// Functions + +int FileFindFirst(char *search_str, FILEFINDSTRUCT *ffstruct) +{ + unsigned retval; + + if (_FileFindFlag) return -1; + + retval = _dos_findfirst(search_str, 0, &_FileFindStruct); + if (retval) return (int)retval; + else { + ffstruct->size = _FileFindStruct.size; + strcpy(ffstruct->name, _FileFindStruct.name); + _FileFindFlag = 1; + return (int)retval; + } +} + + +int FileFindNext(FILEFINDSTRUCT *ffstruct) +{ + unsigned retval; + + if (!_FileFindFlag) return -1; + + retval = _dos_findnext(&_FileFindStruct); + if (retval) return (int)retval; + else { + ffstruct->size = _FileFindStruct.size; + strcpy(ffstruct->name, _FileFindStruct.name); + return (int)retval; + } +} + + +int FileFindClose(void) +{ + unsigned retval = 0; + + if (!_FileFindFlag) return -1; + + if (retval) return (int)retval; + else { + _FileFindFlag = 0; + return (int)retval; + } +} + + +//returns 0 if no error +int GetFileDateTime(int filehandle, FILETIMESTRUCT *ftstruct) +{ + return _dos_getftime(filehandle, &ftstruct->date, &ftstruct->time); + +} + + +//returns 0 if no error +int SetFileDateTime(int filehandle, FILETIMESTRUCT *ftstruct) +{ + return _dos_setftime(filehandle, ftstruct->date, ftstruct->time); +} + + +#endif //__ENV_DJGPP__ diff --git a/arch/dos/include/joy.h b/arch/dos/include/joy.h index 63a8ad94..21786406 100644 --- a/arch/dos/include/joy.h +++ b/arch/dos/include/joy.h @@ -12,9 +12,9 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. */ /* * $Source: /cvs/cvsroot/d2x/arch/dos/include/joy.h,v $ - * $Revision: 1.1.1.1 $ + * $Revision: 1.1.1.2 $ * $Author: bradleyb $ - * $Date: 2001-01-19 03:30:15 $ + * $Date: 2001-01-19 03:33:52 $ * * Headers for joystick functions * @@ -86,7 +86,7 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #ifndef _JOY_H #define _JOY_H -#include "types.h" +#include "pstypes.h" #include "fix.h" #define JOY_1_BUTTON_A 1 diff --git a/arch/dos/include/key.h b/arch/dos/include/key.h index 0f9daa4c..ba2937aa 100644 --- a/arch/dos/include/key.h +++ b/arch/dos/include/key.h @@ -12,9 +12,9 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. */ /* * $Source: /cvs/cvsroot/d2x/arch/dos/include/key.h,v $ - * $Revision: 1.1.1.1 $ + * $Revision: 1.1.1.2 $ * $Author: bradleyb $ - * $Date: 2001-01-19 03:30:15 $ + * $Date: 2001-01-19 03:33:52 $ * * Header for keyboard functions * @@ -85,7 +85,7 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #define _KEY_H #include "fix.h" -#include "types.h" +#include "pstypes.h" //========================================================================== // This installs the int9 vector and initializes the keyboard in buffered diff --git a/arch/dos/include/mouse.h b/arch/dos/include/mouse.h index 28a5cd0d..43b86b7e 100644 --- a/arch/dos/include/mouse.h +++ b/arch/dos/include/mouse.h @@ -12,9 +12,9 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. */ /* * $Source: /cvs/cvsroot/d2x/arch/dos/include/mouse.h,v $ - * $Revision: 1.1.1.1 $ + * $Revision: 1.1.1.2 $ * $Author: bradleyb $ - * $Date: 2001-01-19 03:30:15 $ + * $Date: 2001-01-19 03:33:52 $ * * Header for mouse functions * @@ -59,7 +59,7 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #ifndef MOUSE_H #define MOUSE_H -#include "types.h" +#include "pstypes.h" #include "fix.h" #define MB_LEFT 0 diff --git a/arch/dos/init.c b/arch/dos/init.c index 72748b0b..3f74ec43 100644 --- a/arch/dos/init.c +++ b/arch/dos/init.c @@ -1,3 +1,6 @@ +#include +#ifdef __ENV_DJGPP__ + #include #include #ifdef __DJGPP__ @@ -7,6 +10,7 @@ #include "../../main/inferno.h" #include "../../main/text.h" +#include "console.h" #include "args.h" #include "error.h" @@ -18,10 +22,9 @@ #include "mouse.h" //added on 9/15/98 by Victor Rachels to add cd controls -#include "bcd.h" +//#include "bcd.h" //end this section addition - Victor Rachels -int WVIDEO_running=0; //debugger can set to 1 if running void install_int3_handler(void); @@ -212,8 +215,6 @@ void check_memory() } } -extern int Inferno_verbose; - //NO_STACK_SIZE_CHECK uint * stack, *stack_ptr; //NO_STACK_SIZE_CHECK int stack_size, unused_stack_space; //NO_STACK_SIZE_CHECK int sil; @@ -268,12 +269,12 @@ void arch_init_start() { // (To check memory size and availbabitliy and allocate some low DOS memory) // adb: no TXT_... loaded yet //if (Inferno_verbose) printf( "%s... ", TXT_INITIALIZING_DPMI); - if (Inferno_verbose) printf( "Initializing DPMI services... "); - dpmi_init(Inferno_verbose); // Before anything - if (Inferno_verbose) printf( "\n" ); + con_printf(CON_VERBOSE, "Initializing DPMI services... "); + dpmi_init(1); // Before anything + con_printf(CON_VERBOSE, "\n" ); #ifndef __GNUC__ - if (Inferno_verbose) printf( "\n%s...", TXT_INITIALIZING_CRIT); + con_printf(CON_VERBOSE, "\n%s...", TXT_INITIALIZING_CRIT); if (!dpmi_lock_region((void near *)descent_critical_error_handler,(char *)chandler_end - (char near *)descent_critical_error_handler)) { Error( "Unable to lock critial error handler" ); } @@ -293,13 +294,13 @@ void arch_init_start() { } void arch_init() { - if ( !FindArg( "-nodoscheck" )) + if ( !args_find( "-nodoscheck" )) check_dos_version(); - if ( !FindArg( "-nofilecheck" )) + if ( !args_find( "-nofilecheck" )) dos_check_file_handles(5); - if ( !FindArg( "-nomemcheck" )) + if ( !args_find( "-nomemcheck" )) check_memory(); #ifndef NDEBUG @@ -308,48 +309,48 @@ void arch_init() { mopen( 1, 2, 1, 78, 5, "Errors & Serious Warnings"); #endif - if (!WVIDEO_running) - mprintf((0,"WVIDEO_running = %d\n",WVIDEO_running)); +/* if (!WVIDEO_running) + mprintf((0,"WVIDEO_running = %d\n",WVIDEO_running));*/ //if (!WVIDEO_running) install_int3_handler(); - if (Inferno_verbose) printf( "\n%s", TXT_VERBOSE_2); + con_printf(CON_VERBOSE, "\n%s", TXT_VERBOSE_2); timer_init(); timer_set_rate( digi_timer_rate ); // Tell our timer how fast to go (120 Hz) joy_set_timer_rate( digi_timer_rate ); // Tell joystick how fast timer is going - if (Inferno_verbose) printf( "\n%s", TXT_VERBOSE_3); + con_printf(CON_VERBOSE, "\n%s", TXT_VERBOSE_3); key_init(); - if (!FindArg( "-nomouse" )) { - if (Inferno_verbose) printf( "\n%s", TXT_VERBOSE_4); - if (FindArg( "-nocyberman" )) + if (!args_find( "-nomouse" )) { + con_printf(CON_VERBOSE, "\n%s", TXT_VERBOSE_4); + if (args_find( "-nocyberman" )) mouse_init(0); else mouse_init(1); } else { - if (Inferno_verbose) printf( "\n%s", TXT_VERBOSE_5); + con_printf(CON_VERBOSE, "\n%s", TXT_VERBOSE_5); } - if (!FindArg( "-nojoystick" )) { - if (Inferno_verbose) printf( "\n%s", TXT_VERBOSE_6); + if (!args_find( "-nojoystick" )) { + con_printf(CON_VERBOSE, "\n%s", TXT_VERBOSE_6); joy_init(); - if ( FindArg( "-joyslow" )) { - if (Inferno_verbose) printf( "\n%s", TXT_VERBOSE_7); + if ( args_find( "-joyslow" )) { + con_printf(CON_VERBOSE, "\n%s", TXT_VERBOSE_7); joy_set_slow_reading(JOY_SLOW_READINGS); } - if ( FindArg( "-joypolled" )) { - if (Inferno_verbose) printf( "\n%s", TXT_VERBOSE_8); + if ( args_find( "-joypolled" )) { + con_printf(CON_VERBOSE, "\n%s", TXT_VERBOSE_8); joy_set_slow_reading(JOY_POLLED_READINGS); } - if ( FindArg( "-joybios" )) { - if (Inferno_verbose) printf( "\n%s", TXT_VERBOSE_9); + if ( args_find( "-joybios" )) { + con_printf(CON_VERBOSE, "\n%s", TXT_VERBOSE_9); joy_set_slow_reading(JOY_BIOS_READINGS); } - if ( FindArg( "-joynice" )) { - if (Inferno_verbose) printf( "\n%s", "Using nice joystick poller..." ); + if ( args_find( "-joynice" )) { + con_printf(CON_VERBOSE, "\n%s", "Using nice joystick poller..." ); joy_set_slow_reading(JOY_FRIENDLY_READINGS); } - if ( FindArg( "-gameport" )) { + if ( args_find( "-gameport" )) { if ( init_gameport() ) { joy_set_slow_reading(JOY_BIOS_READINGS); } else { @@ -357,10 +358,12 @@ void arch_init() { } } } else { - if (Inferno_verbose) printf( "\n%s", TXT_VERBOSE_10); + con_printf(CON_VERBOSE, "\n%s", TXT_VERBOSE_10); } #if 0 // no divzero if (Inferno_verbose) printf( "\n%s", TXT_VERBOSE_11); div0_init(DM_ERROR); #endif } + +#endif // __ENV_DJGPP__ diff --git a/arch/dos/joyc.c b/arch/dos/joyc.c index 442873ab..410e7a32 100644 --- a/arch/dos/joyc.c +++ b/arch/dos/joyc.c @@ -12,9 +12,9 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. */ /* * $Source: /cvs/cvsroot/d2x/arch/dos/joyc.c,v $ - * $Revision: 1.1.1.1 $ + * $Revision: 1.1.1.2 $ * $Author: bradleyb $ - * $Date: 2001-01-19 03:30:15 $ + * $Date: 2001-01-19 03:33:52 $ * * Routines for joystick reading. * @@ -155,19 +155,15 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. */ -#ifdef RCS -static char rcsid[] = "$Id: joyc.c,v 1.1.1.1 2001-01-19 03:30:15 bradleyb Exp $"; -#endif +#include #include #include -#include #include -#include //#define ARCADE 1 -#include "types.h" +#include "pstypes.h" #include "mono.h" #include "joy.h" #include "u_dpmi.h" @@ -447,9 +443,9 @@ int joy_init() int i; int temp_axis[4]; -// if(FindArg("-joy209")) +// if(args_find("-joy209")) // use_alt_joyport=1; - if(FindArg("-joy209")) + if(args_find("-joy209")) JOY_PORT = 521; //209h; joy_flush(); diff --git a/arch/dos/joydefs.c b/arch/dos/joydefs.c index e9b74514..4444f148 100644 --- a/arch/dos/joydefs.c +++ b/arch/dos/joydefs.c @@ -12,9 +12,9 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. */ /* * $Source: /cvs/cvsroot/d2x/arch/dos/joydefs.c,v $ - * $Revision: 1.1.1.1 $ + * $Revision: 1.1.1.2 $ * $Author: bradleyb $ - * $Date: 2001-01-19 03:30:15 $ + * $Date: 2001-01-19 03:33:52 $ * * . * @@ -270,12 +270,7 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. * */ - -#ifdef RCS -#pragma off (unreferenced) -static char rcsid[] = "$Id: joydefs.c,v 1.1.1.1 2001-01-19 03:30:15 bradleyb Exp $"; -#pragma on (unreferenced) -#endif +#include #include #include @@ -305,6 +300,8 @@ static char rcsid[] = "$Id: joydefs.c,v 1.1.1.1 2001-01-19 03:30:15 bradleyb Exp int joydefs_calibrate_flag = 0; +int Joy_is_Sidewinder = 0; + void joy_delay() { #ifdef __MSDOS__ @@ -572,8 +569,6 @@ extern ubyte kc_use_external_control; extern ubyte kc_enable_external_control; extern ubyte *kc_external_name; -int Joy_is_Sidewinder=0; - void joydefs_config() { char xtext[128]; diff --git a/arch/dos/key.c b/arch/dos/key.c index bec3d31a..36882000 100644 --- a/arch/dos/key.c +++ b/arch/dos/key.c @@ -12,9 +12,9 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. */ /* * $Source: /cvs/cvsroot/d2x/arch/dos/key.c,v $ - * $Revision: 1.1.1.1 $ + * $Revision: 1.1.1.2 $ * $Author: bradleyb $ - * $Date: 2001-01-19 03:30:15 $ + * $Date: 2001-01-19 03:33:52 $ * * Functions for keyboard handler. * @@ -140,15 +140,10 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. //#define PASS_KEYS_TO_BIOS 1 //if set, bios gets keys -#ifdef RCS -static char rcsid[] = "$Id: key.c,v 1.1.1.1 2001-01-19 03:30:15 bradleyb Exp $"; -#endif - +#include #include #include -#include #include -#include //#define WATCOM_10 #ifdef __DJGPP__ @@ -219,7 +214,7 @@ unsigned char shifted_ascii_table[128] = 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255 }; - +/* char * key_text[256] = { "","ESC","1","2","3","4","5","6","7","8","9","0","-", "=","BSPC","TAB","Q","W","E","R","T","Y","U","I","O", @@ -241,7 +236,7 @@ char * key_text[256] = { "DEL","","","","","","","","","","","","","","","","","", "","","","","","","","","","","","","","","","","","","","", "","","","","","","" }; - +*/ unsigned char key_to_ascii(int keycode ) { int shifted; diff --git a/arch/dos/mouse.c b/arch/dos/mouse.c index 37e9b535..da635a02 100644 --- a/arch/dos/mouse.c +++ b/arch/dos/mouse.c @@ -12,9 +12,9 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. */ /* * $Source: /cvs/cvsroot/d2x/arch/dos/mouse.c,v $ - * $Revision: 1.1.1.1 $ + * $Revision: 1.1.1.2 $ * $Author: bradleyb $ - * $Date: 2001-01-19 03:30:15 $ + * $Date: 2001-01-19 03:33:52 $ * * Functions to access Mouse and Cyberman... * @@ -65,9 +65,7 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. * */ -#ifdef RCS -static char rcsid[] = "$Id: mouse.c,v 1.1.1.1 2001-01-19 03:30:15 bradleyb Exp $"; -#endif +#include #ifdef __DJGPP__ #include @@ -80,9 +78,9 @@ _go32_dpmi_registers handler_regs; #include #include -#include +//#include #include -#include +//#include #include #include "error.h" diff --git a/arch/dos/vesa.c b/arch/dos/vesa.c index 54791301..fd965b50 100644 --- a/arch/dos/vesa.c +++ b/arch/dos/vesa.c @@ -1,3 +1,7 @@ +#include +#ifdef __ENV_DJGPP__ + + #include #include "gr.h" #include "grdef.h" @@ -90,8 +94,7 @@ int gr_vesa_setmode(int mode) { inline void gr_vesa_setpage(int bank) { if (bank != lastbank) asm volatile("int $0x10" - : : "a" (0x4f05), "b" (0), "d" ((lastbank = bank) << bankshift) - : "%eax"); + : : "a" (0x4f05), "b" (0), "d" ((lastbank = bank) << bankshift)); } void gr_vesa_incpage() { @@ -100,13 +103,13 @@ void gr_vesa_incpage() { void gr_vesa_setstart(int col, int row) { asm volatile("int $0x10" - : : "a" (0x4f07), "b" (0), "c" (col), "d" (row) : "%eax"); + : : "a" (0x4f07), "b" (0), "c" (col), "d" (row)); } int gr_vesa_setlogical(int line_width) { int ret; asm volatile("int $0x10" - : "=c" (ret) : "a" (0x4f07), "b" (0), "c" (line_width) : "%eax"); + : "=c" (ret) : "a" (0x4f07), "b" (0), "c" (line_width)); return ret; } @@ -132,3 +135,6 @@ void gr_vesa_pixel(unsigned char color, unsigned int addr) { gr_vesa_setpage(addr >> 16); gr_video_memory[addr & 0xffff] = color; } + + +#endif // __ENV_DJGPP__ diff --git a/arch/dos_dpmi.c b/arch/dos_dpmi.c new file mode 100644 index 00000000..9bd503c4 --- /dev/null +++ b/arch/dos_dpmi.c @@ -0,0 +1,398 @@ +/* +THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. +*/ + + +#include +#ifdef __ENV_DJGPP__ + +#ifdef __DJGPP__ +#define _BORLAND_DOS_REGS 1 +#define far +#include +#include +#include +#define FP_SEG(p) _my_ds() +#define FP_OFF(p) (int)p + int _crt0_startup_flags=_CRT0_FLAG_NONMOVE_SBRK+_CRT0_FLAG_FILL_SBRK_MEMORY+_CRT0_FLAG_FILL_DEADBEEF+_CRT0_FLAG_NEARPTR+_CRT0_FLAG_NO_LFN; +#endif + +#include +#include +#include +#include +#include + +#include "pstypes.h" +#include "mono.h" +#include "error.h" +#include "u_dpmi.h" + +int dpmi_find_dos_memory() +{ + union REGS r; + + memset(&r,0,sizeof(r)); + r.x.eax = 0x0100; // DPMI allocate DOS memory + r.x.ebx = 0xffff; // Number of paragraphs requested + int386 (0x31, &r, &r); + //if ( (r.x.eax & 0xffff) == 0x08 ) + //if ( (r.x.eax & 0xffff) == 0x08 ) + if ( r.x.cflag ) + return ((r.x.ebx & 0xffff)*16); + else + return 640*1024; +} + +void *dpmi_real_malloc( int size, ushort *selector ) +{ + union REGS r; + + memset(&r,0,sizeof(r)); + r.x.eax = 0x0100; // DPMI allocate DOS memory + r.x.ebx = (size + 15) >> 4; // Number of paragraphs requested + int386 (0x31, &r, &r); + + if (r.x.cflag) // Failed + return ((uint) 0); + + if(selector!=NULL) + *selector = r.x.edx & 0xFFFF; + +#ifdef __DJGPP__ + return (void *) ((r.x.eax & 0xFFFF) << 4)+__djgpp_conventional_base; +#else + return (void *) ((r.x.eax & 0xFFFF) << 4); +#endif +} + +void dpmi_real_free( ushort selector ) +{ + union REGS r; + + memset(&r,0,sizeof(r)); + r.x.eax = 0x0101; // DPMI free DOS memory + r.x.ebx = selector; // Selector to free + int386 (0x31, &r, &r); +} + +int dos_stack_initialized = 0; +ubyte * dos_stack = NULL; +ubyte * dos_stack_top = NULL; +#define DOS_STACK_SIZE (4*1024) // A big ol' 4K stack!!! + +static void dpmi_setup_stack(dpmi_real_regs *rregs) { + ushort temp_selector; + + if ( !dos_stack_initialized ) { + dos_stack_initialized = 1; + dos_stack = dpmi_real_malloc( DOS_STACK_SIZE, &temp_selector ); + if ( dos_stack == NULL ) { + printf( "Error allocating real mode stack!\n" ); + dos_stack_top = NULL; + } else { + dos_stack_top = &dos_stack[DOS_STACK_SIZE]; + } + } + + // Give this puppy a stack!!! + if ( dos_stack_top ) { + rregs->ss = DPMI_real_segment(dos_stack_top); + rregs->sp = DPMI_real_offset(dos_stack_top); + } +} + + +void dpmi_real_int386x( ubyte intno, dpmi_real_regs * rregs ) +{ + union REGS regs; + struct SREGS sregs; + + /* Use DMPI call 300h to issue the DOS interrupt */ + + dpmi_setup_stack(rregs); + memset(®s,0,sizeof(regs)); + memset(&sregs,0,sizeof(sregs)); + regs.w.ax = 0x0300; + regs.h.bl = intno; + regs.h.bh = 0; + regs.w.cx = 0; + sregs.es = FP_SEG(rregs); + regs.x.edi = FP_OFF(rregs); + int386x( 0x31, ®s, ®s, &sregs ); +} + +void dpmi_real_call(dpmi_real_regs * rregs) +{ + union REGS regs; + struct SREGS sregs; + + dpmi_setup_stack(rregs); + + /* Use DMPI call 301h to call real mode procedure */ + memset(®s,0,sizeof(regs)); + memset(&sregs,0,sizeof(sregs)); + regs.w.ax = 0x0301; + regs.h.bh = 0; + regs.w.cx = 0; + sregs.es = FP_SEG(rregs); + regs.x.edi = FP_OFF(rregs); + int386x( 0x31, ®s, ®s, &sregs ); + if ( regs.x.cflag ) + exit(regs.w.ax); +} + +int total_bytes = 0; + +int dpmi_unlock_region(void *address, unsigned length) +{ + union REGS regs; + unsigned int linear; + + linear = (unsigned int) address; +#ifdef __DJGPP__ + linear += __djgpp_base_address; +#endif + + total_bytes -= length; + //mprintf( 1, "DPMI unlocked %d bytes\n", total_bytes ); + + memset(®s,0,sizeof(regs)); + regs.w.ax = 0x601; // DPMI Unlock Linear Region + regs.w.bx = (linear >> 16); // Linear address in BX:CX + regs.w.cx = (linear & 0xFFFF); + + regs.w.si = (length >> 16); // Length in SI:DI + regs.w.di = (length & 0xFFFF); + int386 (0x31, ®s, ®s); + return (! regs.w.cflag); // Return 0 if can't lock +} + +int dpmi_lock_region(void *address, unsigned length) +{ + union REGS regs; + unsigned int linear; + + linear = (unsigned int) address; +#ifdef __DJGPP__ + linear += __djgpp_base_address; +#endif + + total_bytes += length; + //mprintf( 1, "DPMI Locked down %d bytes\n", total_bytes ); + + memset(®s,0,sizeof(regs)); + regs.w.ax = 0x600; // DPMI Lock Linear Region + regs.w.bx = (linear >> 16); // Linear address in BX:CX + regs.w.cx = (linear & 0xFFFF); + + regs.w.si = (length >> 16); // Length in SI:DI + regs.w.di = (length & 0xFFFF); + int386 (0x31, ®s, ®s); + return (! regs.w.cflag); // Return 0 if can't lock +} + + +int dpmi_modify_selector_base( ushort selector, void * address ) +{ + union REGS regs; + unsigned int linear; + + linear = (unsigned int)address; +#ifdef __DJGPP__ + linear += __djgpp_base_address; +#endif + + memset(®s,0,sizeof(regs)); + regs.w.ax = 0x0007; // DPMI Change Selector Base Addres + regs.w.bx = selector; // Selector to change + regs.w.cx = (linear >> 16); // Base address + regs.w.dx = (linear & 0xFFFF); + int386 (0x31, ®s, ®s); // call dpmi + if (regs.w.cflag) + return 0; // Return 0 if error + + return 1; +} + + +int dpmi_modify_selector_limit( ushort selector, int size ) +{ + union REGS regs; + unsigned int segment_limit; + + segment_limit = (unsigned int) size; + + memset(®s,0,sizeof(regs)); + regs.w.ax = 0x0008; // DPMI Change Selector Limit + regs.w.bx = selector; // Selector to change + regs.w.cx = (segment_limit >> 16); // Size of selector + regs.w.dx = (segment_limit & 0xFFFF); + int386 (0x31, ®s, ®s); // call dpmi + if (regs.w.cflag) + return 0; // Return 0 if error + + return 1; +} + + +int dpmi_allocate_selector( void * address, int size, ushort * selector ) +{ + union REGS regs; + + + memset(®s,0,sizeof(regs)); + regs.w.ax = 0; // DPMI Allocate Selector + regs.w.cx = 1; // Allocate 1 selector + int386 (0x31, ®s, ®s); // call dpmi + if (regs.w.cflag) + return 0; // Return 0 if error + *selector = regs.w.ax; + + if ( !dpmi_modify_selector_base( *selector, address ) ) + return 0; + + if ( !dpmi_modify_selector_limit( *selector, size ) ) + return 0; + +// mprintf( 0, "Selector 0x%4x has base of 0x%8x, size %d bytes\n", *selector, linear,segment_limit); + + return 1; +} + +static void * dpmi_dos_buffer = NULL; +static ushort dpmi_dos_selector = 0; + +void dpmi_close() +{ + if (dpmi_dos_selector!=0) { + dpmi_dos_buffer = NULL; + dpmi_dos_selector = 0; + } +} + +typedef struct mem_data { + int largest_block_bytes; + int max_unlocked_page_allocation; + int largest_lockable_pages; + int total_pages; + int unlocked_pages; + int unused_physical_pages; + int total_physical_pages; + int free_linear_pages; + int paging_size_pages; + int reserved[3]; +} mem_data; + +unsigned int dpmi_virtual_memory=0; +unsigned int dpmi_available_memory=0; +unsigned int dpmi_physical_memory=0; +unsigned int dpmi_dos_memory = 0; + +#ifdef __WATCOMC__ +extern void cdecl _GETDS(); +extern void cdecl cstart_(); +#endif + +int dpmi_init(int verbose) +{ + union REGS regs; + struct SREGS sregs; + mem_data mi; + + dpmi_dos_memory = dpmi_find_dos_memory(); + + dpmi_dos_buffer = dpmi_real_malloc( 1024, &dpmi_dos_selector); + if (!dpmi_dos_buffer) { + dpmi_dos_selector = 0; + printf( "Error allocating 1K of DOS memory\n" ); + exit(1); + } + atexit(dpmi_close); + + // Check dpmi + memset(®s,0,sizeof(regs)); + regs.x.eax = 0x400; // DPMI Get Memory Info + int386( 0x31, ®s, ®s ); + if (!regs.w.cflag) { + if (verbose) printf( "V%d.%d, CPU:%d, VMM:", regs.h.ah, regs.h.al, regs.h.cl ); + if (regs.w.bx & 4) { + if (verbose) printf( "1" ); + dpmi_virtual_memory = 1; + } else { + if (verbose) printf( "0" ); + } + } + + //--------- Find available memory + memset(®s,0,sizeof(regs)); + memset(&sregs,0,sizeof(sregs)); + regs.x.eax = 0x500; // DPMI Get Memory Info + sregs.es = FP_SEG(&mi); + regs.x.edi = FP_OFF(&mi); + int386x( 0x31, ®s, ®s, &sregs ); + if (!regs.w.cflag) { + if (verbose) printf( ", P:%dK", mi.largest_lockable_pages*4 ); + if (dpmi_virtual_memory) + if (verbose) printf( ", A:%dK", mi.largest_block_bytes/1024 ); + //dpmi_physical_memory = mi.largest_lockable_pages*4096; + //dpmi_available_memory = mi.largest_block_bytes; + dpmi_physical_memory = mi.total_physical_pages*4096; + dpmi_available_memory = mi.total_pages * 4096; + } else { + if (verbose) printf( "MemInfo failed!" ); + dpmi_physical_memory = 16*1024*1024; // Assume 16 MB + dpmi_available_memory = 16*1024*1024; // Assume 16 MB + } + +#ifdef __WATCOMC__ + if (!dpmi_lock_region( _GETDS, 4096 )) { + printf( "Error locking _GETDS" ); + exit(1); + } + if (!dpmi_lock_region( cstart_, 4096 )) { + printf( "Error locking cstart" ); + exit(1); + } + if (!dpmi_lock_region( _chain_intr, 4096 )) { + printf( "Error locking _chain_intr" ); + exit(1); + } +#endif + return 1; +} + +void *dpmi_get_temp_low_buffer( int size ) +{ + if ( dpmi_dos_buffer == NULL ) return NULL; + if ( size > 1024 ) return NULL; + + return dpmi_dos_buffer; +} + +int dpmi_set_pm_handler(unsigned intnum, void far * isr ) +{ + union REGS regs; + + /* Use DMPI call 204h to get pm interrrupt */ + memset(®s,0,sizeof(regs)); + regs.w.ax = 0x0205; + regs.h.bl = intnum; + regs.w.cx = FP_SEG(isr); + regs.x.edx = FP_OFF(isr); + int386( 0x31, ®s, ®s ); + if (!regs.w.cflag) + return 0; + return 1; +} + +#endif // __ENV_DJGPP__ diff --git a/arch/dos_findfile.c b/arch/dos_findfile.c new file mode 100644 index 00000000..4db5c8cb --- /dev/null +++ b/arch/dos_findfile.c @@ -0,0 +1,95 @@ +/* +THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. +*/ + + +#include +#ifdef __ENV_DJGPP__ + +#include +#include + +#include "findfile.h" + + +// Global Variables ---------------------------------------------------------- + +static int _FileFindFlag = 0; +static struct find_t _FileFindStruct; + + + +// Functions + +int FileFindFirst(char *search_str, FILEFINDSTRUCT *ffstruct) +{ + unsigned retval; + + if (_FileFindFlag) return -1; + + retval = _dos_findfirst(search_str, 0, &_FileFindStruct); + if (retval) return (int)retval; + else { + ffstruct->size = _FileFindStruct.size; + strcpy(ffstruct->name, _FileFindStruct.name); + _FileFindFlag = 1; + return (int)retval; + } +} + + +int FileFindNext(FILEFINDSTRUCT *ffstruct) +{ + unsigned retval; + + if (!_FileFindFlag) return -1; + + retval = _dos_findnext(&_FileFindStruct); + if (retval) return (int)retval; + else { + ffstruct->size = _FileFindStruct.size; + strcpy(ffstruct->name, _FileFindStruct.name); + return (int)retval; + } +} + + +int FileFindClose(void) +{ + unsigned retval = 0; + + if (!_FileFindFlag) return -1; + + if (retval) return (int)retval; + else { + _FileFindFlag = 0; + return (int)retval; + } +} + + +//returns 0 if no error +int GetFileDateTime(int filehandle, FILETIMESTRUCT *ftstruct) +{ + return _dos_getftime(filehandle, &ftstruct->date, &ftstruct->time); + +} + + +//returns 0 if no error +int SetFileDateTime(int filehandle, FILETIMESTRUCT *ftstruct) +{ + return _dos_setftime(filehandle, ftstruct->date, ftstruct->time); +} + + +#endif //__ENV_DJGPP__ diff --git a/arch/dos_init.c b/arch/dos_init.c new file mode 100644 index 00000000..2143a5b7 --- /dev/null +++ b/arch/dos_init.c @@ -0,0 +1,370 @@ +#include +#ifdef __ENV_DJGPP__ + +#include +#include +#ifdef __DJGPP__ +#define _BORLAND_DOS_REGS 1 +#endif +#include + +#include "pstypes.h" +#include "inferno.h" +#include "text.h" +#include "console.h" +#include "args.h" +#include "error.h" + +#include "joy.h" +#include "timer.h" +#include "key.h" +#include "mono.h" +#include "u_dpmi.h" +#include "mouse.h" + +//added on 9/15/98 by Victor Rachels to add cd controls +//#include "bcd.h" +//end this section addition - Victor Rachels + + +void install_int3_handler(void); + +#ifdef __WATCOMC__ +int __far descent_critical_error_handler( unsigned deverr, unsigned errcode, unsigned far * devhdr ); +#endif + +#ifndef NDEBUG +#ifdef __WATCOMC__ +void do_heap_check() +{ + int heap_status; + + heap_status = _heapset( 0xFF ); + switch( heap_status ) + { + case _HEAPBADBEGIN: + mprintf((1, "ERROR - heap is damaged\n")); + Int3(); + break; + case _HEAPBADNODE: + mprintf((1, "ERROR - bad node in heap\n" )); + Int3(); + break; + } +} +#endif +#endif + + + +#ifdef VR_DEVICES +int is_3dbios_installed() +{ + dpmi_real_regs rregs; + memset(&rregs,0,sizeof(dpmi_real_regs)); + rregs.eax = 0x4ed0; + //rregs.ebx = 0x3d10; + dpmi_real_int386x( 0x10, &rregs ); + if ( (rregs.edx & 0xFFFF) != 0x3344 ) + return 0; + else + return 1; +} +#endif + +// Returns 1 if ok, 0 if failed... +int init_gameport() +{ + union REGS regs; + + memset(®s,0,sizeof(regs)); + regs.x.eax = 0x8400; + regs.x.edx = 0xF0; + int386( 0x15, ®s, ®s ); + if ( ( regs.x.eax & 0xFFFF ) == 0x4753 /*'SG'*/ ) + return 1; + else + return 0; +} + +void check_dos_version() +{ + int major, minor; + union REGS regs; + + memset(®s,0,sizeof(regs)); + regs.x.eax = 0x3000; // Get MS-DOS Version Number + int386( 0x21, ®s, ®s ); + + major = regs.h.al; + minor = regs.h.ah; + + if ( major < 5 ) { + printf( "Using MS-DOS version %d.%d\nThis is not compatable with Descent.", major, minor); + exit(1); + } + //printf( "\nUsing MS-DOS %d.%d...\n", major, minor ); +} + +void dos_check_file_handles(int num_required) +{ + int i, n; + FILE * fp[16]; + + if ( num_required > 16 ) + num_required = 16; + + n = 0; + for (i=0; i<16; i++ ) + fp[i] = NULL; + for (i=0; i<16; i++ ) { + fp[i] = fopen( "nul", "wb" ); + if ( !fp[i] ) break; + } + n = i; + for (i=0; i<16; i++ ) { + if (fp[i]) + fclose(fp[i]); + } + if ( n < num_required ) { + printf( "\n%s\n", TXT_NOT_ENOUGH_HANDLES ); + printf( "------------------------\n" ); + printf( "%d/%d %s\n", n, num_required, TXT_HANDLES_1 ); + printf( "%s\n", TXT_HANDLES_2); + printf( "%s\n", TXT_HANDLES_3); + exit(1); + } +} + +#define NEEDED_DOS_MEMORY ( 300*1024) // 300 K +#define NEEDED_LINEAR_MEMORY (7680*1024) // 7.5 MB +#define LOW_PHYSICAL_MEMORY_CUTOFF (5*1024*1024) // 5.0 MB +#define NEEDED_PHYSICAL_MEMORY (2000*1024) // 2000 KB + +extern int piggy_low_memory; + +void mem_int_to_string( int number, char *dest ) +{ + int i,l,c; + char buffer[20],*p; + + sprintf( buffer, "%d", number ); + + l = strlen(buffer); + if (l<=3) { + // Don't bother with less than 3 digits + sprintf( dest, "%d", number ); + return; + } + + c = l % 3; + p=dest; + for (i=0; i dpmi_physical_memory ) { + mem_int_to_string( (dpmi_available_memory-dpmi_physical_memory)/1024, text ); + } else { + mem_int_to_string( 0, text ); + } + printf( "Virtual: %7s KB\n", text ); + printf( "\n" ); + + if ( dpmi_dos_memory < NEEDED_DOS_MEMORY ) { + printf( "%d %s\n", NEEDED_DOS_MEMORY - dpmi_dos_memory, TXT_MEMORY_CONFIG ); + exit(1); + } + + if ( dpmi_available_memory < NEEDED_LINEAR_MEMORY ) { + if ( dpmi_virtual_memory ) { + printf( "%d %s\n", NEEDED_LINEAR_MEMORY - dpmi_available_memory, TXT_RECONFIGURE_VMM ); + } else { + printf( "%d %s\n", NEEDED_LINEAR_MEMORY - dpmi_available_memory, TXT_MORE_MEMORY ); + printf( "%s\n", TXT_MORE_MEMORY_2); + } + exit(1); + } + + if ( dpmi_physical_memory < NEEDED_PHYSICAL_MEMORY ) { + printf( "%d %s\n", NEEDED_PHYSICAL_MEMORY - dpmi_physical_memory, TXT_PHYSICAL_MEMORY ); + if ( dpmi_virtual_memory ) { + printf( "%s\n", TXT_PHYSICAL_MEMORY_2); + } + exit(1); + } + + if ( dpmi_physical_memory < LOW_PHYSICAL_MEMORY_CUTOFF ) { + piggy_low_memory = 1; + } +} + +//NO_STACK_SIZE_CHECK uint * stack, *stack_ptr; +//NO_STACK_SIZE_CHECK int stack_size, unused_stack_space; +//NO_STACK_SIZE_CHECK int sil; +//NO_STACK_SIZE_CHECK +//NO_STACK_SIZE_CHECK int main(int argc,char **argv) +//NO_STACK_SIZE_CHECK { +//NO_STACK_SIZE_CHECK uint ret_value; +//NO_STACK_SIZE_CHECK +//NO_STACK_SIZE_CHECK unused_stack_space = 0; +//NO_STACK_SIZE_CHECK stack = &ret_value; +//NO_STACK_SIZE_CHECK stack_size = stackavail()/4; +//NO_STACK_SIZE_CHECK +//NO_STACK_SIZE_CHECK for ( sil=0; sil + +#ifdef __ENV_DJGPP__ + +#ifdef __GNUC__ +#define _BORLAND_DOS_REGS 1 +#define far +#endif + +#include +#include +#include +#include +#include +#include + +#include "pstypes.h" +#include "timer.h" +#include "ipx.h" +#include "error.h" +#include "u_dpmi.h" +#include "key.h" + +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned long DWORD; + +typedef struct local_address { + ubyte address[6]; +} __pack__ local_address; + +typedef struct net_address { + BYTE network_id[4]; + local_address node_id; + WORD socket_id; +} __pack__ net_address; + +typedef struct ipx_header { + WORD checksum; + WORD length; + BYTE transport_control; + BYTE packet_type; + net_address destination; + net_address source; +} __pack__ ipx_header; + +typedef struct ecb_header { + WORD link[2]; + WORD esr_address[2]; + BYTE in_use; + BYTE completion_code; + WORD socket_id; + BYTE ipx_reserved[14]; + WORD connection_id; + local_address immediate_address; + WORD fragment_count; + WORD fragment_pointer[2]; + WORD fragment_size; +} __pack__ ecb_header; + +typedef struct packet_data { + int packetnum; + byte data[IPX_MAX_DATA_SIZE]; +} __pack__ packet_data; + +typedef struct ipx_packet { + ecb_header ecb; + ipx_header ipx; + packet_data pd; +} __pack__ ipx_packet; + +typedef struct user_address { + ubyte network[4]; + ubyte node[6]; + ubyte address[6]; +} __pack__ user_address; + +#define MAX_USERS 64 +int Ipx_num_users = 0; +user_address Ipx_users[MAX_USERS]; + +#define MAX_NETWORKS 64 +int Ipx_num_networks = 0; +uint Ipx_networks[MAX_NETWORKS]; + +int ipx_packetnum = 0; + +#define MAX_PACKETS 64 + +static packet_data packet_buffers[MAX_PACKETS]; +static short packet_free_list[MAX_PACKETS]; +static int num_packets = 0; +static int largest_packet_index = 0; +static short packet_size[MAX_PACKETS]; + +WORD ipx_socket=0; +ubyte ipx_installed=0; +WORD ipx_vector_segment; +WORD ipx_vector_offset; +ubyte ipx_socket_life = 0; // 0=closed at prog termination, 0xff=closed when requested. +DWORD ipx_network = 0; +local_address ipx_my_node; +WORD ipx_num_packets=32; // 32 Ipx packets +ipx_packet * packets; +int neterrors = 0; +ushort ipx_packets_selector; + +ecb_header * last_ecb=NULL; +int lastlen=0; + +void got_new_packet( ecb_header * ecb ); +void ipx_listen_for_packet(ecb_header * ecb ); + +void free_packet( int id ) +{ + packet_buffers[id].packetnum = -1; + packet_free_list[ --num_packets ] = id; + if (largest_packet_index==id) + while ((--largest_packet_index>0) && (packet_buffers[largest_packet_index].packetnum == -1 )); +} + +int ipx_get_packet_data( ubyte * data ) +{ + int i, n, best, best_id, size; + + for (i=1; i -1 ) { + n++; + if ( best == -1 || (packet_buffers[i].packetnum ", neterrors )); + + if ( best_id < 0 ) return 0; + + size = packet_size[best_id]; + memcpy( data, packet_buffers[best_id].data, size ); + free_packet(best_id); + + return size; +} + +#ifndef __GNUC__ +unsigned int swap_short( unsigned int short ) +#pragma aux swap_short parm [eax] = "xchg al,ah"; +#else +static inline unsigned int swap_short( unsigned int sshort ) { + int __retval; + asm("xchg %%ah,%%al" : "=a" (__retval) : "a" (sshort)); + return __retval; +} +#endif + +void got_new_packet( ecb_header * ecb ) +{ + ipx_packet * p; + int id; + unsigned short datasize; + + datasize = 0; + last_ecb = ecb; + p = (ipx_packet *)ecb; + + if ( p->ecb.in_use ) { neterrors++; return; } + if ( p->ecb.completion_code ) { neterrors++; return; } + + // Error( "Recieve error %d for completion code", p->ecb.completion_code ); + + if ( memcmp( &p->ipx.source.node_id, &ipx_my_node, 6 ) ) { + datasize=swap_short(p->ipx.length); + lastlen=datasize; + datasize -= sizeof(ipx_header); + // Find slot to put packet in... + if ( datasize > 0 && datasize <= sizeof(packet_data) ) { + if ( num_packets >= MAX_PACKETS ) { + //printf( 1, "IPX: Packet buffer overrun!!!\n" ); + neterrors++; + return; + } + id = packet_free_list[ num_packets++ ]; + if (id > largest_packet_index ) largest_packet_index = id; + packet_size[id] = datasize-sizeof(int); + packet_buffers[id].packetnum = p->pd.packetnum; + if ( packet_buffers[id].packetnum < 0 ) { neterrors++; return; } + memcpy( packet_buffers[id].data, p->pd.data, packet_size[id] ); + } else { + neterrors++; return; + } + } + // Repost the ecb + p->ecb.in_use = 0; + //ipx_listen_for_packet(&p->ecb); +} + +ubyte * ipx_get_my_local_address() +{ + return ipx_my_node.address; +} + +ubyte * ipx_get_my_server_address() +{ + return (ubyte *)&ipx_network; +} + +void ipx_listen_for_packet(ecb_header * ecb ) +{ + dpmi_real_regs rregs; + ecb->in_use = 0x1d; + memset(&rregs,0,sizeof(dpmi_real_regs)); + rregs.ebx = 4; // Listen For Packet function + rregs.esi = DPMI_real_offset(ecb); + rregs.es = DPMI_real_segment(ecb); + dpmi_real_int386x( 0x7A, &rregs ); +} + +void ipx_cancel_listen_for_packet(ecb_header * ecb ) +{ + dpmi_real_regs rregs; + memset(&rregs,0,sizeof(dpmi_real_regs)); + rregs.ebx = 6; // IPX Cancel event + rregs.esi = DPMI_real_offset(ecb); + rregs.es = DPMI_real_segment(ecb); + dpmi_real_int386x( 0x7A, &rregs ); +} + + +void ipx_send_packet(ecb_header * ecb ) +{ + dpmi_real_regs rregs; + memset(&rregs,0,sizeof(dpmi_real_regs)); + rregs.ebx = 3; // Send Packet function + rregs.esi = DPMI_real_offset(ecb); + rregs.es = DPMI_real_segment(ecb); + dpmi_real_int386x( 0x7A, &rregs ); +} + +typedef struct { + ubyte network[4]; + ubyte node[6]; + ubyte local_target[6]; +} __pack__ net_xlat_info; + +void ipx_get_local_target( ubyte * server, ubyte * node, ubyte * local_target ) +{ + net_xlat_info * info; + dpmi_real_regs rregs; + + // Get dos memory for call... + info = (net_xlat_info *)dpmi_get_temp_low_buffer( sizeof(net_xlat_info) ); + assert( info != NULL ); + memcpy( info->network, server, 4 ); + memcpy( info->node, node, 6 ); + + memset(&rregs,0,sizeof(dpmi_real_regs)); + + rregs.ebx = 2; // Get Local Target + rregs.es = DPMI_real_segment(info); + rregs.esi = DPMI_real_offset(info->network); + rregs.edi = DPMI_real_offset(info->local_target); + + dpmi_real_int386x( 0x7A, &rregs ); + + // Save the local target... + memcpy( local_target, info->local_target, 6 ); +} + +void ipx_close() +{ + dpmi_real_regs rregs; + if ( ipx_installed ) { + // When using VLM's instead of NETX, the sockets don't + // seem to automatically get closed, so we must explicitly + // close them at program termination. + ipx_installed = 0; + memset(&rregs,0,sizeof(dpmi_real_regs)); + rregs.edx = ipx_socket; + rregs.ebx = 1; // Close socket + dpmi_real_int386x( 0x7A, &rregs ); + } +} + + +//--------------------------------------------------------------- +// Initializes all IPX internals. +// If socket_number==0, then opens next available socket. +// Returns: 0 if successful. +// -1 if socket already open. +// -2 if socket table full. +// -3 if IPX not installed. +// -4 if couldn't allocate low dos memory +// -5 if error with getting internetwork address + +int ipx_init( int socket_number, int show_address ) +{ + dpmi_real_regs rregs; + ubyte *ipx_real_buffer; + int i; + + atexit(ipx_close); + + ipx_packetnum = 0; + + // init packet buffers. + for (i=0; i= IPX_MAX_DATA_SIZE ) { + printf( "Data too big\n" ); +//added/replaced on 11/8/98 by Victor Rachels to stop crappage + return; +// exit(1); +//end this section replacement - VR + } + + // Make sure no one is already sending something + while( packets[0].ecb.in_use ) + { + } + + if (packets[0].ecb.completion_code) { +// printf( "Send error %d for completion code\n", packets[0].ecb.completion_code ); +//added/replaced on 11/8/98 by Victor Rachels to stop crappage + return; + // exit(1); +//end this section replacement - VR + + } + + // Fill in destination address + if ( memcmp( network, &ipx_network, 4 ) ) + memcpy( packets[0].ipx.destination.network_id, network, 4 ); + else + memset( packets[0].ipx.destination.network_id, 0, 4 ); + memcpy( packets[0].ipx.destination.node_id.address, address, 6 ); + memcpy( packets[0].ecb.immediate_address.address, immediate_address, 6 ); + packets[0].pd.packetnum = ipx_packetnum++; + + // Fill in data to send + packets[0].ecb.fragment_size = sizeof(ipx_header) + sizeof(int) + datasize; + + assert( datasize > 1 ); + assert( packets[0].ecb.fragment_size <= 576 ); + + memcpy( packets[0].pd.data, data, datasize ); + + // Send it + ipx_send_packet( &packets[0].ecb ); + +} + +void ipx_send_broadcast_packet_data( ubyte * data, int datasize ) +{ + int i, j; + ubyte broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + ubyte local_address[6]; + + // Set to all networks besides mine + for (i=0; i= Ipx_num_networks ) { + memcpy( &Ipx_networks[Ipx_num_networks++], tmp.network, 4 ); + printf(" %02x%02x%02x%02x\n", tmp.network[0], tmp.network[1], tmp.network[2], tmp.network[3] ); + } + } else { + printf( "Too many networks in %s! (Limit of %d)\n", filename, MAX_NETWORKS ); + fclose(fp); + return; + } + } + fclose(fp); + +} + +//---typedef struct rip_entry { +//--- uint network; +//--- ushort nhops; +//--- ushort nticks; +//---} rip_entry; +//--- +//---typedef struct rip_packet { +//--- ushort operation; //1=request, 2=response +//--- rip_entry rip[50]; +//---} rip_packet; +//--- +//--- +//---void ipx_find_all_servers() +//---{ +//--- int i; +//--- rip_packet * rp; +//--- assert(ipx_installed); +//--- +//--- ipx_change_default_socket( 0x0453 ); +//--- // ipx_change_default_socket( 0x5304 ); +//--- +//--- // Make sure no one is already sending something +//--- while( packets[0].ecb.in_use ) +//--- { +//--- } +//--- +//--- if (packets[0].ecb.completion_code) { +//--- printf( "AAAA:Send error %d for completion code\n", packets[0].ecb.completion_code ); +//--- //exit(1); +//--- } +//--- +//--- rp = (rip_packet *)&packets[0].pd; +//--- +//--- // Fill in destination address +//--- { +//--- char mzero1[] = {0,0,0,1}; +//--- char mzero[] = {0,0,0,0,0,1}; +//--- char immediate[6]; +//--- //memcpy( packets[0].ipx.destination.network_id, &ipx_network, 4 ); +//--- //memcpy( packets[0].ipx.destination.node_id.address, ipx_my_node.address, 6 ); +//--- +//--- memcpy( packets[0].ipx.destination.network_id, mzero1, 4 ); +//--- memcpy( packets[0].ipx.destination.node_id.address, mzero, 6 ); +//--- +//--- memcpy( packets[0].ipx.destination.socket_id, &ipx_socket, 2 ); +//--- memcpy( packets[0].ipx.source.network_id, &ipx_network, 4 ); +//--- memcpy( packets[0].ipx.source.node_id.address, ipx_my_node.address, 6 ); +//--- memcpy( packets[0].ipx.source.socket_id, &ipx_socket, 2 ); +//--- //memcpy( packets[0].ecb.immediate_address.address, ipx_my_node.address, 6 ); +//--- //mzero1[3] = 1; +//--- //memcpy( packets[0].ipx.destination.network_id, mzero1, 4 ); +//--- //mzero[5] = 1; +//--- //memcpy( packets[0].ipx.destination.node_id.address, mzero, 6 ); +//--- //ipx_get_local_target( mzero1, mzero, immediate ); +//--- //memcpy( packets[0].ecb.immediate_address.address, mzero, 6 ); +//--- //memcpy( packets[0].ecb.immediate_address.address, immediate, 6 ); +//--- //mzero[5] = 0; +//--- } +//--- +//--- packets[0].ipx.packet_type = 1; // RIP packet +//--- +//--- // Fill in data to send +//--- packets[0].ecb.fragment_size = sizeof(ipx_header) + sizeof(rip_packet); +//--- assert( packets[0].ecb.fragment_size <= 576 ); +//--- +//--- rp->operation = 0; // Request +//--- for (i=0;i<50; i++) { +//--- rp->rip[i].network = 0xFFFFFFFF; +//--- rp->rip[i].nhops = 0; +//--- rp->rip[i].nticks = 0; +//--- } +//--- +//--- // Send it +//--- ipx_send_packet( &packets[0].ecb ); +//--- +//--- for (i=0;i<50; i++) { +//--- if ( rp->rip[i].network != 0xFFFFFFFF ) +//--- printf( "Network = %8x, Hops=%d, Ticks=%d\n", rp->rip[i].network, rp->rip[i].nhops, rp->rip[i].nticks ); +//--- } +//---} +//--- +//--- + +#endif // __ENV_DJGPP__ diff --git a/arch/dos_modex.asm b/arch/dos_modex.asm new file mode 100644 index 00000000..d85f061e --- /dev/null +++ b/arch/dos_modex.asm @@ -0,0 +1,829 @@ +;THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +;SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +;END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +;ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +;IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +;SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +;FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +;CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +;AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +;COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. +; +; $Source: /cvs/cvsroot/d2x/arch/dos_modex.asm,v $ +; $Revision: 1.1.1.1 $ +; $Author: bradleyb $ +; $Date: 2001-01-19 03:33:51 $ +; +; Routines to access ModeX VGA memory +; +; $Log: not supported by cvs2svn $ +; Revision 1.1.1.1 1999/06/14 21:57:56 donut +; Import of d1x 1.37 source. +; +; Revision 1.19 1995/03/01 15:37:46 john +; Better ModeX support. +; +; Revision 1.18 1994/11/24 13:24:20 john +; Made sure that some rep movs had the cld set first. +; Took some unused functions out. +; +; Revision 1.17 1994/09/22 18:15:02 john +; Made flip page wait for retrace. +; +; Revision 1.16 1994/09/22 16:08:27 john +; Fixed some palette stuff. +; +; Revision 1.15 1994/07/13 12:03:05 john +; Added assembly modex line-drawer. +; +; Revision 1.14 1994/05/06 12:50:34 john +; Added supertransparency; neatend things up; took out warnings. +; +; Revision 1.13 1994/05/03 19:39:04 john +; *** empty log message *** +; +; Revision 1.12 1994/02/18 15:32:32 john +; *** empty log message *** +; +; Revision 1.11 1993/12/21 11:40:36 john +; *** empty log message *** +; +; Revision 1.10 1993/12/09 15:02:26 john +; Changed palette stuff majorly +; +; Revision 1.9 1993/12/03 12:11:32 john +; fixed cx/ecx loop bugs. +; +; Revision 1.8 1993/11/16 11:28:18 john +; *** empty log message *** +; +; Revision 1.7 1993/10/15 16:23:23 john +; y +; +; Revision 1.6 1993/09/28 19:07:19 john +; stripped the waitforretrace out of fade to speed things up. +; +; Revision 1.5 1993/09/26 18:58:58 john +; fade stuff +; +; Revision 1.4 1993/09/21 14:01:15 john +; turned off video before mode set to reduce flicker. +; +; Revision 1.3 1993/09/08 11:38:36 john +; changed rcs stuff at beginning. +; +; +; + + +[BITS 32] + +section .data +%include "dos_vgaregs.inc" +%include "dos_tweak.inc" + +extern _gr_var_bwidth +extern _gr_video_memory + +global _modex_line_vertincr +global _modex_line_incr1 +global _modex_line_incr2 +global _modex_line_x1 +global _modex_line_x2 +global _modex_line_y1 +global _modex_line_y2 +global _modex_line_Color + +_modex_line_vertincr dd 0 +_modex_line_incr1 dd 0 +_modex_line_incr2 dd 0 +_modex_line_x1 dd 0 +_modex_line_y1 dd 0 +_modex_line_x2 dd 0 +_modex_line_y2 dd 0 +_modex_line_Color db 0 + + +_modex_line_routine dd 0 +SavedColor db 0 + +%define LEFT_MASK1 1000b +%define LEFT_MASK2 1100b +%define LEFT_MASK3 1110b +%define RIGHT_MASK1 0001b +%define RIGHT_MASK2 0011b +%define RIGHT_MASK3 0111b +%define ALL_MASK 1111b + +tmppal times 768 db 0 +fb_pal dd 0 +fb_add dw 0 +fb_count dd 0 + +MaskTable1 db ALL_MASK & RIGHT_MASK1 + db ALL_MASK & RIGHT_MASK2 + db ALL_MASK & RIGHT_MASK3 + db ALL_MASK + db LEFT_MASK3 & RIGHT_MASK1 + db LEFT_MASK3 & RIGHT_MASK2 + db LEFT_MASK3 & RIGHT_MASK3 + db LEFT_MASK3 + db LEFT_MASK2 & RIGHT_MASK1 + db LEFT_MASK2 & RIGHT_MASK2 + db LEFT_MASK2 & RIGHT_MASK3 + db LEFT_MASK2 + db LEFT_MASK1 & RIGHT_MASK1 + db LEFT_MASK1 & RIGHT_MASK2 + db LEFT_MASK1 & RIGHT_MASK3 + db LEFT_MASK1 + +MaskTable2 db ALL_MASK,RIGHT_MASK1 + db ALL_MASK,RIGHT_MASK2 + db ALL_MASK,RIGHT_MASK3 + db ALL_MASK,ALL_MASK + db LEFT_MASK3,RIGHT_MASK1 + db LEFT_MASK3,RIGHT_MASK2 + db LEFT_MASK3,RIGHT_MASK3 + db LEFT_MASK3,ALL_MASK + db LEFT_MASK2,RIGHT_MASK1 + db LEFT_MASK2,RIGHT_MASK2 + db LEFT_MASK2,RIGHT_MASK3 + db LEFT_MASK2,ALL_MASK + db LEFT_MASK1,RIGHT_MASK1 + db LEFT_MASK1,RIGHT_MASK2 + db LEFT_MASK1,RIGHT_MASK3 + db LEFT_MASK1,ALL_MASK + +DrawTable dd DrawMR + dd DrawMR + dd DrawMR + dd DrawM + dd DrawLMR + dd DrawLMR + dd DrawLMR + dd DrawLM + dd DrawLMR + dd DrawLMR + dd DrawLMR + dd DrawLM + dd DrawLMR + dd DrawLMR + dd DrawLMR + dd DrawLM + +section .text + +global _gr_sync_display + +_gr_sync_display: + mov dx, VERT_RESCAN +VS2A: in al, dx + and al, 08h + jnz VS2A ; Loop until not in vertical retrace +VS2B: in al, dx + and al, 08h + jz VS2B ; Loop until in vertical retrace + ret + + +; gr_modex_uscanline(int x1,int x2,int y,int color); +global _gr_modex_uscanline + +_gr_modex_uscanline: + push ebx + mov eax,[esp+8];x1 + mov edx,[esp+12];x2 + mov ebx,[esp+16];y + mov ecx,[esp+20];color + push edi + + ; EAX = X1 (X1 and X2 don't need to be sorted) + ; EDX = X2 + ; EBX = Y + ; ECX = Color + + mov [SavedColor], cl + + ;mov ebx, _RowOffset[ebx*4] + mov edi, [_gr_var_bwidth] + imul edi, ebx + add edi, [_gr_video_memory] + cmp eax, edx + jle @@f1 + xchg eax, edx +@@f1: mov bl, al + shl bl, 2 + mov bh, dl + and bh, 011b + or bl, bh + and ebx, 0fh + ; BX = LeftRight switch command. (4bit) + shr eax, 2 + shr edx, 2 + add edi, eax + ; EDI = Offset into video memory + mov ecx, edx + sub ecx, eax + ; ECX = X2/4 - X1/4 - 1 + jnz LargerThan4 + +;======================= ONE GROUP OF 4 OR LESS TO DRAW ==================== + + mov dx, SC_INDEX + mov al, SC_MAP_MASK + out dx, al + inc dx + mov al, [MaskTable1+ebx] + out dx, al + mov al, [SavedColor] + mov [edi], al ; Write the one pixel + pop edi + pop ebx + ret + +LargerThan4: + dec ecx + jnz LargerThan8 + +;===================== TWO GROUPS OF 4 OR LESS TO DRAW ==================== + + mov cx, word [MaskTable2+ebx*2] + mov bl, [SavedColor] + mov dx, SC_INDEX + mov al, SC_MAP_MASK + out dx, al + inc dx + mov al, cl + out dx, al + mov [edi], bl ; Write the left pixel + mov al, ch + out dx, al + mov [edi+1], bl ; Write the right pixel + pop edi + pop ebx + ret + +;========================= MANY GROUPS OF 4 TO DRAW ====================== +LargerThan8: + mov dx, SC_INDEX + mov al, SC_MAP_MASK + out dx, al + inc dx + ; DX = SC_INDEX + mov al, [SavedColor] + mov ah, al + ; AL,AH = color of pixel + jmp dword [DrawTable+ebx*4] + + +DrawM: ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index + mov al, ALL_MASK + out dx, al + mov al, ah + cld + add ecx, 2 + shr ecx, 1 + rep stosw ; Write the middle pixels + jnc @@f2 + stosb ; Write the middle odd pixel +@@f2: pop edi + pop ebx + ret + +DrawLM: + ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index + mov al, byte [MaskTable2+ebx*2] + out dx, al + mov [edi], ah ; Write leftmost pixels + inc edi + mov al, ALL_MASK + out dx, al + mov al, ah + cld + inc ecx + shr ecx, 1 + rep stosw ; Write the middle pixels + jnc @@f3 + stosb ; Write the middle odd pixel +@@f3: pop edi + pop ebx + ret + + +DrawLMR: ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index + mov bx, word [MaskTable2+ebx*2] + mov al, bl + out dx, al + mov [edi], ah ; Write leftmost pixels + inc edi + mov al, ALL_MASK + out dx, al + mov al, ah + cld + shr ecx, 1 + rep stosw ; Write the middle pixels + jnc @@f4 + stosb ; Write the middle odd pixel +@@f4: mov al, bh + out dx, al + mov [edi], ah ; Write the rightmost pixels + pop edi + pop ebx + ret + +DrawMR: ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index + mov bx, word [MaskTable2+ebx*2] + mov al, ALL_MASK + out dx, al + mov al, ah + cld + inc ecx + shr ecx, 1 + rep stosw ; Write the middle pixels + jnc @@f5 + stosb ; Write the middle odd pixel +@@f5: mov al, bh + out dx, al + mov [edi], ah ; Write the rightmost pixels + pop edi + pop ebx + ret + + +global _gr_modex_setmode + +_gr_modex_setmode: + mov eax,[esp+4] + push ecx + push edx + push esi + push edi + + mov ecx, eax + dec ecx + + cmp ecx, LAST_X_MODE + jbe @@f6 + mov ecx, 0 +@@f6: + + ;call turn_screen_off + + push ecx ; some bios's dont preserve cx + + ;mov ax, 1201h + ;mov bl, 31h ; disable palette loading at mode switch + ;int 10h + mov ax,13h ; let the BIOS set standard 256-color + int 10h ; mode (320x200 linear) + ;mov ax, 1200h + ;mov bl, 31h ; enable palette loading at mode switch + ;int 10h + + pop ecx + + mov dx,SC_INDEX + mov ax,0604h + out dx,ax ; disable chain4 mode + + mov dx,SC_INDEX + mov ax,0100h + out dx,ax ; synchronous reset while setting Misc + ; Output for safety, even though clock + ; unchanged + + mov esi, dword [ModeTable+ecx*4] + lodsb + + or al,al + jz DontSetDot + + mov dx,MISC_OUTPUT + out dx,al ; select the dot clock and Horiz + ; scanning rate + + ;mov dx,SC_INDEX + ;mov al,01h + ;out dx,al + ;inc dx + ;in al, dx + ;or al, 1000b + ;out dx, al + +DontSetDot: + mov dx,SC_INDEX + mov ax,0300h + out dx,ax ; undo reset (restart sequencer) + + mov dx,CRTC_INDEX ; reprogram the CRT Controller + mov al,11h ; VSync End reg contains register write + out dx,al ; protect bit + inc dx ; CRT Controller Data register + in al,dx ; get current VSync End register setting + and al,07fh ; remove write protect on various + out dx,al ; CRTC registers + dec dx ; CRT Controller Index + cld + xor ecx,ecx + lodsb + mov cl,al + +SetCRTParmsLoop: + lodsw ; get the next CRT Index/Data pair + out dx,ax ; set the next CRT Index/Data pair + loop SetCRTParmsLoop + + mov dx,SC_INDEX + mov ax,0f02h + out dx,ax ; enable writes to all four planes + mov edi, [_gr_video_memory] ; point ES:DI to display memory + xor eax,eax ; clear to zero-value pixels + mov ecx,4000h ; # of dwords in display memory + rep stosd ; clear all of display memory + + ; Set pysical screen dimensions + + xor eax, eax + lodsw ; Load scrn pixel width + mov cx, ax + shl eax, 16 + + mov dx,CRTC_INDEX + mov al,CRTC_OFFSET + out dx,al + inc dx + mov ax,cx + shr ax,3 + out dx,al + + ;mov si, 360 + ;@@: + ;mov ax, 04f06h + ;mov bl, 0 + ;mov cx, si + ;int 10h + ;cmp cx, si + ;je @f + ;inc si + ;jmp @B + ;@@: + ;movzx eax, si + + lodsw ; Load Screen Phys. Height + + ;call turn_screen_on + + pop edi + pop esi + pop edx + pop ecx + + ret + +global _gr_modex_setplane + +_gr_modex_setplane: + mov eax,[esp+4] + + mov cl, al + + ; SELECT WRITE PLANE + and cl,011b ;CL = plane + mov ax,0100h + MAP_MASK ;AL = index in SC of Map Mask reg + shl ah,cl ;set only the bit for the required + ; plane to 1 + mov dx,SC_INDEX ;set the Map Mask to enable only the + out dx,ax ; pixel's plane + + ; SELECT READ PLANE + mov ah,cl ;AH = plane + mov al,READ_MAP ;AL = index in GC of the Read Map reg + mov dx,GC_INDEX ;set the Read Map to read the pixel's + out dx,ax ; plane + ret + +global _gr_modex_setstart + +_gr_modex_setstart: + push ebx + mov eax,[esp+8] + mov edx,[esp+12] + mov ebx,[esp+16] + push ebx + + ; EAX = X + ; EDX = Y + ; EBX = Wait for retrace + + mov ecx, [_gr_var_bwidth] + imul ecx, edx + + shr eax, 2 + add eax, ecx + + mov ch, ah + mov bh, al + + mov bl, CC_START_LO + mov cl, CC_START_HI + + cli + mov dx, VERT_RESCAN +WaitDE: in al, dx + test al, 01h + jnz WaitDE + + mov dx, CRTC_INDEX + mov ax, bx + out dx, ax ; Start address low + mov ax, cx + out dx, ax ; Start address high + sti + + pop ebx + cmp ebx, 0 + je NoWaitVS + mov dx, VERT_RESCAN +WaitVS: in al, dx + test al, 08h + jz WaitVS ; Loop until in vertical retrace +NoWaitVS: + + pop ebx + + ret + + + + +%macro ModeXAddr 0 +; given: ebx=x, eax=y, return cl=plane mask, ebx=address, trash eax + mov cl, bl + and cl, 3 + shr ebx, 2 + imul eax, [_gr_var_bwidth] + add ebx, eax + add ebx, [_gr_video_memory] +%endmacro + + +;----------------------------------------------------------------------- +; +; Line drawing function for all MODE X 256 Color resolutions +; Based on code from "PC and PS/2 Video Systems" by Richard Wilton. + +global _gr_modex_line + +_gr_modex_line: + pusha + + mov dx,SC_INDEX ; setup for plane mask access + +; check for vertical line + + mov esi,[_gr_var_bwidth] + mov ecx,[_modex_line_x2] + sub ecx,[_modex_line_x1] + jz near VertLine + +; force x1 < x2 + + jns L01 + + neg ecx + + mov ebx,[_modex_line_x2] + xchg ebx,[_modex_line_x1] + mov [_modex_line_x2],ebx + + mov ebx,[_modex_line_y2] + xchg ebx,[_modex_line_y1] + mov [_modex_line_y2],ebx + +; calc dy = abs(y2 - y1) + +L01: + mov ebx,[_modex_line_y2] + sub ebx,[_modex_line_y1] + jnz short skip + jmp HorizLine +skip: jns L03 + + neg ebx + neg esi + +; select appropriate routine for slope of line + +L03: + mov [_modex_line_vertincr],esi + mov dword [_modex_line_routine],LoSlopeLine + cmp ebx,ecx + jle L04 + mov dword [_modex_line_routine],HiSlopeLine + xchg ebx,ecx + +; calc initial decision variable and increments + +L04: + shl ebx,1 + mov [_modex_line_incr1],ebx + sub ebx,ecx + mov esi,ebx + sub ebx,ecx + mov [_modex_line_incr2],ebx + +; calc first pixel address + + push ecx + mov eax,[_modex_line_y1] + mov ebx,[_modex_line_x1] + ModeXAddr + mov edi,ebx + mov al,1 + shl al,cl + mov ah,al ; duplicate nybble + shl al,4 + add ah,al + mov bl,ah + pop ecx + inc ecx + jmp near dword [_modex_line_routine] + +; routine for verticle lines + +VertLine: + mov eax,[_modex_line_y1] + mov ebx,[_modex_line_y2] + mov ecx,ebx + sub ecx,eax + jge L31 + neg ecx + mov eax,ebx + +L31: + inc ecx + mov ebx,[_modex_line_x1] + push ecx + ModeXAddr + + mov ah,1 + shl ah,cl + mov al,MAP_MASK + out dx,ax + pop ecx + mov ax, word [_modex_line_Color] + +; draw the line + +L32: + mov [ebx],al + add ebx,esi + loop L32 + jmp Lexit + +; routine for horizontal line + +HorizLine: + + mov eax,[_modex_line_y1] + mov ebx,[_modex_line_x1] + ModeXAddr + + mov edi,ebx ; set dl = first byte mask + mov dl,00fh + shl dl,cl + + mov ecx,[_modex_line_x2] ; set dh = last byte mask + and cl,3 + mov dh,00eh + shl dh,cl + not dh + +; determine byte offset of first and last pixel in line + + mov eax,[_modex_line_x2] + mov ebx,[_modex_line_x1] + + shr eax,2 ; set ax = last byte column + shr ebx,2 ; set bx = first byte column + mov ecx,eax ; cx = ax - bx + sub ecx,ebx + + mov eax,edx ; mov end byte masks to ax + mov dx,SC_INDEX ; setup dx for VGA outs + mov bl,[_modex_line_Color] + +; set pixels in leftmost byte of line + + or ecx,ecx ; is start and end pt in same byte + jnz L42 ; no ! + and ah,al ; combine start and end masks + jmp short L44 + +L42: push eax + mov ah,al + mov al,MAP_MASK + out dx,ax + mov al,bl + stosb + dec ecx + +; draw remainder of the line + +L43: + mov ah,0Fh + mov al,MAP_MASK + out dx,ax + mov al,bl + rep stosb + pop eax + +; set pixels in rightmost byte of line + +L44: + mov al,MAP_MASK + out dx, ax + mov [edi],bl + jmp Lexit + + +; routine for dy >= dx (slope <= 1) + +LoSlopeLine: + mov al,MAP_MASK + mov bh,byte [_modex_line_Color] +L10: + mov ah,bl + +L11: + or ah,bl + rol bl,1 + jc L14 + +; bit mask not shifted out + + or esi,esi + jns L12 + add esi,[_modex_line_incr1] + loop L11 + + out dx,ax + mov [edi],bh + jmp short Lexit + +L12: + add esi,[_modex_line_incr2] + out dx,ax + mov [edi],bh + add edi,[_modex_line_vertincr] + loop L10 + jmp short Lexit + +; bit mask shifted out + +L14: out dx,ax + mov [edi],bh + inc edi + or esi,esi + jns L15 + add esi,[_modex_line_incr1] + loop L10 + jmp short Lexit + +L15: + add esi,[_modex_line_incr2] + add edi,[_modex_line_vertincr] + loop L10 + jmp short Lexit + +; routine for dy > dx (slope > 1) + +HiSlopeLine: + mov ebx,[_modex_line_vertincr] + mov al,MAP_MASK +L21: out dx,ax + push eax + mov al,[_modex_line_Color] + mov [edi],al + pop eax + add edi,ebx + +L22: + or esi,esi + jns L23 + + add esi,[_modex_line_incr1] + loop L21 + jmp short Lexit + +L23: + add esi,[_modex_line_incr2] + rol ah,1 + adc edi,0 +lx21: loop L21 + +; return to caller + +Lexit: + popa + ret diff --git a/arch/dos_timer.asm b/arch/dos_timer.asm new file mode 100644 index 00000000..e738fe61 --- /dev/null +++ b/arch/dos_timer.asm @@ -0,0 +1,496 @@ +[BITS 32] + +[EXTERN _atexit] +[EXTERN ___djgpp_base_address] + +[GLOBAL _timer_get_fixed_seconds] +[GLOBAL _timer_get_fixed_secondsX] +[GLOBAL _timer_get_approx_seconds] +[GLOBAL _timer_set_rate] +[GLOBAL _timer_set_function] +[GLOBAL _timer_set_joyhandler] +[GLOBAL _timer_init] +[GLOBAL _timer_close] + + +[SECTION .data] +TDATA EQU 40h +TCOMMAND EQU 43h +PIC EQU 020h +STACK_SIZE EQU 4096 + +%define df times 3 dw + +TimerData db 0 + dd 0 + dd 65536 + dd 0 + dd 0 + df 0 + df 0 + df 0 + df 0 + dd 0 + db 0 +times STACK_SIZE db 0 + +td_in_timer equ TimerData +td_nested_counter equ td_in_timer+1 +td__timer_cnt equ td_nested_counter+4 +td_dos_timer equ td__timer_cnt+4 +td_joystick_poller equ td_dos_timer+4 +td_user_function equ td_joystick_poller+4 +td_org_interrupt equ td_user_function+6 +td_saved_stack equ td_org_interrupt+6 +td_new_stack equ td_saved_stack+6 +td_tick_count equ td_new_stack+6 +td_Installed equ td_tick_count+4 +td_TimerStack equ td_Installed+1 + + +[SECTION .text] + +TIMER_LOCKED_CODE_START: + +__my_ds dw 0 + +timer_get_stamp64: +; Return a 64-bit stamp that is the number of 1.19Mhz pulses +; since the time was initialized. Returns in EDX:EAX. +; Also, interrupts must be disabled. + + xor eax, eax ; Clear all of EAX + out TCOMMAND, al ; Tell timer to latch + + mov al, 0ah ; Find if interrupt pending + out PIC, al + jmp @ + @: + in al, PIC + and eax, 01b + jz NoInterrupt + + in al, TDATA ; Read in lo byte + mov dl, al + in al, TDATA ; Read in hi byte + mov dh, al + and edx, 0ffffh + mov eax, [td__timer_cnt] + shl eax, 1 + sub eax, edx + + push ebx + mov ebx, eax + mov eax, [td_tick_count] + imul dword [td__timer_cnt] ; edx:eax = Number of 1.19 MHz ticks elapsed... + add eax, ebx + adc edx, 0 + pop ebx + + ret + +NoInterrupt: + in al, TDATA ; Read in lo byte + mov ah, al + in al, TDATA ; Read in hi byte + xchg ah, al ; arrange em correctly + mov edx, [td__timer_cnt] + sub dx, ax ; BX = timer ticks + mov ax, dx + + push ebx + mov ebx, eax + mov eax, [td_tick_count] + imul dword [td__timer_cnt] ; edx:eax = Number of 1.19 MHz ticks elapsed... + add eax, ebx + adc edx, 0 + pop ebx + + ret + + +_timer_get_fixed_seconds: + push ebx + push edx + + cli + call timer_get_stamp64 + sti + +; Timing in fixed point (16.16) seconds. +; Can be used for up to 1000 hours + shld edx, eax, 16 ; Keep 32+11 bits + shl eax, 16 +; edx:eax = number of 1.19Mhz pulses elapsed. + mov ebx, 1193180 + +; Make sure we won't divide overflow. Make time wrap at about 9 hours +sub_again: + sub edx, ebx ; subtract until negative... + jns sub_again ; ...to prevent divide overflow... + add edx, ebx ; ...then add in to get correct value. + div ebx +; eax = fixed point seconds elapsed... + + pop edx + pop ebx + + ret + + +_timer_get_fixed_secondsX: + push ebx + push edx + + call timer_get_stamp64 + +; Timing in fixed point (16.16) seconds. +; Can be used for up to 1000 hours + shld edx, eax, 16 ; Keep 32+11 bits + shl eax, 16 +; edx:eax = number of 1.19Mhz pulses elapsed. + mov ebx, 1193180 + +xsub_again: + sub edx, ebx ; subtract until negative... + jns xsub_again ; ...to prevent divide overflow... + add edx, ebx ; ...then add in to get correct value. + + div ebx +; eax = fixed point seconds elapsed... + + pop edx + pop ebx + + ret + +_timer_get_approx_seconds: + push ebx + push edx + + mov eax, [td_tick_count] + imul dword [td__timer_cnt] ; edx:eax = Number of 1.19 MHz ticks elapsed... + shld edx, eax, 16 ; Keep 32+16 bits, for conversion to fixed point + shl eax, 16 +; edx:eax = number of 1.19Mhz pulses elapsed. + mov ebx, 1193180 + +approx_sub_again: + sub edx, ebx ; subtract until negative... + jns approx_sub_again ; ...to prevent divide overflow... + add edx, ebx ; ...then add in to get correct value. + + div ebx +; eax = fixed point seconds elapsed... + + pop edx + pop ebx + ret + +;---------------------------------------------------------------------------- +;Prototype: extern void timer_set_rate(int count_val); +;---------------------------------------------------------------------------- +_timer_set_rate: + mov eax,[esp+4] +; eax = rate + pushad + +; Make sure eax below or equal to 65535 and above 0 +; if its not, make it be 65536 which is normal dos +; timing. + cmp eax, 65535 + jbe @@ + mov eax, 65536 +@@: + cmp eax, 0 + jne @@@ + mov eax, 65536 +@@@: ; Set the timer rate to eax + cli + mov dword [td_tick_count], 0 + mov [td__timer_cnt], eax + mov al, 34h ; count in binary, mode 2, load low byte then hi byte, counter 0: 00 11 010 0 + out TCOMMAND, al ; Reset PIT channel 0 + mov eax, [td__timer_cnt] + out TDATA, al + mov al, ah + out TDATA, al + sti + popad + ret + +;---------------------------------------------------------------------------- +;Prototype: extern void timer_set_function( void * function ); +;---------------------------------------------------------------------------- +_timer_set_function: +; arg1 = near pointer to user function + push eax + mov eax, [esp+8] ; arg 1 + cli + mov dword [td_user_function+0], eax ; offset + mov word [td_user_function+4], cs ; selector + sti + pop eax + ret + +_timer_set_joyhandler: + mov eax, [esp+4] + cli + mov dword [td_joystick_poller], eax + sti + ret + +;************************************************************************ +;************************************************************************ +;***** ***** +;***** T I M E R _ H A N D L E R ***** +;***** ***** +;************************************************************************ +;************************************************************************ + +timer_handler: + push ds + push es + push eax + + mov ax, [cs:__my_ds] ; Interrupt, so point to our data segment + mov ds, ax + mov es, ax + +; Increment time counter... + inc dword [td_tick_count] + + mov eax, [td__timer_cnt] + add dword [td_dos_timer], eax ; Increment DOS timer + cmp dword [td_dos_timer], 65536 + jb NoChainToOld ; See if we need to chain to DOS 18.2 + and dword [td_dos_timer], 0ffffh + +; +; Call the original DOS handler.... +; + pushfd + call far dword [td_org_interrupt] + + jmp NoReset ;old handler has reset, so we don't + +NoChainToOld: +; Reset controller + mov al, 20h ; Reset interrupt controller + out 20h, al + +NoReset: + cmp byte [td_in_timer], 0 + jne ExitInterrupt + + mov byte [td_in_timer], 1 ; Mark that we're in a timer interrupt... + + ; Reenable interrupts + sti ; Reenable interrupts + + cmp word [td_user_function+4], 0 ; Check the selector... + je NoUserFunction + +; Switch stacks while calling the user-definable function... + pushad + push fs + push gs + mov dword [td_saved_stack+0], esp + mov word [td_saved_stack+4], ss + lss esp, [td_new_stack] ; Switch to new stack + call far dword [td_user_function] ; Call new function + lss esp, [td_saved_stack] ; Switch back to original stack + pop gs + pop fs + popad + +NoUserFunction: + cmp dword [td_joystick_poller], 0 + je NoJoyPolling + mov eax, [td__timer_cnt] + mov dword [td_saved_stack+0], esp + mov word [td_saved_stack+4], ss + lss esp, [td_new_stack] ; Switch to new stack + pusha + push eax + call dword [td_joystick_poller] + pop eax + popa + lss esp, [td_saved_stack] ; Switch back to original stack + +NoJoyPolling: + cli + mov byte [td_in_timer], 0 + +ExitInterrupt: +;;mov al, 20h ; Reset interrupt controller +;;out 20h, al + pop eax + pop es + pop ds + iretd ; Return from timer interrupt + +TIMER_LOCKED_CODE_STOP: + +;************************************************************************ +;************************************************************************ +;***** ***** +;***** T I M E R _ I N I T ***** +;***** ***** +;************************************************************************ +;************************************************************************ + +_timer_init: + pushad + push ds + push es + + cmp byte [td_Installed], 1 + je NEAR AlreadyInstalled + + mov [__my_ds],ds + + mov dword [td__timer_cnt], 65536 ; Set to BIOS's normal 18.2 Hz + mov dword [td_dos_timer], 0 ; clear DOS Interrupt counter + mov dword [td_user_function+0], 0 ; offset of user function + mov word [td_user_function+4], 0 ; selector of user function + + lea eax, [ds:td_TimerStack] ; Use EAX as temp stack pointer + add eax, STACK_SIZE ; Top of stack minus space for saving old ss:esp + mov dword [td_new_stack+0], eax + mov word [td_new_stack+4], ds + + ;--------------- lock data used in interrupt + mov eax, (td_TimerStack-TimerData)+STACK_SIZE ;sizeof timer_data + mov esi, eax + shr esi, 16 + mov edi, eax + and edi, 0ffffh ; si:di = length of region to lock in bytes + mov ebx, TimerData + add ebx, [___djgpp_base_address] + mov ecx, ebx + shr ebx, 16 + and ecx, 0ffffh ; bx:cx = start of linear address to lock + mov eax, 0600h ; DPMI lock address function + int 31h ; call dpmi + jnc @@@@ + int 3 ; LOCK FAILED!! +@@@@: + ;--------------- lock code used in interrupt + mov eax, TIMER_LOCKED_CODE_STOP + sub eax, TIMER_LOCKED_CODE_START + inc eax ; EAX = size of timer interrupt handler + mov esi, eax + shr esi, 16 + mov edi, eax + and edi, 0ffffh ; si:di = length of region to lock in bytes + mov ebx, TIMER_LOCKED_CODE_START + add ebx, [___djgpp_base_address] + mov ecx, ebx + shr ebx, 16 + and ecx, 0ffffh ; bx:cx = start of linear address to lock + mov eax, 0600h ; DPMI lock address function + int 31h ; call dpmi + jnc @@@@@ ;This is getting fun + int 3 ; LOCK FAILED!! +@@@@@: + +;************************************************************** +;******************* SAVE OLD INT8 HANDLER ******************** +;************************************************************** + mov ax,0204h + mov bl,8 + int 31h + mov dword [td_org_interrupt+0],edx + mov word [td_org_interrupt+4],cx + +;************************************************************** +;***************** INSTALL NEW INT8 HANDLER ******************* +;************************************************************** + + cli + + mov al, 34h ; count in binary, mode 2, load low byte then hi byte, counter 0: 00 11 010 0 + out TCOMMAND, al ; Reset PIT channel 0 + mov eax, [td__timer_cnt] + out TDATA, al + mov al, ah + out TDATA, al + + mov dword [td_tick_count], 0 + mov byte [td_Installed],1 + + mov ax,0205h + mov bl,8 + mov edx,timer_handler + mov cx,cs + int 31h + + + sti + push dword _timer_close + call _atexit + add esp,4 + +AlreadyInstalled: + + pop es + pop ds + popad + + ret + +;************************************************************************ +;************************************************************************ +;***** ***** +;***** T I M E R _ C L O S E _ ***** +;***** ***** +;************************************************************************ +;************************************************************************ + +_timer_close: + push eax + push ebx + push ecx + push edx + + cmp byte [td_Installed], 0 + je NotInstalled + mov byte [td_Installed], 0 + +;************************************************************** +;***************** RESTORE OLD INT8 HANDLER ******************* +;************************************************************** + + cli + mov al, 36h ; count in binary, mode 3, load low byte then hi byte, counter 0: 00 11 011 0 + out TCOMMAND, al ; Reser PIT channel 0 + mov ax, 0h + out TDATA, al + mov al, ah + out TDATA, al + + mov ax,0205h + mov bl,8 + mov edx,dword [td_org_interrupt+0] + mov cx,word [td_org_interrupt+4] + int 31h + + sti + + cmp dword [td_nested_counter], 0 + je NoNestedInterrupts + mov eax, [td_nested_counter] + ;int 3 ; Get John!! + +NoNestedInterrupts: + + +NotInstalled: + pop edx + pop ecx + pop ebx + pop eax + + ret + diff --git a/arch/dos_tweak.inc b/arch/dos_tweak.inc new file mode 100644 index 00000000..4523ba0d --- /dev/null +++ b/arch/dos_tweak.inc @@ -0,0 +1,258 @@ +;THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +;SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +;END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +;ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +;IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +;SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +;FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +;CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +;AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +;COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. +; +; $Source: /cvs/cvsroot/d2x/arch/dos_tweak.inc,v $ +; $Revision: 1.1.1.1 $ +; $Author: bradleyb $ +; $Date: 2001-01-19 03:33:51 $ +; +; Parameters used by modex.asm to set various modex resolutions. +; +; $Log: not supported by cvs2svn $ +; Revision 1.1.1.1 1999/06/14 21:58:45 donut +; Import of d1x 1.37 source. +; +; Revision 1.3 1993/11/16 11:28:09 john +; *** empty log message *** +; +; Revision 1.2 1993/10/15 16:23:18 john +; y +; +; Revision 1.1 1993/09/08 11:41:09 john +; Initial revision +; +; +; + + +; Mode X CRTC register tweaks for various resolutions + +X320Y200 db 00 ; 0e3h ; dot clock + db 02 ; Number of CRTC Registers to update + dw 00014h ; turn off dword mode + dw 0e317h ; turn on byte mode + dw 320 ; width + dw 200 ; height + +X320Y240 db 0e3h ; dot clock + db 10 ; Number of CRTC Registers to update + dw 00d06h ; vertical total + dw 03e07h ; overflow (bit 8 of vertical counts) + dw 04109h ; cell height (2 to double-scan) + dw 0ea10h ; v sync start + dw 0ac11h ; v sync end and protect cr0-cr7 + dw 0df12h ; vertical displayed + dw 00014h ; turn off dword mode + dw 0e715h ; v blank start + dw 00616h ; v blank end + dw 0e317h ; turn on byte mode + dw 320 ; width + dw 240 ; height + +X360Y200 db 0e7h ; dot clock + db 08 ; Number of CRTC Registers to update + dw 06b00h ; horz total + dw 05901h ; horz displayed + dw 05a02h ; start horz blanking + dw 08e03h ; end horz blanking + dw 05e04h ; start h sync + dw 08a05h ; end h sync + dw 00014h ; turn off dword mode + dw 0e317h ; turn on byte mode + dw 360 ; width + dw 200 ; height + + +X360Y240 db 0e7h ; dot clock + db 17 ; Number of CRTC Registers to update + dw 06b00h ; horz total + dw 05901h ; horz displayed + dw 05a02h ; start horz blanking + dw 08e03h ; end horz blanking + dw 05e04h ; start h sync + dw 08a05h ; end h sync + dw 00d06h ; vertical total + dw 03e07h ; overflow (bit 8 of vertical counts) + dw 04109h ; cell height (2 to double-scan) + dw 0ea10h ; v sync start + dw 0ac11h ; v sync end and protect cr0-cr7 + dw 0df12h ; vertical displayed + dw 02d13h ; offset; + dw 00014h ; turn off dword mode + dw 0e715h ; v blank start + dw 00616h ; v blank end + dw 0e317h ; turn on byte mode + dw 360 + dw 240 + +X376Y282 db 0e7h + db 18 + dw 06e00h ; horz total + dw 05d01h ; horz displayed + dw 05e02h ; start horz blanking + dw 09103h ; end horz blanking + dw 06204h ; start h sync + dw 08f05h ; end h sync + dw 06206h ; vertical total + dw 0f007h ; overflow + dw 06109h ; cell height + dw 0310fh ; + dw 03710h ; v sync start + dw 08911h ; v sync end and protect cr0-cr7 + dw 03312h ; vertical displayed + dw 02f13h ; offset + dw 00014h ; turn off dword mode + dw 03c15h ; v blank start + dw 05c16h ; v blank end + dw 0eb17h ; turn on byte mode + dw 376 + dw 282 + + +X320Y400 db 0h ; dot clock + db 03 ; Number of CRTC Registers to update + dw 04009h ; cell height + dw 00014h ; turn off dword mode + dw 0e317h ; turn on byte mode + dw 320 ; width + dw 400 ; height + +X320Y480 db 0e3h ; dotclock + db 10 ; Number of CRTC Registers to update + dw 00d06h ; vertical total + dw 03e07h ; overflow (bit 8 of vertical counts) + dw 04009h ; cell height (2 to double-scan) + dw 0ea10h ; v sync start + dw 0ac11h ; v sync end and protect cr0-cr7 + dw 0df12h ; vertical displayed + dw 00014h ; turn off dword mode + dw 0e715h ; v blank start + dw 00616h ; v blank end + dw 0e317h ; turn on byte mode + dw 320 ; width + dw 480 ; height + +X360Y400 db 0e7h ; dot clock + db 09 ; Number of CRTC Registers to update + dw 06b00h ; horz total + dw 05901h ; horz displayed + dw 05a02h ; start horz blanking + dw 08e03h ; end horz blanking + dw 05e04h ; start h sync + dw 08a05h ; end h sync + dw 04009h ; cell height + dw 00014h ; turn off dword mode + dw 0e317h ; turn on byte mode + dw 360 ; width + dw 400 ; height + +X360Y480 db 0e7h + db 17 + dw 06b00h ; horz total + dw 05901h ; horz displayed + dw 05a02h ; start horz blanking + dw 08e03h ; end horz blanking + dw 05e04h ; start h sync + dw 08a05h ; end h sync + dw 00d06h ; vertical total + dw 03e07h ; overflow + dw 04009h ; cell height + dw 0ea10h ; v sync start + dw 0ac11h ; v sync end and protect cr0-cr7 + dw 0df12h ; vertical displayed + dw 02d13h ; offset + dw 00014h ; turn off dword mode + dw 0e715h ; v blank start + dw 00616h ; v blank end + dw 0e317h ; turn on byte mode + dw 360 + dw 480 + +X360Y360 db 0e7h + db 15 + dw 06b00h ; horz total + dw 05901h ; horz displayed + dw 05a02h ; start horz blanking + dw 08e03h ; end horz blanking + dw 05e04h ; start h sync + dw 08a05h ; end h sync + dw 04009h ; cell height + dw 08810h ; v sync start + dw 08511h ; v sync end and protect cr0-cr7 + dw 06712h ; vertical displayed + dw 02d13h ; offset + dw 00014h ; turn off dword mode + dw 06d15h ; v blank start + dw 0ba16h ; v blank end + dw 0e317h ; turn on byte mode + dw 360 + dw 360 + +X376Y308 db 0e7h + db 18 + dw 06e00h ; horz total + dw 05d01h ; horz displayed + dw 05e02h ; start horz blanking + dw 09103h ; end horz blanking + dw 06204h ; start h sync + dw 08f05h ; end h sync + dw 06206h ; vertical total + dw 00f07h ; overflow + dw 04009h ; + dw 0310fh ; + dw 03710h ; v sync start + dw 08911h ; v sync end and protect cr0-cr7 + dw 03312h ; vertical displayed + dw 02f13h ; offset + dw 00014h ; turn off dword mode + dw 03c15h ; v blank start + dw 05c16h ; v blank end + dw 0e317h ; turn on byte mode + dw 376 + dw 308 + +X376Y564 db 0e7h + db 18 + dw 06e00h ; horz total + dw 05d01h ; horz displayed + dw 05e02h ; start horz blanking + dw 09103h ; end horz blanking + dw 06204h ; start h sync + dw 08f05h ; end h sync + dw 06206h ; vertical total + dw 0f007h ; overflow + dw 06009h ; + dw 0310fh ; + dw 03710h ; v sync start + dw 08911h ; v sync end and protect cr0-cr7 + dw 03312h ; vertical displayed + dw 02f13h ; offset + dw 00014h ; turn off dword mode + dw 03c15h ; v blank start + dw 05c16h ; v blank end + dw 0e317h ; turn on byte mode + dw 376 + dw 564 + +%define LAST_X_MODE 11 + +ModeTable dd X320Y200 + dd X320Y240 + dd X360Y200 + dd X360Y240 + dd X376Y282 + dd X320Y400 + dd X320Y480 + dd X360Y400 + dd X360Y480 + dd X360Y360 + dd X376Y308 + dd X376Y564 diff --git a/arch/dos_vesa.c b/arch/dos_vesa.c new file mode 100644 index 00000000..fd965b50 --- /dev/null +++ b/arch/dos_vesa.c @@ -0,0 +1,140 @@ +#include +#ifdef __ENV_DJGPP__ + + +#include +#include "gr.h" +#include "grdef.h" +#include "u_dpmi.h" +#include "vesa.h" + +#define SC_INDEX 0x3c4 +#define CRTC_INDEX 0x3d4 +#define CRTC_DATA 0x3d5 + +static int bankshift; +static int lastbank; + +/* this comes from Allegro */ +typedef struct vesa_mode_info +{ + unsigned short ModeAttributes; + unsigned char WinAAttributes; + unsigned char WinBAttributes; + unsigned short WinGranularity; + unsigned short WinSize; + unsigned short WinASegment; + unsigned short WinBSegment; + unsigned long WinFuncPtr; + unsigned short BytesPerScanLine; + unsigned short XResolution; + unsigned short YResolution; + unsigned char XCharSize; + unsigned char YCharSize; + unsigned char NumberOfPlanes; + unsigned char BitsPerPixel; + unsigned char NumberOfBanks; + unsigned char MemoryModel; + unsigned char BankSize; + unsigned char NumberOfImagePages; + unsigned char Reserved_page; + unsigned char RedMaskSize; + unsigned char RedMaskPos; + unsigned char GreenMaskSize; + unsigned char GreenMaskPos; + unsigned char BlueMaskSize; + unsigned char BlueMaskPos; + unsigned char ReservedMaskSize; + unsigned char ReservedMaskPos; + unsigned char DirectColorModeInfo; + unsigned long PhysBasePtr; + unsigned long OffScreenMemOffset; + unsigned short OffScreenMemSize; + unsigned char Reserved[206]; +} __attribute__ ((packed)) vesa_mode_info; + + +int gr_vesa_checkmode(int mode) { + int i; + dpmi_real_regs rregs; + vesa_mode_info *mode_info; + + if (!(mode_info = dpmi_get_temp_low_buffer( 1024 ))) + return 7; + rregs.eax = 0x4f01; + rregs.ecx = mode; + rregs.edi = DPMI_real_offset(mode_info); + rregs.es = DPMI_real_segment(mode_info); + dpmi_real_int386x( 0x10, &rregs ); + if (rregs.eax != 0x4f) + return 5; /* no vesa */ + if (!(mode_info->ModeAttributes & 1)) + return 4; /* unsupported mode */ + + bankshift = 0; + i = mode_info->WinGranularity; + while (i < 64) { + i <<= 1; + bankshift++; + } + if (i != 64) + return 2; /* incompatible window granularity */ + return 0; +} + +int gr_vesa_setmode(int mode) { + int ret; + lastbank = -1; + if ((ret = gr_vesa_checkmode(mode))) + return ret; + asm volatile("int $0x10" : "=a" (ret) : "a" (0x4f02), "b" (mode)); + return (ret == 0x4f) ? 0 : 4; +} + +inline void gr_vesa_setpage(int bank) { + if (bank != lastbank) + asm volatile("int $0x10" + : : "a" (0x4f05), "b" (0), "d" ((lastbank = bank) << bankshift)); +} + +void gr_vesa_incpage() { + gr_vesa_setpage(lastbank + 1); +} + +void gr_vesa_setstart(int col, int row) { + asm volatile("int $0x10" + : : "a" (0x4f07), "b" (0), "c" (col), "d" (row)); +} + +int gr_vesa_setlogical(int line_width) { + int ret; + asm volatile("int $0x10" + : "=c" (ret) : "a" (0x4f07), "b" (0), "c" (line_width)); + return ret; +} + +void gr_vesa_scanline(int x1, int x2, int y, unsigned char color) { + int addr = (y * gr_var_bwidth) + x1; + int left = x2 - x1 + 1; + gr_vesa_setpage(addr >> 16); + addr &= 0xffff; + while (left) { + if (left > (65536 - addr)) { + left -= (65536 - addr); + memset(gr_video_memory + addr, color, 65536 - addr); + addr = 0; + gr_vesa_incpage(); + } else { + memset(gr_video_memory + addr, color, left); + left = 0; + } + } +} + +void gr_vesa_pixel(unsigned char color, unsigned int addr) { + gr_vesa_setpage(addr >> 16); + gr_video_memory[addr & 0xffff] = color; +} + + +#endif // __ENV_DJGPP__ diff --git a/arch/dos_vgaregs.inc b/arch/dos_vgaregs.inc new file mode 100644 index 00000000..5434bfdd --- /dev/null +++ b/arch/dos_vgaregs.inc @@ -0,0 +1,62 @@ +;THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +;SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +;END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +;ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +;IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +;SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +;FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +;CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +;AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +;COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. +; +; $Source: /cvs/cvsroot/d2x/arch/dos_vgaregs.inc,v $ +; $Revision: 1.1.1.1 $ +; $Author: bradleyb $ +; $Date: 2001-01-19 03:33:51 $ +; +; Readable descriptions of VGA ports. +; +; $Log: not supported by cvs2svn $ +; Revision 1.1.1.1 1999/06/14 21:58:45 donut +; Import of d1x 1.37 source. +; +; Revision 1.2 1993/10/15 16:22:45 john +; *** empty log message *** +; +; Revision 1.1 1993/09/08 11:41:00 john +; Initial revision +; +; +; + + +%define MISC_OUTPUT 03c2h ;Miscellaneous Output register +%define MAP_MASK 02h ;index in SC of Map Mask register +%define READ_MAP 04h ;index in GC of the Read Map register +%define BIT_MASK 08h ;index in GC of Bit Mask register + +%define SC_INDEX 3c4h ;Index register for sequencer ctrl. +%define SC_MAP_MASK 2 ;Number of map mask register + +%define SC_INDEX 3c4h ;Index register for sequencer ctrl. +%define SC_MAP_MASK 2 ;Number of map mask register +%define SC_MEM_MODE 4 ;Number of memory mode register + +%define GC_INDEX 3ceh ;Index register for graphics ctrl. +%define GC_READ_MAP 4 ;Number of read map register +%define GC_GRAPH_MODE 5 ;Number of graphics mode register +%define GC_MISCELL 6 ;Number of miscellaneous register + +%define CRTC_INDEX 3d4h ;Index register for CRT controller +%define CC_MAX_SCAN 9 ;Number of maximum scan line reg. +%define CC_START_HI 0Ch ;Number of start address high register +%define CC_START_LO 0Dh ;Number of start address low register +%define CC_UNDERLINE 14h ;Number of underline register +%define CC_MODE_CTRL 17h ;Number of mode control register +%define CRTC_OFFSET 13h ; CRTC offset register index + +%define DAC_WRITE_ADR 3C8h ;DAC write address +%define DAC_READ_ADR 3C7h ;DAC read address +%define DAC_DATA 3C9h ;DAC data register + +%define VERT_RESCAN 3DAh ;Input status register #1 diff --git a/arch/linux/Makefile.am b/arch/linux/Makefile.am index c0749e0f..4c991cae 100644 --- a/arch/linux/Makefile.am +++ b/arch/linux/Makefile.am @@ -1,6 +1,10 @@ +ifndef ENV_DJGPP + noinst_LIBRARIES = libarchlinux.a INCLUDES = -I $(top_srcdir)/includes -I../../input/sdl/include -I../../input/linux/include -I $(top_srcdir)/main -Iinclude libarchlinux_a_SOURCES = \ init.c ipx_lin.c \ ipx_bsd.c ipx_udp.c linuxnet.c findfile.c + +endif diff --git a/arch/linux/Makefile.in b/arch/linux/Makefile.in index 66efad5d..48a44fe7 100644 --- a/arch/linux/Makefile.in +++ b/arch/linux/Makefile.in @@ -185,7 +185,7 @@ distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ if test -d $$d/$$file; then \ - cp -pr $$d/$$file $(distdir)/$$file; \ + cp -pr $$/$$file $(distdir)/$$file; \ else \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ @@ -297,6 +297,8 @@ mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean +ifndef ENV_DJGPP + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/arch/linux/findfile.c b/arch/linux/findfile.c index 70ab4edb..6fcb350f 100644 --- a/arch/linux/findfile.c +++ b/arch/linux/findfile.c @@ -1,4 +1,6 @@ #include +#ifdef __ENV_LINUX__ + #include #include #include @@ -51,3 +53,6 @@ int FileFindClose(void) globfree(&glob_a); return 0; } + + +#endif // __ENV_LINUX__ diff --git a/arch/linux/init.c b/arch/linux/init.c index 3d4fa7e0..41330ae6 100644 --- a/arch/linux/init.c +++ b/arch/linux/init.c @@ -1,5 +1,7 @@ // linux init.c - added Matt Mueller 9/6/98 #include +#ifdef __ENV_LINUX__ + #include #include #include "pstypes.h" @@ -44,3 +46,6 @@ void arch_init() //end addition -MM key_init(); } + + +#endif // __ENV_LINUX__ diff --git a/arch/linux/ipx_bsd.c b/arch/linux/ipx_bsd.c index 9e78b861..de7f6710 100644 --- a/arch/linux/ipx_bsd.c +++ b/arch/linux/ipx_bsd.c @@ -1,6 +1,7 @@ /* IPX driver using BSD style sockets */ /* Mostly taken from dosemu */ #include +#ifdef __ENV_LINUX__ #ifdef NETWORK #include @@ -226,3 +227,4 @@ struct ipx_driver ipx_bsd = { ipx_general_PacketReady }; #endif // NETWORK +#endif // __ENV_LINUX__ diff --git a/arch/linux/ipx_lin.c b/arch/linux/ipx_lin.c index 91ab95a3..459d4204 100644 --- a/arch/linux/ipx_lin.c +++ b/arch/linux/ipx_lin.c @@ -1,4 +1,7 @@ #include + +#ifdef __ENV_LINUX__ + #ifdef NETWORK #include #include @@ -212,3 +215,4 @@ int ipx_linux_ReceivePacket(ipx_socket_t *s, char *buffer, int bufsize, return size; } #endif // NETWORK +#endif // __ENV_LINUX__ diff --git a/arch/linux/ipx_udp.c b/arch/linux/ipx_udp.c index c369a284..48a11250 100644 --- a/arch/linux/ipx_udp.c +++ b/arch/linux/ipx_udp.c @@ -59,6 +59,7 @@ */ #include +#ifdef __ENV_LINUX__ #ifdef NETWORK #include #include @@ -589,3 +590,4 @@ struct ipx_driver ipx_udp = { ipx_general_PacketReady }; #endif // NETWORK +#endif // __ENV_LINUX__ diff --git a/arch/linux/linuxnet.c b/arch/linux/linuxnet.c index c06b938b..e96f724b 100644 --- a/arch/linux/linuxnet.c +++ b/arch/linux/linuxnet.c @@ -12,6 +12,7 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. */ #include +#ifdef __ENV_LINUX__ #ifdef NETWORK #include #include @@ -364,3 +365,4 @@ void ipx_read_network_file(char * filename) fclose(fp); } #endif //NETWORK +#endif // __ENV_LINUX__ diff --git a/arch/linux_findfile.c b/arch/linux_findfile.c new file mode 100644 index 00000000..6fcb350f --- /dev/null +++ b/arch/linux_findfile.c @@ -0,0 +1,58 @@ +#include +#ifdef __ENV_LINUX__ + +#include +#include +#include +#include "findfile.h" +#include "u_mem.h" +#include "error.h" + +/* KLUDGE ALERT: evil globals */ +static glob_t glob_a; +static int glob_whichfile; + +int FileFindFirst(char *search_str, FILEFINDSTRUCT *ffstruct) +{ + int r; + char *t; + + Assert(search_str != NULL); + Assert(ffstruct != NULL); + + r = glob(search_str, 0, NULL, &glob_a); + if (r == GLOB_NOMATCH) return -1; + + glob_whichfile = 0; + + t = strrchr(glob_a.gl_pathv[glob_whichfile], '/'); + if (t == NULL) t = glob_a.gl_pathv[glob_whichfile]; else t++; + strncpy(ffstruct->name, t, 255); + ffstruct->size = strlen(ffstruct->name); + + return 0; +} + +int FileFindNext(FILEFINDSTRUCT *ffstruct) +{ + char *t; + + glob_whichfile++; + + if (glob_whichfile >= glob_a.gl_pathc) return -1; + + t = strrchr(glob_a.gl_pathv[glob_whichfile], '/'); + if (t == NULL) t = glob_a.gl_pathv[glob_whichfile]; else t++; + strncpy(ffstruct->name, t, 255); + ffstruct->size = strlen(ffstruct->name); + return 0; +} + +int FileFindClose(void) +{ + globfree(&glob_a); + return 0; +} + + +#endif // __ENV_LINUX__ diff --git a/arch/linux_init.c b/arch/linux_init.c new file mode 100644 index 00000000..41330ae6 --- /dev/null +++ b/arch/linux_init.c @@ -0,0 +1,51 @@ +// linux init.c - added Matt Mueller 9/6/98 +#include +#ifdef __ENV_LINUX__ + +#include +#include +#include "pstypes.h" +#include "console.h" +#include "text.h" +#include "event.h" +#include "error.h" +#include "joy.h" +#include "args.h" + +extern void arch_sdl_init(); +extern void arch_svgalib_init(); +extern void key_init(); +extern int com_init(); +extern void timer_init(); + +void arch_init_start() +{ + +} + +void arch_init() +{ + // Initialise the library + arch_sdl_init(); +#ifdef __SVGALIB__ + arch_svgalib_init(); +#endif + if (!args_find( "-nojoystick" )) { + con_printf(CON_VERBOSE, "\n%s", TXT_VERBOSE_6); + joy_init(); + } + //added 06/09/99 Matt Mueller - fix nonetwork compile +#ifdef NETWORK + //end addition -MM +//added on 10/19/98 by Victor Rachels to add serial support (from DPH) + if(!(args_find("-noserial"))) + com_init(); +//end this section addition - Victor + //added 06/09/99 Matt Mueller - fix nonetwork compile +#endif + //end addition -MM + key_init(); +} + + +#endif // __ENV_LINUX__ diff --git a/arch/linux_ipx_bsd.c b/arch/linux_ipx_bsd.c new file mode 100644 index 00000000..de7f6710 --- /dev/null +++ b/arch/linux_ipx_bsd.c @@ -0,0 +1,230 @@ +/* IPX driver using BSD style sockets */ +/* Mostly taken from dosemu */ +#include +#ifdef __ENV_LINUX__ +#ifdef NETWORK + +#include +#include +#include +#include + +#ifdef HAVE_NETIPX_IPX_H +#include +#else +# include +# ifndef IPX_TYPE +# define IPX_TYPE 1 +# endif +#endif + +#include +#include +#include + +#include "pstypes.h" +#include "ipx_drv.h" +#include "ipx_bsd.h" + +#ifndef DOSEMU +#include "mono.h" +#define n_printf(format, args...) mprintf((1, format, ## args)) +#define enter_priv_on() +#define leave_priv_setting() +#endif + +static int ipx_bsd_GetMyAddress( void ) +{ + int sock; + struct sockaddr_ipx ipxs; + struct sockaddr_ipx ipxs2; + int len; + int i; + + sock=socket(AF_IPX,SOCK_DGRAM,PF_IPX); + if(sock==-1) + { + n_printf("IPX: could not open socket in GetMyAddress\n"); + return(-1); + } + + /* bind this socket to network 0 */ + ipxs.sipx_family=AF_IPX; +#ifdef IPX_MANUAL_ADDRESS + memcpy(&ipxs.sipx_network, ipx_MyAddress, 4); +#else + ipxs.sipx_network=0; +#endif + ipxs.sipx_port=0; + + if(bind(sock,(struct sockaddr *)&ipxs,sizeof(ipxs))==-1) + { + n_printf("IPX: could bind to network 0 in GetMyAddress\n"); + close( sock ); + return(-1); + } + + len = sizeof(ipxs2); + if (getsockname(sock,(struct sockaddr *)&ipxs2,&len) < 0) { + n_printf("IPX: could not get socket name in GetMyAddress\n"); + close( sock ); + return(-1); + } + + memcpy(ipx_MyAddress, &ipxs2.sipx_network, 4); + for (i = 0; i < 6; i++) { + ipx_MyAddress[4+i] = ipxs2.sipx_node[i]; + } + close( sock ); + return(0); +} + +static int ipx_bsd_OpenSocket(ipx_socket_t *sk, int port) +{ + int sock; /* sock here means Linux socket handle */ + int opt; + struct sockaddr_ipx ipxs; + int len; + struct sockaddr_ipx ipxs2; + + /* DANG_FIXTHIS - kludge to support broken linux IPX stack */ + /* need to convert dynamic socket open into a real socket number */ +/* if (port == 0) { + n_printf("IPX: using socket %x\n", nextDynamicSocket); + port = nextDynamicSocket++; + } +*/ + /* do a socket call, then bind to this port */ + sock = socket(AF_IPX, SOCK_DGRAM, PF_IPX); + if (sock == -1) { + n_printf("IPX: could not open IPX socket.\n"); + return -1; + } + +#ifdef DOSEMU + opt = 1; + /* turn on socket debugging */ + if (d.network) { + enter_priv_on(); + if (setsockopt(sock, SOL_SOCKET, SO_DEBUG, &opt, sizeof(opt)) == -1) { + leave_priv_setting(); + n_printf("IPX: could not set socket option for debugging.\n"); + return -1; + } + leave_priv_setting(); + } +#endif + opt = 1; + /* Permit broadcast output */ + enter_priv_on(); + if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, + &opt, sizeof(opt)) == -1) { + leave_priv_setting(); + n_printf("IPX: could not set socket option for broadcast.\n"); + return -1; + } +#ifdef DOSEMU + /* allow setting the type field in the IPX header */ + opt = 1; +#if 0 /* this seems to be wrong: IPX_TYPE can only be set on level SOL_IPX */ + if (setsockopt(sock, SOL_SOCKET, IPX_TYPE, &opt, sizeof(opt)) == -1) { +#else + /* the socket _is_ an IPX socket, hence it first passes ipx_setsockopt() + * in file linux/net/ipx/af_ipx.c. This one handles SOL_IPX itself and + * passes SOL_SOCKET-levels down to sock_setsockopt(). + * Hence I guess the below is correct (can somebody please verify this?) + * -- Hans, June 14 1997 + */ + if (setsockopt(sock, SOL_IPX, IPX_TYPE, &opt, sizeof(opt)) == -1) { +#endif + leave_priv_setting(); + n_printf("IPX: could not set socket option for type.\n"); + return -1; + } +#endif + ipxs.sipx_family = AF_IPX; + ipxs.sipx_network = *((unsigned int *)&ipx_MyAddress[0]); +/* ipxs.sipx_network = htonl(MyNetwork); */ + bzero(ipxs.sipx_node, 6); /* Please fill in my node name */ + ipxs.sipx_port = htons(port); + + /* now bind to this port */ + if (bind(sock, (struct sockaddr *) &ipxs, sizeof(ipxs)) == -1) { + n_printf("IPX: could not bind socket to address\n"); + close( sock ); + leave_priv_setting(); + return -1; + } + + if( port==0 ) { + len = sizeof(ipxs2); + if (getsockname(sock,(struct sockaddr *)&ipxs2,&len) < 0) { + n_printf("IPX: could not get socket name in IPXOpenSocket\n"); + close( sock ); + leave_priv_setting(); + return -1; + } else { + port = htons(ipxs2.sipx_port); + n_printf("IPX: opened dynamic socket %04x\n", port); + } + } + leave_priv_setting(); + sk->fd = sock; + sk->socket = port; + return 0; +} + +static void ipx_bsd_CloseSocket(ipx_socket_t *mysock) { + /* now close the file descriptor for the socket, and free it */ + n_printf("IPX: closing file descriptor on socket %x\n", mysock->socket); + close(mysock->fd); +} + +static int ipx_bsd_SendPacket(ipx_socket_t *mysock, IPXPacket_t *IPXHeader, + u_char *data, int dataLen) { + struct sockaddr_ipx ipxs; + + ipxs.sipx_family = AF_IPX; + /* get destination address from IPX packet header */ + memcpy(&ipxs.sipx_network, IPXHeader->Destination.Network, 4); + /* if destination address is 0, then send to my net */ + if (ipxs.sipx_network == 0) { + ipxs.sipx_network = *((unsigned int *)&ipx_MyAddress[0]); +/* ipxs.sipx_network = htonl(MyNetwork); */ + } + memcpy(&ipxs.sipx_node, IPXHeader->Destination.Node, 6); + memcpy(&ipxs.sipx_port, IPXHeader->Destination.Socket, 2); + ipxs.sipx_type = IPXHeader->PacketType; + /* ipxs.sipx_port=htons(0x452); */ + return sendto(mysock->fd, data, dataLen, 0, + (struct sockaddr *) &ipxs, sizeof(ipxs)); +} + +static int ipx_bsd_ReceivePacket(ipx_socket_t *s, char *buffer, int bufsize, + struct ipx_recv_data *rd) { + int sz, size; + struct sockaddr_ipx ipxs; + + sz = sizeof(ipxs); + if ((size = recvfrom(s->fd, buffer, bufsize, 0, + (struct sockaddr *) &ipxs, &sz)) <= 0) + return size; + memcpy(rd->src_network, &ipxs.sipx_network, 4); + memcpy(rd->src_node, ipxs.sipx_node, 6); + rd->src_socket = ipxs.sipx_port; + rd->dst_socket = s->socket; + rd->pkt_type = ipxs.sipx_type; + + return size; +} + +struct ipx_driver ipx_bsd = { + ipx_bsd_GetMyAddress, + ipx_bsd_OpenSocket, + ipx_bsd_CloseSocket, + ipx_bsd_SendPacket, + ipx_bsd_ReceivePacket, + ipx_general_PacketReady +}; +#endif // NETWORK +#endif // __ENV_LINUX__ diff --git a/arch/linux_ipx_lin.c b/arch/linux_ipx_lin.c new file mode 100644 index 00000000..459d4204 --- /dev/null +++ b/arch/linux_ipx_lin.c @@ -0,0 +1,218 @@ +#include + +#ifdef __ENV_LINUX__ + +#ifdef NETWORK +#include +#include +#include +#include + +#ifdef HAVE_NETIPX_IPX_H +#include +#else +# include +# ifndef IPX_TYPE +# define IPX_TYPE 1 +# endif +#endif + +#include +#include +#include +#include "pstypes.h" + +#include "ipx_ld.h" +#include "ipx_hlpr.h" +#include "ipx_lin.h" + +extern unsigned char ipx_MyAddress[10]; + +int +ipx_linux_GetMyAddress( void ) +{ + int sock; + struct sockaddr_ipx ipxs; + struct sockaddr_ipx ipxs2; + int len; + int i; + + sock=socket(AF_IPX,SOCK_DGRAM,PF_IPX); + if(sock==-1) + { + n_printf("IPX: could not open socket in GetMyAddress\n"); + return(-1); + } + + /* bind this socket to network 0 */ + ipxs.sipx_family=AF_IPX; +#ifdef IPX_MANUAL_ADDRESS + memcpy(&ipxs.sipx_network, ipx_MyAddress, 4); +#else + ipxs.sipx_network=0; +#endif + ipxs.sipx_port=0; + + if(bind(sock,(struct sockaddr *)&ipxs,sizeof(ipxs))==-1) + { + n_printf("IPX: could bind to network 0 in GetMyAddress\n"); + close( sock ); + return(-1); + } + + len = sizeof(ipxs2); + if (getsockname(sock,(struct sockaddr *)&ipxs2,&len) < 0) { + n_printf("IPX: could not get socket name in GetMyAddress\n"); + close( sock ); + return(-1); + } + + memcpy(ipx_MyAddress, &ipxs2.sipx_network, 4); + for (i = 0; i < 6; i++) { + ipx_MyAddress[4+i] = ipxs2.sipx_node[i]; + } + close( sock ); + return(0); +} + +int +ipx_linux_OpenSocket(ipx_socket_t *sk, int port) +{ + int sock; /* sock here means Linux socket handle */ + int opt; + struct sockaddr_ipx ipxs; + int len; + struct sockaddr_ipx ipxs2; + + /* DANG_FIXTHIS - kludge to support broken linux IPX stack */ + /* need to convert dynamic socket open into a real socket number */ +/* if (port == 0) { + n_printf("IPX: using socket %x\n", nextDynamicSocket); + port = nextDynamicSocket++; + } +*/ + /* do a socket call, then bind to this port */ + sock = socket(AF_IPX, SOCK_DGRAM, PF_IPX); + if (sock == -1) { + n_printf("IPX: could not open IPX socket.\n"); + return -1; + } + +#ifdef DOSEMU + opt = 1; + /* turn on socket debugging */ + if (d.network) { + enter_priv_on(); + if (setsockopt(sock, SOL_SOCKET, SO_DEBUG, &opt, sizeof(opt)) == -1) { + leave_priv_setting(); + n_printf("IPX: could not set socket option for debugging.\n"); + return -1; + } + leave_priv_setting(); + } +#endif + opt = 1; + /* Permit broadcast output */ + enter_priv_on(); + if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, + &opt, sizeof(opt)) == -1) { + leave_priv_setting(); + n_printf("IPX: could not set socket option for broadcast.\n"); + return -1; + } +#ifdef DOSEMU + /* allow setting the type field in the IPX header */ + opt = 1; +#if 0 /* this seems to be wrong: IPX_TYPE can only be set on level SOL_IPX */ + if (setsockopt(sock, SOL_SOCKET, IPX_TYPE, &opt, sizeof(opt)) == -1) { +#else + /* the socket _is_ an IPX socket, hence it first passes ipx_setsockopt() + * in file linux/net/ipx/af_ipx.c. This one handles SOL_IPX itself and + * passes SOL_SOCKET-levels down to sock_setsockopt(). + * Hence I guess the below is correct (can somebody please verify this?) + * -- Hans, June 14 1997 + */ + if (setsockopt(sock, SOL_IPX, IPX_TYPE, &opt, sizeof(opt)) == -1) { +#endif + leave_priv_setting(); + n_printf("IPX: could not set socket option for type.\n"); + return -1; + } +#endif + ipxs.sipx_family = AF_IPX; + ipxs.sipx_network = *((unsigned int *)&ipx_MyAddress[0]); +/* ipxs.sipx_network = htonl(MyNetwork); */ + bzero(ipxs.sipx_node, 6); /* Please fill in my node name */ + ipxs.sipx_port = htons(port); + + /* now bind to this port */ + if (bind(sock, (struct sockaddr *) &ipxs, sizeof(ipxs)) == -1) { + n_printf("IPX: could not bind socket to address\n"); + close( sock ); + leave_priv_setting(); + return -1; + } + + if( port==0 ) { + len = sizeof(ipxs2); + if (getsockname(sock,(struct sockaddr *)&ipxs2,&len) < 0) { + n_printf("IPX: could not get socket name in IPXOpenSocket\n"); + close( sock ); + leave_priv_setting(); + return -1; + } else { + port = htons(ipxs2.sipx_port); + n_printf("IPX: opened dynamic socket %04x\n", port); + } + } + leave_priv_setting(); + sk->fd = sock; + sk->socket = port; + return 0; +} + +void ipx_linux_CloseSocket(ipx_socket_t *mysock) { + /* now close the file descriptor for the socket, and free it */ + n_printf("IPX: closing file descriptor on socket %x\n", mysock->socket); + close(mysock->fd); +} + +int ipx_linux_SendPacket(ipx_socket_t *mysock, IPXPacket_t *IPXHeader, + u_char *data, int dataLen) { + struct sockaddr_ipx ipxs; + + ipxs.sipx_family = AF_IPX; + /* get destination address from IPX packet header */ + memcpy(&ipxs.sipx_network, IPXHeader->Destination.Network, 4); + /* if destination address is 0, then send to my net */ + if (ipxs.sipx_network == 0) { + ipxs.sipx_network = *((unsigned int *)&ipx_MyAddress[0]); +/* ipxs.sipx_network = htonl(MyNetwork); */ + } + memcpy(&ipxs.sipx_node, IPXHeader->Destination.Node, 6); + memcpy(&ipxs.sipx_port, IPXHeader->Destination.Socket, 2); + ipxs.sipx_type = IPXHeader->PacketType; + /* ipxs.sipx_port=htons(0x452); */ + return sendto(mysock->fd, data, dataLen, 0, + (struct sockaddr *) &ipxs, sizeof(ipxs)); +} + +int ipx_linux_ReceivePacket(ipx_socket_t *s, char *buffer, int bufsize, + struct ipx_recv_data *rd) { + int sz, size; + struct sockaddr_ipx ipxs; + + sz = sizeof(ipxs); + if ((size = recvfrom(s->fd, buffer, bufsize, 0, + (struct sockaddr *) &ipxs, &sz)) <= 0) + return size; + memcpy(rd->src_network, &ipxs.sipx_network, 4); + memcpy(rd->src_node, ipxs.sipx_node, 6); + rd->src_socket = ipxs.sipx_port; + rd->dst_socket = s->socket; + rd->pkt_type = ipxs.sipx_type; + + return size; +} +#endif // NETWORK +#endif // __ENV_LINUX__ diff --git a/arch/linux_ipx_udp.c b/arch/linux_ipx_udp.c new file mode 100644 index 00000000..48a11250 --- /dev/null +++ b/arch/linux_ipx_udp.c @@ -0,0 +1,593 @@ +/* IPX driver for native Linux TCP/IP networking (UDP implementation) + * Version 0.99.2 + * Contact Jan [Lace] Kratochvil for assistance + * (no "It somehow doesn't work! What should I do?" complaints, please) + * Special thanks to Vojtech Pavlik for testing. + * + * Also you may see KIX - KIX kix out KaliNix (in Linux-Linux only): + * http://atrey.karlin.mff.cuni.cz/~short/sw/kix.c.gz + * + * Primarily based on ipx_kali.c - "IPX driver for KaliNix interface" + * which is probably mostly by Jay Cotton . + * Parts shamelessly stolen from my KIX v0.99.2 and GGN v0.100 + * + * Changes: + * -------- + * 0.99.1 - now the default broadcast list also contains all point-to-point + * links with their destination peer addresses + * 0.99.2 - commented a bit :-) + * - now adds to broadcast list each host it gets some packet from + * which is already not covered by local physical ethernet broadcast + * - implemented short-signature packet format + * - compatibility mode for old D1X releases due to the previous bullet + * + * Configuration: + * -------------- + * No network server software is needed, neither KIX nor KaliNIX. + * + * Add command line argument "-udp". In default operation D1X will send + * broadcasts too all the local interfaces found. But you may also use + * additional parameter specified after "-udp" to modify the default + * broadcasting style and UDP port numbers binding: + * + * ./d1x -udp [@SHIFT]=HOST_LIST Broadcast ONLY to HOST_LIST + * ./d1x -udp [@SHIFT]+HOST_LIST Broadcast both to local ifaces & to HOST_LIST + * + * HOST_LIST is a comma (',') separated list of HOSTs: + * HOST is an IPv4 address (so-called quad like 192.168.1.2) or regular hostname + * HOST can also be in form 'address:SHIFT' + * SHIFT sets the UDP port base offset (e.g. +2), can be used to run multiple + * clients on one host simultaneously. This SHIFT has nothing to do + * with the dynamic-sockets (PgUP/PgDOWN) option in Descent, it's another + * higher-level differentiation option. + * + * Examples: + * --------- + * ./d1x -udp + * - Run D1X to participate in normal local network (Linux only, of course) + * + * ./d1x -udp @1=localhost:2 & ./d1x -udp @2=localhost:1 + * - Run two clients simultaneously fighting each other (only each other) + * + * ./d1x -udp =192.168.4.255 + * - Run distant Descent which will participate with remote network + * 192.168.4.0 with netmask 255.255.255.0 (broadcast has 192.168.4.255) + * - You'll have to also setup hosts in that network accordingly: + * ./d1x -udp +UPPER_DISTANT_MACHINE_NAME + * + * Have fun! + */ + +#include +#ifdef __ENV_LINUX__ +#ifdef NETWORK +#include +#include +#include /* for htons & co. */ +#include +#include +#include +#include +#include +#include +#include + +#include "ipx_drv.h" +#include "args.h" + +extern unsigned char ipx_MyAddress[10]; + +// #define UDPDEBUG + +#define UDP_BASEPORT 28342 +#define PORTSHIFT_TOLERANCE 0x100 +#define MAX_PACKETSIZE 8192 + +/* Packet format: first is the signature { 0xD1,'X' } which can be also + * { 'D','1','X','u','d','p'} for old-fashioned packets. + * Then follows virtual socket number (as changed during PgDOWN/PgUP) + * in network-byte-order as 2 bytes (u_short). After such 4/8 byte header + * follows raw data as communicated with D1X network core functions. + */ + +// Length HAS TO BE 6! +#define D1Xudp "D1Xudp" +// Length HAS TO BE 2! +#define D1Xid "\xD1X" + +static int open_sockets = 0; +static int dynamic_socket = 0x401; +static const int val_one=1; + +/* OUR port. Can be changed by "@X[+=]..." argument (X is the shift value) + */ + +static int baseport=UDP_BASEPORT; + +/* Have we some old D1X in network and have we to maintain compatibility? + * FIXME: Following scenario is braindead: + * A (NEW) , B (OLD) , C (NEW) + * host A) We start new D1X. A-newcomm, B-none , C-none + * host B) We start OLD D1X. A-newcomm, B-oldcomm, C-none + * Now host A hears host B and switches: A-oldcomm, B-oldcomm, C-none + * host C) We start new D1X. A-oldcomm, B-oldcomm, C-newcomm + * Now host C hears host A/B and switches: A-oldcomm, B-oldcomm, C-oldcomm + * Now host B finishes: A-oldcomm, B-none , C-oldcomm + * + * But right now we have hosts A and C, both new code equipped but + * communicating wastefully by the OLD protocol! Bummer. + */ + +static char compatibility=0; + +static int have_empty_address() { + int i; + for (i = 0; i < 10 && !ipx_MyAddress[i]; i++) ; + return i == 10; +} + +#define MSGHDR "IPX_udp: " + +static void msg(const char *fmt,...) +{ +va_list ap; + fputs(MSGHDR,stdout); + va_start(ap,fmt); + vprintf(fmt,ap); + va_end(ap); + putchar('\n'); +} + +static void chk(void *p) +{ + if (p) return; + msg("FATAL: Virtual memory exhausted!"); + exit(EXIT_FAILURE); +} + +#define FAIL(m...) do { msg(#m); return -1; } while (0) + +/* Find as much as MAX_BRDINTERFACES during local iface autoconfiguration. + * Note that more interfaces can be added during manual configuration + * or host-received-packet autoconfiguration + */ + +#define MAX_BRDINTERFACES 16 + +/* We require the interface to be UP and RUNNING to accept it. + */ + +#define IF_REQFLAGS (IFF_UP|IFF_RUNNING) + +/* We reject any interfaces declared as LOOPBACK type. + */ +#define IF_NOTFLAGS (IFF_LOOPBACK) + +static struct sockaddr_in *broads,broadmasks[MAX_BRDINTERFACES]; +static int broadnum,masksnum,broadsize; + +/* We'll check whether the "broads" array of destination addresses is now + * full and so needs expanding. + */ + +static void chkbroadsize(void) +{ + if (broadnumsin_family!=AF_INET || sinmp->sin_family!=AF_INET) continue; + broads[j]=*sinp; + broads[j].sin_port=UDP_BASEPORT; //FIXME: No possibility to override from cmdline + broadmasks[j]=*sinmp; + j++; + } + broadnum=j; + masksnum=j; + return(0); +} + +#define addreq(a,b) ((a).sin_port==(b).sin_port&&(a).sin_addr.s_addr==(b).sin_addr.s_addr) + +/* Previous function addiflist() can (and probably will) report multiple + * same addresses. On some Linux boxes is present both device "eth0" and + * "dummy0" with the same IP addreesses - we'll filter it here. + */ + +static void unifyiflist(void) +{ +int d=0,s,i; + + for (s=0;s=s) broads[d++]=broads[s]; + } + broadnum=d; +} + +static unsigned char qhbuf[6]; + +/* Parse PORTSHIFT numeric parameter + */ + +static void portshift(const char *cs) +{ +long port; +unsigned short ports=0; + + port=atol(cs); + if (port<-PORTSHIFT_TOLERANCE || port>+PORTSHIFT_TOLERANCE) + msg("Invalid portshift in \"%s\", tolerance is +/-%d",cs,PORTSHIFT_TOLERANCE); + else ports=htons(port); + memcpy(qhbuf+4,&ports,2); +} + +/* Do hostname resolve on name "buf" and return the address in buffer "qhbuf". + */ +static unsigned char *queryhost(char *buf) +{ +struct hostent *he; +char *s; +char c=0; + + if ((s=strrchr(buf,':'))) { + c=*s; + *s='\0'; + portshift(s+1); + } + else memset(qhbuf+4,0,2); + he=gethostbyname((char *)buf); + if (s) *s=c; + if (!he) { + msg("Error resolving my hostname \"%s\"",buf); + return(NULL); + } + if (he->h_addrtype!=AF_INET || he->h_length!=4) { + msg("Error parsing resolved my hostname \"%s\"",buf); + return(NULL); + } + if (!*he->h_addr_list) { + msg("My resolved hostname \"%s\" address list empty",buf); + return(NULL); + } + memcpy(qhbuf,(*he->h_addr_list),4); + return(qhbuf); +} + +/* Dump raw form of IP address/port by fancy output to user + */ +static void dumpraddr(unsigned char *a) +{ +short port; + printf("[%u.%u.%u.%u]",a[0],a[1],a[2],a[3]); + port=(signed short)ntohs(*(unsigned short *)(a+4)); + if (port) printf(":%+d",port); +} + +/* Like dumpraddr() but for structure "sockaddr_in" + */ + +static void dumpaddr(struct sockaddr_in *sin) +{ +unsigned short ports; + + memcpy(qhbuf+0,&sin->sin_addr,4); + ports=htons(((short)ntohs(sin->sin_port))-UDP_BASEPORT); + memcpy(qhbuf+4,&ports,2); + dumpraddr(qhbuf); +} + +/* Startup... Uninteresting parsing... + */ + +static int ipx_udp_GetMyAddress(void) { + +char buf[256]; +int i; +char *s,*s2,*ns; + + if (!have_empty_address()) + return 0; + + if (!((i=args_find("-udp")) && (s=Args[i+1]) && (*s=='=' || *s=='+' || *s=='@'))) s=NULL; + + if (gethostname(buf,sizeof(buf))) FAIL("Error getting my hostname"); + if (!(queryhost(buf))) FAIL("Querying my own hostname \"%s\"",buf); + + if (s) while (*s=='@') { + portshift(++s); + while (isdigit(*s)) s++; + } + + memset(ipx_MyAddress+0,0,4); + memcpy(ipx_MyAddress+4,qhbuf,6); + baseport+=(short)ntohs(*(unsigned short *)(qhbuf+4)); + + if (!s || (s && !*s)) addiflist(); + else { + if (*s=='+') addiflist(); + s++; + for (;;) { +struct sockaddr_in *sin; + while (isspace(*s)) s++; + if (!*s) break; + for (s2=s;*s2 && *s2!=',';s2++); + chk(ns=malloc(s2-s+1)); + memcpy(ns,s,s2-s); + ns[s2-s]='\0'; + if (!queryhost(ns)) msg("Ignored broadcast-destination \"%s\" as being invalid",ns); + free(ns); + chkbroadsize(); + sin=broads+(broadnum++); + sin->sin_family=AF_INET; + memcpy(&sin->sin_addr,qhbuf+0,4); + sin->sin_port=htons(((short)ntohs(*(unsigned short *)(qhbuf+4)))+UDP_BASEPORT); + s=s2+(*s2==','); + } + } + + unifyiflist(); + + printf(MSGHDR "Using TCP/IP address "); + dumpraddr(ipx_MyAddress+4); + putchar('\n'); + if (broadnum) { + printf(MSGHDR "Using %u broadcast-dest%s:",broadnum,(broadnum==1?"":"s")); + for (i=0;ifd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)) < 0) { + sk->fd = -1; + FAIL("socket() creation failed on port %d: %m",port); + } + if (setsockopt(sk->fd,SOL_SOCKET,SO_BROADCAST,&val_one,sizeof(val_one))) { + if (close(sk->fd)) msg("close() failed during error recovery: %m"); + sk->fd=-1; + FAIL("setsockopt(SO_BROADCAST) failed: %m"); + } + sin.sin_family=AF_INET; + sin.sin_addr.s_addr=htonl(INADDR_ANY); + sin.sin_port=htons(baseport); + if (bind(sk->fd,(struct sockaddr *)&sin,sizeof(sin))) { + if (close(sk->fd)) msg("close() failed during error recovery: %m"); + sk->fd=-1; + FAIL("bind() to UDP port %d failed: %m",baseport); + } + + open_sockets++; + sk->socket = port; + return 0; +} + +/* The same comment as in previous "ipx_udp_OpenSocket"... + */ + +static void ipx_udp_CloseSocket(ipx_socket_t *mysock) { + if (!open_sockets) { + msg("close w/o open"); + return; + } + msg("CloseSocket on D1X socket port %d",mysock->socket); + if (close(mysock->fd)) + msg("close() failed on CloseSocket D1X socket port %d: %m",mysock->socket); + mysock->fd=-1; + if (--open_sockets) { + msg("(closesocket) %d sockets left", open_sockets); + return; + } +} + +/* Here we'll send the packet to our host. If it is unicast packet, send + * it to IP address/port as retrieved from IPX address. Otherwise (broadcast) + * we'll repeat the same data to each host in our broadcasting list. + */ + +static int ipx_udp_SendPacket(ipx_socket_t *mysock, IPXPacket_t *IPXHeader, + u_char *data, int dataLen) { + struct sockaddr_in toaddr,*dest; + int i=dataLen; + int bcast; + char *buf; + +#ifdef UDPDEBUG + msg("SendPacket enter, dataLen=%d",dataLen); +#endif + if (dataLen<0 || dataLen>MAX_PACKETSIZE) return -1; + chk(buf=alloca(8+dataLen)); + if (compatibility) memcpy(buf+0,D1Xudp,6),buf+=6; + else memcpy(buf+0,D1Xid ,2),buf+=2; + memcpy(buf+0,IPXHeader->Destination.Socket,2); + memcpy(buf+2,data,dataLen); + + toaddr.sin_family=AF_INET; + memcpy(&toaddr.sin_addr,IPXHeader->Destination.Node+0,4); + toaddr.sin_port=htons(((short)ntohs(*(unsigned short *)(IPXHeader->Destination.Node+4)))+UDP_BASEPORT); + + for (bcast=(toaddr.sin_addr.s_addr==htonl(INADDR_BROADCAST)?0:-1);bcast=0) dest=broads+bcast; + else dest=&toaddr; + +#ifdef UDPDEBUG + printf(MSGHDR "sendto((%d),Node=[4] %02X %02X,Socket=%02X %02X,s_port=%u,", + dataLen, + IPXHeader->Destination.Node [4],IPXHeader->Destination.Node [5], + IPXHeader->Destination.Socket[0],IPXHeader->Destination.Socket[1], + ntohs(dest->sin_port)); + dumpaddr(dest); + puts(")."); +#endif + i=sendto(mysock->fd,buf-(compatibility?6:2),(compatibility?8:4)+dataLen, + 0,(struct sockaddr *)dest,sizeof(*dest)); + if (bcast==-1) return (i<8?-1:i-8); + } + return(dataLen); +} + +/* Here we will receive new packet to the given buffer. Both formats of packets + * are supported, we fallback to old format when first obsolete packet is seen. + * If the (valid) packet is received from unknown host, we will add it to our + * broadcasting list. FIXME: For now such autoconfigured hosts are NEVER removed. + */ + +static int ipx_udp_ReceivePacket(ipx_socket_t *s, char *outbuf, int outbufsize, + struct ipx_recv_data *rd) { + int size; + struct sockaddr_in fromaddr; + int fromaddrsize=sizeof(fromaddr); + unsigned short ports; + size_t offs; + int i; + + if ((size=recvfrom(s->fd,outbuf,outbufsize,0,(struct sockaddr *)&fromaddr,&fromaddrsize))<0) + return -1; +#ifdef UDPDEBUG + printf(MSGHDR "recvfrom((%d-8=%d),",size,size-8); + dumpaddr(&fromaddr); + puts(")."); +#endif + if (fromaddr.sin_family!=AF_INET) return -1; + if (size<4) return -1; + if (memcmp(outbuf+0,D1Xid,2)) { + if (size<8 || memcmp(outbuf+0,D1Xudp,6)) return -1; + if (!compatibility) { + compatibility=1; + fputs(MSGHDR "Received obsolete packet from ",stdout); + dumpaddr(&fromaddr); + puts(", upgrade that machine.\n" MSGHDR "Turning on compatibility mode..."); + } + offs=6; + } + else offs=2; + + /* Lace: (dst_socket & src_socket) should be network-byte-order by comment in include/ipx_drv.h */ + /* This behaviour presented here is broken. It is not used anywhere, so why bother? */ + rd->src_socket = ntohs(*(unsigned short *)(outbuf+offs)); + if (rd->src_socket != s->socket) { +#ifdef UDPDEBUG + msg(" - pkt was dropped (dst=%d,my=%d)",rd->src_socket,s->socket); +#endif + return -1; + } + rd->dst_socket = s->socket; + + for (i=0;i=masksnum) { + if (addreq(fromaddr,broads[i])) break; + } + else { + if (fromaddr.sin_port==broads[i].sin_port + &&( fromaddr.sin_addr.s_addr & broadmasks[i].sin_addr.s_addr) + ==(broads[i].sin_addr.s_addr & broadmasks[i].sin_addr.s_addr)) break; + } + } + if (i>=broadnum) { + chkbroadsize(); + broads[broadnum++]=fromaddr; + fputs(MSGHDR "Adding host ",stdout); + dumpaddr(&fromaddr); + puts(" to broadcasting address list"); + } + + memmove(outbuf,outbuf+offs+2,size-(offs+2)); + size-=offs+2; + + memcpy(rd->src_node+0,&fromaddr.sin_addr,4); + ports=htons(ntohs(fromaddr.sin_port)-UDP_BASEPORT); + memcpy(rd->src_node+4,&ports,2); + memset(rd->src_network, 0, 4); + rd->pkt_type = 0; +#ifdef UDPDEBUG + printf(MSGHDR "ReceivePacket: size=%d,from=",size); + dumpraddr(rd->src_node); + putchar('\n'); +#endif + + return size; +} + +struct ipx_driver ipx_udp = { + ipx_udp_GetMyAddress, + ipx_udp_OpenSocket, + ipx_udp_CloseSocket, + ipx_udp_SendPacket, + ipx_udp_ReceivePacket, + ipx_general_PacketReady +}; +#endif // NETWORK +#endif // __ENV_LINUX__ diff --git a/arch/linux_net.c b/arch/linux_net.c new file mode 100644 index 00000000..e96f724b --- /dev/null +++ b/arch/linux_net.c @@ -0,0 +1,368 @@ +/* +THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. +*/ +#include + +#ifdef __ENV_LINUX__ +#ifdef NETWORK +#include +#include +#include +#include +#include +#include /* for htons & co. */ + +#include "pstypes.h" +#include "config.h" +#include "args.h" + +#include "ipx_drv.h" +#include "ipx_bsd.h" +#include "ipx_kali.h" +#include "ipx_udp.h" +//added 05/17/99 Matt Mueller - needed to redefine FD_* so that no asm is used +//#include "checker.h" +//end addition -MM +#define MAX_IPX_DATA 576 + +int ipx_fd; +ipx_socket_t ipx_socket_data; +ubyte ipx_installed=0; +ushort ipx_socket = 0; +uint ipx_network = 0; +ubyte ipx_MyAddress[10]; +int ipx_packetnum = 0; /* Sequence number */ +//int ipx_packettotal=0,ipx_lastspeed=0; + +/* User defined routing stuff */ +typedef struct user_address { + ubyte network[4]; + ubyte node[6]; + ubyte address[6]; +} user_address; +#define MAX_USERS 64 +int Ipx_num_users = 0; +user_address Ipx_users[MAX_USERS]; + +#define MAX_NETWORKS 64 +int Ipx_num_networks = 0; +uint Ipx_networks[MAX_NETWORKS]; + +void ipx_close(void); + +int ipx_general_PacketReady(ipx_socket_t *s) { + fd_set set; + struct timeval tv; + + FD_ZERO(&set); + FD_SET(s->fd, &set); + tv.tv_sec = tv.tv_usec = 0; + if (select(s->fd + 1, &set, NULL, NULL, &tv) > 0) + return 1; + else + return 0; +} + +struct ipx_driver *driver = &ipx_bsd; + +ubyte * ipx_get_my_server_address() +{ + return (ubyte *)&ipx_network; +} + +ubyte * ipx_get_my_local_address() +{ + return (ubyte *)(ipx_MyAddress + 4); +} + +//--------------------------------------------------------------- +// Initializes all IPX internals. +// If socket_number==0, then opens next available socket. +// Returns: 0 if successful. +// -1 if socket already open. +// -2 if socket table full. +// -3 if IPX not installed. +// -4 if couldn't allocate low dos memory +// -5 if error with getting internetwork address +int ipx_init( int socket_number, int show_address ) +{ + int i; + +/* DPH: killed kali for now + if (args_find("-kali")) { + printf("Using Kali for network games\n"); + driver = &ipx_kali; +//added on 12/20/98 by Jan Kratochvil for direct TCP/IP games + } else*/ if (args_find("-udp")) { + printf("Using native TCP/IP (UDP) for network games\n"); + driver = &ipx_udp; +//end this section addition - JK + } else { + printf("Using real IPX for network games\n"); + driver = &ipx_bsd; + } + if ((i = args_find("-ipxnetwork")) && Args[i + 1]) { + unsigned long n = strtol(Args[i + 1], NULL, 16); + ipx_MyAddress[0] = n >> 24; ipx_MyAddress[1] = (n >> 16) & 255; + ipx_MyAddress[2] = (n >> 8) & 255; ipx_MyAddress[3] = n & 255; + printf("IPX: Using network %08x\n", (unsigned int)n); + } + if (driver->OpenSocket(&ipx_socket_data, socket_number)) { + return -3; + } + driver->GetMyAddress(); + memcpy(&ipx_network, ipx_MyAddress, 4); + Ipx_num_networks = 0; + memcpy( &Ipx_networks[Ipx_num_networks++], &ipx_network, 4 ); + ipx_installed = 1; + atexit(ipx_close); + return 0; +} + +void ipx_close() +{ + if (ipx_installed) + driver->CloseSocket(&ipx_socket_data); + ipx_installed = 0; +} + +int ipx_get_packet_data( ubyte * data ) +{ + struct ipx_recv_data rd; + char buf[MAX_IPX_DATA]; +//killed 6-15-99 to get rid of compile warnings - OE +// uint best_id = 0; +// uint pkt_num; +//end kill - OE + int size; + int best_size = 0; +//edited 04/12/99 Matt Mueller - duh, we don't want to throw all that data away! + //--killed-- Like the original, only take latest packet, throw away rest + //do _NOT_ throw them away! + while (driver->PacketReady(&ipx_socket_data)) { + if ((size = + driver->ReceivePacket(&ipx_socket_data, buf, + sizeof(buf), &rd)) > 4) { + if (!memcmp(rd.src_network, ipx_MyAddress, 10)) + continue; /* don't get own pkts */ +//--killed-- pkt_num = *(uint *)buf; +//--killed-- if (pkt_num >= best_id) { + memcpy(data, buf + 4, size - 4); + return size-4; +//--killed-- best_id = pkt_num; +//--killed-- best_size = size - 4; +//--killed-- } +//end edit -MM + } + } + return best_size; +} + +void ipx_send_packet_data( ubyte * data, int datasize, ubyte *network, ubyte *address, ubyte *immediate_address ) +{ + u_char buf[MAX_IPX_DATA]; + IPXPacket_t ipx_header; + + memcpy(ipx_header.Destination.Network, network, 4); + memcpy(ipx_header.Destination.Node, immediate_address, 6); + *(u_short *)ipx_header.Destination.Socket = htons(ipx_socket_data.socket); + ipx_header.PacketType = 4; /* Packet Exchange */ + *(uint *)buf = ipx_packetnum++; + //ipx_packettotal+=datasize+4; + //if (f2i(Players[Player_num].time_level) && (f2i(Players[Player_num].time_level)%10!=ipx_lastspeed)) + //{ + // ipx_lastspeed=f2i(Players[Player_num].time_level)%10; + // printf("tot=%i,t2=%i,time=%i,avg=%i,a2=%i\n",ipx_packetnum,ipx_packettotal,(int)f2i(Players[Player_num].time_level), + // ipx_packetnum/(int)f2i(Players[Player_num].time_level), + // ipx_packettotal/(int)f2i(Players[Player_num].time_level)); + //} + memcpy(buf + 4, data, datasize); + driver->SendPacket(&ipx_socket_data, &ipx_header, buf, datasize + 4); +} + +void ipx_get_local_target( ubyte * server, ubyte * node, ubyte * local_target ) +{ + // let's hope Linux knows how to route it + memcpy( local_target, node, 6 ); +} + +void ipx_send_broadcast_packet_data( ubyte * data, int datasize ) +{ + int i, j; + ubyte broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + ubyte local_address[6]; + + // Set to all networks besides mine + for (i=0; iCloseSocket(&ipx_socket_data); + if (driver->OpenSocket(&ipx_socket_data, socket_number)) { + return -3; + } + return 0; +} + +void ipx_read_user_file(char * filename) +{ + FILE * fp; + user_address tmp; + char temp_line[132], *p1; + int n, ln=0, x; + + if (!filename) return; + + Ipx_num_users = 0; + + fp = fopen( filename, "rt" ); + if ( !fp ) return; + + printf( "Broadcast Users:\n" ); + + while (fgets(temp_line, 132, fp)) { + ln++; + p1 = strchr(temp_line,'\n'); if (p1) *p1 = '\0'; + p1 = strchr(temp_line,';'); if (p1) *p1 = '\0'; +#if 1 // adb: replaced sscanf(..., "%2x...", (char *)...) with better, but longer code + if (strlen(temp_line) >= 21 && temp_line[8] == '/') { + for (n = 0; n < 4; n++) { + if (sscanf(temp_line + n * 2, "%2x", &x) != 1) + break; + tmp.network[n] = x; + } + if (n != 4) + continue; + for (n = 0; n < 6; n++) { + if (sscanf(temp_line + 9 + n * 2, "%2x", &x) != 1) + break; + tmp.node[n] = x; + } + if (n != 6) + continue; + } else + continue; +#else + n = sscanf( temp_line, "%2x%2x%2x%2x/%2x%2x%2x%2x%2x%2x", &tmp.network[0], &tmp.network[1], &tmp.network[2], &tmp.network[3], &tmp.node[0], &tmp.node[1], &tmp.node[2],&tmp.node[3], &tmp.node[4], &tmp.node[5] ); + if ( n != 10 ) continue; +#endif + if ( Ipx_num_users < MAX_USERS ) { + ubyte * ipx_real_buffer = (ubyte *)&tmp; + ipx_get_local_target( tmp.network, tmp.node, tmp.address ); + Ipx_users[Ipx_num_users++] = tmp; + printf( "%02X%02X%02X%02X/", ipx_real_buffer[0],ipx_real_buffer[1],ipx_real_buffer[2],ipx_real_buffer[3] ); + printf( "%02X%02X%02X%02X%02X%02X\n", ipx_real_buffer[4],ipx_real_buffer[5],ipx_real_buffer[6],ipx_real_buffer[7],ipx_real_buffer[8],ipx_real_buffer[9] ); + } else { + printf( "Too many addresses in %s! (Limit of %d)\n", filename, MAX_USERS ); + fclose(fp); + return; + } + } + fclose(fp); +} + + +void ipx_read_network_file(char * filename) +{ + FILE * fp; + user_address tmp; + char temp_line[132], *p1; + int i, n, ln=0, x; + + if (!filename) return; + + fp = fopen( filename, "rt" ); + if ( !fp ) return; + + printf( "Using Networks:\n" ); + for (i=0; i= 8) { + for (n = 0; n < 4; n++) { + if (sscanf(temp_line + n * 2, "%2x", &x) != 1) + break; + tmp.network[n] = x; + } + if (n != 4) + continue; + } else + continue; +#else + n = sscanf( temp_line, "%2x%2x%2x%2x", &tmp.network[0], &tmp.network[1], &tmp.network[2], &tmp.network[3] ); + if ( n != 4 ) continue; +#endif + if ( Ipx_num_networks < MAX_NETWORKS ) { + int j; + for (j=0; j= Ipx_num_networks ) { + memcpy( &Ipx_networks[Ipx_num_networks++], tmp.network, 4 ); + printf(" %02x%02x%02x%02x\n", tmp.network[0], tmp.network[1], tmp.network[2], tmp.network[3] ); + } + } else { + printf( "Too many networks in %s! (Limit of %d)\n", filename, MAX_NETWORKS ); + fclose(fp); + return; + } + } + fclose(fp); +} +#endif //NETWORK +#endif // __ENV_LINUX__ diff --git a/arch/sdl/Makefile.in b/arch/sdl/Makefile.in index d4985647..5af03369 100644 --- a/arch/sdl/Makefile.in +++ b/arch/sdl/Makefile.in @@ -182,7 +182,7 @@ distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ if test -d $$d/$$file; then \ - cp -pr $$d/$$file $(distdir)/$$file; \ + cp -pr $$/$$file $(distdir)/$$file; \ else \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ diff --git a/arch/sdl_init.c b/arch/sdl_init.c new file mode 100644 index 00000000..33c77794 --- /dev/null +++ b/arch/sdl_init.c @@ -0,0 +1,32 @@ +// SDL architecture support +#include +#ifdef __ENV_LINUX__ +#include +#include +#include +#include "text.h" +#include "event.h" +#include "error.h" +#include "args.h" + +extern void d_mouse_init(); + +void sdl_close() +{ + SDL_Quit(); +} + +void arch_sdl_init() +{ + // Initialise the library +//edited on 01/03/99 by Matt Mueller - if we use SDL_INIT_EVERYTHING, cdrom is initialized even if -nocdaudio is used +#ifdef SDL_INPUT + if (!args_find("-nomouse")) + d_mouse_init(); +#endif + if (!args_find("-nosound")) + digi_init(); + atexit(sdl_close); +} + +#endif // __ENV_LINUX__ diff --git a/arch/sdl_timer.c b/arch/sdl_timer.c new file mode 100644 index 00000000..44e9cf31 --- /dev/null +++ b/arch/sdl_timer.c @@ -0,0 +1,15 @@ +// SDL library timer functions + +#include +#ifdef __ENV_LINUX__ +#include +#include "maths.h" + +fix timer_get_fixed_seconds(void) { + fix x; + unsigned long tv_now = SDL_GetTicks(); + x=i2f(tv_now/1000) | fixdiv(i2f(tv_now % 1000),i2f(1000)); + return x; +} + +#endif diff --git a/conf.h.in b/conf.h.in index b75dd216..70c4c9d6 100644 --- a/conf.h.in +++ b/conf.h.in @@ -18,18 +18,27 @@ /* Define if you want an OpenGL build */ #undef OGL +/* Define if building under linux */ +#undef __ENV_LINUX__ + +/* Define if building under msdos */ +#undef __ENV_DJGPP__ + +/* General defines */ #define NMONO 1 -#define SDL_AUDIO 1 #define PIGGY_USE_PAGING 1 #define NEWDEMO 1 -#ifdef OGL -# define GLX_VIDEO 1 -# define GII_INPUT 1 -# define GII_XWIN 1 -#else -# define SDL_VIDEO 1 -# define SDL_INPUT 1 -#endif -#define __ENV_LINUX__ 1 +#ifdef __ENV_LINUX__ +# define SDL_AUDIO 1 + +# ifdef OGL +# define GLX_VIDEO 1 +# define GII_INPUT 1 +# define GII_XWIN 1 +# else +# define SDL_VIDEO 1 +# define SDL_INPUT 1 +# endif +#endif diff --git a/configure b/configure index 02c4ae72..683ade7a 100644 --- a/configure +++ b/configure @@ -15,11 +15,11 @@ ac_help="$ac_help --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer" ac_help="$ac_help - --without-assembler Do not use assembler optimization " + --with-opengl Build OpenGL support " ac_help="$ac_help - --without-network Do not build network/serial support " + --without-assembler Do not use assembler optimization " ac_help="$ac_help - --with-opengl Build OpenGL support " + --without-network Do not build network/serial support " # Initialize some variables set by options. # The variables have the same names as the options, with @@ -704,7 +704,7 @@ fi PACKAGE=d2x -VERSION=0.0.8 +VERSION=0.0.9 if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } @@ -811,11 +811,10 @@ fi - # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:819: checking for $ac_word" >&5 +echo "configure:818: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -845,7 +844,7 @@ if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:849: checking for $ac_word" >&5 +echo "configure:848: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -896,7 +895,7 @@ fi # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:900: checking for $ac_word" >&5 +echo "configure:899: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -928,7 +927,7 @@ fi fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:932: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:931: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. @@ -939,12 +938,12 @@ cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF -#line 943 "configure" +#line 942 "configure" #include "confdefs.h" main(){return(0);} EOF -if { (eval echo configure:948: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:947: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -970,12 +969,12 @@ if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:974: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:973: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:979: checking whether we are using GNU C" >&5 +echo "configure:978: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -984,7 +983,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:988: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:987: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -1003,7 +1002,7 @@ ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:1007: checking whether ${CC-cc} accepts -g" >&5 +echo "configure:1006: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1035,7 +1034,7 @@ else fi echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6 -echo "configure:1039: checking for POSIXized ISC" >&5 +echo "configure:1038: checking for POSIXized ISC" >&5 if test -d /etc/conf/kconfig.d && grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1 then @@ -1058,7 +1057,7 @@ fi # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1062: checking for $ac_word" >&5 +echo "configure:1061: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1088,7 +1087,7 @@ if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1092: checking for $ac_word" >&5 +echo "configure:1091: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1139,7 +1138,7 @@ fi # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1143: checking for $ac_word" >&5 +echo "configure:1142: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1171,7 +1170,7 @@ fi fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:1175: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:1174: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. @@ -1182,12 +1181,12 @@ cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF -#line 1186 "configure" +#line 1185 "configure" #include "confdefs.h" main(){return(0);} EOF -if { (eval echo configure:1191: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1190: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -1213,12 +1212,12 @@ if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:1217: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:1216: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:1222: checking whether we are using GNU C" >&5 +echo "configure:1221: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1227,7 +1226,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1231: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1230: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -1246,7 +1245,7 @@ ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:1250: checking whether ${CC-cc} accepts -g" >&5 +echo "configure:1249: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1280,7 +1279,7 @@ fi # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1284: checking for $ac_word" >&5 +echo "configure:1283: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1308,7 +1307,7 @@ else fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:1312: checking how to run the C preprocessor" >&5 +echo "configure:1311: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -1323,13 +1322,13 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1333: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1332: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -1340,13 +1339,13 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1350: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1349: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -1357,13 +1356,13 @@ else rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1367: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1366: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -1388,12 +1387,12 @@ fi echo "$ac_t""$CPP" 1>&6 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:1392: checking for ANSI C header files" >&5 +echo "configure:1391: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -1401,7 +1400,7 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1405: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1404: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -1418,7 +1417,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -1436,7 +1435,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -1457,7 +1456,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -1468,7 +1467,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:1472: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:1471: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -1493,12 +1492,12 @@ fi echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6 -echo "configure:1497: checking for Cygwin environment" >&5 +echo "configure:1496: checking for Cygwin environment" >&5 if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1512: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_cygwin=yes else @@ -1526,19 +1525,19 @@ echo "$ac_t""$ac_cv_cygwin" 1>&6 CYGWIN= test "$ac_cv_cygwin" = yes && CYGWIN=yes echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6 -echo "configure:1530: checking for mingw32 environment" >&5 +echo "configure:1529: checking for mingw32 environment" >&5 if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1541: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_mingw32=yes else @@ -1555,11 +1554,82 @@ echo "$ac_t""$ac_cv_mingw32" 1>&6 MINGW32= test "$ac_cv_mingw32" = yes && MINGW32=yes -CFLAGS="-D_REENTRANT -g -O2 -Wall -pipe" +CFLAGS="-g -O2 -Wall" + +# Test for DJGPP +if test "$OSTYPE" = "MSDOS"; then + + CFLAGS="-I \$(top_srcdir)/arch/dos/include $CFLAGS" + + +if test "$OSTYPE" = "MSDOS"; then + ENV_DJGPP_TRUE= + ENV_DJGPP_FALSE='#' +else + ENV_DJGPP_TRUE='#' + ENV_DJGPP_FALSE= +fi + cat >> confdefs.h <<\EOF +#define __ENV_DJGPP__ 1 +EOF + + # Extract the first word of "nasmw", so it can be a program name with args. +set dummy nasmw; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1580: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_NASM'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$NASM" in + /*) + ac_cv_path_NASM="$NASM" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_NASM="$NASM" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_NASM="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_NASM" && ac_cv_path_NASM="no" + ;; +esac +fi +NASM="$ac_cv_path_NASM" +if test -n "$NASM"; then + echo "$ac_t""$NASM" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + -echo $ac_n "checking for SDL_Init in -lSDL""... $ac_c" 1>&6 -echo "configure:1563: checking for SDL_Init in -lSDL" >&5 +else + CFLAGS="-D_REENTRANT -pipe $CFLAGS" + + +if test "$OSTYPE" != "MSDOS"; then + ENV_LINUX_TRUE= + ENV_LINUX_FALSE='#' +else + ENV_LINUX_TRUE='#' + ENV_LINUX_FALSE= +fi + cat >> confdefs.h <<\EOF +#define __ENV_LINUX__ 1 +EOF + + + + echo $ac_n "checking for SDL_Init in -lSDL""... $ac_c" 1>&6 +echo "configure:1633: checking for SDL_Init in -lSDL" >&5 ac_lib_var=`echo SDL'_'SDL_Init | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1567,7 +1637,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lSDL -ldl -lpthread $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1652: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1596,24 +1666,24 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then SDL_LIBS="-lSDL" else echo "$ac_t""no" 1>&6 -{ echo "configure: error: The SDL" 1>&2; exit 1; } +{ echo "configure: error: The SDL which is required not found." 1>&2; exit 1; } fi -for ac_hdr in netipx/ipx.h + for ac_hdr in netipx/ipx.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:1607: checking for $ac_hdr" >&5 +echo "configure:1677: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1617: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1687: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -1639,118 +1709,26 @@ else fi done + - -# Check for NASM and network -NO_ASM=0 -NO_NETWORK=0 -# Check whether --with-assembler or --without-assembler was given. -if test "${with_assembler+set}" = set; then - withval="$with_assembler" - if test x$withval = xno; then - NO_ASM=1 - fi -fi - -# Check whether --with-network or --without-network was given. -if test "${with_network+set}" = set; then - withval="$with_network" - if test x$withval = xno; then - NO_NETWORK=1 - fi -fi - - - -# Extract the first word of "nasm", so it can be a program name with args. -set dummy nasm; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1669: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_path_NASM'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - case "$NASM" in - /*) - ac_cv_path_NASM="$NASM" # Let the user override the test with a path. - ;; - ?:/*) - ac_cv_path_NASM="$NASM" # Let the user override the test with a dos path. - ;; - *) - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_path_NASM="$ac_dir/$ac_word" - break - fi - done - IFS="$ac_save_ifs" - test -z "$ac_cv_path_NASM" && ac_cv_path_NASM="no" - ;; -esac -fi -NASM="$ac_cv_path_NASM" -if test -n "$NASM"; then - echo "$ac_t""$NASM" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -if test "$NASM" = "no"; then - NO_ASM=1 -fi -if test "$NO_ASM" = 1; then - cat >> confdefs.h <<\EOF -#define NO_ASM 1 -EOF - - NASMFLAGS="" -else - case $ARCH in - win32) - NASMFLAGS="-f win32" - ;; - *) - NASMFLAGS="-f elf -d__ENV_LINUX__" - ;; - esac -fi -if test "$NO_NETWORK" = 0; then - cat >> confdefs.h <<\EOF -#define NETWORK 1 -EOF - -fi - - -if test "$NO_ASM" != 1; then - USE_ASM_TRUE= - USE_ASM_FALSE='#' -else - USE_ASM_TRUE='#' - USE_ASM_FALSE= -fi - - -# Check for OpenGL -# Check whether --with-opengl or --without-opengl was given. + + # Check for OpenGL + # Check whether --with-opengl or --without-opengl was given. if test "${with_opengl+set}" = set; then withval="$with_opengl" case "${withval}" in - yes) opengl=true ;; - no) opengl=false ;; - *) { echo "configure: error: bad value ${withval} for --with-opengl" 1>&2; exit 1; } ;; - esac + yes) opengl=true ;; + no) opengl=false ;; + *) { echo "configure: error: bad value ${withval} for --with-opengl" 1>&2; exit 1; } ;; + esac else opengl=false fi - -if test x$opengl = xtrue; then - echo $ac_n "checking for main in -lMesaGL""... $ac_c" 1>&6 -echo "configure:1754: checking for main in -lMesaGL" >&5 + + if test x$opengl = xtrue; then + echo $ac_n "checking for main in -lMesaGL""... $ac_c" 1>&6 +echo "configure:1732: checking for main in -lMesaGL" >&5 ac_lib_var=`echo MesaGL'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1758,14 +1736,14 @@ else ac_save_LIBS="$LIBS" LIBS="-lMesaGL -L/usr/X11R6/lib -lX11 -lXext -lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1747: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1784,11 +1762,11 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 { echo "configure: error: MesaGL not found" 1>&2; exit 1; } - opengl=false + opengl=false fi - echo $ac_n "checking for main in -lMesaGLU""... $ac_c" 1>&6 -echo "configure:1792: checking for main in -lMesaGLU" >&5 + echo $ac_n "checking for main in -lMesaGLU""... $ac_c" 1>&6 +echo "configure:1770: checking for main in -lMesaGLU" >&5 ac_lib_var=`echo MesaGLU'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1796,14 +1774,14 @@ else ac_save_LIBS="$LIBS" LIBS="-lMesaGLU -lMesaGL -L/usr/X11R6/lib -lX11 -lXext -lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1785: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1822,18 +1800,21 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 { echo "configure: error: MesaGLU not found" 1>&2; exit 1; } - opengl=false + opengl=false fi -fi + fi -if test x$opengl = xtrue; then - cat >> confdefs.h <<\EOF + if test x$opengl = xtrue; then + cat >> confdefs.h <<\EOF #define OGL 1 EOF -fi - + CFLAGS="-I \$(top_srcdir)/input/ggi/include $CFLAGS" + else + CFLAGS="-I \$(top_srcdir)/input/sdl/include $CFLAGS" + fi + if test x$opengl = xtrue; then USE_OPENGL_TRUE= @@ -1843,6 +1824,107 @@ else USE_OPENGL_FALSE= fi + # Extract the first word of "nasm", so it can be a program name with args. +set dummy nasm; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1831: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_NASM'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$NASM" in + /*) + ac_cv_path_NASM="$NASM" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_NASM="$NASM" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_NASM="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_NASM" && ac_cv_path_NASM="no" + ;; +esac +fi +NASM="$ac_cv_path_NASM" +if test -n "$NASM"; then + echo "$ac_t""$NASM" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + CFLAGS="-I \$(top_srcdir)/input/linux/include -I \$(top_srcdir)/arch/linux/include $CFLAGS" + +fi + +# Check for NASM and network +NO_ASM=0 +NO_NETWORK=0 +# Check whether --with-assembler or --without-assembler was given. +if test "${with_assembler+set}" = set; then + withval="$with_assembler" + if test x$withval = xno; then + NO_ASM=1 + fi +fi + +# Check whether --with-network or --without-network was given. +if test "${with_network+set}" = set; then + withval="$with_network" + if test x$withval = xno; then + NO_NETWORK=1 + fi +fi + + +if test "$NASM" = "no"; then + NO_ASM=1 +fi +if test "$NO_ASM" = 1; then + cat >> confdefs.h <<\EOF +#define NO_ASM 1 +EOF + + NASMFLAGS="" +else + case $ARCH in + win32) + NASMFLAGS="-f win32" + ;; + *) + if test "$OSTYPE" = "MSDOS"; then + NASMFLAGS="-f coff" + else + NASMFLAGS="-f elf -d__ENV_LINUX__" + fi + ;; + esac +fi +if test "$NO_NETWORK" = 0; then + cat >> confdefs.h <<\EOF +#define NETWORK 1 +EOF + +fi + + +if test "$NO_ASM" != 1; then + USE_ASM_TRUE= + USE_ASM_FALSE='#' +else + USE_ASM_TRUE='#' + USE_ASM_FALSE= +fi + + + if test "$program_transform_name" = s,x,x,; then program_transform_name= @@ -1865,7 +1947,6 @@ test "$program_transform_name" = "" && program_transform_name="s,x,x," #libdir='$(shell pwd)/${top_srcdir}/main' - trap '' 1 2 15 cat > confcache <<\EOF # This file is a shell script that caches the results of configure @@ -1977,14 +2058,9 @@ iff/Makefile texmap/Makefile misc/Makefile input/Makefile -input/sdl/Makefile -input/linux/Makefile -input/ggi/Makefile video/Makefile sound/Makefile arch/Makefile -arch/linux/Makefile -arch/sdl/Makefile main/Makefile conf.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF @@ -2035,13 +2111,17 @@ s%@MAINT@%$MAINT%g s%@CC@%$CC%g s%@RANLIB@%$RANLIB%g s%@CPP@%$CPP%g -s%@SDL_LIBS@%$SDL_LIBS%g +s%@ENV_DJGPP_TRUE@%$ENV_DJGPP_TRUE%g +s%@ENV_DJGPP_FALSE@%$ENV_DJGPP_FALSE%g s%@NASM@%$NASM%g +s%@ENV_LINUX_TRUE@%$ENV_LINUX_TRUE%g +s%@ENV_LINUX_FALSE@%$ENV_LINUX_FALSE%g +s%@SDL_LIBS@%$SDL_LIBS%g +s%@USE_OPENGL_TRUE@%$USE_OPENGL_TRUE%g +s%@USE_OPENGL_FALSE@%$USE_OPENGL_FALSE%g s%@USE_ASM_TRUE@%$USE_ASM_TRUE%g s%@USE_ASM_FALSE@%$USE_ASM_FALSE%g s%@NASMFLAGS@%$NASMFLAGS%g -s%@USE_OPENGL_TRUE@%$USE_OPENGL_TRUE%g -s%@USE_OPENGL_FALSE@%$USE_OPENGL_FALSE%g CEOF EOF @@ -2093,14 +2173,9 @@ iff/Makefile texmap/Makefile misc/Makefile input/Makefile -input/sdl/Makefile -input/linux/Makefile -input/ggi/Makefile video/Makefile sound/Makefile arch/Makefile -arch/linux/Makefile -arch/sdl/Makefile main/Makefile "} EOF diff --git a/configure.in b/configure.in index e0c1969c..daeb1a3c 100644 --- a/configure.in +++ b/configure.in @@ -1,11 +1,10 @@ AC_INIT(main/game.c) AM_CONFIG_HEADER(conf.h) -AM_INIT_AUTOMAKE(d2x, 0.0.8) +AM_INIT_AUTOMAKE(d2x, 0.0.9) AM_MAINTAINER_MODE - AC_ISC_POSIX AC_PROG_CC AC_PROG_RANLIB @@ -14,83 +13,108 @@ AC_STDC_HEADERS AC_CYGWIN AC_MINGW32 -CFLAGS="-D_REENTRANT -g -O2 -Wall -pipe" -AC_SUBST(CFLAGS) +CFLAGS="-g -O2 -Wall" + +# Test for DJGPP +if test "$OSTYPE" = "MSDOS"; then + + CFLAGS="-I \$(top_srcdir)/arch/dos/include $CFLAGS" + AM_CONDITIONAL(ENV_DJGPP, test "$OSTYPE" = "MSDOS") + AC_DEFINE(__ENV_DJGPP__) + AC_PATH_PROG(NASM, nasmw, no) -AC_CHECK_LIB(SDL, SDL_Init, SDL_LIBS="-lSDL", AC_MSG_ERROR(The SDL, which is required, not found.),-ldl -lpthread) -AC_CHECK_HEADERS(netipx/ipx.h) -AC_SUBST(SDL_LIBS) + +else + CFLAGS="-D_REENTRANT -pipe $CFLAGS" + AM_CONDITIONAL(ENV_LINUX, test "$OSTYPE" != "MSDOS") + AC_DEFINE(__ENV_LINUX__) + + + AC_CHECK_LIB(SDL, SDL_Init, SDL_LIBS="-lSDL", AC_MSG_ERROR(The SDL which is required not found.),-ldl -lpthread) + AC_CHECK_HEADERS(netipx/ipx.h) + AC_SUBST(SDL_LIBS) + + + # Check for OpenGL + AC_ARG_WITH(opengl, + [ --with-opengl Build OpenGL support ], + [case "${withval}" in + yes) opengl=true ;; + no) opengl=false ;; + *) AC_MSG_ERROR(bad value ${withval} for --with-opengl) ;; + esac],[opengl=false]) + + if test x$opengl = xtrue; then + AC_CHECK_LIB(MesaGL, main, + OGL_LIBS="-lMesaGL", + [AC_MSG_ERROR(MesaGL not found, OpenGL cannot be built) + opengl=false], + -L/usr/X11R6/lib -lX11 -lXext -lm) + AC_CHECK_LIB(MesaGLU,main, + OGL_LIBS="${OGL_LIBS} -lMesaGLU", + [AC_MSG_ERROR(MesaGLU not found, OpenGL cannot be built) + opengl=false], + -lMesaGL -L/usr/X11R6/lib -lX11 -lXext -lm) + fi + + if test x$opengl = xtrue; then + AC_DEFINE(OGL) + CFLAGS="-I \$(top_srcdir)/input/ggi/include $CFLAGS" + else + CFLAGS="-I \$(top_srcdir)/input/sdl/include $CFLAGS" + fi + AM_CONDITIONAL(USE_OPENGL, test x$opengl = xtrue) + + AC_PATH_PROG(NASM, nasm, no) + CFLAGS="-I \$(top_srcdir)/input/linux/include -I \$(top_srcdir)/arch/linux/include $CFLAGS" + +fi # Check for NASM and network NO_ASM=0 NO_NETWORK=0 AC_ARG_WITH(assembler, - [ --without-assembler Do not use assembler optimization ], + [ --without-assembler Do not use assembler optimization ], if test x$withval = xno; then NO_ASM=1 fi) AC_ARG_WITH(network, [ --without-network Do not build network/serial support ], if test x$withval = xno; then - NO_NETWORK=1 + NO_NETWORK=1 fi) - -AC_PATH_PROG(NASM, nasm, no) if test "$NASM" = "no"; then - NO_ASM=1 + NO_ASM=1 fi if test "$NO_ASM" = 1; then - AC_DEFINE(NO_ASM) - NASMFLAGS="" + AC_DEFINE(NO_ASM) + NASMFLAGS="" else - case $ARCH in - win32) + case $ARCH in + win32) NASMFLAGS="-f win32" ;; *) - NASMFLAGS="-f elf -d__ENV_LINUX__" + if test "$OSTYPE" = "MSDOS"; then + NASMFLAGS="-f coff" + else + NASMFLAGS="-f elf -d__ENV_LINUX__" + fi ;; esac -fi +fi if test "$NO_NETWORK" = 0; then - AC_DEFINE(NETWORK) + AC_DEFINE(NETWORK) fi AM_CONDITIONAL(USE_ASM, test "$NO_ASM" != 1) AC_SUBST(NASMFLAGS) -# Check for OpenGL -AC_ARG_WITH(opengl, - [ --with-opengl Build OpenGL support ], - [case "${withval}" in - yes) opengl=true ;; - no) opengl=false ;; - *) AC_MSG_ERROR(bad value ${withval} for --with-opengl) ;; - esac],[opengl=false]) - -if test x$opengl = xtrue; then - AC_CHECK_LIB(MesaGL, main, - OGL_LIBS="-lMesaGL", - [AC_MSG_ERROR(MesaGL not found, OpenGL cannot be built) - opengl=false], - -L/usr/X11R6/lib -lX11 -lXext -lm) - AC_CHECK_LIB(MesaGLU,main, - OGL_LIBS="${OGL_LIBS} -lMesaGLU", - [AC_MSG_ERROR(MesaGLU not found, OpenGL cannot be built) - opengl=false], - -lMesaGL -L/usr/X11R6/lib -lX11 -lXext -lm) -fi - -if test x$opengl = xtrue; then - AC_DEFINE(OGL) -fi -AM_CONDITIONAL(USE_OPENGL, test x$opengl = xtrue) - +AC_SUBST(CFLAGS) AC_ARG_PROGRAM #libdir='$(shell pwd)/${top_srcdir}/main' - AC_OUTPUT( Makefile 2d/Makefile @@ -102,14 +126,9 @@ iff/Makefile texmap/Makefile misc/Makefile input/Makefile -input/sdl/Makefile -input/linux/Makefile -input/ggi/Makefile video/Makefile sound/Makefile arch/Makefile -arch/linux/Makefile -arch/sdl/Makefile main/Makefile ) diff --git a/copying b/copying new file mode 100644 index 00000000..b23848af --- /dev/null +++ b/copying @@ -0,0 +1,21 @@ +Original Descent 2 code license: + +THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. + +We make no warranties as to the usability or correctness of this code. + +Additional restrictions: +Any executable created using files or code taken from this source tree +MUST be open source. By using this source, you are agreeing to this +term, in the interest of the descent and descent programming +communities. The only exception is if the writer of the original +source gives explicit permission for the code to be used otherwise. diff --git a/djgpp.bat b/djgpp.bat new file mode 100644 index 00000000..3d4211d5 --- /dev/null +++ b/djgpp.bat @@ -0,0 +1 @@ +bash djgpp.sh diff --git a/djgpp.sh b/djgpp.sh new file mode 100644 index 00000000..81ce78d1 --- /dev/null +++ b/djgpp.sh @@ -0,0 +1,6 @@ +#!/bin/sh +autoconf +export CONFIG_SHELL="bash" +echo "Please ignore any non-critical error messages in this script" +./configure "$@" + diff --git a/include/d.bat b/include/d.bat index 9038a864..05befe0d 100644 --- a/include/d.bat +++ b/include/d.bat @@ -1,2 +1,2 @@ -@wvideo test -@fix +@wvideo test +@fix diff --git a/include/d_io.h b/include/d_io.h index 71a8c7e7..6c749ebf 100644 --- a/include/d_io.h +++ b/include/d_io.h @@ -3,7 +3,7 @@ #ifndef _D_IO_H #define _D_IO_H -#if (defined(__MSDOS__) && !defined(__DJGPP__)) || defined(__WINDOWS__) +#ifdef __ENV_WINDOWS__ #include #else #include diff --git a/include/dtypes.inc b/include/dtypes.inc index 4e7fd9e7..a5bd6c16 100644 --- a/include/dtypes.inc +++ b/include/dtypes.inc @@ -1,25 +1,25 @@ -; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX -; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO -; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A -; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS -; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS -; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE -; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE -; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS -; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. -; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. -option expr32 - -IFNDEF types_inc -types_inc EQU 1 - -ubyte typedef byte -ushort typedef word -long typedef dword -uint typedef dword -ulong typedef dword - -bool typedef ubyte - -ENDIF - +; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. +option expr32 + +IFNDEF types_inc +types_inc EQU 1 + +ubyte typedef byte +ushort typedef word +long typedef dword +uint typedef dword +ulong typedef dword + +bool typedef ubyte + +ENDIF + diff --git a/include/gr.h b/include/gr.h index b5f0713d..269874cc 100644 --- a/include/gr.h +++ b/include/gr.h @@ -187,7 +187,7 @@ int gr_init(void); // the video mode changes. int gr_init_screen(int mode, int w, int h, int x, int y, int rowsize, ubyte *data); -int gr_check_mode(int mode); +int gr_check_mode(u_int32_t mode); int gr_set_mode(u_int32_t mode); diff --git a/include/grdef.h b/include/grdef.h index 17f24b5a..7bdd3700 100644 --- a/include/grdef.h +++ b/include/grdef.h @@ -12,9 +12,9 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. */ /* * $Source: /cvs/cvsroot/d2x/include/grdef.h,v $ - * $Revision: 1.1.1.1 $ + * $Revision: 1.1.1.2 $ * $Author: bradleyb $ - * $Date: 2001-01-19 03:30:16 $ + * $Date: 2001-01-19 03:34:09 $ * * Internal definitions for graphics lib. * @@ -100,7 +100,7 @@ void gr_linear_line( int x0, int y0, int x1, int y1); extern unsigned int Table8to32[256]; -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP_ extern unsigned char * gr_video_memory; #endif diff --git a/include/lst.bat b/include/lst.bat index f9ed4f9f..55759a02 100644 --- a/include/lst.bat +++ b/include/lst.bat @@ -1 +1 @@ -ml /c /W3 /Zd /nologo /Fo.\obj\mactest.obj /Fl mactest.asm +ml /c /W3 /Zd /nologo /Fo.\obj\mactest.obj /Fl mactest.asm diff --git a/include/m.bat b/include/m.bat index 9d6b2cc3..b1c070a5 100644 --- a/include/m.bat +++ b/include/m.bat @@ -1 +1 @@ -make test +make test diff --git a/include/psmacros.inc b/include/psmacros.inc index 0f2ce81e..7e0e1aab 100644 --- a/include/psmacros.inc +++ b/include/psmacros.inc @@ -1,330 +1,330 @@ -; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX -; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO -; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A -; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS -; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS -; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE -; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE -; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS -; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. -; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. -;Shortcuts for casting - -w equ word ptr -b equ byte ptr - - -;The macros @ArgCount() & @ArgRev() are from the file MACROS.INC, provided -;with MASM. I have included them here because MACROS.INC has bugs, so I -;couldn't just include it. - -; Utility Macros - Version 1.0 - for Microsoft Macro Assembler 6.0 -; (C) Copyright Microsoft Corporation, 1987,1988,1989,1990 - -;* @ArgCount - Macro function returns the number of arguments in a -;* VARARG list. -;* -;* Params: arglist - arguments to be counted - -@ArgCount MACRO arglist:VARARG - LOCAL count - count = 0 - FOR arg, - count = count + 1 - ENDM - EXITM %count -ENDM - -;* @ArgRev - Macro function returns a reversed order version of a -;* VARARG list. -;* -;* Shows: Operators - <> ! % -;* String directive - SUBSTR -;* Predefined function - @SizeStr -;* -;* Params: arglist - arguments to be reversed - -@ArgRev MACRO arglist:vararg - LOCAL txt, arg - txt TEXTEQU <> -% FOR arg, - txt CATSTR , , txt - ENDM - - txt SUBSTR txt, 1, @SizeStr( %txt ) - 1 - txt CATSTR , txt, > - EXITM txt -ENDM - -;These macros are used for decalaring external vars and functions - -;this macro is used to declare several symbols of the same type -;usage is: extdef type,sym0,sym1,... -extdef macro type,syms:vararg - for sym, - externdef sym:type - endm - endm - -;this macro is used to generate ext macros -extgen macro type,id -ext&id macro syms:vararg - extdef type,syms - endm - endm - -;macros for common types, such as word (extw), byte (extb), & near (extn) - - extgen word,w - extgen byte,b - extgen dword,d - extgen near,n - - -;compute the absolute value of eax. afterwards, edx=sign (0 or -1) -abs_eax macro - cdq - xor eax,edx - sub eax,edx - endm - -;PUSHM & POPM are used for multiple registers. Note that POPM pops in the -;reverse order from PUSHM, so the list of regs shouls be the same for both. -;You can also define a constant which is a register list, and use it as the -;argument to both macros. - -;push multiple registers -pushm macro args:vararg - local arg - for arg, - push arg - endm - endm - -;pop multiple registers -popm macro args:vararg - local arg -% for arg,@ArgRev(args) - pop arg - endm - endm - -;PUSHLONG pushes a long, zero extending the argument if necessary -;it trashes no registers -pushlong macro arg - local s -s = TYPE arg - if s EQ 0 ;constant, I think - push arg - elseif s LT 4 - push eax - movzx eax,arg - xchg eax,[esp] - else - push arg - endif - - endm - -;PUSHML is pushm using pushlong -pushml macro args:vararg - local arg - for arg, - pushlong arg - endm - endm - - -;DBSTR stores a string with occurances of \n converted to newlines -;this macro expects quotes around the string -; -;note the 'fudge' variable. This fixes an odd problem with the way -;the string macros deal with backslashes - @InStr() treats them like -;any other character, but @SubStr() ignores them -dbstr macro str - local pos,oldpos,len,fudge - - oldpos = 2 ;skip initial quote - fudge = 0 - len = @SizeStr(str) - - pos = @InStr(oldpos,str,<\n>) - - while pos GE oldpos - - if pos GT oldpos - %db '&@SubStr(<&str>,&oldpos-&fudge,&pos-&oldpos)' - endif - db 10 - oldpos = pos+2 - fudge = fudge+1 - - pos = @InStr(oldpos,,<\n>) - - endm - - if oldpos LT len -;;; %db '&@SubStr(&str,&oldpos-&fudge,&len-&oldpos-1)' - %db '&@SubStr(&str,&oldpos-&fudge,&len-&oldpos)' - endif - - endm - - -;MPRINTF is a macro interface to the mprintf funcion. It puts the format -;string in the code segment at the current location, pushes the args, and -;calls mprintf. If window is not specified, zero is assumed -mprintf macro window:=<0>,format:req,args:vararg - local string,skip - ifndef NDEBUG - ifndef NMONO - extn mprintf_ - jmp skip -string label byte - dbstr format - db 0 -skip: - ifnb -% pushml @ArgRev(args) - endif - pushml offset string,window - call mprintf_ - add esp,(@ArgCount(args)+2)*4 ;fix stack - endif - endif - endm - - -;MPRINTF_AT - version of mprintf with coordinates -mprintf_at macro window:=<0>,row,col,format:req,args:vararg - local string,skip - ifndef NDEBUG - ifndef NMONO - extn mprintf_at_ - jmp skip -string label byte - dbstr format - db 0 -skip: - ifnb -% pushml @ArgRev(args) - endif - pushml offset string,col,row,window - call mprintf_at_ - add esp,(@ArgCount(args)+4)*4 ;fix stack - endif - endif - endm - - -;DEBUG calls mprintf with window 0, preserving all registers and flags -;is is conditionall assembled based on the DEBUG_ON flags -debug macro format:req,args:vararg - ifndef NDEBUG - pushf ;save flags - push eax ;mprintf trashes eax - mprintf ,format,args - pop eax - popf - endif - endm - -;DEBUG_AT - version of debug with coordinates -debug_at macro row,col,format:req,args:vararg - ifndef NDEBUG - pushf ;save flags - push eax ;mprintf trashes eax - mprintf_at ,row,col,format,args - pop eax - popf - endif - endm - -;Debugging breakpoint macros - -;print a message, and do an int3 to pop into the debugger -debug_brk macro str - ifndef NDEBUG - debug str - int 3 - endif - endm - -break_if macro cc,str - local skip,yes_break - ifndef NDEBUG - j&cc yes_break - jmp skip -yes_break: debug_brk str -skip: - endif - endm - -;returns the bit number of the highest bit -@HighBit macro n - local t,c - if n EQ 0 - exitm <-1> ;error! - else - t = n - c = 0 - while t GT 1 - t = t SHR 1 - c = c+1 - endm - exitm - endif - endm - -;returns the bit number of the lowest bit -@LowBit macro n - ;local t,c - local c - if n EQ 0 - exitm <-1> ;error! - else - t = n - c = 0 - while (t and 1) EQ 0 - t = t SHR 1 - c = c+1 - endm - exitm - endif - endm - - -;"multiply" the given register by a constant, using whatever method is -;best for the given constant -imulc macro reg,c - local low,high - - if c EQ 0 - xor reg,reg - elseif c EQ 1 - elseif c EQ 3 - lea reg,[reg*2+reg] - elseif c EQ 5 - lea reg,[reg*4+reg] - elseif c EQ 6 - lea reg,[reg*2+reg] ;*3 - shl reg,1 ;*6 - elseif c EQ 9 - lea reg,[reg*8+reg] - elseif c EQ 36 - lea reg,[reg*8+reg] - sal reg,2 - else - low = @LowBit(c) - high = @HighBit(c) - if low EQ high - shl reg,@LowBit(c) - else - imul reg,c - echo Warning: Using imul, to perform multiply by &c - ;; .err - endif - endif - - endm - +; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. +;Shortcuts for casting + +w equ word ptr +b equ byte ptr + + +;The macros @ArgCount() & @ArgRev() are from the file MACROS.INC, provided +;with MASM. I have included them here because MACROS.INC has bugs, so I +;couldn't just include it. + +; Utility Macros - Version 1.0 - for Microsoft Macro Assembler 6.0 +; (C) Copyright Microsoft Corporation, 1987,1988,1989,1990 + +;* @ArgCount - Macro function returns the number of arguments in a +;* VARARG list. +;* +;* Params: arglist - arguments to be counted + +@ArgCount MACRO arglist:VARARG + LOCAL count + count = 0 + FOR arg, + count = count + 1 + ENDM + EXITM %count +ENDM + +;* @ArgRev - Macro function returns a reversed order version of a +;* VARARG list. +;* +;* Shows: Operators - <> ! % +;* String directive - SUBSTR +;* Predefined function - @SizeStr +;* +;* Params: arglist - arguments to be reversed + +@ArgRev MACRO arglist:vararg + LOCAL txt, arg + txt TEXTEQU <> +% FOR arg, + txt CATSTR , , txt + ENDM + + txt SUBSTR txt, 1, @SizeStr( %txt ) - 1 + txt CATSTR , txt, > + EXITM txt +ENDM + +;These macros are used for decalaring external vars and functions + +;this macro is used to declare several symbols of the same type +;usage is: extdef type,sym0,sym1,... +extdef macro type,syms:vararg + for sym, + externdef sym:type + endm + endm + +;this macro is used to generate ext macros +extgen macro type,id +ext&id macro syms:vararg + extdef type,syms + endm + endm + +;macros for common types, such as word (extw), byte (extb), & near (extn) + + extgen word,w + extgen byte,b + extgen dword,d + extgen near,n + + +;compute the absolute value of eax. afterwards, edx=sign (0 or -1) +abs_eax macro + cdq + xor eax,edx + sub eax,edx + endm + +;PUSHM & POPM are used for multiple registers. Note that POPM pops in the +;reverse order from PUSHM, so the list of regs shouls be the same for both. +;You can also define a constant which is a register list, and use it as the +;argument to both macros. + +;push multiple registers +pushm macro args:vararg + local arg + for arg, + push arg + endm + endm + +;pop multiple registers +popm macro args:vararg + local arg +% for arg,@ArgRev(args) + pop arg + endm + endm + +;PUSHLONG pushes a long, zero extending the argument if necessary +;it trashes no registers +pushlong macro arg + local s +s = TYPE arg + if s EQ 0 ;constant, I think + push arg + elseif s LT 4 + push eax + movzx eax,arg + xchg eax,[esp] + else + push arg + endif + + endm + +;PUSHML is pushm using pushlong +pushml macro args:vararg + local arg + for arg, + pushlong arg + endm + endm + + +;DBSTR stores a string with occurances of \n converted to newlines +;this macro expects quotes around the string +; +;note the 'fudge' variable. This fixes an odd problem with the way +;the string macros deal with backslashes - @InStr() treats them like +;any other character, but @SubStr() ignores them +dbstr macro str + local pos,oldpos,len,fudge + + oldpos = 2 ;skip initial quote + fudge = 0 + len = @SizeStr(str) + + pos = @InStr(oldpos,str,<\n>) + + while pos GE oldpos + + if pos GT oldpos + %db '&@SubStr(<&str>,&oldpos-&fudge,&pos-&oldpos)' + endif + db 10 + oldpos = pos+2 + fudge = fudge+1 + + pos = @InStr(oldpos,,<\n>) + + endm + + if oldpos LT len +;;; %db '&@SubStr(&str,&oldpos-&fudge,&len-&oldpos-1)' + %db '&@SubStr(&str,&oldpos-&fudge,&len-&oldpos)' + endif + + endm + + +;MPRINTF is a macro interface to the mprintf funcion. It puts the format +;string in the code segment at the current location, pushes the args, and +;calls mprintf. If window is not specified, zero is assumed +mprintf macro window:=<0>,format:req,args:vararg + local string,skip + ifndef NDEBUG + ifndef NMONO + extn mprintf_ + jmp skip +string label byte + dbstr format + db 0 +skip: + ifnb +% pushml @ArgRev(args) + endif + pushml offset string,window + call mprintf_ + add esp,(@ArgCount(args)+2)*4 ;fix stack + endif + endif + endm + + +;MPRINTF_AT - version of mprintf with coordinates +mprintf_at macro window:=<0>,row,col,format:req,args:vararg + local string,skip + ifndef NDEBUG + ifndef NMONO + extn mprintf_at_ + jmp skip +string label byte + dbstr format + db 0 +skip: + ifnb +% pushml @ArgRev(args) + endif + pushml offset string,col,row,window + call mprintf_at_ + add esp,(@ArgCount(args)+4)*4 ;fix stack + endif + endif + endm + + +;DEBUG calls mprintf with window 0, preserving all registers and flags +;is is conditionall assembled based on the DEBUG_ON flags +debug macro format:req,args:vararg + ifndef NDEBUG + pushf ;save flags + push eax ;mprintf trashes eax + mprintf ,format,args + pop eax + popf + endif + endm + +;DEBUG_AT - version of debug with coordinates +debug_at macro row,col,format:req,args:vararg + ifndef NDEBUG + pushf ;save flags + push eax ;mprintf trashes eax + mprintf_at ,row,col,format,args + pop eax + popf + endif + endm + +;Debugging breakpoint macros + +;print a message, and do an int3 to pop into the debugger +debug_brk macro str + ifndef NDEBUG + debug str + int 3 + endif + endm + +break_if macro cc,str + local skip,yes_break + ifndef NDEBUG + j&cc yes_break + jmp skip +yes_break: debug_brk str +skip: + endif + endm + +;returns the bit number of the highest bit +@HighBit macro n + local t,c + if n EQ 0 + exitm <-1> ;error! + else + t = n + c = 0 + while t GT 1 + t = t SHR 1 + c = c+1 + endm + exitm + endif + endm + +;returns the bit number of the lowest bit +@LowBit macro n + ;local t,c + local c + if n EQ 0 + exitm <-1> ;error! + else + t = n + c = 0 + while (t and 1) EQ 0 + t = t SHR 1 + c = c+1 + endm + exitm + endif + endm + + +;"multiply" the given register by a constant, using whatever method is +;best for the given constant +imulc macro reg,c + local low,high + + if c EQ 0 + xor reg,reg + elseif c EQ 1 + elseif c EQ 3 + lea reg,[reg*2+reg] + elseif c EQ 5 + lea reg,[reg*4+reg] + elseif c EQ 6 + lea reg,[reg*2+reg] ;*3 + shl reg,1 ;*6 + elseif c EQ 9 + lea reg,[reg*8+reg] + elseif c EQ 36 + lea reg,[reg*8+reg] + sal reg,2 + else + low = @LowBit(c) + high = @HighBit(c) + if low EQ high + shl reg,@LowBit(c) + else + imul reg,c + echo Warning: Using imul, to perform multiply by &c + ;; .err + endif + endif + + endm + diff --git a/include/pstypes.h b/include/pstypes.h index f5494e94..d470da82 100644 --- a/include/pstypes.h +++ b/include/pstypes.h @@ -26,8 +26,22 @@ typedef unsigned char ubyte; # include # define _MAX_PATH 1024 # define _MAX_DIR 256 -#define min(a,b) (((a)>(b))?(b):(a)) -#define max(a,b) (((a)<(b))?(b):(a)) +# define min(a,b) (((a)>(b))?(b):(a)) +# define max(a,b) (((a)<(b))?(b):(a)) +#elif defined __ENV_DJGPP__ +# include +# define min(a,b) (((a)>(b))?(b):(a)) +# define max(a,b) (((a)<(b))?(b):(a)) +# define _MAX_PATH 255 +# define _MAX_DIR 63 +typedef unsigned short ushort; +typedef unsigned int uint; +typedef unsigned long ulong; +typedef signed long int32_t; +typedef unsigned long u_int32_t; +typedef signed short int16_t; +typedef unsigned short u_int16_t; + #else typedef unsigned short ushort; typedef unsigned int uint; diff --git a/include/pstypes.inc b/include/pstypes.inc index 4e7fd9e7..a5bd6c16 100644 --- a/include/pstypes.inc +++ b/include/pstypes.inc @@ -1,25 +1,25 @@ -; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX -; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO -; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A -; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS -; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS -; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE -; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE -; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS -; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. -; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. -option expr32 - -IFNDEF types_inc -types_inc EQU 1 - -ubyte typedef byte -ushort typedef word -long typedef dword -uint typedef dword -ulong typedef dword - -bool typedef ubyte - -ENDIF - +; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. +option expr32 + +IFNDEF types_inc +types_inc EQU 1 + +ubyte typedef byte +ushort typedef word +long typedef dword +uint typedef dword +ulong typedef dword + +bool typedef ubyte + +ENDIF + diff --git a/include/strutil.h b/include/strutil.h index 87a089ba..ceeb83a6 100644 --- a/include/strutil.h +++ b/include/strutil.h @@ -19,13 +19,20 @@ char *d_strdup(char *str); #ifdef __ENV_LINUX__ #define stricmp(a,b) strcasecmp(a,b) #define strnicmp(a,b,c) strncasecmp(a,b,c) + +void strupr( char *s1 ); +void strlwr( char *s1 ); +#elif defined __ENV_DJGPP__ +// Nothing needed + #else extern int stricmp(char *str1, char *str2); extern int strnicmp(char *str1, char *str2, int n); -#endif void strupr( char *s1 ); void strlwr( char *s1 ); +#endif + void strrev( char *s1 ); void _splitpath(char *name, char *drive, char *path, char *base, char *ext); diff --git a/include/test.lnk b/include/test.lnk index d84706c9..d08455ab 100644 --- a/include/test.lnk +++ b/include/test.lnk @@ -1,5 +1,5 @@ -system dos4g option quiet debug all -file .\obj\test.obj, - .\obj\mactest.obj -library c:\project\miner\source\lib\io.lib -name test +system dos4g option quiet debug all +file .\obj\test.obj, + .\obj\mactest.obj +library c:\project\miner\source\lib\io.lib +name test diff --git a/include/timer.h b/include/timer.h index 6d74051a..682d265b 100644 --- a/include/timer.h +++ b/include/timer.h @@ -12,9 +12,9 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. */ /* * $Source: /cvs/cvsroot/d2x/include/timer.h,v $ - * $Revision: 1.1.1.1 $ + * $Revision: 1.1.1.2 $ * $Author: bradleyb $ - * $Date: 2001-01-19 03:30:16 $ + * $Date: 2001-01-19 03:34:09 $ * * Header for timer functions * @@ -71,11 +71,9 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. // interrupt rate. #define TIMER_FREQUENCY 1193180 -#if !defined (__MSDOS__) || defined(__GNUC__) #define _far #define __far #define __interrupt -#endif extern void timer_init(); extern void timer_close(); @@ -91,7 +89,7 @@ extern void timer_set_function( void _far * function ); // 1 hr, respectively. extern fix timer_get_fixed_seconds(); // Rolls about every 9 hours... -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ extern fix timer_get_fixed_secondsX(); // Assume interrupts already disabled extern fix timer_get_approx_seconds(); // Returns time since program started... accurate to 1/120th of a second extern void timer_set_joyhandler( void (*joy_handler)() ); @@ -108,11 +106,11 @@ extern void timer_set_joyhandler( void (*joy_handler)() ); //========================================================================== // Use to access the BIOS ticker... ie... i = TICKER -#ifdef __LINUX__ +#ifndef __ENV_DJGPP__ #define TICKER (timer_get_fixed_seconds()) #endif -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ #ifndef __GNUC__ #define TICKER (*(volatile int *)0x46C) diff --git a/input/Makefile.am b/input/Makefile.am index 5551342b..3fa3e94c 100644 --- a/input/Makefile.am +++ b/input/Makefile.am @@ -1,17 +1,19 @@ -SUBDIRS = linux -if USE_OPENGL - SUBDIRS += ggi -else - SUBDIRS += sdl -endif - noinst_LIBRARIES = libinput.a +INCLUDES = -I $(top_srcdir)/includes -I $(top_srcdir)/main + +libinput_a_SOURCES = sdl_event.c sdl_key.c sdl_mouse.c \ +ggi_event.c ggi_key.c ggi_mouse.c \ +dos_key.c dos_joyc.c dos_joydefs.c dos_mouse.c\ +linux_joydefs.c linux_joystick.c -libinput_a_SOURCES = +if ENV_DJGPP + SUFFIXES = .asm + %.o: %.asm + $(NASM) $(NASMFLAGS) $< -o $@ -if USE_OPENGL -libinput_a_LIBADD = ggi/event.o ggi/key.o ggi/mouse.o linux/joydefs.o linux/joystick.o -else -libinput_a_LIBADD = sdl/event.o sdl/key.o sdl/mouse.o linux/joydefs.o linux/joystick.o -endif + + libinput_a_SOURCES += dos_joy2.asm + libinput_a_LIBADD += dos_joy2.o + dos_joyc.c: dos_joy2.o +endif diff --git a/input/Makefile.in b/input/Makefile.in index be8ee9de..79e73f77 100644 --- a/input/Makefile.in +++ b/input/Makefile.in @@ -68,13 +68,11 @@ RANLIB = @RANLIB@ SDL_LIBS = @SDL_LIBS@ VERSION = @VERSION@ -SUBDIRS = linux - noinst_LIBRARIES = libinput.a +INCLUDES = -I $(top_srcdir)/includes -I $(top_srcdir)/main + +libinput_a_SOURCES = sdl_event.c sdl_key.c sdl_mouse.c ggi_event.c ggi_key.c ggi_mouse.c dos_key.c dos_joyc.c dos_joydefs.c dos_mouse.c linux_joydefs.c linux_joystick.c -libinput_a_SOURCES = -@USE_OPENGL_TRUE@libinput_a_LIBADD = ggi/event.o ggi/key.o ggi/mouse.o linux/joydefs.o linux/joystick.o -@USE_OPENGL_FALSE@libinput_a_LIBADD = sdl/event.o sdl/key.o sdl/mouse.o linux/joydefs.o linux/joystick.o mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../conf.h CONFIG_CLEAN_FILES = @@ -85,12 +83,14 @@ DEFS = @DEFS@ -I. -I$(srcdir) -I.. CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ -@USE_OPENGL_TRUE@libinput_a_DEPENDENCIES = ggi/event.o ggi/key.o \ -@USE_OPENGL_TRUE@ggi/mouse.o linux/joydefs.o linux/joystick.o -@USE_OPENGL_FALSE@libinput_a_DEPENDENCIES = sdl/event.o sdl/key.o \ -@USE_OPENGL_FALSE@sdl/mouse.o linux/joydefs.o linux/joystick.o -libinput_a_OBJECTS = +libinput_a_LIBADD = +libinput_a_OBJECTS = sdl_event.o sdl_key.o sdl_mouse.o ggi_event.o \ +ggi_key.o ggi_mouse.o dos_key.o dos_joyc.o dos_joydefs.o dos_mouse.o \ +linux_joydefs.o linux_joystick.o AR = ar +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ DIST_COMMON = Makefile.am Makefile.in @@ -98,6 +98,10 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP_ENV = --best +DEP_FILES = .deps/dos_joyc.P .deps/dos_joydefs.P .deps/dos_key.P \ +.deps/dos_mouse.P .deps/ggi_event.P .deps/ggi_key.P .deps/ggi_mouse.P \ +.deps/linux_joydefs.P .deps/linux_joystick.P .deps/sdl_event.P \ +.deps/sdl_key.P .deps/sdl_mouse.P SOURCES = $(libinput_a_SOURCES) OBJECTS = $(libinput_a_OBJECTS) @@ -142,61 +146,6 @@ libinput.a: $(libinput_a_OBJECTS) $(libinput_a_DEPENDENCIES) $(AR) cru libinput.a $(libinput_a_OBJECTS) $(libinput_a_LIBADD) $(RANLIB) libinput.a -# This directory's subdirectories are mostly independent; you can cd -# into them and run `make' without going through this Makefile. -# To change the values of `make' variables: instead of editing Makefiles, -# (1) if the variable is set in `config.status', edit `config.status' -# (which will cause the Makefiles to be regenerated when you run `make'); -# (2) otherwise, pass the desired values on the `make' command line. - -@SET_MAKE@ - -all-recursive install-data-recursive install-exec-recursive \ -installdirs-recursive install-recursive uninstall-recursive \ -check-recursive installcheck-recursive info-recursive dvi-recursive: - @set fnord $(MAKEFLAGS); amf=$$2; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ - fi; test -z "$$fail" - -mostlyclean-recursive clean-recursive distclean-recursive \ -maintainer-clean-recursive: - @set fnord $(MAKEFLAGS); amf=$$2; \ - dot_seen=no; \ - rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ - rev="$$subdir $$rev"; \ - test "$$subdir" = "." && dot_seen=yes; \ - done; \ - test "$$dot_seen" = "no" && rev=". $$rev"; \ - target=`echo $@ | sed s/-recursive//`; \ - for subdir in $$rev; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ - done && test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done - tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) @@ -207,14 +156,9 @@ ID: $(HEADERS) $(SOURCES) $(LISP) here=`pwd` && cd $(srcdir) \ && mkid -f$$here/ID $$unique $(LISP) -TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) tags=; \ here=`pwd`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ - fi; \ - done; \ list='$(SOURCES) $(HEADERS)'; \ unique=`for i in $$list; do echo $$i; done | \ awk ' { files[$$0] = 1; } \ @@ -251,41 +195,62 @@ distdir: $(DISTFILES) || cp -p $$d/$$file $(distdir)/$$file || :; \ fi; \ done - for subdir in $(SUBDIRS); do \ - if test "$$subdir" = .; then :; else \ - test -d $(distdir)/$$subdir \ - || mkdir $(distdir)/$$subdir \ - || exit 1; \ - chmod 777 $(distdir)/$$subdir; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \ - || exit 1; \ - fi; \ - done + +DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) + +-include $(DEP_FILES) + +mostlyclean-depend: + +clean-depend: + +distclean-depend: + -rm -rf .deps + +maintainer-clean-depend: + +%.o: %.c + @echo '$(COMPILE) -c $<'; \ + $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-cp .deps/$(*F).pp .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm .deps/$(*F).pp + +%.lo: %.c + @echo '$(LTCOMPILE) -c $<'; \ + $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ + < .deps/$(*F).pp > .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm -f .deps/$(*F).pp info-am: -info: info-recursive +info: info-am dvi-am: -dvi: dvi-recursive +dvi: dvi-am check-am: all-am -check: check-recursive +check: check-am installcheck-am: -installcheck: installcheck-recursive +installcheck: installcheck-am install-exec-am: -install-exec: install-exec-recursive +install-exec: install-exec-am install-data-am: -install-data: install-data-recursive +install-data: install-data-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -install: install-recursive +install: install-am uninstall-am: -uninstall: uninstall-recursive +uninstall: uninstall-am all-am: Makefile $(LIBRARIES) -all-redirect: all-recursive +all-redirect: all-am install-strip: $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install -installdirs: installdirs-recursive -installdirs-am: +installdirs: mostlyclean-generic: @@ -298,46 +263,50 @@ distclean-generic: maintainer-clean-generic: mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \ - mostlyclean-tags mostlyclean-generic + mostlyclean-tags mostlyclean-depend mostlyclean-generic -mostlyclean: mostlyclean-recursive +mostlyclean: mostlyclean-am -clean-am: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \ - mostlyclean-am +clean-am: clean-noinstLIBRARIES clean-compile clean-tags clean-depend \ + clean-generic mostlyclean-am -clean: clean-recursive +clean: clean-am distclean-am: distclean-noinstLIBRARIES distclean-compile \ - distclean-tags distclean-generic clean-am + distclean-tags distclean-depend distclean-generic \ + clean-am -distclean: distclean-recursive +distclean: distclean-am maintainer-clean-am: maintainer-clean-noinstLIBRARIES \ maintainer-clean-compile maintainer-clean-tags \ - maintainer-clean-generic distclean-am + maintainer-clean-depend maintainer-clean-generic \ + distclean-am @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." -maintainer-clean: maintainer-clean-recursive +maintainer-clean: maintainer-clean-am .PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \ clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \ mostlyclean-compile distclean-compile clean-compile \ -maintainer-clean-compile install-data-recursive \ -uninstall-data-recursive install-exec-recursive \ -uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \ -all-recursive check-recursive installcheck-recursive info-recursive \ -dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \ -maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ -distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ +maintainer-clean-compile tags mostlyclean-tags distclean-tags \ +clean-tags maintainer-clean-tags distdir mostlyclean-depend \ +distclean-depend clean-depend maintainer-clean-depend info-am info \ dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ install-exec install-data-am install-data install-am install \ -uninstall-am uninstall all-redirect all-am all installdirs-am \ -installdirs mostlyclean-generic distclean-generic clean-generic \ +uninstall-am uninstall all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean -@USE_OPENGL_TRUE@ SUBDIRS += ggi -@USE_OPENGL_FALSE@ SUBDIRS += sdl + +@ENV_DJGPP_TRUE@ SUFFIXES = .asm +@ENV_DJGPP_TRUE@ %.o: %.asm +@ENV_DJGPP_TRUE@ $(NASM) $(NASMFLAGS) $< -o $@ + +@ENV_DJGPP_TRUE@ libinput_a_SOURCES += dos_joy2.asm +@ENV_DJGPP_TRUE@ libinput_a_LIBADD += dos_joy2.o +@ENV_DJGPP_TRUE@ dos_joyc.c: dos_joy2.o # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/input/dos_joy2.asm b/input/dos_joy2.asm new file mode 100644 index 00000000..195fc61e --- /dev/null +++ b/input/dos_joy2.asm @@ -0,0 +1,471 @@ +;THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +;SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +;END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +;ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +;IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +;SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +;FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +;CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +;AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +;COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. +; +; $Source: /cvs/cvsroot/d2x/input/dos_joy2.asm,v $ +; $Revision: 1.1.1.1 $ +; $Author: bradleyb $ +; $Date: 2001-01-19 03:33:43 $ +; +; Contains routines for joystick interface. +; +; $Log: not supported by cvs2svn $ +; Revision 1.1.1.1 1999/06/14 21:57:53 donut +; Import of d1x 1.37 source. +; +; Revision 1.17 1995/10/07 13:22:11 john +; Added new method of reading joystick that allows higher-priority +; interrupts to go off. +; +; Revision 1.16 1995/03/30 11:03:30 john +; Made -JoyBios read buttons using BIOS. +; +; Revision 1.15 1995/02/14 11:39:36 john +; Added polled/bios joystick readers.. +; +; Revision 1.14 1995/01/29 18:36:00 john +; Made timer count in mode 2 instead of mode 3. +; +; Revision 1.13 1994/12/28 15:32:21 john +; Added code to read joystick axis not all at one time. +; +; Revision 1.12 1994/12/27 15:44:59 john +; Made the joystick timeout be at 1/100th of a second, +; regardless of CPU speed. +; +; Revision 1.11 1994/11/15 12:04:40 john +; Cleaned up timer code a bit... took out unused functions +; like timer_get_milliseconds, etc. +; +; Revision 1.10 1994/07/01 10:55:54 john +; Fixed some bugs... added support for 4 axis. +; +; Revision 1.9 1994/06/30 20:36:54 john +; Revamped joystick code. +; +; Revision 1.8 1994/04/22 12:52:06 john + +[BITS 32] + +[SECTION .data] + + LastTick dd 0 + TotalTicks dd 0 + + global _joy_bogus_reading + global _joy_retries + extern _JOY_PORT + _joy_bogus_reading dd 0 + _joy_retries dd 0 + RetryCount dd 0 + + +[SECTION .text] + +; JOY_PORT EQU 0209h + TDATA EQU 40h + TCOMMAND EQU 43h + +joy_get_timer: + xor al, al ; Latch timer 0 command + out TCOMMAND, al ; Latch timer + in al, TDATA ; Read lo byte + mov ah, al + in al, TDATA ; Read hi byte + xchg ah, al + and eax, 0ffffh + ret + + + + +global _joy_read_stick_friendly2 +_joy_read_stick_friendly2: + push ebx + push edi + + mov ebx,[esp+12] + mov edi,[esp+16] + mov ecx,[esp+20] + + ; ebx = read mask + ; edi = pointer to event buffer + ; ecx = timeout value + ; returns in eax the number of events + + mov dword [RetryCount], 0 + mov dword [_joy_bogus_reading], 0 + +_joy_read_stick_friendly_retry: + inc dword [RetryCount] + cmp dword [RetryCount], 3 + jbe @@f1 + mov dword [_joy_bogus_reading], 1 + inc dword [_joy_retries] + mov eax, 0 + pop edi + pop ebx + ret + +@@f1: + push ecx + push ebx + push edi + + and ebx, 01111b ; Make sure we only check the right values + ; number of events we found will be in bh, so this also clears it to zero. + + mov dx, [_JOY_PORT] + + cli ; disable interrupts while reading time... + call joy_get_timer ; Returns counter in EAX + sti ; enable interrupts after reading time... + mov dword [LastTick], eax + +waitforstable_f: in al, dx + and al, bl + jz ready_f ; Wait for the port in question to be done reading... + + cli ; disable interrupts while reading time... + call joy_get_timer ; Returns counter in EAX + sti ; enable interrupts after reading time... + xchg eax, dword [LastTick] + cmp eax, dword [LastTick] + jb @@f2 + sub eax, dword [LastTick] +@@f2: ; Higher... + add dword [TotalTicks], eax + cmp dword [TotalTicks], ecx ; Timeout at 1/200'th of a second + jae ready_f + jmp waitforstable_f + +ready_f: + cli + mov al, 0ffh + out dx, al ; Start joystick a readin' + + call joy_get_timer ; Returns counter in EAX + mov dword [LastTick], eax + mov dword [TotalTicks], 0 + + mov [edi], eax ; Store initial count + add edi, 4 + +again_f: in al, dx ; Read Joystick port + not al + and al, bl ; Mask off channels we don't want to read + jnz flip_f ; See if any of the channels flipped + + ; none flipped -- check any interrupts... + mov al, 0Ah + out 20h, al + in al, 20h ; Get interrupts pending + cmp al, 0 + je NoInts + + ; Need to do an interrupt + sti + nop ; let the interrupt go on... + cli + + ; See if any axis turned + in al, dx + not al + and al, bl + jz NoInts + + ; At this point, an interrupt occured, making one or more + ; of the axis values bogus. So, we will restart this process... + + pop edi + pop ebx + pop ecx + + jmp _joy_read_stick_friendly_retry + +NoInts: + call joy_get_timer ; Returns counter in EAX + + xchg eax, dword [LastTick] + cmp eax, dword [LastTick] + jb @@f3 + sub eax, dword [LastTick] +@@f3: ; Higher... + add dword [TotalTicks], eax + cmp dword [TotalTicks], ecx ; Timeout at 1/200'th of a second + jae timed_out_f + jmp again_f + + flip_f: and eax, 01111b ; Only care about axis values + mov [edi], eax ; Record what channel(s) flipped + add edi, 4 + xor bl, al ; Unmark the channels that just tripped + + call joy_get_timer ; Returns counter in EAX + mov [edi], eax ; Record the time this channel flipped + add edi, 4 + inc bh ; Increment number of events + + cmp bl, 0 + jne again_f ; If there are more channels to read, keep looping + + timed_out_f: + sti + + movzx eax, bh ; Return number of events + + pop edi + pop ebx + pop ecx + + pop edi + pop ebx + ret + + + +global _joy_read_stick_asm2 + +_joy_read_stick_asm2: + push ebx + push edi + + mov ebx,[esp+12] + mov edi,[esp+16] + mov ecx,[esp+20] + + ; ebx = read mask + ; edi = pointer to event buffer + ; ecx = timeout value + ; returns in eax the number of events + mov dword [_joy_bogus_reading], 0 + + and ebx, 01111b ; Make sure we only check the right values + ; number of events we found will be in bh, so this also clears it to zero. + + mov dx, [_JOY_PORT] + + cli ; disable interrupts while reading time... + call joy_get_timer ; Returns counter in EAX + sti ; enable interrupts after reading time... + mov dword [LastTick], eax + +waitforstable: in al, dx + and al, bl + jz ready ; Wait for the port in question to be done reading... + + cli ; disable interrupts while reading time... + call joy_get_timer ; Returns counter in EAX + sti ; enable interrupts after reading time... + xchg eax, dword [LastTick] + cmp eax, dword [LastTick] + jb @@f4 + sub eax, dword [LastTick] +@@f4: ; Higher... + add dword [TotalTicks], eax + cmp dword [TotalTicks], ecx ; Timeout at 1/200'th of a second + jae ready + jmp waitforstable + +ready: + cli + mov al, 0ffh + out dx, al ; Start joystick a readin' + + call joy_get_timer ; Returns counter in EAX + mov dword [LastTick], eax + mov dword [TotalTicks], 0 + + mov [edi], eax ; Store initial count + add edi, 4 + + again: in al, dx ; Read Joystick port + not al + and al, bl ; Mask off channels we don't want to read + jnz flip ; See if any of the channels flipped + + call joy_get_timer ; Returns counter in EAX + + xchg eax, dword [LastTick] + cmp eax, dword [LastTick] + jb @@f5 + sub eax, dword [LastTick] +@@f5: ; Higher... + add dword [TotalTicks], eax + cmp dword [TotalTicks], ecx ; Timeout at 1/200'th of a second + jae timedout + jmp again + + flip: and eax, 01111b ; Only care about axis values + mov [edi], eax ; Record what channel(s) flipped + add edi, 4 + xor bl, al ; Unmark the channels that just tripped + + call joy_get_timer ; Returns counter in EAX + mov [edi], eax ; Record the time this channel flipped + add edi, 4 + inc bh ; Increment number of events + + cmp bl, 0 + jne again ; If there are more channels to read, keep looping + + timedout: + movzx eax, bh ; Return number of events + + sti + pop edi + pop ebx + ret + + +global _joy_read_stick_polled2 + +_joy_read_stick_polled2: + push ebx + push edi + + mov ebx,[esp+12] + mov edi,[esp+16] + mov ecx,[esp+20] + + ; ebx = read mask + ; edi = pointer to event buffer + ; ecx = timeout value + ; returns in eax the number of events + mov dword [_joy_bogus_reading], 0 + + and ebx, 01111b ; Make sure we only check the right values + ; number of events we found will be in bh, so this also clears it to zero. + + mov dx, [_JOY_PORT] + + mov dword [TotalTicks], 0 + +waitforstable1: in al, dx + and al, bl + jz ready1 ; Wait for the port in question to be done reading... + + inc dword [TotalTicks] + cmp dword [TotalTicks], ecx ; Timeout at 1/200'th of a second + jae ready1 + jmp waitforstable1 +ready1: + cli + mov al, 0ffh + out dx, al ; Start joystick a readin' + + mov dword [TotalTicks], 0 + + mov dword [edi], 0 ; Store initial count + add edi, 4 + + again1: in al, dx ; Read Joystick port + not al + and al, bl ; Mask off channels we don't want to read + jnz flip1 ; See if any of the channels flipped + + inc dword [TotalTicks] + cmp dword [TotalTicks], ecx ; Timeout at 1/200'th of a second + jae timedout1 + jmp again1 + + flip1: and eax, 01111b ; Only care about axis values + mov [edi], eax ; Record what channel(s) flipped + add edi, 4 + xor bl, al ; Unmark the channels that just tripped + + mov eax, dword [TotalTicks] + mov [edi], eax ; Record the time this channel flipped + add edi, 4 + inc bh ; Increment number of events + + cmp bl, 0 + jne again1 ; If there are more channels to read, keep looping + + timedout1: + movzx eax, bh ; Return number of events + + sti + pop edi + pop ebx + ret + +global _joy_read_stick_bios2 + +_joy_read_stick_bios2: + push ebx + push edi + + mov ebx,[esp+12] + mov edi,[esp+16] + mov ecx,[esp+20] + ; ebx = read mask + ; edi = pointer to event buffer + ; ecx = timeout value + ; returns in eax the number of events + + mov dword [_joy_bogus_reading], 0 + + pusha + + mov dword [edi], 0 + + mov eax, 08400h + mov edx, 1 + cli + int 15h + sti + + mov dword [edi+4], 1 ; Axis 1 + and eax, 0ffffh + mov [edi+8], eax ; Axis 1 value + + mov dword [edi+12], 2 ; Axis 2 + and ebx, 0ffffh + mov [edi+16], ebx ; Axis 2 value + + mov dword [edi+20], 4 ; Axis 3 + and ecx, 0ffffh + mov [edi+24], ecx ; Axis 3 value + + mov dword [edi+28], 8 ; Axis 3 + and edx, 0ffffh + mov [edi+32], edx ; Axis 3 value + + popa + mov eax, 4 ; 4 events + + pop edi + pop ebx + ret + + +global _joy_read_buttons_bios2 + +_joy_read_buttons_bios2: + ; returns in eax the button settings + + push ebx + push ecx + push edx + mov eax, 08400h + mov edx, 0 ; Read switches + int 15h + pop edx + pop ecx + pop ebx + + shr eax, 4 + not eax + and eax, 01111b + ret +global _joy_read_buttons_bios_end2 +_joy_read_buttons_bios_end2: ; to calculate _joy_read_buttons_bios size + diff --git a/input/dos_joyc.c b/input/dos_joyc.c new file mode 100644 index 00000000..870f291c --- /dev/null +++ b/input/dos_joyc.c @@ -0,0 +1,657 @@ +/* +THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. +*/ + +#include + +#ifdef __ENV_DJGPP__ + +#include +#include +#include + +//#define ARCADE 1 + +#include "pstypes.h" +#include "mono.h" +#include "joy.h" +#include "u_dpmi.h" +#include "timer.h" + +#include "args.h" + +extern int joy_bogus_reading; +int JOY_PORT = 513; //201h; +int joy_deadzone = 0; + +int joy_read_stick_asm2( int read_masks, int * event_buffer, int timeout ); +int joy_read_stick_friendly2( int read_masks, int * event_buffer, int timeout ); +int joy_read_stick_polled2( int read_masks, int * event_buffer, int timeout ); +int joy_read_stick_bios2( int read_masks, int * event_buffer, int timeout ); +int joy_read_buttons_bios2(); +void joy_read_buttons_bios_end2(); + + +//In key.c +// ebx = read mask +// edi = pointer to buffer +// returns number of events + +char joy_installed = 0; +char joy_present = 0; + +typedef struct Button_info { + ubyte ignore; + ubyte state; + ubyte last_state; + int timedown; + ubyte downcount; + ubyte upcount; +} Button_info; + +typedef struct Joy_info { + ubyte present_mask; + ubyte slow_read; + int max_timer; + int read_count; + ubyte last_value; + Button_info buttons[MAX_BUTTONS]; + int axis_min[4]; + int axis_center[4]; + int axis_max[4]; +} Joy_info; + +Joy_info joystick; + +ubyte joy_read_buttons() +{ + return ((~(inp(JOY_PORT) >> 4))&0xf); +} + +void joy_get_cal_vals(int *axis_min, int *axis_center, int *axis_max) +{ + int i; + + for (i=0; i<4; i++) { + axis_min[i] = joystick.axis_min[i]; + axis_center[i] = joystick.axis_center[i]; + axis_max[i] = joystick.axis_max[i]; + } +} + +void joy_set_cal_vals(int *axis_min, int *axis_center, int *axis_max) +{ + int i; + + for (i=0; i<4; i++) { + joystick.axis_min[i] = axis_min[i]; + joystick.axis_center[i] = axis_center[i]; + joystick.axis_max[i] = axis_max[i]; + } +} + + +ubyte joy_get_present_mask() { + return joystick.present_mask; +} + +void joy_set_timer_rate(int max_value ) { + _disable(); + joystick.max_timer = max_value; + _enable(); +} + +int joy_get_timer_rate() { + return joystick.max_timer; +} + + +void joy_flush() { + int i; + + if (!joy_installed) return; + + _disable(); + for (i=0; i 7 ) { + joystick.read_count = 0; + value = joy_read_buttons_bios2(); + joystick.last_value = value; + } else { + value = joystick.last_value; + } + } else { + value = joy_read_buttons(); //JOY_READ_BUTTONS; + } + + for (i=0; iignore) { + if ( i < 5 ) + state = (value >> i) & 1; + else if (i==(value+4)) + state = 1; + else + state = 0; + + if ( button->last_state == state ) { + if (state) button->timedown += ticks_this_time; + } else { + if (state) { + button->downcount += state; + button->state = 1; + } else { + button->upcount += button->state; + button->state = 0; + } + button->last_state = state; + } + } + } +} + +void joy_handler_end() { // Dummy function to help calculate size of joystick handler function +} + + +ubyte joy_read_raw_buttons() { + if ( joystick.slow_read & JOY_BIOS_READINGS ) + return joy_read_buttons_bios2(); + else + return joy_read_buttons(); //JOY_READ_BUTTONS; +} + +void joy_set_slow_reading(int flag) +{ + joystick.slow_read |= flag; + joy_set_cen(); +} + +ubyte joystick_read_raw_axis( ubyte mask, int * axis ) +{ + ubyte read_masks, org_masks; + int t, t1, t2, buffer[4*2+2]; + int e, i, num_channels, c; + + axis[0] = 0; axis[1] = 0; + axis[2] = 0; axis[3] = 0; + + if (!joy_installed) return 0; + + read_masks = 0; + org_masks = mask; + + mask &= joystick.present_mask; // Don't read non-present channels + if ( mask==0 ) { + return 0; // Don't read if no stick connected. + } + + if ( joystick.slow_read & JOY_SLOW_READINGS ) { + for (c=0; c<4; c++ ) { + if ( mask & (1 << c)) { + // Time out at (1/100th of a second) + + if ( joystick.slow_read & JOY_POLLED_READINGS ) + num_channels = joy_read_stick_polled2( (1 << c), buffer, 65536 ); + else if ( joystick.slow_read & JOY_BIOS_READINGS ) + num_channels = joy_read_stick_bios2( (1 << c), buffer, 65536 ); + else if ( joystick.slow_read & JOY_FRIENDLY_READINGS ) + num_channels = joy_read_stick_friendly2( (1 << c), buffer, (1193180/100) ); + else + num_channels = joy_read_stick_asm2( (1 << c), buffer, (1193180/100) ); + + if ( num_channels > 0 ) { + t1 = buffer[0]; + e = buffer[1]; + t2 = buffer[2]; + if ( joystick.slow_read & (JOY_POLLED_READINGS|JOY_BIOS_READINGS) ) { + t = t2 - t1; + } else { + if ( t1 > t2 ) + t = t1 - t2; + else { + t = t1 + joystick.max_timer - t2; + //mprintf( 0, "%d, %d, %d, %d\n", t1, t2, joystick.max_timer, t ); + } + } + + if ( e & 1 ) { axis[0] = t; read_masks |= 1; } + if ( e & 2 ) { axis[1] = t; read_masks |= 2; } + if ( e & 4 ) { axis[2] = t; read_masks |= 4; } + if ( e & 8 ) { axis[3] = t; read_masks |= 8; } + } + } + } + } else { + // Time out at (1/100th of a second) + if ( joystick.slow_read & JOY_POLLED_READINGS ) + num_channels = joy_read_stick_polled2( mask, buffer, 65536 ); + else if ( joystick.slow_read & JOY_BIOS_READINGS ) + num_channels = joy_read_stick_bios2( mask, buffer, 65536 ); + else if ( joystick.slow_read & JOY_FRIENDLY_READINGS ) + num_channels = joy_read_stick_friendly2( mask, buffer, (1193180/100) ); + else + num_channels = joy_read_stick_asm2( mask, buffer, (1193180/100) ); + //mprintf(( 0, "(%d)\n", num_channels )); + + for (i=0; i t2 ) + t = t1 - t2; + else { + t = t1 + joystick.max_timer - t2; + //mprintf(( 0, "%d, %d, %d, %d\n", t1, t2, joystick.max_timer, t )); + } + } + e = buffer[i*2+1]; + + if ( e & 1 ) { axis[0] = t; read_masks |= 1; } + if ( e & 2 ) { axis[1] = t; read_masks |= 2; } + if ( e & 4 ) { axis[2] = t; read_masks |= 4; } + if ( e & 8 ) { axis[3] = t; read_masks |= 8; } + } + + } + + return read_masks; +} + +#ifdef __GNUC__ +#define near +#endif + +int joy_init() +{ + int i; + int temp_axis[4]; + +// if(args_find("-joy209")) +// use_alt_joyport=1; + if(args_find("-joy209")) + JOY_PORT = 521; //209h; + + joy_flush(); + + _disable(); + for (i=0; i 127 ) + x = 127; + +//added on 4/13/99 by Victor Rachels to add deadzone control + dz = (joy_deadzone) * 6; + if ((x > (-1*dz)) && (x < dz)) + x = 0; +//end this section addition -VR + + return x; +} + +int last_reading[4] = { 0, 0, 0, 0 }; + +void joy_get_pos( int *x, int *y ) +{ + ubyte flags; + int axis[4]; + + if ((!joy_installed)||(!joy_present)) { *x=*y=0; return; } + + flags=joystick_read_raw_axis( JOY_1_X_AXIS+JOY_1_Y_AXIS, axis ); + + if ( joy_bogus_reading ) { + axis[0] = last_reading[0]; + axis[1] = last_reading[1]; + flags = JOY_1_X_AXIS+JOY_1_Y_AXIS; + } else { + last_reading[0] = axis[0]; + last_reading[1] = axis[1]; + } + + if ( flags & JOY_1_X_AXIS ) + *x = joy_get_scaled_reading( axis[0], 0 ); + else + *x = 0; + + if ( flags & JOY_1_Y_AXIS ) + *y = joy_get_scaled_reading( axis[1], 1 ); + else + *y = 0; +} + +ubyte joy_read_stick( ubyte masks, int *axis ) +{ + ubyte flags; + int raw_axis[4]; + + if ((!joy_installed)||(!joy_present)) { + axis[0] = 0; axis[1] = 0; + axis[2] = 0; axis[3] = 0; + return 0; + } + + flags=joystick_read_raw_axis( masks, raw_axis ); + + if ( joy_bogus_reading ) { + axis[0] = last_reading[0]; + axis[1] = last_reading[1]; + axis[2] = last_reading[2]; + axis[3] = last_reading[3]; + flags = masks; + } else { + last_reading[0] = axis[0]; + last_reading[1] = axis[1]; + last_reading[2] = axis[2]; + last_reading[3] = axis[3]; + } + + if ( flags & JOY_1_X_AXIS ) + axis[0] = joy_get_scaled_reading( raw_axis[0], 0 ); + else + axis[0] = 0; + + if ( flags & JOY_1_Y_AXIS ) + axis[1] = joy_get_scaled_reading( raw_axis[1], 1 ); + else + axis[1] = 0; + + if ( flags & JOY_2_X_AXIS ) + axis[2] = joy_get_scaled_reading( raw_axis[2], 2 ); + else + axis[2] = 0; + + if ( flags & JOY_2_Y_AXIS ) + axis[3] = joy_get_scaled_reading( raw_axis[3], 3 ); + else + axis[3] = 0; + + return flags; +} + + +int joy_get_btns() +{ + if ((!joy_installed)||(!joy_present)) return 0; + + return joy_read_raw_buttons(); +} + +void joy_get_btn_down_cnt( int *btn0, int *btn1 ) +{ + if ((!joy_installed)||(!joy_present)) { *btn0=*btn1=0; return; } + + _disable(); + *btn0 = joystick.buttons[0].downcount; + joystick.buttons[0].downcount = 0; + *btn1 = joystick.buttons[1].downcount; + joystick.buttons[1].downcount = 0; + _enable(); +} + +int joy_get_button_state( int btn ) +{ + int count; + + if ((!joy_installed)||(!joy_present)) return 0; + + if ( btn >= MAX_BUTTONS ) return 0; + + _disable(); + count = joystick.buttons[btn].state; + _enable(); + + return count; +} + +int joy_get_button_up_cnt( int btn ) +{ + int count; + + if ((!joy_installed)||(!joy_present)) return 0; + + if ( btn >= MAX_BUTTONS ) return 0; + + _disable(); + count = joystick.buttons[btn].upcount; + joystick.buttons[btn].upcount = 0; + _enable(); + + return count; +} + +int joy_get_button_down_cnt( int btn ) +{ + int count; + + if ((!joy_installed)||(!joy_present)) return 0; + if ( btn >= MAX_BUTTONS ) return 0; + + _disable(); + count = joystick.buttons[btn].downcount; + joystick.buttons[btn].downcount = 0; + _enable(); + + return count; +} + + +fix joy_get_button_down_time( int btn ) +{ + fix count; + + if ((!joy_installed)||(!joy_present)) return 0; + if ( btn >= MAX_BUTTONS ) return 0; + + _disable(); + count = joystick.buttons[btn].timedown; + joystick.buttons[btn].timedown = 0; + _enable(); + + return fixmuldiv(count, 65536, 1193180 ); +} + +void joy_get_btn_up_cnt( int *btn0, int *btn1 ) +{ + if ((!joy_installed)||(!joy_present)) { *btn0=*btn1=0; return; } + + _disable(); + *btn0 = joystick.buttons[0].upcount; + joystick.buttons[0].upcount = 0; + *btn1 = joystick.buttons[1].upcount; + joystick.buttons[1].upcount = 0; + _enable(); +} + +void joy_set_btn_values( int btn, int state, fix timedown, int downcount, int upcount ) +{ + _disable(); + joystick.buttons[btn].ignore = 1; + joystick.buttons[btn].state = state; + joystick.buttons[btn].timedown = fixmuldiv( timedown, 1193180, 65536 ); + joystick.buttons[btn].downcount = downcount; + joystick.buttons[btn].upcount = upcount; + _enable(); +} + +void joy_poll() +{ + if ( joystick.slow_read & JOY_BIOS_READINGS ) + joystick.last_value = joy_read_buttons_bios2(); +} + +#endif // __ENV_DJGPP__ diff --git a/input/dos_joydefs.c b/input/dos_joydefs.c new file mode 100644 index 00000000..5825c269 --- /dev/null +++ b/input/dos_joydefs.c @@ -0,0 +1,419 @@ +/* +THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. +*/ + +#include + +#ifdef __ENV_DJGPP__ + +#include +#include +#include + +#include "pstypes.h" +#include "mono.h" +#include "key.h" +#include "joy.h" +#include "timer.h" +#include "error.h" + +#include "inferno.h" +#include "game.h" +#include "object.h" +#include "player.h" + +#include "controls.h" +#include "joydefs.h" +#include "render.h" +#include "palette.h" +#include "newmenu.h" +#include "args.h" +#include "text.h" +#include "kconfig.h" +#include "digi.h" +#include "playsave.h" + +int joydefs_calibrate_flag = 0; + +int Joy_is_Sidewinder = 0; + +void joy_delay() +{ +#ifdef __MSDOS__ + int t1 = TICKER + 19/4; // Wait 1/4 second... + stop_time(); + while( TICKER < t1 ); + joy_flush(); + start_time(); +#endif +} + + +int joycal_message( char * title, char * text ) +{ + int i; + newmenu_item m[2]; + m[0].type = NM_TYPE_TEXT; m[0].text = text; + m[1].type = NM_TYPE_MENU; m[1].text = TXT_OK; + i = newmenu_do( title, NULL, 2, m, NULL ); + if ( i < 0 ) + return 1; + return 0; +} + +extern int WriteConfigFile(); + +void joydefs_calibrate() +{ + ubyte masks; + int org_axis_min[4]; + int org_axis_center[4]; + int org_axis_max[4]; + + int axis_min[4] = { 0, 0, 0, 0 }; + int axis_cen[4] = { 0, 0, 0, 0 }; + int axis_max[4] = { 0, 0, 0, 0 }; + + int temp_values[4]; + char title[50]; + char text[50]; + int nsticks = 0; + + joydefs_calibrate_flag = 0; + + if ( (Config_control_type!=CONTROL_JOYSTICK) && (Config_control_type!=CONTROL_FLIGHTSTICK_PRO) && (Config_control_type!=CONTROL_THRUSTMASTER_FCS) && (Config_control_type!=CONTROL_GRAVIS_GAMEPAD) ) + return; + + joy_get_cal_vals(org_axis_min, org_axis_center, org_axis_max); + + joy_set_cen(); + joystick_read_raw_axis( JOY_ALL_AXIS, temp_values ); + + if (!joy_present) { + nm_messagebox( NULL, 1, TXT_OK, TXT_NO_JOYSTICK ); + return; + } + + masks = joy_get_present_mask(); + + if ( masks == JOY_ALL_AXIS ) + nsticks = 2; + else + nsticks = 1; + + if ( nsticks == 2 && !Joy_is_Sidewinder) { + sprintf( title, "%s #1\n%s", TXT_JOYSTICK, TXT_UPPER_LEFT); + sprintf( text, "%s #1 %s", TXT_MOVE_JOYSTICK, TXT_TO_UL); + } else { + sprintf( title, "%s\n%s", TXT_JOYSTICK, TXT_UPPER_LEFT); + sprintf( text, "%s %s", TXT_MOVE_JOYSTICK, TXT_TO_UL); + } + if (joycal_message( title, text )) { + joy_set_cal_vals(org_axis_min, org_axis_center, org_axis_max); + return; + } + joystick_read_raw_axis( JOY_ALL_AXIS, temp_values ); + axis_min[0] = temp_values[0]; + axis_min[1] = temp_values[1]; + joy_delay(); + + if ( nsticks == 2 && !Joy_is_Sidewinder) { + sprintf( title, "%s #1\n%s", TXT_JOYSTICK, TXT_LOWER_RIGHT); + sprintf( text, "%s #1 %s", TXT_MOVE_JOYSTICK, TXT_TO_LR); + } else { + sprintf( title, "%s\n%s", TXT_JOYSTICK, TXT_LOWER_RIGHT); + sprintf( text, "%s %s", TXT_MOVE_JOYSTICK, TXT_TO_LR); + } + if (joycal_message( title, text)) { + joy_set_cal_vals(org_axis_min, org_axis_center, org_axis_max); + return; + } + joystick_read_raw_axis( JOY_ALL_AXIS, temp_values ); + axis_max[0] = temp_values[0]; + axis_max[1] = temp_values[1]; + joy_delay(); + + if ( nsticks == 2 && !Joy_is_Sidewinder) { + sprintf( title, "%s #1\n%s", TXT_JOYSTICK, TXT_CENTER); + sprintf( text, "%s #1 %s", TXT_MOVE_JOYSTICK, TXT_TO_C); + } else { + sprintf( title, "%s\n%s", TXT_JOYSTICK, TXT_CENTER); + sprintf( text, "%s %s", TXT_MOVE_JOYSTICK, TXT_TO_C); + } + if (joycal_message( title, text)) { + joy_set_cal_vals(org_axis_min, org_axis_center, org_axis_max); + return; + } + joystick_read_raw_axis( JOY_ALL_AXIS, temp_values ); + axis_cen[0] = temp_values[0]; + axis_cen[1] = temp_values[1]; + joy_delay(); + + // The fcs uses axes 3 for hat, so don't calibrate it. + if (Config_control_type == CONTROL_THRUSTMASTER_FCS) { + axis_min[3] = 0; + axis_cen[3] = temp_values[3]/2; + axis_max[3] = temp_values[3]; + joy_delay(); + } + + if (Joy_is_Sidewinder || Config_control_type != CONTROL_THRUSTMASTER_FCS) { + // masks = joy_get_present_mask(); + + if ( nsticks == 2 ) { + if ( kconfig_is_axes_used(2) || kconfig_is_axes_used(3) ) { + if(Joy_is_Sidewinder) + { + sprintf( title, "%s\nTWIST-LEFT", TXT_JOYSTICK); + sprintf( text, "Twist Joystick to \nthe left side"); + } + else + { + sprintf( title, "%s #2\n%s", TXT_JOYSTICK, TXT_UPPER_LEFT); + sprintf( text, "%s #2 %s", TXT_MOVE_JOYSTICK, TXT_TO_UL); + } + if (joycal_message( title, text )) { + joy_set_cal_vals(org_axis_min, org_axis_center, org_axis_max); + return; + } + joystick_read_raw_axis( JOY_ALL_AXIS, temp_values ); + axis_min[2] = temp_values[2]; + axis_min[3] = temp_values[3]; + joy_delay(); + + if(Joy_is_Sidewinder) + { + sprintf( title, "%s\nTWIST-RIGHT", TXT_JOYSTICK); + sprintf( text, "Twist Joystick to \nthe right side"); + } + else + { + sprintf( title, "%s #2\n%s", TXT_JOYSTICK, TXT_LOWER_RIGHT); + sprintf( text, "%s #2 %s", TXT_MOVE_JOYSTICK, TXT_TO_LR); + } + if (joycal_message( title, text )) { + joy_set_cal_vals(org_axis_min, org_axis_center, org_axis_max); + return; + } + joystick_read_raw_axis( JOY_ALL_AXIS, temp_values ); + axis_max[2] = temp_values[2]; + axis_max[3] = temp_values[3]; + joy_delay(); + + + if(Joy_is_Sidewinder) + { + sprintf( title, "%s\nCENTER", TXT_JOYSTICK); + sprintf( text, "%s %s",TXT_MOVE_JOYSTICK, TXT_TO_C); + } + else + { + sprintf( title, "%s #2\n%s", TXT_JOYSTICK, TXT_CENTER); + sprintf( text, "%s #2 %s", TXT_MOVE_JOYSTICK, TXT_TO_C); + } + + if (joycal_message( title, text )) { + joy_set_cal_vals(org_axis_min, org_axis_center, org_axis_max); + return; + } + joystick_read_raw_axis( JOY_ALL_AXIS, temp_values ); + axis_cen[2] = temp_values[2]; + axis_cen[3] = temp_values[3]; + joy_delay(); + } + } else if ( (!(masks & JOY_2_X_AXIS)) && (masks & JOY_2_Y_AXIS) ) { + if ( kconfig_is_axes_used(3) ) { + // A throttle axis!!!!! + sprintf( title, "%s\n%s", TXT_THROTTLE, TXT_FORWARD); + if (joycal_message( title, TXT_MOVE_THROTTLE_F)) { + joy_set_cal_vals(org_axis_min, org_axis_center, org_axis_max); + return; + } + joystick_read_raw_axis( JOY_ALL_AXIS, temp_values ); + axis_min[3] = temp_values[3]; + joy_delay(); + + sprintf( title, "%s\n%s", TXT_THROTTLE, TXT_REVERSE); + if (joycal_message( title, TXT_MOVE_THROTTLE_R)) { + joy_set_cal_vals(org_axis_min, org_axis_center, org_axis_max); + return; + } + joystick_read_raw_axis( JOY_ALL_AXIS, temp_values ); + axis_max[3] = temp_values[3]; + joy_delay(); + + sprintf( title, "%s\n%s", TXT_THROTTLE, TXT_CENTER); + if (joycal_message( title, TXT_MOVE_THROTTLE_C)) { + joy_set_cal_vals(org_axis_min, org_axis_center, org_axis_max); + return; + } + joystick_read_raw_axis( JOY_ALL_AXIS, temp_values ); + axis_cen[3] = temp_values[3]; + joy_delay(); + } + } + } + joy_set_cal_vals(axis_min, axis_cen, axis_max); + + +//added 9/1/98 by Victor Rachels to make sidewinder calibratable +/* if(Joy_is_Sidewinder) + Config_control_type=tempstick; */ +//end this section addition - Victor Rachels + + + WriteConfigFile(); +} + + +//char *control_text[CONTROL_MAX_TYPES] = { "Keyboard only", "Joystick", "Flightstick Pro", "Thrustmaster FCS", "Gravis Gamepad", "Mouse", "Cyberman" }; + +void joydef_menuset_1(int nitems, newmenu_item * items, int *last_key, int citem ) +{ + int i; + int oc_type = Config_control_type; + + nitems = nitems; + last_key = last_key; + citem = citem; + + for (i=0; i-1); + + switch (Config_control_type) { + case CONTROL_JOYSTICK: + case CONTROL_FLIGHTSTICK_PRO: + case CONTROL_THRUSTMASTER_FCS: + case CONTROL_GRAVIS_GAMEPAD: + if ( joydefs_calibrate_flag ) + joydefs_calibrate(); + break; + } + +} + + +#endif // __ENV_DJGPP__ diff --git a/input/dos_key.c b/input/dos_key.c new file mode 100644 index 00000000..387f01b6 --- /dev/null +++ b/input/dos_key.c @@ -0,0 +1,584 @@ +/* +THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. +*/ + +//#define PASS_KEYS_TO_BIOS 1 //if set, bios gets keys + +#include + +#ifdef __ENV_DJGPP__ +#include +#include +#include + +//#define WATCOM_10 +#ifdef __DJGPP__ +#include +#define _far +#define __far +#define __interrupt +#define near +_go32_dpmi_seginfo kbd_hand_info; +#endif +#include "error.h" +#include "key.h" +#include "timer.h" +#include "u_dpmi.h" + +#define KEY_BUFFER_SIZE 16 + + +//-------- Variable accessed by outside functions --------- +unsigned char keyd_buffer_type; // 0=No buffer, 1=buffer ASCII, 2=buffer scans +unsigned char keyd_repeat; +unsigned char keyd_editor_mode; +volatile unsigned char keyd_last_pressed; +volatile unsigned char keyd_last_released; +volatile unsigned char keyd_pressed[256]; +volatile int keyd_time_when_last_pressed; + +typedef struct keyboard { + unsigned short keybuffer[KEY_BUFFER_SIZE]; + fix time_pressed[KEY_BUFFER_SIZE]; + fix TimeKeyWentDown[256]; + fix TimeKeyHeldDown[256]; + unsigned int NumDowns[256]; + unsigned int NumUps[256]; + unsigned int keyhead, keytail; + unsigned char E0Flag; + unsigned char E1Flag; + int in_key_handler; +#ifdef __DJGPP__ + _go32_dpmi_seginfo prev_int_9; +#else + void (__interrupt __far *prev_int_9)(); +#endif +} keyboard; + +static volatile keyboard key_data; + +static unsigned char Installed=0; + +unsigned char ascii_table[128] = +{ 255, 255, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=',255,255, + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 255, 255, + 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', 39, '`', + 255, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 255,'*', + 255, ' ', 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255,255, + 255, 255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255 }; + +unsigned char shifted_ascii_table[128] = +{ 255, 255, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+',255,255, + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 255, 255, + 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', + 255, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 255,255, + 255, ' ', 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255,255, + 255, 255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255 }; +/* +char * key_text[256] = { +"","ESC","1","2","3","4","5","6","7","8","9","0","-", +"=","BSPC","TAB","Q","W","E","R","T","Y","U","I","O", +"P","[","]","ƒ","LCTRL","A","S","D","F", +"G","H","J","K","L",";","'","`", +"LSHFT","\\","Z","X","C","V","B","N","M",",", +".","/","RSHFT","PAD*","LALT","SPC", +"CPSLK","F1","F2","F3","F4","F5","F6","F7","F8","F9", +"F10","NMLCK","SCLK","PAD7","PAD8","PAD9","PAD-", +"PAD4","PAD5","PAD6","PAD+","PAD1","PAD2","PAD3","PAD0", +"PAD.","","","","F11","F12","","","","","","","","","", +"","","","","","","","","","","","","","","","","","","","", +"","","","","","","","","","","","","","","","","","","","", +"","","","","","","","","","","","","","","","","","", +"PADƒ","RCTRL","","","","","","","","","","","","","", +"","","","","","","","","","","PAD/","","","RALT","", +"","","","","","","","","","","","","","HOME","‚","PGUP", +"","","","","","END","€","PGDN","INS", +"DEL","","","","","","","","","","","","","","","","","", +"","","","","","","","","","","","","","","","","","","","", +"","","","","","","" }; +*/ +unsigned char key_to_ascii(int keycode ) +{ + int shifted; + + shifted = keycode & KEY_SHIFTED; + keycode &= 0xFF; + + if ( keycode>=127 ) + return 255; + + if (shifted) + return shifted_ascii_table[keycode]; + else + return ascii_table[keycode]; +} + +void key_clear_bios_buffer_all() +{ +#ifdef __WATCOMC__ + // Clear keyboard buffer... + *(ushort *)0x41a=*(ushort *)0x41c; + // Clear the status bits... + *(ubyte *)0x417 = 0; + *(ubyte *)0x418 = 0; +#else + _farpokew(_dos_ds,0x41a, _farpeekw(_dos_ds, 0x41c)); + _farpokeb(_dos_ds,0x417, 0); + _farpokeb(_dos_ds,0x418, 0); +#endif +} + +void key_clear_bios_buffer() +{ +#ifdef __WATCOMC__ + // Clear keyboard buffer... + *(ushort *)0x41a=*(ushort *)0x41c; +#else + _farpokew(_dos_ds,0x41a, _farpeekw(_dos_ds, 0x41c)); +#endif +} + +void key_flush() +{ + int i; + fix CurTime; + + _disable(); + + // Clear the BIOS buffer + key_clear_bios_buffer(); + + key_data.keyhead = key_data.keytail = 0; + + //Clear the keyboard buffer + for (i=0; i= KEY_BUFFER_SIZE ) n=0; + return n; +} + +// Returns 1 if character waiting... 0 otherwise +int key_checkch() +{ + int is_one_waiting = 0; + + _disable(); + + key_clear_bios_buffer(); + + if (key_data.keytail!=key_data.keyhead) + is_one_waiting = 1; + _enable(); + return is_one_waiting; +} + +int key_inkey() +{ + int key = 0; + + _disable(); + + key_clear_bios_buffer(); + + if (key_data.keytail!=key_data.keyhead) { + key = key_data.keybuffer[key_data.keyhead]; + key_data.keyhead = add_one(key_data.keyhead); + } + _enable(); + return key; +} + +int key_inkey_time(fix * time) +{ + int key = 0; + + _disable(); + + key_clear_bios_buffer(); + + if (key_data.keytail!=key_data.keyhead) { + key = key_data.keybuffer[key_data.keyhead]; + *time = key_data.time_pressed[key_data.keyhead]; + key_data.keyhead = add_one(key_data.keyhead); + } + _enable(); + return key; +} + + + +int key_peekkey() +{ + int key = 0; + + _disable(); + + key_clear_bios_buffer(); + + if (key_data.keytail!=key_data.keyhead) { + key = key_data.keybuffer[key_data.keyhead]; + } + _enable(); + return key; +} + +// If not installed, uses BIOS and returns getch(); +// Else returns pending key (or waits for one if none waiting). +int key_getch() +{ + int dummy=0; + + if (!Installed) + return getch(); + + while (!key_checkch()) + dummy++; + return key_inkey(); +} + +unsigned int key_get_shift_status() +{ + unsigned int shift_status = 0; + + _disable(); + + key_clear_bios_buffer(); + + if ( keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT] ) + shift_status |= KEY_SHIFTED; + + if ( keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT] ) + shift_status |= KEY_ALTED; + + if ( keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL] ) + shift_status |= KEY_CTRLED; + +#ifndef NDEBUG + if (keyd_pressed[KEY_DELETE]) + shift_status |=KEY_DEBUGGED; +#endif + + _enable(); + + return shift_status; +} + +// Returns the number of seconds this key has been down since last call. +fix key_down_time(int scancode) { + fix time_down, time; + + if ((scancode<0)|| (scancode>255)) return 0; + +#ifndef NDEBUG + if (keyd_editor_mode && key_get_shift_status() ) + return 0; +#endif + + _disable(); + + if ( !keyd_pressed[scancode] ) { + time_down = key_data.TimeKeyHeldDown[scancode]; + key_data.TimeKeyHeldDown[scancode] = 0; + } else { + time = timer_get_fixed_secondsX(); + time_down = time - key_data.TimeKeyWentDown[scancode]; + key_data.TimeKeyWentDown[scancode] = time; + } + _enable(); + + return time_down; +} + +// Returns number of times key has went from up to down since last call. +unsigned int key_down_count(int scancode) { + int n; + + if ((scancode<0)|| (scancode>255)) return 0; + + _disable(); + n = key_data.NumDowns[scancode]; + key_data.NumDowns[scancode] = 0; + _enable(); + + return n; +} + + +// Returns number of times key has went from down to up since last call. +unsigned int key_up_count(int scancode) { + int n; + + if ((scancode<0)|| (scancode>255)) return 0; + + _disable(); + n = key_data.NumUps[scancode]; + key_data.NumUps[scancode] = 0; + _enable(); + + return n; +} + +// Use intrinsic forms so that we stay in the locked interrup code. + +#ifdef __WATCOMC__ +void Int5(); +#pragma aux Int5 = "int 5"; +#else +#ifdef __GNUC__ +#define Int5() asm volatile("int $5") +#endif +#endif + +void __interrupt __far key_handler() +{ + unsigned char scancode, breakbit, temp; + unsigned short keycode; + +#ifndef WATCOM_10 +#ifndef NDEBUG +#ifdef __WATCOMC__ /* must have _chain_intr */ + ubyte * MONO = (ubyte *)(0x0b0000+24*80*2); + if ( ((MONO[0]=='D') && (MONO[2]=='B') && (MONO[4]=='G') && (MONO[6]=='>')) || + ((MONO[14]=='<') && (MONO[16]=='i') && (MONO[18]=='>') && (MONO[20]==' ') && (MONO[22]=='-')) || + ((MONO[0]==200 ) && (MONO[2]==27) && (MONO[4]==17) ) + ) + _chain_intr( key_data.prev_int_9 ); +#endif +#endif +#endif + + // Read in scancode + scancode = inp( 0x60 ); + + switch( scancode ) { + case 0xE0: + key_data.E0Flag = 0x80; + break; + default: + // Parse scancode and break bit + if (key_data.E1Flag > 0 ) { // Special code for Pause, which is E1 1D 45 E1 9D C5 + key_data.E1Flag--; + if ( scancode == 0x1D ) { + scancode = KEY_PAUSE; + breakbit = 0; + } else if ( scancode == 0x9d ) { + scancode = KEY_PAUSE; + breakbit = 1; + } else { + break; // skip this keycode + } + } else if ( scancode==0xE1 ) { + key_data.E1Flag = 2; + break; + } else { + breakbit = scancode & 0x80; // Get make/break bit + scancode &= 0x7f; // Strip make/break bit off of scancode + scancode |= key_data.E0Flag; // Add in extended key code + } + key_data.E0Flag = 0; // Clear extended key code + + if (breakbit) { + // Key going up + keyd_last_released = scancode; + keyd_pressed[scancode] = 0; + key_data.NumUps[scancode]++; + temp = 0; + temp |= keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT]; + temp |= keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT]; + temp |= keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL]; +#ifndef NDEBUG + temp |= keyd_pressed[KEY_DELETE]; + if ( !(keyd_editor_mode && temp) ) +#endif // NOTICE LINK TO ABOVE IF!!!! + key_data.TimeKeyHeldDown[scancode] += timer_get_fixed_secondsX() - key_data.TimeKeyWentDown[scancode]; + } else { + // Key going down + keyd_last_pressed = scancode; + keyd_time_when_last_pressed = timer_get_fixed_secondsX(); + if (!keyd_pressed[scancode]) { + // First time down + key_data.TimeKeyWentDown[scancode] = timer_get_fixed_secondsX(); + keyd_pressed[scancode] = 1; + key_data.NumDowns[scancode]++; +#ifndef NDEBUG + if ( (keyd_pressed[KEY_LSHIFT]) && (scancode == KEY_BACKSP) ) { + keyd_pressed[KEY_LSHIFT] = 0; + Int5(); + } +#endif + } else if (!keyd_repeat) { + // Don't buffer repeating key if repeat mode is off + scancode = 0xAA; + } + + if ( scancode!=0xAA ) { + keycode = scancode; + + if ( keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT] ) + keycode |= KEY_SHIFTED; + + if ( keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT] ) + keycode |= KEY_ALTED; + + if ( keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL] ) + keycode |= KEY_CTRLED; + +#ifndef NDEBUG + if ( keyd_pressed[KEY_DELETE] ) + keycode |= KEY_DEBUGGED; +#endif + + temp = key_data.keytail+1; + if ( temp >= KEY_BUFFER_SIZE ) temp=0; + + if (temp!=key_data.keyhead) { + key_data.keybuffer[key_data.keytail] = keycode; + key_data.time_pressed[key_data.keytail] = keyd_time_when_last_pressed; + key_data.keytail = temp; + } + } + } + } + +#ifndef NDEBUG +#ifdef PASS_KEYS_TO_BIOS + _chain_intr( key_data.prev_int_9 ); +#endif +#endif + + temp = inp(0x61); // Get current port 61h state + temp |= 0x80; // Turn on bit 7 to signal clear keybrd + outp( 0x61, temp ); // Send to port + temp &= 0x7f; // Turn off bit 7 to signal break + outp( 0x61, temp ); // Send to port + outp( 0x20, 0x20 ); // Reset interrupt controller +} + + +void key_handler_end() { // Dummy function to help calculate size of keyboard handler function +} + +void key_init() +{ + // Initialize queue + + keyd_time_when_last_pressed = timer_get_fixed_seconds(); + keyd_buffer_type = 1; + keyd_repeat = 1; + key_data.in_key_handler = 0; + key_data.E0Flag = 0; + key_data.E1Flag = 0; + + // Clear the keyboard array + key_flush(); + + if (Installed) return; + Installed = 1; + + //--------------- lock everything for the virtal memory ---------------------------------- + if (!dpmi_lock_region ((void near *)key_handler, (char *)key_handler_end - (char near *)key_handler)) { + printf( "Error locking keyboard handler!\n" ); + exit(1); + } + if (!dpmi_lock_region ((void *)&key_data, sizeof(keyboard))) { + printf( "Error locking keyboard handler's data1!\n" ); + exit(1); + } + if (!dpmi_lock_region (&keyd_buffer_type, sizeof(char))) { + printf( "Error locking keyboard handler's data2!\n" ); + exit(1); + } + if (!dpmi_lock_region (&keyd_repeat, sizeof(char))) { + printf( "Error locking keyboard handler's data3!\n" ); + exit(1); + } + if (!dpmi_lock_region (&keyd_editor_mode, sizeof(char))) { + printf( "Error locking keyboard handler's data4!\n" ); + exit(1); + } + if (!dpmi_lock_region ((void *)&keyd_last_pressed, sizeof(char))) { + printf( "Error locking keyboard handler's data5!\n" ); + exit(1); + } + if (!dpmi_lock_region ((void *)&keyd_last_released, sizeof(char))) { + printf( "Error locking keyboard handler's data6!\n" ); + exit(1); + } + if (!dpmi_lock_region ((void *)&keyd_pressed, sizeof(char)*256)) { + printf( "Error locking keyboard handler's data7!\n" ); + exit(1); + } + if (!dpmi_lock_region ((void *)&keyd_time_when_last_pressed, sizeof(int))) { + printf( "Error locking keyboard handler's data8!\n" ); + exit(1); + } + +#ifndef __DJGPP__ + key_data.prev_int_9 = (void *)_dos_getvect( 9 ); + _dos_setvect( 9, key_handler ); +#else + _go32_dpmi_get_protected_mode_interrupt_vector(9, + (_go32_dpmi_seginfo *)&key_data.prev_int_9); + kbd_hand_info.pm_offset = (int)key_handler; + kbd_hand_info.pm_selector = _my_cs(); + _go32_dpmi_allocate_iret_wrapper(&kbd_hand_info); + _go32_dpmi_set_protected_mode_interrupt_vector(9, &kbd_hand_info); +#endif + + atexit( key_close ); +} + +void key_close() +{ + if (!Installed) return; + Installed = 0; + +#ifndef __DJGPP__ + _dos_setvect( 9, key_data.prev_int_9 ); +#else + _go32_dpmi_set_protected_mode_interrupt_vector(9, + (_go32_dpmi_seginfo *)&key_data.prev_int_9); +#endif + + _disable(); + key_clear_bios_buffer_all(); + _enable(); + +} + +#endif // __ENV_DJGPP__ diff --git a/input/dos_mouse.c b/input/dos_mouse.c new file mode 100644 index 00000000..a4f3395f --- /dev/null +++ b/input/dos_mouse.c @@ -0,0 +1,604 @@ +/* +THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. +*/ + +#include + +#ifdef __ENV_DJGPP__ + +#ifdef __DJGPP__ +#include +#define _BORLAND_DOS_REGS 1 +#define near +_go32_dpmi_registers handler_regs; +#endif + +#include + +#include +#include +//#include +#include +//#include +#include + +#include "error.h" +#include "fix.h" +#include "u_dpmi.h" +#include "mouse.h" +#include "timer.h" + +#define ME_CURSOR_MOVED (1<<0) +#define ME_LB_P (1<<1) +#define ME_LB_R (1<<2) +#define ME_RB_P (1<<3) +#define ME_RB_R (1<<4) +#define ME_MB_P (1<<5) +#define ME_MB_R (1<<6) +#define ME_OB_P (1<<7) +#define ME_OB_R (1<<8) +#define ME_X_C (1<<9) +#define ME_Y_C (1<<10) +#define ME_Z_C (1<<11) +#define ME_P_C (1<<12) +#define ME_B_C (1<<13) +#define ME_H_C (1<<14) +#define ME_O_C (1<<15) + +#define MOUSE_MAX_BUTTONS 11 + +typedef struct event_info { + short x; + short y; + short z; + short pitch; + short bank; + short heading; + ushort button_status; + ushort device_dependant; +} event_info; + +typedef struct mouse_info { + fix ctime; + ubyte cyberman; + int num_buttons; + ubyte pressed[MOUSE_MAX_BUTTONS]; + fix time_went_down[MOUSE_MAX_BUTTONS]; + fix time_held_down[MOUSE_MAX_BUTTONS]; + uint num_downs[MOUSE_MAX_BUTTONS]; + uint num_ups[MOUSE_MAX_BUTTONS]; + event_info *x_info; + ushort button_status; +} mouse_info; + +typedef struct cyberman_info { + ubyte device_type; + ubyte major_version; + ubyte minor_version; + ubyte x_descriptor; + ubyte y_descriptor; + ubyte z_descriptor; + ubyte pitch_descriptor; + ubyte roll_descriptor; + ubyte yaw_descriptor; + ubyte reserved; +} cyberman_info; + +static mouse_info Mouse; + +static int Mouse_installed = 0; + +#ifdef __DJGPP__ +#define m_ax r->d.eax +#define mbx r->d.ebx +#define mcx r->d.ecx +#define mdx r->d.edx +#define msi r->d.esi +#define mdi r->d.edi +void mouse_handler (_go32_dpmi_registers *r) +{ +#else +#pragma off (check_stack) +void _loadds far mouse_handler (int m_ax, int mbx, int mcx, int mdx, int msi, int mdi) +{ +#pragma aux mouse_handler parm [EAX] [EBX] [ECX] [EDX] [ESI] [EDI] +#endif + Mouse.ctime = timer_get_fixed_secondsX(); + + if (m_ax & ME_LB_P) { // left button pressed + if (!Mouse.pressed[MB_LEFT]) { + Mouse.pressed[MB_LEFT] = 1; + Mouse.time_went_down[MB_LEFT] = Mouse.ctime; + } + Mouse.num_downs[MB_LEFT]++; + } else if (m_ax & ME_LB_R ) { // left button released + if (Mouse.pressed[MB_LEFT]) { + Mouse.pressed[MB_LEFT] = 0; + Mouse.time_held_down[MB_LEFT] += Mouse.ctime-Mouse.time_went_down[MB_LEFT]; + } + Mouse.num_ups[MB_LEFT]++; + } + + if (m_ax & ME_RB_P ) { // right button pressed + if (!Mouse.pressed[MB_RIGHT]) { + Mouse.pressed[MB_RIGHT] = 1; + Mouse.time_went_down[MB_RIGHT] = Mouse.ctime; + } + Mouse.num_downs[MB_RIGHT]++; + } else if (m_ax & ME_RB_R ) {// right button released + if (Mouse.pressed[MB_RIGHT]) { + Mouse.pressed[MB_RIGHT] = 0; + Mouse.time_held_down[MB_RIGHT] += Mouse.ctime-Mouse.time_went_down[MB_RIGHT]; + } + Mouse.num_ups[MB_RIGHT]++; + } + + if (m_ax & ME_MB_P ) { // middle button pressed + if (!Mouse.pressed[MB_MIDDLE]) { + Mouse.pressed[MB_MIDDLE] = 1; + Mouse.time_went_down[MB_MIDDLE] = Mouse.ctime; + } + Mouse.num_downs[MB_MIDDLE]++; + } else if (m_ax & ME_MB_R ) { // middle button released + if (Mouse.pressed[MB_MIDDLE]) { + Mouse.pressed[MB_MIDDLE] = 0; + Mouse.time_held_down[MB_MIDDLE] += Mouse.ctime-Mouse.time_went_down[MB_MIDDLE]; + } + Mouse.num_ups[MB_MIDDLE]++; + } + + if (Mouse.cyberman && (m_ax & (ME_Z_C|ME_P_C|ME_B_C|ME_H_C))) { + Mouse.x_info = (event_info *)((msi & 0xFFFF) << 4); + + if (m_ax & ME_Z_C ) { // z axis changed + if (Mouse.pressed[MB_Z_UP]) { + // z up released + Mouse.pressed[MB_Z_UP] = 0; + Mouse.time_held_down[MB_Z_UP] += Mouse.ctime-Mouse.time_went_down[MB_Z_UP]; + Mouse.num_ups[MB_Z_UP]++; + } else if ( Mouse.x_info->z>0 ) { + // z up pressed + Mouse.pressed[MB_Z_UP] = 1; + Mouse.time_went_down[MB_Z_UP]=Mouse.ctime; + Mouse.num_downs[MB_Z_UP]++; + } + if (Mouse.pressed[MB_Z_DOWN]) { + // z down released + Mouse.pressed[MB_Z_DOWN] = 0; + Mouse.time_held_down[MB_Z_DOWN] += Mouse.ctime-Mouse.time_went_down[MB_Z_DOWN]; + Mouse.num_ups[MB_Z_DOWN]++; + } else if ( Mouse.x_info->z<0 ) { + // z down pressed + Mouse.pressed[MB_Z_DOWN] = 1; + Mouse.time_went_down[MB_Z_DOWN]=Mouse.ctime; + Mouse.num_downs[MB_Z_DOWN]++; + } + } + if (m_ax & ME_P_C ) { // pitch changed + if (Mouse.pressed[MB_PITCH_BACKWARD]) { + // pitch backward released + Mouse.pressed[MB_PITCH_BACKWARD] = 0; + Mouse.time_held_down[MB_PITCH_BACKWARD] += Mouse.ctime-Mouse.time_went_down[MB_PITCH_BACKWARD]; + Mouse.num_ups[MB_PITCH_BACKWARD]++; + } else if ( Mouse.x_info->pitch>0 ) { + // pitch backward pressed + Mouse.pressed[MB_PITCH_BACKWARD] = 1; + Mouse.time_went_down[MB_PITCH_BACKWARD]=Mouse.ctime; + Mouse.num_downs[MB_PITCH_BACKWARD]++; + } + if (Mouse.pressed[MB_PITCH_FORWARD]) { + // pitch forward released + Mouse.pressed[MB_PITCH_FORWARD] = 0; + Mouse.time_held_down[MB_PITCH_FORWARD] += Mouse.ctime-Mouse.time_went_down[MB_PITCH_FORWARD]; + Mouse.num_ups[MB_PITCH_FORWARD]++; + } else if ( Mouse.x_info->pitch<0 ) { + // pitch forward pressed + Mouse.pressed[MB_PITCH_FORWARD] = 1; + Mouse.time_went_down[MB_PITCH_FORWARD]=Mouse.ctime; + Mouse.num_downs[MB_PITCH_FORWARD]++; + } + } + + if (m_ax & ME_B_C ) { // bank changed + if (Mouse.pressed[MB_BANK_LEFT]) { + // bank left released + Mouse.pressed[MB_BANK_LEFT] = 0; + Mouse.time_held_down[MB_BANK_LEFT] += Mouse.ctime-Mouse.time_went_down[MB_BANK_LEFT]; + Mouse.num_ups[MB_BANK_LEFT]++; + } else if ( Mouse.x_info->bank>0 ) { + // bank left pressed + Mouse.pressed[MB_BANK_LEFT] = 1; + Mouse.time_went_down[MB_BANK_LEFT]=Mouse.ctime; + Mouse.num_downs[MB_BANK_LEFT]++; + } + if (Mouse.pressed[MB_BANK_RIGHT]) { + // bank right released + Mouse.pressed[MB_BANK_RIGHT] = 0; + Mouse.time_held_down[MB_BANK_RIGHT] += Mouse.ctime-Mouse.time_went_down[MB_BANK_RIGHT]; + Mouse.num_ups[MB_BANK_RIGHT]++; + } else if ( Mouse.x_info->bank<0 ) { + // bank right pressed + Mouse.pressed[MB_BANK_RIGHT] = 1; + Mouse.time_went_down[MB_BANK_RIGHT]=Mouse.ctime; + Mouse.num_downs[MB_BANK_RIGHT]++; + } + } + + if (m_ax & ME_H_C ) { // heading changed + if (Mouse.pressed[MB_HEAD_LEFT]) { + // head left released + Mouse.pressed[MB_HEAD_LEFT] = 0; + Mouse.time_held_down[MB_HEAD_LEFT] += Mouse.ctime-Mouse.time_went_down[MB_HEAD_LEFT]; + Mouse.num_ups[MB_HEAD_LEFT]++; + } else if ( Mouse.x_info->heading>0 ) { + // head left pressed + Mouse.pressed[MB_HEAD_LEFT] = 1; + Mouse.time_went_down[MB_HEAD_LEFT]=Mouse.ctime; + Mouse.num_downs[MB_HEAD_LEFT]++; + } + if (Mouse.pressed[MB_HEAD_RIGHT]) { + // head right released + Mouse.pressed[MB_HEAD_RIGHT] = 0; + Mouse.time_held_down[MB_HEAD_RIGHT] += Mouse.ctime-Mouse.time_went_down[MB_HEAD_RIGHT]; + Mouse.num_ups[MB_HEAD_RIGHT]++; + } else if ( Mouse.x_info->heading<0 ) { + // head right pressed + Mouse.pressed[MB_HEAD_RIGHT] = 1; + Mouse.time_went_down[MB_HEAD_RIGHT]=Mouse.ctime; + Mouse.num_downs[MB_HEAD_RIGHT]++; + } + } + } + +} + + + + +void mouse_handler_end (void) // dummy functions +{ +} +#pragma on (check_stack) + +//-------------------------------------------------------- +// returns 0 if no mouse +// else number of buttons +int mouse_init(int enable_cyberman) +{ + dpmi_real_regs rr; + cyberman_info *ci; +#ifndef __DJGPP__ + struct SREGS sregs; +#endif + union REGS inregs, outregs; + ubyte *Mouse_dos_mem; + + if (Mouse_installed) + return Mouse.num_buttons; + +#ifdef __DJGPP__ + if (_farpeekl(_dos_ds, 0x33 * 4) == 0) { +#else + if (_dos_getvect(0x33) == NULL) { +#endif + // No mouse driver loaded + return 0; + } + + // Reset the mouse driver + memset( &inregs, 0, sizeof(inregs) ); + inregs.w.ax = 0; + int386(0x33, &inregs, &outregs); + if (outregs.w.ax != 0xffff) + return 0; + + Mouse.num_buttons = outregs.w.bx; + Mouse.cyberman = 0; + + // Enable mouse driver + memset( &inregs, 0, sizeof(inregs) ); + inregs.w.ax = 0x0020; + int386(0x33, &inregs, &outregs); + if (outregs.w.ax != 0xffff ) + return 0; + + if ( enable_cyberman ) { + Mouse_dos_mem = dpmi_get_temp_low_buffer( 64 ); + if (Mouse_dos_mem==NULL) { + printf( "Unable to allocate DOS buffer in mouse.c\n" ); + } else { + // Check for Cyberman... + memset( &rr, 0, sizeof(dpmi_real_regs) ); + rr.es = DPMI_real_segment(Mouse_dos_mem); + rr.edx = DPMI_real_offset(Mouse_dos_mem); + rr.eax = 0x53c1; + dpmi_real_int386x( 0x33, &rr ); + if (rr.eax==1) { + // SWIFT functions supported + ci = (cyberman_info *)Mouse_dos_mem; + if (ci->device_type==1) { // Cyberman + Mouse.cyberman = 1; + //printf( "Cyberman mouse detected\n" ); + Mouse.num_buttons = 11; + } + } + } + } + + if (!dpmi_lock_region(&Mouse,sizeof(mouse_info))) { + printf( "Unable to lock mouse data region" ); + exit(1); + } + if (!dpmi_lock_region((void near *)mouse_handler,(char *)mouse_handler_end - (char near *)mouse_handler)) { + printf( "Unable to lock mouse handler" ); + exit(1); + } + + // Install mouse handler +#ifdef __DJGPP__ + { + dpmi_real_regs rregs; + _go32_dpmi_seginfo info; + memset(&rregs, 0, sizeof(rregs)); + info.pm_offset = (unsigned int)&mouse_handler; + if (_go32_dpmi_allocate_real_mode_callback_retf(&info, &handler_regs)) { + printf( "Unable allocate mouse handler callback" ); + exit(1); + } + rregs.eax = 0xC; + rregs.ecx = ME_LB_P|ME_LB_R|ME_RB_P|ME_RB_R|ME_MB_P|ME_MB_R; // watch all 3 button ups/downs + if (Mouse.cyberman) + rregs.ecx |= ME_Z_C| ME_P_C| ME_B_C| ME_H_C; // if using a cyberman, also watch z, pitch, bank, heading. + rregs.edx = info.rm_offset; + rregs.es = info.rm_segment; + dpmi_real_int386x( 0x33, &rregs ); + } +#else + memset( &inregs, 0, sizeof(inregs)); + memset( &sregs, 0, sizeof(sregs)); + inregs.w.ax = 0xC; + inregs.w.cx = ME_LB_P|ME_LB_R|ME_RB_P|ME_RB_R|ME_MB_P|ME_MB_R; // watch all 3 button ups/downs + if (Mouse.cyberman) + inregs.w.cx |= ME_Z_C| ME_P_C| ME_B_C| ME_H_C; // if using a cyberman, also watch z, pitch, bank, heading. + inregs.x.edx = FP_OFF(mouse_handler); + sregs.es = FP_SEG(mouse_handler); + int386x(0x33, &inregs, &outregs, &sregs); +#endif + + Mouse_installed = 1; + + atexit( mouse_close ); + + mouse_flush(); + + return Mouse.num_buttons; +} + + + +void mouse_close() +{ + struct SREGS sregs; + union REGS inregs, outregs; + + if (Mouse_installed) { + Mouse_installed = 0; + // clear mouse handler by setting flags to 0. + memset( &inregs, 0, sizeof(inregs)); + memset( &sregs, 0, sizeof(sregs)); + inregs.w.ax = 0xC; + inregs.w.cx = 0; // disable event handler by setting to zero. + inregs.x.edx = 0; + sregs.es = 0; + int386x(0x33, &inregs, &outregs, &sregs); + } +} + + +void mouse_set_limits( int x1, int y1, int x2, int y2 ) +{ + union REGS inregs, outregs; + + if (!Mouse_installed) return; + + memset( &inregs, 0, sizeof(inregs)); + inregs.w.ax = 0x7; // Set Horizontal Limits for Pointer + inregs.w.cx = x1; + inregs.w.dx = x2; + int386(0x33, &inregs, &outregs); + + memset( &inregs, 0, sizeof(inregs)); + inregs.w.ax = 0x8; // Set Vertical Limits for Pointer + inregs.w.cx = y1; + inregs.w.dx = y2; + int386(0x33, &inregs, &outregs); +} + +void mouse_get_pos( int *x, int *y) +{ + union REGS inregs, outregs; + + if (!Mouse_installed) { + *x = *y = 0; + return; + } + memset( &inregs, 0, sizeof(inregs)); + inregs.w.ax = 0x3; // Get Mouse Position and Button Status + int386(0x33, &inregs, &outregs); + *x = (short)outregs.w.cx; + *y = (short)outregs.w.dx; +} + +void mouse_get_delta( int *dx, int *dy ) +{ + union REGS inregs, outregs; + + if (!Mouse_installed) { + *dx = *dy = 0; + return; + } + + memset( &inregs, 0, sizeof(inregs)); + inregs.w.ax = 0xb; // Read Mouse motion counters + int386(0x33, &inregs, &outregs); + *dx = (short)outregs.w.cx; + *dy = (short)outregs.w.dx; +} + +int mouse_get_btns() +{ + int i; + uint flag=1; + int status = 0; + + if (!Mouse_installed) + return 0; + + for (i=0; ix+8128)*256)/(8064+8128+1)) - 127; + *y = (((ei->y+8128)*256)/(8064+8128+1)) - 127; +} + +#endif // __ENV_DJGPP__ diff --git a/input/ggi/Makefile.in b/input/ggi/Makefile.in index 6af61789..fe54753c 100644 --- a/input/ggi/Makefile.in +++ b/input/ggi/Makefile.in @@ -183,7 +183,7 @@ distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ if test -d $$d/$$file; then \ - cp -pr $$d/$$file $(distdir)/$$file; \ + cp -pr $$/$$file $(distdir)/$$file; \ else \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ diff --git a/input/ggi_event.c b/input/ggi_event.c new file mode 100644 index 00000000..c4d120b3 --- /dev/null +++ b/input/ggi_event.c @@ -0,0 +1,131 @@ +#include + +#ifdef GGI_INPUT +#include +#include +#include +#include +#include "event.h" +#include "error.h" +#include "fix.h" + +static int initialised=0; + +#ifdef GGI_VIDEO +#include +extern ggi_visual_t *screenvis; +#endif +gii_input_t inputs; + +extern void keyboard_handler(int key, ubyte state); +extern void mouse_handler_button(int button, ubyte state); +extern void mouse_handler_relative(int x, int y); +extern void mouse_handler_absolute(int x, int y); + +void event_poll() +{ + int n; + struct timeval tv; + gii_event event; + + if (!initialised) + event_init(); + if (inputs==NULL) + return; +// Error("GII error: no inputs (perhaps you need to set GII_INPUT env var)\n"); + + tv.tv_sec = 0; + tv.tv_usec = 0; + + giiEventPoll(inputs, emAll, &tv); + + n = giiEventsQueued(inputs, emAll); + + while (n-- > 0) + { + giiEventRead(inputs, &event, emAll); + switch (event.any.type) + { + case evKeyPress: + keyboard_handler(event.key.label, 1); + break; + case evKeyRelease: + keyboard_handler(event.key.label, 0); + break; + case evPtrAbsolute: + mouse_handler_absolute(event.pmove.x, event.pmove.y); + break; + case evPtrRelative: + mouse_handler_relative(event.pmove.x, event.pmove.y); + break; + case evPtrButtonPress: + mouse_handler_button(event.pbutton.button, 1); + break; + case evPtrButtonRelease: + mouse_handler_button(event.pbutton.button, 0); + break; + } + } +} + +void event_close() +{ + if (inputs) + giiClose(inputs); + giiExit(); +} + +#ifdef GII_XWIN +int gii_xwin_initialized=0; +#include +//void lock_nothing(void){return;} +void init_gii_xwin(Display *disp,Window win){ + printf("gii xwin %i %i\n",initialised,gii_xwin_initialized); + if (!initialised) + event_init(); + if (gii_xwin_initialized){ + gii_event ev; + gii_xwin_cmddata_setparam *giiargs=(gii_xwin_cmddata_setparam *) &ev.cmd.data; + memset(&ev,0,sizeof(gii_cmd_nodata_event)+sizeof(gii_xwin_cmddata_setparam)); + ev.cmd.code=GII_CMDCODE_XWINSETPARAM; + ev.any.type = evCommand; + ev.any.size=sizeof(gii_cmd_nodata_event)+sizeof(gii_xwin_cmddata_setparam); + giiargs->win=win; + giiargs->ptralwaysrel=1; + giiEventSend(inputs,&ev); + }else{ + gii_input_t inputs2; + gii_inputxwin_arg giiargs; + memset(&giiargs,0,sizeof(giiargs)); + giiargs.disp=disp; + giiargs.win=win; + giiargs.ptralwaysrel=1; + //giiargs.gglock=lock_nothing; + inputs2=giiOpen("xwin",&giiargs,NULL); + if (inputs2){ + gii_xwin_initialized=1; + if (inputs) + inputs=giiJoinInputs(inputs,inputs2); + else + inputs=inputs2; + } + } +} +#endif + +int event_init() +{ + if (!initialised){ + giiInit(); +#ifdef GGI_VIDEO + inputs = ggiJoinInputs(screenvis, NULL); +#else + inputs=giiOpen(NULL); +#endif + initialised = 1; + atexit(event_close); + } + return 0; +} + +#endif //GGI_INPUT diff --git a/input/ggi_init.c b/input/ggi_init.c new file mode 100644 index 00000000..80ccebc5 --- /dev/null +++ b/input/ggi_init.c @@ -0,0 +1,11 @@ +#include +#include +#include +#include "text.h" +#include "event.h" +#include "error.h" +#include "args.h" + +void arch_ggi_init() +{ +} diff --git a/input/ggi_key.c b/input/ggi_key.c new file mode 100644 index 00000000..7be12fcb --- /dev/null +++ b/input/ggi_key.c @@ -0,0 +1,498 @@ +#include +#ifdef GGI_INPUT +#include +#include + +#include + +#include "event.h" +#include "error.h" +#include "key.h" +#include "timer.h" +#include "mono.h" + +//added on 9/3/98 by Matt Mueller to free some cpu instead of hogging during menus and such +#include "d_delay.h" +//end this section addition - Matt Mueller + +#define KEY_BUFFER_SIZE 16 + +static unsigned char Installed = 0; + +//-------- Variable accessed by outside functions --------- +unsigned char keyd_buffer_type; // 0=No buffer, 1=buffer ASCII, 2=buffer scans +unsigned char keyd_repeat; +unsigned char keyd_editor_mode; +volatile unsigned char keyd_last_pressed; +volatile unsigned char keyd_last_released; +volatile unsigned char keyd_pressed[256]; +volatile int keyd_time_when_last_pressed; + +typedef struct Key_info { + ubyte state; // state of key 1 == down, 0 == up + ubyte last_state; // previous state of key + int counter; // incremented each time key is down in handler + fix timewentdown; // simple counter incremented each time in interrupt and key is down + fix timehelddown; // counter to tell how long key is down -- gets reset to 0 by key routines + ubyte downcount; // number of key counts key was down + ubyte upcount; // number of times key was released +} Key_info; + +typedef struct keyboard { + unsigned short keybuffer[KEY_BUFFER_SIZE]; + Key_info keys[256]; + fix time_pressed[KEY_BUFFER_SIZE]; + unsigned int keyhead, keytail; +} keyboard; + +static /*volatile*/ keyboard key_data; + +char * key_text[256] = { +"","ESC","1","2","3","4","5","6","7","8","9","0","-", +"=","BSPC","TAB","Q","W","E","R","T","Y","U","I","O", +"P","[","]","ƒ","LCTRL","A","S","D","F", +"G","H","J","K","L",";","'","`", +"LSHFT","\\","Z","X","C","V","B","N","M",",", +".","/","RSHFT","PAD*","LALT","SPC", +"CPSLK","F1","F2","F3","F4","F5","F6","F7","F8","F9", +"F10","NMLCK","SCLK","PAD7","PAD8","PAD9","PAD-", +"PAD4","PAD5","PAD6","PAD+","PAD1","PAD2","PAD3","PAD0", +"PAD.","","","","F11","F12","","","","","","","","","", +"","","","","","","","","","","","","","","","","","","","", +"","","","","","","","","","","","","","","","","","","","", +"","","","","","","","","","","","","","","","","","", +"PADƒ","RCTRL","","","","","","","","","","","","","", +"","","","","","","","","","","PAD/","","","RALT","", +"","","","","","","","","","","","","","HOME","‚","PGUP", +"","","","","","END","€","PGDN","INS", +"DEL","","","","","","","","","","","","","","","","","", +"","","","","","","","","","","","","","","","","","","","", +"","","","","","","" }; + +unsigned char ascii_table[128] = +{ 255, 255, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=',255,255, + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 255, 255, + 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', 39, '`', + 255, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 255,'*', + 255, ' ', 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255,255, + 255, 255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255 }; + +unsigned char shifted_ascii_table[128] = +{ 255, 255, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+',255,255, + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 255, 255, + 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', + 255, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 255,255, + 255, ' ', 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255,255, + 255, 255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255 }; + +int giiKeyTranslate (int keylabel) { + switch (keylabel) + { + case GIIUC_0: return KEY_0; + case GIIUC_1: return KEY_1; + case GIIUC_2: return KEY_2; + case GIIUC_3: return KEY_3; + case GIIUC_4: return KEY_4; + case GIIUC_5: return KEY_5; + case GIIUC_6: return KEY_6; + case GIIUC_7: return KEY_7; + case GIIUC_8: return KEY_8; + case GIIUC_9: return KEY_9; + + case GIIUC_A: return KEY_A; + case GIIUC_B: return KEY_B; + case GIIUC_C: return KEY_C; + case GIIUC_D: return KEY_D; + case GIIUC_E: return KEY_E; + case GIIUC_F: return KEY_F; + case GIIUC_G: return KEY_G; + case GIIUC_H: return KEY_H; + case GIIUC_I: return KEY_I; + case GIIUC_J: return KEY_J; + case GIIUC_K: return KEY_K; + case GIIUC_L: return KEY_L; + case GIIUC_M: return KEY_M; + case GIIUC_N: return KEY_N; + case GIIUC_O: return KEY_O; + case GIIUC_P: return KEY_P; + case GIIUC_Q: return KEY_Q; + case GIIUC_R: return KEY_R; + case GIIUC_S: return KEY_S; + case GIIUC_T: return KEY_T; + case GIIUC_U: return KEY_U; + case GIIUC_V: return KEY_V; + case GIIUC_W: return KEY_W; + case GIIUC_X: return KEY_X; + case GIIUC_Y: return KEY_Y; + case GIIUC_Z: return KEY_Z; + + case GIIUC_Minus: return KEY_MINUS; + case GIIUC_Equal: return KEY_EQUAL; + case GIIUC_Slash: return KEY_DIVIDE; + case GIIUC_BackSlash: return KEY_SLASH; + case GIIUC_Comma: return KEY_COMMA; + case GIIUC_Period: return KEY_PERIOD; + case GIIUC_Semicolon: return KEY_SEMICOL; + + case GIIUC_BracketLeft: return KEY_LBRACKET; + case GIIUC_BracketRight: return KEY_RBRACKET; + + case GIIUC_Apostrophe: return KEY_RAPOSTRO; + case GIIUC_Grave: return KEY_LAPOSTRO; + + case GIIUC_Escape: return KEY_ESC; + case GIIK_Enter: return KEY_ENTER; + case GIIUC_BackSpace: return KEY_BACKSP; + case GIIUC_Tab: return KEY_TAB; + case GIIUC_Space: return KEY_SPACEBAR; + + case GIIK_NumLock: return KEY_NUMLOCK; + case GIIK_ScrollLock: return KEY_SCROLLOCK; + case GIIK_CapsLock: return KEY_CAPSLOCK; + + case GIIK_ShiftL: return KEY_LSHIFT; + case GIIK_ShiftR: return KEY_RSHIFT; + + case GIIK_AltL: return KEY_LALT; + case GIIK_AltR: return KEY_RALT; + + case GIIK_CtrlL: return KEY_LCTRL; + case GIIK_CtrlR: return KEY_RCTRL; + + case GIIK_F1: return KEY_F1; + case GIIK_F2: return KEY_F2; + case GIIK_F3: return KEY_F3; + case GIIK_F4: return KEY_F4; + case GIIK_F5: return KEY_F5; + case GIIK_F6: return KEY_F6; + case GIIK_F7: return KEY_F7; + case GIIK_F8: return KEY_F8; + case GIIK_F9: return KEY_F9; + case GIIK_F10: return KEY_F10; + case GIIK_F11: return KEY_F11; + case GIIK_F12: return KEY_F12; + + case GIIK_P0: return KEY_PAD0; + case GIIK_P1: return KEY_PAD1; + case GIIK_P2: return KEY_PAD2; + case GIIK_P3: return KEY_PAD3; + case GIIK_P4: return KEY_PAD4; + case GIIK_P5: return KEY_PAD5; + case GIIK_P6: return KEY_PAD6; + case GIIK_P7: return KEY_PAD7; + case GIIK_P8: return KEY_PAD8; + case GIIK_P9: return KEY_PAD9; + case GIIK_PMinus: return KEY_PADMINUS; + case GIIK_PPlus: return KEY_PADPLUS; + case GIIK_PDecimal: return KEY_PADPERIOD; + case GIIK_PSlash: return KEY_PADDIVIDE; + case GIIK_PAsterisk: return KEY_PADMULTIPLY; + case GIIK_PEnter: return KEY_PADENTER; + + case GIIK_Insert: return KEY_INSERT; + case GIIK_Home: return KEY_HOME; + case GIIK_PageUp: return KEY_PAGEUP; + case GIIK_Delete: return KEY_DELETE; + case GIIK_End: return KEY_END; + case GIIK_PageDown: return KEY_PAGEDOWN; + case GIIK_Up: return KEY_UP; + case GIIK_Down: return KEY_DOWN; + case GIIK_Left: return KEY_LEFT; + case GIIK_Right: return KEY_RIGHT; + + case GIIK_PrintScreen: return KEY_PRINT_SCREEN; + case GIIK_Pause: return KEY_PAUSE; + } + return 0; +} + +//killed on 10/03/98 by Matt Mueller +//unsigned char key_to_ascii(int a) +//{ +// if (!isprint(a)) return 255; +// if (a & KEY_SHIFTED) { +// return (toupper((unsigned char) a)); +// } else { +// return ((unsigned char) a); +// } +//} +//end kill -MM + +//added on 10/03/98 by Matt Mueller to fix shifted keys (copied from dos/key.c) +unsigned char key_to_ascii(int keycode) +{ + int shifted; + + shifted = keycode & KEY_SHIFTED; + keycode &= 0xFF; + + if ( keycode>=127 ) + return 255; + + if (shifted) + return shifted_ascii_table[keycode]; + else + return ascii_table[keycode]; +} +//end addition -MM + +void keyboard_handler(int button, ubyte state) +{ + ubyte key_state; + int i, keycode; + unsigned short event_key; + Key_info *key; + unsigned char temp; + + key_state = state; + event_key = giiKeyTranslate(button); + //mprintf((0,"keyboard_handler(%i,%i):%i\n",button,state,event_key)); + + //===================================================== + //Here a translation from win keycodes to mac keycodes! + //===================================================== + + for (i = 255; i >= 0; i--) { + + keycode = i; + key = &(key_data.keys[keycode]); + if (i == event_key) + state = key_state; + else + state = key->last_state; + + if ( key->last_state == state ) { + if (state) { + key->counter++; + keyd_last_pressed = keycode; + keyd_time_when_last_pressed = timer_get_fixed_seconds(); + } + } else { + if (state) { + keyd_last_pressed = keycode; + keyd_pressed[keycode] = 1; + key->downcount += state; + key->state = 1; + key->timewentdown = keyd_time_when_last_pressed = timer_get_fixed_seconds(); + key->counter++; + } else { + keyd_pressed[keycode] = 0; + keyd_last_released = keycode; + key->upcount += key->state; + key->state = 0; + key->counter = 0; + key->timehelddown += timer_get_fixed_seconds() - key->timewentdown; + } + } + if ( (state && !key->last_state) || (state && key->last_state && (key->counter > 30) && (key->counter & 0x01)) ) { + if ( keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT]) + keycode |= KEY_SHIFTED; + if ( keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT]) + keycode |= KEY_ALTED; + if ( keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL]) + keycode |= KEY_CTRLED; + if ( keyd_pressed[KEY_DELETE] ) + keycode |= KEY_DEBUGGED; + temp = key_data.keytail+1; + if ( temp >= KEY_BUFFER_SIZE ) temp=0; + if (temp!=key_data.keyhead) { + key_data.keybuffer[key_data.keytail] = keycode; + key_data.time_pressed[key_data.keytail] = keyd_time_when_last_pressed; + key_data.keytail = temp; + } + } + key->last_state = state; + } +} + +void key_close() +{ + Installed = 0; +} + +void key_init() +{ + Installed=1; + + keyd_time_when_last_pressed = timer_get_fixed_seconds(); + keyd_buffer_type = 1; + keyd_repeat = 1; + +// Clear the keyboard array + key_flush(); + atexit(key_close); +} + +void key_flush() +{ + int i; + fix curtime; + + if (!Installed) + key_init(); + + key_data.keyhead = key_data.keytail = 0; + + //Clear the keyboard buffer + for (i=0; i= KEY_BUFFER_SIZE ) n=0; + return n; +} + +int key_checkch() +{ + int is_one_waiting = 0; + event_poll(); + if (key_data.keytail!=key_data.keyhead) + is_one_waiting = 1; + return is_one_waiting; +} + +int key_inkey() +{ + int key = 0; + if (!Installed) + key_init(); + event_poll(); + if (key_data.keytail!=key_data.keyhead) { + key = key_data.keybuffer[key_data.keyhead]; + key_data.keyhead = add_one(key_data.keyhead); + } +//added 9/3/98 by Matt Mueller to free cpu time instead of hogging during menus and such +// else d_delay(1); +//end addition - Matt Mueller + return key; +} + +int key_inkey_time(fix * time) +{ + int key = 0; + + if (!Installed) + key_init(); + event_poll(); + if (key_data.keytail!=key_data.keyhead) { + key = key_data.keybuffer[key_data.keyhead]; + *time = key_data.time_pressed[key_data.keyhead]; + key_data.keyhead = add_one(key_data.keyhead); + } + return key; +} + +int key_peekkey() +{ + int key = 0; + event_poll(); + if (key_data.keytail!=key_data.keyhead) + key = key_data.keybuffer[key_data.keyhead]; + + return key; +} + +int key_getch() +{ + int dummy=0; + + if (!Installed) + return 0; +// return getch(); + + while (!key_checkch()) + dummy++; + return key_inkey(); +} + +unsigned int key_get_shift_status() +{ + unsigned int shift_status = 0; + + if ( keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT] ) + shift_status |= KEY_SHIFTED; + + if ( keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT] ) + shift_status |= KEY_ALTED; + + if ( keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL] ) + shift_status |= KEY_CTRLED; + +#ifndef NDEBUG + if (keyd_pressed[KEY_DELETE]) + shift_status |=KEY_DEBUGGED; +#endif + + return shift_status; +} + +// Returns the number of seconds this key has been down since last call. +fix key_down_time(int scancode) +{ + fix time_down, time; + + event_poll(); + if ((scancode<0)|| (scancode>255)) return 0; + + if (!keyd_pressed[scancode]) { + time_down = key_data.keys[scancode].timehelddown; + key_data.keys[scancode].timehelddown = 0; + } else { + time = timer_get_fixed_seconds(); + time_down = time - key_data.keys[scancode].timewentdown; + key_data.keys[scancode].timewentdown = time; + } + + return time_down; +} + +unsigned int key_down_count(int scancode) +{ + int n; + event_poll(); + if ((scancode<0)|| (scancode>255)) return 0; + + n = key_data.keys[scancode].downcount; + key_data.keys[scancode].downcount = 0; + + return n; +} + +unsigned int key_up_count(int scancode) +{ + int n; + event_poll(); + if ((scancode<0)|| (scancode>255)) return 0; + + n = key_data.keys[scancode].upcount; + key_data.keys[scancode].upcount = 0; + + return n; +} + + +#endif //GGI_INPUT diff --git a/input/ggi_mouse.c b/input/ggi_mouse.c new file mode 100644 index 00000000..f580c49d --- /dev/null +++ b/input/ggi_mouse.c @@ -0,0 +1,161 @@ +#include +#ifdef GGI_INPUT +#include +#include +#include +#include "fix.h" +#include "timer.h" +#include "event.h" +#include "mouse.h" + +struct mousebutton { + ubyte pressed; + fix time_went_down; + fix time_held_down; + uint num_downs; + uint num_ups; +}; + +#define MOUSE_MAX_BUTTONS 3 + +static struct mouseinfo { + struct mousebutton buttons[MOUSE_MAX_BUTTONS]; +//added on 10/17/98 by Hans de Goede for mouse functionality + int min_x, min_y; + int max_x, max_y; + int delta_x, delta_y; + int x,y; +} Mouse; + +void mouse_correct() +{ + if (Mouse.x < Mouse.min_x) + Mouse.x = Mouse.min_x; + else if (Mouse.x > Mouse.max_x) + Mouse.x = Mouse.max_x; + if (Mouse.y < Mouse.min_y) + Mouse.y = Mouse.min_y; + else if (Mouse.y > Mouse.max_y) + Mouse.y = Mouse.max_y; +} + +void mouse_handler_absolute(int x, int y) +{ + Mouse.delta_x += (x - Mouse.x); + Mouse.delta_y += (y - Mouse.y); + Mouse.x = x; + Mouse.y = y; +// mouse_correct(); +} + +void mouse_handler_relative(int x, int y) +{ + Mouse.delta_x += x; + Mouse.delta_y += y; + Mouse.x += x; + Mouse.y += y; +// mouse_correct(); +} + +void mouse_handler_button(int button, ubyte state) +{ + if (!Mouse.buttons[button].pressed && state) + { + Mouse.buttons[button].time_went_down = timer_get_fixed_seconds(); + Mouse.buttons[button].num_downs++; + } + else if (Mouse.buttons[button].pressed && !state) + { + Mouse.buttons[button].num_ups++; + } + + Mouse.buttons[button].pressed = state; +} + +void Mouse_close(void) +{ +} + +void Mouse_init(void) +{ + memset(&Mouse, 0, sizeof(Mouse)); +} + +int mouse_set_limits( int x1, int y1, int x2, int y2 ) +{ + Mouse.min_x = x1; + Mouse.max_x = x2; + Mouse.min_y = y1; + Mouse.max_y = y2; + return MOUSE_MAX_BUTTONS; +} + +void mouse_flush() // clears all mice events... +{ + Mouse.x = 0; + Mouse.y = 0; + Mouse.delta_x = 0; + Mouse.delta_y = 0; +} + +//======================================================================== +void mouse_get_pos( int *x, int *y) +{ + event_poll(); + *x = Mouse.x; + *y = Mouse.y; +} + +void mouse_get_delta( int *dx, int *dy ) +{ + event_poll(); + *dx = Mouse.delta_x; + *dy = Mouse.delta_y; + Mouse.delta_x = 0; + Mouse.delta_y = 0; +} + +int mouse_get_btns() +{ + ubyte buttons = 0; + int i; + event_poll(); + for (i = 0; i < MOUSE_MAX_BUTTONS; i++) + buttons |= (Mouse.buttons[i].pressed << i); + return buttons; +} + +void mouse_set_pos( int x, int y) +{ + Mouse.x = x; + Mouse.y = y; +} + +void mouse_get_cyberman_pos( int *x, int *y ) +{ +} + +// Returns how long this button has been down since last call. +fix mouse_button_down_time(int button) +{ + if (Mouse.buttons[button].pressed) + return (timer_get_fixed_seconds() - Mouse.buttons[button].time_went_down); + else + return 0; +} + +// Returns how many times this button has went down since last call +int mouse_button_down_count(int button) +{ + int count = Mouse.buttons[button].num_downs; + Mouse.buttons[button].num_downs = 0; + return count; +} + +// Returns 1 if this button is currently down +int mouse_button_state(int button) +{ + return Mouse.buttons[button].pressed; +} + +#endif //GGI_INPUT diff --git a/input/linux/Makefile.in b/input/linux/Makefile.in index ba3cea69..450157bb 100644 --- a/input/linux/Makefile.in +++ b/input/linux/Makefile.in @@ -182,7 +182,7 @@ distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ if test -d $$d/$$file; then \ - cp -pr $$d/$$file $(distdir)/$$file; \ + cp -pr $$/$$file $(distdir)/$$file; \ else \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ diff --git a/input/linux_joydefs.c b/input/linux_joydefs.c new file mode 100644 index 00000000..15537358 --- /dev/null +++ b/input/linux_joydefs.c @@ -0,0 +1,240 @@ +/* +THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. +*/ + +#include +#ifdef __ENV_LINUX__ +#include +#include +#include + +#include "pstypes.h" +#include "mono.h" +#include "key.h" +#include "joy.h" +#include "timer.h" +#include "error.h" + +#include "inferno.h" +#include "game.h" +#include "object.h" +#include "player.h" + +#include "controls.h" +#include "joydefs.h" +//#include "victor.h" +#include "render.h" +#include "palette.h" +#include "newmenu.h" +#include "args.h" +#include "text.h" +#include "kconfig.h" +#include "digi.h" +#include "playsave.h" + +int joydefs_calibrate_flag = 0; + +//added 9/6/98 Matt Mueller - not needed at all in linux code but bunches +int Joy_is_Sidewinder=0;// of main/* stuff uses it +//end addition + +void joy_delay() +{ + //int t1 = TICKER + 19/4; // Wait 1/4 second... + //stop_time(); + //while( TICKER < t1 ); + //joy_flush(); + //start_time(); +} + + +int joycal_message( char * title, char * text ) +{ + int i; + newmenu_item m[2]; + m[0].type = NM_TYPE_TEXT; m[0].text = text; + m[1].type = NM_TYPE_MENU; m[1].text = TXT_OK; + i = newmenu_do( title, NULL, 2, m, NULL ); + if ( i < 0 ) + return 1; + return 0; +} + +extern int WriteConfigFile(); + +extern joystick_device j_joystick[4]; +extern joystick_axis j_axis[MAX_AXES]; +extern joystick_button j_button[MAX_BUTTONS]; + +void joydefs_calibrate() +{ + + int i; + int temp_values[MAX_AXES]; + char title[50]; + char text[256]; +//added/killed on 10/17/98 by Hans de Goede for joystick/mouse # fix +//-killed- int nsticks = 0; +//end this section kill - Hans + + joydefs_calibrate_flag = 0; + + if (!joy_present) { + nm_messagebox( NULL, 1, TXT_OK, TXT_NO_JOYSTICK ); + return; + } + + if (j_joystick[0].version) { + joycal_message ("No Calibration", "calibration not required for\njoystick v1.x"); + return; + } + + for (i = 0; i < j_num_axes; i += 2) { + sprintf (title, "js%d Calibration", j_axis[i].joydev); + + sprintf (text, "center joystick %d", j_axis[i].joydev); + joycal_message (title, text); + joystick_read_raw_axis (JOY_ALL_AXIS, temp_values); + j_axis[i].center_val = temp_values[i]; + j_axis[i + 1].center_val = temp_values[i + 1]; + + sprintf (text, "move joystick %d to the upper left", j_axis[i].joydev); + joycal_message (title, text); + joystick_read_raw_axis (JOY_ALL_AXIS, temp_values); + j_axis[i].min_val = temp_values[i]; + j_axis[i + 1].min_val = temp_values[i + 1]; + + sprintf (text, "move joystick %d to the lower right", j_axis[i].joydev); + joycal_message (title, text); + joystick_read_raw_axis (JOY_ALL_AXIS, temp_values); + j_axis[i].max_val = temp_values[i]; + j_axis[i + 1].max_val = temp_values[i + 1]; + + } + + WriteConfigFile (); +} + + +//char *control_text[CONTROL_MAX_TYPES] = { "Keyboard only", "Joystick", "Flightstick Pro", "Thrustmaster FCS", "Gravis Gamepad", "Mouse", "Cyberman" }; + +void joydef_menuset_1(int nitems, newmenu_item * items, int *last_key, int citem ) +{ + int i; + int oc_type = Config_control_type; + + nitems = nitems; + last_key = last_key; + citem = citem; + + for (i=0; i<3; i++ ) + if (items[i].value) Config_control_type = i; + +//added on 10/17/98 by Hans de Goede for joystick/mouse # fix + // remap mouse, since "Flightstick Pro", "Thrustmaster FCS" + // and "Gravis Gamepad" where removed from the options + if (Config_control_type == 2) Config_control_type = CONTROL_MOUSE; +//end this section addition - Hans + + if ( (oc_type != Config_control_type) && (Config_control_type == CONTROL_THRUSTMASTER_FCS ) ) { + nm_messagebox( TXT_IMPORTANT_NOTE, 1, TXT_OK, TXT_FCS ); + } + + if (oc_type != Config_control_type) { + switch (Config_control_type) { + // case CONTROL_NONE: + case CONTROL_JOYSTICK: + case CONTROL_FLIGHTSTICK_PRO: + case CONTROL_THRUSTMASTER_FCS: + case CONTROL_GRAVIS_GAMEPAD: + // case CONTROL_MOUSE: + // case CONTROL_CYBERMAN: + joydefs_calibrate_flag = 1; + } + kc_set_controls(); + } + +} + +extern ubyte kc_use_external_control; +extern ubyte kc_enable_external_control; +extern ubyte *kc_external_name; + +void joydefs_config() +{ +//added/changed/killed on 10/17/98 by Hans de Goede for joystick/mouse # fix +//-killed- char xtext[128]; +//-killed- int i, old_masks, masks; + newmenu_item m[13]; +//-killed- int i1=5; +//-killed- int nitems; +//-killed- +//-killed- do { +//-killed- nitems = 6; + int i, i1=5, j, nitems=7; +//end this section kill/change - Hans + + m[0].type = NM_TYPE_RADIO; m[0].text = "KEYBOARD"; m[0].value = 0; m[0].group = 0; + m[1].type = NM_TYPE_RADIO; m[1].text = "JOYSTICK"; m[1].value = 0; m[1].group = 0; + m[2].type = NM_TYPE_RADIO; m[2].text = "MOUSE"; m[2].value = 0; m[2].group = 0; + m[3].type = NM_TYPE_TEXT; m[3].text=""; + m[4].type = NM_TYPE_MENU; m[4].text="CUSTOMIZE ABOVE"; + m[5].type = NM_TYPE_MENU; m[5].text="CUSTOMIZE KEYBOARD"; +//added on 2/5/99 by Victor Rachels for D1X keys menu + m[6].type = NM_TYPE_MENU; m[6].text="CUSTOMIZE D1X KEYS"; +//end this section addition - VR + +//added/changed/killed on 10/17/98 by Hans de Goede for joystick/mouse # fix +//-killed- m[Config_control_type].value = 1; + + do { + + + i = Config_control_type; + if(i==CONTROL_MOUSE) i = 2; + m[i].value=1; +//end section - OE +//end this section change/addition - Hans + + i1 = newmenu_do1( NULL, TXT_CONTROLS, nitems, m, joydef_menuset_1, i1 ); + +//added 6-15-99 Owen Evans + for (j = 0; j <= 2; j++) + if (m[j].value) + Config_control_type = j; + i = Config_control_type; + if (Config_control_type == 2) + Config_control_type = CONTROL_MOUSE; +//end added - OE + + switch(i1) { + case 4: +//added/changed on 10/17/98 by Hans de Goede for joystick/mouse # fix +//-killed- kconfig(Config_control_type, m[Config_control_type].text); + kconfig (i, m[i].text); +//end this section change - Hans + break; + case 5: + kconfig(0, "KEYBOARD"); + break; +//added on 2/5/99 by Victor Rachels for D1X keys menu + case 6: + kconfig(3, "D1X KEYS"); + break; +//end this section addition - VR + } + + } while(i1>-1); + +} + +#endif //__ENV_LINUX__ diff --git a/input/linux_joystick.c b/input/linux_joystick.c new file mode 100644 index 00000000..c6748ea5 --- /dev/null +++ b/input/linux_joystick.c @@ -0,0 +1,379 @@ +#include + +#ifdef __ENV_LINUX__ +#include +#include +//#include "joystick.h" +#include +#include +#include + +#include "timer.h" +#include "pstypes.h" +#include "mono.h" +#include "joy.h" + +char joy_installed = 0; +char joy_present = 0; + +joystick_device j_joystick[4]; +joystick_axis j_axis[MAX_AXES]; +joystick_button j_button[MAX_BUTTONS]; + +int j_num_axes = 0, j_num_buttons = 0; +int timer_rate; + +int j_axes_in_sticks[4]; /* number of axes in the first [x] sticks */ +int j_buttons_in_sticks[4]; /* number of buttons in the first [x] sticks */ + +int joy_deadzone = 0; + +int j_Get_joydev_axis_number (int all_axis_number) { + int i, joy_axis_number = all_axis_number; + + for (i = 0; i < j_axis[all_axis_number].joydev; i++) { + joy_axis_number -= j_joystick[i].num_axes; + } + + return joy_axis_number; +} + + +int j_Get_joydev_button_number (int all_button_number) { + int i, joy_button_number = all_button_number; + + for (i = 0; i < j_button[all_button_number].joydev; i++) { + joy_button_number -= j_joystick[i].num_buttons; + } + + return joy_button_number; +} + + +int j_Update_state () { +/* int num_processed = 0, i; + struct js_event current_event; + struct JS_DATA_TYPE joy_data; + + for (i = 0; i < j_num_buttons; i++) { + //changed 6/24/1999 to finally squish the timedown bug - Owen Evans + if (j_button[i].state != j_button[i].last_state) { + if (j_button[i].state) { + j_button[i].downcount++; + j_button[i].timedown = timer_get_fixed_seconds(); + } + } + //end changed - OE + j_button[i].last_state = j_button[i].state; + } + + for (i = 0; i < 4; i++) { + if (j_joystick[i].buffer >= 0) { + if (j_joystick[i].version) { + while (read (j_joystick[i].buffer, ¤t_event, sizeof (struct js_event)) > 0) { + num_processed++; + switch (current_event.type & ~JS_EVENT_INIT) { + case JS_EVENT_AXIS: + j_axis[j_axes_in_sticks[i] + current_event.number].value = current_event.value; + break; + case JS_EVENT_BUTTON: + j_button[j_buttons_in_sticks[i] + current_event.number].state = current_event.value; + break; + } + } + } else { + read (j_joystick[i].buffer, &joy_data, JS_RETURN); + j_axis[j_axes_in_sticks[i] + 0].value = joy_data.x; + j_axis[j_axes_in_sticks[i] + 1].value = joy_data.y; + j_button[j_buttons_in_sticks[i] + 0].state = (joy_data.buttons & 0x01); + j_button[j_buttons_in_sticks[i] + 1].state = (joy_data.buttons & 0x02) >> 1; + } + } + } + + return num_processed;*/ + return 0; +} + + +void joy_set_cal_vals(int *axis_min, int *axis_center, int *axis_max) { + int i; + + for (i = 0; i < 4; i++) { + j_axis[i].center_val = axis_center[i]; + j_axis[i].min_val = axis_min[i]; + j_axis[i].max_val = axis_max[i]; + } +} + + +void joy_get_cal_vals(int *axis_min, int *axis_center, int *axis_max) { + int i; + + //edited 05/18/99 Matt Mueller - we should return all axes instead of j_num_axes, since they are all given to us in joy_set_cal_vals ( and because checker complains :) + for (i = 0; i < 4; i++) { + //end edit -MM + axis_center[i] = j_axis[i].center_val; + axis_min[i] = j_axis[i].min_val; + axis_max[i] = j_axis[i].max_val; + } +} + + +void joy_set_min (int axis_number, int value) { + j_axis[axis_number].min_val = value; +} + + +void joy_set_center (int axis_number, int value) { + j_axis[axis_number].center_val = value; +} + + +void joy_set_max (int axis_number, int value) { + j_axis[axis_number].max_val = value; +} + + +ubyte joy_get_present_mask () { + return 1; +} + + +void joy_set_timer_rate (int max_value) { + timer_rate = max_value; +} + + +int joy_get_timer_rate () { + return timer_rate; +} + + +void joy_flush () { + int i; + + if (!joy_installed) return; + + for (i = 0; i < j_num_buttons; i++) { + j_button[i].timedown = 0; + j_button[i].downcount = 0; + } + +} + + +ubyte joystick_read_raw_axis (ubyte mask, int *axes) { + int i; + + j_Update_state(); + + for (i = 0; i <= j_num_axes; i++) { + axes[i] = j_axis[i].value; + } + + return 0; +} + + +/* joy_init () is pretty huge, a bit klunky, and by no means pretty. But who cares? It does the job and it's only run once. */ + + +int joy_init () { + int i, j; + + if (joy_installed) return 0; + joy_flush (); + + if (!joy_installed) { + +// printf ("Initializing joystick... "); + + j_joystick[0].buffer = open ("/dev/js0", O_NONBLOCK); + j_joystick[1].buffer = open ("/dev/js1", O_NONBLOCK); + j_joystick[2].buffer = open ("/dev/js2", O_NONBLOCK); + j_joystick[3].buffer = open ("/dev/js3", O_NONBLOCK); + + if (j_joystick[0].buffer >= 0 || j_joystick[1].buffer >= 0 || j_joystick[2].buffer >= 0 || j_joystick[3].buffer >= 0) { +// printf ("found: "); + + for (i = 0; i < 4; i++) { + if (j_joystick[i].buffer >= 0) { + /* + ioctl (j_joystick[i].buffer, JSIOCGAXES, &j_joystick[i].num_axes); + ioctl (j_joystick[i].buffer, JSIOCGBUTTONS, &j_joystick[i].num_buttons); + ioctl (j_joystick[i].buffer, JSIOCGVERSION, &j_joystick[i].version); +*/ + if (!j_joystick[i].version) { + j_joystick[i].num_axes = 2; + j_joystick[i].num_buttons = 2; +// printf ("js%d (v0.x) " , i); + } else { +// printf ("js%d (v%d.%d.%d) ", i, (j_joystick[i].version & 0xff0000) >> 16, (j_joystick[i].version & 0xff00) >> 8, j_joystick[i].version & 0xff); + } + + for (j = j_num_axes; j < (j_num_axes + j_joystick[i].num_axes); j++) { + j_axis[j].joydev = i; + if (j_joystick[i].version) { + j_axis[j].center_val = 0; + j_axis[j].max_val = 32767; + j_axis[j].min_val = -32767; + } + } + for (j = j_num_buttons; j < (j_num_buttons + j_joystick[i].num_buttons); j++) { + j_button[j].joydev = i; + } + + j_num_axes += j_joystick[i].num_axes; + j_num_buttons += j_joystick[i].num_buttons; + + } else { + j_joystick[i].num_buttons = 0; + j_joystick[i].num_axes = 0; + } + + for (j = 0; j < i; j++) { + j_axes_in_sticks[i] += j_joystick[j].num_axes; + j_buttons_in_sticks[i] += j_joystick[j].num_buttons; + } + } + } else { +// printf ("no joysticks found\n"); + return 0; + } + +// printf ("\n"); + + if (j_num_axes > MAX_AXES) + j_num_axes = MAX_AXES; + if (j_num_buttons > MAX_BUTTONS) + j_num_buttons = MAX_BUTTONS; + + joy_present = 1; + joy_installed = 1; + return 1; + } + + return 1; +} + + +void joy_close() { + int i; + + if (!joy_installed) return; + + for (i = 0; i < 4; i++) { + if (j_joystick[i].buffer>=0) { + printf ("closing js%d\n", i); + close (j_joystick[i].buffer); + } + j_joystick[i].buffer=-1; + } + + joy_present=0; + joy_installed=0; +} + + +void joy_set_cen() { +} + + +int joy_get_scaled_reading(int raw, int axis_num) +{ + int d, x; + + raw -= j_axis[axis_num].center_val; + + if (raw < 0) + d = j_axis[axis_num].center_val - j_axis[axis_num].min_val; + else if (raw > 0) + d = j_axis[axis_num].max_val - j_axis[axis_num].center_val; + else + d = 0; + + if (d) + x = ((raw << 7) / d); + else + x = 0; + + if ( x < -128 ) + x = -128; + if ( x > 127 ) + x = 127; + +//added on 4/13/99 by Victor Rachels to add deadzone control + d = (joy_deadzone) * 6; + if ((x > (-1*d)) && (x < d)) + x = 0; +//end this section addition -VR + + return x; +} + + +void joy_get_pos(int *x, int *y) { + int axis[MAX_AXES]; + + if ((!joy_installed)||(!joy_present)) { *x=*y=0; return; } + + joystick_read_raw_axis (JOY_ALL_AXIS, axis); + + *x = joy_get_scaled_reading( axis[0], 0 ); + *y = joy_get_scaled_reading( axis[1], 1 ); +} + + +int joy_get_btns () { + return 0; +} + + +int joy_get_button_state (int btn) { + if(btn >= j_num_buttons) + return 0; + j_Update_state (); + + return j_button[btn].state; +} + + +int joy_get_button_down_cnt (int btn) { + int downcount; + + j_Update_state (); + + downcount = j_button[btn].downcount; + j_button[btn].downcount = 0; + + return downcount; +} + + +//changed 6/24/99 to finally squish the timedown bug - Owen Evans +fix joy_get_button_down_time(int btn) { + fix downtime; + j_Update_state (); + + if (j_button[btn].state) { + downtime = timer_get_fixed_seconds() - j_button[btn].timedown; + j_button[btn].timedown = timer_get_fixed_seconds(); + } else { + downtime = 0; + } + + return downtime; +} +//end changed - OE + +void joy_poll() { + +} + + +void joy_set_slow_reading(int flag) { + +} + +#endif // __ENV_LINUX__ diff --git a/input/sdl/Makefile.in b/input/sdl/Makefile.in index 5961801a..21b1036b 100644 --- a/input/sdl/Makefile.in +++ b/input/sdl/Makefile.in @@ -182,7 +182,7 @@ distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ if test -d $$d/$$file; then \ - cp -pr $$d/$$file $(distdir)/$$file; \ + cp -pr $$/$$file $(distdir)/$$file; \ else \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ diff --git a/input/sdl_event.c b/input/sdl_event.c new file mode 100644 index 00000000..85caad2a --- /dev/null +++ b/input/sdl_event.c @@ -0,0 +1,58 @@ +// SDL Event related stuff + +#include + +#ifdef SDL_INPUT +#include +#include + +#include + +extern void key_handler(SDL_KeyboardEvent *event); +//added on 10/17/98 by Hans de Goede for mouse functionality +extern void mouse_button_handler(SDL_MouseButtonEvent *mbe); +extern void mouse_motion_handler(SDL_MouseMotionEvent *mme); +//end this section addition - Hans + +static int initialised=0; + +void event_poll() +{ + SDL_Event event; + while (SDL_PollEvent(&event)) + { +// if( (event.type == SDL_KEYEVENT) { +//added/changed on 10/17/98 by Hans de Goede for mouse functionality +//-killed- if( (event.type == SDL_KEYDOWN) || (event.type == SDL_KEYUP) ) { + switch(event.type) + { + case SDL_KEYDOWN: + case SDL_KEYUP: + key_handler((SDL_KeyboardEvent *)&event); + break; + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + mouse_button_handler((SDL_MouseButtonEvent *)&event); + break; + case SDL_MOUSEMOTION: + mouse_motion_handler((SDL_MouseMotionEvent *)&event); + break; +//-killed- return; +//end this section addition/change - Hans + case SDL_QUIT: { +// void quit_request(); +// quit_request(); + } break; + } + } +} + +int event_init() +{ + // We should now be active and responding to events. + initialised = 1; + + return 0; +} + +#endif diff --git a/input/sdl_key.c b/input/sdl_key.c new file mode 100644 index 00000000..a158a5f2 --- /dev/null +++ b/input/sdl_key.c @@ -0,0 +1,621 @@ +// SDL keyboard input support + +#include + +#ifdef SDL_INPUT + +#include +#include + +#include + +#include "event.h" +#include "error.h" +#include "key.h" +#include "timer.h" + +//added on 9/3/98 by Matt Mueller to free some cpu instead of hogging during menus and such +#include "d_delay.h" +//end this section addition - Matt Mueller + +#define KEY_BUFFER_SIZE 16 + +static unsigned char Installed = 0; + +//-------- Variable accessed by outside functions --------- +unsigned char keyd_buffer_type; // 0=No buffer, 1=buffer ASCII, 2=buffer scans +unsigned char keyd_repeat; +unsigned char keyd_editor_mode; +volatile unsigned char keyd_last_pressed; +volatile unsigned char keyd_last_released; +volatile unsigned char keyd_pressed[256]; +volatile int keyd_time_when_last_pressed; + +typedef struct Key_info { + ubyte state; // state of key 1 == down, 0 == up + ubyte last_state; // previous state of key + int counter; // incremented each time key is down in handler + fix timewentdown; // simple counter incremented each time in interrupt and key is down + fix timehelddown; // counter to tell how long key is down -- gets reset to 0 by key routines + ubyte downcount; // number of key counts key was down + ubyte upcount; // number of times key was released +} Key_info; + +typedef struct keyboard { + unsigned short keybuffer[KEY_BUFFER_SIZE]; + Key_info keys[256]; + fix time_pressed[KEY_BUFFER_SIZE]; + unsigned int keyhead, keytail; +} keyboard; + +static keyboard key_data; + +typedef struct key_props { + char *key_text; + unsigned char ascii_value; + unsigned char shifted_ascii_value; + SDLKey sym; +} key_props; + +key_props key_properties[256] = { +{ "", 255, 255, -1 }, +{ "ESC", 255, 255, SDLK_ESCAPE }, +{ "1", '1', '!', SDLK_1 }, +{ "2", '2', '@', SDLK_2 }, +{ "3", '3', '#', SDLK_3 }, +{ "4", '4', '$', SDLK_4 }, +{ "5", '5', '%', SDLK_5 }, +{ "6", '6', '^', SDLK_6 }, +{ "7", '7', '&', SDLK_7 }, +{ "8", '8', '*', SDLK_8 }, +{ "9", '9', '(', SDLK_9 }, +{ "0", '0', ')', SDLK_0 }, +{ "-", '-', '_', SDLK_MINUS }, +{ "=", '=', '+', SDLK_EQUALS }, +{ "BSPC", 255, 255, SDLK_BACKSPACE }, +{ "TAB", 255, 255, SDLK_TAB }, +{ "Q", 'q', 'Q', SDLK_q }, +{ "W", 'w', 'W', SDLK_w }, +{ "E", 'e', 'E', SDLK_e }, +{ "R", 'r', 'R', SDLK_r }, +{ "T", 't', 'T', SDLK_t }, +{ "Y", 'y', 'Y', SDLK_y }, +{ "U", 'u', 'U', SDLK_u }, +{ "I", 'i', 'I', SDLK_i }, +{ "O", 'o', 'O', SDLK_o }, +{ "P", 'p', 'P', SDLK_p }, +{ "[", '[', '{', SDLK_LEFTBRACKET }, +{ "]", ']', '}', SDLK_RIGHTBRACKET }, +//edited 06/08/99 Matt Mueller - set to correct key_text +{ "ƒ", 255, 255, SDLK_RETURN }, +//end edit -MM +{ "LCTRL", 255, 255, SDLK_LCTRL }, +{ "A", 'a', 'A', SDLK_a }, +{ "S", 's', 'S', SDLK_s }, +{ "D", 'd', 'D', SDLK_d }, +{ "F", 'f', 'F', SDLK_f }, +{ "G", 'g', 'G', SDLK_g }, +{ "H", 'h', 'H', SDLK_h }, +{ "J", 'j', 'J', SDLK_j }, +{ "K", 'k', 'K', SDLK_k }, +{ "L", 'l', 'L', SDLK_l }, +//edited 06/08/99 Matt Mueller - set to correct sym +{ ";", ';', ':', SDLK_SEMICOLON }, +//end edit -MM +{ "'", '\'', '"', SDLK_QUOTE }, +//edited 06/08/99 Matt Mueller - set to correct sym +{ "`", '`', '~', SDLK_BACKQUOTE }, +//end edit -MM +{ "LSHFT", 255, 255, SDLK_LSHIFT }, +{ "\\", '\\', '|', SDLK_BACKSLASH }, +{ "Z", 'z', 'Z', SDLK_z }, +{ "X", 'x', 'X', SDLK_x }, +{ "C", 'c', 'C', SDLK_c }, +{ "V", 'v', 'V', SDLK_v }, +{ "B", 'b', 'B', SDLK_b }, +{ "N", 'n', 'N', SDLK_n }, +{ "M", 'm', 'M', SDLK_m }, +//edited 06/08/99 Matt Mueller - set to correct syms +{ ",", ',', '<', SDLK_COMMA }, +{ ".", '.', '>', SDLK_PERIOD }, +{ "/", '/', '?', SDLK_SLASH }, +//end edit -MM +{ "RSHFT", 255, 255, SDLK_RSHIFT }, +{ "PAD*", '*', 255, SDLK_KP_MULTIPLY }, +{ "LALT", 255, 255, SDLK_LALT }, +{ "SPC", ' ', ' ', SDLK_SPACE }, +{ "CPSLK", 255, 255, SDLK_CAPSLOCK }, +{ "F1", 255, 255, SDLK_F1 }, +{ "F2", 255, 255, SDLK_F2 }, +{ "F3", 255, 255, SDLK_F3 }, +{ "F4", 255, 255, SDLK_F4 }, +{ "F5", 255, 255, SDLK_F5 }, +{ "F6", 255, 255, SDLK_F6 }, +{ "F7", 255, 255, SDLK_F7 }, +{ "F8", 255, 255, SDLK_F8 }, +{ "F9", 255, 255, SDLK_F9 }, +{ "F10", 255, 255, SDLK_F10 }, +{ "NMLCK", 255, 255, SDLK_NUMLOCK }, +{ "SCLK", 255, 255, SDLK_SCROLLOCK }, +{ "PAD7", 255, 255, SDLK_KP7 }, +{ "PAD8", 255, 255, SDLK_KP8 }, +{ "PAD9", 255, 255, SDLK_KP9 }, +{ "PAD-", 255, 255, SDLK_KP_MINUS }, +{ "PAD4", 255, 255, SDLK_KP4 }, +{ "PAD5", 255, 255, SDLK_KP5 }, +{ "PAD6", 255, 255, SDLK_KP6 }, +{ "PAD+", 255, 255, SDLK_KP_PLUS }, +{ "PAD1", 255, 255, SDLK_KP1 }, +{ "PAD2", 255, 255, SDLK_KP2 }, +{ "PAD3", 255, 255, SDLK_KP3 }, +{ "PAD0", 255, 255, SDLK_KP0 }, +{ "PAD.", 255, 255, SDLK_KP_PERIOD }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "F11", 255, 255, SDLK_F11 }, +{ "F12", 255, 255, SDLK_F12 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +//edited 06/08/99 Matt Mueller - add pause ability +{ "PAUSE", 255, 255, SDLK_PAUSE }, +//end edit -MM +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +//edited 06/08/99 Matt Mueller - set to correct key_text +{ "PADƒ", 255, 255, SDLK_KP_ENTER }, +//end edit -MM +//edited 06/08/99 Matt Mueller - set to correct sym +{ "RCTRL", 255, 255, SDLK_RCTRL }, +//end edit -MM +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "PAD/", 255, 255, SDLK_KP_DIVIDE }, +{ "", 255, 255, -1 }, +//edited 06/08/99 Matt Mueller - add printscreen ability +{ "PRSCR", 255, 255, SDLK_PRINT }, +//end edit -MM +{ "RALT", 255, 255, SDLK_RALT }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "HOME", 255, 255, SDLK_HOME }, +//edited 06/08/99 Matt Mueller - set to correct key_text +{ "UP", 255, 255, SDLK_UP }, +//end edit -MM +{ "PGUP", 255, 255, SDLK_PAGEUP }, +{ "", 255, 255, -1 }, +//edited 06/08/99 Matt Mueller - set to correct key_text +{ "LEFT", 255, 255, SDLK_LEFT }, +//end edit -MM +{ "", 255, 255, -1 }, +//edited 06/08/99 Matt Mueller - set to correct key_text +{ "RIGHT", 255, 255, SDLK_RIGHT }, +//end edit -MM +{ "", 255, 255, -1 }, +//edited 06/08/99 Matt Mueller - set to correct key_text +{ "END", 255, 255, SDLK_END }, +//end edit -MM +{ "DOWN", 255, 255, SDLK_DOWN }, +{ "PGDN", 255, 255, SDLK_PAGEDOWN }, +{ "INS", 255, 255, SDLK_INSERT }, +{ "DEL", 255, 255, SDLK_DELETE }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +{ "", 255, 255, -1 }, +}; + +char *key_text[256]; + +void key_buid_key_text(void) +{ +} + +unsigned char key_to_ascii(int keycode ) +{ + int shifted; + + shifted = keycode & KEY_SHIFTED; + keycode &= 0xFF; + + if (shifted) + return key_properties[keycode].shifted_ascii_value; + else + return key_properties[keycode].ascii_value; +} + +void key_handler(SDL_KeyboardEvent *event) +{ + ubyte state; + int i, keycode, event_key, key_state; + Key_info *key; + unsigned char temp; + + event_key = event->keysym.sym; + + key_state = (event->state == SDL_PRESSED); // !(wInfo & KF_UP); + //===================================================== + //Here a translation from win keycodes to mac keycodes! + //===================================================== + + for (i = 255; i >= 0; i--) { + + keycode = i; + key = &(key_data.keys[keycode]); + if (key_properties[i].sym == event_key) + state = key_state; + else + state = key->last_state; + + if ( key->last_state == state ) { + if (state) { + key->counter++; + keyd_last_pressed = keycode; + keyd_time_when_last_pressed = timer_get_fixed_seconds(); + } + } else { + if (state) { + keyd_last_pressed = keycode; + keyd_pressed[keycode] = 1; + key->downcount += state; + key->state = 1; + key->timewentdown = keyd_time_when_last_pressed = timer_get_fixed_seconds(); + key->counter++; + } else { + keyd_pressed[keycode] = 0; + keyd_last_released = keycode; + key->upcount += key->state; + key->state = 0; + key->counter = 0; + key->timehelddown += timer_get_fixed_seconds() - key->timewentdown; + } + } + if ( (state && !key->last_state) || (state && key->last_state && (key->counter > 30) && (key->counter & 0x01)) ) { + if ( keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT]) + keycode |= KEY_SHIFTED; + if ( keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT]) + keycode |= KEY_ALTED; + if ( keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL]) + keycode |= KEY_CTRLED; + if ( keyd_pressed[KEY_DELETE] ) + keycode |= KEY_DEBUGGED; + temp = key_data.keytail+1; + if ( temp >= KEY_BUFFER_SIZE ) temp=0; + if (temp!=key_data.keyhead) { + key_data.keybuffer[key_data.keytail] = keycode; + key_data.time_pressed[key_data.keytail] = keyd_time_when_last_pressed; + key_data.keytail = temp; + } + } + key->last_state = state; + } +} + +void key_close() +{ + Installed = 0; +} + +void key_init() +{ + int i; + + if (Installed) return; + + Installed=1; + + keyd_time_when_last_pressed = timer_get_fixed_seconds(); + keyd_buffer_type = 1; + keyd_repeat = 1; + + for(i=0; i<256; i++) + key_text[i] = key_properties[i].key_text; + + // Clear the keyboard array + key_flush(); + atexit(key_close); +} + +void key_flush() +{ + int i; + fix curtime; + + if (!Installed) + key_init(); + + key_data.keyhead = key_data.keytail = 0; + + //Clear the keyboard buffer + for (i=0; i= KEY_BUFFER_SIZE ) n=0; + return n; +} + +int key_checkch() +{ + int is_one_waiting = 0; + event_poll(); + if (key_data.keytail!=key_data.keyhead) + is_one_waiting = 1; + return is_one_waiting; +} + +int key_inkey() +{ + int key = 0; + if (!Installed) + key_init(); + event_poll(); + if (key_data.keytail!=key_data.keyhead) { + key = key_data.keybuffer[key_data.keyhead]; + key_data.keyhead = add_one(key_data.keyhead); + } +//added 9/3/98 by Matt Mueller to free cpu time instead of hogging during menus and such + else d_delay(1); +//end addition - Matt Mueller + + return key; +} + +int key_inkey_time(fix * time) +{ + int key = 0; + + if (!Installed) + key_init(); + event_poll(); + if (key_data.keytail!=key_data.keyhead) { + key = key_data.keybuffer[key_data.keyhead]; + *time = key_data.time_pressed[key_data.keyhead]; + key_data.keyhead = add_one(key_data.keyhead); + } + return key; +} + +int key_peekkey() +{ + int key = 0; + event_poll(); + if (key_data.keytail!=key_data.keyhead) + key = key_data.keybuffer[key_data.keyhead]; + + return key; +} + +int key_getch() +{ + int dummy=0; + + if (!Installed) + return 0; +// return getch(); + + while (!key_checkch()) + dummy++; + return key_inkey(); +} + +unsigned int key_get_shift_status() +{ + unsigned int shift_status = 0; + + if ( keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT] ) + shift_status |= KEY_SHIFTED; + + if ( keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT] ) + shift_status |= KEY_ALTED; + + if ( keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL] ) + shift_status |= KEY_CTRLED; + +#ifndef NDEBUG + if (keyd_pressed[KEY_DELETE]) + shift_status |=KEY_DEBUGGED; +#endif + + return shift_status; +} + +// Returns the number of seconds this key has been down since last call. +fix key_down_time(int scancode) +{ + fix time_down, time; + + event_poll(); + if ((scancode<0)|| (scancode>255)) return 0; + + if (!keyd_pressed[scancode]) { + time_down = key_data.keys[scancode].timehelddown; + key_data.keys[scancode].timehelddown = 0; + } else { + time = timer_get_fixed_seconds(); + time_down = time - key_data.keys[scancode].timewentdown; + key_data.keys[scancode].timewentdown = time; + } + + return time_down; +} + +unsigned int key_down_count(int scancode) +{ + int n; + event_poll(); + if ((scancode<0)|| (scancode>255)) return 0; + + n = key_data.keys[scancode].downcount; + key_data.keys[scancode].downcount = 0; + + return n; +} + +unsigned int key_up_count(int scancode) +{ + int n; + event_poll(); + if ((scancode<0)|| (scancode>255)) return 0; + + n = key_data.keys[scancode].upcount; + key_data.keys[scancode].upcount = 0; + + return n; +} + +#endif //SDL_INPUT diff --git a/input/sdl_mouse.c b/input/sdl_mouse.c new file mode 100644 index 00000000..06c5e24b --- /dev/null +++ b/input/sdl_mouse.c @@ -0,0 +1,238 @@ +// SDL mouse driver. + +#include + +#ifdef SDL_INPUT +#include +#include +#include "fix.h" +#include "timer.h" +#include "event.h" +#include "mouse.h" + +struct mousebutton { + ubyte pressed; + fix time_went_down; + fix time_held_down; + uint num_downs; + uint num_ups; +}; + +static struct mouseinfo { + struct mousebutton buttons[MOUSE_MAX_BUTTONS]; +//added on 10/17/98 by Hans de Goede for mouse functionality + int min_x, min_y; + int max_x, max_y; + int delta_x, delta_y; + int x,y; +//end this section addition - Hans +} Mouse; + +//added on 10/17/98 by Hans de Goede for mouse functionality +void d_mouse_init(void) +{ + memset(&Mouse,0,sizeof(Mouse)); +} + +//added/changed on 10/17/98 by Hans de Goede for mouse functionality +//void mouse_handler(SDL_MouseButtonEvent *mbe) +void mouse_button_handler(SDL_MouseButtonEvent *mbe) +{ + // to bad, SDL buttons use a different mapping as descent expects, + // this is atleast true and tested for the first three buttons + int button_remap[11] = { + MB_LEFT, + MB_MIDDLE, + MB_RIGHT, + MB_Z_UP, + MB_Z_DOWN, + MB_PITCH_BACKWARD, + MB_PITCH_FORWARD, + MB_BANK_LEFT, + MB_BANK_RIGHT, + MB_HEAD_LEFT, + MB_HEAD_RIGHT }; + + int button = button_remap[mbe->button - 1]; // -1 since SDL seems to start counting at 1 + + if (mbe->state == SDL_PRESSED) { +// Mouse.buttons[mbe->button].pressed = 1; +// Mouse.buttons[mbe->button].time_went_down = timer_get_fixed_seconds(); +// Mouse.buttons[mbe->button].num_downs++; + Mouse.buttons[button].pressed = 1; + Mouse.buttons[button].time_went_down = timer_get_fixed_seconds(); + Mouse.buttons[button].num_downs++; + } else { +// Mouse.buttons[mbe->button].pressed = 0; +// Mouse.buttons[mbe->button].time_held_down += timer_get_fixed_seconds() - Mouse.buttons[mbe->button].time_went_down; +// Mouse.buttons[mbe->button].num_ups++; + Mouse.buttons[button].pressed = 0; + Mouse.buttons[button].time_held_down += timer_get_fixed_seconds() - Mouse.buttons[mbe->button].time_went_down; + Mouse.buttons[button].num_ups++; +//end this section addition/change - Hans + } +} + +//added on 10/17/98 by Hans de Goede for mouse functionality +void mouse_motion_handler(SDL_MouseMotionEvent *mme) +{ + Mouse.delta_x += mme->xrel; + Mouse.delta_y += mme->yrel; + Mouse.x += mme->xrel; + Mouse.y += mme->yrel; + if (Mouse.x > Mouse.max_x) Mouse.x = Mouse.max_x; + else if (Mouse.x < Mouse.min_x) Mouse.x = Mouse.min_x; + if (Mouse.y > Mouse.max_y) Mouse.y = Mouse.max_y; + else if (Mouse.y < Mouse.min_y) Mouse.y = Mouse.min_y; +} +//end this section addition - Hans + + +int mouse_set_limits( int x1, int y1, int x2, int y2 ) +{ +//added on 10/17/98 by Hans de Goede for mouse functionality +//-killed- // Shrug... +//-killed- event_poll(); + Mouse.min_x = x1; + Mouse.min_y = y1; + Mouse.max_x = x2; + Mouse.max_y = y2; +//end this section addition - Hans + return 0; +} + +void mouse_flush() // clears all mice events... +{ + int i; + fix current_time; + + event_poll(); + + current_time = timer_get_fixed_seconds(); + for (i=0; i Mouse.max_x) Mouse.x = Mouse.max_x; + else if (Mouse.x < Mouse.min_x) Mouse.x = Mouse.min_x; + if (Mouse.y > Mouse.max_y) Mouse.y = Mouse.max_y; + else if (Mouse.y < Mouse.min_y) Mouse.y = Mouse.min_y; +//end this section change - Hans +} + +void mouse_get_cyberman_pos( int *x, int *y ) +{ + // Shrug... + event_poll(); +} + +// Returns how long this button has been down since last call. +fix mouse_button_down_time(int button) +{ + fix time_down, time; + + event_poll(); + + if (!Mouse.buttons[button].pressed) { + time_down = Mouse.buttons[button].time_held_down; + Mouse.buttons[button].time_held_down = 0; + } else { + time = timer_get_fixed_seconds(); + time_down = time - Mouse.buttons[button].time_held_down; + Mouse.buttons[button].time_held_down = time; + } + return time_down; +} + +// Returns how many times this button has went down since last call +int mouse_button_down_count(int button) +{ + int count; + + event_poll(); + + count = Mouse.buttons[button].num_downs; + Mouse.buttons[button].num_downs = 0; + + return count; +} + +// Returns 1 if this button is currently down +int mouse_button_state(int button) +{ + event_poll(); + return Mouse.buttons[button].pressed; +} + + + +#endif // SDL_INPUT diff --git a/main/Makefile.am b/main/Makefile.am index 72cdd31e..cbbe0a4b 100644 --- a/main/Makefile.am +++ b/main/Makefile.am @@ -1,8 +1,4 @@ -if USE_OPENGL -INCLUDES = -I $(top_srcdir)/includes -I $(top_srcdir)/input/ggi/include -I $(top_srcdir)/input/linux/include -fwritable-strings -else -INCLUDES = -I $(top_srcdir)/includes -I $(top_srcdir)/input/sdl/include -I $(top_srcdir)/input/linux/include -fwritable-strings -endif +INCLUDES = -I $(top_srcdir)/includes -fwritable-strings bin_PROGRAMS = d2x @@ -23,9 +19,14 @@ console.c cmd.c d2x_LDFLAGS = -export-dynamic + +if ENV_DJGPP + d2x_LDADD = ../3d/lib3d.a ../2d/lib2d.a ../mem/libmem.a ../cfile/libcfile.a ../iff/libiff.a ../texmap/libtexmap.a ../misc/libmisc.a ../maths/libmaths.a ../video/libvideo.a ../arch/libarch.a ../sound/libsound.a ../input/libinput.a + +else if USE_OPENGL -d2x_LDADD = ../3d/lib3d.a ../2d/lib2d.a ../mem/libmem.a ../cfile/libcfile.a ../iff/libiff.a ../texmap/libtexmap.a ../misc/libmisc.a ../maths/libmaths.a ../arch/libarch.a ../video/libvideo.a ../sound/libsound.a ../input/libinput.a -lm -lSDL -ldl -lpthread -lMesaGL -lMesaGLU -lgii -L/usr/X11R6/lib -lXext + d2x_LDADD = ../3d/lib3d.a ../2d/lib2d.a ../mem/libmem.a ../cfile/libcfile.a ../iff/libiff.a ../texmap/libtexmap.a ../misc/libmisc.a ../maths/libmaths.a ../arch/libarch.a ../video/libvideo.a ../sound/libsound.a ../input/libinput.a -lm -lSDL -ldl -lpthread -lMesaGL -lMesaGLU -lgii -L/usr/X11R6/lib -lXext else -d2x_LDADD = ../3d/lib3d.a ../2d/lib2d.a ../mem/libmem.a ../cfile/libcfile.a ../iff/libiff.a ../texmap/libtexmap.a ../misc/libmisc.a ../maths/libmaths.a ../arch/libarch.a ../video/libvideo.a ../sound/libsound.a ../input/libinput.a -lm -lSDL -ldl -lpthread + d2x_LDADD = ../3d/lib3d.a ../2d/lib2d.a ../mem/libmem.a ../cfile/libcfile.a ../iff/libiff.a ../texmap/libtexmap.a ../misc/libmisc.a ../maths/libmaths.a ../arch/libarch.a ../video/libvideo.a ../sound/libsound.a ../input/libinput.a -lm -lSDL -ldl -lpthread +endif endif - diff --git a/main/Makefile.in b/main/Makefile.in index ba4647ca..b9c5bd3a 100644 --- a/main/Makefile.in +++ b/main/Makefile.in @@ -67,8 +67,8 @@ PACKAGE = @PACKAGE@ RANLIB = @RANLIB@ SDL_LIBS = @SDL_LIBS@ VERSION = @VERSION@ -@USE_OPENGL_TRUE@INCLUDES = -I $(top_srcdir)/includes -I $(top_srcdir)/input/ggi/include -I $(top_srcdir)/input/linux/include -fwritable-strings -@USE_OPENGL_FALSE@INCLUDES = -I $(top_srcdir)/includes -I $(top_srcdir)/input/sdl/include -I $(top_srcdir)/input/linux/include -fwritable-strings + +INCLUDES = -I $(top_srcdir)/includes -fwritable-strings bin_PROGRAMS = d2x @@ -76,8 +76,6 @@ d2x_SOURCES = ai.c gamerend.c lighting.c paging.c switch.c ai2.c ef d2x_LDFLAGS = -export-dynamic -@USE_OPENGL_TRUE@d2x_LDADD = ../3d/lib3d.a ../2d/lib2d.a ../mem/libmem.a ../cfile/libcfile.a ../iff/libiff.a ../texmap/libtexmap.a ../misc/libmisc.a ../maths/libmaths.a ../arch/libarch.a ../video/libvideo.a ../sound/libsound.a ../input/libinput.a -lm -lSDL -ldl -lpthread -lMesaGL -lMesaGLU -lgii -L/usr/X11R6/lib -lXext -@USE_OPENGL_FALSE@d2x_LDADD = ../3d/lib3d.a ../2d/lib2d.a ../mem/libmem.a ../cfile/libcfile.a ../iff/libiff.a ../texmap/libtexmap.a ../misc/libmisc.a ../maths/libmaths.a ../arch/libarch.a ../video/libvideo.a ../sound/libsound.a ../input/libinput.a -lm -lSDL -ldl -lpthread mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../conf.h CONFIG_CLEAN_FILES = @@ -98,18 +96,8 @@ inferno.o netmisc.o robot.o config.o gamecntl.o kconfig.o network.o \ scores.o controls.o gamefont.o kludge.o newdemo.o slew.o credits.o \ gamemine.o kmatrix.o newmenu.o songs.o crypt.o gamepal.o laser.o \ object.o state.o console.o cmd.o -@USE_OPENGL_TRUE@d2x_DEPENDENCIES = ../3d/lib3d.a ../2d/lib2d.a \ -@USE_OPENGL_TRUE@../mem/libmem.a ../cfile/libcfile.a ../iff/libiff.a \ -@USE_OPENGL_TRUE@../texmap/libtexmap.a ../misc/libmisc.a \ -@USE_OPENGL_TRUE@../maths/libmaths.a ../arch/libarch.a \ -@USE_OPENGL_TRUE@../video/libvideo.a ../sound/libsound.a \ -@USE_OPENGL_TRUE@../input/libinput.a -@USE_OPENGL_FALSE@d2x_DEPENDENCIES = ../3d/lib3d.a ../2d/lib2d.a \ -@USE_OPENGL_FALSE@../mem/libmem.a ../cfile/libcfile.a ../iff/libiff.a \ -@USE_OPENGL_FALSE@../texmap/libtexmap.a ../misc/libmisc.a \ -@USE_OPENGL_FALSE@../maths/libmaths.a ../arch/libarch.a \ -@USE_OPENGL_FALSE@../video/libvideo.a ../sound/libsound.a \ -@USE_OPENGL_FALSE@../input/libinput.a +d2x_LDADD = $(LDADD) +d2x_DEPENDENCIES = COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ @@ -350,6 +338,11 @@ mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean +@ENV_DJGPP_TRUE@ d2x_LDADD = ../3d/lib3d.a ../2d/lib2d.a ../mem/libmem.a ../cfile/libcfile.a ../iff/libiff.a ../texmap/libtexmap.a ../misc/libmisc.a ../maths/libmaths.a ../video/libvideo.a ../arch/libarch.a ../sound/libsound.a ../input/libinput.a + +@ENV_DJGPP_FALSE@@USE_OPENGL_TRUE@ d2x_LDADD = ../3d/lib3d.a ../2d/lib2d.a ../mem/libmem.a ../cfile/libcfile.a ../iff/libiff.a ../texmap/libtexmap.a ../misc/libmisc.a ../maths/libmaths.a ../arch/libarch.a ../video/libvideo.a ../sound/libsound.a ../input/libinput.a -lm -lSDL -ldl -lpthread -lMesaGL -lMesaGLU -lgii -L/usr/X11R6/lib -lXext +@ENV_DJGPP_FALSE@@USE_OPENGL_FALSE@ d2x_LDADD = ../3d/lib3d.a ../2d/lib2d.a ../mem/libmem.a ../cfile/libcfile.a ../iff/libiff.a ../texmap/libtexmap.a ../misc/libmisc.a ../maths/libmaths.a ../arch/libarch.a ../video/libvideo.a ../sound/libsound.a ../input/libinput.a -lm -lSDL -ldl -lpthread + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/main/config.c b/main/config.c index 300f092f..e4c05a41 100644 --- a/main/config.c +++ b/main/config.c @@ -46,7 +46,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #ifdef RCS -static char rcsid[] = "$Id: config.c,v 1.1.1.1 2001-01-19 03:30:02 bradleyb Exp $"; +static char rcsid[] = "$Id: config.c,v 1.1.1.2 2001-01-19 03:33:47 bradleyb Exp $"; #endif ubyte Config_digi_volume = 8; @@ -369,17 +369,15 @@ int ReadConfigFile() Config_digi_type = digi_driver_board; Config_digi_dma = digi_driver_dma;*/ -#if !defined WINDOWS && !defined __ENV_LINUX__ +#if !defined WINDOWS && !defined __ENV_LINUX__ && !defined __ENV_DJGPP__ if (digi_driver_board_16 > 0 && !args_find("-no16bit") && digi_driver_board_16 != _GUS_16_ST) { digi_driver_board = digi_driver_board_16; digi_driver_dma = digi_driver_dma_16; } -#endif - // HACK!!! + // HACK!!! //Hack to make some cards look like others, such as //the Crytal Lake look like Microsoft Sound System -#if !defined WINDOWS && !defined __ENV_LINUX__ if ( digi_driver_board == _CRYSTAL_LAKE_8_ST ) { ubyte tmp; tmp = CrystalLakeReadMCP( CL_MC1 ); @@ -578,7 +576,7 @@ int WriteConfigFile() #endif #ifdef RCS -static char rcsid[] = "$Id: config.c,v 1.1.1.1 2001-01-19 03:30:02 bradleyb Exp $"; +static char rcsid[] = "$Id: config.c,v 1.1.1.2 2001-01-19 03:33:47 bradleyb Exp $"; #endif #define MAX_CTB_LEN 512 diff --git a/main/console.c b/main/console.c index aefd188d..d92e37ee 100644 --- a/main/console.c +++ b/main/console.c @@ -10,7 +10,13 @@ #include "console.h" #include "cmd.h" +#ifdef __ENV_LINUX__ int text_console_enabled = 1; +#else +int isvga(); +#define text_console_enabled (!isvga()) +#endif + cvar_t *cvar_vars = NULL; /* Console specific cvars */ @@ -55,7 +61,7 @@ void con_printf(int priority, char *fmt, ...) if (priority <= ((int)con_threshold.value)) { va_start (arglist, fmt); - vsnprintf (buffer, 2048, fmt, arglist); + vsprintf (buffer, fmt, arglist); if (text_console_enabled) vprintf(fmt, arglist); va_end (arglist); diff --git a/main/digi.h b/main/digi.h index 9c97a167..c65eee1c 100644 --- a/main/digi.h +++ b/main/digi.h @@ -12,9 +12,9 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. */ /* * $Source: /cvs/cvsroot/d2x/main/digi.h,v $ - * $Revision: 1.1.1.1 $ + * $Revision: 1.1.1.2 $ * $Author: bradleyb $ - * $Date: 2001-01-19 03:29:59 $ + * $Date: 2001-01-19 03:33:43 $ * * Include file for sound hardware. * @@ -164,7 +164,7 @@ typedef struct digi_sound { -#ifdef __MSDOS__ +#ifdef __ENV_DJGPP__ extern int digi_driver_board; extern int digi_driver_port; extern int digi_driver_irq; diff --git a/main/gamerend.c b/main/gamerend.c index 0d13f45b..54d47a7a 100644 --- a/main/gamerend.c +++ b/main/gamerend.c @@ -13,7 +13,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #ifdef RCS -static char rcsid[] = "$Id: gamerend.c,v 1.1.1.1 2001-01-19 03:30:02 bradleyb Exp $"; +static char rcsid[] = "$Id: gamerend.c,v 1.1.1.2 2001-01-19 03:33:47 bradleyb Exp $"; #endif @@ -423,7 +423,7 @@ extern int gr_bitblt_dest_step_shift; extern int gr_wait_for_retrace; extern int gr_bitblt_double; -#if !defined MACINTOSH && !defined __ENV_LINUX__ +#if !defined MACINTOSH && !defined __ENV_LINUX__ && !defined __ENV_DJGPP__ void expand_row(ubyte * dest, ubyte * src, int num_src_pixels ); #pragma aux expand_row parm [edi] [esi] [ecx] modify exact [ecx esi edi eax ebx] = \ "add esi, ecx" \ diff --git a/main/inferno.c b/main/inferno.c index 186ef84f..1639aa6c 100644 --- a/main/inferno.c +++ b/main/inferno.c @@ -123,34 +123,6 @@ void check_joystick_calibration(void); extern int piggy_low_memory; -void mem_int_to_string( int number, char *dest ) -{ - int i,l,c; - char buffer[20],*p; - - sprintf( buffer, "%d", number ); - - l = strlen(buffer); - if (l<=3) { - // Don't bother with less than 3 digits - sprintf( dest, "%d", number ); - return; - } - - c = 0; - p=dest; - for (i=l-1; i>=0; i-- ) { - if (c==3) { - *p++=','; - c = 0; - } - c++; - *p++ = buffer[i]; - } - *p++ = '\0'; - strrev(dest); -} - int descent_critical_error = 0; unsigned descent_critical_deverror = 0; diff --git a/main/inferno.ini b/main/inferno.ini index d106c2c7..7eebe64e 100644 --- a/main/inferno.ini +++ b/main/inferno.ini @@ -1,47 +1,47 @@ -# -# Matt's personal settings file -# -# Comment out lines to disable them -# - -TARGSYS = WIN32 -COMPILER = WATCOM #SYMANTEC - -# These define changes in the code - -RELEASE_VERSION = 1 #turn off test, cheat, & debugging functions -NMONO = 1 #is monochrome debugging turned off? -NDEBUG = 1 #is debugging turned off? (kills Asserts, Int3s, etc.) - -#D2_OEM = 1 # 8-level OEM version? - -#_3DFX = 1 #is the 3Dfx code compiled in? -TACTILE = 1 #are tactile-feedback joysticks supported? - -#SHAREWARE = 1 #is this the smaller shareware -#BUILD_EDITOR = 1 #is the editor included? - - -# These never really get changed - -#PIGGY_NO_PAGING = 1 #don't use John's new paging code -#STORE_DEMO = 1 #is the one-level store demo in? -#ARCADE = 1 #is the Arcade/AWD code in? -#MARK_ON = 1 #are marks on? -#PASSWORD = 'RUST' #is a password required? -#DEMO_ONLY = 1 #is this a non-playable demo? - - -# These define changes in compiling & linking -# Undefining DEBUG_ON will kill symbols and source - -OPTIMIZE_ON = 1 #build optimized -%undef DEBUG_ON #no debug - -#STACK_CHECK_ON = 1 #re-enable stack check - - -#This defines the name of this version - -#VERSION_NAME = "CD Burn Test" - +# +# Matt's personal settings file +# +# Comment out lines to disable them +# + +TARGSYS = WIN32 +COMPILER = WATCOM #SYMANTEC + +# These define changes in the code + +RELEASE_VERSION = 1 #turn off test, cheat, & debugging functions +NMONO = 1 #is monochrome debugging turned off? +NDEBUG = 1 #is debugging turned off? (kills Asserts, Int3s, etc.) + +#D2_OEM = 1 # 8-level OEM version? + +#_3DFX = 1 #is the 3Dfx code compiled in? +TACTILE = 1 #are tactile-feedback joysticks supported? + +#SHAREWARE = 1 #is this the smaller shareware +#BUILD_EDITOR = 1 #is the editor included? + + +# These never really get changed + +#PIGGY_NO_PAGING = 1 #don't use John's new paging code +#STORE_DEMO = 1 #is the one-level store demo in? +#ARCADE = 1 #is the Arcade/AWD code in? +#MARK_ON = 1 #are marks on? +#PASSWORD = 'RUST' #is a password required? +#DEMO_ONLY = 1 #is this a non-playable demo? + + +# These define changes in compiling & linking +# Undefining DEBUG_ON will kill symbols and source + +OPTIMIZE_ON = 1 #build optimized +%undef DEBUG_ON #no debug + +#STACK_CHECK_ON = 1 #re-enable stack check + + +#This defines the name of this version + +#VERSION_NAME = "CD Burn Test" + diff --git a/main/kconfig.c b/main/kconfig.c index 913c0e45..472f668d 100644 --- a/main/kconfig.c +++ b/main/kconfig.c @@ -13,7 +13,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #ifdef RCS -static char rcsid[] = "$Id: kconfig.c,v 1.1.1.1 2001-01-19 03:29:59 bradleyb Exp $"; +static char rcsid[] = "$Id: kconfig.c,v 1.1.1.2 2001-01-19 03:33:43 bradleyb Exp $"; #endif #include @@ -3504,7 +3504,7 @@ void kconfig_read_external_controls() kc_external_control->automap_state = 1; //memset(&r,0,sizeof(r)); - #if !defined WINDOWS && !defined __ENV_LINUX__ + #if !defined WINDOWS && !defined __ENV_LINUX__ && !defined __ENV_DJGPP__ int386 ( kc_external_intno, &r, &r); // Read external info... diff --git a/main/kludge.c b/main/kludge.c index a77b908f..d8c4f5fe 100644 --- a/main/kludge.c +++ b/main/kludge.c @@ -19,10 +19,12 @@ int Dont_start_sound_objects = 1; int Window_clip_left,Window_clip_top,Window_clip_right,Window_clip_bot; char CDROM_dir[40] = "."; -int gr_check_mode(int a) +#ifndef __ENV_DJGPP__ +int gr_check_mode(u_int32_t a) { return 0; -} +} +#endif extern int Num_computed_colors; void gr_copy_palette(ubyte *gr_palette, ubyte *pal, int size) @@ -32,10 +34,12 @@ void gr_copy_palette(ubyte *gr_palette, ubyte *pal, int size) Num_computed_colors = 0; } +#ifndef __ENV_DJGPP__ int joy_set_btn_values( int btn, int state, int time_down, int downcount, int upcount ) { } +#endif int request_cd(void) { diff --git a/main/link.bat b/main/link.bat new file mode 100644 index 00000000..9f10bbcd --- /dev/null +++ b/main/link.bat @@ -0,0 +1 @@ +gcc -o d2x.exe *.o ..\mem\*.o ..\cfile\*.o ..\2d\*.o ..\3d\*.o ..\texmap\*.o ..\misc\*.o ..\arch\dos\*.o ..\iff\*.o ..\maths\*.o diff --git a/main/multi.c b/main/multi.c index 2909b56d..59777af7 100644 --- a/main/multi.c +++ b/main/multi.c @@ -1061,7 +1061,7 @@ multi_menu_poll(void) return(-1); } -#if !defined(WINDOWS) && !defined(MACINTOSH) && (!defined(__ENV_LINUX__)) +#if !defined(WINDOWS) && !defined(MACINTOSH) && (!defined(__ENV_LINUX__) && (!defined (__ENV_DJGPP__))) if ((Game_mode & GM_MODEM) && (!GetCd(com_port))) { multi_leave_menu = 1; diff --git a/main/network.c b/main/network.c index f5f80f61..a729f9f1 100644 --- a/main/network.c +++ b/main/network.c @@ -12,7 +12,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. */ #ifdef RCS -static char rcsid[] = "$Id: network.c,v 1.1.1.1 2001-01-19 03:30:02 bradleyb Exp $"; +static char rcsid[] = "$Id: network.c,v 1.1.1.2 2001-01-19 03:33:46 bradleyb Exp $"; #endif #include @@ -26,6 +26,7 @@ static char rcsid[] = "$Id: network.c,v 1.1.1.1 2001-01-19 03:30:02 bradleyb Exp #include #include "pstypes.h" +#include "strutil.h" #include "args.h" #include "timer.h" #include "mono.h" diff --git a/maths/vecmat.c b/maths/vecmat.c index 6a39f75d..980c28c2 100644 --- a/maths/vecmat.c +++ b/maths/vecmat.c @@ -12,9 +12,9 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. */ /* * $Source: /cvs/cvsroot/d2x/maths/vecmat.c,v $ - * $Revision: 1.1.1.1 $ + * $Revision: 1.1.1.2 $ * $Author: bradleyb $ - * $Date: 2001-01-19 03:29:58 $ + * $Date: 2001-01-19 03:33:42 $ * * C version of vecmat library * @@ -47,7 +47,7 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. */ #ifdef RCS -static char rcsid[] = "$Id: vecmat.c,v 1.1.1.1 2001-01-19 03:29:58 bradleyb Exp $"; +static char rcsid[] = "$Id: vecmat.c,v 1.1.1.2 2001-01-19 03:33:42 bradleyb Exp $"; #endif #include @@ -79,7 +79,7 @@ vms_vector *vm_vec_scale2(vms_vector *dest,fix n,fix d) return dest; } -#ifndef ASM_VECMAT +#ifdef NO_ASM vms_vector vmd_zero_vector = {0,0,0}; vms_matrix vmd_identity_matrix = { { f1_0,0,0 }, { 0,f1_0,0 }, diff --git a/misc/d_io.c b/misc/d_io.c index df822359..1e7ab075 100644 --- a/misc/d_io.c +++ b/misc/d_io.c @@ -4,14 +4,14 @@ #include #include #include "d_io.h" -#ifdef __MSDOS__ -#include "disk.h" +#ifdef __ENV_DJGPP__ +#include "dos_disk.h" #endif //added 05/17/99 Matt Mueller #include "u_mem.h" //end addition -MM -#ifdef __WINDOWS__ +#ifdef __ENV_WINDOWS__ #include #define lseek(a,b,c) _lseek(a,b,c) #endif @@ -34,10 +34,10 @@ long ffilelength(FILE *fh) unsigned long d_getdiskfree() { -#ifdef __MSDOS__ +#ifdef __ENV_MSDOS__ return getdiskfree(); #else -#ifdef __WINDOWS__ +#ifdef __ENV_WINDOWS__ ULONG cbCluster = 0; ULONG cClusters = 0; diff --git a/misc/dos_disk.h b/misc/dos_disk.h new file mode 100644 index 00000000..c983fce4 --- /dev/null +++ b/misc/dos_disk.h @@ -0,0 +1,6 @@ +#ifndef _DISK_H +#define _DISK_H + +unsigned long getdiskfree(); + +#endif diff --git a/misc/strutil.c b/misc/strutil.c index 3c09afe2..c484341a 100644 --- a/misc/strutil.c +++ b/misc/strutil.c @@ -30,6 +30,8 @@ char *d_strdup(char *str) return a; } + +#if !defined __ENV_LINUX__ && !defined __ENV_DJGPP__ // string compare without regard to case int stricmp( char *s1, char *s2 ) @@ -55,6 +57,10 @@ int strnicmp( char *s1, char *s2, int n ) return 0; } +#endif + +#ifndef __ENV_DJGPP__ + void strlwr( char *s1 ) { while( *s1 ) { @@ -71,6 +77,8 @@ void strupr( char *s1 ) } } +#endif + void strrev( char *s1 ) { int i,l; diff --git a/readme.txt b/readme.txt index 8d19b846..c058eb6c 100644 --- a/readme.txt +++ b/readme.txt @@ -1,75 +1,75 @@ -Please view the file README before this file. - - -Legal Stuff: - -THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX -SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO -END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A -ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS -IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS -SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE -FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE -CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS -AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. -COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. - -We make no warranties as to the usability or correctness of this code. - -============================================ -Message from Matt Toschlog & Mike Kulas: - -Descent fans: - -Here, finally, is the source for Descent II. We've been so busy with -Descent 3, Mercenary, FreeSpace, FreeSpace 2, and several other -projects that we haven't given much thought to this old code. But we -know that many of you are eager to get it, so here you go. - -We were amazed and impressed at the cool things people did with -the Descent source we released a few years ago. It touches us -deeply how devoted some people are to the Descent series, and we -look forward to seeing what people can do with this Descent II -source. - -Matt Toschlog Mike Kulas -Outrage Entertainment Volition, Inc. - -============================================ - -About the Source Code: - -Included is almost all the source code to Descent 2, ver. 1.2. We removed -all code to which we did not own the copyright. This mainly involved low- -level sound and modem code and the movie code. - -The Descent Network has agreed to provide a list of mirror locations where -this code can be downloaded. The location is: - -http://www.descent2.com/ddn/sources/descent2 - -The following tools were used in the development of Descent: -Watcom C/C++, version 9.5 -Microsoft Macro Assembler, version 6.1x -Opus Make, version 6.01 - -Have fun with the code! -Parallax Software Corporation -12/14/1999 - - -As Packaged the code currently will not compile. Some code had to be removed -to release it, therefore you will get some missing file errors when building. - -Much of this code is very close to the Descent 1 source code. Many people have -put effort into porting that code, so if you are interested in porting D2, you -should be able to take advantage of some of that work. - -A few good web sites to check out are: - -The D1X Project: -http://d1x.warpcore.org - -The Descent Network: -http://www.descent-network.com - +Please view the file README before this file. + + +Legal Stuff: + +THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. + +We make no warranties as to the usability or correctness of this code. + +============================================ +Message from Matt Toschlog & Mike Kulas: + +Descent fans: + +Here, finally, is the source for Descent II. We've been so busy with +Descent 3, Mercenary, FreeSpace, FreeSpace 2, and several other +projects that we haven't given much thought to this old code. But we +know that many of you are eager to get it, so here you go. + +We were amazed and impressed at the cool things people did with +the Descent source we released a few years ago. It touches us +deeply how devoted some people are to the Descent series, and we +look forward to seeing what people can do with this Descent II +source. + +Matt Toschlog Mike Kulas +Outrage Entertainment Volition, Inc. + +============================================ + +About the Source Code: + +Included is almost all the source code to Descent 2, ver. 1.2. We removed +all code to which we did not own the copyright. This mainly involved low- +level sound and modem code and the movie code. + +The Descent Network has agreed to provide a list of mirror locations where +this code can be downloaded. The location is: + +http://www.descent2.com/ddn/sources/descent2 + +The following tools were used in the development of Descent: +Watcom C/C++, version 9.5 +Microsoft Macro Assembler, version 6.1x +Opus Make, version 6.01 + +Have fun with the code! +Parallax Software Corporation +12/14/1999 + + +As Packaged the code currently will not compile. Some code had to be removed +to release it, therefore you will get some missing file errors when building. + +Much of this code is very close to the Descent 1 source code. Many people have +put effort into porting that code, so if you are interested in porting D2, you +should be able to take advantage of some of that work. + +A few good web sites to check out are: + +The D1X Project: +http://d1x.warpcore.org + +The Descent Network: +http://www.descent-network.com + diff --git a/sound/Makefile.am b/sound/Makefile.am index 36c5aa02..38e119d1 100644 --- a/sound/Makefile.am +++ b/sound/Makefile.am @@ -1,3 +1,4 @@ noinst_LIBRARIES = libsound.a INCLUDES = -I $(top_srcdir) -I$(top_srcdir)/includes -I$(top_srcdir)/main -libsound_a_SOURCES = sdl_digi.c sdl_cdrom.c +libsound_a_SOURCES = sdl_digi.c sdl_cdrom.c \ +dos_digi.c dos_cdrom.c diff --git a/sound/Makefile.in b/sound/Makefile.in index 0148e6d9..35d8502d 100644 --- a/sound/Makefile.in +++ b/sound/Makefile.in @@ -70,7 +70,8 @@ VERSION = @VERSION@ noinst_LIBRARIES = libsound.a INCLUDES = -I $(top_srcdir) -I$(top_srcdir)/includes -I$(top_srcdir)/main -libsound_a_SOURCES = sdl_digi.c sdl_cdrom.c +libsound_a_SOURCES = sdl_digi.c sdl_cdrom.c dos_digi.c dos_cdrom.c + mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../conf.h CONFIG_CLEAN_FILES = @@ -82,7 +83,7 @@ CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ libsound_a_LIBADD = -libsound_a_OBJECTS = sdl_digi.o sdl_cdrom.o +libsound_a_OBJECTS = sdl_digi.o sdl_cdrom.o dos_digi.o dos_cdrom.o AR = ar COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) @@ -94,7 +95,8 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP_ENV = --best -DEP_FILES = .deps/sdl_cdrom.P .deps/sdl_digi.P +DEP_FILES = .deps/dos_cdrom.P .deps/dos_digi.P .deps/sdl_cdrom.P \ +.deps/sdl_digi.P SOURCES = $(libsound_a_SOURCES) OBJECTS = $(libsound_a_OBJECTS) diff --git a/sound/dos_cdrom.c b/sound/dos_cdrom.c new file mode 100644 index 00000000..b812a850 --- /dev/null +++ b/sound/dos_cdrom.c @@ -0,0 +1,80 @@ +/* DPH: This is the file where all the stub functions go. The aim is to have nothing in here ,eventually */ +#include +#ifdef __ENV_DJGPP__ +#include +#include +#include "pstypes.h" +#include "error.h" +#include "args.h" + + +extern int Redbook_playing; +static int initialised = 0; + +void RBAExit() +{ +} + +void RBAInit() +{ + +} + +int RBAEnabled() +{ + return 1; +} + +void RBARegisterCD() +{ + +} + +int RBAPlayTrack(int a) +{ +return 0; +} + +void RBAStop() +{ +} + +void RBASetVolume(int a) +{ + +} + +void RBAPause() +{ +} + +void RBAResume() +{ +} + +int RBAGetNumberOfTracks() +{ +return 0; +} + +int RBAPlayTracks(int tracknum,int something) +{ +return -1; +} + +int RBAGetTrackNum() +{ +return -1; +} + +int RBAPeekPlayStatus() +{ + return -1; +} + +int CD_blast_mixer() +{ + return 0; +} + +#endif // __ENV_DJGPP__ diff --git a/sound/dos_digi.c b/sound/dos_digi.c new file mode 100644 index 00000000..f0e17444 --- /dev/null +++ b/sound/dos_digi.c @@ -0,0 +1,813 @@ +// SDL digital audio support + +#include +#ifdef __ENV_DJGPP__ +#include +#include +#include + +#include "pstypes.h" +#include "error.h" +#include "mono.h" +#include "fix.h" +#include "vecmat.h" +#include "gr.h" // needed for piggy.h +#include "piggy.h" +#include "digi.h" +#include "sounds.h" +#include "wall.h" +#include "newdemo.h" +#include "kconfig.h" + +int digi_sample_rate=11025; +int digi_timer_rate = 9943; // rate for the timer to go off to handle the driver system (120 Hz) + +//edited 05/17/99 Matt Mueller - added ifndef NO_ASM +//added on 980905 by adb to add inline fixmul for mixer on i386 +#ifndef NO_ASM +#ifdef __i386__ +#define do_fixmul(x,y) \ +({ \ + int _ax, _dx; \ + asm("imull %2\n\tshrdl %3,%1,%0" \ + : "=a"(_ax), "=d"(_dx) \ + : "rm"(y), "i"(16), "0"(x)); \ + _ax; \ +}) +extern inline fix fixmul(fix x, fix y) { return do_fixmul(x,y); } +#endif +#endif +//end edit by adb +//end edit -MM + +//changed on 980905 by adb to increase number of concurrent sounds +#define MAX_SOUND_SLOTS 32 +//end changes by adb +#define SOUND_BUFFER_SIZE 512 + +#define MIN_VOLUME 10 + +/* This table is used to add two sound values together and pin + * the value to avoid overflow. (used with permission from ARDI) + * DPH: Taken from SDL/src/SDL_mixer.c. + */ +static const unsigned char mix8[] = +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, + 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, + 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, + 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, + 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, + 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, + 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, + 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, + 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, + 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, + 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, + 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, + 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, + 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, + 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, + 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; + +#define SOF_USED 1 // Set if this sample is used +#define SOF_PLAYING 2 // Set if this sample is playing on a channel +#define SOF_LINK_TO_OBJ 4 // Sound is linked to a moving object. If object dies, then finishes play and quits. +#define SOF_LINK_TO_POS 8 // Sound is linked to segment, pos +#define SOF_PLAY_FOREVER 16 // Play forever (or until level is stopped), otherwise plays once + +typedef struct sound_object { + short signature; // A unique signature to this sound + ubyte flags; // Used to tell if this slot is used and/or currently playing, and how long. + fix max_volume; // Max volume that this sound is playing at + fix max_distance; // The max distance that this sound can be heard at... + int volume; // Volume that this sound is playing at + int pan; // Pan value that this sound is playing at + int handle; // What handle this sound is playing on. Valid only if SOF_PLAYING is set. + short soundnum; // The sound number that is playing + union { + struct { + short segnum; // Used if SOF_LINK_TO_POS field is used + short sidenum; + vms_vector position; + }pos; + struct { + short objnum; // Used if SOF_LINK_TO_OBJ field is used + short objsignature; + }obj; + }link; +} sound_object; +#define lp_segnum link.pos.segnum +#define lp_sidenum link.pos.sidenum +#define lp_position link.pos.position + +#define lo_objnum link.obj.objnum +#define lo_objsignature link.obj.objsignature + +#define MAX_SOUND_OBJECTS 16 +sound_object SoundObjects[MAX_SOUND_OBJECTS]; +short next_signature=0; + +//added/changed on 980905 by adb to make sfx volume work, on 990221 by adb changed F1_0 to F1_0 / 2 +#define SOUND_MAX_VOLUME (F1_0 / 2) + +int digi_volume = SOUND_MAX_VOLUME; +//end edit by adb + +int digi_lomem = 0; + +static int digi_initialised = 0; + +struct sound_slot { + int soundno; + int playing; // Is there a sample playing on this channel? + int looped; // Play this sample looped? + fix pan; // 0 = far left, 1 = far right + fix volume; // 0 = nothing, 1 = fully on + //changed on 980905 by adb from char * to unsigned char * + unsigned char *samples; + //end changes by adb + unsigned int length; // Length of the sample + unsigned int position; // Position we are at at the moment. +} SoundSlots[MAX_SOUND_SLOTS]; + +static int digi_sounds_initialized = 0; + +//added on 980905 by adb to add rotating/volume based sound kill system +static int digi_max_channels = 16; +static int next_handle = 0; +int SampleHandles[32]; +void reset_sounds_on_channel(int channel); +//end edit by adb + +void digi_reset_digi_sounds(void); + +/* Audio mixing callback */ +//changed on 980905 by adb to cleanup, add pan support and optimize mixer +static void audio_mixcallback(void *userdata, unsigned char *stream, int len) +{ + unsigned char *streamend = stream + len; + struct sound_slot *sl; + + for (sl = SoundSlots; sl < SoundSlots + MAX_SOUND_SLOTS; sl++) + { + if (sl->playing) + { + unsigned char *sldata = sl->samples + sl->position, *slend = sl->samples + sl->length; + unsigned char *sp = stream; + signed char v; + fix vl, vr; + int x; + + if ((x = sl->pan) & 0x8000) + { + vl = 0x20000 - x * 2; + vr = 0x10000; + } + else + { + vl = 0x10000; + vr = x * 2; + } + vl = fixmul(vl, (x = sl->volume)); + vr = fixmul(vr, x); + while (sp < streamend) + { + if (sldata == slend) + { + if (!sl->looped) + { + sl->playing = 0; + break; + } + sldata = sl->samples; + } + v = *(sldata++) - 0x80; + *(sp++) = mix8[ *sp + fixmul(v, vl) + 0x80 ]; + *(sp++) = mix8[ *sp + fixmul(v, vr) + 0x80 ]; + } + sl->position = sldata - sl->samples; + } + } +} +//end changes by adb + +/* Initialise audio devices. */ +int digi_init() +{ + + return 1; +} + +/* Toggle audio */ +void digi_reset() { } + +/* Shut down audio */ +void digi_close() +{ + if (!digi_initialised) return; + digi_initialised = 0; +} + +/* Find the sound which actually equates to a sound number */ +int digi_xlat_sound(int soundno) +{ + if ( soundno < 0 ) return -1; + + if ( digi_lomem ) { + soundno = AltSounds[soundno]; + if ( soundno == 255 ) return -1; + } + return Sounds[soundno]; +} + +static int get_free_slot() +{ + int i; + for (i=0; i= 0) && (SoundSlots[SampleHandles[next_handle]].playing) ) + { + if ( (SoundSlots[SampleHandles[next_handle]].volume > digi_volume) && (ntries= digi_max_channels ) + next_handle = 0; + ntries++; + goto TryNextChannel; + } + //mprintf(( 0, "[SS:%d]", next_handle )); + SoundSlots[SampleHandles[next_handle]].playing = 0; + SampleHandles[next_handle] = -1; + } + //end edit by adb + + slot = get_free_slot(); + if (slot<0) return -1; + + SoundSlots[slot].soundno = soundnum; + SoundSlots[slot].samples = GameSounds[soundnum].data; + SoundSlots[slot].length = GameSounds[soundnum].length; + SoundSlots[slot].volume = fixmul(digi_volume, volume); + SoundSlots[slot].pan = pan; + SoundSlots[slot].position = 0; + SoundSlots[slot].looped = 0; + SoundSlots[slot].playing = 1; + + //added on 980905 by adb to add sound kill system from original sos digi.c + reset_sounds_on_channel(slot); + SampleHandles[next_handle] = slot; + next_handle++; + if ( next_handle >= digi_max_channels ) + next_handle = 0; + //end edit by adb + + return slot; +} + + //added on 980905 by adb to add sound kill system from original sos digi.c +void reset_sounds_on_channel( int channel ) +{ + int i; + + for (i=0; i -1 ) { + *volume = max_volume - fixdiv(path_distance,max_distance); + //mprintf( (0, "Sound path distance %.2f, volume is %d / %d\n", f2fl(distance), *volume, max_volume )); + if (*volume > 0 ) { + angle_from_ear = vm_vec_delta_ang_norm(&listener->rvec,&vector_to_sound,&listener->uvec); + fix_sincos(angle_from_ear,&sinang,&cosang); + //mprintf( (0, "volume is %.2f\n", f2fl(*volume) )); + if (Config_channels_reversed) cosang *= -1; + *pan = (cosang + F1_0)/2; + } else { + *volume = 0; + } + } + } +} + +int digi_link_sound_to_object2( int org_soundnum, short objnum, int forever, fix max_volume, fix max_distance ) +{ + int i,volume,pan; + object * objp; + int soundnum; + + soundnum = digi_xlat_sound(org_soundnum); + + if ( max_volume < 0 ) return -1; +// if ( max_volume > F1_0 ) max_volume = F1_0; + + if (!digi_initialised) return -1; + if (soundnum < 0 ) return -1; + if (GameSounds[soundnum].data==NULL) { + Int3(); + return -1; + } + if ((objnum<0)||(objnum>Highest_object_index)) + return -1; + + if ( !forever ) { + // Hack to keep sounds from building up... + digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, &Objects[objnum].pos, Objects[objnum].segnum, max_volume,&volume, &pan, max_distance ); + digi_play_sample_3d( org_soundnum, pan, volume, 0 ); + return -1; + } + + for (i=0; iorient, &Viewer->pos, Viewer->segnum, + &objp->pos, objp->segnum, SoundObjects[i].max_volume, + &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); + + if (!forever || SoundObjects[i].volume >= MIN_VOLUME) + digi_start_sound_object(i); + + return SoundObjects[i].signature; +} + +int digi_link_sound_to_object( int soundnum, short objnum, int forever, fix max_volume ) +{ return digi_link_sound_to_object2( soundnum, objnum, forever, max_volume, 256*F1_0); } + +int digi_link_sound_to_pos2( int org_soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume, fix max_distance ) +{ + int i, volume, pan; + int soundnum; + + soundnum = digi_xlat_sound(org_soundnum); + + if ( max_volume < 0 ) return -1; +// if ( max_volume > F1_0 ) max_volume = F1_0; + + if (!digi_initialised) return -1; + if (soundnum < 0 ) return -1; + if (GameSounds[soundnum].data==NULL) { + Int3(); + return -1; + } + + if ((segnum<0)||(segnum>Highest_segment_index)) + return -1; + + if ( !forever ) { + // Hack to keep sounds from building up... + digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, pos, segnum, max_volume, &volume, &pan, max_distance ); + digi_play_sample_3d( org_soundnum, pan, volume, 0 ); + return -1; + } + + for (i=0; iorient, &Viewer->pos, Viewer->segnum, + &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum, + SoundObjects[i].max_volume, + &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); + + if (!forever || SoundObjects[i].volume >= MIN_VOLUME) + digi_start_sound_object(i); + + return SoundObjects[i].signature; +} + +int digi_link_sound_to_pos( int soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume ) +{ + return digi_link_sound_to_pos2( soundnum, segnum, sidenum, pos, forever, max_volume, F1_0 * 256 ); +} + +void digi_kill_sound_linked_to_segment( int segnum, int sidenum, int soundnum ) +{ + int i,killed; + + soundnum = digi_xlat_sound(soundnum); + + if (!digi_initialised) return; + + killed = 0; + + for (i=0; i 1 ) { + mprintf( (1, "ERROR: More than 1 sounds were deleted from seg %d\n", segnum )); + } +} + +void digi_kill_sound_linked_to_object( int objnum ) +{ + int i,killed; + + if (!digi_initialised) return; + + killed = 0; + + for (i=0; i 1 ) { + mprintf( (1, "ERROR: More than 1 sounds were deleted from object %d\n", objnum )); + } +} + +void digi_sync_sounds() +{ + int i; + int oldvolume, oldpan; + + if (!digi_initialised) return; + + for (i=0; iorient, &Viewer->pos, Viewer->segnum, + &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum, + SoundObjects[i].max_volume, + &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); + + } else if ( SoundObjects[i].flags & SOF_LINK_TO_OBJ ) { + object * objp; + + objp = &Objects[SoundObjects[i].lo_objnum]; + + if ((objp->type==OBJ_NONE) || (objp->signature!=SoundObjects[i].lo_objsignature)) { + // The object that this is linked to is dead, so just end this sound if it is looping. + if ( (SoundObjects[i].flags & SOF_PLAYING) && (SoundObjects[i].flags & SOF_PLAY_FOREVER)) { + SoundSlots[SoundObjects[i].handle].playing = 0; + } + SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound + continue; // Go on to next sound... + } else { + digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, + &objp->pos, objp->segnum, SoundObjects[i].max_volume, + &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); + } + } + + if (oldvolume != SoundObjects[i].volume) { + if ( SoundObjects[i].volume < MIN_VOLUME ) { + // Sound is too far away, so stop it from playing. + if ((SoundObjects[i].flags & SOF_PLAYING)&&(SoundObjects[i].flags & SOF_PLAY_FOREVER)) { + SoundSlots[SoundObjects[i].handle].playing = 0; + SoundObjects[i].flags &= ~SOF_PLAYING; // Mark sound as not playing + } + } else { + if (!(SoundObjects[i].flags & SOF_PLAYING)) { + digi_start_sound_object(i); + } else { + SoundSlots[SoundObjects[i].handle].volume = fixmuldiv(SoundObjects[i].volume,digi_volume,F1_0); + } + } + } + + if (oldpan != SoundObjects[i].pan) { + if (SoundObjects[i].flags & SOF_PLAYING) + SoundSlots[SoundObjects[i].handle].pan = SoundObjects[i].pan; + } + } + } +} + +void digi_init_sounds() +{ + int i; + + if (!digi_initialised) return; + + digi_reset_digi_sounds(); + + for (i=0; i SOUND_MAX_VOLUME ) + digi_volume = SOUND_MAX_VOLUME; + else if ( dvolume < 0 ) + digi_volume = 0; + else + digi_volume = dvolume; + + if ( !digi_initialised ) return; + + digi_sync_sounds(); +} +//end edit by adb + +void digi_set_volume( int dvolume, int mvolume ) { } + +int digi_is_sound_playing(int soundno) +{ + int i; + + soundno = digi_xlat_sound(soundno); + + for (i = 0; i < MAX_SOUND_SLOTS; i++) + //changed on 980905 by adb: added SoundSlots[i].playing && + if (SoundSlots[i].playing && SoundSlots[i].soundno == soundno) + //end changes by adb + return 1; + return 0; +} + + +void digi_pause_all() { } +void digi_resume_all() { } +void digi_stop_all() { } + + //added on 980905 by adb to make sound channel setting work +void digi_set_max_channels(int n) { + digi_max_channels = n; + + if ( digi_max_channels < 1 ) + digi_max_channels = 1; + if ( digi_max_channels > (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS) ) + digi_max_channels = (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS); + + if ( !digi_initialised ) return; + + digi_reset_digi_sounds(); +} + +int digi_get_max_channels() { + return digi_max_channels; +} +// end edit by adb + +void digi_reset_digi_sounds() { + int i; + + for (i=0; i< MAX_SOUND_SLOTS; i++) + SoundSlots[i].playing=0; + + //added on 980905 by adb to reset sound kill system + memset(SampleHandles, 255, sizeof(SampleHandles)); + next_handle = 0; + //end edit by adb +} + + +// MIDI stuff follows. +//added/killed on 11/25/98 by Matthew Mueller +//void digi_set_midi_volume( int mvolume ) { } +//void digi_play_midi_song( char * filename, char * melodic_bank, char * drum_bank, int loop ) {} +//void digi_stop_current_song() +//{ +//#ifdef HMIPLAY +// char buf[10]; +// +// sprintf(buf,"s"); +// send_ipc(buf); +//#endif +//} +//end this section kill - MM + +#endif // __ENV_DJGPP__ diff --git a/sound/sdl_cdrom.c b/sound/sdl_cdrom.c index 39c57118..7f099305 100644 --- a/sound/sdl_cdrom.c +++ b/sound/sdl_cdrom.c @@ -1,5 +1,7 @@ /* DPH: This is the file where all the stub functions go. The aim is to have nothing in here ,eventually */ #include + +#ifdef SDL_AUDIO #include #include #include @@ -118,3 +120,5 @@ int CD_blast_mixer() { return 0; } + +#endif //SDL_AUDIO diff --git a/sound/sdl_digi.c b/sound/sdl_digi.c index 749f6785..940967c5 100644 --- a/sound/sdl_digi.c +++ b/sound/sdl_digi.c @@ -1,6 +1,8 @@ // SDL digital audio support #include + +#ifdef SDL_AUDIO #include #include #include @@ -840,3 +842,5 @@ void digi_reset_digi_sounds() { //#endif //} //end this section kill - MM + +#endif // SDL_AUDIO diff --git a/unused/bios/d.bat b/unused/bios/d.bat index 9086baaf..c5278afb 100644 --- a/unused/bios/d.bat +++ b/unused/bios/d.bat @@ -1 +1 @@ -wvideo cdtest +wvideo cdtest diff --git a/unused/bios/dd.bat b/unused/bios/dd.bat index 1a96ee78..9996353e 100644 --- a/unused/bios/dd.bat +++ b/unused/bios/dd.bat @@ -1 +1 @@ -rcsdiff %1 %2 %3 %4 %5 %6 %7 %8 %9 |more +rcsdiff %1 %2 %3 %4 %5 %6 %7 %8 %9 |more diff --git a/unused/bios/joy.asm b/unused/bios/joy.asm index b88bc808..5c66a571 100644 --- a/unused/bios/joy.asm +++ b/unused/bios/joy.asm @@ -1,252 +1,252 @@ -; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX -; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO -; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A -; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS -; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS -; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE -; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE -; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS -; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. -; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. -.386 - -_DATA SEGMENT BYTE PUBLIC USE32 'DATA' - -rcsid db "$Id: joy.asm,v 1.1.1.1 2001-01-19 03:30:14 bradleyb Exp $" - - LastTick dd 0 - TotalTicks dd 0 - -_DATA ENDS - -DGROUP GROUP _DATA - - -_TEXT SEGMENT BYTE PUBLIC USE32 'CODE' - - ASSUME ds:_DATA - ASSUME cs:_TEXT - - JOY_PORT EQU 0201h - TDATA EQU 40h - TCOMMAND EQU 43h - -joy_get_timer: - xor al, al ; Latch timer 0 command - out TCOMMAND, al ; Latch timer - in al, TDATA ; Read lo byte - mov ah, al - in al, TDATA ; Read hi byte - xchg ah, al - and eax, 0ffffh - ret - -PUBLIC joy_read_stick_asm_ - -joy_read_stick_asm_: - ; ebx = read mask - ; edi = pointer to event buffer - ; ecx = timeout value - ; returns in eax the number of events - and ebx, 01111b ; Make sure we only check the right values - ; number of events we found will be in bh, so this also clears it to zero. - - mov dx, JOY_PORT - - cli ; disable interrupts while reading time... - call joy_get_timer ; Returns counter in EAX - sti ; enable interrupts after reading time... - mov LastTick, eax - -waitforstable: in al, dx - and al, bl - jz ready ; Wait for the port in question to be done reading... - - cli ; disable interrupts while reading time... - call joy_get_timer ; Returns counter in EAX - sti ; enable interrupts after reading time... - xchg eax, LastTick - cmp eax, LastTick - jb @f - sub eax, LastTick -@@: ; Higher... - add TotalTicks, eax - cmp TotalTicks, ecx ; Timeout at 1/200'th of a second - jae ready - jmp waitforstable - -ready: - cli - mov al, 0ffh - out dx, al ; Start joystick a readin' - - call joy_get_timer ; Returns counter in EAX - mov LastTick, eax - mov TotalTicks, 0 - - mov [edi], eax ; Store initial count - add edi, 4 - - again: in al, dx ; Read Joystick port - not al - and al, bl ; Mask off channels we don't want to read - jnz flip ; See if any of the channels flipped - - call joy_get_timer ; Returns counter in EAX - - xchg eax, LastTick - cmp eax, LastTick - jb @f - sub eax, LastTick -@@: ; Higher... - add TotalTicks, eax - cmp TotalTicks, ecx ; Timeout at 1/200'th of a second - jae timedout - jmp again - - flip: and eax, 01111b ; Only care about axis values - mov [edi], eax ; Record what channel(s) flipped - add edi, 4 - xor bl, al ; Unmark the channels that just tripped - - call joy_get_timer ; Returns counter in EAX - mov [edi], eax ; Record the time this channel flipped - add edi, 4 - inc bh ; Increment number of events - - cmp bl, 0 - jne again ; If there are more channels to read, keep looping - - timedout: - movzx eax, bh ; Return number of events - - sti - ret - - -PUBLIC joy_read_stick_polled_ - -joy_read_stick_polled_: - ; ebx = read mask - ; edi = pointer to event buffer - ; ecx = timeout value - ; returns in eax the number of events - and ebx, 01111b ; Make sure we only check the right values - ; number of events we found will be in bh, so this also clears it to zero. - - mov dx, JOY_PORT - - mov TotalTicks, 0 - -waitforstable1: in al, dx - and al, bl - jz ready1 ; Wait for the port in question to be done reading... - - inc TotalTicks - cmp TotalTicks, ecx ; Timeout at 1/200'th of a second - jae ready1 - jmp waitforstable1 -ready1: - cli - mov al, 0ffh - out dx, al ; Start joystick a readin' - - mov TotalTicks, 0 - - mov dword ptr [edi], 0 ; Store initial count - add edi, 4 - - again1: in al, dx ; Read Joystick port - not al - and al, bl ; Mask off channels we don't want to read - jnz flip1 ; See if any of the channels flipped - - inc TotalTicks - cmp TotalTicks, ecx ; Timeout at 1/200'th of a second - jae timedout1 - jmp again1 - - flip1: and eax, 01111b ; Only care about axis values - mov [edi], eax ; Record what channel(s) flipped - add edi, 4 - xor bl, al ; Unmark the channels that just tripped - - mov eax, TotalTicks - mov [edi], eax ; Record the time this channel flipped - add edi, 4 - inc bh ; Increment number of events - - cmp bl, 0 - jne again1 ; If there are more channels to read, keep looping - - timedout1: - movzx eax, bh ; Return number of events - - sti - ret - -PUBLIC joy_read_stick_bios_ - -joy_read_stick_bios_: - ; ebx = read mask - ; edi = pointer to event buffer - ; ecx = timeout value - ; returns in eax the number of events - - pusha - - mov dword ptr [edi], 0 - - mov eax, 08400h - mov edx, 1 - cli - int 15h - sti - - mov dword ptr [edi+4], 1 ; Axis 1 - and eax, 0ffffh - mov [edi+8], eax ; Axis 1 value - - mov dword ptr [edi+12], 2 ; Axis 2 - and ebx, 0ffffh - mov [edi+16], ebx ; Axis 2 value - - mov dword ptr [edi+20], 4 ; Axis 3 - and ecx, 0ffffh - mov [edi+24], ecx ; Axis 3 value - - mov dword ptr [edi+28], 8 ; Axis 3 - and edx, 0ffffh - mov [edi+32], edx ; Axis 3 value - - popa - mov eax, 4 ; 4 events - - ret - - -PUBLIC joy_read_buttons_bios_ - -joy_read_buttons_bios_: - ; returns in eax the button settings - - push ebx - push ecx - push edx - mov eax, 08400h - mov edx, 0 ; Read switches - int 15h - pop edx - pop ecx - pop ebx - - shr eax, 4 - not eax - and eax, 01111b - ret - - -_TEXT ENDS - - - END +; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. +.386 + +_DATA SEGMENT BYTE PUBLIC USE32 'DATA' + +rcsid db "$Id: joy.asm,v 1.1.1.2 2001-01-19 03:33:50 bradleyb Exp $" + + LastTick dd 0 + TotalTicks dd 0 + +_DATA ENDS + +DGROUP GROUP _DATA + + +_TEXT SEGMENT BYTE PUBLIC USE32 'CODE' + + ASSUME ds:_DATA + ASSUME cs:_TEXT + + JOY_PORT EQU 0201h + TDATA EQU 40h + TCOMMAND EQU 43h + +joy_get_timer: + xor al, al ; Latch timer 0 command + out TCOMMAND, al ; Latch timer + in al, TDATA ; Read lo byte + mov ah, al + in al, TDATA ; Read hi byte + xchg ah, al + and eax, 0ffffh + ret + +PUBLIC joy_read_stick_asm_ + +joy_read_stick_asm_: + ; ebx = read mask + ; edi = pointer to event buffer + ; ecx = timeout value + ; returns in eax the number of events + and ebx, 01111b ; Make sure we only check the right values + ; number of events we found will be in bh, so this also clears it to zero. + + mov dx, JOY_PORT + + cli ; disable interrupts while reading time... + call joy_get_timer ; Returns counter in EAX + sti ; enable interrupts after reading time... + mov LastTick, eax + +waitforstable: in al, dx + and al, bl + jz ready ; Wait for the port in question to be done reading... + + cli ; disable interrupts while reading time... + call joy_get_timer ; Returns counter in EAX + sti ; enable interrupts after reading time... + xchg eax, LastTick + cmp eax, LastTick + jb @f + sub eax, LastTick +@@: ; Higher... + add TotalTicks, eax + cmp TotalTicks, ecx ; Timeout at 1/200'th of a second + jae ready + jmp waitforstable + +ready: + cli + mov al, 0ffh + out dx, al ; Start joystick a readin' + + call joy_get_timer ; Returns counter in EAX + mov LastTick, eax + mov TotalTicks, 0 + + mov [edi], eax ; Store initial count + add edi, 4 + + again: in al, dx ; Read Joystick port + not al + and al, bl ; Mask off channels we don't want to read + jnz flip ; See if any of the channels flipped + + call joy_get_timer ; Returns counter in EAX + + xchg eax, LastTick + cmp eax, LastTick + jb @f + sub eax, LastTick +@@: ; Higher... + add TotalTicks, eax + cmp TotalTicks, ecx ; Timeout at 1/200'th of a second + jae timedout + jmp again + + flip: and eax, 01111b ; Only care about axis values + mov [edi], eax ; Record what channel(s) flipped + add edi, 4 + xor bl, al ; Unmark the channels that just tripped + + call joy_get_timer ; Returns counter in EAX + mov [edi], eax ; Record the time this channel flipped + add edi, 4 + inc bh ; Increment number of events + + cmp bl, 0 + jne again ; If there are more channels to read, keep looping + + timedout: + movzx eax, bh ; Return number of events + + sti + ret + + +PUBLIC joy_read_stick_polled_ + +joy_read_stick_polled_: + ; ebx = read mask + ; edi = pointer to event buffer + ; ecx = timeout value + ; returns in eax the number of events + and ebx, 01111b ; Make sure we only check the right values + ; number of events we found will be in bh, so this also clears it to zero. + + mov dx, JOY_PORT + + mov TotalTicks, 0 + +waitforstable1: in al, dx + and al, bl + jz ready1 ; Wait for the port in question to be done reading... + + inc TotalTicks + cmp TotalTicks, ecx ; Timeout at 1/200'th of a second + jae ready1 + jmp waitforstable1 +ready1: + cli + mov al, 0ffh + out dx, al ; Start joystick a readin' + + mov TotalTicks, 0 + + mov dword ptr [edi], 0 ; Store initial count + add edi, 4 + + again1: in al, dx ; Read Joystick port + not al + and al, bl ; Mask off channels we don't want to read + jnz flip1 ; See if any of the channels flipped + + inc TotalTicks + cmp TotalTicks, ecx ; Timeout at 1/200'th of a second + jae timedout1 + jmp again1 + + flip1: and eax, 01111b ; Only care about axis values + mov [edi], eax ; Record what channel(s) flipped + add edi, 4 + xor bl, al ; Unmark the channels that just tripped + + mov eax, TotalTicks + mov [edi], eax ; Record the time this channel flipped + add edi, 4 + inc bh ; Increment number of events + + cmp bl, 0 + jne again1 ; If there are more channels to read, keep looping + + timedout1: + movzx eax, bh ; Return number of events + + sti + ret + +PUBLIC joy_read_stick_bios_ + +joy_read_stick_bios_: + ; ebx = read mask + ; edi = pointer to event buffer + ; ecx = timeout value + ; returns in eax the number of events + + pusha + + mov dword ptr [edi], 0 + + mov eax, 08400h + mov edx, 1 + cli + int 15h + sti + + mov dword ptr [edi+4], 1 ; Axis 1 + and eax, 0ffffh + mov [edi+8], eax ; Axis 1 value + + mov dword ptr [edi+12], 2 ; Axis 2 + and ebx, 0ffffh + mov [edi+16], ebx ; Axis 2 value + + mov dword ptr [edi+20], 4 ; Axis 3 + and ecx, 0ffffh + mov [edi+24], ecx ; Axis 3 value + + mov dword ptr [edi+28], 8 ; Axis 3 + and edx, 0ffffh + mov [edi+32], edx ; Axis 3 value + + popa + mov eax, 4 ; 4 events + + ret + + +PUBLIC joy_read_buttons_bios_ + +joy_read_buttons_bios_: + ; returns in eax the button settings + + push ebx + push ecx + push edx + mov eax, 08400h + mov edx, 0 ; Read switches + int 15h + pop edx + pop ecx + pop ebx + + shr eax, 4 + not eax + and eax, 01111b + ret + + +_TEXT ENDS + + + END diff --git a/unused/bios/key.asm b/unused/bios/key.asm index b7eb31fe..905f8f82 100644 --- a/unused/bios/key.asm +++ b/unused/bios/key.asm @@ -1,906 +1,906 @@ -; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX -; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO -; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A -; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS -; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS -; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE -; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE -; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS -; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. -; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. -;*************************************************************************** -;*************************************************************************** -;***** ***** -;***** ***** -;***** K E Y . A S M ***** -;***** ***** -;***** Contains routines to get, buffer, and check key presses. ***** -;***** ***** -;***** ***** -;***** PROCEDURES ***** -;***** ***** -;***** key_init() - Activates the keyboard package. ***** -;***** key_close() - Deactivates the keyboard package. ***** -;***** key_check() - Returns 1 if a buffered key is waiting. ***** -;***** key_getch() - Waits for and returns a buffered keypress. ***** -;***** key_flush() - Clears buffers and state array. ***** -;***** key_time() - Index by scan code. Contains the time key has been ***** -;***** held down. NOT DONE YET. ***** -;***** ***** -;***** ***** -;***** VARIABLES ***** -;***** ***** -;***** keyd_buffer_type -Set to 0 and key_getch() always returns 0. ***** -;***** Set to 1 to so that ASCII codes are returned ***** -;***** by key_getch(). Set to 2 and key_getch() returns***** -;***** the buffered keyboard scan codes. ***** -;***** keyd_repeat - Set to 0 to not allow repeated keys in the ***** -;***** keyboard buffer. Set to 1 to allow repeats. ***** -;***** keyd_pressed[] -Index by scan code. Contains 1 if key down else 0***** -;***** ***** -;***** ***** -;***** CONSTANTS ***** -;***** ***** -;***** Setting the DEBUG to 1 at compile time passes SysReq through ***** -;***** to the debugger, and when the debugger is active, it will give ***** -;***** the debugger any keys that are pressed. Note that this only ***** -;***** works with the Watcom VIDEO debugger at this time. Setting ***** -;***** DEBUG to 0 takes out all the debugging stuff. ***** -;***** ***** -;*************************************************************************** -;*************************************************************************** - -DEBUG EQU 1 -.386 - -;************************************************************************ -;**************** FLAT MODEL DATA SEGMENT STUFF ************************* -;************************************************************************ - -_DATA SEGMENT BYTE PUBLIC USE32 'DATA' - -rcsid db "$Id: key.asm,v 1.1.1.1 2001-01-19 03:30:14 bradleyb Exp $" - -PUBLIC _keyd_pressed ; Must start with a _ so C can see the variable. - - _keyd_pressed db 256 dup (?) - - keybuffer dw 256 dup (?) ; Use 256 so an inc wraps around - - TimeKeyWentDown dd 256 dup(0) - TimeKeyHeldDown dd 256 dup(0) - NumDowns dd 256 dup(0) - NumUps dd 256 dup(0) - - MyCodeSegment dw ? - -PUBLIC _keyd_last_pressed - _keyd_last_pressed db 0 -PUBLIC _keyd_last_released - _keyd_last_released db 0 - - org_int_sel dw ? - org_int_off dd ? - keyhead db ? - keytail db ? -PUBLIC _keyd_buffer_type -PUBLIC _keyd_repeat - _keyd_buffer_type db ? ; 0=No buffer, 1=buffer ASCII, 2=buffer scans - _keyd_repeat db ? - - E0Flag db 0 - - Installed db 0 - -INCLUDE KEYS.INC - - -_DATA ENDS - -DGROUP GROUP _DATA - - -;************************************************************************ -;**************** FLAT MODEL CODE SEGMENT STUFF ************************* -;************************************************************************ - -_TEXT SEGMENT BYTE PUBLIC USE32 'CODE' - - ASSUME ds:_DATA - ASSUME cs:_TEXT - - -;************************************************************************ -;************************************************************************ -;***** ***** -;***** K E Y _ T O _ A S C I I _ ***** -;***** ***** -;************************************************************************ -;************************************************************************ - -PUBLIC key_to_ascii_ - -key_to_ascii_: - - ; EAX = scancode - push ebx - - mov bl, ah - and bl, 011111110b - cmp bl, 0 - jne CantDoKey - - cmp al, 127 - jae CantDoKey - - and ah, 01b ; take away ctrl and alt codes - shl al, 1 - shr eax, 1 - and eax, 0ffh - mov al, byte ptr key1[eax] - pop ebx - ret - -CantDoKey: - pop ebx - mov eax, 255 - ret - - -public key_clear_times_,key_clear_counts_ - -;clear the array of key down times. -key_clear_times_: push eax - push ecx - push edi - xor eax,eax - mov ecx,256 - lea edi,TimeKeyHeldDown - rep stosd ;clear array - pop edi - pop ecx - pop eax - ret - -;clear the arrays of key down counts -key_clear_counts_: push eax - push ecx - push edi - xor eax,eax - mov ecx,256 - lea edi,NumDowns - rep stosd ;clear array - mov ecx,256 - lea edi,NumUps - rep stosd ;clear array - pop edi - pop ecx - pop eax - ret - - -PUBLIC key_down_time_ - -key_down_time_: - - EXTERNDEF timer_get_milliseconds_:NEAR - - push edx - push ecx - push ebx - - mov ebx, eax - xor eax, eax - - cmp _keyd_pressed[ebx], 0 - je NotPressed - - call get_modifiers ;shift,alt,ctrl? - or ah,ah - jz read_time - xor eax,eax - jmp NotPressed -read_time: - - mov ecx, TimeKeyWentDown[ebx*4] - cli - call timer_get_milliseconds_ - mov TimeKeyWentDown[ebx*4], eax - sub eax, ecx ; EAX = time held since last - -NotPressed: - add eax, TimeKeyHeldDown[ebx*4] - mov TimeKeyHeldDown[ebx*4], 0 - - sti - pop ebx - pop ecx - pop edx - ret - -PUBLIC key_down_count_ -key_down_count_: - push ebx - mov ebx, eax - cli - mov eax, NumDowns[ebx*4] - mov NumDowns[ebx*4], 0 - sti - pop ebx - ret - -PUBLIC key_up_count_ -key_up_count_: - push ebx - mov ebx, eax - cli - mov eax, NumUps[ebx*4] - mov NumUps[ebx*4], 0 - sti - pop ebx - ret - - - -;************************************************************************ -;************************************************************************ -;***** ***** -;***** K E Y _ F L U S H ***** -;***** ***** -;************************************************************************ -;************************************************************************ - -PUBLIC key_flush_ - -key_flush_: - push eax - push ecx - push edi - - cli - mov keyhead,0 - mov keytail,255 - mov E0Flag, 0 - - ; Clear the keyboard array - mov edi, offset _keyd_pressed - mov ecx, 32 - mov eax,0 - rep stosd - sti - - pop edi - pop ecx - pop eax - ret - -;************************************************************************ -;************************************************************************ -;***** ***** -;***** K E Y _ I N I T ***** -;***** ***** -;************************************************************************ -;************************************************************************ - -PUBLIC key_init_ - -key_init_: - push eax - push ebx - push ds - push es - - ;************************************************************** - ;******************* INITIALIZE key QUEUE ********************** - ;************************************************************** - - - mov _keyd_buffer_type,1 - mov _keyd_repeat,1 - mov E0Flag, 0 - - ; Clear the keyboard array - call key_flush_ - - - cmp Installed, 0 - jne AlreadyInstalled - - ;************************************************************** - ;******************* SAVE OLD INT9 HANDLER ******************** - ;************************************************************** - - mov Installed, 1 - - mov eax, 03509h ; DOS Get Vector 09h - int 21h ; Call DOS - mov org_int_sel, es ; Save old interrupt selector - mov org_int_off, ebx ; Save old interrupt offset - - - ;************************************************************** - ;***************** INSTALL NEW INT9 HANDLER ******************* - ;************************************************************** - - mov eax, 02509h ; DOS Set Vector 09h - mov edx, offset key_handler ; Point DS:EDX to new handler - mov bx, cs - mov MyCodeSegment, bx - mov ds, bx - int 21h - - -AlreadyInstalled: - - pop es - pop ds - pop ebx - pop eax - - ret - - -;************************************************************************ -;************************************************************************ -;***** ***** -;***** K E Y _ C L O S E _ ***** -;***** ***** -;************************************************************************ -;************************************************************************ - -PUBLIC key_close_ - -key_close_: - push eax - push ebx - push edx - push ds - - - cmp Installed, 0 - je @f - - ;************************************************************** - ;***************** RESTORE OLD INT9 HANDLER ******************* - ;************************************************************** - - mov Installed, 0 - - ; Clear the BIOS buffer - mov ebx, 041ch - mov al, byte ptr [ebx] - mov ebx, 041ah - mov byte ptr [ebx], al - - mov eax, 02509h ; DOS Set Vector 09h - mov edx, org_int_off - mov ds, org_int_sel - int 21h - -@@: pop ds - pop edx - pop ebx - pop eax - - ret - -;************************************************************************ -;************************************************************************ -;***** ***** -;***** K E Y _ C H E C K _ ***** -;***** ***** -;************************************************************************ -;************************************************************************ - -PUBLIC key_checkch_ ; Must end with a _ so C can see the function. - -key_checkch_: - push ebx - - xor eax, eax - cmp Installed, 0 - je NoKey - - cli - mov bl, keytail - inc bl - cmp bl, keyhead - je Nokey - mov eax, 1 - -Nokey: - sti - pop ebx - ret - -;************************************************************************ -;************************************************************************ -;***** ***** -;***** K E Y _ D E B U G ***** -;***** ***** -;************************************************************************ -;************************************************************************ - -PUBLIC key_debug_ -key_debug_: - int 3h - ret - - -;************************************************************************ -;************************************************************************ -;***** ***** -;***** K E Y _ G E T C H _ ***** -;***** ***** -;************************************************************************ -;************************************************************************ - -PUBLIC key_getch_ ; Must end with a _ so C can see the function. - -key_getch_: - push ebx - - xor eax, eax - xor ebx, ebx - cmp Installed, 0 - jne StillNoKey - pop ebx - ret - -StillNoKey: - cli ; Critical section - mov bl, keytail - inc bl - cmp bl, keyhead - sti - je StillNoKey - - cli ; Critical section - xor ebx, ebx - mov bl, keyhead - mov ax, word ptr keybuffer[ebx*2] - inc BYTE PTR keyhead - sti - - pop ebx - ret - - -;************************************************************************ -;************************************************************************ -;***** ***** -;***** K E Y _ I N K E Y _ ***** -;***** ***** -;************************************************************************ -;************************************************************************ - -PUBLIC key_inkey_ ; Must end with a _ so C can see the function. - -key_inkey_: - push ebx - - xor eax, eax - xor ebx, ebx - - cmp Installed, 0 - je NoInkey - - cli ; Critical section - mov bl, keytail - inc bl - cmp bl, keyhead - sti - je NoInkey - - cli ; Critical section - mov bl, keyhead - mov ax, word ptr keybuffer[ebx*2] - inc BYTE PTR keyhead - sti -NoInkey: - pop ebx - ret - -PUBLIC key_peekkey_ ; Must end with a _ so C can see the function. - -key_peekkey_: - push ebx - - xor eax, eax - xor ebx, ebx - - cmp Installed, 0 - je NoPeek - - cli ; Critical section - mov bl, keytail - inc bl - cmp bl, keyhead - sti - je NoPeek - - cli ; Critical section - mov bl, keyhead - mov ax, word ptr keybuffer[ebx*2] - sti -NoPeek: - pop ebx - ret - - - -;************************************************************************ -;************************************************************************ -;***** ***** -;***** K E Y _ H A N D L E R ***** -;***** ***** -;************************************************************************ -;************************************************************************ - -PUBLIC key_handler ; Must end with a _ so C can see the function. - -key_handler: - EXTERNDEF timer_get_milliseconds_:NEAR - - pushfd ; Save flags in case we have to chain to original - push eax - push ebx - push ecx - push edx - push ds - - mov ax, DGROUP ; Point to our data segment, since this is an - mov ds, ax ; interrupt and we don't know where we were. - -IFDEF DEBUG - call CheckForDebugger - jnc @f - mov eax, 0b0000h+78*2 - mov byte ptr [eax], 'D' - jmp SkipBuffer ; If debugger is active, then skip buffer -@@: mov eax, 0b0000h+78*2 - mov byte ptr [eax], 'I' - - ; Clear the BIOS buffer - mov ebx, 041ch - mov al, byte ptr [ebx] - mov ebx, 041ah - mov byte ptr [ebx], al -ENDIF - - ;************************************************************** - ;****************** READ IN THE SCAN CODE ********************* - ;************************************************************** - ; Reads the scan code from the keyboard and masks off the - ; scan code and puts it in EAX. - - xor eax, eax - in al, 060h ; Get scan code from keyboard - - cmp al, 0E0h - jne NotE0Code - -E0Code: - mov E0Flag, 128 - jmp SkipBuffer - -NotE0Code: - mov bl,al ; Save scan code in BL - and bl,01111111b - add bl, E0Flag - mov E0Flag,0 - xor bh,bh ; clear for index use - and al,10000000b ; keep break bit, if set - xor al,10000000b ; flip bit - 1 means pressed - ; - 0 means released - rol al,1 ; put it in bit 0 - xchg ax, bx - - ; AX = Key code - ; BX = 1 if pressed, 0 if released. - cmp bx, 1 - je pkeyDown - - ;************************************************************** - ;******************* HANDLE A RELEASED KEY ******************** - ;************************************************************** - ; Unmarks the key press in EAX from the scancode array. - - - mov _keyd_last_released, al - mov byte ptr _keyd_pressed[eax], 0 - inc NumUps[eax*4] - - push eax - xor ah,ah - call get_modifiers - or ah,ah ;check modifiers - pop eax - jnz skip_time - - push edx - push eax - call timer_get_milliseconds_ - mov edx, eax - pop eax - sub edx, TimeKeyWentDown[eax*4] - add TimeKeyHeldDown[eax*4], edx - pop edx -skip_time: - - jmp pdone - -pkeyDown: - - ;************************************************************** - ;****************** HANDLE A NEWLY PRESSED KEY **************** - ;************************************************************** - ;Marks the key press in EAX in the scancode array. - - - mov _keyd_last_pressed, al - ; Check if the key is repeating or if it just got pressed. - cmp byte ptr _keyd_pressed[eax], 1 - je AlreadyDown - - mov byte ptr _keyd_pressed[eax], 1 - ; Set the time - - push edx - push eax - call timer_get_milliseconds_ - mov edx, eax - pop eax - mov TimeKeyWentDown[eax*4], edx - pop edx - - inc NumDowns[eax*4] - - jmp TryBuffer - - ;************************************************************** - ;******************** HANDLE A PRESSED KEY ******************** - ;************************************************************** - ; Adds key scan code in EAX to the keybuffer array. - -AlreadyDown: - cmp _keyd_repeat, 0 - je SkipBuffer - -TryBuffer: - cmp _keyd_buffer_type, 0 - je SkipBuffer ; Buffer = 0 means don't buffer anything. - - ; Dont buffer shift, ctrl, or alt keys. - ;cmp al, 02ah ; Right Shift - ;je SkipBuffer - ;cmp al, 036h ; Left Shift - ;je SkipBuffer - ;cmp al, 038h ; Left Alt - ;je SkipBuffer - ;cmp al, 0b8h ; Right Alt - ;je SkipBuffer - ;cmp al, 01dh ; Left Ctrl - ;je SkipBuffer - ;cmp al, 09dh ' Right Ctrl - ;je SkipBuffer - - cmp al, 0AAh ; garbage key - je SkipBuffer - - call get_modifiers ;returns ah - -BufferAX: - - xor ebx, ebx - mov bl, keytail - inc bl - inc bl - - ; If the buffer is full then don't buffer this key - cmp bl, keyhead - je SkipBuffer - dec bl - - mov word ptr keybuffer[ebx*2], ax - mov keytail, bl - -SkipBuffer: - -pdone: - - -;************************************************************** -;*************** FINISH UP THE KEYBOARD INTERRUPT ************* -;************************************************************** - -; If in debugger, pass control to dos interrupt. -IFDEF DEBUG - pop ds ; Nothing left on stack but flags - pop edx - pop ecx - pop ebx - pop eax - - sub esp, 8 ; Save space for IRETD frame - push ds ; Save registers we use. - push eax - mov ax, DGROUP - mov ds, ax ; Set DS to our data segment - mov eax, org_int_off ; put original handler address - mov [esp+8], eax ; in the IRETD frame - movzx eax, org_int_sel - mov [esp+12], eax - pop eax ; Restore registers - pop ds - iretd ; Chain to previous handler -ENDIF - -; Resets the keyboard, PIC, restores stack, returns. - in al, 61h ; Get current port 61h state - or al, 10000000b ; Turn on bit 7 to signal clear keybrd - out 61h, al ; Send to port - and al, 01111111b ; Turn off bit 7 to signal break - out 61h, al ; Send to port - mov al, 20h ; Reset interrupt controller - out 20h, al - sti ; Reenable interrupts - pop ds - pop edx ; Restore all of the saved registers. - pop ecx - pop ebx - pop eax - popfd - iretd ; Interrupt must return with IRETD - -;returns ah=bitmask of shift,ctrl,alt keys -get_modifiers: push ecx - - xor ah,ah - - ; Check the shift keys - mov cl, _keyd_pressed[ 036h ] - or cl, _keyd_pressed[ 02ah ] - or ah, cl - - ; Check the alt key - mov cl, _keyd_pressed[ 038h ] - or cl, _keyd_pressed[ 0b8h ] - shl cl, 1 - or ah, cl - - ; Check the ctrl key - mov cl, _keyd_pressed[ 01dh ] - or cl, _keyd_pressed[ 09dh ] - shl cl, 2 - or ah, cl - - pop ecx - ret - -IFDEF DEBUG -CheckForDebugger: - ; Returns CF=0 if debugger isn't active - ; CF=1 if debugger is active - - ;*************************** DEBUG ****************************** - ; When we're in the VIDEO debugger, we want to pass control to - ; the original interrupt. So, to tell if the debugger is active, - ; I check if video page 1 is the active page since that is what - ; page the debugger uses, and if that works, I check the top of - ; the screen to see if the texxt "Control" is there, which should - ; only be there when we're in the debugger. - - push eax - ;mov eax, 0462h ; Address 0462 stores BIOS current page - ;cmp BYTE PTR [eax], 1 - ;jne NoDebuggerOnColor - ;mov eax, 0b8000h+4096 ; 4096 = offset to 2nd video mem page - ;cmp BYTE PTR [eax+2],'C' - ;jne NoDebuggerOnColor - ;cmp BYTE PTR [eax+4],'o' - ;jne NoDebuggerOnColor - ;cmp BYTE PTR [eax+6],'n' - ;jne NoDebuggerOnColor - ;cmp BYTE PTR [eax+8],'t' - ;jne NoDebuggerOnColor - ;cmp BYTE PTR [eax+10],'r' - ;jne NoDebuggerOnColor - ;cmp BYTE PTR [eax+12],'o' - ;jne NoDebuggerOnColor - ;cmp BYTE PTR [eax+14],'l' - ;jne NoDebuggerOnColor - ;jmp ActiveDebugger - ;NoDebuggerOnColor: - ; First, see if there is a mono debugger... - - ;mov eax, 0b0000h ; 4096 = offset to mono video mem - ;cmp BYTE PTR [eax+2],'C' - ;jne NoActiveDebugger - ;cmp BYTE PTR [eax+4],'o' - ;jne NoActiveDebugger - ;cmp BYTE PTR [eax+6],'n' - ;jne NoActiveDebugger - ;cmp BYTE PTR [eax+8],'t' - ;jne NoActiveDebugger - ;cmp BYTE PTR [eax+10],'r' - ;jne NoActiveDebugger - ;cmp BYTE PTR [eax+12],'o' - ;jne NoActiveDebugger - ;cmp BYTE PTR [eax+14],'l' - ;jne NoActiveDebugger - - mov eax, 0b0000h ; 4096 = offset to mono video mem - add eax, 24*80*2 - - - cmp BYTE PTR [eax+0],'D' - jne NextTest - cmp BYTE PTR [eax+2],'B' - jne NextTest - cmp BYTE PTR [eax+4],'G' - jne NextTest - cmp BYTE PTR [eax+6],'>' - jne NextTest - - ;Found DBG>, so consider debugger active: - jmp ActiveDebugger - -NextTest: - cmp BYTE PTR [eax+14],'<' - jne NextTest1 - cmp BYTE PTR [eax+16],'i' - jne NextTest1 - cmp BYTE PTR [eax+18],'>' - jne NextTest1 - cmp BYTE PTR [eax+20],' ' - jne NextTest1 - cmp BYTE PTR [eax+22],'-' - jne NextTest1 - - ; Found - , so consider debugger active: - jmp ActiveDebugger - -NextTest1: - cmp BYTE PTR [eax+0], 200 - jne NextTest2 - cmp BYTE PTR [eax+2], 27 - jne NextTest2 - cmp BYTE PTR [eax+4], 17 - jne NextTest2 - - ; Found either the help screen or view screen, so consider - ; debugger active - jmp ActiveDebugger - -NextTest2: - ; Now we see if its active by looking for the "Executing..." - ; text on the bottom of the mono screen - ;mov eax, 0b0000h ; 4096 = offset to mono video mem - ;add eax, 24*80*2 - ;cmp BYTE PTR [eax+0],'E' - ;je NoActiveDebugger - ;cmp BYTE PTR [eax+2],'x' - ;je NoActiveDebugger - ;cmp BYTE PTR [eax+4],'e' - ;je NoActiveDebugger - ;cmp BYTE PTR [eax+6],'c' - ;je NoActiveDebugger - -NoActiveDebugger: - pop eax - clc - ret - -ActiveDebugger: - pop eax - stc - ret - -ENDIF - -_TEXT ENDS - - END - - +; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. +;*************************************************************************** +;*************************************************************************** +;***** ***** +;***** ***** +;***** K E Y . A S M ***** +;***** ***** +;***** Contains routines to get, buffer, and check key presses. ***** +;***** ***** +;***** ***** +;***** PROCEDURES ***** +;***** ***** +;***** key_init() - Activates the keyboard package. ***** +;***** key_close() - Deactivates the keyboard package. ***** +;***** key_check() - Returns 1 if a buffered key is waiting. ***** +;***** key_getch() - Waits for and returns a buffered keypress. ***** +;***** key_flush() - Clears buffers and state array. ***** +;***** key_time() - Index by scan code. Contains the time key has been ***** +;***** held down. NOT DONE YET. ***** +;***** ***** +;***** ***** +;***** VARIABLES ***** +;***** ***** +;***** keyd_buffer_type -Set to 0 and key_getch() always returns 0. ***** +;***** Set to 1 to so that ASCII codes are returned ***** +;***** by key_getch(). Set to 2 and key_getch() returns***** +;***** the buffered keyboard scan codes. ***** +;***** keyd_repeat - Set to 0 to not allow repeated keys in the ***** +;***** keyboard buffer. Set to 1 to allow repeats. ***** +;***** keyd_pressed[] -Index by scan code. Contains 1 if key down else 0***** +;***** ***** +;***** ***** +;***** CONSTANTS ***** +;***** ***** +;***** Setting the DEBUG to 1 at compile time passes SysReq through ***** +;***** to the debugger, and when the debugger is active, it will give ***** +;***** the debugger any keys that are pressed. Note that this only ***** +;***** works with the Watcom VIDEO debugger at this time. Setting ***** +;***** DEBUG to 0 takes out all the debugging stuff. ***** +;***** ***** +;*************************************************************************** +;*************************************************************************** + +DEBUG EQU 1 +.386 + +;************************************************************************ +;**************** FLAT MODEL DATA SEGMENT STUFF ************************* +;************************************************************************ + +_DATA SEGMENT BYTE PUBLIC USE32 'DATA' + +rcsid db "$Id: key.asm,v 1.1.1.2 2001-01-19 03:33:50 bradleyb Exp $" + +PUBLIC _keyd_pressed ; Must start with a _ so C can see the variable. + + _keyd_pressed db 256 dup (?) + + keybuffer dw 256 dup (?) ; Use 256 so an inc wraps around + + TimeKeyWentDown dd 256 dup(0) + TimeKeyHeldDown dd 256 dup(0) + NumDowns dd 256 dup(0) + NumUps dd 256 dup(0) + + MyCodeSegment dw ? + +PUBLIC _keyd_last_pressed + _keyd_last_pressed db 0 +PUBLIC _keyd_last_released + _keyd_last_released db 0 + + org_int_sel dw ? + org_int_off dd ? + keyhead db ? + keytail db ? +PUBLIC _keyd_buffer_type +PUBLIC _keyd_repeat + _keyd_buffer_type db ? ; 0=No buffer, 1=buffer ASCII, 2=buffer scans + _keyd_repeat db ? + + E0Flag db 0 + + Installed db 0 + +INCLUDE KEYS.INC + + +_DATA ENDS + +DGROUP GROUP _DATA + + +;************************************************************************ +;**************** FLAT MODEL CODE SEGMENT STUFF ************************* +;************************************************************************ + +_TEXT SEGMENT BYTE PUBLIC USE32 'CODE' + + ASSUME ds:_DATA + ASSUME cs:_TEXT + + +;************************************************************************ +;************************************************************************ +;***** ***** +;***** K E Y _ T O _ A S C I I _ ***** +;***** ***** +;************************************************************************ +;************************************************************************ + +PUBLIC key_to_ascii_ + +key_to_ascii_: + + ; EAX = scancode + push ebx + + mov bl, ah + and bl, 011111110b + cmp bl, 0 + jne CantDoKey + + cmp al, 127 + jae CantDoKey + + and ah, 01b ; take away ctrl and alt codes + shl al, 1 + shr eax, 1 + and eax, 0ffh + mov al, byte ptr key1[eax] + pop ebx + ret + +CantDoKey: + pop ebx + mov eax, 255 + ret + + +public key_clear_times_,key_clear_counts_ + +;clear the array of key down times. +key_clear_times_: push eax + push ecx + push edi + xor eax,eax + mov ecx,256 + lea edi,TimeKeyHeldDown + rep stosd ;clear array + pop edi + pop ecx + pop eax + ret + +;clear the arrays of key down counts +key_clear_counts_: push eax + push ecx + push edi + xor eax,eax + mov ecx,256 + lea edi,NumDowns + rep stosd ;clear array + mov ecx,256 + lea edi,NumUps + rep stosd ;clear array + pop edi + pop ecx + pop eax + ret + + +PUBLIC key_down_time_ + +key_down_time_: + + EXTERNDEF timer_get_milliseconds_:NEAR + + push edx + push ecx + push ebx + + mov ebx, eax + xor eax, eax + + cmp _keyd_pressed[ebx], 0 + je NotPressed + + call get_modifiers ;shift,alt,ctrl? + or ah,ah + jz read_time + xor eax,eax + jmp NotPressed +read_time: + + mov ecx, TimeKeyWentDown[ebx*4] + cli + call timer_get_milliseconds_ + mov TimeKeyWentDown[ebx*4], eax + sub eax, ecx ; EAX = time held since last + +NotPressed: + add eax, TimeKeyHeldDown[ebx*4] + mov TimeKeyHeldDown[ebx*4], 0 + + sti + pop ebx + pop ecx + pop edx + ret + +PUBLIC key_down_count_ +key_down_count_: + push ebx + mov ebx, eax + cli + mov eax, NumDowns[ebx*4] + mov NumDowns[ebx*4], 0 + sti + pop ebx + ret + +PUBLIC key_up_count_ +key_up_count_: + push ebx + mov ebx, eax + cli + mov eax, NumUps[ebx*4] + mov NumUps[ebx*4], 0 + sti + pop ebx + ret + + + +;************************************************************************ +;************************************************************************ +;***** ***** +;***** K E Y _ F L U S H ***** +;***** ***** +;************************************************************************ +;************************************************************************ + +PUBLIC key_flush_ + +key_flush_: + push eax + push ecx + push edi + + cli + mov keyhead,0 + mov keytail,255 + mov E0Flag, 0 + + ; Clear the keyboard array + mov edi, offset _keyd_pressed + mov ecx, 32 + mov eax,0 + rep stosd + sti + + pop edi + pop ecx + pop eax + ret + +;************************************************************************ +;************************************************************************ +;***** ***** +;***** K E Y _ I N I T ***** +;***** ***** +;************************************************************************ +;************************************************************************ + +PUBLIC key_init_ + +key_init_: + push eax + push ebx + push ds + push es + + ;************************************************************** + ;******************* INITIALIZE key QUEUE ********************** + ;************************************************************** + + + mov _keyd_buffer_type,1 + mov _keyd_repeat,1 + mov E0Flag, 0 + + ; Clear the keyboard array + call key_flush_ + + + cmp Installed, 0 + jne AlreadyInstalled + + ;************************************************************** + ;******************* SAVE OLD INT9 HANDLER ******************** + ;************************************************************** + + mov Installed, 1 + + mov eax, 03509h ; DOS Get Vector 09h + int 21h ; Call DOS + mov org_int_sel, es ; Save old interrupt selector + mov org_int_off, ebx ; Save old interrupt offset + + + ;************************************************************** + ;***************** INSTALL NEW INT9 HANDLER ******************* + ;************************************************************** + + mov eax, 02509h ; DOS Set Vector 09h + mov edx, offset key_handler ; Point DS:EDX to new handler + mov bx, cs + mov MyCodeSegment, bx + mov ds, bx + int 21h + + +AlreadyInstalled: + + pop es + pop ds + pop ebx + pop eax + + ret + + +;************************************************************************ +;************************************************************************ +;***** ***** +;***** K E Y _ C L O S E _ ***** +;***** ***** +;************************************************************************ +;************************************************************************ + +PUBLIC key_close_ + +key_close_: + push eax + push ebx + push edx + push ds + + + cmp Installed, 0 + je @f + + ;************************************************************** + ;***************** RESTORE OLD INT9 HANDLER ******************* + ;************************************************************** + + mov Installed, 0 + + ; Clear the BIOS buffer + mov ebx, 041ch + mov al, byte ptr [ebx] + mov ebx, 041ah + mov byte ptr [ebx], al + + mov eax, 02509h ; DOS Set Vector 09h + mov edx, org_int_off + mov ds, org_int_sel + int 21h + +@@: pop ds + pop edx + pop ebx + pop eax + + ret + +;************************************************************************ +;************************************************************************ +;***** ***** +;***** K E Y _ C H E C K _ ***** +;***** ***** +;************************************************************************ +;************************************************************************ + +PUBLIC key_checkch_ ; Must end with a _ so C can see the function. + +key_checkch_: + push ebx + + xor eax, eax + cmp Installed, 0 + je NoKey + + cli + mov bl, keytail + inc bl + cmp bl, keyhead + je Nokey + mov eax, 1 + +Nokey: + sti + pop ebx + ret + +;************************************************************************ +;************************************************************************ +;***** ***** +;***** K E Y _ D E B U G ***** +;***** ***** +;************************************************************************ +;************************************************************************ + +PUBLIC key_debug_ +key_debug_: + int 3h + ret + + +;************************************************************************ +;************************************************************************ +;***** ***** +;***** K E Y _ G E T C H _ ***** +;***** ***** +;************************************************************************ +;************************************************************************ + +PUBLIC key_getch_ ; Must end with a _ so C can see the function. + +key_getch_: + push ebx + + xor eax, eax + xor ebx, ebx + cmp Installed, 0 + jne StillNoKey + pop ebx + ret + +StillNoKey: + cli ; Critical section + mov bl, keytail + inc bl + cmp bl, keyhead + sti + je StillNoKey + + cli ; Critical section + xor ebx, ebx + mov bl, keyhead + mov ax, word ptr keybuffer[ebx*2] + inc BYTE PTR keyhead + sti + + pop ebx + ret + + +;************************************************************************ +;************************************************************************ +;***** ***** +;***** K E Y _ I N K E Y _ ***** +;***** ***** +;************************************************************************ +;************************************************************************ + +PUBLIC key_inkey_ ; Must end with a _ so C can see the function. + +key_inkey_: + push ebx + + xor eax, eax + xor ebx, ebx + + cmp Installed, 0 + je NoInkey + + cli ; Critical section + mov bl, keytail + inc bl + cmp bl, keyhead + sti + je NoInkey + + cli ; Critical section + mov bl, keyhead + mov ax, word ptr keybuffer[ebx*2] + inc BYTE PTR keyhead + sti +NoInkey: + pop ebx + ret + +PUBLIC key_peekkey_ ; Must end with a _ so C can see the function. + +key_peekkey_: + push ebx + + xor eax, eax + xor ebx, ebx + + cmp Installed, 0 + je NoPeek + + cli ; Critical section + mov bl, keytail + inc bl + cmp bl, keyhead + sti + je NoPeek + + cli ; Critical section + mov bl, keyhead + mov ax, word ptr keybuffer[ebx*2] + sti +NoPeek: + pop ebx + ret + + + +;************************************************************************ +;************************************************************************ +;***** ***** +;***** K E Y _ H A N D L E R ***** +;***** ***** +;************************************************************************ +;************************************************************************ + +PUBLIC key_handler ; Must end with a _ so C can see the function. + +key_handler: + EXTERNDEF timer_get_milliseconds_:NEAR + + pushfd ; Save flags in case we have to chain to original + push eax + push ebx + push ecx + push edx + push ds + + mov ax, DGROUP ; Point to our data segment, since this is an + mov ds, ax ; interrupt and we don't know where we were. + +IFDEF DEBUG + call CheckForDebugger + jnc @f + mov eax, 0b0000h+78*2 + mov byte ptr [eax], 'D' + jmp SkipBuffer ; If debugger is active, then skip buffer +@@: mov eax, 0b0000h+78*2 + mov byte ptr [eax], 'I' + + ; Clear the BIOS buffer + mov ebx, 041ch + mov al, byte ptr [ebx] + mov ebx, 041ah + mov byte ptr [ebx], al +ENDIF + + ;************************************************************** + ;****************** READ IN THE SCAN CODE ********************* + ;************************************************************** + ; Reads the scan code from the keyboard and masks off the + ; scan code and puts it in EAX. + + xor eax, eax + in al, 060h ; Get scan code from keyboard + + cmp al, 0E0h + jne NotE0Code + +E0Code: + mov E0Flag, 128 + jmp SkipBuffer + +NotE0Code: + mov bl,al ; Save scan code in BL + and bl,01111111b + add bl, E0Flag + mov E0Flag,0 + xor bh,bh ; clear for index use + and al,10000000b ; keep break bit, if set + xor al,10000000b ; flip bit - 1 means pressed + ; - 0 means released + rol al,1 ; put it in bit 0 + xchg ax, bx + + ; AX = Key code + ; BX = 1 if pressed, 0 if released. + cmp bx, 1 + je pkeyDown + + ;************************************************************** + ;******************* HANDLE A RELEASED KEY ******************** + ;************************************************************** + ; Unmarks the key press in EAX from the scancode array. + + + mov _keyd_last_released, al + mov byte ptr _keyd_pressed[eax], 0 + inc NumUps[eax*4] + + push eax + xor ah,ah + call get_modifiers + or ah,ah ;check modifiers + pop eax + jnz skip_time + + push edx + push eax + call timer_get_milliseconds_ + mov edx, eax + pop eax + sub edx, TimeKeyWentDown[eax*4] + add TimeKeyHeldDown[eax*4], edx + pop edx +skip_time: + + jmp pdone + +pkeyDown: + + ;************************************************************** + ;****************** HANDLE A NEWLY PRESSED KEY **************** + ;************************************************************** + ;Marks the key press in EAX in the scancode array. + + + mov _keyd_last_pressed, al + ; Check if the key is repeating or if it just got pressed. + cmp byte ptr _keyd_pressed[eax], 1 + je AlreadyDown + + mov byte ptr _keyd_pressed[eax], 1 + ; Set the time + + push edx + push eax + call timer_get_milliseconds_ + mov edx, eax + pop eax + mov TimeKeyWentDown[eax*4], edx + pop edx + + inc NumDowns[eax*4] + + jmp TryBuffer + + ;************************************************************** + ;******************** HANDLE A PRESSED KEY ******************** + ;************************************************************** + ; Adds key scan code in EAX to the keybuffer array. + +AlreadyDown: + cmp _keyd_repeat, 0 + je SkipBuffer + +TryBuffer: + cmp _keyd_buffer_type, 0 + je SkipBuffer ; Buffer = 0 means don't buffer anything. + + ; Dont buffer shift, ctrl, or alt keys. + ;cmp al, 02ah ; Right Shift + ;je SkipBuffer + ;cmp al, 036h ; Left Shift + ;je SkipBuffer + ;cmp al, 038h ; Left Alt + ;je SkipBuffer + ;cmp al, 0b8h ; Right Alt + ;je SkipBuffer + ;cmp al, 01dh ; Left Ctrl + ;je SkipBuffer + ;cmp al, 09dh ' Right Ctrl + ;je SkipBuffer + + cmp al, 0AAh ; garbage key + je SkipBuffer + + call get_modifiers ;returns ah + +BufferAX: + + xor ebx, ebx + mov bl, keytail + inc bl + inc bl + + ; If the buffer is full then don't buffer this key + cmp bl, keyhead + je SkipBuffer + dec bl + + mov word ptr keybuffer[ebx*2], ax + mov keytail, bl + +SkipBuffer: + +pdone: + + +;************************************************************** +;*************** FINISH UP THE KEYBOARD INTERRUPT ************* +;************************************************************** + +; If in debugger, pass control to dos interrupt. +IFDEF DEBUG + pop ds ; Nothing left on stack but flags + pop edx + pop ecx + pop ebx + pop eax + + sub esp, 8 ; Save space for IRETD frame + push ds ; Save registers we use. + push eax + mov ax, DGROUP + mov ds, ax ; Set DS to our data segment + mov eax, org_int_off ; put original handler address + mov [esp+8], eax ; in the IRETD frame + movzx eax, org_int_sel + mov [esp+12], eax + pop eax ; Restore registers + pop ds + iretd ; Chain to previous handler +ENDIF + +; Resets the keyboard, PIC, restores stack, returns. + in al, 61h ; Get current port 61h state + or al, 10000000b ; Turn on bit 7 to signal clear keybrd + out 61h, al ; Send to port + and al, 01111111b ; Turn off bit 7 to signal break + out 61h, al ; Send to port + mov al, 20h ; Reset interrupt controller + out 20h, al + sti ; Reenable interrupts + pop ds + pop edx ; Restore all of the saved registers. + pop ecx + pop ebx + pop eax + popfd + iretd ; Interrupt must return with IRETD + +;returns ah=bitmask of shift,ctrl,alt keys +get_modifiers: push ecx + + xor ah,ah + + ; Check the shift keys + mov cl, _keyd_pressed[ 036h ] + or cl, _keyd_pressed[ 02ah ] + or ah, cl + + ; Check the alt key + mov cl, _keyd_pressed[ 038h ] + or cl, _keyd_pressed[ 0b8h ] + shl cl, 1 + or ah, cl + + ; Check the ctrl key + mov cl, _keyd_pressed[ 01dh ] + or cl, _keyd_pressed[ 09dh ] + shl cl, 2 + or ah, cl + + pop ecx + ret + +IFDEF DEBUG +CheckForDebugger: + ; Returns CF=0 if debugger isn't active + ; CF=1 if debugger is active + + ;*************************** DEBUG ****************************** + ; When we're in the VIDEO debugger, we want to pass control to + ; the original interrupt. So, to tell if the debugger is active, + ; I check if video page 1 is the active page since that is what + ; page the debugger uses, and if that works, I check the top of + ; the screen to see if the texxt "Control" is there, which should + ; only be there when we're in the debugger. + + push eax + ;mov eax, 0462h ; Address 0462 stores BIOS current page + ;cmp BYTE PTR [eax], 1 + ;jne NoDebuggerOnColor + ;mov eax, 0b8000h+4096 ; 4096 = offset to 2nd video mem page + ;cmp BYTE PTR [eax+2],'C' + ;jne NoDebuggerOnColor + ;cmp BYTE PTR [eax+4],'o' + ;jne NoDebuggerOnColor + ;cmp BYTE PTR [eax+6],'n' + ;jne NoDebuggerOnColor + ;cmp BYTE PTR [eax+8],'t' + ;jne NoDebuggerOnColor + ;cmp BYTE PTR [eax+10],'r' + ;jne NoDebuggerOnColor + ;cmp BYTE PTR [eax+12],'o' + ;jne NoDebuggerOnColor + ;cmp BYTE PTR [eax+14],'l' + ;jne NoDebuggerOnColor + ;jmp ActiveDebugger + ;NoDebuggerOnColor: + ; First, see if there is a mono debugger... + + ;mov eax, 0b0000h ; 4096 = offset to mono video mem + ;cmp BYTE PTR [eax+2],'C' + ;jne NoActiveDebugger + ;cmp BYTE PTR [eax+4],'o' + ;jne NoActiveDebugger + ;cmp BYTE PTR [eax+6],'n' + ;jne NoActiveDebugger + ;cmp BYTE PTR [eax+8],'t' + ;jne NoActiveDebugger + ;cmp BYTE PTR [eax+10],'r' + ;jne NoActiveDebugger + ;cmp BYTE PTR [eax+12],'o' + ;jne NoActiveDebugger + ;cmp BYTE PTR [eax+14],'l' + ;jne NoActiveDebugger + + mov eax, 0b0000h ; 4096 = offset to mono video mem + add eax, 24*80*2 + + + cmp BYTE PTR [eax+0],'D' + jne NextTest + cmp BYTE PTR [eax+2],'B' + jne NextTest + cmp BYTE PTR [eax+4],'G' + jne NextTest + cmp BYTE PTR [eax+6],'>' + jne NextTest + + ;Found DBG>, so consider debugger active: + jmp ActiveDebugger + +NextTest: + cmp BYTE PTR [eax+14],'<' + jne NextTest1 + cmp BYTE PTR [eax+16],'i' + jne NextTest1 + cmp BYTE PTR [eax+18],'>' + jne NextTest1 + cmp BYTE PTR [eax+20],' ' + jne NextTest1 + cmp BYTE PTR [eax+22],'-' + jne NextTest1 + + ; Found - , so consider debugger active: + jmp ActiveDebugger + +NextTest1: + cmp BYTE PTR [eax+0], 200 + jne NextTest2 + cmp BYTE PTR [eax+2], 27 + jne NextTest2 + cmp BYTE PTR [eax+4], 17 + jne NextTest2 + + ; Found either the help screen or view screen, so consider + ; debugger active + jmp ActiveDebugger + +NextTest2: + ; Now we see if its active by looking for the "Executing..." + ; text on the bottom of the mono screen + ;mov eax, 0b0000h ; 4096 = offset to mono video mem + ;add eax, 24*80*2 + ;cmp BYTE PTR [eax+0],'E' + ;je NoActiveDebugger + ;cmp BYTE PTR [eax+2],'x' + ;je NoActiveDebugger + ;cmp BYTE PTR [eax+4],'e' + ;je NoActiveDebugger + ;cmp BYTE PTR [eax+6],'c' + ;je NoActiveDebugger + +NoActiveDebugger: + pop eax + clc + ret + +ActiveDebugger: + pop eax + stc + ret + +ENDIF + +_TEXT ENDS + + END + + diff --git a/unused/bios/keys.inc b/unused/bios/keys.inc index 8839c8ba..557476aa 100644 --- a/unused/bios/keys.inc +++ b/unused/bios/keys.inc @@ -1,284 +1,284 @@ -; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX -; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO -; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A -; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS -; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS -; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE -; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE -; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS -; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. -; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. -;************************************************************** -;**************** SCAN CODE TO ASCII TABLES ******************* -;************************************************************** -; This are two tables of ASCII codes for a given scan code. -; The character Û is used to denote an invalid keystroke that won't -; be put into the keyboard buffer. - -;0 1 2 3 4 5 6 7 -;0 1 23456789ABCD E F 0123456789AB C DEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF -;db "Û",27,"1234567890-=",8,9,"qwertyuiop[]",13,"Ûasdfghjkl;'`Û\zxcvbnm,./Û*Û ÛÛÛÛÛÛÛÛÛÛÛÛÛ789-456+1230.ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ" - -;0 1 2 3 4 5 6 7 -;0123456789ABCDE F0123456789ABCDEF01234567 8 9ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF -;Key2 db "ÛÛ!@#$%^&*()_+Û",11,"QWERTYUIOP{}ÛÛASDFGHJKL:",34,"ÛÛ|ZXCVBNM<>?ÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ-ÛÛÛ+ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ" - -Key1 db 255 ; No key for 0 - db 255 ; Esc - db '1' - db '2' - db '3' - db '4' - db '5' - db '6' - db '7' - db '8' - db '9' - db '0' - db '-' - db '=' - db 255 ; Backspace - db 255 ; Tab - db 'q' - db 'w' - db 'e' - db 'r' - db 't' - db 'y' - db 'u' - db 'i' - db 'o' - db 'p' - db '[' - db ']' - db 255 ; Enter - db 255 ; Ctrl - db 'a' - db 's' - db 'd' - db 'f' - db 'g' - db 'h' - db 'j' - db 'k' - db 'l' - db ';' - db 39 ; ' - db '`' - db 255 ; Left Shift - db '\' - db 'z' - db 'x' - db 'c' - db 'v' - db 'b' - db 'n' - db 'm' - db ',' - db '.' - db '/' - db 255 ; Right Shift - db '*' ; Prtsc or * - db 255 ; Alt - db ' ' ; Spacebar - db 255 ; Capslock - db 255 ; F1 - db 255 ; F2 - db 255 ; F3 - db 255 ; F4 - db 255 ; F5 - db 255 ; F6 - db 255 ; F7 - db 255 ; F8 - db 255 ; F9 - db 255 ; F10 - db 255 ; Numlock - db 255 ; ScrollLock - db 255 ; Home or 7 - db 255 ; Up or 8 - db 255 ; - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 -Key2 db 255 ; No key for 0 - db 255 ; Esc - db '!' - db '@' - db '#' - db '$' - db '%' - db '^' - db '&' - db '*' - db '(' - db ')' - db '_' - db '+' - db 255 ; Backspace - db 255 ; Tab - db 'Q' - db 'W' - db 'E' - db 'R' - db 'T' - db 'Y' - db 'U' - db 'I' - db 'O' - db 'P' - db '{' - db '}' - db 255 ; Enter - db 255 ; Ctrl - db 'A' - db 'S' - db 'D' - db 'F' - db 'G' - db 'H' - db 'J' - db 'K' - db 'L' - db ':' - db '"' - db '~' - db 255 ; Left Shift - db '|' - db 'Z' - db 'X' - db 'C' - db 'V' - db 'B' - db 'N' - db 'M' - db '<' - db '>' - db '?' - db 255 ; Right Shift - db 255 ; Prtsc or * - db 255 ; Alt - db ' ' ; Spacebar - db 255 ; Capslock - db 255 ; F1 - db 255 ; F2 - db 255 ; F3 - db 255 ; F4 - db 255 ; F5 - db 255 ; F6 - db 255 ; F7 - db 255 ; F8 - db 255 ; F9 - db 255 ; F10 - db 255 ; Numlock - db 255 ; ScrollLock - db 255 ; Home or 7 - db 255 ; Up or 8 - db 255 ; - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - db 255 - - - +; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. +;************************************************************** +;**************** SCAN CODE TO ASCII TABLES ******************* +;************************************************************** +; This are two tables of ASCII codes for a given scan code. +; The character Û is used to denote an invalid keystroke that won't +; be put into the keyboard buffer. + +;0 1 2 3 4 5 6 7 +;0 1 23456789ABCD E F 0123456789AB C DEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF +;db "Û",27,"1234567890-=",8,9,"qwertyuiop[]",13,"Ûasdfghjkl;'`Û\zxcvbnm,./Û*Û ÛÛÛÛÛÛÛÛÛÛÛÛÛ789-456+1230.ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ" + +;0 1 2 3 4 5 6 7 +;0123456789ABCDE F0123456789ABCDEF01234567 8 9ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF +;Key2 db "ÛÛ!@#$%^&*()_+Û",11,"QWERTYUIOP{}ÛÛASDFGHJKL:",34,"ÛÛ|ZXCVBNM<>?ÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ-ÛÛÛ+ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ" + +Key1 db 255 ; No key for 0 + db 255 ; Esc + db '1' + db '2' + db '3' + db '4' + db '5' + db '6' + db '7' + db '8' + db '9' + db '0' + db '-' + db '=' + db 255 ; Backspace + db 255 ; Tab + db 'q' + db 'w' + db 'e' + db 'r' + db 't' + db 'y' + db 'u' + db 'i' + db 'o' + db 'p' + db '[' + db ']' + db 255 ; Enter + db 255 ; Ctrl + db 'a' + db 's' + db 'd' + db 'f' + db 'g' + db 'h' + db 'j' + db 'k' + db 'l' + db ';' + db 39 ; ' + db '`' + db 255 ; Left Shift + db '\' + db 'z' + db 'x' + db 'c' + db 'v' + db 'b' + db 'n' + db 'm' + db ',' + db '.' + db '/' + db 255 ; Right Shift + db '*' ; Prtsc or * + db 255 ; Alt + db ' ' ; Spacebar + db 255 ; Capslock + db 255 ; F1 + db 255 ; F2 + db 255 ; F3 + db 255 ; F4 + db 255 ; F5 + db 255 ; F6 + db 255 ; F7 + db 255 ; F8 + db 255 ; F9 + db 255 ; F10 + db 255 ; Numlock + db 255 ; ScrollLock + db 255 ; Home or 7 + db 255 ; Up or 8 + db 255 ; + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 +Key2 db 255 ; No key for 0 + db 255 ; Esc + db '!' + db '@' + db '#' + db '$' + db '%' + db '^' + db '&' + db '*' + db '(' + db ')' + db '_' + db '+' + db 255 ; Backspace + db 255 ; Tab + db 'Q' + db 'W' + db 'E' + db 'R' + db 'T' + db 'Y' + db 'U' + db 'I' + db 'O' + db 'P' + db '{' + db '}' + db 255 ; Enter + db 255 ; Ctrl + db 'A' + db 'S' + db 'D' + db 'F' + db 'G' + db 'H' + db 'J' + db 'K' + db 'L' + db ':' + db '"' + db '~' + db 255 ; Left Shift + db '|' + db 'Z' + db 'X' + db 'C' + db 'V' + db 'B' + db 'N' + db 'M' + db '<' + db '>' + db '?' + db 255 ; Right Shift + db 255 ; Prtsc or * + db 255 ; Alt + db ' ' ; Spacebar + db 255 ; Capslock + db 255 ; F1 + db 255 ; F2 + db 255 ; F3 + db 255 ; F4 + db 255 ; F5 + db 255 ; F6 + db 255 ; F7 + db 255 ; F8 + db 255 ; F9 + db 255 ; F10 + db 255 ; Numlock + db 255 ; ScrollLock + db 255 ; Home or 7 + db 255 ; Up or 8 + db 255 ; + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + db 255 + + + diff --git a/unused/bios/make0000.bat b/unused/bios/make0000.bat index ff0ba743..e5d45885 100644 --- a/unused/bios/make0000.bat +++ b/unused/bios/make0000.bat @@ -1,5 +1,5 @@ -@echo off -del ____temp.tmp -if errorlevel 1 goto m_end -echo>C:\MINER\SOURCE\BIOS\make0000.err -:m_end +@echo off +del ____temp.tmp +if errorlevel 1 goto m_end +echo>C:\MINER\SOURCE\BIOS\make0000.err +:m_end diff --git a/unused/bios/make0001.bat b/unused/bios/make0001.bat index ab68f52d..9804927b 100644 --- a/unused/bios/make0001.bat +++ b/unused/bios/make0001.bat @@ -1,5 +1,5 @@ -@echo off -del ____temp.tmp -if errorlevel 1 goto m_end -echo>D:\MINER\SOURCE\BIOS\make0000.err -:m_end +@echo off +del ____temp.tmp +if errorlevel 1 goto m_end +echo>D:\MINER\SOURCE\BIOS\make0000.err +:m_end diff --git a/unused/bios/make0100.bat b/unused/bios/make0100.bat index 73d3ddc6..d5d57221 100644 --- a/unused/bios/make0100.bat +++ b/unused/bios/make0100.bat @@ -1,5 +1,5 @@ -@echo off -del ____temp.tmp -if errorlevel 1 goto m_end -echo>D:\MINER\SOURCE\BIOS\make0100.err -:m_end +@echo off +del ____temp.tmp +if errorlevel 1 goto m_end +echo>D:\MINER\SOURCE\BIOS\make0100.err +:m_end diff --git a/unused/bios/mouse.asm b/unused/bios/mouse.asm index a3fb989b..bcad9138 100644 --- a/unused/bios/mouse.asm +++ b/unused/bios/mouse.asm @@ -1,316 +1,316 @@ -; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX -; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO -; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A -; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS -; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS -; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE -; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE -; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS -; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. -; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. -;*************************************************************************** -;*************************************************************************** -;***** ***** -;***** M O U S E . A S M ***** -;***** ***** -;***** Contains routines for a mouse interface. ***** -;***** ***** -;***** ***** -;***** PROCEDURES ***** -;***** ***** -;***** VARIABLES ***** -;***** ***** -;***** ***** -;***** CONSTANTS ***** -;***** ***** -;***** ***** -;*************************************************************************** -;*************************************************************************** - -.386 - -;************************************************************************ -;**************** FLAT MODEL DATA SEGMENT STUFF ************************* -;************************************************************************ - -_DATA SEGMENT BYTE PUBLIC USE32 'DATA' - -rcsid db "$Id: mouse.asm,v 1.1.1.1 2001-01-19 03:30:14 bradleyb Exp $" - - MOUSE_EVENT STRUCT 2 - MouseDX dw ? - MouseDY dw ? - MouseButtons dw ? - MouseFlags dw ? - MOUSE_EVENT ENDS - - NumberOfButtons dw ? - - MyEvent MOUSE_EVENT < > - MyEventHandler dd 0 - - - -_DATA ENDS - -DGROUP GROUP _DATA - - -;************************************************************************ -;**************** FLAT MODEL CODE SEGMENT STUFF ************************* -;************************************************************************ - -_TEXT SEGMENT BYTE PUBLIC USE32 'CODE' - - ASSUME ds:_DATA - ASSUME cs:_TEXT - -PUBLIC mouse_init_ - -mouse_init_: - - push bx - xor ax, ax ; Reset mouse - int 33h - mov NumberOfButtons, bx - pop bx - or ax, ax - jnz present - jmp absent - - -present: - mov ax, 0020h ; Enable driver - int 33h - - mov ax, 1 - ret - -absent: - mov ax, 0 - ret - - - -PUBLIC mouse_get_pos_ - -mouse_get_pos_: - - push eax - push ebx - push ecx - push edx - - push eax - - mov ax, 03h ; Get Mouse Position and Button Status - int 33h - ; bx = buttons, cx = x, dx = y - - pop eax - mov [eax], cx - pop eax - mov [eax], dx - mov edx, eax - - pop ecx - pop ebx - pop eax - - ret - -PUBLIC mouse_get_delta_ - -mouse_get_delta_: - - push eax - push ebx - push ecx - push edx - - - push eax - - mov eax, 0bh ; Read Mouse Motion Counters - int 33h - - pop eax - mov [eax], cx - pop eax - mov [eax], dx - mov edx, eax - - pop ecx - pop ebx - pop eax - ret - - -PUBLIC mouse_get_btns_ - -mouse_get_btns_: - - push ebx - push ecx - push edx - - mov ax, 03h ; Get Mouse Position and Button Status - int 33h - ; bx = buttons, cx = x, dx = y - - movzx eax, bx - - pop edx - pop ecx - pop ebx - - ret - - -PUBLIC mouse_close_ - -mouse_close_: - - push eax - push ebx - push es - - mov ax, 01fh ; Disable mouse driver - int 33h - - pop es - pop ebx - pop eax - - ret - -MyHandler: - - pushad - push ds - - push ax - mov ax, DGROUP - mov ds, ax - pop ax - - mov MyEvent.MouseDX, cx - mov MyEvent.MouseDY, dx - mov MyEvent.MouseButtons, bx - mov MyEvent.MouseFlags, ax - - mov eax, offset MyEvent - - call MyEventHandler - - pop ds - popad - - retf - -PUBLIC mouse_set_handler_ - -mouse_set_handler_: - - push eax - push ebx - push ecx - push edx - push es - - mov MyEventHandler, edx - - mov ecx, eax ; Event flags - mov edx, MyHandler - mov ax, cs - mov es, ax - mov ax, 0Ch ; Set User-defined Mouse Event Handler - int 33h - - pop es - pop edx - pop ecx - pop edx - pop eax - - ret - -PUBLIC mouse_clear_handler_ - -mouse_clear_handler_: - - push eax - push ebx - push ecx - push edx - push es - - mov MyEventHandler, 0 - - mov ecx, 0 ; Event flags - mov edx, MyHandler - mov ax, cs - mov es, ax - mov ax, 0Ch ; Set User-defined Mouse Event Handler - int 33h - - pop es - pop edx - pop ecx - pop edx - pop eax - - ret - - -PUBLIC mouse_set_limits_ - -mouse_set_limits_: - - ; EAX = minx - ; EDX = miny - ; EBX = maxx - ; ECX = maxy - - push edx ; Save Vertical stuff - push ecx - - mov cx, ax - mov dx, bx - mov ax, 7 - int 33h - - pop edx - pop ecx - mov ax, 8 - int 33h - - ret - - -;extern void mouse_set_pos( short x, short y); - - -PUBLIC mouse_set_pos_ - -mouse_set_pos_: - - ; EAX = x - ; EDX = y - - push ecx - - mov ecx, eax - mov eax, 04h - int 33h - pop ecx - - - ret - - - -_TEXT ENDS - - - END +; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. +;*************************************************************************** +;*************************************************************************** +;***** ***** +;***** M O U S E . A S M ***** +;***** ***** +;***** Contains routines for a mouse interface. ***** +;***** ***** +;***** ***** +;***** PROCEDURES ***** +;***** ***** +;***** VARIABLES ***** +;***** ***** +;***** ***** +;***** CONSTANTS ***** +;***** ***** +;***** ***** +;*************************************************************************** +;*************************************************************************** + +.386 + +;************************************************************************ +;**************** FLAT MODEL DATA SEGMENT STUFF ************************* +;************************************************************************ + +_DATA SEGMENT BYTE PUBLIC USE32 'DATA' + +rcsid db "$Id: mouse.asm,v 1.1.1.2 2001-01-19 03:33:49 bradleyb Exp $" + + MOUSE_EVENT STRUCT 2 + MouseDX dw ? + MouseDY dw ? + MouseButtons dw ? + MouseFlags dw ? + MOUSE_EVENT ENDS + + NumberOfButtons dw ? + + MyEvent MOUSE_EVENT < > + MyEventHandler dd 0 + + + +_DATA ENDS + +DGROUP GROUP _DATA + + +;************************************************************************ +;**************** FLAT MODEL CODE SEGMENT STUFF ************************* +;************************************************************************ + +_TEXT SEGMENT BYTE PUBLIC USE32 'CODE' + + ASSUME ds:_DATA + ASSUME cs:_TEXT + +PUBLIC mouse_init_ + +mouse_init_: + + push bx + xor ax, ax ; Reset mouse + int 33h + mov NumberOfButtons, bx + pop bx + or ax, ax + jnz present + jmp absent + + +present: + mov ax, 0020h ; Enable driver + int 33h + + mov ax, 1 + ret + +absent: + mov ax, 0 + ret + + + +PUBLIC mouse_get_pos_ + +mouse_get_pos_: + + push eax + push ebx + push ecx + push edx + + push eax + + mov ax, 03h ; Get Mouse Position and Button Status + int 33h + ; bx = buttons, cx = x, dx = y + + pop eax + mov [eax], cx + pop eax + mov [eax], dx + mov edx, eax + + pop ecx + pop ebx + pop eax + + ret + +PUBLIC mouse_get_delta_ + +mouse_get_delta_: + + push eax + push ebx + push ecx + push edx + + + push eax + + mov eax, 0bh ; Read Mouse Motion Counters + int 33h + + pop eax + mov [eax], cx + pop eax + mov [eax], dx + mov edx, eax + + pop ecx + pop ebx + pop eax + ret + + +PUBLIC mouse_get_btns_ + +mouse_get_btns_: + + push ebx + push ecx + push edx + + mov ax, 03h ; Get Mouse Position and Button Status + int 33h + ; bx = buttons, cx = x, dx = y + + movzx eax, bx + + pop edx + pop ecx + pop ebx + + ret + + +PUBLIC mouse_close_ + +mouse_close_: + + push eax + push ebx + push es + + mov ax, 01fh ; Disable mouse driver + int 33h + + pop es + pop ebx + pop eax + + ret + +MyHandler: + + pushad + push ds + + push ax + mov ax, DGROUP + mov ds, ax + pop ax + + mov MyEvent.MouseDX, cx + mov MyEvent.MouseDY, dx + mov MyEvent.MouseButtons, bx + mov MyEvent.MouseFlags, ax + + mov eax, offset MyEvent + + call MyEventHandler + + pop ds + popad + + retf + +PUBLIC mouse_set_handler_ + +mouse_set_handler_: + + push eax + push ebx + push ecx + push edx + push es + + mov MyEventHandler, edx + + mov ecx, eax ; Event flags + mov edx, MyHandler + mov ax, cs + mov es, ax + mov ax, 0Ch ; Set User-defined Mouse Event Handler + int 33h + + pop es + pop edx + pop ecx + pop edx + pop eax + + ret + +PUBLIC mouse_clear_handler_ + +mouse_clear_handler_: + + push eax + push ebx + push ecx + push edx + push es + + mov MyEventHandler, 0 + + mov ecx, 0 ; Event flags + mov edx, MyHandler + mov ax, cs + mov es, ax + mov ax, 0Ch ; Set User-defined Mouse Event Handler + int 33h + + pop es + pop edx + pop ecx + pop edx + pop eax + + ret + + +PUBLIC mouse_set_limits_ + +mouse_set_limits_: + + ; EAX = minx + ; EDX = miny + ; EBX = maxx + ; ECX = maxy + + push edx ; Save Vertical stuff + push ecx + + mov cx, ax + mov dx, bx + mov ax, 7 + int 33h + + pop edx + pop ecx + mov ax, 8 + int 33h + + ret + + +;extern void mouse_set_pos( short x, short y); + + +PUBLIC mouse_set_pos_ + +mouse_set_pos_: + + ; EAX = x + ; EDX = y + + push ecx + + mov ecx, eax + mov eax, 04h + int 33h + pop ecx + + + ret + + + +_TEXT ENDS + + + END diff --git a/unused/bios/oldkey.asm b/unused/bios/oldkey.asm index 757e3297..63c1422d 100644 --- a/unused/bios/oldkey.asm +++ b/unused/bios/oldkey.asm @@ -1,1060 +1,1060 @@ -; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX -; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO -; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A -; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS -; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS -; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE -; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE -; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS -; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. -; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. -; $Log: not supported by cvs2svn $ -; Revision 1.2 1994/02/17 15:55:59 john -; Initial version -; -; Revision 1.20 1994/01/18 10:58:55 john -; *** empty log message *** -; -; Revision 1.19 1993/12/22 13:28:40 john -; Added back changes Matt made in r1.14 -; -; Revision 1.18 1993/12/22 13:18:32 john -; *** empty log message *** -; -; Revision 1.17 1993/12/20 16:48:47 john -; Put cli/sti around clear keybuffer in key_close -; -; Revision 1.16 1993/12/20 15:39:13 john -; Tried to neaten handler code... also, moved some cli's and sti's around -; trying to find bug. Made the code call key_get_milliseconds instead -; of timer_get_milliseconds, because we don't want the cli and sti -; stuff in the interrupt handler. -; -; Revision 1.15 1993/12/02 10:54:48 john -; Made the Ctrl,Shift,Alt keys buffer like all the other keys. -; -; Revision 1.14 1993/10/29 11:25:18 matt -; Made key_down_time() not accumulate time if shift,alt,ctrl down -; -; Revision 1.13 1993/10/29 10:47:00 john -; *** empty log message *** -; -; Revision 1.12 1993/10/16 19:24:16 matt -; Added new function key_clear_times() & key_clear_counts() -; -; Revision 1.11 1993/10/15 10:16:49 john -; bunch of stuff, mainly with detecting debugger. -; -; Revision 1.10 1993/10/04 13:25:57 john -; Changed the way extended keys are processed. -; -; Revision 1.9 1993/09/28 11:35:32 john -; added key_peekkey -; -; Revision 1.8 1993/09/23 18:09:23 john -; fixed bug checking for DBG -; -; Revision 1.7 1993/09/23 17:28:01 john -; made debug check look for DBG> instead of CONTROL -; -; Revision 1.6 1993/09/20 17:08:19 john -; Made so that keys pressed in debugger don't get passed through to -; the keyboard handler. I also discovered, but didn't fix a error -; (page fault) caused by jumping back and forth between the debugger -; and the program... -; -; Revision 1.5 1993/09/17 09:58:12 john -; Added checks for already installed, not installed, etc. -; -; Revision 1.4 1993/09/15 17:28:00 john -; Fixed bug in FlushBuffer that used CX before a REP instead of ECX. -; -; Revision 1.3 1993/09/08 14:48:00 john -; made getch() return an int instead of a char that has shift states, etc. -; -; Revision 1.2 1993/07/22 13:12:23 john -; fixed comment -; ,. -; -; Revision 1.1 1993/07/10 13:10:42 matt -; Initial revision -; -; -; - -;*************************************************************************** -;*************************************************************************** -;***** ***** -;***** ***** -;***** K E Y . A S M ***** -;***** ***** -;***** Contains routines to get, buffer, and check key presses. ***** -;***** ***** -;***** ***** -;***** PROCEDURES ***** -;***** ***** -;***** key_init() - Activates the keyboard package. ***** -;***** key_close() - Deactivates the keyboard package. ***** -;***** key_check() - Returns 1 if a buffered key is waiting. ***** -;***** key_getch() - Waits for and returns a buffered keypress. ***** -;***** key_flush() - Clears buffers and state array. ***** -;***** key_time() - Index by scan code. Contains the time key has been ***** -;***** held down. NOT DONE YET. ***** -;***** ***** -;***** ***** -;***** VARIABLES ***** -;***** ***** -;***** keyd_buffer_type -Set to 0 and key_getch() always returns 0. ***** -;***** Set to 1 to so that ASCII codes are returned ***** -;***** by key_getch(). Set to 2 and key_getch() returns***** -;***** the buffered keyboard scan codes. ***** -;***** keyd_repeat - Set to 0 to not allow repeated keys in the ***** -;***** keyboard buffer. Set to 1 to allow repeats. ***** -;***** keyd_pressed[] -Index by scan code. Contains 1 if key down else 0***** -;***** ***** -;***** ***** -;***** CONSTANTS ***** -;***** ***** -;***** Setting the DEBUG to 1 at compile time passes SysReq through ***** -;***** to the debugger, and when the debugger is active, it will give ***** -;***** the debugger any keys that are pressed. Note that this only ***** -;***** works with the Watcom VIDEO debugger at this time. Setting ***** -;***** DEBUG to 0 takes out all the debugging stuff. ***** -;***** ***** -;*************************************************************************** -;*************************************************************************** - -DEBUG EQU 1 -.386 - -;************************************************************************ -;**************** FLAT MODEL DATA SEGMENT STUFF ************************* -;************************************************************************ - -_DATA SEGMENT BYTE PUBLIC USE32 'DATA' - -rcsid db "$Id: oldkey.asm,v 1.1.1.1 2001-01-19 03:30:14 bradleyb Exp $" - -PUBLIC _keyd_pressed ; Must start with a _ so C can see the variable. - - _keyd_pressed db 256 dup (?) - - keybuffer dw 256 dup (?) ; Use 256 so an inc wraps around - - TimeKeyWentDown dd 256 dup(0) - TimeKeyHeldDown dd 256 dup(0) - NumDowns dd 256 dup(0) - NumUps dd 256 dup(0) - - MyCodeSegment dw ? - -PUBLIC _keyd_editor_mode - - _keyd_editor_mode db 0 - -PUBLIC _keyd_use_bios - - _keyd_use_bios db 1 - -PUBLIC _keyd_last_pressed - _keyd_last_pressed db 0 -PUBLIC _keyd_last_released - _keyd_last_released db 0 - -PUBLIC _keyd_dump_key_array - _keyd_dump_key_array db 0 - org_int_sel dw ? - org_int_off dd ? - - interrupted_cs dw ? - interrupted_eip dd ? - - keyhead db ? - keytail db ? -PUBLIC _keyd_buffer_type -PUBLIC _keyd_repeat - _keyd_buffer_type db ? ; 0=No buffer, 1=buffer ASCII, 2=buffer scans - _keyd_repeat db ? - - E0Flag db 0 - - Installed db 0 - -INCLUDE KEYS.INC - - -_DATA ENDS - -DGROUP GROUP _DATA - - -;************************************************************************ -;**************** FLAT MODEL CODE SEGMENT STUFF ************************* -;************************************************************************ - -_TEXT SEGMENT BYTE PUBLIC USE32 'CODE' - - ASSUME ds:_DATA - ASSUME cs:_TEXT - -key_get_milliseconds: - EXTERNDEF timer_get_stamp64:NEAR - - push ebx - push edx - - call timer_get_stamp64 - - ; Timing in milliseconds - ; Can be used for up to 1000 hours - shld edx, eax, 21 ; Keep 32+11 bits - shl eax, 21 - mov ebx, 2502279823 ; 2^21*1193180/1000 - div ebx - - pop edx - pop ebx - - ret - -;************************************************************************ -;************************************************************************ -;***** ***** -;***** K E Y _ T O _ A S C I I _ ***** -;***** ***** -;************************************************************************ -;************************************************************************ - -PUBLIC key_to_ascii_ - -key_to_ascii_: - - ; EAX = scancode - push ebx - - mov bl, ah - and bl, 011111110b - cmp bl, 0 - jne CantDoKey - - cmp al, 127 - jae CantDoKey - - and ah, 01b ; take away ctrl and alt codes - shl al, 1 - shr eax, 1 - and eax, 0ffh - mov al, byte ptr key1[eax] - pop ebx - ret - -CantDoKey: - pop ebx - mov eax, 255 - ret - - -public key_clear_times_,key_clear_counts_ - -;clear the array of key down times. -key_clear_times_: - cli - push eax - push ecx - push edi - xor eax,eax - mov ecx,256 - lea edi,TimeKeyHeldDown - rep stosd ;clear array - pop edi - pop ecx - pop eax - sti - ret - -;clear the arrays of key down counts -key_clear_counts_: - cli - push eax - push ecx - push edi - xor eax,eax - mov ecx,256 - lea edi,NumDowns - rep stosd ;clear array - mov ecx,256 - lea edi,NumUps - rep stosd ;clear array - pop edi - pop ecx - pop eax - sti - ret - - -PUBLIC key_down_time_ - -key_down_time_: - cli - - push edx - push ecx - push ebx - - - mov ebx, eax - xor eax, eax - - cmp _keyd_pressed[ebx], 0 - je NotPressed - - - cmp _keyd_editor_mode, 0 - je read_time - - call get_modifiers ;shift,alt,ctrl? - or ah,ah - jz read_time - xor eax,eax - jmp NotPressed - -read_time: mov ecx, TimeKeyWentDown[ebx*4] - call key_get_milliseconds - mov TimeKeyWentDown[ebx*4], eax - sub eax, ecx ; EAX = time held since last - -NotPressed: - add eax, TimeKeyHeldDown[ebx*4] - mov TimeKeyHeldDown[ebx*4], 0 - - pop ebx - pop ecx - pop edx - sti - ret - -PUBLIC key_down_count_ -key_down_count_: - cli - push ebx - mov ebx, eax - mov eax, NumDowns[ebx*4] - mov NumDowns[ebx*4], 0 - pop ebx - sti - ret - -PUBLIC key_up_count_ -key_up_count_: - cli - push ebx - mov ebx, eax - mov eax, NumUps[ebx*4] - mov NumUps[ebx*4], 0 - pop ebx - sti - ret - - - -;************************************************************************ -;************************************************************************ -;***** ***** -;***** K E Y _ F L U S H ***** -;***** ***** -;************************************************************************ -;************************************************************************ - -PUBLIC key_flush_ - -key_flush_: - cli - - push eax - push ecx - push edi - - mov keyhead,0 - mov keytail,255 - mov E0Flag, 0 - - ; Clear the keyboard array - mov edi, offset _keyd_pressed - mov ecx, 32 - mov eax,0 - rep stosd - - pop edi - pop ecx - pop eax - sti - ret - -;************************************************************************ -;************************************************************************ -;***** ***** -;***** K E Y _ I N I T ***** -;***** ***** -;************************************************************************ -;************************************************************************ - -PUBLIC key_init_ - -key_init_: - push eax - push ebx - push ds - push es - - ;************************************************************** - ;******************* INITIALIZE key QUEUE ********************** - ;************************************************************** - - mov _keyd_buffer_type,1 - mov _keyd_repeat,1 - mov E0Flag, 0 - - ; Clear the keyboard array - call key_flush_ - - cmp Installed, 0 - jne AlreadyInstalled - - ;************************************************************** - ;******************* SAVE OLD INT9 HANDLER ******************** - ;************************************************************** - - mov Installed, 1 - - mov eax, 03509h ; DOS Get Vector 09h - int 21h ; Call DOS - mov org_int_sel, es ; Save old interrupt selector - mov org_int_off, ebx ; Save old interrupt offset - - - ;************************************************************** - ;***************** INSTALL NEW INT9 HANDLER ******************* - ;************************************************************** - - mov eax, 02509h ; DOS Set Vector 09h - mov edx, offset key_handler ; Point DS:EDX to new handler - mov bx, cs - mov MyCodeSegment, bx - mov ds, bx - int 21h - - -AlreadyInstalled: - - pop es - pop ds - pop ebx - pop eax - - ret - - -;************************************************************************ -;************************************************************************ -;***** ***** -;***** K E Y _ C L O S E _ ***** -;***** ***** -;************************************************************************ -;************************************************************************ - -PUBLIC key_close_ - -key_close_: - push eax - push ebx - push edx - push ds - - - cmp Installed, 0 - je @f - - ;************************************************************** - ;***************** RESTORE OLD INT9 HANDLER ******************* - ;************************************************************** - - mov Installed, 0 - - ; Clear the BIOS buffer - cli - mov ebx, 041ch - mov al, byte ptr [ebx] - mov ebx, 041ah - mov byte ptr [ebx], al - sti - - mov eax, 02509h ; DOS Set Vector 09h - mov edx, org_int_off - mov ds, org_int_sel - int 21h - -@@: pop ds - pop edx - pop ebx - pop eax - - ret - -;************************************************************************ -;************************************************************************ -;***** ***** -;***** K E Y _ C H E C K _ ***** -;***** ***** -;************************************************************************ -;************************************************************************ - -PUBLIC key_checkch_ ; Must end with a _ so C can see the function. - -key_checkch_: - cli - push ebx - - xor eax, eax - cmp Installed, 0 - je NoKey - - mov bl, keytail - inc bl - cmp bl, keyhead - je Nokey - mov eax, 1 -Nokey: - pop ebx - sti - ret - -;************************************************************************ -;************************************************************************ -;***** ***** -;***** K E Y _ D E B U G ***** -;***** ***** -;************************************************************************ -;************************************************************************ - -PUBLIC key_debug_ -key_debug_: - int 3h - ret - - -;************************************************************************ -;************************************************************************ -;***** ***** -;***** K E Y _ G E T C H _ ***** -;***** ***** -;************************************************************************ -;************************************************************************ - -PUBLIC key_getch_ ; Must end with a _ so C can see the function. - -key_getch_: - push ebx - - xor eax, eax - xor ebx, ebx - cmp Installed, 0 - jne StillNoKey - pop ebx - ret - -StillNoKey: - cli ; Critical section - mov bl, keytail - inc bl - cmp bl, keyhead - sti - je StillNoKey - - cli ; Critical section - xor ebx, ebx - mov bl, keyhead - mov ax, word ptr keybuffer[ebx*2] - inc BYTE PTR keyhead - sti - - pop ebx - ret - - -;************************************************************************ -;************************************************************************ -;***** ***** -;***** K E Y _ I N K E Y _ ***** -;***** ***** -;************************************************************************ -;************************************************************************ - -PUBLIC key_inkey_ ; Must end with a _ so C can see the function. - -key_inkey_: - push ebx - - xor eax, eax - xor ebx, ebx - - cmp Installed, 0 - je NoInkey - - cli ; Critical section - mov bl, keytail - inc bl - cmp bl, keyhead - sti - je NoInkey - - cli ; Critical section - mov bl, keyhead - mov ax, word ptr keybuffer[ebx*2] - inc BYTE PTR keyhead - sti -NoInkey: - pop ebx - ret - -PUBLIC key_peekkey_ ; Must end with a _ so C can see the function. - -key_peekkey_: - push ebx - - xor eax, eax - xor ebx, ebx - - cli ; Critical section - - cmp Installed, 0 - je NoPeek - mov bl, keytail - inc bl - cmp bl, keyhead - je NoPeek - mov bl, keyhead - mov ax, word ptr keybuffer[ebx*2] - -NoPeek: sti - pop ebx - ret - - - -;************************************************************************ -;************************************************************************ -;***** ***** -;***** K E Y _ H A N D L E R ***** -;***** ***** -;************************************************************************ -;************************************************************************ - -PUBLIC key_handler ; Must end with a _ so C can see the function. - -key_handler: - - pushfd ; Save flags in case we have to chain to original - push eax - push ebx - push ecx - push edx - push ds - - mov ax, DGROUP ; Point to our data segment, since this is an - mov ds, ax ; interrupt and we don't know where we were. - - mov eax, (0b0000h+76*2) - mov byte ptr [eax], '1' - -IFDEF DEBUG - call CheckForDebugger - jnc @f - mov eax, 0b0000h+78*2 - mov byte ptr [eax], 'D' - jmp PassToBios ; If debugger is active, then skip buffer - -@@: mov eax, 0b0000h+78*2 - mov byte ptr [eax], 'I' - - ; Clear the BIOS buffer - ;**mov ebx, 041ch - ;**mov al, byte ptr [ebx] - ;**mov ebx, 041ah - ;**mov byte ptr [ebx], al -ENDIF - - xor eax, eax - xor ebx, ebx - - in al, 060h ; Get scan code from keyboard - - cmp al, 0E0h - jne NotE0Code - -E0Code: mov E0Flag, 010000000b - jmp LeaveHandler ; If garbage key, then don't buffer it - -NotE0Code: mov bl, al ; Put break bit into bl ; 0 = pressed, 1=released - and al, 01111111b ; AL = scancode - or al, E0Flag ; AL = extended scancode - mov E0Flag,0 ; clear E0 flag - cmp al, 029h - je pause_execution - shl bl, 1 ; put upper bit into carry flag - jc key_mark_released ; if upper bit of bl was set, then it was a release code - -;************************************************************** -;****************** HANDLE A NEWLY PRESSED KEY **************** -;************************************************************** -;Marks the key press in EAX in the scancode array. - -key_mark_pressed: - ;cmp al, 0eh ; backspace - ;je pause_execution - - mov _keyd_last_pressed, al - ; Check if the key is repeating or if it just got pressed. - cmp byte ptr _keyd_pressed[eax], 1 - je AlreadyDown - -;------------------------------- Code for a key pressed for the first time ------------------------ - mov byte ptr _keyd_pressed[eax], 1 - ; Set the time - - push edx - push eax - call key_get_milliseconds - mov edx, eax - pop eax - mov TimeKeyWentDown[eax*4], edx - pop edx - - inc NumDowns[eax*4] - - jmp BufferAX - -;------------------------------- Code for a key that is already pressed ------------------------ -AlreadyDown: - cmp _keyd_repeat, 0 - je DoneMarkingPressed - -BufferAX: - cmp _keyd_buffer_type, 0 - je SkipBuffer ; Buffer = 0 means don't buffer anything. - - cmp al, 0AAh ; garbage key - je SkipBuffer - - call get_modifiers ;returns ah - - xor ebx, ebx - mov bl, keytail - inc bl - inc bl - - ; If the buffer is full then don't buffer this key - cmp bl, keyhead - je SkipBuffer - dec bl - - mov word ptr keybuffer[ebx*2], ax - mov keytail, bl - -SkipBuffer: - -;---------------------------------- Exit function ----------------------------- -DoneMarkingPressed: - jmp LeaveHandler - -;************************************************************** -;******************* HANDLE A RELEASED KEY ******************** -;************************************************************** -; Unmarks the key press in EAX from the scancode array. -key_mark_released: - - mov _keyd_last_released, al - mov byte ptr _keyd_pressed[eax], 0 - inc NumUps[eax*4] - - cmp _keyd_editor_mode, 0 - je NotInEditorMode - push eax - xor ah,ah - call get_modifiers - or ah,ah ;check modifiers - pop eax - jnz skip_time - -NotInEditorMode: - push eax - - call timer_get_stamp64 - - ; Timing in milliseconds - ; Can be used for up to 1000 hours - shld edx, eax, 21 ; Keep 32+11 bits - shl eax, 21 - mov ebx, 2502279823 ; 2^21*1193180/1000 - div ebx - - mov edx, eax - pop eax - sub edx, TimeKeyWentDown[eax*4] - add TimeKeyHeldDown[eax*4], edx - -skip_time: ;**jmp LeaveHandler - -;************************************************************** -;*************** FINISH UP THE KEYBOARD INTERRUPT ************* -;************************************************************** -LeaveHandler: - mov eax, (0b0000h+76*2) - mov byte ptr [eax], '2' - -;; cmp _keyd_dump_key_array, 0 -;; je DontPassToBios - jmp PassToBios - - mov ecx, 256 - mov ebx, 0 - -showdown: mov al, _keyd_pressed[ebx] - add al, '0' - mov [ebx*2+ 0b0000h], al - inc ebx - loop showdown - - mov eax, 0b0000h - mov byte ptr [ eax+(036h*2+1) ], 070h - mov byte ptr [ eax+(02Ah*2+1) ], 070h - mov byte ptr [ eax+(038h*2+1) ], 070h - mov byte ptr [ eax+(0B8h*2+1) ], 070h - mov byte ptr [ eax+(01Dh*2+1) ], 070h - mov byte ptr [ eax+(09dh*2+1) ], 070h - - mov byte ptr [ eax+(0AAh*2+1) ], 07Fh - mov byte ptr [ eax+(0E0h*2+1) ], 07Fh - - jmp DontPassToBios - - -; If in debugger, pass control to dos interrupt. - -PassToBios: pop ds ; Nothing left on stack but flags - pop edx - pop ecx - pop ebx - pop eax - - sub esp, 8 ; Save space for IRETD frame - push ds ; Save registers we use. - push eax - mov ax, DGROUP - mov ds, ax ; Set DS to our data segment - mov eax, org_int_off ; put original handler address - mov [esp+8], eax ; in the IRETD frame - movzx eax, org_int_sel - mov [esp+12], eax - pop eax ; Restore registers - pop ds - iretd ; Chain to previous handler - -pause_execution: - in al, 61h ; Get current port 61h state - or al, 10000000b ; Turn on bit 7 to signal clear keybrd - out 61h, al ; Send to port - and al, 01111111b ; Turn off bit 7 to signal break - out 61h, al ; Send to port - mov al, 20h ; Reset interrupt controller - out 20h, al - sti ; Reenable interrupts - pop ds - pop edx ; Restore all of the saved registers. - pop ecx - pop ebx - pop eax - - sub esp, 8 ; Save space for IRETD frame - push ds ; Save registers we use. - push eax - mov ax, DGROUP - mov ds, ax ; Set DS to our data segment - mov eax, org_int_off ; put original handler address - mov [esp+8], eax ; in the IRETD frame - movzx eax, org_int_sel - mov [esp+12], eax - pop eax ; Restore registers - pop ds - - iretd ; Interrupt must return with IRETD - -DontPassToBios: - -; Resets the keyboard, PIC, restores stack, returns. - in al, 61h ; Get current port 61h state - or al, 10000000b ; Turn on bit 7 to signal clear keybrd - out 61h, al ; Send to port - and al, 01111111b ; Turn off bit 7 to signal break - out 61h, al ; Send to port - mov al, 20h ; Reset interrupt controller - out 20h, al - sti ; Reenable interrupts - pop ds - pop edx ; Restore all of the saved registers. - pop ecx - pop ebx - pop eax - popfd - iretd ; Interrupt must return with IRETD - -;returns ah=bitmask of shift,ctrl,alt keys -get_modifiers: push ecx - - xor ah,ah - - ; Check the shift keys - mov cl, _keyd_pressed[ 036h ] - or cl, _keyd_pressed[ 02ah ] - or ah, cl - - ; Check the alt key - mov cl, _keyd_pressed[ 038h ] - or cl, _keyd_pressed[ 0b8h ] - shl cl, 1 - or ah, cl - - ; Check the ctrl key - mov cl, _keyd_pressed[ 01dh ] - or cl, _keyd_pressed[ 09dh ] - shl cl, 2 - or ah, cl - - pop ecx - ret - -IFDEF DEBUG -CheckForDebugger: - ; Returns CF=0 if debugger isn't active - ; CF=1 if debugger is active - - ;*************************** DEBUG ****************************** - ; When we're in the VIDEO debugger, we want to pass control to - ; the original interrupt. So, to tell if the debugger is active, - ; I check if video page 1 is the active page since that is what - ; page the debugger uses, and if that works, I check the top of - ; the screen to see if the texxt "Control" is there, which should - ; only be there when we're in the debugger. - - - - push eax - ;mov eax, 0462h ; Address 0462 stores BIOS current page - ;cmp BYTE PTR [eax], 1 - ;jne NoDebuggerOnColor - ;mov eax, 0b8000h+4096 ; 4096 = offset to 2nd video mem page - ;cmp BYTE PTR [eax+2],'C' - ;jne NoDebuggerOnColor - ;cmp BYTE PTR [eax+4],'o' - ;jne NoDebuggerOnColor - ;cmp BYTE PTR [eax+6],'n' - ;jne NoDebuggerOnColor - ;cmp BYTE PTR [eax+8],'t' - ;jne NoDebuggerOnColor - ;cmp BYTE PTR [eax+10],'r' - ;jne NoDebuggerOnColor - ;cmp BYTE PTR [eax+12],'o' - ;jne NoDebuggerOnColor - ;cmp BYTE PTR [eax+14],'l' - ;jne NoDebuggerOnColor - ;jmp ActiveDebugger - ;NoDebuggerOnColor: - ; First, see if there is a mono debugger... - - ;mov eax, 0b0000h ; 4096 = offset to mono video mem - ;cmp BYTE PTR [eax+2],'C' - ;jne NoActiveDebugger - ;cmp BYTE PTR [eax+4],'o' - ;jne NoActiveDebugger - ;cmp BYTE PTR [eax+6],'n' - ;jne NoActiveDebugger - ;cmp BYTE PTR [eax+8],'t' - ;jne NoActiveDebugger - ;cmp BYTE PTR [eax+10],'r' - ;jne NoActiveDebugger - ;cmp BYTE PTR [eax+12],'o' - ;jne NoActiveDebugger - ;cmp BYTE PTR [eax+14],'l' - ;jne NoActiveDebugger - - mov eax, 0b0000h ; 4096 = offset to mono video mem - add eax, 24*80*2 - - - cmp BYTE PTR [eax+0],'D' - jne NextTest - cmp BYTE PTR [eax+2],'B' - jne NextTest - cmp BYTE PTR [eax+4],'G' - jne NextTest - cmp BYTE PTR [eax+6],'>' - jne NextTest - - ;Found DBG>, so consider debugger active: - jmp ActiveDebugger - -NextTest: - cmp BYTE PTR [eax+14],'<' - jne NextTest1 - cmp BYTE PTR [eax+16],'i' - jne NextTest1 - cmp BYTE PTR [eax+18],'>' - jne NextTest1 - cmp BYTE PTR [eax+20],' ' - jne NextTest1 - cmp BYTE PTR [eax+22],'-' - jne NextTest1 - - ; Found - , so consider debugger active: - jmp ActiveDebugger - -NextTest1: - cmp BYTE PTR [eax+0], 200 - jne NextTest2 - cmp BYTE PTR [eax+2], 27 - jne NextTest2 - cmp BYTE PTR [eax+4], 17 - jne NextTest2 - - ; Found either the help screen or view screen, so consider - ; debugger active - jmp ActiveDebugger - -NextTest2: - ; Now we see if its active by looking for the "Executing..." - ; text on the bottom of the mono screen - ;mov eax, 0b0000h ; 4096 = offset to mono video mem - ;add eax, 24*80*2 - ;cmp BYTE PTR [eax+0],'E' - ;je NoActiveDebugger - ;cmp BYTE PTR [eax+2],'x' - ;je NoActiveDebugger - ;cmp BYTE PTR [eax+4],'e' - ;je NoActiveDebugger - ;cmp BYTE PTR [eax+6],'c' - ;je NoActiveDebugger - -NoActiveDebugger: - pop eax - clc - ret - -ActiveDebugger: - pop eax - stc - ret - -ENDIF - -_TEXT ENDS - - END +; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. +; $Log: not supported by cvs2svn $ +; Revision 1.2 1994/02/17 15:55:59 john +; Initial version +; +; Revision 1.20 1994/01/18 10:58:55 john +; *** empty log message *** +; +; Revision 1.19 1993/12/22 13:28:40 john +; Added back changes Matt made in r1.14 +; +; Revision 1.18 1993/12/22 13:18:32 john +; *** empty log message *** +; +; Revision 1.17 1993/12/20 16:48:47 john +; Put cli/sti around clear keybuffer in key_close +; +; Revision 1.16 1993/12/20 15:39:13 john +; Tried to neaten handler code... also, moved some cli's and sti's around +; trying to find bug. Made the code call key_get_milliseconds instead +; of timer_get_milliseconds, because we don't want the cli and sti +; stuff in the interrupt handler. +; +; Revision 1.15 1993/12/02 10:54:48 john +; Made the Ctrl,Shift,Alt keys buffer like all the other keys. +; +; Revision 1.14 1993/10/29 11:25:18 matt +; Made key_down_time() not accumulate time if shift,alt,ctrl down +; +; Revision 1.13 1993/10/29 10:47:00 john +; *** empty log message *** +; +; Revision 1.12 1993/10/16 19:24:16 matt +; Added new function key_clear_times() & key_clear_counts() +; +; Revision 1.11 1993/10/15 10:16:49 john +; bunch of stuff, mainly with detecting debugger. +; +; Revision 1.10 1993/10/04 13:25:57 john +; Changed the way extended keys are processed. +; +; Revision 1.9 1993/09/28 11:35:32 john +; added key_peekkey +; +; Revision 1.8 1993/09/23 18:09:23 john +; fixed bug checking for DBG +; +; Revision 1.7 1993/09/23 17:28:01 john +; made debug check look for DBG> instead of CONTROL +; +; Revision 1.6 1993/09/20 17:08:19 john +; Made so that keys pressed in debugger don't get passed through to +; the keyboard handler. I also discovered, but didn't fix a error +; (page fault) caused by jumping back and forth between the debugger +; and the program... +; +; Revision 1.5 1993/09/17 09:58:12 john +; Added checks for already installed, not installed, etc. +; +; Revision 1.4 1993/09/15 17:28:00 john +; Fixed bug in FlushBuffer that used CX before a REP instead of ECX. +; +; Revision 1.3 1993/09/08 14:48:00 john +; made getch() return an int instead of a char that has shift states, etc. +; +; Revision 1.2 1993/07/22 13:12:23 john +; fixed comment +; ,. +; +; Revision 1.1 1993/07/10 13:10:42 matt +; Initial revision +; +; +; + +;*************************************************************************** +;*************************************************************************** +;***** ***** +;***** ***** +;***** K E Y . A S M ***** +;***** ***** +;***** Contains routines to get, buffer, and check key presses. ***** +;***** ***** +;***** ***** +;***** PROCEDURES ***** +;***** ***** +;***** key_init() - Activates the keyboard package. ***** +;***** key_close() - Deactivates the keyboard package. ***** +;***** key_check() - Returns 1 if a buffered key is waiting. ***** +;***** key_getch() - Waits for and returns a buffered keypress. ***** +;***** key_flush() - Clears buffers and state array. ***** +;***** key_time() - Index by scan code. Contains the time key has been ***** +;***** held down. NOT DONE YET. ***** +;***** ***** +;***** ***** +;***** VARIABLES ***** +;***** ***** +;***** keyd_buffer_type -Set to 0 and key_getch() always returns 0. ***** +;***** Set to 1 to so that ASCII codes are returned ***** +;***** by key_getch(). Set to 2 and key_getch() returns***** +;***** the buffered keyboard scan codes. ***** +;***** keyd_repeat - Set to 0 to not allow repeated keys in the ***** +;***** keyboard buffer. Set to 1 to allow repeats. ***** +;***** keyd_pressed[] -Index by scan code. Contains 1 if key down else 0***** +;***** ***** +;***** ***** +;***** CONSTANTS ***** +;***** ***** +;***** Setting the DEBUG to 1 at compile time passes SysReq through ***** +;***** to the debugger, and when the debugger is active, it will give ***** +;***** the debugger any keys that are pressed. Note that this only ***** +;***** works with the Watcom VIDEO debugger at this time. Setting ***** +;***** DEBUG to 0 takes out all the debugging stuff. ***** +;***** ***** +;*************************************************************************** +;*************************************************************************** + +DEBUG EQU 1 +.386 + +;************************************************************************ +;**************** FLAT MODEL DATA SEGMENT STUFF ************************* +;************************************************************************ + +_DATA SEGMENT BYTE PUBLIC USE32 'DATA' + +rcsid db "$Id: oldkey.asm,v 1.1.1.2 2001-01-19 03:33:50 bradleyb Exp $" + +PUBLIC _keyd_pressed ; Must start with a _ so C can see the variable. + + _keyd_pressed db 256 dup (?) + + keybuffer dw 256 dup (?) ; Use 256 so an inc wraps around + + TimeKeyWentDown dd 256 dup(0) + TimeKeyHeldDown dd 256 dup(0) + NumDowns dd 256 dup(0) + NumUps dd 256 dup(0) + + MyCodeSegment dw ? + +PUBLIC _keyd_editor_mode + + _keyd_editor_mode db 0 + +PUBLIC _keyd_use_bios + + _keyd_use_bios db 1 + +PUBLIC _keyd_last_pressed + _keyd_last_pressed db 0 +PUBLIC _keyd_last_released + _keyd_last_released db 0 + +PUBLIC _keyd_dump_key_array + _keyd_dump_key_array db 0 + org_int_sel dw ? + org_int_off dd ? + + interrupted_cs dw ? + interrupted_eip dd ? + + keyhead db ? + keytail db ? +PUBLIC _keyd_buffer_type +PUBLIC _keyd_repeat + _keyd_buffer_type db ? ; 0=No buffer, 1=buffer ASCII, 2=buffer scans + _keyd_repeat db ? + + E0Flag db 0 + + Installed db 0 + +INCLUDE KEYS.INC + + +_DATA ENDS + +DGROUP GROUP _DATA + + +;************************************************************************ +;**************** FLAT MODEL CODE SEGMENT STUFF ************************* +;************************************************************************ + +_TEXT SEGMENT BYTE PUBLIC USE32 'CODE' + + ASSUME ds:_DATA + ASSUME cs:_TEXT + +key_get_milliseconds: + EXTERNDEF timer_get_stamp64:NEAR + + push ebx + push edx + + call timer_get_stamp64 + + ; Timing in milliseconds + ; Can be used for up to 1000 hours + shld edx, eax, 21 ; Keep 32+11 bits + shl eax, 21 + mov ebx, 2502279823 ; 2^21*1193180/1000 + div ebx + + pop edx + pop ebx + + ret + +;************************************************************************ +;************************************************************************ +;***** ***** +;***** K E Y _ T O _ A S C I I _ ***** +;***** ***** +;************************************************************************ +;************************************************************************ + +PUBLIC key_to_ascii_ + +key_to_ascii_: + + ; EAX = scancode + push ebx + + mov bl, ah + and bl, 011111110b + cmp bl, 0 + jne CantDoKey + + cmp al, 127 + jae CantDoKey + + and ah, 01b ; take away ctrl and alt codes + shl al, 1 + shr eax, 1 + and eax, 0ffh + mov al, byte ptr key1[eax] + pop ebx + ret + +CantDoKey: + pop ebx + mov eax, 255 + ret + + +public key_clear_times_,key_clear_counts_ + +;clear the array of key down times. +key_clear_times_: + cli + push eax + push ecx + push edi + xor eax,eax + mov ecx,256 + lea edi,TimeKeyHeldDown + rep stosd ;clear array + pop edi + pop ecx + pop eax + sti + ret + +;clear the arrays of key down counts +key_clear_counts_: + cli + push eax + push ecx + push edi + xor eax,eax + mov ecx,256 + lea edi,NumDowns + rep stosd ;clear array + mov ecx,256 + lea edi,NumUps + rep stosd ;clear array + pop edi + pop ecx + pop eax + sti + ret + + +PUBLIC key_down_time_ + +key_down_time_: + cli + + push edx + push ecx + push ebx + + + mov ebx, eax + xor eax, eax + + cmp _keyd_pressed[ebx], 0 + je NotPressed + + + cmp _keyd_editor_mode, 0 + je read_time + + call get_modifiers ;shift,alt,ctrl? + or ah,ah + jz read_time + xor eax,eax + jmp NotPressed + +read_time: mov ecx, TimeKeyWentDown[ebx*4] + call key_get_milliseconds + mov TimeKeyWentDown[ebx*4], eax + sub eax, ecx ; EAX = time held since last + +NotPressed: + add eax, TimeKeyHeldDown[ebx*4] + mov TimeKeyHeldDown[ebx*4], 0 + + pop ebx + pop ecx + pop edx + sti + ret + +PUBLIC key_down_count_ +key_down_count_: + cli + push ebx + mov ebx, eax + mov eax, NumDowns[ebx*4] + mov NumDowns[ebx*4], 0 + pop ebx + sti + ret + +PUBLIC key_up_count_ +key_up_count_: + cli + push ebx + mov ebx, eax + mov eax, NumUps[ebx*4] + mov NumUps[ebx*4], 0 + pop ebx + sti + ret + + + +;************************************************************************ +;************************************************************************ +;***** ***** +;***** K E Y _ F L U S H ***** +;***** ***** +;************************************************************************ +;************************************************************************ + +PUBLIC key_flush_ + +key_flush_: + cli + + push eax + push ecx + push edi + + mov keyhead,0 + mov keytail,255 + mov E0Flag, 0 + + ; Clear the keyboard array + mov edi, offset _keyd_pressed + mov ecx, 32 + mov eax,0 + rep stosd + + pop edi + pop ecx + pop eax + sti + ret + +;************************************************************************ +;************************************************************************ +;***** ***** +;***** K E Y _ I N I T ***** +;***** ***** +;************************************************************************ +;************************************************************************ + +PUBLIC key_init_ + +key_init_: + push eax + push ebx + push ds + push es + + ;************************************************************** + ;******************* INITIALIZE key QUEUE ********************** + ;************************************************************** + + mov _keyd_buffer_type,1 + mov _keyd_repeat,1 + mov E0Flag, 0 + + ; Clear the keyboard array + call key_flush_ + + cmp Installed, 0 + jne AlreadyInstalled + + ;************************************************************** + ;******************* SAVE OLD INT9 HANDLER ******************** + ;************************************************************** + + mov Installed, 1 + + mov eax, 03509h ; DOS Get Vector 09h + int 21h ; Call DOS + mov org_int_sel, es ; Save old interrupt selector + mov org_int_off, ebx ; Save old interrupt offset + + + ;************************************************************** + ;***************** INSTALL NEW INT9 HANDLER ******************* + ;************************************************************** + + mov eax, 02509h ; DOS Set Vector 09h + mov edx, offset key_handler ; Point DS:EDX to new handler + mov bx, cs + mov MyCodeSegment, bx + mov ds, bx + int 21h + + +AlreadyInstalled: + + pop es + pop ds + pop ebx + pop eax + + ret + + +;************************************************************************ +;************************************************************************ +;***** ***** +;***** K E Y _ C L O S E _ ***** +;***** ***** +;************************************************************************ +;************************************************************************ + +PUBLIC key_close_ + +key_close_: + push eax + push ebx + push edx + push ds + + + cmp Installed, 0 + je @f + + ;************************************************************** + ;***************** RESTORE OLD INT9 HANDLER ******************* + ;************************************************************** + + mov Installed, 0 + + ; Clear the BIOS buffer + cli + mov ebx, 041ch + mov al, byte ptr [ebx] + mov ebx, 041ah + mov byte ptr [ebx], al + sti + + mov eax, 02509h ; DOS Set Vector 09h + mov edx, org_int_off + mov ds, org_int_sel + int 21h + +@@: pop ds + pop edx + pop ebx + pop eax + + ret + +;************************************************************************ +;************************************************************************ +;***** ***** +;***** K E Y _ C H E C K _ ***** +;***** ***** +;************************************************************************ +;************************************************************************ + +PUBLIC key_checkch_ ; Must end with a _ so C can see the function. + +key_checkch_: + cli + push ebx + + xor eax, eax + cmp Installed, 0 + je NoKey + + mov bl, keytail + inc bl + cmp bl, keyhead + je Nokey + mov eax, 1 +Nokey: + pop ebx + sti + ret + +;************************************************************************ +;************************************************************************ +;***** ***** +;***** K E Y _ D E B U G ***** +;***** ***** +;************************************************************************ +;************************************************************************ + +PUBLIC key_debug_ +key_debug_: + int 3h + ret + + +;************************************************************************ +;************************************************************************ +;***** ***** +;***** K E Y _ G E T C H _ ***** +;***** ***** +;************************************************************************ +;************************************************************************ + +PUBLIC key_getch_ ; Must end with a _ so C can see the function. + +key_getch_: + push ebx + + xor eax, eax + xor ebx, ebx + cmp Installed, 0 + jne StillNoKey + pop ebx + ret + +StillNoKey: + cli ; Critical section + mov bl, keytail + inc bl + cmp bl, keyhead + sti + je StillNoKey + + cli ; Critical section + xor ebx, ebx + mov bl, keyhead + mov ax, word ptr keybuffer[ebx*2] + inc BYTE PTR keyhead + sti + + pop ebx + ret + + +;************************************************************************ +;************************************************************************ +;***** ***** +;***** K E Y _ I N K E Y _ ***** +;***** ***** +;************************************************************************ +;************************************************************************ + +PUBLIC key_inkey_ ; Must end with a _ so C can see the function. + +key_inkey_: + push ebx + + xor eax, eax + xor ebx, ebx + + cmp Installed, 0 + je NoInkey + + cli ; Critical section + mov bl, keytail + inc bl + cmp bl, keyhead + sti + je NoInkey + + cli ; Critical section + mov bl, keyhead + mov ax, word ptr keybuffer[ebx*2] + inc BYTE PTR keyhead + sti +NoInkey: + pop ebx + ret + +PUBLIC key_peekkey_ ; Must end with a _ so C can see the function. + +key_peekkey_: + push ebx + + xor eax, eax + xor ebx, ebx + + cli ; Critical section + + cmp Installed, 0 + je NoPeek + mov bl, keytail + inc bl + cmp bl, keyhead + je NoPeek + mov bl, keyhead + mov ax, word ptr keybuffer[ebx*2] + +NoPeek: sti + pop ebx + ret + + + +;************************************************************************ +;************************************************************************ +;***** ***** +;***** K E Y _ H A N D L E R ***** +;***** ***** +;************************************************************************ +;************************************************************************ + +PUBLIC key_handler ; Must end with a _ so C can see the function. + +key_handler: + + pushfd ; Save flags in case we have to chain to original + push eax + push ebx + push ecx + push edx + push ds + + mov ax, DGROUP ; Point to our data segment, since this is an + mov ds, ax ; interrupt and we don't know where we were. + + mov eax, (0b0000h+76*2) + mov byte ptr [eax], '1' + +IFDEF DEBUG + call CheckForDebugger + jnc @f + mov eax, 0b0000h+78*2 + mov byte ptr [eax], 'D' + jmp PassToBios ; If debugger is active, then skip buffer + +@@: mov eax, 0b0000h+78*2 + mov byte ptr [eax], 'I' + + ; Clear the BIOS buffer + ;**mov ebx, 041ch + ;**mov al, byte ptr [ebx] + ;**mov ebx, 041ah + ;**mov byte ptr [ebx], al +ENDIF + + xor eax, eax + xor ebx, ebx + + in al, 060h ; Get scan code from keyboard + + cmp al, 0E0h + jne NotE0Code + +E0Code: mov E0Flag, 010000000b + jmp LeaveHandler ; If garbage key, then don't buffer it + +NotE0Code: mov bl, al ; Put break bit into bl ; 0 = pressed, 1=released + and al, 01111111b ; AL = scancode + or al, E0Flag ; AL = extended scancode + mov E0Flag,0 ; clear E0 flag + cmp al, 029h + je pause_execution + shl bl, 1 ; put upper bit into carry flag + jc key_mark_released ; if upper bit of bl was set, then it was a release code + +;************************************************************** +;****************** HANDLE A NEWLY PRESSED KEY **************** +;************************************************************** +;Marks the key press in EAX in the scancode array. + +key_mark_pressed: + ;cmp al, 0eh ; backspace + ;je pause_execution + + mov _keyd_last_pressed, al + ; Check if the key is repeating or if it just got pressed. + cmp byte ptr _keyd_pressed[eax], 1 + je AlreadyDown + +;------------------------------- Code for a key pressed for the first time ------------------------ + mov byte ptr _keyd_pressed[eax], 1 + ; Set the time + + push edx + push eax + call key_get_milliseconds + mov edx, eax + pop eax + mov TimeKeyWentDown[eax*4], edx + pop edx + + inc NumDowns[eax*4] + + jmp BufferAX + +;------------------------------- Code for a key that is already pressed ------------------------ +AlreadyDown: + cmp _keyd_repeat, 0 + je DoneMarkingPressed + +BufferAX: + cmp _keyd_buffer_type, 0 + je SkipBuffer ; Buffer = 0 means don't buffer anything. + + cmp al, 0AAh ; garbage key + je SkipBuffer + + call get_modifiers ;returns ah + + xor ebx, ebx + mov bl, keytail + inc bl + inc bl + + ; If the buffer is full then don't buffer this key + cmp bl, keyhead + je SkipBuffer + dec bl + + mov word ptr keybuffer[ebx*2], ax + mov keytail, bl + +SkipBuffer: + +;---------------------------------- Exit function ----------------------------- +DoneMarkingPressed: + jmp LeaveHandler + +;************************************************************** +;******************* HANDLE A RELEASED KEY ******************** +;************************************************************** +; Unmarks the key press in EAX from the scancode array. +key_mark_released: + + mov _keyd_last_released, al + mov byte ptr _keyd_pressed[eax], 0 + inc NumUps[eax*4] + + cmp _keyd_editor_mode, 0 + je NotInEditorMode + push eax + xor ah,ah + call get_modifiers + or ah,ah ;check modifiers + pop eax + jnz skip_time + +NotInEditorMode: + push eax + + call timer_get_stamp64 + + ; Timing in milliseconds + ; Can be used for up to 1000 hours + shld edx, eax, 21 ; Keep 32+11 bits + shl eax, 21 + mov ebx, 2502279823 ; 2^21*1193180/1000 + div ebx + + mov edx, eax + pop eax + sub edx, TimeKeyWentDown[eax*4] + add TimeKeyHeldDown[eax*4], edx + +skip_time: ;**jmp LeaveHandler + +;************************************************************** +;*************** FINISH UP THE KEYBOARD INTERRUPT ************* +;************************************************************** +LeaveHandler: + mov eax, (0b0000h+76*2) + mov byte ptr [eax], '2' + +;; cmp _keyd_dump_key_array, 0 +;; je DontPassToBios + jmp PassToBios + + mov ecx, 256 + mov ebx, 0 + +showdown: mov al, _keyd_pressed[ebx] + add al, '0' + mov [ebx*2+ 0b0000h], al + inc ebx + loop showdown + + mov eax, 0b0000h + mov byte ptr [ eax+(036h*2+1) ], 070h + mov byte ptr [ eax+(02Ah*2+1) ], 070h + mov byte ptr [ eax+(038h*2+1) ], 070h + mov byte ptr [ eax+(0B8h*2+1) ], 070h + mov byte ptr [ eax+(01Dh*2+1) ], 070h + mov byte ptr [ eax+(09dh*2+1) ], 070h + + mov byte ptr [ eax+(0AAh*2+1) ], 07Fh + mov byte ptr [ eax+(0E0h*2+1) ], 07Fh + + jmp DontPassToBios + + +; If in debugger, pass control to dos interrupt. + +PassToBios: pop ds ; Nothing left on stack but flags + pop edx + pop ecx + pop ebx + pop eax + + sub esp, 8 ; Save space for IRETD frame + push ds ; Save registers we use. + push eax + mov ax, DGROUP + mov ds, ax ; Set DS to our data segment + mov eax, org_int_off ; put original handler address + mov [esp+8], eax ; in the IRETD frame + movzx eax, org_int_sel + mov [esp+12], eax + pop eax ; Restore registers + pop ds + iretd ; Chain to previous handler + +pause_execution: + in al, 61h ; Get current port 61h state + or al, 10000000b ; Turn on bit 7 to signal clear keybrd + out 61h, al ; Send to port + and al, 01111111b ; Turn off bit 7 to signal break + out 61h, al ; Send to port + mov al, 20h ; Reset interrupt controller + out 20h, al + sti ; Reenable interrupts + pop ds + pop edx ; Restore all of the saved registers. + pop ecx + pop ebx + pop eax + + sub esp, 8 ; Save space for IRETD frame + push ds ; Save registers we use. + push eax + mov ax, DGROUP + mov ds, ax ; Set DS to our data segment + mov eax, org_int_off ; put original handler address + mov [esp+8], eax ; in the IRETD frame + movzx eax, org_int_sel + mov [esp+12], eax + pop eax ; Restore registers + pop ds + + iretd ; Interrupt must return with IRETD + +DontPassToBios: + +; Resets the keyboard, PIC, restores stack, returns. + in al, 61h ; Get current port 61h state + or al, 10000000b ; Turn on bit 7 to signal clear keybrd + out 61h, al ; Send to port + and al, 01111111b ; Turn off bit 7 to signal break + out 61h, al ; Send to port + mov al, 20h ; Reset interrupt controller + out 20h, al + sti ; Reenable interrupts + pop ds + pop edx ; Restore all of the saved registers. + pop ecx + pop ebx + pop eax + popfd + iretd ; Interrupt must return with IRETD + +;returns ah=bitmask of shift,ctrl,alt keys +get_modifiers: push ecx + + xor ah,ah + + ; Check the shift keys + mov cl, _keyd_pressed[ 036h ] + or cl, _keyd_pressed[ 02ah ] + or ah, cl + + ; Check the alt key + mov cl, _keyd_pressed[ 038h ] + or cl, _keyd_pressed[ 0b8h ] + shl cl, 1 + or ah, cl + + ; Check the ctrl key + mov cl, _keyd_pressed[ 01dh ] + or cl, _keyd_pressed[ 09dh ] + shl cl, 2 + or ah, cl + + pop ecx + ret + +IFDEF DEBUG +CheckForDebugger: + ; Returns CF=0 if debugger isn't active + ; CF=1 if debugger is active + + ;*************************** DEBUG ****************************** + ; When we're in the VIDEO debugger, we want to pass control to + ; the original interrupt. So, to tell if the debugger is active, + ; I check if video page 1 is the active page since that is what + ; page the debugger uses, and if that works, I check the top of + ; the screen to see if the texxt "Control" is there, which should + ; only be there when we're in the debugger. + + + + push eax + ;mov eax, 0462h ; Address 0462 stores BIOS current page + ;cmp BYTE PTR [eax], 1 + ;jne NoDebuggerOnColor + ;mov eax, 0b8000h+4096 ; 4096 = offset to 2nd video mem page + ;cmp BYTE PTR [eax+2],'C' + ;jne NoDebuggerOnColor + ;cmp BYTE PTR [eax+4],'o' + ;jne NoDebuggerOnColor + ;cmp BYTE PTR [eax+6],'n' + ;jne NoDebuggerOnColor + ;cmp BYTE PTR [eax+8],'t' + ;jne NoDebuggerOnColor + ;cmp BYTE PTR [eax+10],'r' + ;jne NoDebuggerOnColor + ;cmp BYTE PTR [eax+12],'o' + ;jne NoDebuggerOnColor + ;cmp BYTE PTR [eax+14],'l' + ;jne NoDebuggerOnColor + ;jmp ActiveDebugger + ;NoDebuggerOnColor: + ; First, see if there is a mono debugger... + + ;mov eax, 0b0000h ; 4096 = offset to mono video mem + ;cmp BYTE PTR [eax+2],'C' + ;jne NoActiveDebugger + ;cmp BYTE PTR [eax+4],'o' + ;jne NoActiveDebugger + ;cmp BYTE PTR [eax+6],'n' + ;jne NoActiveDebugger + ;cmp BYTE PTR [eax+8],'t' + ;jne NoActiveDebugger + ;cmp BYTE PTR [eax+10],'r' + ;jne NoActiveDebugger + ;cmp BYTE PTR [eax+12],'o' + ;jne NoActiveDebugger + ;cmp BYTE PTR [eax+14],'l' + ;jne NoActiveDebugger + + mov eax, 0b0000h ; 4096 = offset to mono video mem + add eax, 24*80*2 + + + cmp BYTE PTR [eax+0],'D' + jne NextTest + cmp BYTE PTR [eax+2],'B' + jne NextTest + cmp BYTE PTR [eax+4],'G' + jne NextTest + cmp BYTE PTR [eax+6],'>' + jne NextTest + + ;Found DBG>, so consider debugger active: + jmp ActiveDebugger + +NextTest: + cmp BYTE PTR [eax+14],'<' + jne NextTest1 + cmp BYTE PTR [eax+16],'i' + jne NextTest1 + cmp BYTE PTR [eax+18],'>' + jne NextTest1 + cmp BYTE PTR [eax+20],' ' + jne NextTest1 + cmp BYTE PTR [eax+22],'-' + jne NextTest1 + + ; Found - , so consider debugger active: + jmp ActiveDebugger + +NextTest1: + cmp BYTE PTR [eax+0], 200 + jne NextTest2 + cmp BYTE PTR [eax+2], 27 + jne NextTest2 + cmp BYTE PTR [eax+4], 17 + jne NextTest2 + + ; Found either the help screen or view screen, so consider + ; debugger active + jmp ActiveDebugger + +NextTest2: + ; Now we see if its active by looking for the "Executing..." + ; text on the bottom of the mono screen + ;mov eax, 0b0000h ; 4096 = offset to mono video mem + ;add eax, 24*80*2 + ;cmp BYTE PTR [eax+0],'E' + ;je NoActiveDebugger + ;cmp BYTE PTR [eax+2],'x' + ;je NoActiveDebugger + ;cmp BYTE PTR [eax+4],'e' + ;je NoActiveDebugger + ;cmp BYTE PTR [eax+6],'c' + ;je NoActiveDebugger + +NoActiveDebugger: + pop eax + clc + ret + +ActiveDebugger: + pop eax + stc + ret + +ENDIF + +_TEXT ENDS + + END diff --git a/unused/bios/rbaudio.new b/unused/bios/rbaudio.new index 956b8b70..6a382c6a 100644 --- a/unused/bios/rbaudio.new +++ b/unused/bios/rbaudio.new @@ -1,736 +1,736 @@ -/* - * $Source: /cvs/cvsroot/d2x/unused/bios/rbaudio.new,v $ - * $Revision: 1.1.1.1 $ - * $Author: bradleyb $ - * $Date: 2001-01-19 03:30:14 $ - * - * Redbook Audio Library - * - * $Log: not supported by cvs2svn $ - * Revision 1.18 1996/04/15 15:27:40 samir - * Play multiple tracks and PeekPlayStatus uses timer method! - * - * Revision 1.17 1996/04/12 20:08:42 samir - * Added debugging info and Redbook / HSG detection - * - * Revision 1.16 1996/04/12 19:13:29 matt - * Changed parameter name and added comments - * - * Revision 1.15 1996/04/12 18:08:02 samir - * We now pass a cd drive letter to RBAInit. - * - * Revision 1.14 1996/02/14 13:31:29 samir - * Fixed stupid bug that caused last track to never be played - * - * Revision 1.13 1996/02/13 17:16:04 samir - * Added Pause and Resume Caps. - * - * Revision 1.12 1996/01/11 10:08:01 matt - * RBARegisterCD wasn't checking SendRequest error code, so it was reporting - * CD tracks when there was no CD in the drive. - * - * Revision 1.11 1996/01/10 20:15:45 samir - * Changed behavior of RBACheckMediaChange to work - * correctly, as well as calling this function in critical - * RBA functions to take care of CD changes. - * - * Revision 1.10 1996/01/10 18:30:49 samir - * Changed property of RBCheckMediaChange which would - * not disable RBA if media had changed. GetNumberOfTracks - * returns num. of tracks or if media changed, re-registers - * CD and then returns number of tracks. If media has changed - * RBAPlayTrack will return an error. - * - * Revision 1.9 1995/08/01 19:30:11 samir - * Added ability to get number of tracks on CD via call. - * - * Revision 1.8 1995/07/20 16:13:56 samir - * Doesn't quit if CD isn't Redbook. - * - * Revision 1.7 1995/05/10 11:37:51 samir - * Checks whether CD-ROM in drive at start of game - * - * Revision 1.6 1995/05/09 18:00:08 samir - * Error cleaned. - * - * Revision 1.5 1995/05/09 17:57:43 samir - * No CD in Drive, then diable RBA - * - * Revision 1.4 1995/05/09 17:12:24 samir - * Added user detection of Redbook Audio. - * - * Revision 1.3 1995/05/09 12:04:57 samir - * Added ability to known when a CD is playing - * and when it's stopped. - * - * Revision 1.2 1995/05/08 11:33:37 samir - * Initial revision - * - * - */ - -char rbaudio_rcsid[] = "$Id: rbaudio.new,v 1.1.1.1 2001-01-19 03:30:14 bradleyb Exp $"; - - -#include -#include -#include - -#include "mono.h" -#include "error.h" -#include "rbaudio.h" -#include "fix.h" -#include "timer.h" - - -#define HSG_CD_PLAYBACK 0 -#define MSF_CD_PLAYBACK 1 - -#define RBERR_WRITEPROTVIOL 0 -#define RBERR_UNKNOWNUNIT 1 -#define RBERR_DRIVENOTREADY 2 -#define RBERR_UNKNOWNCOMMAND 3 -#define RBERR_CRCERROR 4 -#define RBERR_BADDRIVEREQ 5 -#define RBERR_SEEKERROR 6 -#define RBERR_UNKNOWNMEDIA 7 -#define RBERR_SECTORNOTFOUND 8 -#define RBERR_WRITEFAULT 10 -#define RBERR_READFAULT 12 -#define RBERR_GENERALFAILURE 13 -#define RBERR_BADDISKCHANGE 15 - -#define RBSTAT_ERROR 0x8000 -#define RBSTAT_BUSY 0x0200 -#define RBSTAT_DONE 0x0100 - -#pragma pack(1) - - -// Request Header ----------------------------------------------------- - -typedef struct _REQHDR { - unsigned char length; - unsigned char subunit; - unsigned char func; - unsigned short status; - char array[8]; -} REQHDR; - -typedef struct _IOCTL { - char bpb; - unsigned short buffer_realoff; - unsigned short buffer_realseg; - unsigned short xferlen; - unsigned short sector; - unsigned long id; -} IOCTL; - - -// CD Information ----------------------------------------------------- - -static struct { - char code; // Control Block Code - char track; // Track Number - long start; // Start of Track in MSF (Redbook) - unsigned char info; // Track Control Info -} CDTrackInfo = {11,2,0L,0}; - -static struct { - REQHDR reqheader; - IOCTL ioctl; -} TrackInfoREQ = {{13,0,3,0,""}, {0,0,0,0,0}}; - -static struct { - unsigned char code; - unsigned long devstat; -} DevStat = {6,0}; - -static struct { - REQHDR reqhdr; - IOCTL ioctl; -} DevStatREQ = {{13,0,3,0,""}, {0,0,0,0,0}}; - -static struct { - unsigned char code; - char byte; -} MedChg = {9,0}; - -static struct { - REQHDR reqhdr; - IOCTL ioctl; -} MedChgREQ = {{13,0,3,0,""}, {0,0,0,0,0}}; - -static struct { - REQHDR reqhdr; -} StopREQ = {{13,0,133,0,""}}; - -static struct { - REQHDR reqhdr; -} ResumeREQ = {{13,0,136,0,""}}; - -static struct { - unsigned char code; - unsigned char first; - unsigned char last; - unsigned long lead_out; -} CDInfo = {10,0,0,0L}; - -static struct { - REQHDR reqhdr; - IOCTL ioctl; -} CDInfoREQ = {{13,0,3,0,""},{0,0,0,0,0}}; - -static struct { - REQHDR reqheader; - char mode; // Play in HSG or MSF(RedBook) - unsigned long playbeg; - unsigned long playlen; // HSG Format - char empty; // Empty byte used so that all requests have same size -} PlayREQ = {{13,0,132,0,""},0,0,0,0}; - -static struct { - unsigned char code; - unsigned char out0in; - unsigned char out0vol; - unsigned char out1in; - unsigned char out1vol; - unsigned char out2in; - unsigned char out2vol; - unsigned char out3in; - unsigned char out3vol; -} AUDChannelCtl = {3,0,0,0,0,0,0,0,0}; - -static struct { - REQHDR reqhdr; - IOCTL ioctl; -} AUDChannelCtlREQ = {{13,0,12,0,""},{0,0,0,0,0}}; - -static struct { - unsigned char code; - unsigned char out0in; - unsigned char out0vol; - unsigned char out1in; - unsigned char out1vol; - unsigned char out2in; - unsigned char out2vol; - unsigned char out3in; - unsigned char out3vol; -} AUDChannelInfo = {4,0,0,0,0,0,0,0,0}; - -static struct { - REQHDR reqhdr; - IOCTL ioctl; -} AUDChannelInfoREQ = {{13,0,3,0,""},{0,0,0,0,0}}; - -static struct { - unsigned char code; - unsigned char mode; - unsigned long headloc; -} HeadInfo = {1,MSF_CD_PLAYBACK,0L}; - -static struct { - REQHDR reqhdr; - IOCTL ioctl; -} HeadInfoREQ = {{13,0,3,0,""},{0,0,0,0,0}}; - -//@@static struct { -//@@ ubyte code; -//@@ ubyte adr; -//@@ ubyte tno; -//@@ ubyte point; -//@@ ubyte min; -//@@ ubyte sec; -//@@ ubyte frame; -//@@ ubyte zero; -//@@ ubyte pmin; -//@@ ubyte psec; -//@@ ubyte pframe; -//@@} QChannelInfo = {12, MSF_CD_PLAYBACK, 2,0,0,0,0,0,0,0,0 }; -//@@ -//@@static struct { -//@@ REQHDR reqhdr; -//@@ IOCTL ioctl; -//@@} QChannelInfoREQ = {{13, 0, 3, 0, ""}, {0,0,0,0,0}}; - - -// Translation from RealMode->Protected mode buffer - -typedef struct _REQ_xlatbuf { // Buffer for Real Mode Callback - REQHDR reqheader; - char ioctl[10]; -} REQ_xlatbuf; - - - -// Other Data --------------------------------------------------------- - -static unsigned char CDDriveLetter; -static unsigned long CDNumTracks,CDTrackStart[101]; -static int RedBookEnabled = 0; -static int RedBookPlaybackType = MSF_CD_PLAYBACK; -static fix Playback_Start_Time = 0; -static fix Playback_Pause_Time = 0; -static fix Playback_Length = 0; - - -// Prototypes --------------------------------------------------------- - -int RBSendRequest(char *request, char *xferptr, int xferlen); -unsigned long msf_to_lsn(unsigned long msf); -unsigned long lsn_to_msf(unsigned long lsn); - - -// -------------------------------------------------------------------- - -void RBAInit(ubyte cd_drive_num) //drive a == 0, drive b == 1 -{ - union REGS regs; - -// Detect presence of CD-ROM - regs.x.eax = 0x1500; - regs.x.ebx = 0; - int386(0x2f, ®s, ®s); - - if (regs.x.ebx == 0) - RBADisable(); // Disable RedBook - // Error("RBA Error: MSCDEX.EXE compatible driver couldn't be found."); - else { - CDDriveLetter = cd_drive_num; -// CDDriveLetter = (unsigned char)regs.x.ecx; - - RBAEnable(); - RBACheckMediaChange(); - - RBSendRequest((char*)&DevStatREQ, (char*)&DevStat, sizeof(DevStat)); - - // If Door drive open, or no disc in CD-ROM, then Redbook is Disabled. - if ((DevStat.devstat&2048) || (DevStat.devstat&1) || RBAEnabled() == 0) - RBADisable(); - -//@@ if (DevStat.devstat&4) -//@@ mprintf((0, "supports cooked and raw reading.\n")); -//@@ else -//@@ mprintf((0, "supports only cooked reading.\n")); -//@@ -//@@ if (DevStat.devstat&256) -//@@ mprintf((0, "audio channel manipulation.\n")); -//@@ else -//@@ mprintf((0, "no audio channel manipulation.\n")); - - if (DevStat.devstat&512) { -// RedBookPlaybackType = MSF_CD_PLAYBACK; - mprintf((0, "supports HSG and RedBook addressing mode.\n")); - } - else { -// RedBookPlaybackType = HSG_CD_PLAYBACK; - mprintf((0, "supports HSG addressing only.\n")); - } - - RedBookPlaybackType = MSF_CD_PLAYBACK; - - } -} - -//find out how many tracks on the CD, and their starting locations -void RBARegisterCD(void) -{ - int i; - int error; - - // Get CD Information First - RBACheckMediaChange(); - - error = RBSendRequest((char*)&CDInfoREQ, (char*)&CDInfo, sizeof(CDInfo)); - - if (error & RBSTAT_ERROR) { //error! - CDNumTracks = 0; - return; - } - - CDNumTracks = (CDInfo.last-CDInfo.first)+1; - - // Define Track Starts - for (i=CDInfo.first; i<=CDNumTracks; i++) - { - CDTrackInfo.track = i; - RBSendRequest((char *)&TrackInfoREQ, (char*)&CDTrackInfo, sizeof(CDTrackInfo)); - CDTrackStart[i] = CDTrackInfo.start; - } - - CDTrackStart[i] = CDInfo.lead_out; -} - - -long RBAGetDeviceStatus() -{ - RBSendRequest((char*)&DevStatREQ, (char*)&DevStat, sizeof(DevStat)); - return (long)DevStat.devstat; -} - - -int RBAGetNumberOfTracks(void) -{ - // Get CD Information - if (RBACheckMediaChange()) - RBARegisterCD(); - - return CDNumTracks; -} - - -int RBAPlayTrack(int track) -{ - unsigned long playlen; - int min, sec; - - Playback_Start_Time = 0; - Playback_Length = 0; - - if (track < CDInfo.first || track > CDInfo.last) { - mprintf((0,"CD not Redbook Compatible. Will not play track.\n")); - } -// Error("RBA Error: Track %d doesn't exist on CD!!!", track); - - if (RBACheckMediaChange()) { - mprintf((0, "Unable to play track due to CD change.\n")); - return 0; - } - - // Play the track now!!! - PlayREQ.mode = RedBookPlaybackType; - PlayREQ.playbeg = CDTrackStart[track]; - - if (RedBookPlaybackType == MSF_CD_PLAYBACK) { - PlayREQ.playlen = - msf_to_lsn(CDTrackStart[track+1]) - msf_to_lsn(CDTrackStart[track]); - } - else { - mprintf((1, "RBERR: No! No! No! This shouldn't happen (HSG_CD_PLAYBACK).\n")); - Int3(); - PlayREQ.playlen = CDTrackStart[track+1] - CDTrackStart[track]; - } - RBSendRequest((char *)&PlayREQ,NULL,0); - - playlen = msf_to_lsn(CDTrackStart[track+1]) - msf_to_lsn(CDTrackStart[track]); - playlen = lsn_to_msf(playlen); - min = (int)((playlen >> 16) & 0xFF); - sec = (int)((playlen >> 8) & 0xFF); - - Playback_Start_Time = timer_get_fixed_seconds(); - Playback_Length = i2f(min*60+sec); - - mprintf( (0,"Playing Track %d (len: %d secs)\n", track, min*60+sec) ); - - return 1; -} - -//plays tracks first through last, inclusive -int RBAPlayTracks(int first, int last) -{ - unsigned long playlen; - int min, sec; - - Playback_Start_Time = 0; - Playback_Length = 0; - - if (first < CDInfo.first || last > CDInfo.last) { - mprintf((0,"Invalid start or end track.\n")); - } -// Error("RBA Error: Track %d doesn't exist on CD!!!", track); - - if (RBACheckMediaChange()) { - mprintf((0, "Unable to play track due to CD change.\n")); - return 0; - } - - // Play the track now!!! - PlayREQ.mode = RedBookPlaybackType; - PlayREQ.playbeg = CDTrackStart[first]; - - if (RedBookPlaybackType == MSF_CD_PLAYBACK) { - PlayREQ.playlen = - msf_to_lsn(CDTrackStart[last+1]) - msf_to_lsn(CDTrackStart[first]); - } - else { - mprintf((1, "RBERR: No! No! No! This shouldn't happen (HSG_CD_PLAYBACK).\n")); - Int3(); - PlayREQ.playlen = CDTrackStart[last+1] - CDTrackStart[first]; - } - RBSendRequest((char *)&PlayREQ,NULL,0); - - playlen = msf_to_lsn(CDTrackStart[last+1]) - msf_to_lsn(CDTrackStart[first]); - playlen = lsn_to_msf(playlen); - min = (int)((playlen >> 16) & 0xFF); - sec = (int)((playlen >> 8) & 0xFF); - - Playback_Start_Time = timer_get_fixed_seconds(); - Playback_Length = i2f(min*60+sec); - - mprintf( (0,"Playing Tracks %d-%d (len: %d secs)\n", first,last,min*60+sec) ); - - return 1; -} - - -void RBAPause() -{ - RBSendRequest((char *)&StopREQ, NULL, 0); - Playback_Pause_Time = timer_get_fixed_seconds(); -} - - -int RBAResume() -{ - if (RBACheckMediaChange()) { - RBARegisterCD(); - return RBA_MEDIA_CHANGED; - } - RBSendRequest((char *)&ResumeREQ, NULL, 0); - - Playback_Start_Time += timer_get_fixed_seconds() - Playback_Pause_Time; - - return 1; -} - - -void RBAStop() -{ - if (RBACheckMediaChange()) - RBARegisterCD(); - - RBSendRequest((char *)&StopREQ,NULL,0); -} - - -void RBASetStereoAudio(RBACHANNELCTL *channels) -{ - AUDChannelCtl.out0in = channels->out0in; - AUDChannelCtl.out0vol = channels->out0vol; - AUDChannelCtl.out1in = channels->out1in; - AUDChannelCtl.out1vol = channels->out1vol; - AUDChannelCtl.out2in = AUDChannelCtl.out2vol = 0; - AUDChannelCtl.out3in = AUDChannelCtl.out3vol = 0; - - RBSendRequest((char*)&AUDChannelCtlREQ, (char*)&AUDChannelCtl, sizeof(AUDChannelCtl)); -} - - -void RBASetQuadAudio(RBACHANNELCTL *channels) -{ - AUDChannelCtl.out0in = (unsigned char)channels->out0in; - AUDChannelCtl.out0vol = (unsigned char)channels->out0vol; - AUDChannelCtl.out1in = (unsigned char)channels->out1in; - AUDChannelCtl.out1vol = (unsigned char)channels->out1vol; - AUDChannelCtl.out2in = (unsigned char)channels->out2in; - AUDChannelCtl.out2vol = (unsigned char)channels->out2vol; - AUDChannelCtl.out3in = (unsigned char)channels->out3in; - AUDChannelCtl.out3vol = (unsigned char)channels->out3vol; - - RBSendRequest((char*)&AUDChannelCtlREQ, (char*)&AUDChannelCtl, sizeof(AUDChannelCtl)); -} - - -void RBAGetAudioInfo(RBACHANNELCTL *channels) -{ - RBSendRequest((char*)&AUDChannelInfoREQ, (char*)&AUDChannelInfo, sizeof(AUDChannelInfo)); - - channels->out0in = (int)AUDChannelInfo.out0in; - channels->out0vol = (int)AUDChannelInfo.out0vol; - channels->out1in = (int)AUDChannelInfo.out1in; - channels->out1vol = (int)AUDChannelInfo.out1vol; - channels->out2in = (int)AUDChannelInfo.out2in; - channels->out2vol = (int)AUDChannelInfo.out2vol; - channels->out3in = (int)AUDChannelInfo.out3in; - channels->out3vol = (int)AUDChannelInfo.out3vol; - -} - - -void RBASetChannelVolume(int channel, int volume) -{ - //RBACHANNELCTL channels; - - RBSendRequest((char*)&AUDChannelInfoREQ, (char*)&AUDChannelInfo, sizeof(AUDChannelInfo)); - - AUDChannelCtl.out0in = AUDChannelInfo.out0in; - AUDChannelCtl.out0vol = AUDChannelInfo.out0vol; - AUDChannelCtl.out1in = AUDChannelInfo.out1in; - AUDChannelCtl.out1vol = AUDChannelInfo.out1vol; - AUDChannelCtl.out2in = AUDChannelInfo.out2in; - AUDChannelCtl.out2vol = AUDChannelInfo.out2vol; - AUDChannelCtl.out3in = AUDChannelInfo.out3in; - AUDChannelCtl.out3vol = AUDChannelInfo.out3vol; - - if (channel == 0) AUDChannelCtl.out0vol = (unsigned char)volume; - if (channel == 1) AUDChannelCtl.out1vol = (unsigned char)volume; - if (channel == 2) AUDChannelCtl.out2vol = (unsigned char)volume; - if (channel == 3) AUDChannelCtl.out3vol = (unsigned char)volume; - - RBSendRequest((char*)&AUDChannelCtlREQ,(char*)&AUDChannelCtl, sizeof(AUDChannelCtl)); - -} - - -void RBASetVolume(int volume) -{ - RBASetChannelVolume(0,volume); - RBASetChannelVolume(1,volume); -} - - -long RBAGetHeadLoc(int *min, int *sec, int *frame) -{ - unsigned long loc; - - if (RBACheckMediaChange()) - return RBA_MEDIA_CHANGED; - - HeadInfo.mode = RedBookPlaybackType; - RBSendRequest((char*)&HeadInfoREQ, (char*)&HeadInfo, sizeof(HeadInfo)); - - if (RedBookPlaybackType == MSF_CD_PLAYBACK) - loc = HeadInfo.headloc; - else - loc = lsn_to_msf(HeadInfo.headloc); - - *min = (int)((loc >> 16) & 0xFF); - *sec = (int)((loc >> 8) & 0xFF); - *frame = (int)((loc >> 0) & 0xFF); - - return loc; -} - - -int RBAPeekPlayStatus() -{ - if ((timer_get_fixed_seconds()-Playback_Start_Time) > Playback_Length) return 0; - else return 1; -} - - -int RBAEnabled() -{ - if (RedBookEnabled < 1) return 0; - else return 1; -} - - -void RBAEnable() -{ - RedBookEnabled = 1; - mprintf((0, "Enabling Redbook...\n")); -} - - -void RBADisable() -{ - RedBookEnabled = 0; - mprintf((0, "Disabling Redbook...\n")); -} - - - -// RB functions: Internal to RBA library ----------------------------- - -//returns 1 if media has changed, else 0 -int RBACheckMediaChange() -{ - RBSendRequest((char *)&MedChgREQ, (char*)&MedChg, sizeof(MedChg)); - - if (MedChg.byte == 255 || MedChg.byte == 0) { - // New media in drive (or maybe no media in drive) - mprintf((0,"CD-ROM Media change detected\n")); - return 1; - } - return 0; -} - - -// Send Request - -//returns 16-bit value. Bit 15 means error. -//WE NEED SYMBOLOIC CONSTANTS FOR ALL RETURN CODES & STATUS BITS -int RBSendRequest(char *request, char *xferptr, int xferlen) -{ - //union REGS regs; - dpmi_real_regs rregs; - - IOCTL *ioctl; - REQ_xlatbuf *xlat_req; // Translated Buffer Request - char *xlat_xferptr; // Translated Buffer Transfer Buffer Ptr - - unsigned short status; - - if (!RedBookEnabled) return 0; // Don't send request if no RBA - - memset(&rregs,0,sizeof(dpmi_real_regs)); - -// Get Temporary Real Mode Buffer for request translation - xlat_req = (REQ_xlatbuf *)dpmi_get_temp_low_buffer(128+xferlen); - memcpy(xlat_req, request, sizeof(REQHDR)+sizeof(IOCTL)); - ioctl = (IOCTL *)(((char*)xlat_req)+sizeof(REQHDR)); - -// Set Transfer Buffer in IOCTL reqion of 'request' - if (xferlen && xferptr) { - xlat_xferptr = ((char*)xlat_req) + 128; - memcpy(xlat_xferptr, xferptr, xferlen); - - ioctl->buffer_realoff = DPMI_real_offset(xlat_xferptr); - ioctl->buffer_realseg = DPMI_real_segment(xlat_xferptr); - ioctl->xferlen = xferlen; - } - -// Setup and Send Request Packet - rregs.eax = 0x1510; - rregs.ecx = (unsigned)(CDDriveLetter); - rregs.es = DPMI_real_segment(xlat_req); - rregs.ebx = DPMI_real_offset(xlat_req); - dpmi_real_int386x(0x2f, &rregs); - -// Return Translate Buffer to Protected mode 'xferptr' - if (xferlen && xferptr) { - memcpy(xferptr, xlat_xferptr, xferlen); - } - memcpy(request, xlat_req, sizeof(REQHDR)+sizeof(IOCTL)); - -// Check for Errors. - status = ((REQHDR *)request)->status; - - if (status & RBSTAT_ERROR) { - mprintf((0,"Error in SendRequest: %x.\n", status)); - } - - return status; -} - - -// Converts Logical Sector Number to Minutes Seconds Frame Format - -unsigned long lsn_to_msf(unsigned long lsn) -{ - unsigned long min,sec,frame; - lsn += 150; - - min = lsn / (60*75); - lsn = lsn % (60*75); - sec = lsn / 75; - lsn = lsn % 75; - frame = lsn; - - return((min << 16) + (sec << 8) + (frame << 0)); -} - -// convert minutes seconds frame format to a logical sector number. - -unsigned long msf_to_lsn(unsigned long msf) -{ - unsigned long min,sec,frame; - - min = (msf >> 16) & 0xFF; - sec = (msf >> 8) & 0xFF; - frame = (msf >> 0) & 0xFF; - - return( (min * 60*75) + (sec * 75) + frame - 150 ); -} - +/* + * $Source: /cvs/cvsroot/d2x/unused/bios/rbaudio.new,v $ + * $Revision: 1.1.1.2 $ + * $Author: bradleyb $ + * $Date: 2001-01-19 03:33:50 $ + * + * Redbook Audio Library + * + * $Log: not supported by cvs2svn $ + * Revision 1.18 1996/04/15 15:27:40 samir + * Play multiple tracks and PeekPlayStatus uses timer method! + * + * Revision 1.17 1996/04/12 20:08:42 samir + * Added debugging info and Redbook / HSG detection + * + * Revision 1.16 1996/04/12 19:13:29 matt + * Changed parameter name and added comments + * + * Revision 1.15 1996/04/12 18:08:02 samir + * We now pass a cd drive letter to RBAInit. + * + * Revision 1.14 1996/02/14 13:31:29 samir + * Fixed stupid bug that caused last track to never be played + * + * Revision 1.13 1996/02/13 17:16:04 samir + * Added Pause and Resume Caps. + * + * Revision 1.12 1996/01/11 10:08:01 matt + * RBARegisterCD wasn't checking SendRequest error code, so it was reporting + * CD tracks when there was no CD in the drive. + * + * Revision 1.11 1996/01/10 20:15:45 samir + * Changed behavior of RBACheckMediaChange to work + * correctly, as well as calling this function in critical + * RBA functions to take care of CD changes. + * + * Revision 1.10 1996/01/10 18:30:49 samir + * Changed property of RBCheckMediaChange which would + * not disable RBA if media had changed. GetNumberOfTracks + * returns num. of tracks or if media changed, re-registers + * CD and then returns number of tracks. If media has changed + * RBAPlayTrack will return an error. + * + * Revision 1.9 1995/08/01 19:30:11 samir + * Added ability to get number of tracks on CD via call. + * + * Revision 1.8 1995/07/20 16:13:56 samir + * Doesn't quit if CD isn't Redbook. + * + * Revision 1.7 1995/05/10 11:37:51 samir + * Checks whether CD-ROM in drive at start of game + * + * Revision 1.6 1995/05/09 18:00:08 samir + * Error cleaned. + * + * Revision 1.5 1995/05/09 17:57:43 samir + * No CD in Drive, then diable RBA + * + * Revision 1.4 1995/05/09 17:12:24 samir + * Added user detection of Redbook Audio. + * + * Revision 1.3 1995/05/09 12:04:57 samir + * Added ability to known when a CD is playing + * and when it's stopped. + * + * Revision 1.2 1995/05/08 11:33:37 samir + * Initial revision + * + * + */ + +char rbaudio_rcsid[] = "$Id: rbaudio.new,v 1.1.1.2 2001-01-19 03:33:50 bradleyb Exp $"; + + +#include +#include +#include + +#include "mono.h" +#include "error.h" +#include "rbaudio.h" +#include "fix.h" +#include "timer.h" + + +#define HSG_CD_PLAYBACK 0 +#define MSF_CD_PLAYBACK 1 + +#define RBERR_WRITEPROTVIOL 0 +#define RBERR_UNKNOWNUNIT 1 +#define RBERR_DRIVENOTREADY 2 +#define RBERR_UNKNOWNCOMMAND 3 +#define RBERR_CRCERROR 4 +#define RBERR_BADDRIVEREQ 5 +#define RBERR_SEEKERROR 6 +#define RBERR_UNKNOWNMEDIA 7 +#define RBERR_SECTORNOTFOUND 8 +#define RBERR_WRITEFAULT 10 +#define RBERR_READFAULT 12 +#define RBERR_GENERALFAILURE 13 +#define RBERR_BADDISKCHANGE 15 + +#define RBSTAT_ERROR 0x8000 +#define RBSTAT_BUSY 0x0200 +#define RBSTAT_DONE 0x0100 + +#pragma pack(1) + + +// Request Header ----------------------------------------------------- + +typedef struct _REQHDR { + unsigned char length; + unsigned char subunit; + unsigned char func; + unsigned short status; + char array[8]; +} REQHDR; + +typedef struct _IOCTL { + char bpb; + unsigned short buffer_realoff; + unsigned short buffer_realseg; + unsigned short xferlen; + unsigned short sector; + unsigned long id; +} IOCTL; + + +// CD Information ----------------------------------------------------- + +static struct { + char code; // Control Block Code + char track; // Track Number + long start; // Start of Track in MSF (Redbook) + unsigned char info; // Track Control Info +} CDTrackInfo = {11,2,0L,0}; + +static struct { + REQHDR reqheader; + IOCTL ioctl; +} TrackInfoREQ = {{13,0,3,0,""}, {0,0,0,0,0}}; + +static struct { + unsigned char code; + unsigned long devstat; +} DevStat = {6,0}; + +static struct { + REQHDR reqhdr; + IOCTL ioctl; +} DevStatREQ = {{13,0,3,0,""}, {0,0,0,0,0}}; + +static struct { + unsigned char code; + char byte; +} MedChg = {9,0}; + +static struct { + REQHDR reqhdr; + IOCTL ioctl; +} MedChgREQ = {{13,0,3,0,""}, {0,0,0,0,0}}; + +static struct { + REQHDR reqhdr; +} StopREQ = {{13,0,133,0,""}}; + +static struct { + REQHDR reqhdr; +} ResumeREQ = {{13,0,136,0,""}}; + +static struct { + unsigned char code; + unsigned char first; + unsigned char last; + unsigned long lead_out; +} CDInfo = {10,0,0,0L}; + +static struct { + REQHDR reqhdr; + IOCTL ioctl; +} CDInfoREQ = {{13,0,3,0,""},{0,0,0,0,0}}; + +static struct { + REQHDR reqheader; + char mode; // Play in HSG or MSF(RedBook) + unsigned long playbeg; + unsigned long playlen; // HSG Format + char empty; // Empty byte used so that all requests have same size +} PlayREQ = {{13,0,132,0,""},0,0,0,0}; + +static struct { + unsigned char code; + unsigned char out0in; + unsigned char out0vol; + unsigned char out1in; + unsigned char out1vol; + unsigned char out2in; + unsigned char out2vol; + unsigned char out3in; + unsigned char out3vol; +} AUDChannelCtl = {3,0,0,0,0,0,0,0,0}; + +static struct { + REQHDR reqhdr; + IOCTL ioctl; +} AUDChannelCtlREQ = {{13,0,12,0,""},{0,0,0,0,0}}; + +static struct { + unsigned char code; + unsigned char out0in; + unsigned char out0vol; + unsigned char out1in; + unsigned char out1vol; + unsigned char out2in; + unsigned char out2vol; + unsigned char out3in; + unsigned char out3vol; +} AUDChannelInfo = {4,0,0,0,0,0,0,0,0}; + +static struct { + REQHDR reqhdr; + IOCTL ioctl; +} AUDChannelInfoREQ = {{13,0,3,0,""},{0,0,0,0,0}}; + +static struct { + unsigned char code; + unsigned char mode; + unsigned long headloc; +} HeadInfo = {1,MSF_CD_PLAYBACK,0L}; + +static struct { + REQHDR reqhdr; + IOCTL ioctl; +} HeadInfoREQ = {{13,0,3,0,""},{0,0,0,0,0}}; + +//@@static struct { +//@@ ubyte code; +//@@ ubyte adr; +//@@ ubyte tno; +//@@ ubyte point; +//@@ ubyte min; +//@@ ubyte sec; +//@@ ubyte frame; +//@@ ubyte zero; +//@@ ubyte pmin; +//@@ ubyte psec; +//@@ ubyte pframe; +//@@} QChannelInfo = {12, MSF_CD_PLAYBACK, 2,0,0,0,0,0,0,0,0 }; +//@@ +//@@static struct { +//@@ REQHDR reqhdr; +//@@ IOCTL ioctl; +//@@} QChannelInfoREQ = {{13, 0, 3, 0, ""}, {0,0,0,0,0}}; + + +// Translation from RealMode->Protected mode buffer + +typedef struct _REQ_xlatbuf { // Buffer for Real Mode Callback + REQHDR reqheader; + char ioctl[10]; +} REQ_xlatbuf; + + + +// Other Data --------------------------------------------------------- + +static unsigned char CDDriveLetter; +static unsigned long CDNumTracks,CDTrackStart[101]; +static int RedBookEnabled = 0; +static int RedBookPlaybackType = MSF_CD_PLAYBACK; +static fix Playback_Start_Time = 0; +static fix Playback_Pause_Time = 0; +static fix Playback_Length = 0; + + +// Prototypes --------------------------------------------------------- + +int RBSendRequest(char *request, char *xferptr, int xferlen); +unsigned long msf_to_lsn(unsigned long msf); +unsigned long lsn_to_msf(unsigned long lsn); + + +// -------------------------------------------------------------------- + +void RBAInit(ubyte cd_drive_num) //drive a == 0, drive b == 1 +{ + union REGS regs; + +// Detect presence of CD-ROM + regs.x.eax = 0x1500; + regs.x.ebx = 0; + int386(0x2f, ®s, ®s); + + if (regs.x.ebx == 0) + RBADisable(); // Disable RedBook + // Error("RBA Error: MSCDEX.EXE compatible driver couldn't be found."); + else { + CDDriveLetter = cd_drive_num; +// CDDriveLetter = (unsigned char)regs.x.ecx; + + RBAEnable(); + RBACheckMediaChange(); + + RBSendRequest((char*)&DevStatREQ, (char*)&DevStat, sizeof(DevStat)); + + // If Door drive open, or no disc in CD-ROM, then Redbook is Disabled. + if ((DevStat.devstat&2048) || (DevStat.devstat&1) || RBAEnabled() == 0) + RBADisable(); + +//@@ if (DevStat.devstat&4) +//@@ mprintf((0, "supports cooked and raw reading.\n")); +//@@ else +//@@ mprintf((0, "supports only cooked reading.\n")); +//@@ +//@@ if (DevStat.devstat&256) +//@@ mprintf((0, "audio channel manipulation.\n")); +//@@ else +//@@ mprintf((0, "no audio channel manipulation.\n")); + + if (DevStat.devstat&512) { +// RedBookPlaybackType = MSF_CD_PLAYBACK; + mprintf((0, "supports HSG and RedBook addressing mode.\n")); + } + else { +// RedBookPlaybackType = HSG_CD_PLAYBACK; + mprintf((0, "supports HSG addressing only.\n")); + } + + RedBookPlaybackType = MSF_CD_PLAYBACK; + + } +} + +//find out how many tracks on the CD, and their starting locations +void RBARegisterCD(void) +{ + int i; + int error; + + // Get CD Information First + RBACheckMediaChange(); + + error = RBSendRequest((char*)&CDInfoREQ, (char*)&CDInfo, sizeof(CDInfo)); + + if (error & RBSTAT_ERROR) { //error! + CDNumTracks = 0; + return; + } + + CDNumTracks = (CDInfo.last-CDInfo.first)+1; + + // Define Track Starts + for (i=CDInfo.first; i<=CDNumTracks; i++) + { + CDTrackInfo.track = i; + RBSendRequest((char *)&TrackInfoREQ, (char*)&CDTrackInfo, sizeof(CDTrackInfo)); + CDTrackStart[i] = CDTrackInfo.start; + } + + CDTrackStart[i] = CDInfo.lead_out; +} + + +long RBAGetDeviceStatus() +{ + RBSendRequest((char*)&DevStatREQ, (char*)&DevStat, sizeof(DevStat)); + return (long)DevStat.devstat; +} + + +int RBAGetNumberOfTracks(void) +{ + // Get CD Information + if (RBACheckMediaChange()) + RBARegisterCD(); + + return CDNumTracks; +} + + +int RBAPlayTrack(int track) +{ + unsigned long playlen; + int min, sec; + + Playback_Start_Time = 0; + Playback_Length = 0; + + if (track < CDInfo.first || track > CDInfo.last) { + mprintf((0,"CD not Redbook Compatible. Will not play track.\n")); + } +// Error("RBA Error: Track %d doesn't exist on CD!!!", track); + + if (RBACheckMediaChange()) { + mprintf((0, "Unable to play track due to CD change.\n")); + return 0; + } + + // Play the track now!!! + PlayREQ.mode = RedBookPlaybackType; + PlayREQ.playbeg = CDTrackStart[track]; + + if (RedBookPlaybackType == MSF_CD_PLAYBACK) { + PlayREQ.playlen = + msf_to_lsn(CDTrackStart[track+1]) - msf_to_lsn(CDTrackStart[track]); + } + else { + mprintf((1, "RBERR: No! No! No! This shouldn't happen (HSG_CD_PLAYBACK).\n")); + Int3(); + PlayREQ.playlen = CDTrackStart[track+1] - CDTrackStart[track]; + } + RBSendRequest((char *)&PlayREQ,NULL,0); + + playlen = msf_to_lsn(CDTrackStart[track+1]) - msf_to_lsn(CDTrackStart[track]); + playlen = lsn_to_msf(playlen); + min = (int)((playlen >> 16) & 0xFF); + sec = (int)((playlen >> 8) & 0xFF); + + Playback_Start_Time = timer_get_fixed_seconds(); + Playback_Length = i2f(min*60+sec); + + mprintf( (0,"Playing Track %d (len: %d secs)\n", track, min*60+sec) ); + + return 1; +} + +//plays tracks first through last, inclusive +int RBAPlayTracks(int first, int last) +{ + unsigned long playlen; + int min, sec; + + Playback_Start_Time = 0; + Playback_Length = 0; + + if (first < CDInfo.first || last > CDInfo.last) { + mprintf((0,"Invalid start or end track.\n")); + } +// Error("RBA Error: Track %d doesn't exist on CD!!!", track); + + if (RBACheckMediaChange()) { + mprintf((0, "Unable to play track due to CD change.\n")); + return 0; + } + + // Play the track now!!! + PlayREQ.mode = RedBookPlaybackType; + PlayREQ.playbeg = CDTrackStart[first]; + + if (RedBookPlaybackType == MSF_CD_PLAYBACK) { + PlayREQ.playlen = + msf_to_lsn(CDTrackStart[last+1]) - msf_to_lsn(CDTrackStart[first]); + } + else { + mprintf((1, "RBERR: No! No! No! This shouldn't happen (HSG_CD_PLAYBACK).\n")); + Int3(); + PlayREQ.playlen = CDTrackStart[last+1] - CDTrackStart[first]; + } + RBSendRequest((char *)&PlayREQ,NULL,0); + + playlen = msf_to_lsn(CDTrackStart[last+1]) - msf_to_lsn(CDTrackStart[first]); + playlen = lsn_to_msf(playlen); + min = (int)((playlen >> 16) & 0xFF); + sec = (int)((playlen >> 8) & 0xFF); + + Playback_Start_Time = timer_get_fixed_seconds(); + Playback_Length = i2f(min*60+sec); + + mprintf( (0,"Playing Tracks %d-%d (len: %d secs)\n", first,last,min*60+sec) ); + + return 1; +} + + +void RBAPause() +{ + RBSendRequest((char *)&StopREQ, NULL, 0); + Playback_Pause_Time = timer_get_fixed_seconds(); +} + + +int RBAResume() +{ + if (RBACheckMediaChange()) { + RBARegisterCD(); + return RBA_MEDIA_CHANGED; + } + RBSendRequest((char *)&ResumeREQ, NULL, 0); + + Playback_Start_Time += timer_get_fixed_seconds() - Playback_Pause_Time; + + return 1; +} + + +void RBAStop() +{ + if (RBACheckMediaChange()) + RBARegisterCD(); + + RBSendRequest((char *)&StopREQ,NULL,0); +} + + +void RBASetStereoAudio(RBACHANNELCTL *channels) +{ + AUDChannelCtl.out0in = channels->out0in; + AUDChannelCtl.out0vol = channels->out0vol; + AUDChannelCtl.out1in = channels->out1in; + AUDChannelCtl.out1vol = channels->out1vol; + AUDChannelCtl.out2in = AUDChannelCtl.out2vol = 0; + AUDChannelCtl.out3in = AUDChannelCtl.out3vol = 0; + + RBSendRequest((char*)&AUDChannelCtlREQ, (char*)&AUDChannelCtl, sizeof(AUDChannelCtl)); +} + + +void RBASetQuadAudio(RBACHANNELCTL *channels) +{ + AUDChannelCtl.out0in = (unsigned char)channels->out0in; + AUDChannelCtl.out0vol = (unsigned char)channels->out0vol; + AUDChannelCtl.out1in = (unsigned char)channels->out1in; + AUDChannelCtl.out1vol = (unsigned char)channels->out1vol; + AUDChannelCtl.out2in = (unsigned char)channels->out2in; + AUDChannelCtl.out2vol = (unsigned char)channels->out2vol; + AUDChannelCtl.out3in = (unsigned char)channels->out3in; + AUDChannelCtl.out3vol = (unsigned char)channels->out3vol; + + RBSendRequest((char*)&AUDChannelCtlREQ, (char*)&AUDChannelCtl, sizeof(AUDChannelCtl)); +} + + +void RBAGetAudioInfo(RBACHANNELCTL *channels) +{ + RBSendRequest((char*)&AUDChannelInfoREQ, (char*)&AUDChannelInfo, sizeof(AUDChannelInfo)); + + channels->out0in = (int)AUDChannelInfo.out0in; + channels->out0vol = (int)AUDChannelInfo.out0vol; + channels->out1in = (int)AUDChannelInfo.out1in; + channels->out1vol = (int)AUDChannelInfo.out1vol; + channels->out2in = (int)AUDChannelInfo.out2in; + channels->out2vol = (int)AUDChannelInfo.out2vol; + channels->out3in = (int)AUDChannelInfo.out3in; + channels->out3vol = (int)AUDChannelInfo.out3vol; + +} + + +void RBASetChannelVolume(int channel, int volume) +{ + //RBACHANNELCTL channels; + + RBSendRequest((char*)&AUDChannelInfoREQ, (char*)&AUDChannelInfo, sizeof(AUDChannelInfo)); + + AUDChannelCtl.out0in = AUDChannelInfo.out0in; + AUDChannelCtl.out0vol = AUDChannelInfo.out0vol; + AUDChannelCtl.out1in = AUDChannelInfo.out1in; + AUDChannelCtl.out1vol = AUDChannelInfo.out1vol; + AUDChannelCtl.out2in = AUDChannelInfo.out2in; + AUDChannelCtl.out2vol = AUDChannelInfo.out2vol; + AUDChannelCtl.out3in = AUDChannelInfo.out3in; + AUDChannelCtl.out3vol = AUDChannelInfo.out3vol; + + if (channel == 0) AUDChannelCtl.out0vol = (unsigned char)volume; + if (channel == 1) AUDChannelCtl.out1vol = (unsigned char)volume; + if (channel == 2) AUDChannelCtl.out2vol = (unsigned char)volume; + if (channel == 3) AUDChannelCtl.out3vol = (unsigned char)volume; + + RBSendRequest((char*)&AUDChannelCtlREQ,(char*)&AUDChannelCtl, sizeof(AUDChannelCtl)); + +} + + +void RBASetVolume(int volume) +{ + RBASetChannelVolume(0,volume); + RBASetChannelVolume(1,volume); +} + + +long RBAGetHeadLoc(int *min, int *sec, int *frame) +{ + unsigned long loc; + + if (RBACheckMediaChange()) + return RBA_MEDIA_CHANGED; + + HeadInfo.mode = RedBookPlaybackType; + RBSendRequest((char*)&HeadInfoREQ, (char*)&HeadInfo, sizeof(HeadInfo)); + + if (RedBookPlaybackType == MSF_CD_PLAYBACK) + loc = HeadInfo.headloc; + else + loc = lsn_to_msf(HeadInfo.headloc); + + *min = (int)((loc >> 16) & 0xFF); + *sec = (int)((loc >> 8) & 0xFF); + *frame = (int)((loc >> 0) & 0xFF); + + return loc; +} + + +int RBAPeekPlayStatus() +{ + if ((timer_get_fixed_seconds()-Playback_Start_Time) > Playback_Length) return 0; + else return 1; +} + + +int RBAEnabled() +{ + if (RedBookEnabled < 1) return 0; + else return 1; +} + + +void RBAEnable() +{ + RedBookEnabled = 1; + mprintf((0, "Enabling Redbook...\n")); +} + + +void RBADisable() +{ + RedBookEnabled = 0; + mprintf((0, "Disabling Redbook...\n")); +} + + + +// RB functions: Internal to RBA library ----------------------------- + +//returns 1 if media has changed, else 0 +int RBACheckMediaChange() +{ + RBSendRequest((char *)&MedChgREQ, (char*)&MedChg, sizeof(MedChg)); + + if (MedChg.byte == 255 || MedChg.byte == 0) { + // New media in drive (or maybe no media in drive) + mprintf((0,"CD-ROM Media change detected\n")); + return 1; + } + return 0; +} + + +// Send Request + +//returns 16-bit value. Bit 15 means error. +//WE NEED SYMBOLOIC CONSTANTS FOR ALL RETURN CODES & STATUS BITS +int RBSendRequest(char *request, char *xferptr, int xferlen) +{ + //union REGS regs; + dpmi_real_regs rregs; + + IOCTL *ioctl; + REQ_xlatbuf *xlat_req; // Translated Buffer Request + char *xlat_xferptr; // Translated Buffer Transfer Buffer Ptr + + unsigned short status; + + if (!RedBookEnabled) return 0; // Don't send request if no RBA + + memset(&rregs,0,sizeof(dpmi_real_regs)); + +// Get Temporary Real Mode Buffer for request translation + xlat_req = (REQ_xlatbuf *)dpmi_get_temp_low_buffer(128+xferlen); + memcpy(xlat_req, request, sizeof(REQHDR)+sizeof(IOCTL)); + ioctl = (IOCTL *)(((char*)xlat_req)+sizeof(REQHDR)); + +// Set Transfer Buffer in IOCTL reqion of 'request' + if (xferlen && xferptr) { + xlat_xferptr = ((char*)xlat_req) + 128; + memcpy(xlat_xferptr, xferptr, xferlen); + + ioctl->buffer_realoff = DPMI_real_offset(xlat_xferptr); + ioctl->buffer_realseg = DPMI_real_segment(xlat_xferptr); + ioctl->xferlen = xferlen; + } + +// Setup and Send Request Packet + rregs.eax = 0x1510; + rregs.ecx = (unsigned)(CDDriveLetter); + rregs.es = DPMI_real_segment(xlat_req); + rregs.ebx = DPMI_real_offset(xlat_req); + dpmi_real_int386x(0x2f, &rregs); + +// Return Translate Buffer to Protected mode 'xferptr' + if (xferlen && xferptr) { + memcpy(xferptr, xlat_xferptr, xferlen); + } + memcpy(request, xlat_req, sizeof(REQHDR)+sizeof(IOCTL)); + +// Check for Errors. + status = ((REQHDR *)request)->status; + + if (status & RBSTAT_ERROR) { + mprintf((0,"Error in SendRequest: %x.\n", status)); + } + + return status; +} + + +// Converts Logical Sector Number to Minutes Seconds Frame Format + +unsigned long lsn_to_msf(unsigned long lsn) +{ + unsigned long min,sec,frame; + lsn += 150; + + min = lsn / (60*75); + lsn = lsn % (60*75); + sec = lsn / 75; + lsn = lsn % 75; + frame = lsn; + + return((min << 16) + (sec << 8) + (frame << 0)); +} + +// convert minutes seconds frame format to a logical sector number. + +unsigned long msf_to_lsn(unsigned long msf) +{ + unsigned long min,sec,frame; + + min = (msf >> 16) & 0xFF; + sec = (msf >> 8) & 0xFF; + frame = (msf >> 0) & 0xFF; + + return( (min * 60*75) + (sec * 75) + frame - 150 ); +} + diff --git a/unused/bios/testk.lnk b/unused/bios/testk.lnk index 8216c4d9..597c9d46 100644 --- a/unused/bios/testk.lnk +++ b/unused/bios/testk.lnk @@ -1,4 +1,4 @@ -system dos4g option quiet debug all -file .\obj\testk.obj -library .\io.lib -name testk +system dos4g option quiet debug all +file .\obj\testk.obj +library .\io.lib +name testk diff --git a/unused/bios/testm.lnk b/unused/bios/testm.lnk index 4b8740b8..5e083a6e 100644 --- a/unused/bios/testm.lnk +++ b/unused/bios/testm.lnk @@ -1,4 +1,4 @@ -system dos4g option quiet debug all -file .\obj\testm.obj -library .\io.lib -name testm +system dos4g option quiet debug all +file .\obj\testm.obj +library .\io.lib +name testm diff --git a/unused/bios/timer.asm b/unused/bios/timer.asm index 6613de9c..1afa6094 100644 --- a/unused/bios/timer.asm +++ b/unused/bios/timer.asm @@ -1,551 +1,551 @@ -; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX -; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO -; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A -; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS -; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS -; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE -; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE -; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS -; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. -; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. -;*************************************************************************** -;*************************************************************************** -;***** ***** -;***** T I M E R . A S M ***** -;***** ***** -;***** ***** -;***** PROCEDURES ***** -;***** ***** -;***** ***** -;***** ***** -;***** VARIABLES ***** -;***** ***** -;***** ***** -;***** CONSTANTS ***** -;***** ***** -;***** ***** -;*************************************************************************** -;*************************************************************************** - -.386 - -;************************************************************************ -;**************** FLAT MODEL DATA SEGMENT STUFF ************************* -;************************************************************************ - -_DATA SEGMENT BYTE PUBLIC USE32 'DATA' - -rcsid db "$Id: timer.asm,v 1.1.1.1 2001-01-19 03:30:14 bradleyb Exp $" - -TDATA EQU 40h -TCOMMAND EQU 43h -PIC EQU 020h -STACK_SIZE EQU 4096 ; A 4K stack - -TIMER_DATA STRUCT - in_timer db 0 - - nested_counter dd 0 - - _timer_cnt dd 65536 - dos_timer dd ? - - joystick_poller dd 0 - - user_function df 0 - - org_interrupt df 0 - - saved_stack df 0 - - new_stack df 0 - - tick_count dd 0 - - Installed db 0 - - TimerStack db STACK_SIZE dup (?) -TIMER_DATA ENDS - - TimerData TIMER_DATA <> - -_DATA ENDS - -DGROUP GROUP _DATA - - -;************************************************************************ -;**************** FLAT MODEL CODE SEGMENT STUFF ************************* -;************************************************************************ - -_TEXT SEGMENT BYTE PUBLIC USE32 'CODE' - - ASSUME ds:_DATA - ASSUME cs:_TEXT - -INCLUDE PSMACROS.INC -INCLUDE FIX.INC - -TIMER_LOCKED_CODE_START: - - extn atexit_ - -PUBLIC timer_get_stamp64 - -timer_get_stamp64: - ; Return a 64-bit stamp that is the number of 1.19Mhz pulses - ; since the time was initialized. Returns in EDX:EAX. - ; Also, interrupts must be disabled. - - xor eax, eax ; Clear all of EAX - out TCOMMAND, al ; Tell timer to latch - - mov al, 0ah ; Find if interrupt pending - out PIC, al - jmp @f -@@: in al, PIC - and eax, 01b - jz NoInterrupt - - in al, TDATA ; Read in lo byte - mov dl, al - in al, TDATA ; Read in hi byte - mov dh, al - and edx, 0ffffh - mov eax, TimerData._timer_cnt - shl eax, 1 - sub eax, edx - - push ebx - mov ebx, eax - mov eax, TimerData.tick_count - imul TimerData._timer_cnt ; edx:eax = Number of 1.19 MHz ticks elapsed... - add eax, ebx - adc edx, 0 - pop ebx - - ret - -NoInterrupt: - in al, TDATA ; Read in lo byte - mov ah, al - in al, TDATA ; Read in hi byte - xchg ah, al ; arrange em correctly - mov edx, TimerData._timer_cnt - sub dx, ax ; BX = timer ticks - mov ax, dx - - push ebx - mov ebx, eax - mov eax, TimerData.tick_count - imul TimerData._timer_cnt ; edx:eax = Number of 1.19 MHz ticks elapsed... - add eax, ebx - adc edx, 0 - pop ebx - - ret - - -PUBLIC timer_get_fixed_seconds_ - -timer_get_fixed_seconds_: - push ebx - push edx - - cli - call timer_get_stamp64 - sti - - ; Timing in fixed point (16.16) seconds. - ; Can be used for up to 1000 hours - shld edx, eax, 16 ; Keep 32+11 bits - shl eax, 16 - ; edx:eax = number of 1.19Mhz pulses elapsed. - mov ebx, 1193180 - -; Make sure we won't divide overflow. Make time wrap at about 9 hours -sub_again: sub edx, ebx ; subtract until negative... - jns sub_again ; ...to prevent divide overflow... - add edx, ebx ; ...then add in to get correct value. - div ebx - ; eax = fixed point seconds elapsed... - - pop edx - pop ebx - - ret - -PUBLIC timer_get_fixed_secondsX_ - -timer_get_fixed_secondsX_: - push ebx - push edx - - call timer_get_stamp64 - - ; Timing in fixed point (16.16) seconds. - ; Can be used for up to 1000 hours - shld edx, eax, 16 ; Keep 32+11 bits - shl eax, 16 - ; edx:eax = number of 1.19Mhz pulses elapsed. - mov ebx, 1193180 - -xsub_again: sub edx, ebx ; subtract until negative... - jns xsub_again ; ...to prevent divide overflow... - add edx, ebx ; ...then add in to get correct value. - - div ebx - ; eax = fixed point seconds elapsed... - - pop edx - pop ebx - - ret - -PUBLIC timer_get_approx_seconds_ -timer_get_approx_seconds_: - push ebx - push edx - - mov eax, TimerData.tick_count - imul TimerData._timer_cnt ; edx:eax = Number of 1.19 MHz ticks elapsed... - shld edx, eax, 16 ; Keep 32+16 bits, for conversion to fixed point - shl eax, 16 - ; edx:eax = number of 1.19Mhz pulses elapsed. - mov ebx, 1193180 - -approx_sub_again: sub edx, ebx ; subtract until negative... - jns approx_sub_again ; ...to prevent divide overflow... - add edx, ebx ; ...then add in to get correct value. - - div ebx - ; eax = fixed point seconds elapsed... - - pop edx - pop ebx - ret - - - -;extern void timer_set_rate(int count_val); -;extern void timer_set_function( void _far * function ); - -PUBLIC timer_set_rate_ -timer_set_rate_: - ; eax = rate - pushad - - ; Make sure eax below or equal to 65535 and above 0 - ; if its not, make it be 65536 which is normal dos - ; timing. - cmp eax, 65535 - jbe @f - mov eax, 65536 -@@: cmp eax, 0 - jne @f - mov eax, 65536 -@@: ; Set the timer rate to eax - cli - mov TimerData.tick_count, 0 - mov TimerData._timer_cnt, eax - mov al, 34h ; count in binary, mode 2, load low byte then hi byte, counter 0: 00 11 010 0 - out TCOMMAND, al ; Reset PIT channel 0 - mov eax, TimerData._timer_cnt - out TDATA, al - mov al, ah - out TDATA, al - sti - popad - ret - -PUBLIC timer_set_function_ -timer_set_function_: - ; dx:eax = far pointer to user function - pushad - cli - mov dword ptr TimerData.user_function[0], eax ; offset - mov word ptr TimerData.user_function[4], dx ; selector - sti - popad - ret - -PUBLIC timer_set_joyhandler_ -timer_set_joyhandler_: - cli - mov TimerData.joystick_poller, eax - sti - ret - -PUBLIC timer_delay_ -timer_delay_: - pushad - mov edx, 18 - mov ecx, [ds:046Ch] ; Get Current DOS Ticks - fixmul edx - add ecx, eax -timeloop: - cmp ecx, [ds:046ch] - jg timeloop - popad - ret - - - -;************************************************************************ -;************************************************************************ -;***** ***** -;***** T I M E R _ H A N D L E R ***** -;***** ***** -;************************************************************************ -;************************************************************************ - -timer_handler: - push ds - push es - push eax - - mov ax, DGROUP ; Interrupt, so point to our data segment - mov ds, ax - mov es, ax - - ; Increment time counter... - inc TimerData.tick_count - - mov eax, TimerData._timer_cnt - add TimerData.dos_timer, eax ; Increment DOS timer - cmp TimerData.dos_timer, 65536 - jb NoChainToOld ; See if we need to chain to DOS 18.2 - and TimerData.dos_timer, 0ffffh - - ; - ; Call the original DOS handler.... - ; - pushfd - call fword ptr [TimerData.org_interrupt] - - jmp NoReset ;old handler has reset, so we don't - -NoChainToOld: - ; Reset controller - mov al, 20h ; Reset interrupt controller - out 20h, al - -NoReset: - cmp TimerData.in_timer, 0 - jne ExitInterrupt - - mov TimerData.in_timer, 1 ; Mark that we're in a timer interrupt... - - ; Reenable interrupts - sti ; Reenable interrupts - - cmp word ptr TimerData.user_function[4], 0 ; Check the selector... - je NoUserFunction - - ; Switch stacks while calling the user-definable function... - pushad - push fs - push gs - mov dword ptr TimerData.saved_stack[0], esp - mov word ptr TimerData.saved_stack[4], ss - lss esp, TimerData.new_stack ; Switch to new stack - call fword ptr [TimerData.user_function] ; Call new function - lss esp, TimerData.saved_stack ; Switch back to original stack - pop gs - pop fs - popad - -NoUserFunction: - cmp dword ptr TimerData.joystick_poller, 0 - je NoJoyPolling - mov eax, TimerData._timer_cnt - mov dword ptr TimerData.saved_stack[0], esp - mov word ptr TimerData.saved_stack[4], ss - lss esp, TimerData.new_stack ; Switch to new stack - call dword ptr TimerData.joystick_poller - lss esp, TimerData.saved_stack ; Switch back to original stack - -NoJoyPolling: - cli - mov TimerData.in_timer, 0 - -ExitInterrupt: - ;;mov al, 20h ; Reset interrupt controller - ;;out 20h, al - pop eax - pop es - pop ds - iretd ; Return from timer interrupt - - -TIMER_LOCKED_CODE_STOP: - -;************************************************************************ -;************************************************************************ -;***** ***** -;***** T I M E R _ I N I T ***** -;***** ***** -;************************************************************************ -;************************************************************************ - - -PUBLIC timer_init_ - -timer_init_: - pushad - push ds - push es - - cmp TimerData.Installed, 1 - je AlreadyInstalled - - mov TimerData._timer_cnt, 65536 ; Set to BIOS's normal 18.2 Hz - mov TimerData.dos_timer, 0 ; clear DOS Interrupt counter - mov dword ptr TimerData.user_function[0], 0 ; offset of user function - mov word ptr TimerData.user_function[4], 0 ; selector of user function - - lea eax, ds:[TimerData.TimerStack] ; Use EAX as temp stack pointer - add eax, STACK_SIZE ; Top of stack minus space for saving old ss:esp - mov dword ptr TimerData.new_stack[0], eax - mov word ptr TimerData.new_stack[4], ds - - ;--------------- lock data used in interrupt - mov eax, SIZEOF TIMER_DATA - mov esi, eax - shr esi, 16 - mov edi, eax - and edi, 0ffffh ; si:di = length of region to lock in bytes - lea ebx, ds:TimerData - lea ecx, ds:TimerData - shr ebx, 16 - and ecx, 0ffffh ; bx:cx = start of linear address to lock - mov eax, 0600h ; DPMI lock address function - int 31h ; call dpmi - jnc @f - int 3 ; LOCK FAILED!! -@@: - ;--------------- lock code used in interrupt - lea eax, cs:TIMER_LOCKED_CODE_STOP - lea ecx, cs:TIMER_LOCKED_CODE_START - sub eax, ecx - inc eax ; EAX = size of timer interrupt handler - mov esi, eax - shr esi, 16 - mov edi, eax - and edi, 0ffffh ; si:di = length of region to lock in bytes - lea ebx, cs:TIMER_LOCKED_CODE_START - lea ecx, cs:TIMER_LOCKED_CODE_START - shr ebx, 16 - and ecx, 0ffffh ; bx:cx = start of linear address to lock - mov eax, 0600h ; DPMI lock address function - int 31h ; call dpmi - jnc @f - int 3 ; LOCK FAILED!! -@@: - - ;************************************************************** - ;******************* SAVE OLD INT8 HANDLER ******************** - ;************************************************************** - mov eax, 03508h ; DOS Get Vector 08h - int 21h ; Call DOS - - mov dword ptr TimerData.org_interrupt[0], ebx ; offset of user function - mov word ptr TimerData.org_interrupt[4], es ; selector of user function - - ;************************************************************** - ;***************** INSTALL NEW INT8 HANDLER ******************* - ;************************************************************** - - cli - - mov al, 34h ; count in binary, mode 2, load low byte then hi byte, counter 0: 00 11 010 0 - out TCOMMAND, al ; Reset PIT channel 0 - mov eax, TimerData._timer_cnt - out TDATA, al - mov al, ah - out TDATA, al - - mov TimerData.tick_count, 0 - mov TimerData.Installed,1 - - mov eax, 02508h ; DOS Set Vector 08h - mov edx, offset timer_handler ; Point DS:EDX to new handler - mov bx, cs - push ds - mov ds, bx - int 21h - pop ds - sti - lea eax, cs:timer_close_ - call atexit_ - -AlreadyInstalled: - - pop es - pop ds - popad - - ret - - -;************************************************************************ -;************************************************************************ -;***** ***** -;***** T I M E R _ C L O S E _ ***** -;***** ***** -;************************************************************************ -;************************************************************************ - -PUBLIC timer_close_ - -timer_close_: - push eax - push edx - push ds - - - cmp TimerData.Installed, 0 - je NotInstalled - mov TimerData.Installed, 0 - - ;************************************************************** - ;***************** RESTORE OLD INT9 HANDLER ******************* - ;************************************************************** - - cli - mov al, 36h ; count in binary, mode 3, load low byte then hi byte, counter 0: 00 11 011 0 - out TCOMMAND, al ; Reser PIT channel 0 - mov ax, 0h - out TDATA, al - mov al, ah - out TDATA, al - - push ds - mov eax, 02508h ; DOS Set Vector 08h - mov edx, dword ptr TimerData.org_interrupt[0] - mov ds, word ptr TimerData.org_interrupt[4] - int 21h - pop ds - - sti - - cmp TimerData.nested_counter, 0 - je NoNestedInterrupts - mov eax, TimerData.nested_counter - ;int 3 ; Get John!! - -NoNestedInterrupts: - - -NotInstalled: - pop ds - pop edx - pop eax - - ret - - -_TEXT ENDS - - - END +; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. +;*************************************************************************** +;*************************************************************************** +;***** ***** +;***** T I M E R . A S M ***** +;***** ***** +;***** ***** +;***** PROCEDURES ***** +;***** ***** +;***** ***** +;***** ***** +;***** VARIABLES ***** +;***** ***** +;***** ***** +;***** CONSTANTS ***** +;***** ***** +;***** ***** +;*************************************************************************** +;*************************************************************************** + +.386 + +;************************************************************************ +;**************** FLAT MODEL DATA SEGMENT STUFF ************************* +;************************************************************************ + +_DATA SEGMENT BYTE PUBLIC USE32 'DATA' + +rcsid db "$Id: timer.asm,v 1.1.1.2 2001-01-19 03:33:50 bradleyb Exp $" + +TDATA EQU 40h +TCOMMAND EQU 43h +PIC EQU 020h +STACK_SIZE EQU 4096 ; A 4K stack + +TIMER_DATA STRUCT + in_timer db 0 + + nested_counter dd 0 + + _timer_cnt dd 65536 + dos_timer dd ? + + joystick_poller dd 0 + + user_function df 0 + + org_interrupt df 0 + + saved_stack df 0 + + new_stack df 0 + + tick_count dd 0 + + Installed db 0 + + TimerStack db STACK_SIZE dup (?) +TIMER_DATA ENDS + + TimerData TIMER_DATA <> + +_DATA ENDS + +DGROUP GROUP _DATA + + +;************************************************************************ +;**************** FLAT MODEL CODE SEGMENT STUFF ************************* +;************************************************************************ + +_TEXT SEGMENT BYTE PUBLIC USE32 'CODE' + + ASSUME ds:_DATA + ASSUME cs:_TEXT + +INCLUDE PSMACROS.INC +INCLUDE FIX.INC + +TIMER_LOCKED_CODE_START: + + extn atexit_ + +PUBLIC timer_get_stamp64 + +timer_get_stamp64: + ; Return a 64-bit stamp that is the number of 1.19Mhz pulses + ; since the time was initialized. Returns in EDX:EAX. + ; Also, interrupts must be disabled. + + xor eax, eax ; Clear all of EAX + out TCOMMAND, al ; Tell timer to latch + + mov al, 0ah ; Find if interrupt pending + out PIC, al + jmp @f +@@: in al, PIC + and eax, 01b + jz NoInterrupt + + in al, TDATA ; Read in lo byte + mov dl, al + in al, TDATA ; Read in hi byte + mov dh, al + and edx, 0ffffh + mov eax, TimerData._timer_cnt + shl eax, 1 + sub eax, edx + + push ebx + mov ebx, eax + mov eax, TimerData.tick_count + imul TimerData._timer_cnt ; edx:eax = Number of 1.19 MHz ticks elapsed... + add eax, ebx + adc edx, 0 + pop ebx + + ret + +NoInterrupt: + in al, TDATA ; Read in lo byte + mov ah, al + in al, TDATA ; Read in hi byte + xchg ah, al ; arrange em correctly + mov edx, TimerData._timer_cnt + sub dx, ax ; BX = timer ticks + mov ax, dx + + push ebx + mov ebx, eax + mov eax, TimerData.tick_count + imul TimerData._timer_cnt ; edx:eax = Number of 1.19 MHz ticks elapsed... + add eax, ebx + adc edx, 0 + pop ebx + + ret + + +PUBLIC timer_get_fixed_seconds_ + +timer_get_fixed_seconds_: + push ebx + push edx + + cli + call timer_get_stamp64 + sti + + ; Timing in fixed point (16.16) seconds. + ; Can be used for up to 1000 hours + shld edx, eax, 16 ; Keep 32+11 bits + shl eax, 16 + ; edx:eax = number of 1.19Mhz pulses elapsed. + mov ebx, 1193180 + +; Make sure we won't divide overflow. Make time wrap at about 9 hours +sub_again: sub edx, ebx ; subtract until negative... + jns sub_again ; ...to prevent divide overflow... + add edx, ebx ; ...then add in to get correct value. + div ebx + ; eax = fixed point seconds elapsed... + + pop edx + pop ebx + + ret + +PUBLIC timer_get_fixed_secondsX_ + +timer_get_fixed_secondsX_: + push ebx + push edx + + call timer_get_stamp64 + + ; Timing in fixed point (16.16) seconds. + ; Can be used for up to 1000 hours + shld edx, eax, 16 ; Keep 32+11 bits + shl eax, 16 + ; edx:eax = number of 1.19Mhz pulses elapsed. + mov ebx, 1193180 + +xsub_again: sub edx, ebx ; subtract until negative... + jns xsub_again ; ...to prevent divide overflow... + add edx, ebx ; ...then add in to get correct value. + + div ebx + ; eax = fixed point seconds elapsed... + + pop edx + pop ebx + + ret + +PUBLIC timer_get_approx_seconds_ +timer_get_approx_seconds_: + push ebx + push edx + + mov eax, TimerData.tick_count + imul TimerData._timer_cnt ; edx:eax = Number of 1.19 MHz ticks elapsed... + shld edx, eax, 16 ; Keep 32+16 bits, for conversion to fixed point + shl eax, 16 + ; edx:eax = number of 1.19Mhz pulses elapsed. + mov ebx, 1193180 + +approx_sub_again: sub edx, ebx ; subtract until negative... + jns approx_sub_again ; ...to prevent divide overflow... + add edx, ebx ; ...then add in to get correct value. + + div ebx + ; eax = fixed point seconds elapsed... + + pop edx + pop ebx + ret + + + +;extern void timer_set_rate(int count_val); +;extern void timer_set_function( void _far * function ); + +PUBLIC timer_set_rate_ +timer_set_rate_: + ; eax = rate + pushad + + ; Make sure eax below or equal to 65535 and above 0 + ; if its not, make it be 65536 which is normal dos + ; timing. + cmp eax, 65535 + jbe @f + mov eax, 65536 +@@: cmp eax, 0 + jne @f + mov eax, 65536 +@@: ; Set the timer rate to eax + cli + mov TimerData.tick_count, 0 + mov TimerData._timer_cnt, eax + mov al, 34h ; count in binary, mode 2, load low byte then hi byte, counter 0: 00 11 010 0 + out TCOMMAND, al ; Reset PIT channel 0 + mov eax, TimerData._timer_cnt + out TDATA, al + mov al, ah + out TDATA, al + sti + popad + ret + +PUBLIC timer_set_function_ +timer_set_function_: + ; dx:eax = far pointer to user function + pushad + cli + mov dword ptr TimerData.user_function[0], eax ; offset + mov word ptr TimerData.user_function[4], dx ; selector + sti + popad + ret + +PUBLIC timer_set_joyhandler_ +timer_set_joyhandler_: + cli + mov TimerData.joystick_poller, eax + sti + ret + +PUBLIC timer_delay_ +timer_delay_: + pushad + mov edx, 18 + mov ecx, [ds:046Ch] ; Get Current DOS Ticks + fixmul edx + add ecx, eax +timeloop: + cmp ecx, [ds:046ch] + jg timeloop + popad + ret + + + +;************************************************************************ +;************************************************************************ +;***** ***** +;***** T I M E R _ H A N D L E R ***** +;***** ***** +;************************************************************************ +;************************************************************************ + +timer_handler: + push ds + push es + push eax + + mov ax, DGROUP ; Interrupt, so point to our data segment + mov ds, ax + mov es, ax + + ; Increment time counter... + inc TimerData.tick_count + + mov eax, TimerData._timer_cnt + add TimerData.dos_timer, eax ; Increment DOS timer + cmp TimerData.dos_timer, 65536 + jb NoChainToOld ; See if we need to chain to DOS 18.2 + and TimerData.dos_timer, 0ffffh + + ; + ; Call the original DOS handler.... + ; + pushfd + call fword ptr [TimerData.org_interrupt] + + jmp NoReset ;old handler has reset, so we don't + +NoChainToOld: + ; Reset controller + mov al, 20h ; Reset interrupt controller + out 20h, al + +NoReset: + cmp TimerData.in_timer, 0 + jne ExitInterrupt + + mov TimerData.in_timer, 1 ; Mark that we're in a timer interrupt... + + ; Reenable interrupts + sti ; Reenable interrupts + + cmp word ptr TimerData.user_function[4], 0 ; Check the selector... + je NoUserFunction + + ; Switch stacks while calling the user-definable function... + pushad + push fs + push gs + mov dword ptr TimerData.saved_stack[0], esp + mov word ptr TimerData.saved_stack[4], ss + lss esp, TimerData.new_stack ; Switch to new stack + call fword ptr [TimerData.user_function] ; Call new function + lss esp, TimerData.saved_stack ; Switch back to original stack + pop gs + pop fs + popad + +NoUserFunction: + cmp dword ptr TimerData.joystick_poller, 0 + je NoJoyPolling + mov eax, TimerData._timer_cnt + mov dword ptr TimerData.saved_stack[0], esp + mov word ptr TimerData.saved_stack[4], ss + lss esp, TimerData.new_stack ; Switch to new stack + call dword ptr TimerData.joystick_poller + lss esp, TimerData.saved_stack ; Switch back to original stack + +NoJoyPolling: + cli + mov TimerData.in_timer, 0 + +ExitInterrupt: + ;;mov al, 20h ; Reset interrupt controller + ;;out 20h, al + pop eax + pop es + pop ds + iretd ; Return from timer interrupt + + +TIMER_LOCKED_CODE_STOP: + +;************************************************************************ +;************************************************************************ +;***** ***** +;***** T I M E R _ I N I T ***** +;***** ***** +;************************************************************************ +;************************************************************************ + + +PUBLIC timer_init_ + +timer_init_: + pushad + push ds + push es + + cmp TimerData.Installed, 1 + je AlreadyInstalled + + mov TimerData._timer_cnt, 65536 ; Set to BIOS's normal 18.2 Hz + mov TimerData.dos_timer, 0 ; clear DOS Interrupt counter + mov dword ptr TimerData.user_function[0], 0 ; offset of user function + mov word ptr TimerData.user_function[4], 0 ; selector of user function + + lea eax, ds:[TimerData.TimerStack] ; Use EAX as temp stack pointer + add eax, STACK_SIZE ; Top of stack minus space for saving old ss:esp + mov dword ptr TimerData.new_stack[0], eax + mov word ptr TimerData.new_stack[4], ds + + ;--------------- lock data used in interrupt + mov eax, SIZEOF TIMER_DATA + mov esi, eax + shr esi, 16 + mov edi, eax + and edi, 0ffffh ; si:di = length of region to lock in bytes + lea ebx, ds:TimerData + lea ecx, ds:TimerData + shr ebx, 16 + and ecx, 0ffffh ; bx:cx = start of linear address to lock + mov eax, 0600h ; DPMI lock address function + int 31h ; call dpmi + jnc @f + int 3 ; LOCK FAILED!! +@@: + ;--------------- lock code used in interrupt + lea eax, cs:TIMER_LOCKED_CODE_STOP + lea ecx, cs:TIMER_LOCKED_CODE_START + sub eax, ecx + inc eax ; EAX = size of timer interrupt handler + mov esi, eax + shr esi, 16 + mov edi, eax + and edi, 0ffffh ; si:di = length of region to lock in bytes + lea ebx, cs:TIMER_LOCKED_CODE_START + lea ecx, cs:TIMER_LOCKED_CODE_START + shr ebx, 16 + and ecx, 0ffffh ; bx:cx = start of linear address to lock + mov eax, 0600h ; DPMI lock address function + int 31h ; call dpmi + jnc @f + int 3 ; LOCK FAILED!! +@@: + + ;************************************************************** + ;******************* SAVE OLD INT8 HANDLER ******************** + ;************************************************************** + mov eax, 03508h ; DOS Get Vector 08h + int 21h ; Call DOS + + mov dword ptr TimerData.org_interrupt[0], ebx ; offset of user function + mov word ptr TimerData.org_interrupt[4], es ; selector of user function + + ;************************************************************** + ;***************** INSTALL NEW INT8 HANDLER ******************* + ;************************************************************** + + cli + + mov al, 34h ; count in binary, mode 2, load low byte then hi byte, counter 0: 00 11 010 0 + out TCOMMAND, al ; Reset PIT channel 0 + mov eax, TimerData._timer_cnt + out TDATA, al + mov al, ah + out TDATA, al + + mov TimerData.tick_count, 0 + mov TimerData.Installed,1 + + mov eax, 02508h ; DOS Set Vector 08h + mov edx, offset timer_handler ; Point DS:EDX to new handler + mov bx, cs + push ds + mov ds, bx + int 21h + pop ds + sti + lea eax, cs:timer_close_ + call atexit_ + +AlreadyInstalled: + + pop es + pop ds + popad + + ret + + +;************************************************************************ +;************************************************************************ +;***** ***** +;***** T I M E R _ C L O S E _ ***** +;***** ***** +;************************************************************************ +;************************************************************************ + +PUBLIC timer_close_ + +timer_close_: + push eax + push edx + push ds + + + cmp TimerData.Installed, 0 + je NotInstalled + mov TimerData.Installed, 0 + + ;************************************************************** + ;***************** RESTORE OLD INT9 HANDLER ******************* + ;************************************************************** + + cli + mov al, 36h ; count in binary, mode 3, load low byte then hi byte, counter 0: 00 11 011 0 + out TCOMMAND, al ; Reser PIT channel 0 + mov ax, 0h + out TDATA, al + mov al, ah + out TDATA, al + + push ds + mov eax, 02508h ; DOS Set Vector 08h + mov edx, dword ptr TimerData.org_interrupt[0] + mov ds, word ptr TimerData.org_interrupt[4] + int 21h + pop ds + + sti + + cmp TimerData.nested_counter, 0 + je NoNestedInterrupts + mov eax, TimerData.nested_counter + ;int 3 ; Get John!! + +NoNestedInterrupts: + + +NotInstalled: + pop ds + pop edx + pop eax + + ret + + +_TEXT ENDS + + + END diff --git a/unused/bios/x b/unused/bios/x index 068b0373..4411e8ab 100644 --- a/unused/bios/x +++ b/unused/bios/x @@ -1,3 +1,3 @@ -//the both return 0 if no error -int GetFileTime(int filehandle, FILETIMESTRUCT *ftstruct); -int SetFileTime(int filehandle, FILETIMESTRUCT *ftstruct); +//the both return 0 if no error +int GetFileTime(int filehandle, FILETIMESTRUCT *ftstruct); +int SetFileTime(int filehandle, FILETIMESTRUCT *ftstruct); diff --git a/unused/bios/x.bat b/unused/bios/x.bat index d41a7ba7..8a29bda8 100644 --- a/unused/bios/x.bat +++ b/unused/bios/x.bat @@ -1 +1 @@ -4gwbind t:\4gwpro\4gwpro.exe cdtest.exe cdtest3.exe +4gwbind t:\4gwpro\4gwpro.exe cdtest.exe cdtest3.exe diff --git a/unused/bios/y.bat b/unused/bios/y.bat index 843ddf15..117585ca 100644 --- a/unused/bios/y.bat +++ b/unused/bios/y.bat @@ -1,11 +1,11 @@ -echo Library functions for printing to mono card. | rcs -i mono.c -echo Headers for joystick functions | rcs -i joy.h -echo Header for keyboard functions | rcs -i key.h -echo Header for monochrome/mprintf functions | rcs -i mono.h -echo Header for mouse functions | rcs -i mouse.h -echo Header for timer functions | rcs -i timer.h -echo Contains routines for joystick interface. | rcs -i joy.asm -echo Contains routines to get, buffer, and check key presses. | rcs -i key.asm -echo Contains routines for a mouse interface. | rcs -i mouse.asm -echo Routines for setting and using system timers | rcs -i timer.asm - +echo Library functions for printing to mono card. | rcs -i mono.c +echo Headers for joystick functions | rcs -i joy.h +echo Header for keyboard functions | rcs -i key.h +echo Header for monochrome/mprintf functions | rcs -i mono.h +echo Header for mouse functions | rcs -i mouse.h +echo Header for timer functions | rcs -i timer.h +echo Contains routines for joystick interface. | rcs -i joy.asm +echo Contains routines to get, buffer, and check key presses. | rcs -i key.asm +echo Contains routines for a mouse interface. | rcs -i mouse.asm +echo Routines for setting and using system timers | rcs -i timer.asm + diff --git a/unused/vga/dd.bat b/unused/vga/dd.bat index 1a96ee78..9996353e 100644 --- a/unused/vga/dd.bat +++ b/unused/vga/dd.bat @@ -1 +1 @@ -rcsdiff %1 %2 %3 %4 %5 %6 %7 %8 %9 |more +rcsdiff %1 %2 %3 %4 %5 %6 %7 %8 %9 |more diff --git a/unused/vga/framebuf.jas b/unused/vga/framebuf.jas index 562d5cac..f6429c93 100644 --- a/unused/vga/framebuf.jas +++ b/unused/vga/framebuf.jas @@ -1,320 +1,320 @@ -#include -#include -#include -#include -#include -#include -#include "mono.h" - - -#include "fxdpmi.h" -#include "fxvesa.h" - -#define DPMI_INTERRUPT 0x31 -const VIDEO_INTERRUPT = 0x10; - -typedef struct -{ - short ModeAttributes; /* Mode attributes */ - char WinAAttributes; /* Window A attributes */ - char WinBAttributes; /* Window B attributes */ - short WinGranularity; /* Window granularity in k */ - short WinSize; /* Window size in k */ - short WinASegment; /* Window A segment */ - short WinBSegment; /* Window B segment */ - void *WinFuncPtr; /* Pointer to window function */ - short BytesPerScanLine; /* Bytes per scanline */ - short XResolution; /* Horizontal resolution */ - short YResolution; /* Vertical resolution */ - char XCharSize; /* Character cell width */ - char YCharSize; /* Character cell height */ - char NumberOfPlanes; /* Number of memory planes */ - char BitsPerPixel; /* Bits per pixel */ - char NumberOfBanks; /* Number of CGA style banks */ - char MemoryModel; /* Memory model type */ - char BankSize; /* Size of CGA style banks */ - char NumberOfImagePages; /* Number of images pages */ - char res1; /* Reserved */ - char RedMaskSize; /* Size of direct color red mask */ - char RedFieldPosition; /* Bit posn of lsb of red mask */ - char GreenMaskSize; /* Size of direct color green mask */ - char GreenFieldPosition; /* Bit posn of lsb of green mask */ - char BlueMaskSize; /* Size of direct color blue mask */ - char BlueFieldPosition; /* Bit posn of lsb of blue mask */ - char RsvdMaskSize; /* Size of direct color res mask */ - char RsvdFieldPosition; /* Bit posn of lsb of res mask */ - char DirectColorModeInfo; /* Direct color mode attributes */ - FxU32 PhysBasePtr; /* Physical address of lfb */ - FxU32 OffScreenMemOffset; - FxU32 OffScreenMemSize; - char res2[206]; /* Pad to 256 byte block size */ -} ModeInfoBlock; - - -void VesaMain() -{ - FxU16 mode = 0x111; - VesaErr_t error; - - if ( ( error = VesaInit( mode ) ) != VESA_ERR_NONE ) - { - printf( "VesaInit failed with error '%s'\n", VesaGetErrorString( error ) ); - exit( 1 ); - } - else - { - char *MyPtr; - MyPtr=(char *)VesaGetPtr(); - memset( (MyPtr+((rand()%0x10000)<<4)+rand()%0x10000),rand()%256, 1 ); - } - - VesaEnd(); -} - -/* -** DpmiMapPhysicalToLinear -*/ -FxU32 DpmiMapPhysicalToLinear( FxU32 paddr, FxU32 length ) -{ - FxU32 laddr; - union REGS r; - - /* - ** DPMI function 0x800 - */ - r.w.ax = 0x800; - - /* - ** BX:CX = physical address - ** SI:DI = length - */ - r.w.bx = ( FxU16 ) ( paddr >> 16 ); - r.w.cx = ( FxU16 ) ( paddr & 0x0000FFFF ); - r.w.si = ( FxU16 ) ( length >> 16 ); - r.w.di = ( FxU16 ) ( length & 0x0000FFFF ); - int386( DPMI_INTERRUPT, &r, &r ); - - /* - ** if cflag set then an error occured - */ - if ( r.w.cflag ) - { - laddr = 0; - } - else - { - laddr = r.w.bx; - laddr <<= 16; - laddr |= r.w.cx; - } - return laddr; -} - -/* -** DpmiAllocDosMem -*/ -void *DpmiAllocDosMem( FxU16 size, DpmiSelector_t *pSel ) -{ - union REGS r; - void *ptr; - FxU32 seg; - - /* - ** AX = DPMI function 0x100 - */ - r.w.ax = 0x100; - - /* - ** BX = # of paragraphs to allocate - */ - r.w.bx = ( FxI16 ) ( size / 16 + 1 ); - - int386( DPMI_INTERRUPT, &r, &r ); - - if ( r.w.cflag ) - { - ptr = 0; - } - else - { - seg = r.w.ax; - *pSel = r.w.dx; - - ptr = ( void * ) ( seg << 4 ); - } - - return ptr; -} - -/* -** DpmiFreeDosMem -*/ -FxBool DpmiFreeDosMem( DpmiSelector_t sel ) -{ - union REGS r; - - r.w.ax = 0x101; - r.w.bx = sel; - int386( DPMI_INTERRUPT, &r, &r ); - - if ( r.w.cflag ) - return FXFALSE; - else - return FXTRUE; -} - -DpmiRMI RMI; -ModeInfoBlock infoblock; - -static void *vesa_lfb_ptr; - -static void VesaGetModeInfo( int mode, ModeInfoBlock *infoblock ) -{ - union REGS r; - struct SREGS sr; - DpmiSelector_t infosel; - unsigned short infoseg; - ModeInfoBlock *far_infoblock; - - /* - ** Allocate some real-mode DOS memory using DPMI function 0x100 - */ - far_infoblock = ( ModeInfoBlock * ) DpmiAllocDosMem( sizeof( ModeInfoBlock ), &infosel ); - infoseg = ( unsigned short ) ( ( ( unsigned long ) far_infoblock ) >> 4 ); - - /* - ** Get VESA SVGA info block by executing real-mode interrupt - ** 0x10, function 0x4F01. This must be done using DPMI service - ** 0x300 since DOS4GW doesn't automatically thunk pointers down - ** for VESA functions. - */ - memset( &RMI, 0, sizeof( RMI ) ); - RMI.EAX = 0x4F01; // Function 0x4F01 - RMI.ECX = mode; // - RMI.ES = infoseg; // ES:DI -> pointer to real mode buffer - RMI.EDI = 0; - - r.x.eax = 0x0300; // DPMI service "execute real mode interrupt" - r.x.ebx = VIDEO_INTERRUPT; // BL = function to execute - r.x.ecx = 0; // CX = 0 - segread( &sr ); - sr.es = FP_SEG( &RMI ); // ES:EDI -> buffer to RMI struct - r.x.edi = FP_OFF( &RMI ); - - #define DPMI_INTERRUPT 0x31 - - int386x( DPMI_INTERRUPT, &r, &r, &sr ); - - /* - ** Copy realmode buffer into protected mode buffer - */ - memcpy( infoblock, far_infoblock, sizeof( ModeInfoBlock ) ); - - /* - ** Free up the memory - */ - DpmiFreeDosMem( infosel ); -} - - -extern int FindArg(char *); -/* -** VesaInit -** -** VESA initialization function. Returns a pointer to the -** linear frame buffer. -*/ - - -int VesaInit( int mode ) -{ - union REGS r; - - if ( FindArg( "-virge" ) && (mode==0x101) ) { - vesa_lfb_ptr = virge_init(); - return 1; - } - - if (FindArg ("-novesa")) - return(0); - - /* - ** Get VESA mode information - */ - VesaGetModeInfo( mode, &infoblock ); - - /* - ** Check mode information stuff - */ - if ( !( infoblock.ModeAttributes & 0x1 ) || - !( infoblock.ModeAttributes & 0x80 ) ) - { - mprintf ((0,"mode %x is not supported!\n",mode)); - return 0; - } - - /* - ** Get a pointer to the linear frame buffer - */ - if ( ( vesa_lfb_ptr = ( void * ) DpmiMapPhysicalToLinear( infoblock.PhysBasePtr, 0x400000 - 1 ) ) == 0 ) - { - mprintf ((0,"mode %x mapping not supported!\n",mode)); - - return 0; - } - - /* - ** Set the video mode - */ - r.w.ax = 0x4F02; - r.w.bx = ( short ) ( mode | 0x4000 ); - int386( VIDEO_INTERRUPT, &r, &r ); - - if ( r.w.ax != 0x004F ) - { - VesaEnd(); - mprintf ((0,"mode %x not set!\n",mode)); - - return 0; - } - mprintf ((0,"No errors! mode %x is go!\n",mode)); - return 1; -} - -/* -** VesaEnd -*/ -void VesaEnd( void ) -{ - union REGS r; - - r.w.ax = 0x3; - int386( VIDEO_INTERRUPT, &r, &r ); -} - -/* -** VesaGetPtr -*/ -void *VesaGetPtr( void ) -{ - return vesa_lfb_ptr; -} - -static const char *vesa_errors[] = -{ - "VESA_ERR_NONE", - "VESA_ERR_DPMI_MAPPING_FAILED", - "VESA_ERR_MODE_NOT_SUPPORTED", - "VESA_ERR_MODE_NOT_SET" -}; - -/* -** VesaGetErrorString -*/ -const char *VesaGetErrorString( VesaErr_t err ) -{ - return vesa_errors[err]; -} - - +#include +#include +#include +#include +#include +#include +#include "mono.h" + + +#include "fxdpmi.h" +#include "fxvesa.h" + +#define DPMI_INTERRUPT 0x31 +const VIDEO_INTERRUPT = 0x10; + +typedef struct +{ + short ModeAttributes; /* Mode attributes */ + char WinAAttributes; /* Window A attributes */ + char WinBAttributes; /* Window B attributes */ + short WinGranularity; /* Window granularity in k */ + short WinSize; /* Window size in k */ + short WinASegment; /* Window A segment */ + short WinBSegment; /* Window B segment */ + void *WinFuncPtr; /* Pointer to window function */ + short BytesPerScanLine; /* Bytes per scanline */ + short XResolution; /* Horizontal resolution */ + short YResolution; /* Vertical resolution */ + char XCharSize; /* Character cell width */ + char YCharSize; /* Character cell height */ + char NumberOfPlanes; /* Number of memory planes */ + char BitsPerPixel; /* Bits per pixel */ + char NumberOfBanks; /* Number of CGA style banks */ + char MemoryModel; /* Memory model type */ + char BankSize; /* Size of CGA style banks */ + char NumberOfImagePages; /* Number of images pages */ + char res1; /* Reserved */ + char RedMaskSize; /* Size of direct color red mask */ + char RedFieldPosition; /* Bit posn of lsb of red mask */ + char GreenMaskSize; /* Size of direct color green mask */ + char GreenFieldPosition; /* Bit posn of lsb of green mask */ + char BlueMaskSize; /* Size of direct color blue mask */ + char BlueFieldPosition; /* Bit posn of lsb of blue mask */ + char RsvdMaskSize; /* Size of direct color res mask */ + char RsvdFieldPosition; /* Bit posn of lsb of res mask */ + char DirectColorModeInfo; /* Direct color mode attributes */ + FxU32 PhysBasePtr; /* Physical address of lfb */ + FxU32 OffScreenMemOffset; + FxU32 OffScreenMemSize; + char res2[206]; /* Pad to 256 byte block size */ +} ModeInfoBlock; + + +void VesaMain() +{ + FxU16 mode = 0x111; + VesaErr_t error; + + if ( ( error = VesaInit( mode ) ) != VESA_ERR_NONE ) + { + printf( "VesaInit failed with error '%s'\n", VesaGetErrorString( error ) ); + exit( 1 ); + } + else + { + char *MyPtr; + MyPtr=(char *)VesaGetPtr(); + memset( (MyPtr+((rand()%0x10000)<<4)+rand()%0x10000),rand()%256, 1 ); + } + + VesaEnd(); +} + +/* +** DpmiMapPhysicalToLinear +*/ +FxU32 DpmiMapPhysicalToLinear( FxU32 paddr, FxU32 length ) +{ + FxU32 laddr; + union REGS r; + + /* + ** DPMI function 0x800 + */ + r.w.ax = 0x800; + + /* + ** BX:CX = physical address + ** SI:DI = length + */ + r.w.bx = ( FxU16 ) ( paddr >> 16 ); + r.w.cx = ( FxU16 ) ( paddr & 0x0000FFFF ); + r.w.si = ( FxU16 ) ( length >> 16 ); + r.w.di = ( FxU16 ) ( length & 0x0000FFFF ); + int386( DPMI_INTERRUPT, &r, &r ); + + /* + ** if cflag set then an error occured + */ + if ( r.w.cflag ) + { + laddr = 0; + } + else + { + laddr = r.w.bx; + laddr <<= 16; + laddr |= r.w.cx; + } + return laddr; +} + +/* +** DpmiAllocDosMem +*/ +void *DpmiAllocDosMem( FxU16 size, DpmiSelector_t *pSel ) +{ + union REGS r; + void *ptr; + FxU32 seg; + + /* + ** AX = DPMI function 0x100 + */ + r.w.ax = 0x100; + + /* + ** BX = # of paragraphs to allocate + */ + r.w.bx = ( FxI16 ) ( size / 16 + 1 ); + + int386( DPMI_INTERRUPT, &r, &r ); + + if ( r.w.cflag ) + { + ptr = 0; + } + else + { + seg = r.w.ax; + *pSel = r.w.dx; + + ptr = ( void * ) ( seg << 4 ); + } + + return ptr; +} + +/* +** DpmiFreeDosMem +*/ +FxBool DpmiFreeDosMem( DpmiSelector_t sel ) +{ + union REGS r; + + r.w.ax = 0x101; + r.w.bx = sel; + int386( DPMI_INTERRUPT, &r, &r ); + + if ( r.w.cflag ) + return FXFALSE; + else + return FXTRUE; +} + +DpmiRMI RMI; +ModeInfoBlock infoblock; + +static void *vesa_lfb_ptr; + +static void VesaGetModeInfo( int mode, ModeInfoBlock *infoblock ) +{ + union REGS r; + struct SREGS sr; + DpmiSelector_t infosel; + unsigned short infoseg; + ModeInfoBlock *far_infoblock; + + /* + ** Allocate some real-mode DOS memory using DPMI function 0x100 + */ + far_infoblock = ( ModeInfoBlock * ) DpmiAllocDosMem( sizeof( ModeInfoBlock ), &infosel ); + infoseg = ( unsigned short ) ( ( ( unsigned long ) far_infoblock ) >> 4 ); + + /* + ** Get VESA SVGA info block by executing real-mode interrupt + ** 0x10, function 0x4F01. This must be done using DPMI service + ** 0x300 since DOS4GW doesn't automatically thunk pointers down + ** for VESA functions. + */ + memset( &RMI, 0, sizeof( RMI ) ); + RMI.EAX = 0x4F01; // Function 0x4F01 + RMI.ECX = mode; // + RMI.ES = infoseg; // ES:DI -> pointer to real mode buffer + RMI.EDI = 0; + + r.x.eax = 0x0300; // DPMI service "execute real mode interrupt" + r.x.ebx = VIDEO_INTERRUPT; // BL = function to execute + r.x.ecx = 0; // CX = 0 + segread( &sr ); + sr.es = FP_SEG( &RMI ); // ES:EDI -> buffer to RMI struct + r.x.edi = FP_OFF( &RMI ); + + #define DPMI_INTERRUPT 0x31 + + int386x( DPMI_INTERRUPT, &r, &r, &sr ); + + /* + ** Copy realmode buffer into protected mode buffer + */ + memcpy( infoblock, far_infoblock, sizeof( ModeInfoBlock ) ); + + /* + ** Free up the memory + */ + DpmiFreeDosMem( infosel ); +} + + +extern int FindArg(char *); +/* +** VesaInit +** +** VESA initialization function. Returns a pointer to the +** linear frame buffer. +*/ + + +int VesaInit( int mode ) +{ + union REGS r; + + if ( FindArg( "-virge" ) && (mode==0x101) ) { + vesa_lfb_ptr = virge_init(); + return 1; + } + + if (FindArg ("-novesa")) + return(0); + + /* + ** Get VESA mode information + */ + VesaGetModeInfo( mode, &infoblock ); + + /* + ** Check mode information stuff + */ + if ( !( infoblock.ModeAttributes & 0x1 ) || + !( infoblock.ModeAttributes & 0x80 ) ) + { + mprintf ((0,"mode %x is not supported!\n",mode)); + return 0; + } + + /* + ** Get a pointer to the linear frame buffer + */ + if ( ( vesa_lfb_ptr = ( void * ) DpmiMapPhysicalToLinear( infoblock.PhysBasePtr, 0x400000 - 1 ) ) == 0 ) + { + mprintf ((0,"mode %x mapping not supported!\n",mode)); + + return 0; + } + + /* + ** Set the video mode + */ + r.w.ax = 0x4F02; + r.w.bx = ( short ) ( mode | 0x4000 ); + int386( VIDEO_INTERRUPT, &r, &r ); + + if ( r.w.ax != 0x004F ) + { + VesaEnd(); + mprintf ((0,"mode %x not set!\n",mode)); + + return 0; + } + mprintf ((0,"No errors! mode %x is go!\n",mode)); + return 1; +} + +/* +** VesaEnd +*/ +void VesaEnd( void ) +{ + union REGS r; + + r.w.ax = 0x3; + int386( VIDEO_INTERRUPT, &r, &r ); +} + +/* +** VesaGetPtr +*/ +void *VesaGetPtr( void ) +{ + return vesa_lfb_ptr; +} + +static const char *vesa_errors[] = +{ + "VESA_ERR_NONE", + "VESA_ERR_DPMI_MAPPING_FAILED", + "VESA_ERR_MODE_NOT_SUPPORTED", + "VESA_ERR_MODE_NOT_SET" +}; + +/* +** VesaGetErrorString +*/ +const char *VesaGetErrorString( VesaErr_t err ) +{ + return vesa_errors[err]; +} + +  \ No newline at end of file diff --git a/unused/vga/modex.asm b/unused/vga/modex.asm index e45460fd..385114e1 100644 --- a/unused/vga/modex.asm +++ b/unused/vga/modex.asm @@ -1,770 +1,770 @@ -; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX -; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO -; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A -; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS -; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS -; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE -; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE -; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS -; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. -; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. - -.386 - -_DATA SEGMENT BYTE PUBLIC USE32 'DATA' - -INCLUDE psmacros.inc -INCLUDE TWEAK.INC -INCLUDE VGAREGS.INC - -extd _gr_var_bwidth - -extd _modex_line_vertincr -extd _modex_line_incr1 -extd _modex_line_incr2 - _modex_line_routine dd ? -extd _modex_line_x1 -extd _modex_line_y1 -extd _modex_line_x2 -extd _modex_line_y2 -extb _modex_line_Color - - SavedColor db ? - -LEFT_MASK1 = 1000b -LEFT_MASK2 = 1100b -LEFT_MASK3 = 1110b -RIGHT_MASK1 = 0001b -RIGHT_MASK2 = 0011b -RIGHT_MASK3 = 0111b -ALL_MASK = 1111b - -tmppal db 768 dup (0) -fb_pal dd ? -fb_add dw ? -fb_count dd ? - -MaskTable1 db ALL_MASK AND RIGHT_MASK1, - ALL_MASK AND RIGHT_MASK2, - ALL_MASK AND RIGHT_MASK3, - ALL_MASK, - LEFT_MASK3 AND RIGHT_MASK1, - LEFT_MASK3 AND RIGHT_MASK2, - LEFT_MASK3 AND RIGHT_MASK3, - LEFT_MASK3, - LEFT_MASK2 AND RIGHT_MASK1, - LEFT_MASK2 AND RIGHT_MASK2, - LEFT_MASK2 AND RIGHT_MASK3, - LEFT_MASK2, - LEFT_MASK1 AND RIGHT_MASK1, - LEFT_MASK1 AND RIGHT_MASK2, - LEFT_MASK1 AND RIGHT_MASK3, - LEFT_MASK1, - -MaskTable2 db ALL_MASK,RIGHT_MASK1, - ALL_MASK,RIGHT_MASK2, - ALL_MASK,RIGHT_MASK3, - ALL_MASK,ALL_MASK, - LEFT_MASK3,RIGHT_MASK1, - LEFT_MASK3,RIGHT_MASK2, - LEFT_MASK3,RIGHT_MASK3, - LEFT_MASK3,ALL_MASK, - LEFT_MASK2,RIGHT_MASK1, - LEFT_MASK2,RIGHT_MASK2, - LEFT_MASK2,RIGHT_MASK3, - LEFT_MASK2,ALL_MASK, - LEFT_MASK1,RIGHT_MASK1, - LEFT_MASK1,RIGHT_MASK2, - LEFT_MASK1,RIGHT_MASK3, - LEFT_MASK1,ALL_MASK - -DrawTable dd DrawMR, - DrawMR, - DrawMR, - DrawM, - DrawLMR, - DrawLMR, - DrawLMR, - DrawLM, - DrawLMR, - DrawLMR, - DrawLMR, - DrawLM, - DrawLMR, - DrawLMR, - DrawLMR, - DrawLM - -_DATA ENDS - -DGROUP GROUP _DATA - - -_TEXT SEGMENT BYTE PUBLIC USE32 'CODE' - - ASSUME DS:_DATA - ASSUME CS:_TEXT - -PUBLIC gr_sync_display_ - -gr_sync_display_: - - push ax - push dx - mov dx, VERT_RESCAN -VS2A: in al, dx - and al, 08h - jnz VS2A ; Loop until not in vertical retrace -VS2B: in al, dx - and al, 08h - jz VS2B ; Loop until in vertical retrace - - pop dx - pop ax - ret - - -PUBLIC gr_modex_uscanline_ - -gr_modex_uscanline_: - push edi - - ; EAX = X1 (X1 and X2 don't need to be sorted) - ; EDX = X2 - ; EBX = Y - ; ECX = Color - - mov SavedColor, cl - - ;mov ebx, _RowOffset[ebx*4] - mov edi, _gr_var_bwidth - imul edi, ebx - add edi, 0A0000h - cmp eax, edx - jle @f - xchg eax, edx -@@: mov bl, al - shl bl, 2 - mov bh, dl - and bh, 011b - or bl, bh - and ebx, 0fh - ; BX = LeftRight switch command. (4bit) - shr eax, 2 - shr edx, 2 - add edi, eax - ; EDI = Offset into video memory - mov ecx, edx - sub ecx, eax - ; ECX = X2/4 - X1/4 - 1 - jnz LargerThan4 - -;======================= ONE GROUP OF 4 OR LESS TO DRAW ==================== - - mov dx, SC_INDEX - mov al, SC_MAP_MASK - out dx, al - inc dx - mov al, MaskTable1[ebx] - out dx, al - mov al, SavedColor - mov [edi], al ; Write the one pixel - pop edi - ret - -LargerThan4: - dec ecx - jnz LargerThan8 - -;===================== TWO GROUPS OF 4 OR LESS TO DRAW ==================== - - mov cx, WORD PTR MaskTable2[ebx*2] - mov bl, SavedColor - mov dx, SC_INDEX - mov al, SC_MAP_MASK - out dx, al - inc dx - mov al, cl - out dx, al - mov [edi], bl ; Write the left pixel - mov al, ch - out dx, al - mov [edi+1], bl ; Write the right pixel - pop edi - ret - -;========================= MANY GROUPS OF 4 TO DRAW ====================== -LargerThan8: - mov dx, SC_INDEX - mov al, SC_MAP_MASK - out dx, al - inc dx - ; DX = SC_INDEX - mov al, SavedColor - mov ah, al - ; AL,AH = color of pixel - jmp NEAR32 PTR DrawTable[ebx*4] - - -DrawM: ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index - mov al, ALL_MASK - out dx, al - mov al, ah - cld - add ecx, 2 - shr ecx, 1 - rep stosw ; Write the middle pixels - jnc @F - stosb ; Write the middle odd pixel -@@: pop edi - ret - -DrawLM: - ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index - mov al, BYTE PTR MaskTable2[ebx*2] - out dx, al - mov [edi], ah ; Write leftmost pixels - inc edi - mov al, ALL_MASK - out dx, al - mov al, ah - cld - inc ecx - shr ecx, 1 - rep stosw ; Write the middle pixels - jnc @F - stosb ; Write the middle odd pixel -@@: pop edi - ret - - -DrawLMR: ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index - mov bx, WORD PTR MaskTable2[ebx*2] - mov al, bl - out dx, al - mov [edi], ah ; Write leftmost pixels - inc edi - mov al, ALL_MASK - out dx, al - mov al, ah - cld - shr ecx, 1 - rep stosw ; Write the middle pixels - jnc @F - stosb ; Write the middle odd pixel -@@: mov al, bh - out dx, al - mov [edi], ah ; Write the rightmost pixels - pop edi - ret - -DrawMR: ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index - mov bx, WORD PTR MaskTable2[ebx*2] - mov al, ALL_MASK - out dx, al - mov al, ah - cld - inc ecx - shr ecx, 1 - rep stosw ; Write the middle pixels - jnc @F - stosb ; Write the middle odd pixel -@@: mov al, bh - out dx, al - mov [edi], ah ; Write the rightmost pixels - pop edi - ret - - -PUBLIC gr_modex_setmode_ - -gr_modex_setmode_: - - push ebx - push ecx - push edx - push esi - push edi - - mov ecx, eax - dec ecx - - cmp ecx, LAST_X_MODE - jbe @f - mov ecx, 0 -@@: - - ;call turn_screen_off - - push ecx ; some bios's dont preserve cx - - ;mov ax, 1201h - ;mov bl, 31h ; disable palette loading at mode switch - ;int 10h - mov ax,13h ; let the BIOS set standard 256-color - int 10h ; mode (320x200 linear) - ;mov ax, 1200h - ;mov bl, 31h ; enable palette loading at mode switch - ;int 10h - - pop ecx - - mov dx,SC_INDEX - mov ax,0604h - out dx,ax ; disable chain4 mode - - mov dx,SC_INDEX - mov ax,0100h - out dx,ax ; synchronous reset while setting Misc - ; Output for safety, even though clock - ; unchanged - - mov esi, dword ptr ModeTable[ecx*4] - lodsb - - or al,al - jz DontSetDot - - mov dx,MISC_OUTPUT - out dx,al ; select the dot clock and Horiz - ; scanning rate - - ;mov dx,SC_INDEX - ;mov al,01h - ;out dx,al - ;inc dx - ;in al, dx - ;or al, 1000b - ;out dx, al - -DontSetDot: - mov dx,SC_INDEX - mov ax,0300h - out dx,ax ; undo reset (restart sequencer) - - mov dx,CRTC_INDEX ; reprogram the CRT Controller - mov al,11h ; VSync End reg contains register write - out dx,al ; protect bit - inc dx ; CRT Controller Data register - in al,dx ; get current VSync End register setting - and al,07fh ; remove write protect on various - out dx,al ; CRTC registers - dec dx ; CRT Controller Index - cld - xor ecx,ecx - lodsb - mov cl,al - -SetCRTParmsLoop: - lodsw ; get the next CRT Index/Data pair - out dx,ax ; set the next CRT Index/Data pair - loop SetCRTParmsLoop - - mov dx,SC_INDEX - mov ax,0f02h - out dx,ax ; enable writes to all four planes - mov edi, 0A0000h ; point ES:DI to display memory - xor ax,ax ; clear to zero-value pixels - mov ecx,8000h ; # of words in display memory - rep stosw ; clear all of display memory - - ; Set pysical screen dimensions - - xor eax, eax - lodsw ; Load scrn pixel width - mov cx, ax - shl eax, 16 - - mov dx,CRTC_INDEX - mov al,CRTC_OFFSET - out dx,al - inc dx - mov ax,cx - shr ax,3 - out dx,al - - ;mov si, 360 - ;@@: - ;mov ax, 04f06h - ;mov bl, 0 - ;mov cx, si - ;int 10h - ;cmp cx, si - ;je @f - ;inc si - ;jmp @B - ;@@: - ;movzx eax, si - - lodsw ; Load Screen Phys. Height - - ;call turn_screen_on - - pop edi - pop esi - pop edx - pop ecx - pop ebx - - ret - -PUBLIC gr_modex_setplane_ - -gr_modex_setplane_: - - push cx - push dx - - mov cl, al - - ; SELECT WRITE PLANE - and cl,011b ;CL = plane - mov ax,0100h + MAP_MASK ;AL = index in SC of Map Mask reg - shl ah,cl ;set only the bit for the required - ; plane to 1 - mov dx,SC_INDEX ;set the Map Mask to enable only the - out dx,ax ; pixel's plane - - ; SELECT READ PLANE - mov ah,cl ;AH = plane - mov al,READ_MAP ;AL = index in GC of the Read Map reg - mov dx,GC_INDEX ;set the Read Map to read the pixel's - out dx,ax ; plane - - pop dx - pop cx - - ret - -PUBLIC gr_modex_setstart_ - -gr_modex_setstart_: - - ; EAX = X - ; EDX = Y - ; EBX = Wait for retrace - - push ebx - push ecx - push ebx - - mov ecx, _gr_var_bwidth - imul ecx, edx - - shr eax, 2 - add eax, ecx - - mov ch, ah - mov bh, al - - mov bl, CC_START_LO - mov cl, CC_START_HI - - cli - mov dx, VERT_RESCAN -WaitDE: in al, dx - test al, 01h - jnz WaitDE - - mov dx, CRTC_INDEX - mov ax, bx - out dx, ax ; Start address low - mov ax, cx - out dx, ax ; Start address high - sti - - pop ebx - cmp ebx, 0 - je NoWaitVS - mov dx, VERT_RESCAN -WaitVS: in al, dx - test al, 08h - jz WaitVS ; Loop until in vertical retrace -NoWaitVS: - - pop ecx - pop ebx - - ret - - - - -ModeXAddr macro -; given: ebx=x, eax=y, return cl=plane mask, ebx=address, trash eax - mov cl, bl - and cl, 3 - shr ebx, 2 - imul eax, _gr_var_bwidth - add ebx, eax - add ebx, 0A0000h - endm - - -;----------------------------------------------------------------------- -; -; Line drawing function for all MODE X 256 Color resolutions -; Based on code from "PC and PS/2 Video Systems" by Richard Wilton. - -PUBLIC gr_modex_line_ - -gr_modex_line_: - pusha - - mov dx,SC_INDEX ; setup for plane mask access - -; check for vertical line - - mov esi,_gr_var_bwidth - mov ecx,_modex_line_x2 - sub ecx,_modex_line_x1 - jz VertLine - -; force x1 < x2 - - jns L01 - - neg ecx - - mov ebx,_modex_line_x2 - xchg ebx,_modex_line_x1 - mov _modex_line_x2,ebx - - mov ebx,_modex_line_y2 - xchg ebx,_modex_line_y1 - mov _modex_line_y2,ebx - -; calc dy = abs(y2 - y1) - -L01: - mov ebx,_modex_line_y2 - sub ebx,_modex_line_y1 - jnz short skip - jmp HorizLine -skip: jns L03 - - neg ebx - neg esi - -; select appropriate routine for slope of line - -L03: - mov _modex_line_vertincr,esi - mov _modex_line_routine,offset LoSlopeLine - cmp ebx,ecx - jle L04 - mov _modex_line_routine,offset HiSlopeLine - xchg ebx,ecx - -; calc initial decision variable and increments - -L04: - shl ebx,1 - mov _modex_line_incr1,ebx - sub ebx,ecx - mov esi,ebx - sub ebx,ecx - mov _modex_line_incr2,ebx - -; calc first pixel address - - push ecx - mov eax,_modex_line_y1 - mov ebx,_modex_line_x1 - ModeXAddr - mov edi,ebx - mov al,1 - shl al,cl - mov ah,al ; duplicate nybble - shl al,4 - add ah,al - mov bl,ah - pop ecx - inc ecx - jmp [_modex_line_routine] - -; routine for verticle lines - -VertLine: - mov eax,_modex_line_y1 - mov ebx,_modex_line_y2 - mov ecx,ebx - sub ecx,eax - jge L31 - neg ecx - mov eax,ebx - -L31: - inc ecx - mov ebx,_modex_line_x1 - push ecx - ModeXAddr - - mov ah,1 - shl ah,cl - mov al,MAP_MASK - out dx,ax - pop ecx - mov ax, word ptr _modex_line_Color - -; draw the line - -L32: - mov [ebx],al - add ebx,esi - loop L32 - jmp Lexit - -; routine for horizontal line - -HorizLine: - - mov eax,_modex_line_y1 - mov ebx,_modex_line_x1 - ModeXAddr - - mov edi,ebx ; set dl = first byte mask - mov dl,00fh - shl dl,cl - - mov ecx,_modex_line_x2 ; set dh = last byte mask - and cl,3 - mov dh,00eh - shl dh,cl - not dh - -; determine byte offset of first and last pixel in line - - mov eax,_modex_line_x2 - mov ebx,_modex_line_x1 - - shr eax,2 ; set ax = last byte column - shr ebx,2 ; set bx = first byte column - mov ecx,eax ; cx = ax - bx - sub ecx,ebx - - mov eax,edx ; mov end byte masks to ax - mov dx,SC_INDEX ; setup dx for VGA outs - mov bl,_modex_line_Color - -; set pixels in leftmost byte of line - - or ecx,ecx ; is start and end pt in same byte - jnz L42 ; no ! - and ah,al ; combine start and end masks - jmp short L44 - -L42: push eax - mov ah,al - mov al,MAP_MASK - out dx,ax - mov al,bl - stosb - dec ecx - -; draw remainder of the line - -L43: - mov ah,0Fh - mov al,MAP_MASK - out dx,ax - mov al,bl - rep stosb - pop eax - -; set pixels in rightmost byte of line - -L44: - mov al,MAP_MASK - out dx, ax - mov byte ptr [edi],bl - jmp Lexit - - -; routine for dy >= dx (slope <= 1) - -LoSlopeLine: - mov al,MAP_MASK - mov bh,byte ptr _modex_line_Color -L10: - mov ah,bl - -L11: - or ah,bl - rol bl,1 - jc L14 - -; bit mask not shifted out - - or esi,esi - jns L12 - add esi,_modex_line_incr1 - loop L11 - - out dx,ax - mov [edi],bh - jmp short Lexit - -L12: - add esi,_modex_line_incr2 - out dx,ax - mov [edi],bh - add edi,_modex_line_vertincr - loop L10 - jmp short Lexit - -; bit mask shifted out - -L14: out dx,ax - mov [edi],bh - inc edi - or esi,esi - jns L15 - add esi,_modex_line_incr1 - loop L10 - jmp short Lexit - -L15: - add esi,_modex_line_incr2 - add edi,_modex_line_vertincr - loop L10 - jmp short Lexit - -; routine for dy > dx (slope > 1) - -HiSlopeLine: - mov ebx,_modex_line_vertincr - mov al,MAP_MASK -L21: out dx,ax - push eax - mov al,_modex_line_Color - mov [edi],al - pop eax - add edi,ebx - -L22: - or esi,esi - jns L23 - - add esi,_modex_line_incr1 - loop L21 - jmp short Lexit - -L23: - add esi,_modex_line_incr2 - rol ah,1 - adc edi,0 -lx21: loop L21 - -; return to caller - -Lexit: - popa - ret - - - -_TEXT ENDS - - - END +; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. + +.386 + +_DATA SEGMENT BYTE PUBLIC USE32 'DATA' + +INCLUDE psmacros.inc +INCLUDE TWEAK.INC +INCLUDE VGAREGS.INC + +extd _gr_var_bwidth + +extd _modex_line_vertincr +extd _modex_line_incr1 +extd _modex_line_incr2 + _modex_line_routine dd ? +extd _modex_line_x1 +extd _modex_line_y1 +extd _modex_line_x2 +extd _modex_line_y2 +extb _modex_line_Color + + SavedColor db ? + +LEFT_MASK1 = 1000b +LEFT_MASK2 = 1100b +LEFT_MASK3 = 1110b +RIGHT_MASK1 = 0001b +RIGHT_MASK2 = 0011b +RIGHT_MASK3 = 0111b +ALL_MASK = 1111b + +tmppal db 768 dup (0) +fb_pal dd ? +fb_add dw ? +fb_count dd ? + +MaskTable1 db ALL_MASK AND RIGHT_MASK1, + ALL_MASK AND RIGHT_MASK2, + ALL_MASK AND RIGHT_MASK3, + ALL_MASK, + LEFT_MASK3 AND RIGHT_MASK1, + LEFT_MASK3 AND RIGHT_MASK2, + LEFT_MASK3 AND RIGHT_MASK3, + LEFT_MASK3, + LEFT_MASK2 AND RIGHT_MASK1, + LEFT_MASK2 AND RIGHT_MASK2, + LEFT_MASK2 AND RIGHT_MASK3, + LEFT_MASK2, + LEFT_MASK1 AND RIGHT_MASK1, + LEFT_MASK1 AND RIGHT_MASK2, + LEFT_MASK1 AND RIGHT_MASK3, + LEFT_MASK1, + +MaskTable2 db ALL_MASK,RIGHT_MASK1, + ALL_MASK,RIGHT_MASK2, + ALL_MASK,RIGHT_MASK3, + ALL_MASK,ALL_MASK, + LEFT_MASK3,RIGHT_MASK1, + LEFT_MASK3,RIGHT_MASK2, + LEFT_MASK3,RIGHT_MASK3, + LEFT_MASK3,ALL_MASK, + LEFT_MASK2,RIGHT_MASK1, + LEFT_MASK2,RIGHT_MASK2, + LEFT_MASK2,RIGHT_MASK3, + LEFT_MASK2,ALL_MASK, + LEFT_MASK1,RIGHT_MASK1, + LEFT_MASK1,RIGHT_MASK2, + LEFT_MASK1,RIGHT_MASK3, + LEFT_MASK1,ALL_MASK + +DrawTable dd DrawMR, + DrawMR, + DrawMR, + DrawM, + DrawLMR, + DrawLMR, + DrawLMR, + DrawLM, + DrawLMR, + DrawLMR, + DrawLMR, + DrawLM, + DrawLMR, + DrawLMR, + DrawLMR, + DrawLM + +_DATA ENDS + +DGROUP GROUP _DATA + + +_TEXT SEGMENT BYTE PUBLIC USE32 'CODE' + + ASSUME DS:_DATA + ASSUME CS:_TEXT + +PUBLIC gr_sync_display_ + +gr_sync_display_: + + push ax + push dx + mov dx, VERT_RESCAN +VS2A: in al, dx + and al, 08h + jnz VS2A ; Loop until not in vertical retrace +VS2B: in al, dx + and al, 08h + jz VS2B ; Loop until in vertical retrace + + pop dx + pop ax + ret + + +PUBLIC gr_modex_uscanline_ + +gr_modex_uscanline_: + push edi + + ; EAX = X1 (X1 and X2 don't need to be sorted) + ; EDX = X2 + ; EBX = Y + ; ECX = Color + + mov SavedColor, cl + + ;mov ebx, _RowOffset[ebx*4] + mov edi, _gr_var_bwidth + imul edi, ebx + add edi, 0A0000h + cmp eax, edx + jle @f + xchg eax, edx +@@: mov bl, al + shl bl, 2 + mov bh, dl + and bh, 011b + or bl, bh + and ebx, 0fh + ; BX = LeftRight switch command. (4bit) + shr eax, 2 + shr edx, 2 + add edi, eax + ; EDI = Offset into video memory + mov ecx, edx + sub ecx, eax + ; ECX = X2/4 - X1/4 - 1 + jnz LargerThan4 + +;======================= ONE GROUP OF 4 OR LESS TO DRAW ==================== + + mov dx, SC_INDEX + mov al, SC_MAP_MASK + out dx, al + inc dx + mov al, MaskTable1[ebx] + out dx, al + mov al, SavedColor + mov [edi], al ; Write the one pixel + pop edi + ret + +LargerThan4: + dec ecx + jnz LargerThan8 + +;===================== TWO GROUPS OF 4 OR LESS TO DRAW ==================== + + mov cx, WORD PTR MaskTable2[ebx*2] + mov bl, SavedColor + mov dx, SC_INDEX + mov al, SC_MAP_MASK + out dx, al + inc dx + mov al, cl + out dx, al + mov [edi], bl ; Write the left pixel + mov al, ch + out dx, al + mov [edi+1], bl ; Write the right pixel + pop edi + ret + +;========================= MANY GROUPS OF 4 TO DRAW ====================== +LargerThan8: + mov dx, SC_INDEX + mov al, SC_MAP_MASK + out dx, al + inc dx + ; DX = SC_INDEX + mov al, SavedColor + mov ah, al + ; AL,AH = color of pixel + jmp NEAR32 PTR DrawTable[ebx*4] + + +DrawM: ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index + mov al, ALL_MASK + out dx, al + mov al, ah + cld + add ecx, 2 + shr ecx, 1 + rep stosw ; Write the middle pixels + jnc @F + stosb ; Write the middle odd pixel +@@: pop edi + ret + +DrawLM: + ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index + mov al, BYTE PTR MaskTable2[ebx*2] + out dx, al + mov [edi], ah ; Write leftmost pixels + inc edi + mov al, ALL_MASK + out dx, al + mov al, ah + cld + inc ecx + shr ecx, 1 + rep stosw ; Write the middle pixels + jnc @F + stosb ; Write the middle odd pixel +@@: pop edi + ret + + +DrawLMR: ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index + mov bx, WORD PTR MaskTable2[ebx*2] + mov al, bl + out dx, al + mov [edi], ah ; Write leftmost pixels + inc edi + mov al, ALL_MASK + out dx, al + mov al, ah + cld + shr ecx, 1 + rep stosw ; Write the middle pixels + jnc @F + stosb ; Write the middle odd pixel +@@: mov al, bh + out dx, al + mov [edi], ah ; Write the rightmost pixels + pop edi + ret + +DrawMR: ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index + mov bx, WORD PTR MaskTable2[ebx*2] + mov al, ALL_MASK + out dx, al + mov al, ah + cld + inc ecx + shr ecx, 1 + rep stosw ; Write the middle pixels + jnc @F + stosb ; Write the middle odd pixel +@@: mov al, bh + out dx, al + mov [edi], ah ; Write the rightmost pixels + pop edi + ret + + +PUBLIC gr_modex_setmode_ + +gr_modex_setmode_: + + push ebx + push ecx + push edx + push esi + push edi + + mov ecx, eax + dec ecx + + cmp ecx, LAST_X_MODE + jbe @f + mov ecx, 0 +@@: + + ;call turn_screen_off + + push ecx ; some bios's dont preserve cx + + ;mov ax, 1201h + ;mov bl, 31h ; disable palette loading at mode switch + ;int 10h + mov ax,13h ; let the BIOS set standard 256-color + int 10h ; mode (320x200 linear) + ;mov ax, 1200h + ;mov bl, 31h ; enable palette loading at mode switch + ;int 10h + + pop ecx + + mov dx,SC_INDEX + mov ax,0604h + out dx,ax ; disable chain4 mode + + mov dx,SC_INDEX + mov ax,0100h + out dx,ax ; synchronous reset while setting Misc + ; Output for safety, even though clock + ; unchanged + + mov esi, dword ptr ModeTable[ecx*4] + lodsb + + or al,al + jz DontSetDot + + mov dx,MISC_OUTPUT + out dx,al ; select the dot clock and Horiz + ; scanning rate + + ;mov dx,SC_INDEX + ;mov al,01h + ;out dx,al + ;inc dx + ;in al, dx + ;or al, 1000b + ;out dx, al + +DontSetDot: + mov dx,SC_INDEX + mov ax,0300h + out dx,ax ; undo reset (restart sequencer) + + mov dx,CRTC_INDEX ; reprogram the CRT Controller + mov al,11h ; VSync End reg contains register write + out dx,al ; protect bit + inc dx ; CRT Controller Data register + in al,dx ; get current VSync End register setting + and al,07fh ; remove write protect on various + out dx,al ; CRTC registers + dec dx ; CRT Controller Index + cld + xor ecx,ecx + lodsb + mov cl,al + +SetCRTParmsLoop: + lodsw ; get the next CRT Index/Data pair + out dx,ax ; set the next CRT Index/Data pair + loop SetCRTParmsLoop + + mov dx,SC_INDEX + mov ax,0f02h + out dx,ax ; enable writes to all four planes + mov edi, 0A0000h ; point ES:DI to display memory + xor ax,ax ; clear to zero-value pixels + mov ecx,8000h ; # of words in display memory + rep stosw ; clear all of display memory + + ; Set pysical screen dimensions + + xor eax, eax + lodsw ; Load scrn pixel width + mov cx, ax + shl eax, 16 + + mov dx,CRTC_INDEX + mov al,CRTC_OFFSET + out dx,al + inc dx + mov ax,cx + shr ax,3 + out dx,al + + ;mov si, 360 + ;@@: + ;mov ax, 04f06h + ;mov bl, 0 + ;mov cx, si + ;int 10h + ;cmp cx, si + ;je @f + ;inc si + ;jmp @B + ;@@: + ;movzx eax, si + + lodsw ; Load Screen Phys. Height + + ;call turn_screen_on + + pop edi + pop esi + pop edx + pop ecx + pop ebx + + ret + +PUBLIC gr_modex_setplane_ + +gr_modex_setplane_: + + push cx + push dx + + mov cl, al + + ; SELECT WRITE PLANE + and cl,011b ;CL = plane + mov ax,0100h + MAP_MASK ;AL = index in SC of Map Mask reg + shl ah,cl ;set only the bit for the required + ; plane to 1 + mov dx,SC_INDEX ;set the Map Mask to enable only the + out dx,ax ; pixel's plane + + ; SELECT READ PLANE + mov ah,cl ;AH = plane + mov al,READ_MAP ;AL = index in GC of the Read Map reg + mov dx,GC_INDEX ;set the Read Map to read the pixel's + out dx,ax ; plane + + pop dx + pop cx + + ret + +PUBLIC gr_modex_setstart_ + +gr_modex_setstart_: + + ; EAX = X + ; EDX = Y + ; EBX = Wait for retrace + + push ebx + push ecx + push ebx + + mov ecx, _gr_var_bwidth + imul ecx, edx + + shr eax, 2 + add eax, ecx + + mov ch, ah + mov bh, al + + mov bl, CC_START_LO + mov cl, CC_START_HI + + cli + mov dx, VERT_RESCAN +WaitDE: in al, dx + test al, 01h + jnz WaitDE + + mov dx, CRTC_INDEX + mov ax, bx + out dx, ax ; Start address low + mov ax, cx + out dx, ax ; Start address high + sti + + pop ebx + cmp ebx, 0 + je NoWaitVS + mov dx, VERT_RESCAN +WaitVS: in al, dx + test al, 08h + jz WaitVS ; Loop until in vertical retrace +NoWaitVS: + + pop ecx + pop ebx + + ret + + + + +ModeXAddr macro +; given: ebx=x, eax=y, return cl=plane mask, ebx=address, trash eax + mov cl, bl + and cl, 3 + shr ebx, 2 + imul eax, _gr_var_bwidth + add ebx, eax + add ebx, 0A0000h + endm + + +;----------------------------------------------------------------------- +; +; Line drawing function for all MODE X 256 Color resolutions +; Based on code from "PC and PS/2 Video Systems" by Richard Wilton. + +PUBLIC gr_modex_line_ + +gr_modex_line_: + pusha + + mov dx,SC_INDEX ; setup for plane mask access + +; check for vertical line + + mov esi,_gr_var_bwidth + mov ecx,_modex_line_x2 + sub ecx,_modex_line_x1 + jz VertLine + +; force x1 < x2 + + jns L01 + + neg ecx + + mov ebx,_modex_line_x2 + xchg ebx,_modex_line_x1 + mov _modex_line_x2,ebx + + mov ebx,_modex_line_y2 + xchg ebx,_modex_line_y1 + mov _modex_line_y2,ebx + +; calc dy = abs(y2 - y1) + +L01: + mov ebx,_modex_line_y2 + sub ebx,_modex_line_y1 + jnz short skip + jmp HorizLine +skip: jns L03 + + neg ebx + neg esi + +; select appropriate routine for slope of line + +L03: + mov _modex_line_vertincr,esi + mov _modex_line_routine,offset LoSlopeLine + cmp ebx,ecx + jle L04 + mov _modex_line_routine,offset HiSlopeLine + xchg ebx,ecx + +; calc initial decision variable and increments + +L04: + shl ebx,1 + mov _modex_line_incr1,ebx + sub ebx,ecx + mov esi,ebx + sub ebx,ecx + mov _modex_line_incr2,ebx + +; calc first pixel address + + push ecx + mov eax,_modex_line_y1 + mov ebx,_modex_line_x1 + ModeXAddr + mov edi,ebx + mov al,1 + shl al,cl + mov ah,al ; duplicate nybble + shl al,4 + add ah,al + mov bl,ah + pop ecx + inc ecx + jmp [_modex_line_routine] + +; routine for verticle lines + +VertLine: + mov eax,_modex_line_y1 + mov ebx,_modex_line_y2 + mov ecx,ebx + sub ecx,eax + jge L31 + neg ecx + mov eax,ebx + +L31: + inc ecx + mov ebx,_modex_line_x1 + push ecx + ModeXAddr + + mov ah,1 + shl ah,cl + mov al,MAP_MASK + out dx,ax + pop ecx + mov ax, word ptr _modex_line_Color + +; draw the line + +L32: + mov [ebx],al + add ebx,esi + loop L32 + jmp Lexit + +; routine for horizontal line + +HorizLine: + + mov eax,_modex_line_y1 + mov ebx,_modex_line_x1 + ModeXAddr + + mov edi,ebx ; set dl = first byte mask + mov dl,00fh + shl dl,cl + + mov ecx,_modex_line_x2 ; set dh = last byte mask + and cl,3 + mov dh,00eh + shl dh,cl + not dh + +; determine byte offset of first and last pixel in line + + mov eax,_modex_line_x2 + mov ebx,_modex_line_x1 + + shr eax,2 ; set ax = last byte column + shr ebx,2 ; set bx = first byte column + mov ecx,eax ; cx = ax - bx + sub ecx,ebx + + mov eax,edx ; mov end byte masks to ax + mov dx,SC_INDEX ; setup dx for VGA outs + mov bl,_modex_line_Color + +; set pixels in leftmost byte of line + + or ecx,ecx ; is start and end pt in same byte + jnz L42 ; no ! + and ah,al ; combine start and end masks + jmp short L44 + +L42: push eax + mov ah,al + mov al,MAP_MASK + out dx,ax + mov al,bl + stosb + dec ecx + +; draw remainder of the line + +L43: + mov ah,0Fh + mov al,MAP_MASK + out dx,ax + mov al,bl + rep stosb + pop eax + +; set pixels in rightmost byte of line + +L44: + mov al,MAP_MASK + out dx, ax + mov byte ptr [edi],bl + jmp Lexit + + +; routine for dy >= dx (slope <= 1) + +LoSlopeLine: + mov al,MAP_MASK + mov bh,byte ptr _modex_line_Color +L10: + mov ah,bl + +L11: + or ah,bl + rol bl,1 + jc L14 + +; bit mask not shifted out + + or esi,esi + jns L12 + add esi,_modex_line_incr1 + loop L11 + + out dx,ax + mov [edi],bh + jmp short Lexit + +L12: + add esi,_modex_line_incr2 + out dx,ax + mov [edi],bh + add edi,_modex_line_vertincr + loop L10 + jmp short Lexit + +; bit mask shifted out + +L14: out dx,ax + mov [edi],bh + inc edi + or esi,esi + jns L15 + add esi,_modex_line_incr1 + loop L10 + jmp short Lexit + +L15: + add esi,_modex_line_incr2 + add edi,_modex_line_vertincr + loop L10 + jmp short Lexit + +; routine for dy > dx (slope > 1) + +HiSlopeLine: + mov ebx,_modex_line_vertincr + mov al,MAP_MASK +L21: out dx,ax + push eax + mov al,_modex_line_Color + mov [edi],al + pop eax + add edi,ebx + +L22: + or esi,esi + jns L23 + + add esi,_modex_line_incr1 + loop L21 + jmp short Lexit + +L23: + add esi,_modex_line_incr2 + rol ah,1 + adc edi,0 +lx21: loop L21 + +; return to caller + +Lexit: + popa + ret + + + +_TEXT ENDS + + + END diff --git a/unused/vga/tweak.inc b/unused/vga/tweak.inc index 3d4a437f..e74d427e 100644 --- a/unused/vga/tweak.inc +++ b/unused/vga/tweak.inc @@ -1,235 +1,235 @@ -; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX -; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO -; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A -; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS -; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS -; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE -; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE -; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS -; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. -; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. - -; Mode X CRTC register tweaks for various resolutions - -X320Y200 db 00 ; 0e3h ; dot clock - db 02 ; Number of CRTC Registers to update - dw 00014h ; turn off dword mode - dw 0e317h ; turn on byte mode - dw 320 ; width - dw 200 ; height - -X320Y240 db 0e3h ; dot clock - db 10 ; Number of CRTC Registers to update - dw 00d06h ; vertical total - dw 03e07h ; overflow (bit 8 of vertical counts) - dw 04109h ; cell height (2 to double-scan) - dw 0ea10h ; v sync start - dw 0ac11h ; v sync end and protect cr0-cr7 - dw 0df12h ; vertical displayed - dw 00014h ; turn off dword mode - dw 0e715h ; v blank start - dw 00616h ; v blank end - dw 0e317h ; turn on byte mode - dw 320 ; width - dw 240 ; height - -X360Y200 db 0e7h ; dot clock - db 08 ; Number of CRTC Registers to update - dw 06b00h ; horz total - dw 05901h ; horz displayed - dw 05a02h ; start horz blanking - dw 08e03h ; end horz blanking - dw 05e04h ; start h sync - dw 08a05h ; end h sync - dw 00014h ; turn off dword mode - dw 0e317h ; turn on byte mode - dw 360 ; width - dw 200 ; height - - -X360Y240 db 0e7h ; dot clock - db 17 ; Number of CRTC Registers to update - dw 06b00h ; horz total - dw 05901h ; horz displayed - dw 05a02h ; start horz blanking - dw 08e03h ; end horz blanking - dw 05e04h ; start h sync - dw 08a05h ; end h sync - dw 00d06h ; vertical total - dw 03e07h ; overflow (bit 8 of vertical counts) - dw 04109h ; cell height (2 to double-scan) - dw 0ea10h ; v sync start - dw 0ac11h ; v sync end and protect cr0-cr7 - dw 0df12h ; vertical displayed - dw 02d13h ; offset; - dw 00014h ; turn off dword mode - dw 0e715h ; v blank start - dw 00616h ; v blank end - dw 0e317h ; turn on byte mode - dw 360 - dw 240 - -X376Y282 db 0e7h - db 18 - dw 06e00h ; horz total - dw 05d01h ; horz displayed - dw 05e02h ; start horz blanking - dw 09103h ; end horz blanking - dw 06204h ; start h sync - dw 08f05h ; end h sync - dw 06206h ; vertical total - dw 0f007h ; overflow - dw 06109h ; cell height - dw 0310fh ; - dw 03710h ; v sync start - dw 08911h ; v sync end and protect cr0-cr7 - dw 03312h ; vertical displayed - dw 02f13h ; offset - dw 00014h ; turn off dword mode - dw 03c15h ; v blank start - dw 05c16h ; v blank end - dw 0eb17h ; turn on byte mode - dw 376 - dw 282 - - -X320Y400 db 0h ; dot clock - db 03 ; Number of CRTC Registers to update - dw 04009h ; cell height - dw 00014h ; turn off dword mode - dw 0e317h ; turn on byte mode - dw 320 ; width - dw 400 ; height - -X320Y480 db 0e3h ; dotclock - db 10 ; Number of CRTC Registers to update - dw 00d06h ; vertical total - dw 03e07h ; overflow (bit 8 of vertical counts) - dw 04009h ; cell height (2 to double-scan) - dw 0ea10h ; v sync start - dw 0ac11h ; v sync end and protect cr0-cr7 - dw 0df12h ; vertical displayed - dw 00014h ; turn off dword mode - dw 0e715h ; v blank start - dw 00616h ; v blank end - dw 0e317h ; turn on byte mode - dw 320 ; width - dw 480 ; height - -X360Y400 db 0e7h ; dot clock - db 09 ; Number of CRTC Registers to update - dw 06b00h ; horz total - dw 05901h ; horz displayed - dw 05a02h ; start horz blanking - dw 08e03h ; end horz blanking - dw 05e04h ; start h sync - dw 08a05h ; end h sync - dw 04009h ; cell height - dw 00014h ; turn off dword mode - dw 0e317h ; turn on byte mode - dw 360 ; width - dw 400 ; height - -X360Y480 db 0e7h - db 17 - dw 06b00h ; horz total - dw 05901h ; horz displayed - dw 05a02h ; start horz blanking - dw 08e03h ; end horz blanking - dw 05e04h ; start h sync - dw 08a05h ; end h sync - dw 00d06h ; vertical total - dw 03e07h ; overflow - dw 04009h ; cell height - dw 0ea10h ; v sync start - dw 0ac11h ; v sync end and protect cr0-cr7 - dw 0df12h ; vertical displayed - dw 02d13h ; offset - dw 00014h ; turn off dword mode - dw 0e715h ; v blank start - dw 00616h ; v blank end - dw 0e317h ; turn on byte mode - dw 360 - dw 480 - -X360Y360 db 0e7h - db 15 - dw 06b00h ; horz total - dw 05901h ; horz displayed - dw 05a02h ; start horz blanking - dw 08e03h ; end horz blanking - dw 05e04h ; start h sync - dw 08a05h ; end h sync - dw 04009h ; cell height - dw 08810h ; v sync start - dw 08511h ; v sync end and protect cr0-cr7 - dw 06712h ; vertical displayed - dw 02d13h ; offset - dw 00014h ; turn off dword mode - dw 06d15h ; v blank start - dw 0ba16h ; v blank end - dw 0e317h ; turn on byte mode - dw 360 - dw 360 - -X376Y308 db 0e7h - db 18 - dw 06e00h ; horz total - dw 05d01h ; horz displayed - dw 05e02h ; start horz blanking - dw 09103h ; end horz blanking - dw 06204h ; start h sync - dw 08f05h ; end h sync - dw 06206h ; vertical total - dw 00f07h ; overflow - dw 04009h ; - dw 0310fh ; - dw 03710h ; v sync start - dw 08911h ; v sync end and protect cr0-cr7 - dw 03312h ; vertical displayed - dw 02f13h ; offset - dw 00014h ; turn off dword mode - dw 03c15h ; v blank start - dw 05c16h ; v blank end - dw 0e317h ; turn on byte mode - dw 376 - dw 308 - -X376Y564 db 0e7h - db 18 - dw 06e00h ; horz total - dw 05d01h ; horz displayed - dw 05e02h ; start horz blanking - dw 09103h ; end horz blanking - dw 06204h ; start h sync - dw 08f05h ; end h sync - dw 06206h ; vertical total - dw 0f007h ; overflow - dw 06009h ; - dw 0310fh ; - dw 03710h ; v sync start - dw 08911h ; v sync end and protect cr0-cr7 - dw 03312h ; vertical displayed - dw 02f13h ; offset - dw 00014h ; turn off dword mode - dw 03c15h ; v blank start - dw 05c16h ; v blank end - dw 0e317h ; turn on byte mode - dw 376 - dw 564 - -LAST_X_MODE equ 11 - -ModeTable dd offset X320Y200 - dd offset X320Y240 - dd offset X360Y200 - dd offset X360Y240 - dd offset X376Y282 - dd offset X320Y400 - dd offset X320Y480 - dd offset X360Y400 - dd offset X360Y480 - dd offset X360Y360 - dd offset X376Y308 - dd offset X376Y564 - +; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. + +; Mode X CRTC register tweaks for various resolutions + +X320Y200 db 00 ; 0e3h ; dot clock + db 02 ; Number of CRTC Registers to update + dw 00014h ; turn off dword mode + dw 0e317h ; turn on byte mode + dw 320 ; width + dw 200 ; height + +X320Y240 db 0e3h ; dot clock + db 10 ; Number of CRTC Registers to update + dw 00d06h ; vertical total + dw 03e07h ; overflow (bit 8 of vertical counts) + dw 04109h ; cell height (2 to double-scan) + dw 0ea10h ; v sync start + dw 0ac11h ; v sync end and protect cr0-cr7 + dw 0df12h ; vertical displayed + dw 00014h ; turn off dword mode + dw 0e715h ; v blank start + dw 00616h ; v blank end + dw 0e317h ; turn on byte mode + dw 320 ; width + dw 240 ; height + +X360Y200 db 0e7h ; dot clock + db 08 ; Number of CRTC Registers to update + dw 06b00h ; horz total + dw 05901h ; horz displayed + dw 05a02h ; start horz blanking + dw 08e03h ; end horz blanking + dw 05e04h ; start h sync + dw 08a05h ; end h sync + dw 00014h ; turn off dword mode + dw 0e317h ; turn on byte mode + dw 360 ; width + dw 200 ; height + + +X360Y240 db 0e7h ; dot clock + db 17 ; Number of CRTC Registers to update + dw 06b00h ; horz total + dw 05901h ; horz displayed + dw 05a02h ; start horz blanking + dw 08e03h ; end horz blanking + dw 05e04h ; start h sync + dw 08a05h ; end h sync + dw 00d06h ; vertical total + dw 03e07h ; overflow (bit 8 of vertical counts) + dw 04109h ; cell height (2 to double-scan) + dw 0ea10h ; v sync start + dw 0ac11h ; v sync end and protect cr0-cr7 + dw 0df12h ; vertical displayed + dw 02d13h ; offset; + dw 00014h ; turn off dword mode + dw 0e715h ; v blank start + dw 00616h ; v blank end + dw 0e317h ; turn on byte mode + dw 360 + dw 240 + +X376Y282 db 0e7h + db 18 + dw 06e00h ; horz total + dw 05d01h ; horz displayed + dw 05e02h ; start horz blanking + dw 09103h ; end horz blanking + dw 06204h ; start h sync + dw 08f05h ; end h sync + dw 06206h ; vertical total + dw 0f007h ; overflow + dw 06109h ; cell height + dw 0310fh ; + dw 03710h ; v sync start + dw 08911h ; v sync end and protect cr0-cr7 + dw 03312h ; vertical displayed + dw 02f13h ; offset + dw 00014h ; turn off dword mode + dw 03c15h ; v blank start + dw 05c16h ; v blank end + dw 0eb17h ; turn on byte mode + dw 376 + dw 282 + + +X320Y400 db 0h ; dot clock + db 03 ; Number of CRTC Registers to update + dw 04009h ; cell height + dw 00014h ; turn off dword mode + dw 0e317h ; turn on byte mode + dw 320 ; width + dw 400 ; height + +X320Y480 db 0e3h ; dotclock + db 10 ; Number of CRTC Registers to update + dw 00d06h ; vertical total + dw 03e07h ; overflow (bit 8 of vertical counts) + dw 04009h ; cell height (2 to double-scan) + dw 0ea10h ; v sync start + dw 0ac11h ; v sync end and protect cr0-cr7 + dw 0df12h ; vertical displayed + dw 00014h ; turn off dword mode + dw 0e715h ; v blank start + dw 00616h ; v blank end + dw 0e317h ; turn on byte mode + dw 320 ; width + dw 480 ; height + +X360Y400 db 0e7h ; dot clock + db 09 ; Number of CRTC Registers to update + dw 06b00h ; horz total + dw 05901h ; horz displayed + dw 05a02h ; start horz blanking + dw 08e03h ; end horz blanking + dw 05e04h ; start h sync + dw 08a05h ; end h sync + dw 04009h ; cell height + dw 00014h ; turn off dword mode + dw 0e317h ; turn on byte mode + dw 360 ; width + dw 400 ; height + +X360Y480 db 0e7h + db 17 + dw 06b00h ; horz total + dw 05901h ; horz displayed + dw 05a02h ; start horz blanking + dw 08e03h ; end horz blanking + dw 05e04h ; start h sync + dw 08a05h ; end h sync + dw 00d06h ; vertical total + dw 03e07h ; overflow + dw 04009h ; cell height + dw 0ea10h ; v sync start + dw 0ac11h ; v sync end and protect cr0-cr7 + dw 0df12h ; vertical displayed + dw 02d13h ; offset + dw 00014h ; turn off dword mode + dw 0e715h ; v blank start + dw 00616h ; v blank end + dw 0e317h ; turn on byte mode + dw 360 + dw 480 + +X360Y360 db 0e7h + db 15 + dw 06b00h ; horz total + dw 05901h ; horz displayed + dw 05a02h ; start horz blanking + dw 08e03h ; end horz blanking + dw 05e04h ; start h sync + dw 08a05h ; end h sync + dw 04009h ; cell height + dw 08810h ; v sync start + dw 08511h ; v sync end and protect cr0-cr7 + dw 06712h ; vertical displayed + dw 02d13h ; offset + dw 00014h ; turn off dword mode + dw 06d15h ; v blank start + dw 0ba16h ; v blank end + dw 0e317h ; turn on byte mode + dw 360 + dw 360 + +X376Y308 db 0e7h + db 18 + dw 06e00h ; horz total + dw 05d01h ; horz displayed + dw 05e02h ; start horz blanking + dw 09103h ; end horz blanking + dw 06204h ; start h sync + dw 08f05h ; end h sync + dw 06206h ; vertical total + dw 00f07h ; overflow + dw 04009h ; + dw 0310fh ; + dw 03710h ; v sync start + dw 08911h ; v sync end and protect cr0-cr7 + dw 03312h ; vertical displayed + dw 02f13h ; offset + dw 00014h ; turn off dword mode + dw 03c15h ; v blank start + dw 05c16h ; v blank end + dw 0e317h ; turn on byte mode + dw 376 + dw 308 + +X376Y564 db 0e7h + db 18 + dw 06e00h ; horz total + dw 05d01h ; horz displayed + dw 05e02h ; start horz blanking + dw 09103h ; end horz blanking + dw 06204h ; start h sync + dw 08f05h ; end h sync + dw 06206h ; vertical total + dw 0f007h ; overflow + dw 06009h ; + dw 0310fh ; + dw 03710h ; v sync start + dw 08911h ; v sync end and protect cr0-cr7 + dw 03312h ; vertical displayed + dw 02f13h ; offset + dw 00014h ; turn off dword mode + dw 03c15h ; v blank start + dw 05c16h ; v blank end + dw 0e317h ; turn on byte mode + dw 376 + dw 564 + +LAST_X_MODE equ 11 + +ModeTable dd offset X320Y200 + dd offset X320Y240 + dd offset X360Y200 + dd offset X360Y240 + dd offset X376Y282 + dd offset X320Y400 + dd offset X320Y480 + dd offset X360Y400 + dd offset X360Y480 + dd offset X360Y360 + dd offset X376Y308 + dd offset X376Y564 + diff --git a/unused/vga/vesa.asm b/unused/vga/vesa.asm index 13d8d732..8e70cf7d 100644 --- a/unused/vga/vesa.asm +++ b/unused/vga/vesa.asm @@ -1,925 +1,925 @@ -; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX -; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO -; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A -; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS -; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS -; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE -; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE -; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS -; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. -; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. -.386 - -OPTION OLDSTRUCTS -INCLUDE VGAREGS.INC -INCLUDE GR.INC - -_DATA SEGMENT BYTE PUBLIC USE32 'DATA' - - PUBLIC __A0000 - __A0000 dw ? - - BufferPtr dd 0 - BufferSeg dw 0 - GoalMode dw ? - LastPage db 0FFh - - BPR dw ? - TempReg dd ? - - ; Information from VESA return SuperVGA Information - - VESAVersion dw ? - OEMStringPtr dd ? - Capabilities dd ? - VideoModePtr dd ? - TotalMemory dw ? - WinGranularity dw ? - WinSize dw ? - WinFuncPtr dd ? - PageSizeShift db ? - WinAttributes dw ? - - - VESA_Signature = 041534556h - -REALREGS STRUCT - RealEDI dd ? - RealESI dd ? - RealEBP dd ? - Reserved dd ? - RealEBX dd ? - RealEDX dd ? - RealECX dd ? - RealEAX dd ? - RealFlags dw ? - RealES dw ? - RealDS dw ? - RealFS dw ? - RealGS dw ? - RealIP dw ? - RealCS dw ? - RealSP dw ? - RealSS dw ? -REALREGS ENDS - - regs REALREGS < > - - vesa_error dd ? - SourceInc dd ? - DestInc dw ? - RowWidth dd ? - - extern _gr_var_color:dword, _gr_var_bwidth:dword - - -_DATA ENDS - -DGROUP GROUP _DATA - - -_TEXT SEGMENT BYTE PUBLIC USE32 'CODE' - - ASSUME DS:_DATA - ASSUME CS:_TEXT - -MyStosd MACRO Width:REQ -; Assumes: EDI = Dest Address -; Width = a 32-bit value, can't be ECX or EDI -; Trashes: ECX will be zero -; EDI = Dest Address + Width -; EDX = ???? -; Width -LOCAL Aligned - cmp Width, 16 - jbe Aligned - mov ecx, edi - and ecx, 3 - jcxz Aligned - neg ecx - add ecx, 4 - sub Width, ecx - rep stosb -Aligned: mov ecx, Width - shr ecx, 2 - rep stosd - mov ecx, Width - and ecx, 3 - rep stosb -ENDM - - -ENTER_PROC MACRO - push esi - push edi - push ebp - push eax - push ebx - push ecx - push edx -ENDM - -EXIT_PROC MACRO - - cmp [esp-4], edx - je @f - ; YOU TRASHED EDX !!!!!!! - int 3 -@@: pop edx - - cmp [esp-4], ecx - je @f - ; YOU TRASHED ECX !!!!!!! - int 3 -@@: pop ecx - - cmp [esp-4], ebx - je @f - ; YOU TRASHED EBX !!!!!!! - int 3 -@@: pop ebx - - cmp [esp-4], eax - je @f - ; YOU TRASHED EAX !!!!!!! - int 3 -@@: pop eax - - cmp [esp-4], ebp - je @f - ; YOU TRASHED EBP !!!!!!! - int 3 -@@: pop ebp - - cmp [esp-4], edi - je @f - ; YOU TRASHED EDI !!!!!!! - int 3 -@@: pop edi - - cmp [esp-4], esi - je @f - ; YOU TRASHED ESI !!!!!!! - int 3 -@@: pop esi - -ENDM - - -MyMovsd MACRO Width:REQ -; Assumes: EDI = Dest Address -; ESI = Source Address -; Width = a 32-bit value, can't be ECX or EDI or ESI -; Assumes that ESI is already aligned -; Trashes: ECX will be zero -; EDI = Dest Address + Width -; ESI = Source Address + Width -; EDX = ???? -LOCAL Aligned - cmp Width, 16 - jbe Aligned - mov ecx, edi - and ecx, 3 - jcxz Aligned - neg ecx - add ecx, 4 - sub Width, ecx - rep movsb -Aligned: mov ecx, Width - shr ecx, 2 - rep movsd - mov ecx, Width - and ecx, 3 - rep movsb -ENDM - - -EBXFarTo32: - push ecx - mov ecx, ebx - and ecx, 0FFFF0000h - shr ecx, 12 - and ebx, 0FFFFh - add ebx, ecx - pop ecx - ret - -PUBLIC gr_init_A0000_ - -gr_init_A0000_: - - push ebx - mov ax, 0002h - mov bx, 0a000h - int 31h - jc NoGo - mov __A0000, ax - pop ebx - xor eax, eax - ret -NoGo: pop ebx - mov eax, 1 - ret - -PUBLIC gr_vesa_checkmode_ - -gr_vesa_checkmode_: - pushad - - mov GoalMode, ax - cmp BufferSeg, 0 - jne GotDosMemory - - ; Allocate a 256 byte block of DOS memory using DPMI - mov ax, 0100h - mov bx, 16 - int 31h - jc NoMemory - - ; AX = real mode segment of allocated block - and eax, 0FFFFh - mov BufferSeg, ax - shl eax, 4 ; EAX = 32-bit pointer to DOS memory - mov BufferPtr, eax -GotDosMemory: - - - ; Get SuperVGA information - mov ax, BufferSeg - mov regs.RealEDI, 0 - mov regs.RealESI, 0 - mov regs.RealEBP, 0 - mov regs.Reserved, 0 - mov regs.RealEBX, 0 - mov regs.RealEDX, 0 - mov regs.RealECX, 0 - mov regs.RealEAX, 04f00h - mov regs.RealFlags, 0 - mov regs.RealES, ax - mov regs.RealDS, 0 - mov regs.RealFS, 0 - mov regs.RealGS, 0 - mov regs.RealIP, 0 - mov regs.RealCS, 0 - mov regs.RealSP, 0 - mov regs.RealSS, 0 - - mov bl, 10h - xor bh, bh - xor ecx, ecx - mov edi, offset regs - mov ax, 0300h - int 31h - - mov eax, regs.RealEAX - cmp ax, 04fh - jne NoVESADriver - - ; Make sure there is a VESA signature - mov eax, BufferPtr - cmp dword ptr[eax+0], VESA_Signature - jne NoVESADriver - - ; We now have a valid VESA driver loaded - - mov bx, word ptr [eax+4] - mov VESAVersion, bx - - mov ebx, dword ptr [eax+6] - call EBXFarTo32 - mov OEMStringPtr, ebx - - mov ebx, dword ptr [eax+10] - mov Capabilities, ebx - - mov bx, word ptr [eax+18] - mov TotalMemory, bx - - mov ebx, dword ptr [eax+14] - call EBXFarTo32 - mov VideoModePtr, ebx - -TryAnotherMode: - mov ax, word ptr [ebx] - add ebx, 2 - cmp ax, GoalMode - je ModeSupported - cmp ax, -1 - je ModeNotSupported - jmp TryAnotherMode - -ModeSupported: - - ; Get SuperVGA information - mov ax, BufferSeg - movzx ecx, GoalMode - mov regs.RealEDI, 0 - mov regs.RealESI, 0 - mov regs.RealEBP, 0 - mov regs.Reserved, 0 - mov regs.RealEBX, 0 - mov regs.RealEDX, 0 - mov regs.RealECX, ecx - mov regs.RealEAX, 04f01h - mov regs.RealFlags, 0 - mov regs.RealES, ax - mov regs.RealDS, 0 - mov regs.RealFS, 0 - mov regs.RealGS, 0 - mov regs.RealIP, 0 - mov regs.RealCS, 0 - mov regs.RealSP, 0 - mov regs.RealSS, 0 - - mov bl, 10h - xor bh, bh - xor cx, cx - mov edi, offset regs - mov ax, 0300h - int 31h - - mov eax, regs.RealEAX - cmp ax, 04fh - jne BadStatus - - ; Check if this mode supported by hardware. - mov eax, BufferPtr - mov bx, [eax] - bt bx, 0 - jnc HardwareNotSupported - - - mov bx, [eax+4] - cmp bx, 64 - jne @f - mov PageSizeShift, 0 - jmp GranularityOK -@@: cmp bx, 32 - jne @f - mov PageSizeShift, 1 - jmp GranularityOK -@@: cmp bx, 16 - jne @f - mov PageSizeShift, 2 - jmp GranularityOK -@@: cmp bx, 8 - jne @f - mov PageSizeShift, 3 - jmp GranularityOK -@@: cmp bx, 4 - jne @f - mov PageSizeShift, 4 - jmp GranularityOK -@@: cmp bx, 2 - jne @f - mov PageSizeShift, 5 - jmp GranularityOK -@@: cmp bx, 1 - jne WrongGranularity - mov PageSizeShift, 6 - -GranularityOK: - shl bx, 10 - mov WinGranularity, bx - - mov bx, [eax+6] - mov WinSize, bx - - mov ebx, [eax+12] - call EBXFarTo32 - mov WinFuncPtr, ebx - - mov bl, byte ptr [eax+2] - mov bh, byte ptr [eax+3] - mov word ptr WinAttributes, bx - - movzx ebx, word ptr [eax+16] - -NoError: - mov vesa_error, 0 - jmp Done - -WrongGranularity: - mov vesa_error, 2 - jmp Done - -HardwareNotSupported: - mov vesa_error, 3 - jmp Done - -ModeNotSupported: - mov vesa_error, 4 - jmp Done - -NoVESADriver: - mov vesa_error, 5 - jmp Done - -BadStatus: - mov vesa_error, 6 - jmp Done - -NoMemory: - mov vesa_error, 7 - jmp Done - -DPMIError: - mov vesa_error, 8 - -Done: popad - mov eax, vesa_error - - ret - -PUBLIC gr_get_dos_mem_ - -gr_get_dos_mem_: - - ; eax = how many bytes - - push ebx - - mov ebx, eax - shr ebx, 4 - mov eax, 0100h - int 31h - jc nomem - and eax, 0ffffh - shl eax, 4 - pop ebx - ret - -nomem: pop ebx - mov eax,0 - ret - - - - -PUBLIC gr_vesa_setmodea_ - -gr_vesa_setmodea_: - - ; eax = mode - pushad - mov LastPage,0ffh ;force page reset - mov ebx, eax - mov eax, 04f02h - int 10h - cmp ax, 04fh - jne BadStatus - jmp NoError - -PUBLIC gr_vesa_setpage_ - -gr_vesa_setpage_: - - ; EAX = 64K Page number - and eax, 0ffh - cmp al, LastPage - jne @f - ret -@@: mov LastPage, al - push edx - push ebx - push ecx - mov edx, eax - mov cl, PageSizeShift - shl edx, cl ; Convert from 64K pages to GranUnit pages. - push edx - xor ebx, ebx ; BH=Select window, BL=Window A - mov eax, 04f05h ; AX=Super VGA video memory window control - int 10h - - ; New code to fix those ATI Mach64's with separate - ; read/write pages. - mov bx, word ptr WinAttributes - and ebx, 0110b ; Set if PageA can read and write - cmp ebx, 0110b - jne WinACantReadAndWrite - pop edx - pop ecx - pop ebx - pop edx - ret - -WinACantReadAndWrite: ; Page A can't read and write, so we need to update page B also! - pop edx ; DX=Window - mov ebx, 1 ; BH=Select window, BL=Window B - mov eax, 04f05h ; AX=Super VGA video memory window control - int 10h - pop ecx - pop ebx - pop edx - ret - -PUBLIC gr_vesa_incpage_ - -gr_vesa_incpage_: - push eax - xor eax, eax - mov al, LastPage - inc eax - call gr_vesa_setpage_ - pop eax - ret - -PUBLIC gr_vesa_setstart_ - -gr_vesa_setstart_: - - ; EAX = First column - ; EDX = First row - push ebx - push ecx - mov ecx, eax - mov eax, 4f07h - xor ebx, ebx - int 10h - pop ecx - pop ebx - ret - - -PUBLIC gr_vesa_setlogical_ - -gr_vesa_setlogical_: - - ; EAX = line width - push ebx - push ecx - push edx - - mov cx, ax - mov ax, 04f06h - mov bl, 0 - int 10h - and ebx, 0FFFFh - mov ax, cx - - pop edx - pop ecx - pop ebx - ret - - - -PUBLIC gr_vesa_scanline_ - -gr_vesa_scanline_: - - ; EAX = x1 - ; EDX = x2 - ; EBX = y - ; ECX = color - - push edi - cld - cmp edx, eax - jge @f - xchg edx, eax - -@@: mov edi, ebx - imul edi, _gr_var_bwidth - add edi, eax ; EDI = y*bpr+x1 - sub edx, eax ; ECX = x2-x1 - inc edx - - mov eax, edi - shr eax, 16 - - call gr_vesa_setpage_ - - and edi, 00FFFFh - or edi, 0A0000h - - ;mov eax, _Table8to32[ecx*4] - mov ch, cl - mov ax, cx - shl eax, 16 - mov ax, cx - - ; edx = width in bytes - ; edi = dest - mov bx, dx - add bx, di - jnc scanonepage - - sub dx, bx - movzx ecx, dx - - shr ecx, 1 - rep stosw - adc ecx, ecx - rep stosb - - movzx edx, bx - cmp edx, 0 - je scandone - - call gr_vesa_incpage_ - mov edi, 0A0000h - -scanonepage: - movzx ecx, dx - - shr ecx, 1 - rep stosw - adc ecx, ecx - rep stosb - -scandone: - - pop edi - ret - - -PUBLIC gr_vesa_set_logical_ - -gr_vesa_set_logical_: - - ; EAX = logical width in pixels - - push ebx - push ecx - - mov ecx, eax - mov eax, 04f06h - mov bl, 0 - int 10h - and ebx, 0ffffh - - movzx eax, cx - - pop ecx - pop ebx - - ret - - -PUBLIC gr_vesa_pixel_ - -gr_vesa_pixel_: - ; EAX = color (in AL) - ; EDX = offset from 0A0000 - push ebx - mov bl, al - - mov eax, edx - shr eax, 16 - and edx, 0ffffh - - call gr_vesa_setpage_ - mov [edx+0A0000h], bl - pop ebx - ret - -PUBLIC gr_vesa_bitblt_ - -gr_vesa_bitblt_: - - ; EAX = source_ptr - ; EDX = vesa_address - ; EBX = height - ; ECX = width - - push edi - push esi - - mov esi, eax ; Point ESI to source bitmap - - ; Set the initial page - mov eax, edx ; Move offset into SVGA into eax - shr eax, 16 ; Page = offset / 64K - call gr_vesa_setpage_ - - mov edi, edx ; EDI = offset into SVGA - and edi, 0FFFFh ; EDI = offset into 64K page - add edi, 0A0000h ; EDI = ptr to dest - - - mov edx, _gr_var_bwidth - sub edx, ecx ; EDX = amount to step each row - - - mov eax, ecx - -NextScanLine: - push eax - MyMovsd eax - pop eax - - dec ebx - jz DoneBlt - - add di, dx - jnc NextScanLine - - ; Need to increment page! - call gr_vesa_incpage_ - jmp NextScanLine - -DoneBlt: pop esi - pop edi - - ret - -PUBLIC gr_vesa_bitmap_ - -gr_vesa_bitmap_: - - ; EAX = Source bitmap (LINEAR) - ; EDX = Destination bitmap (SVGA) - ; EBX = x - ; ECX = y - - push esi - push edi - push ebp - push es - - push eax - mov eax, [edx].bm_data - imul ecx, _gr_var_bwidth - add eax, ecx - add eax, ebx - mov edi, eax ; EDI = offset into SVGA - shr eax, 16 - call gr_vesa_setpage_ - - mov ax, __A0000 - mov es, ax - pop eax - - mov esi, [eax].bm_data - and edi, 0ffffh - - movzx ecx, [eax].bm_h - -NextScanLine1: - push ecx - movzx ecx, [eax].bm_w - mov bx, cx - add bx, di - jnc OnePage - - sub cx,bx - mov ebp, ecx - MyMovsd ebp - and edi, 00ffffh ; IN CASE IT WENT OVER 64K - mov cx,bx - call gr_vesa_incpage_ - jcxz DoneWithLine -OnePage: - mov ebp, ecx - MyMovsd ebp - and edi, 00ffffh ; IN CASE IT WENT OVER 64K - -DoneWithLine: mov bx, [eax].bm_rowsize - sub bx, [eax].bm_w - and ebx, 0ffffh - add esi, ebx - mov bx, [edx].bm_rowsize - sub bx, [eax].bm_w - add di, bx - jnc NoPageInc - call gr_vesa_incpage_ -NoPageInc: pop ecx - dec ecx - jz @f - jmp NextScanLine1 - -@@: - - pop es - pop ebp - pop edi - pop esi - ret - - - - -PUBLIC gr_vesa_update_ - -gr_vesa_update_: - - ; EAX = Source bitmap (LINEAR) - ; EDX = Destination bitmap (SVGA) - ; EBX = Old source bitmap (LINEAR) - - push ecx - push esi - push edi - push ebp - push fs - - push eax - mov eax, [edx].bm_data - mov ebp, eax ; EDI = offset into SVGA - shr eax, 16 - call gr_vesa_setpage_ - - mov ax, __A0000 - mov fs, ax - pop eax - - mov esi, [eax].bm_data - and ebp, 0ffffh - - movzx ecx, [eax].bm_h - - mov edi, [ebx].bm_data - - movzx ebx, [eax].bm_rowsize - sub bx, [eax].bm_w - mov SourceInc, ebx - - movzx ebx, [edx].bm_rowsize - sub bx, [eax].bm_w - mov DestInc, bx - - movzx ebx, [eax].bm_w - mov RowWidth, ebx - -NextScanLine3: - push ecx - mov ecx, RowWidth - mov dx, cx - add dx, bp - jnc OnePage3 - - sub cx,dx - mov ebx, esi - -InnerLoop3: repe cmpsb - mov al, [esi-1] - sub esi, ebx - mov fs:[ebp+esi-1], al ; EDX = dest + size - bytes to end - add esi, ebx - cmp ecx, 0 - jne InnerLoop3 - - sub esi, ebx - add ebp, esi - add esi, ebx - and ebp, 00ffffh ; IN CASE IT WENT OVER 64K - - mov cx,dx - call gr_vesa_incpage_ - jcxz DoneWithLine3 -OnePage3: - mov ebx, esi - mov edx, ecx - and edx, 11b - shr ecx, 2 - -InnerLoop4: repe cmpsd - mov eax, [esi-4] - sub esi, ebx - mov fs:[ebp+esi-4], eax ; EDX = dest + size - bytes to end - add esi, ebx - cmp ecx, 0 - jne InnerLoop4 - - mov ecx, edx - jecxz EvenWidth -InnerLoop5: repe cmpsb - mov al, [esi-1] - sub esi, ebx - mov fs:[ebp+esi-1], al ; EDX = dest + size - bytes to end - add esi, ebx - cmp ecx, 0 - jne InnerLoop5 - -EvenWidth: sub esi, ebx - add ebp, esi - add esi, ebx - and ebp, 00ffffh ; IN CASE IT WENT OVER 64K - -DoneWithLine3: - add esi, SourceInc - add edi, SourceInc - add bp, DestInc - jnc NoPageInc3 - call gr_vesa_incpage_ -NoPageInc3: pop ecx - dec ecx - jnz NextScanLine3 - - pop fs - pop ebp - pop edi - pop esi - pop ecx - ret - - - - -_TEXT ENDS - - - END - - +; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. +.386 + +OPTION OLDSTRUCTS +INCLUDE VGAREGS.INC +INCLUDE GR.INC + +_DATA SEGMENT BYTE PUBLIC USE32 'DATA' + + PUBLIC __A0000 + __A0000 dw ? + + BufferPtr dd 0 + BufferSeg dw 0 + GoalMode dw ? + LastPage db 0FFh + + BPR dw ? + TempReg dd ? + + ; Information from VESA return SuperVGA Information + + VESAVersion dw ? + OEMStringPtr dd ? + Capabilities dd ? + VideoModePtr dd ? + TotalMemory dw ? + WinGranularity dw ? + WinSize dw ? + WinFuncPtr dd ? + PageSizeShift db ? + WinAttributes dw ? + + + VESA_Signature = 041534556h + +REALREGS STRUCT + RealEDI dd ? + RealESI dd ? + RealEBP dd ? + Reserved dd ? + RealEBX dd ? + RealEDX dd ? + RealECX dd ? + RealEAX dd ? + RealFlags dw ? + RealES dw ? + RealDS dw ? + RealFS dw ? + RealGS dw ? + RealIP dw ? + RealCS dw ? + RealSP dw ? + RealSS dw ? +REALREGS ENDS + + regs REALREGS < > + + vesa_error dd ? + SourceInc dd ? + DestInc dw ? + RowWidth dd ? + + extern _gr_var_color:dword, _gr_var_bwidth:dword + + +_DATA ENDS + +DGROUP GROUP _DATA + + +_TEXT SEGMENT BYTE PUBLIC USE32 'CODE' + + ASSUME DS:_DATA + ASSUME CS:_TEXT + +MyStosd MACRO Width:REQ +; Assumes: EDI = Dest Address +; Width = a 32-bit value, can't be ECX or EDI +; Trashes: ECX will be zero +; EDI = Dest Address + Width +; EDX = ???? +; Width +LOCAL Aligned + cmp Width, 16 + jbe Aligned + mov ecx, edi + and ecx, 3 + jcxz Aligned + neg ecx + add ecx, 4 + sub Width, ecx + rep stosb +Aligned: mov ecx, Width + shr ecx, 2 + rep stosd + mov ecx, Width + and ecx, 3 + rep stosb +ENDM + + +ENTER_PROC MACRO + push esi + push edi + push ebp + push eax + push ebx + push ecx + push edx +ENDM + +EXIT_PROC MACRO + + cmp [esp-4], edx + je @f + ; YOU TRASHED EDX !!!!!!! + int 3 +@@: pop edx + + cmp [esp-4], ecx + je @f + ; YOU TRASHED ECX !!!!!!! + int 3 +@@: pop ecx + + cmp [esp-4], ebx + je @f + ; YOU TRASHED EBX !!!!!!! + int 3 +@@: pop ebx + + cmp [esp-4], eax + je @f + ; YOU TRASHED EAX !!!!!!! + int 3 +@@: pop eax + + cmp [esp-4], ebp + je @f + ; YOU TRASHED EBP !!!!!!! + int 3 +@@: pop ebp + + cmp [esp-4], edi + je @f + ; YOU TRASHED EDI !!!!!!! + int 3 +@@: pop edi + + cmp [esp-4], esi + je @f + ; YOU TRASHED ESI !!!!!!! + int 3 +@@: pop esi + +ENDM + + +MyMovsd MACRO Width:REQ +; Assumes: EDI = Dest Address +; ESI = Source Address +; Width = a 32-bit value, can't be ECX or EDI or ESI +; Assumes that ESI is already aligned +; Trashes: ECX will be zero +; EDI = Dest Address + Width +; ESI = Source Address + Width +; EDX = ???? +LOCAL Aligned + cmp Width, 16 + jbe Aligned + mov ecx, edi + and ecx, 3 + jcxz Aligned + neg ecx + add ecx, 4 + sub Width, ecx + rep movsb +Aligned: mov ecx, Width + shr ecx, 2 + rep movsd + mov ecx, Width + and ecx, 3 + rep movsb +ENDM + + +EBXFarTo32: + push ecx + mov ecx, ebx + and ecx, 0FFFF0000h + shr ecx, 12 + and ebx, 0FFFFh + add ebx, ecx + pop ecx + ret + +PUBLIC gr_init_A0000_ + +gr_init_A0000_: + + push ebx + mov ax, 0002h + mov bx, 0a000h + int 31h + jc NoGo + mov __A0000, ax + pop ebx + xor eax, eax + ret +NoGo: pop ebx + mov eax, 1 + ret + +PUBLIC gr_vesa_checkmode_ + +gr_vesa_checkmode_: + pushad + + mov GoalMode, ax + cmp BufferSeg, 0 + jne GotDosMemory + + ; Allocate a 256 byte block of DOS memory using DPMI + mov ax, 0100h + mov bx, 16 + int 31h + jc NoMemory + + ; AX = real mode segment of allocated block + and eax, 0FFFFh + mov BufferSeg, ax + shl eax, 4 ; EAX = 32-bit pointer to DOS memory + mov BufferPtr, eax +GotDosMemory: + + + ; Get SuperVGA information + mov ax, BufferSeg + mov regs.RealEDI, 0 + mov regs.RealESI, 0 + mov regs.RealEBP, 0 + mov regs.Reserved, 0 + mov regs.RealEBX, 0 + mov regs.RealEDX, 0 + mov regs.RealECX, 0 + mov regs.RealEAX, 04f00h + mov regs.RealFlags, 0 + mov regs.RealES, ax + mov regs.RealDS, 0 + mov regs.RealFS, 0 + mov regs.RealGS, 0 + mov regs.RealIP, 0 + mov regs.RealCS, 0 + mov regs.RealSP, 0 + mov regs.RealSS, 0 + + mov bl, 10h + xor bh, bh + xor ecx, ecx + mov edi, offset regs + mov ax, 0300h + int 31h + + mov eax, regs.RealEAX + cmp ax, 04fh + jne NoVESADriver + + ; Make sure there is a VESA signature + mov eax, BufferPtr + cmp dword ptr[eax+0], VESA_Signature + jne NoVESADriver + + ; We now have a valid VESA driver loaded + + mov bx, word ptr [eax+4] + mov VESAVersion, bx + + mov ebx, dword ptr [eax+6] + call EBXFarTo32 + mov OEMStringPtr, ebx + + mov ebx, dword ptr [eax+10] + mov Capabilities, ebx + + mov bx, word ptr [eax+18] + mov TotalMemory, bx + + mov ebx, dword ptr [eax+14] + call EBXFarTo32 + mov VideoModePtr, ebx + +TryAnotherMode: + mov ax, word ptr [ebx] + add ebx, 2 + cmp ax, GoalMode + je ModeSupported + cmp ax, -1 + je ModeNotSupported + jmp TryAnotherMode + +ModeSupported: + + ; Get SuperVGA information + mov ax, BufferSeg + movzx ecx, GoalMode + mov regs.RealEDI, 0 + mov regs.RealESI, 0 + mov regs.RealEBP, 0 + mov regs.Reserved, 0 + mov regs.RealEBX, 0 + mov regs.RealEDX, 0 + mov regs.RealECX, ecx + mov regs.RealEAX, 04f01h + mov regs.RealFlags, 0 + mov regs.RealES, ax + mov regs.RealDS, 0 + mov regs.RealFS, 0 + mov regs.RealGS, 0 + mov regs.RealIP, 0 + mov regs.RealCS, 0 + mov regs.RealSP, 0 + mov regs.RealSS, 0 + + mov bl, 10h + xor bh, bh + xor cx, cx + mov edi, offset regs + mov ax, 0300h + int 31h + + mov eax, regs.RealEAX + cmp ax, 04fh + jne BadStatus + + ; Check if this mode supported by hardware. + mov eax, BufferPtr + mov bx, [eax] + bt bx, 0 + jnc HardwareNotSupported + + + mov bx, [eax+4] + cmp bx, 64 + jne @f + mov PageSizeShift, 0 + jmp GranularityOK +@@: cmp bx, 32 + jne @f + mov PageSizeShift, 1 + jmp GranularityOK +@@: cmp bx, 16 + jne @f + mov PageSizeShift, 2 + jmp GranularityOK +@@: cmp bx, 8 + jne @f + mov PageSizeShift, 3 + jmp GranularityOK +@@: cmp bx, 4 + jne @f + mov PageSizeShift, 4 + jmp GranularityOK +@@: cmp bx, 2 + jne @f + mov PageSizeShift, 5 + jmp GranularityOK +@@: cmp bx, 1 + jne WrongGranularity + mov PageSizeShift, 6 + +GranularityOK: + shl bx, 10 + mov WinGranularity, bx + + mov bx, [eax+6] + mov WinSize, bx + + mov ebx, [eax+12] + call EBXFarTo32 + mov WinFuncPtr, ebx + + mov bl, byte ptr [eax+2] + mov bh, byte ptr [eax+3] + mov word ptr WinAttributes, bx + + movzx ebx, word ptr [eax+16] + +NoError: + mov vesa_error, 0 + jmp Done + +WrongGranularity: + mov vesa_error, 2 + jmp Done + +HardwareNotSupported: + mov vesa_error, 3 + jmp Done + +ModeNotSupported: + mov vesa_error, 4 + jmp Done + +NoVESADriver: + mov vesa_error, 5 + jmp Done + +BadStatus: + mov vesa_error, 6 + jmp Done + +NoMemory: + mov vesa_error, 7 + jmp Done + +DPMIError: + mov vesa_error, 8 + +Done: popad + mov eax, vesa_error + + ret + +PUBLIC gr_get_dos_mem_ + +gr_get_dos_mem_: + + ; eax = how many bytes + + push ebx + + mov ebx, eax + shr ebx, 4 + mov eax, 0100h + int 31h + jc nomem + and eax, 0ffffh + shl eax, 4 + pop ebx + ret + +nomem: pop ebx + mov eax,0 + ret + + + + +PUBLIC gr_vesa_setmodea_ + +gr_vesa_setmodea_: + + ; eax = mode + pushad + mov LastPage,0ffh ;force page reset + mov ebx, eax + mov eax, 04f02h + int 10h + cmp ax, 04fh + jne BadStatus + jmp NoError + +PUBLIC gr_vesa_setpage_ + +gr_vesa_setpage_: + + ; EAX = 64K Page number + and eax, 0ffh + cmp al, LastPage + jne @f + ret +@@: mov LastPage, al + push edx + push ebx + push ecx + mov edx, eax + mov cl, PageSizeShift + shl edx, cl ; Convert from 64K pages to GranUnit pages. + push edx + xor ebx, ebx ; BH=Select window, BL=Window A + mov eax, 04f05h ; AX=Super VGA video memory window control + int 10h + + ; New code to fix those ATI Mach64's with separate + ; read/write pages. + mov bx, word ptr WinAttributes + and ebx, 0110b ; Set if PageA can read and write + cmp ebx, 0110b + jne WinACantReadAndWrite + pop edx + pop ecx + pop ebx + pop edx + ret + +WinACantReadAndWrite: ; Page A can't read and write, so we need to update page B also! + pop edx ; DX=Window + mov ebx, 1 ; BH=Select window, BL=Window B + mov eax, 04f05h ; AX=Super VGA video memory window control + int 10h + pop ecx + pop ebx + pop edx + ret + +PUBLIC gr_vesa_incpage_ + +gr_vesa_incpage_: + push eax + xor eax, eax + mov al, LastPage + inc eax + call gr_vesa_setpage_ + pop eax + ret + +PUBLIC gr_vesa_setstart_ + +gr_vesa_setstart_: + + ; EAX = First column + ; EDX = First row + push ebx + push ecx + mov ecx, eax + mov eax, 4f07h + xor ebx, ebx + int 10h + pop ecx + pop ebx + ret + + +PUBLIC gr_vesa_setlogical_ + +gr_vesa_setlogical_: + + ; EAX = line width + push ebx + push ecx + push edx + + mov cx, ax + mov ax, 04f06h + mov bl, 0 + int 10h + and ebx, 0FFFFh + mov ax, cx + + pop edx + pop ecx + pop ebx + ret + + + +PUBLIC gr_vesa_scanline_ + +gr_vesa_scanline_: + + ; EAX = x1 + ; EDX = x2 + ; EBX = y + ; ECX = color + + push edi + cld + cmp edx, eax + jge @f + xchg edx, eax + +@@: mov edi, ebx + imul edi, _gr_var_bwidth + add edi, eax ; EDI = y*bpr+x1 + sub edx, eax ; ECX = x2-x1 + inc edx + + mov eax, edi + shr eax, 16 + + call gr_vesa_setpage_ + + and edi, 00FFFFh + or edi, 0A0000h + + ;mov eax, _Table8to32[ecx*4] + mov ch, cl + mov ax, cx + shl eax, 16 + mov ax, cx + + ; edx = width in bytes + ; edi = dest + mov bx, dx + add bx, di + jnc scanonepage + + sub dx, bx + movzx ecx, dx + + shr ecx, 1 + rep stosw + adc ecx, ecx + rep stosb + + movzx edx, bx + cmp edx, 0 + je scandone + + call gr_vesa_incpage_ + mov edi, 0A0000h + +scanonepage: + movzx ecx, dx + + shr ecx, 1 + rep stosw + adc ecx, ecx + rep stosb + +scandone: + + pop edi + ret + + +PUBLIC gr_vesa_set_logical_ + +gr_vesa_set_logical_: + + ; EAX = logical width in pixels + + push ebx + push ecx + + mov ecx, eax + mov eax, 04f06h + mov bl, 0 + int 10h + and ebx, 0ffffh + + movzx eax, cx + + pop ecx + pop ebx + + ret + + +PUBLIC gr_vesa_pixel_ + +gr_vesa_pixel_: + ; EAX = color (in AL) + ; EDX = offset from 0A0000 + push ebx + mov bl, al + + mov eax, edx + shr eax, 16 + and edx, 0ffffh + + call gr_vesa_setpage_ + mov [edx+0A0000h], bl + pop ebx + ret + +PUBLIC gr_vesa_bitblt_ + +gr_vesa_bitblt_: + + ; EAX = source_ptr + ; EDX = vesa_address + ; EBX = height + ; ECX = width + + push edi + push esi + + mov esi, eax ; Point ESI to source bitmap + + ; Set the initial page + mov eax, edx ; Move offset into SVGA into eax + shr eax, 16 ; Page = offset / 64K + call gr_vesa_setpage_ + + mov edi, edx ; EDI = offset into SVGA + and edi, 0FFFFh ; EDI = offset into 64K page + add edi, 0A0000h ; EDI = ptr to dest + + + mov edx, _gr_var_bwidth + sub edx, ecx ; EDX = amount to step each row + + + mov eax, ecx + +NextScanLine: + push eax + MyMovsd eax + pop eax + + dec ebx + jz DoneBlt + + add di, dx + jnc NextScanLine + + ; Need to increment page! + call gr_vesa_incpage_ + jmp NextScanLine + +DoneBlt: pop esi + pop edi + + ret + +PUBLIC gr_vesa_bitmap_ + +gr_vesa_bitmap_: + + ; EAX = Source bitmap (LINEAR) + ; EDX = Destination bitmap (SVGA) + ; EBX = x + ; ECX = y + + push esi + push edi + push ebp + push es + + push eax + mov eax, [edx].bm_data + imul ecx, _gr_var_bwidth + add eax, ecx + add eax, ebx + mov edi, eax ; EDI = offset into SVGA + shr eax, 16 + call gr_vesa_setpage_ + + mov ax, __A0000 + mov es, ax + pop eax + + mov esi, [eax].bm_data + and edi, 0ffffh + + movzx ecx, [eax].bm_h + +NextScanLine1: + push ecx + movzx ecx, [eax].bm_w + mov bx, cx + add bx, di + jnc OnePage + + sub cx,bx + mov ebp, ecx + MyMovsd ebp + and edi, 00ffffh ; IN CASE IT WENT OVER 64K + mov cx,bx + call gr_vesa_incpage_ + jcxz DoneWithLine +OnePage: + mov ebp, ecx + MyMovsd ebp + and edi, 00ffffh ; IN CASE IT WENT OVER 64K + +DoneWithLine: mov bx, [eax].bm_rowsize + sub bx, [eax].bm_w + and ebx, 0ffffh + add esi, ebx + mov bx, [edx].bm_rowsize + sub bx, [eax].bm_w + add di, bx + jnc NoPageInc + call gr_vesa_incpage_ +NoPageInc: pop ecx + dec ecx + jz @f + jmp NextScanLine1 + +@@: + + pop es + pop ebp + pop edi + pop esi + ret + + + + +PUBLIC gr_vesa_update_ + +gr_vesa_update_: + + ; EAX = Source bitmap (LINEAR) + ; EDX = Destination bitmap (SVGA) + ; EBX = Old source bitmap (LINEAR) + + push ecx + push esi + push edi + push ebp + push fs + + push eax + mov eax, [edx].bm_data + mov ebp, eax ; EDI = offset into SVGA + shr eax, 16 + call gr_vesa_setpage_ + + mov ax, __A0000 + mov fs, ax + pop eax + + mov esi, [eax].bm_data + and ebp, 0ffffh + + movzx ecx, [eax].bm_h + + mov edi, [ebx].bm_data + + movzx ebx, [eax].bm_rowsize + sub bx, [eax].bm_w + mov SourceInc, ebx + + movzx ebx, [edx].bm_rowsize + sub bx, [eax].bm_w + mov DestInc, bx + + movzx ebx, [eax].bm_w + mov RowWidth, ebx + +NextScanLine3: + push ecx + mov ecx, RowWidth + mov dx, cx + add dx, bp + jnc OnePage3 + + sub cx,dx + mov ebx, esi + +InnerLoop3: repe cmpsb + mov al, [esi-1] + sub esi, ebx + mov fs:[ebp+esi-1], al ; EDX = dest + size - bytes to end + add esi, ebx + cmp ecx, 0 + jne InnerLoop3 + + sub esi, ebx + add ebp, esi + add esi, ebx + and ebp, 00ffffh ; IN CASE IT WENT OVER 64K + + mov cx,dx + call gr_vesa_incpage_ + jcxz DoneWithLine3 +OnePage3: + mov ebx, esi + mov edx, ecx + and edx, 11b + shr ecx, 2 + +InnerLoop4: repe cmpsd + mov eax, [esi-4] + sub esi, ebx + mov fs:[ebp+esi-4], eax ; EDX = dest + size - bytes to end + add esi, ebx + cmp ecx, 0 + jne InnerLoop4 + + mov ecx, edx + jecxz EvenWidth +InnerLoop5: repe cmpsb + mov al, [esi-1] + sub esi, ebx + mov fs:[ebp+esi-1], al ; EDX = dest + size - bytes to end + add esi, ebx + cmp ecx, 0 + jne InnerLoop5 + +EvenWidth: sub esi, ebx + add ebp, esi + add esi, ebx + and ebp, 00ffffh ; IN CASE IT WENT OVER 64K + +DoneWithLine3: + add esi, SourceInc + add edi, SourceInc + add bp, DestInc + jnc NoPageInc3 + call gr_vesa_incpage_ +NoPageInc3: pop ecx + dec ecx + jnz NextScanLine3 + + pop fs + pop ebp + pop edi + pop esi + pop ecx + ret + + + + +_TEXT ENDS + + + END + + diff --git a/unused/vga/vga.jas b/unused/vga/vga.jas index e75976ea..93a9c3f7 100644 --- a/unused/vga/vga.jas +++ b/unused/vga/vga.jas @@ -1,611 +1,611 @@ -/* - * $Source: /cvs/cvsroot/d2x/unused/vga/vga.jas,v $ - * $Revision: 1.1.1.1 $ - * $Author: bradleyb $ - * $Date: 2001-01-19 03:30:15 $ - * - * VGA library code - * - * $Log: not supported by cvs2svn $ - * Revision 1.14 1996/01/02 18:00:51 matt - * New parms for gr_init_screen - * - * Revision 1.13 1995/12/19 13:46:05 matt - * Use symbolic constant for special 3dmax mode - * - * Revision 1.12 1995/12/13 18:03:03 matt - * From JOHN: added code for special 3dbios mode - * - * Revision 1.11 1995/12/13 16:28:54 matt - * Use more legal way of checking screen mode - * - * Revision 1.10 1995/11/28 10:30:22 matt - * Added support for 1280x1024 - * - * Revision 1.9 1995/11/22 12:52:42 matt - * Changed numeric literals to symbolic constants - * - * Revision 1.8 1995/11/16 12:00:17 jed - * killed some prototype stuff - * - * Revision 1.7 1995/11/14 18:11:07 jed - * added code to support linear frame buffering - * - * Revision 1.6 1995/08/30 21:11:26 matt - * Added global containing current VGA mode - * - * Revision 1.5 1995/06/05 12:41:37 samir - * Moved gr_palette_clear from gr.c to vga.c - * - * Revision 1.4 1995/05/31 10:54:26 matt - * Added RCS header - * - * - * - */ - -#include -#include -#include -#include -#include -#include - -#include "types.h" -#include "mem.h" -#include "error.h" -#include "mono.h" - -// New for VGA Library. -#include "gr.h" -#include "vga.h" -#include "palette.h" -#include "grdef.h" -#include "fxvesa.h" - - -// Global Variables ----------------------------------------------------------- - -ubyte *vga_screen_addr = NULL; - -unsigned char * vga_video_memory = (unsigned char *)0xA0000; - -char vga_pal_default[768]; - -int vga_installed = 0; - -//extern int gr_palette_realized; -int vga_prevent_palette_loading = 0; - -ubyte * pVideoMode = (volatile ubyte *)0x449; -uword * pNumColumns = (volatile uword *)0x44a; -ubyte * pNumRows = (volatile ubyte *)0x484; -uword * pCharHeight = (volatile uword *)0x485; -uword * pCursorPos = (volatile uword *)0x450; -uword * pCursorType = (volatile uword *)0x460; -uword * pTextMemory = (volatile uword *)0xb8000; - -ubyte saved_video_mode = 0; -uword saved_num_columns = 0; -ubyte saved_num_rows = 0; -uword saved_char_height = 0; -uword saved_cursor_pos = 0; -uword saved_cursor_type = 0; -ubyte saved_is_graphics = 0; -uword * saved_video_memory = NULL; - -int cga_show_screen_info = 0; - - -// VGA Functions -------------------------------------------------------------- - -ubyte vga_get_screen_mode( void ) -{ - union REGS regs; - - regs.w.ax = 0x0f00; - int386( 0x10, ®s, ®s ); - return regs.w.ax & 0xff; -} - -void vga_set_cellheight( ubyte height ) -{ - ubyte temp; - - outp( 0x3d4, 9 ); - temp = inp( 0x3d5 ); - temp &= 0xE0; - temp |= height; - outp( 0x3d5, temp ); -} - -void vga_set_linear() -{ - outpw( 0x3c4, 0xE04 ); // enable chain4 mode - outpw( 0x3d4, 0x4014 ); // turn on dword mode - outpw( 0x3d4, 0xa317 ); // turn off byte mode -} - -void vga_16_to_256() -{ - outpw( 0x3ce, 0x4005 ); // set Shift reg to 1 - - inp( 0x3da ); // dummy input - - outp( 0x3c0, 0x30 ); - outp( 0x3c0, 0x61 ); // turns on PCS & PCC - - inp( 0x3da ); // dummy input - - outp( 0x3c0, 0x33 ); - outp( 0x3c0, 0 ); -} - -void vga_turn_screen_off() -{ - ubyte temp; - temp = inp( 0x3da ); - outp( 0x3c0, 0 ); -} - -void vga_turn_screen_on() -{ - ubyte temp; - temp = inp( 0x3da ); - outp( 0x3c0, 0x20 ); -} - -void vga_set_misc_mode( uword mode ) -{ - union REGS regs; - - regs.w.ax = mode; - int386( 0x10, ®s, ®s ); - -} - -void gr_set_3dbios_mode( uint mode ) -{ - union REGS regs; - memset( ®s, 0, sizeof(regs) ); - regs.w.ax = 0x4fd0; - regs.w.bx = 0x3d00 | (mode & 0xff); - int386( 0x10, ®s, ®s ); -} - - -void vga_set_text_25() -{ - union REGS regs; - - regs.w.ax = 3; - int386( 0x10, ®s, ®s ); - -} - -void vga_set_text_43() -{ - union REGS regs; - - regs.w.ax = 0x1201; - regs.w.bx = 0x30; - int386( 0x10, ®s, ®s ); - - regs.w.ax = 3; - int386( 0x10, ®s, ®s ); - - regs.w.ax = 0x1112; - regs.w.bx = 0x0; - int386( 0x10, ®s, ®s ); -} - -void vga_set_text_50() -{ - union REGS regs; - - regs.w.ax = 0x1202; - regs.w.bx = 0x30; - int386( 0x10, ®s, ®s ); - - regs.w.ax = 3; - int386( 0x10, ®s, ®s ); - - regs.w.ax = 0x1112; - regs.w.bx = 0x0; - int386( 0x10, ®s, ®s ); -} - -ubyte is_graphics_mode() -{ - byte tmp; - tmp = inp( 0x3DA ); // Reset flip-flip - outp( 0x3C0, 0x30 ); // Select attr register 10 - tmp = inp( 0x3C1 ); // Get graphics/text bit - return tmp & 1; -} - -int vga_save_mode() -{ - int i; - - saved_video_mode = vga_get_screen_mode(); - saved_num_columns = *pNumColumns; - saved_num_rows = *pNumRows+1; - saved_char_height = *pCharHeight; - saved_cursor_pos = *pCursorPos; - saved_cursor_type = *pCursorType; - saved_is_graphics = is_graphics_mode(); - - if (saved_is_graphics==0) - { - MALLOC(saved_video_memory,uword, saved_num_columns*saved_num_rows ); - - for (i=0; i < saved_num_columns*saved_num_rows; i++ ) - saved_video_memory[i] = pTextMemory[i]; - } - - if (cga_show_screen_info ) - { - printf( "Current video mode 0x%x:\n", saved_video_mode ); - if (saved_is_graphics) - printf( "Graphics mode\n" ); - else - printf( "Text mode\n" ); - - printf( "( %d columns by %d rows)\n", saved_num_columns, saved_num_rows ); - printf( "Char height is %d pixel rows\n", saved_char_height ); - printf( "Cursor of type 0x%x is at (%d, %d)\n", saved_cursor_type, saved_cursor_pos & 0xFF, saved_cursor_pos >> 8 ); - } - - return 0; -} - -int isvga() -{ - union REGS regs; - - regs.w.ax = 0x1a00; - int386( 0x10, ®s, ®s ); - - if ( regs.h.al != 0x1a ) return 0; - if ( (regs.h.bl==7) || (regs.h.bl==8)) return 1; - return 0; -} - -void vga_set_cursor_type( uword ctype ) -{ - union REGS regs; - - regs.w.ax = 0x0100; - regs.w.cx = ctype; - int386( 0x10, ®s, ®s ); -} - -void vga_enable_default_palette_loading() -{ - union REGS regs; - regs.w.ax = 0x1200; - regs.w.bx = 0x31; - int386( 0x10, ®s, ®s ); - vga_prevent_palette_loading = 0; -} - -void vga_disable_default_palette_loading() -{ - union REGS regs; - regs.w.ax = 0x1201; - regs.w.bx = 0x31; - int386( 0x10, ®s, ®s ); - vga_prevent_palette_loading = 1; -} - -void vga_set_cursor_position( uword position ) -{ - union REGS regs; - - regs.w.ax = 0x0200; - regs.w.bx = 0; - regs.w.dx = position; - int386( 0x10, ®s, ®s ); - -} - -void vga_restore_mode() -{ - int i; - - if ( saved_video_mode == 3 ) - { - switch( saved_num_rows ) - { - case 43: vga_set_text_43(); break; - case 50: vga_set_text_50(); break; - default: vga_set_text_25(); break; - } - } else { - vga_set_misc_mode(saved_video_mode); - } - - if (saved_is_graphics==0) - { - for (i=0; i < saved_num_columns*saved_num_rows; i++ ) - pTextMemory[i]=saved_video_memory[i]; - vga_set_cursor_type( saved_cursor_type ); - vga_set_cursor_position( saved_cursor_pos ); - } -} - -short vga_close() -{ - - if (vga_installed==1) - { - vga_installed = 0; - vga_restore_mode(); - if( saved_video_memory ) - free(saved_video_memory); - } - - return 0; -} - -int LinearSVGABuffer=0; - -int vga_vesa_setmode( short mode ) -{ - int retcode; - - if (VesaInit (mode)) // if there is an error with linear support - { - LinearSVGABuffer=1; - return(0); - } - - LinearSVGABuffer=0; - retcode=gr_vesa_checkmode( mode ); // do the old banking way - if ( retcode ) return retcode; - return gr_vesa_setmodea( mode ); -} - -int VGA_current_mode = SM_ORIGINAL; - -#define VIRGE -#ifdef VIRGE -extern int Virge_enabled; -#endif - -short vga_set_mode(short mode) -{ - int retcode; - unsigned int w,h,t,data, r; - - LinearSVGABuffer=0; - - if (!vga_installed) - return 1; - -#ifdef VIRGE - Virge_enabled = 0; -#endif - - switch(mode) - { - case SM_ORIGINAL: - return 0; - - case SM_320x200C: - if (!isvga()) return 1; - vga_set_misc_mode(0x13); - w = 320; r = 320; h = 200; t=BM_LINEAR; data = 0xA0000; - break; - - case SM_640x400V: - retcode = vga_vesa_setmode( 0x100 ); - //gr_enable_default_palette_loading(); - if (retcode !=0 ) return retcode; - w = 640; r = 640; h = 400; t=BM_SVGA; data = 0; - break; - - case SM_640x480V: - retcode = vga_vesa_setmode( 0x101 ); - //gr_enable_default_palette_loading(); - if (retcode !=0 ) return retcode; - w = 640; r = 640; h = 480; t=BM_SVGA; data = 0; - break; - - case SM_800x600V: - retcode = vga_vesa_setmode( 0x103 ); - //gr_enable_default_palette_loading(); - if (retcode !=0 ) return retcode; - w = 800; r = 800; h = 600; t=BM_SVGA; data = 0; - break; - - case SM_1024x768V: - retcode = vga_vesa_setmode( 0x105 ); - //gr_enable_default_palette_loading(); - if (retcode !=0 ) return retcode; - w = 1024; r = 1024; h = 768; t=BM_SVGA; data = 0; - break; - - case SM_1280x1024V: - retcode = vga_vesa_setmode( 0x107 ); - //gr_enable_default_palette_loading(); - if (retcode !=0 ) return retcode; - w = 1280; r = 1280; h = 1024; t=BM_SVGA; data = 0; - break; - - case SM_640x480V15: - retcode = vga_vesa_setmode( 0x110 ); - //gr_enable_default_palette_loading(); - if (retcode !=0 ) return retcode; - w = 640; r = 640*2; h=480; t=BM_SVGA15; data = 0; - break; - - case SM_800x600V15: - retcode = vga_vesa_setmode( 0x113 ); - //gr_enable_default_palette_loading(); - if (retcode !=0 ) return retcode; - w = 800; r = 800*2; h=600; t=BM_SVGA15; data = 0; - break; - - //super-special code for 3dmax high-res mode - case SM_320x400_3DMAX: // 3dmax 320x400 - if (!isvga()) return 1; - gr_set_3dbios_mode(0x31); - //w = 320; r = 320/4; h = 400; t=BM_MODEX; data = 0; - w = 320; r = 320; h = 400; t=BM_SVGA; data = 0; - break; - - //@@case 19: - //@@ if (!isvga()) return 1; - //@@ vga_set_misc_mode(0x13); - //@@ vga_set_cellheight( 3 ); - //@@ w = 320; r = 320; h = 200; t=BM_LINEAR; data = 0xA0000; - //@@ break; - //@@ - //@@case 20: - //@@ retcode = vga_vesa_setmode( 0x102 ); - //@@ //gr_enable_default_palette_loading(); - //@@ if (retcode !=0 ) return retcode; - //@@ vga_16_to_256(); - //@@ vga_set_linear(); - //@@ //gr_set_cellheight( 1 ); - //@@ gr_vesa_setlogical( 400 ); - //@@ w = 400; r = 400; h = 600; t=BM_SVGA; data = 0; - //@@ break; - //@@ - //@@case 21: - //@@ if (!isvga()) return 1; - //@@ vga_set_misc_mode(0xd); - //@@ vga_16_to_256(); - //@@ vga_set_linear(); - //@@ //gr_set_cellheight( 3 ); - //@@ w = 160; r = 160; h = 200; t=BM_LINEAR; data = 0xA0000; - //@@ break; - - case SM_320x200U: - case SM_320x240U: - case SM_360x200U: - case SM_360x240U: - case SM_376x282U: - case SM_320x400U: - case SM_320x480U: - case SM_360x400U: - case SM_360x480U: - case SM_360x360U: - case SM_376x308U: - case SM_376x564U: //mode X modes - - if (!isvga()) return 1; - w = gr_modex_setmode( mode ); - //gr_enable_default_palette_loading(); - h = w & 0xffff; w = w >> 16; r = w / 4;t = BM_MODEX; data = 0; - break; - - default: //unknown mode!!! Very bad!! - Error("Unknown mode %d in vga_set_mode()",mode); - } - -// if (vga_palette_realized && (vga_prevent_palette_loading==0)) -// gr_pal_setblock( 0, 256, gr_palette); - -// return 0; - - VGA_current_mode = mode; - if (LinearSVGABuffer) - { - mprintf ((0,"GREEEEAT!\n")); - t=BM_LINEAR; - vga_screen_addr=(ubyte *)VesaGetPtr(); - } - else - vga_screen_addr=(ubyte *)0xa0000; - - gr_palette_clear(); - return gr_init_screen( t,w,h,0,0,r,vga_screen_addr); -} - - -short vga_init() -{ - // Only do this function once! - if (vga_installed==1) - return 1; - - if (gr_init_A0000()) - return 10; - - vga_screen_addr = (ubyte *)0xa0000; //address in memory of screen - - // Save the current text screen mode - if (vga_save_mode()==1) - return 1; - -/* if (get_selector( &vga_fade_table, 256*GR_FADE_LEVELS, &vga_fade_table_selector )) - Error( "Error allocating fade table selector!" ); - - if (get_selector( &vga_palette, 256*3, &vga_palette_selector )) - Error( "Error allocating palette selector!" ); - - if (get_selector( &vga_inverse_table, 32*32*32, &vga_inverse_table_selector )) - Error( "Error allocating inverse table selector!" ); -*/ - - // Set flags indicating that this is installed. - gr_palette_clear(); - vga_installed = 1; - atexit(vga_close); - - return 0; -} - -short vga_mode13_checkmode() -{ - if (isvga()) - return 0; - else - return 1; -} - -// 0=Mode set OK -// 1=No VGA adapter installed -// 2=Program doesn't support this VESA granularity -// 3=Monitor doesn't support that VESA mode.: -// 4=Video card doesn't support that VESA mode. -// 5=No VESA driver found. -// 6=Bad Status after VESA call/ -// 7=Not enough DOS memory to call VESA functions. -// 8=Error using DPMI. -// 9=Error setting logical line width. -// 10=Error allocating selector for A0000h -// 11=Not a valid mode support by gr.lib - -short vga_check_mode(short mode) -{ - switch(mode) - { - case 19: - case SM_320x200C: - case SM_320x200U: - case SM_320x240U: - case SM_360x200U: - case SM_360x240U: - case SM_376x282U: - case SM_320x400U: - case SM_320x480U: - case SM_360x400U: - case SM_360x480U: - case SM_360x360U: - case SM_376x308U: - case SM_376x564U: return vga_mode13_checkmode(); - case SM_640x400V: return gr_vesa_checkmode( 0x100 ); - case SM_640x480V: return gr_vesa_checkmode( 0x101 ); - case SM_800x600V: return gr_vesa_checkmode( 0x103 ); - case SM_1024x768V: return vga_vesa_setmode( 0x105 ); - case SM_640x480V15: return vga_vesa_setmode( 0x110 ); - case SM_800x600V15: return vga_vesa_setmode( 0x113 ); - } - return 11; -} - +/* + * $Source: /cvs/cvsroot/d2x/unused/vga/vga.jas,v $ + * $Revision: 1.1.1.2 $ + * $Author: bradleyb $ + * $Date: 2001-01-19 03:33:51 $ + * + * VGA library code + * + * $Log: not supported by cvs2svn $ + * Revision 1.14 1996/01/02 18:00:51 matt + * New parms for gr_init_screen + * + * Revision 1.13 1995/12/19 13:46:05 matt + * Use symbolic constant for special 3dmax mode + * + * Revision 1.12 1995/12/13 18:03:03 matt + * From JOHN: added code for special 3dbios mode + * + * Revision 1.11 1995/12/13 16:28:54 matt + * Use more legal way of checking screen mode + * + * Revision 1.10 1995/11/28 10:30:22 matt + * Added support for 1280x1024 + * + * Revision 1.9 1995/11/22 12:52:42 matt + * Changed numeric literals to symbolic constants + * + * Revision 1.8 1995/11/16 12:00:17 jed + * killed some prototype stuff + * + * Revision 1.7 1995/11/14 18:11:07 jed + * added code to support linear frame buffering + * + * Revision 1.6 1995/08/30 21:11:26 matt + * Added global containing current VGA mode + * + * Revision 1.5 1995/06/05 12:41:37 samir + * Moved gr_palette_clear from gr.c to vga.c + * + * Revision 1.4 1995/05/31 10:54:26 matt + * Added RCS header + * + * + * + */ + +#include +#include +#include +#include +#include +#include + +#include "types.h" +#include "mem.h" +#include "error.h" +#include "mono.h" + +// New for VGA Library. +#include "gr.h" +#include "vga.h" +#include "palette.h" +#include "grdef.h" +#include "fxvesa.h" + + +// Global Variables ----------------------------------------------------------- + +ubyte *vga_screen_addr = NULL; + +unsigned char * vga_video_memory = (unsigned char *)0xA0000; + +char vga_pal_default[768]; + +int vga_installed = 0; + +//extern int gr_palette_realized; +int vga_prevent_palette_loading = 0; + +ubyte * pVideoMode = (volatile ubyte *)0x449; +uword * pNumColumns = (volatile uword *)0x44a; +ubyte * pNumRows = (volatile ubyte *)0x484; +uword * pCharHeight = (volatile uword *)0x485; +uword * pCursorPos = (volatile uword *)0x450; +uword * pCursorType = (volatile uword *)0x460; +uword * pTextMemory = (volatile uword *)0xb8000; + +ubyte saved_video_mode = 0; +uword saved_num_columns = 0; +ubyte saved_num_rows = 0; +uword saved_char_height = 0; +uword saved_cursor_pos = 0; +uword saved_cursor_type = 0; +ubyte saved_is_graphics = 0; +uword * saved_video_memory = NULL; + +int cga_show_screen_info = 0; + + +// VGA Functions -------------------------------------------------------------- + +ubyte vga_get_screen_mode( void ) +{ + union REGS regs; + + regs.w.ax = 0x0f00; + int386( 0x10, ®s, ®s ); + return regs.w.ax & 0xff; +} + +void vga_set_cellheight( ubyte height ) +{ + ubyte temp; + + outp( 0x3d4, 9 ); + temp = inp( 0x3d5 ); + temp &= 0xE0; + temp |= height; + outp( 0x3d5, temp ); +} + +void vga_set_linear() +{ + outpw( 0x3c4, 0xE04 ); // enable chain4 mode + outpw( 0x3d4, 0x4014 ); // turn on dword mode + outpw( 0x3d4, 0xa317 ); // turn off byte mode +} + +void vga_16_to_256() +{ + outpw( 0x3ce, 0x4005 ); // set Shift reg to 1 + + inp( 0x3da ); // dummy input + + outp( 0x3c0, 0x30 ); + outp( 0x3c0, 0x61 ); // turns on PCS & PCC + + inp( 0x3da ); // dummy input + + outp( 0x3c0, 0x33 ); + outp( 0x3c0, 0 ); +} + +void vga_turn_screen_off() +{ + ubyte temp; + temp = inp( 0x3da ); + outp( 0x3c0, 0 ); +} + +void vga_turn_screen_on() +{ + ubyte temp; + temp = inp( 0x3da ); + outp( 0x3c0, 0x20 ); +} + +void vga_set_misc_mode( uword mode ) +{ + union REGS regs; + + regs.w.ax = mode; + int386( 0x10, ®s, ®s ); + +} + +void gr_set_3dbios_mode( uint mode ) +{ + union REGS regs; + memset( ®s, 0, sizeof(regs) ); + regs.w.ax = 0x4fd0; + regs.w.bx = 0x3d00 | (mode & 0xff); + int386( 0x10, ®s, ®s ); +} + + +void vga_set_text_25() +{ + union REGS regs; + + regs.w.ax = 3; + int386( 0x10, ®s, ®s ); + +} + +void vga_set_text_43() +{ + union REGS regs; + + regs.w.ax = 0x1201; + regs.w.bx = 0x30; + int386( 0x10, ®s, ®s ); + + regs.w.ax = 3; + int386( 0x10, ®s, ®s ); + + regs.w.ax = 0x1112; + regs.w.bx = 0x0; + int386( 0x10, ®s, ®s ); +} + +void vga_set_text_50() +{ + union REGS regs; + + regs.w.ax = 0x1202; + regs.w.bx = 0x30; + int386( 0x10, ®s, ®s ); + + regs.w.ax = 3; + int386( 0x10, ®s, ®s ); + + regs.w.ax = 0x1112; + regs.w.bx = 0x0; + int386( 0x10, ®s, ®s ); +} + +ubyte is_graphics_mode() +{ + byte tmp; + tmp = inp( 0x3DA ); // Reset flip-flip + outp( 0x3C0, 0x30 ); // Select attr register 10 + tmp = inp( 0x3C1 ); // Get graphics/text bit + return tmp & 1; +} + +int vga_save_mode() +{ + int i; + + saved_video_mode = vga_get_screen_mode(); + saved_num_columns = *pNumColumns; + saved_num_rows = *pNumRows+1; + saved_char_height = *pCharHeight; + saved_cursor_pos = *pCursorPos; + saved_cursor_type = *pCursorType; + saved_is_graphics = is_graphics_mode(); + + if (saved_is_graphics==0) + { + MALLOC(saved_video_memory,uword, saved_num_columns*saved_num_rows ); + + for (i=0; i < saved_num_columns*saved_num_rows; i++ ) + saved_video_memory[i] = pTextMemory[i]; + } + + if (cga_show_screen_info ) + { + printf( "Current video mode 0x%x:\n", saved_video_mode ); + if (saved_is_graphics) + printf( "Graphics mode\n" ); + else + printf( "Text mode\n" ); + + printf( "( %d columns by %d rows)\n", saved_num_columns, saved_num_rows ); + printf( "Char height is %d pixel rows\n", saved_char_height ); + printf( "Cursor of type 0x%x is at (%d, %d)\n", saved_cursor_type, saved_cursor_pos & 0xFF, saved_cursor_pos >> 8 ); + } + + return 0; +} + +int isvga() +{ + union REGS regs; + + regs.w.ax = 0x1a00; + int386( 0x10, ®s, ®s ); + + if ( regs.h.al != 0x1a ) return 0; + if ( (regs.h.bl==7) || (regs.h.bl==8)) return 1; + return 0; +} + +void vga_set_cursor_type( uword ctype ) +{ + union REGS regs; + + regs.w.ax = 0x0100; + regs.w.cx = ctype; + int386( 0x10, ®s, ®s ); +} + +void vga_enable_default_palette_loading() +{ + union REGS regs; + regs.w.ax = 0x1200; + regs.w.bx = 0x31; + int386( 0x10, ®s, ®s ); + vga_prevent_palette_loading = 0; +} + +void vga_disable_default_palette_loading() +{ + union REGS regs; + regs.w.ax = 0x1201; + regs.w.bx = 0x31; + int386( 0x10, ®s, ®s ); + vga_prevent_palette_loading = 1; +} + +void vga_set_cursor_position( uword position ) +{ + union REGS regs; + + regs.w.ax = 0x0200; + regs.w.bx = 0; + regs.w.dx = position; + int386( 0x10, ®s, ®s ); + +} + +void vga_restore_mode() +{ + int i; + + if ( saved_video_mode == 3 ) + { + switch( saved_num_rows ) + { + case 43: vga_set_text_43(); break; + case 50: vga_set_text_50(); break; + default: vga_set_text_25(); break; + } + } else { + vga_set_misc_mode(saved_video_mode); + } + + if (saved_is_graphics==0) + { + for (i=0; i < saved_num_columns*saved_num_rows; i++ ) + pTextMemory[i]=saved_video_memory[i]; + vga_set_cursor_type( saved_cursor_type ); + vga_set_cursor_position( saved_cursor_pos ); + } +} + +short vga_close() +{ + + if (vga_installed==1) + { + vga_installed = 0; + vga_restore_mode(); + if( saved_video_memory ) + free(saved_video_memory); + } + + return 0; +} + +int LinearSVGABuffer=0; + +int vga_vesa_setmode( short mode ) +{ + int retcode; + + if (VesaInit (mode)) // if there is an error with linear support + { + LinearSVGABuffer=1; + return(0); + } + + LinearSVGABuffer=0; + retcode=gr_vesa_checkmode( mode ); // do the old banking way + if ( retcode ) return retcode; + return gr_vesa_setmodea( mode ); +} + +int VGA_current_mode = SM_ORIGINAL; + +#define VIRGE +#ifdef VIRGE +extern int Virge_enabled; +#endif + +short vga_set_mode(short mode) +{ + int retcode; + unsigned int w,h,t,data, r; + + LinearSVGABuffer=0; + + if (!vga_installed) + return 1; + +#ifdef VIRGE + Virge_enabled = 0; +#endif + + switch(mode) + { + case SM_ORIGINAL: + return 0; + + case SM_320x200C: + if (!isvga()) return 1; + vga_set_misc_mode(0x13); + w = 320; r = 320; h = 200; t=BM_LINEAR; data = 0xA0000; + break; + + case SM_640x400V: + retcode = vga_vesa_setmode( 0x100 ); + //gr_enable_default_palette_loading(); + if (retcode !=0 ) return retcode; + w = 640; r = 640; h = 400; t=BM_SVGA; data = 0; + break; + + case SM_640x480V: + retcode = vga_vesa_setmode( 0x101 ); + //gr_enable_default_palette_loading(); + if (retcode !=0 ) return retcode; + w = 640; r = 640; h = 480; t=BM_SVGA; data = 0; + break; + + case SM_800x600V: + retcode = vga_vesa_setmode( 0x103 ); + //gr_enable_default_palette_loading(); + if (retcode !=0 ) return retcode; + w = 800; r = 800; h = 600; t=BM_SVGA; data = 0; + break; + + case SM_1024x768V: + retcode = vga_vesa_setmode( 0x105 ); + //gr_enable_default_palette_loading(); + if (retcode !=0 ) return retcode; + w = 1024; r = 1024; h = 768; t=BM_SVGA; data = 0; + break; + + case SM_1280x1024V: + retcode = vga_vesa_setmode( 0x107 ); + //gr_enable_default_palette_loading(); + if (retcode !=0 ) return retcode; + w = 1280; r = 1280; h = 1024; t=BM_SVGA; data = 0; + break; + + case SM_640x480V15: + retcode = vga_vesa_setmode( 0x110 ); + //gr_enable_default_palette_loading(); + if (retcode !=0 ) return retcode; + w = 640; r = 640*2; h=480; t=BM_SVGA15; data = 0; + break; + + case SM_800x600V15: + retcode = vga_vesa_setmode( 0x113 ); + //gr_enable_default_palette_loading(); + if (retcode !=0 ) return retcode; + w = 800; r = 800*2; h=600; t=BM_SVGA15; data = 0; + break; + + //super-special code for 3dmax high-res mode + case SM_320x400_3DMAX: // 3dmax 320x400 + if (!isvga()) return 1; + gr_set_3dbios_mode(0x31); + //w = 320; r = 320/4; h = 400; t=BM_MODEX; data = 0; + w = 320; r = 320; h = 400; t=BM_SVGA; data = 0; + break; + + //@@case 19: + //@@ if (!isvga()) return 1; + //@@ vga_set_misc_mode(0x13); + //@@ vga_set_cellheight( 3 ); + //@@ w = 320; r = 320; h = 200; t=BM_LINEAR; data = 0xA0000; + //@@ break; + //@@ + //@@case 20: + //@@ retcode = vga_vesa_setmode( 0x102 ); + //@@ //gr_enable_default_palette_loading(); + //@@ if (retcode !=0 ) return retcode; + //@@ vga_16_to_256(); + //@@ vga_set_linear(); + //@@ //gr_set_cellheight( 1 ); + //@@ gr_vesa_setlogical( 400 ); + //@@ w = 400; r = 400; h = 600; t=BM_SVGA; data = 0; + //@@ break; + //@@ + //@@case 21: + //@@ if (!isvga()) return 1; + //@@ vga_set_misc_mode(0xd); + //@@ vga_16_to_256(); + //@@ vga_set_linear(); + //@@ //gr_set_cellheight( 3 ); + //@@ w = 160; r = 160; h = 200; t=BM_LINEAR; data = 0xA0000; + //@@ break; + + case SM_320x200U: + case SM_320x240U: + case SM_360x200U: + case SM_360x240U: + case SM_376x282U: + case SM_320x400U: + case SM_320x480U: + case SM_360x400U: + case SM_360x480U: + case SM_360x360U: + case SM_376x308U: + case SM_376x564U: //mode X modes + + if (!isvga()) return 1; + w = gr_modex_setmode( mode ); + //gr_enable_default_palette_loading(); + h = w & 0xffff; w = w >> 16; r = w / 4;t = BM_MODEX; data = 0; + break; + + default: //unknown mode!!! Very bad!! + Error("Unknown mode %d in vga_set_mode()",mode); + } + +// if (vga_palette_realized && (vga_prevent_palette_loading==0)) +// gr_pal_setblock( 0, 256, gr_palette); + +// return 0; + + VGA_current_mode = mode; + if (LinearSVGABuffer) + { + mprintf ((0,"GREEEEAT!\n")); + t=BM_LINEAR; + vga_screen_addr=(ubyte *)VesaGetPtr(); + } + else + vga_screen_addr=(ubyte *)0xa0000; + + gr_palette_clear(); + return gr_init_screen( t,w,h,0,0,r,vga_screen_addr); +} + + +short vga_init() +{ + // Only do this function once! + if (vga_installed==1) + return 1; + + if (gr_init_A0000()) + return 10; + + vga_screen_addr = (ubyte *)0xa0000; //address in memory of screen + + // Save the current text screen mode + if (vga_save_mode()==1) + return 1; + +/* if (get_selector( &vga_fade_table, 256*GR_FADE_LEVELS, &vga_fade_table_selector )) + Error( "Error allocating fade table selector!" ); + + if (get_selector( &vga_palette, 256*3, &vga_palette_selector )) + Error( "Error allocating palette selector!" ); + + if (get_selector( &vga_inverse_table, 32*32*32, &vga_inverse_table_selector )) + Error( "Error allocating inverse table selector!" ); +*/ + + // Set flags indicating that this is installed. + gr_palette_clear(); + vga_installed = 1; + atexit(vga_close); + + return 0; +} + +short vga_mode13_checkmode() +{ + if (isvga()) + return 0; + else + return 1; +} + +// 0=Mode set OK +// 1=No VGA adapter installed +// 2=Program doesn't support this VESA granularity +// 3=Monitor doesn't support that VESA mode.: +// 4=Video card doesn't support that VESA mode. +// 5=No VESA driver found. +// 6=Bad Status after VESA call/ +// 7=Not enough DOS memory to call VESA functions. +// 8=Error using DPMI. +// 9=Error setting logical line width. +// 10=Error allocating selector for A0000h +// 11=Not a valid mode support by gr.lib + +short vga_check_mode(short mode) +{ + switch(mode) + { + case 19: + case SM_320x200C: + case SM_320x200U: + case SM_320x240U: + case SM_360x200U: + case SM_360x240U: + case SM_376x282U: + case SM_320x400U: + case SM_320x480U: + case SM_360x400U: + case SM_360x480U: + case SM_360x360U: + case SM_376x308U: + case SM_376x564U: return vga_mode13_checkmode(); + case SM_640x400V: return gr_vesa_checkmode( 0x100 ); + case SM_640x480V: return gr_vesa_checkmode( 0x101 ); + case SM_800x600V: return gr_vesa_checkmode( 0x103 ); + case SM_1024x768V: return vga_vesa_setmode( 0x105 ); + case SM_640x480V15: return vga_vesa_setmode( 0x110 ); + case SM_800x600V15: return vga_vesa_setmode( 0x113 ); + } + return 11; +} +  \ No newline at end of file diff --git a/unused/vga/vgaregs.inc b/unused/vga/vgaregs.inc index b399d78c..ee799dde 100644 --- a/unused/vga/vgaregs.inc +++ b/unused/vga/vgaregs.inc @@ -1,42 +1,42 @@ -; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX -; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO -; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A -; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS -; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS -; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE -; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE -; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS -; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. -; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. - -MISC_OUTPUT = 03c2h ;Miscellaneous Output register -MAP_MASK = 02h ;index in SC of Map Mask register -READ_MAP = 04h ;index in GC of the Read Map register -BIT_MASK = 08h ;index in GC of Bit Mask register - -SC_INDEX = 3c4h ;Index register for sequencer ctrl. -SC_MAP_MASK = 2 ;Number of map mask register - -SC_INDEX = 3c4h ;Index register for sequencer ctrl. -SC_MAP_MASK = 2 ;Number of map mask register -SC_MEM_MODE = 4 ;Number of memory mode register - -GC_INDEX = 3ceh ;Index register for graphics ctrl. -GC_READ_MAP = 4 ;Number of read map register -GC_GRAPH_MODE = 5 ;Number of graphics mode register -GC_MISCELL = 6 ;Number of miscellaneous register - -CRTC_INDEX = 3d4h ;Index register for CRT controller -CC_MAX_SCAN = 9 ;Number of maximum scan line reg. -CC_START_HI = 0Ch ;Number of start address high register -CC_START_LO = 0Dh ;Number of start address low register -CC_UNDERLINE = 14h ;Number of underline register -CC_MODE_CTRL = 17h ;Number of mode control register -CRTC_OFFSET = 13h ; CRTC offset register index - -DAC_WRITE_ADR = 3C8h ;DAC write address -DAC_READ_ADR = 3C7h ;DAC read address -DAC_DATA = 3C9h ;DAC data register - -VERT_RESCAN = 3DAh ;Input status register #1 - +; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. + +MISC_OUTPUT = 03c2h ;Miscellaneous Output register +MAP_MASK = 02h ;index in SC of Map Mask register +READ_MAP = 04h ;index in GC of the Read Map register +BIT_MASK = 08h ;index in GC of Bit Mask register + +SC_INDEX = 3c4h ;Index register for sequencer ctrl. +SC_MAP_MASK = 2 ;Number of map mask register + +SC_INDEX = 3c4h ;Index register for sequencer ctrl. +SC_MAP_MASK = 2 ;Number of map mask register +SC_MEM_MODE = 4 ;Number of memory mode register + +GC_INDEX = 3ceh ;Index register for graphics ctrl. +GC_READ_MAP = 4 ;Number of read map register +GC_GRAPH_MODE = 5 ;Number of graphics mode register +GC_MISCELL = 6 ;Number of miscellaneous register + +CRTC_INDEX = 3d4h ;Index register for CRT controller +CC_MAX_SCAN = 9 ;Number of maximum scan line reg. +CC_START_HI = 0Ch ;Number of start address high register +CC_START_LO = 0Dh ;Number of start address low register +CC_UNDERLINE = 14h ;Number of underline register +CC_MODE_CTRL = 17h ;Number of mode control register +CRTC_OFFSET = 13h ; CRTC offset register index + +DAC_WRITE_ADR = 3C8h ;DAC write address +DAC_READ_ADR = 3C7h ;DAC read address +DAC_DATA = 3C9h ;DAC data register + +VERT_RESCAN = 3DAh ;Input status register #1 + diff --git a/unused/vga/xyz.bat b/unused/vga/xyz.bat index 128f275b..075b7d40 100644 --- a/unused/vga/xyz.bat +++ b/unused/vga/xyz.bat @@ -1,10 +1,10 @@ -if exist %1 goto done -if exist %1.tmp goto done -if not "%2" == "" rcsmerge -r%2 -r%3 %1.c -ren %1.c *.tmp -co %1.c -attrib -r %1.c -diff -b %1.c %1.tmp |more -b %1.c %1.tmp -diff -b %1.c %1.tmp |more -:done +if exist %1 goto done +if exist %1.tmp goto done +if not "%2" == "" rcsmerge -r%2 -r%3 %1.c +ren %1.c *.tmp +co %1.c +attrib -r %1.c +diff -b %1.c %1.tmp |more +b %1.c %1.tmp +diff -b %1.c %1.tmp |more +:done diff --git a/unused/win95/dd.bat b/unused/win95/dd.bat index 1a96ee78..9996353e 100644 --- a/unused/win95/dd.bat +++ b/unused/win95/dd.bat @@ -1 +1 @@ -rcsdiff %1 %2 %3 %4 %5 %6 %7 %8 %9 |more +rcsdiff %1 %2 %3 %4 %5 %6 %7 %8 %9 |more diff --git a/unused/win95/winckpit.asm b/unused/win95/winckpit.asm index f4fb9496..58f63720 100644 --- a/unused/win95/winckpit.asm +++ b/unused/win95/winckpit.asm @@ -1,128 +1,128 @@ -; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX -; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO -; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A -; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS -; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS -; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE -; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE -; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS -; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. -; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. - - -.386 - option oldstructs - - .nolist - include pstypes.inc - include psmacros.inc - .list - - assume cs:_TEXT, ds:_DATA - -_DATA segment dword public USE32 'DATA' - -rcsid db "$Id: winckpit.asm,v 1.1.1.1 2001-01-19 03:30:15 bradleyb Exp $" - align 4 - -_DATA ends - - - -_TEXT segment dword public USE32 'CODE' - -; gr_winckpit_blt_span -; blts a span region from source to dest buffer given a span -; list -; -; EBX = xmin -; ECX = xmax -; ESI = bm_data source at start of y -; EDI = bm_data dest - -PUBLIC gr_winckpit_blt_span -gr_winckpit_blt_span: - - push ebp - - inc ecx ; Better for counting and testing - -NewSpanBlt: - mov al, [esi+ebx] ; else blt odd pixel then check right - mov [edi+ebx], al - inc ebx - cmp ebx, ecx - jl NewSpanBlt - - pop ebp - ret - - - -; gr_winckpit_blt_span_long -; blts a span region from source to dest buffer given a span -; list -; This uses word optimization, and should be used for spans longer -; than 10 pixels, and can't be used for spans of 3 pixels or less. -; -; EBX = xmin -; ECX = xmax -; ESI = bm_data source at start of y -; EDI = bm_data dest - -PUBLIC gr_winckpit_blt_span_long -gr_winckpit_blt_span_long: - -; EDX = right word boundary - - push ebp - - inc ecx ; Better for counting and testing - mov edx, ecx ; Current right word boundary - - test ebx, 1 ; is left boundary odd? - jz TestRightBound ; if even check right boundary. - - mov al, [esi+ebx] ; else blt odd pixel then check right - mov [edi+ebx], al - inc ebx - -; Assured even left boundary and find right word boundary. - -TestRightBound: - test ecx, 1 ; if even, then we have an even bound - jz NewSpanBlt2_0 - dec edx ; if odd, force even boundary - jmp NewSpanBlt2_1 - - -; This is a word only blt. No odd pixels. - -NewSpanBlt2_0: - mov ax, [esi+ebx] - mov [edi+ebx], ax ; straight out blt. - add ebx, 2 - cmp ebx, edx ; do up to right word boundary - jl NewSpanBlt2_0 - jmp EndProc - - -; Blts word span and odd right byte is needed. - -NewSpanBlt2_1: - mov ax, [esi+ebx] - mov [edi+ebx], ax ; straight out blt. - add ebx, 2 - cmp ebx, edx ; do up to right word boundary - jl NewSpanBlt2_1 - mov al, [esi+ebx] ; blt right odd pixel. - mov [edi+ebx], al - -EndProc: - pop ebp - ret - -_TEXT ends - - end - +; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX +; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO +; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A +; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS +; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS +; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE +; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE +; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS +; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. +; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. + + +.386 + option oldstructs + + .nolist + include pstypes.inc + include psmacros.inc + .list + + assume cs:_TEXT, ds:_DATA + +_DATA segment dword public USE32 'DATA' + +rcsid db "$Id: winckpit.asm,v 1.1.1.2 2001-01-19 03:33:51 bradleyb Exp $" + align 4 + +_DATA ends + + + +_TEXT segment dword public USE32 'CODE' + +; gr_winckpit_blt_span +; blts a span region from source to dest buffer given a span +; list +; +; EBX = xmin +; ECX = xmax +; ESI = bm_data source at start of y +; EDI = bm_data dest + +PUBLIC gr_winckpit_blt_span +gr_winckpit_blt_span: + + push ebp + + inc ecx ; Better for counting and testing + +NewSpanBlt: + mov al, [esi+ebx] ; else blt odd pixel then check right + mov [edi+ebx], al + inc ebx + cmp ebx, ecx + jl NewSpanBlt + + pop ebp + ret + + + +; gr_winckpit_blt_span_long +; blts a span region from source to dest buffer given a span +; list +; This uses word optimization, and should be used for spans longer +; than 10 pixels, and can't be used for spans of 3 pixels or less. +; +; EBX = xmin +; ECX = xmax +; ESI = bm_data source at start of y +; EDI = bm_data dest + +PUBLIC gr_winckpit_blt_span_long +gr_winckpit_blt_span_long: + +; EDX = right word boundary + + push ebp + + inc ecx ; Better for counting and testing + mov edx, ecx ; Current right word boundary + + test ebx, 1 ; is left boundary odd? + jz TestRightBound ; if even check right boundary. + + mov al, [esi+ebx] ; else blt odd pixel then check right + mov [edi+ebx], al + inc ebx + +; Assured even left boundary and find right word boundary. + +TestRightBound: + test ecx, 1 ; if even, then we have an even bound + jz NewSpanBlt2_0 + dec edx ; if odd, force even boundary + jmp NewSpanBlt2_1 + + +; This is a word only blt. No odd pixels. + +NewSpanBlt2_0: + mov ax, [esi+ebx] + mov [edi+ebx], ax ; straight out blt. + add ebx, 2 + cmp ebx, edx ; do up to right word boundary + jl NewSpanBlt2_0 + jmp EndProc + + +; Blts word span and odd right byte is needed. + +NewSpanBlt2_1: + mov ax, [esi+ebx] + mov [edi+ebx], ax ; straight out blt. + add ebx, 2 + cmp ebx, edx ; do up to right word boundary + jl NewSpanBlt2_1 + mov al, [esi+ebx] ; blt right odd pixel. + mov [edi+ebx], al + +EndProc: + pop ebp + ret + +_TEXT ends + + end + diff --git a/video/Makefile.am b/video/Makefile.am index 99c6f93a..0cba3d18 100644 --- a/video/Makefile.am +++ b/video/Makefile.am @@ -1,4 +1,4 @@ noinst_LIBRARIES = libvideo.a INCLUDES = -I $(top_srcdir) -I$(top_srcdir)/includes -I$(top_srcdir)/main -I../input/ggi/include libvideo_a_SOURCES = ogl.c ogl_glx.c ogl_gr.c \ -sdl_gr.c +sdl_gr.c dos_gr.c diff --git a/video/Makefile.in b/video/Makefile.in index aacde06a..bcd2176f 100644 --- a/video/Makefile.in +++ b/video/Makefile.in @@ -70,7 +70,7 @@ VERSION = @VERSION@ noinst_LIBRARIES = libvideo.a INCLUDES = -I $(top_srcdir) -I$(top_srcdir)/includes -I$(top_srcdir)/main -I../input/ggi/include -libvideo_a_SOURCES = ogl.c ogl_glx.c ogl_gr.c sdl_gr.c +libvideo_a_SOURCES = ogl.c ogl_glx.c ogl_gr.c sdl_gr.c dos_gr.c mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../conf.h @@ -83,7 +83,7 @@ CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ libvideo_a_LIBADD = -libvideo_a_OBJECTS = ogl.o ogl_glx.o ogl_gr.o sdl_gr.o +libvideo_a_OBJECTS = ogl.o ogl_glx.o ogl_gr.o sdl_gr.o dos_gr.o AR = ar COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) @@ -95,7 +95,8 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP_ENV = --best -DEP_FILES = .deps/ogl.P .deps/ogl_glx.P .deps/ogl_gr.P .deps/sdl_gr.P +DEP_FILES = .deps/dos_gr.P .deps/ogl.P .deps/ogl_glx.P .deps/ogl_gr.P \ +.deps/sdl_gr.P SOURCES = $(libvideo_a_SOURCES) OBJECTS = $(libvideo_a_OBJECTS) diff --git a/video/dos_gr.c b/video/dos_gr.c new file mode 100644 index 00000000..1cffb330 --- /dev/null +++ b/video/dos_gr.c @@ -0,0 +1,728 @@ +// Graphics functions for DOS. + +#include +#ifdef __ENV_DJGPP__ + +#include +#include +#include +#include +#include +#include "gr.h" +#include "grdef.h" +#include "palette.h" +#include "maths.h" +#include "u_mem.h" +#include "u_dpmi.h" +#include "vesa.h" +#include "modex.h" +#include "error.h" + +#ifdef __DJGPP__ +#include +#endif + +static int last_r=0, last_g=0, last_b=0; + +/* old gr.c stuff */ +unsigned char * gr_video_memory = (unsigned char *)0xa0000; + +char gr_pal_default[768]; + +int gr_installed = 0; + +volatile ubyte * pVideoMode = (volatile ubyte *)0x449; +volatile ushort * pNumColumns = (volatile ushort *)0x44a; +volatile ubyte * pNumRows = (volatile ubyte *)0x484; +volatile ushort * pCharHeight = (volatile ushort *)0x485; +volatile ushort * pCursorPos = (volatile ushort *)0x450; +volatile ushort * pCursorType = (volatile ushort *)0x460; +volatile ushort * pTextMemory = (volatile ushort *)0xb8000; + +typedef struct screen_save { + ubyte video_mode; + ubyte is_graphics; + ushort char_height; + ubyte width; + ubyte height; + ubyte cursor_x, cursor_y; + ubyte cursor_sline, cursor_eline; + ushort * video_memory; +} screen_save; + +screen_save gr_saved_screen; + +int gr_show_screen_info = 0; +extern int VGA_current_mode; + +void gr_set_cellheight( ubyte height ) +{ + ubyte temp; + + outp( 0x3d4, 9 ); + temp = inp( 0x3d5 ); + temp &= 0xE0; + temp |= height; + outp( 0x3d5, temp ); +} + +void gr_set_linear() +{ + outpw( 0x3c4, 0xE04 ); // enable chain4 mode + outpw( 0x3d4, 0x4014 ); // turn on dword mode + outpw( 0x3d4, 0xa317 ); // turn off byte mode +} + +void gr_16_to_256() +{ + outpw( 0x3ce, 0x4005 ); // set Shift reg to 1 + + inp( 0x3da ); // dummy input + + outp( 0x3c0, 0x30 ); + outp( 0x3c0, 0x61 ); // turns on PCS & PCC + + inp( 0x3da ); // dummy input + + outp( 0x3c0, 0x33 ); + outp( 0x3c0, 0 ); +} + +void gr_turn_screen_off() +{ + ubyte temp; + temp = inp( 0x3da ); + outp( 0x3c0, 0 ); +} + +void gr_turn_screen_on() +{ + ubyte temp; + temp = inp( 0x3da ); + outp( 0x3c0, 0x20 ); +} + +void gr_set_misc_mode( uint mode ) +{ + union REGS regs; + + memset( ®s, 0, sizeof(regs) ); + regs.w.ax = mode; + int386( 0x10, ®s, ®s ); + +} + +void gr_set_3dbios_mode( uint mode ) +{ + union REGS regs; + memset( ®s, 0, sizeof(regs) ); + regs.w.ax = 0x4fd0; + regs.w.bx = 0x3d00 | (mode & 0xff); + int386( 0x10, ®s, ®s ); +} + + + +void gr_set_text_25() +{ + union REGS regs; + + regs.w.ax = 3; + int386( 0x10, ®s, ®s ); + +} + +void gr_set_text_43() +{ + union REGS regs; + + regs.w.ax = 0x1201; + regs.w.bx = 0x30; + int386( 0x10, ®s, ®s ); + + regs.w.ax = 3; + int386( 0x10, ®s, ®s ); + + regs.w.ax = 0x1112; + regs.w.bx = 0x0; + int386( 0x10, ®s, ®s ); +} + +void gr_set_text_50() +{ + union REGS regs; + + regs.w.ax = 0x1202; + regs.w.bx = 0x30; + int386( 0x10, ®s, ®s ); + + regs.w.ax = 3; + int386( 0x10, ®s, ®s ); + + regs.w.ax = 0x1112; + regs.w.bx = 0x0; + int386( 0x10, ®s, ®s ); +} + +ubyte is_graphics_mode() +{ + byte tmp; + tmp = inp( 0x3DA ); // Reset flip-flip + outp( 0x3C0, 0x30 ); // Select attr register 10 + tmp = inp( 0x3C1 ); // Get graphics/text bit + return tmp & 1; +} + +void gr_setcursor(ubyte x, ubyte y, ubyte sline, ubyte eline) +{ + union REGS regs; + + memset( ®s, 0, sizeof(regs) ); + regs.w.ax = 0x0200; + regs.w.bx = 0; + regs.h.dh = y; + regs.h.dl = x; + int386( 0x10, ®s, ®s ); + + memset( ®s, 0, sizeof(regs) ); + regs.w.ax = 0x0100; + regs.h.ch = sline & 0xf; + regs.h.cl = eline & 0xf; + int386( 0x10, ®s, ®s ); +} + +void gr_getcursor(ubyte *x, ubyte *y, ubyte * sline, ubyte * eline) +{ + union REGS regs; + + memset( ®s, 0, sizeof(regs) ); + regs.w.ax = 0x0300; + regs.w.bx = 0; + int386( 0x10, ®s, ®s ); + *y = regs.h.dh; + *x = regs.h.dl; + *sline = regs.h.ch; + *eline = regs.h.cl; +} + + +int gr_save_mode() +{ + int i; + + gr_saved_screen.is_graphics = is_graphics_mode(); + gr_saved_screen.video_mode = *pVideoMode; + + if (!gr_saved_screen.is_graphics) { + gr_saved_screen.width = *pNumColumns; + gr_saved_screen.height = *pNumRows+1; + gr_saved_screen.char_height = *pCharHeight; + gr_getcursor(&gr_saved_screen.cursor_x, &gr_saved_screen.cursor_y, &gr_saved_screen.cursor_sline, &gr_saved_screen.cursor_eline ); + MALLOC(gr_saved_screen.video_memory,ushort, gr_saved_screen.width*gr_saved_screen.height ); + for (i=0; i < gr_saved_screen.width*gr_saved_screen.height; i++ ) + gr_saved_screen.video_memory[i] = pTextMemory[i]; + } + + if (gr_show_screen_info ) { + printf( "Current video mode 0x%x:\n", gr_saved_screen.video_mode ); + if (gr_saved_screen.is_graphics) + printf( "Graphics mode\n" ); + else { + printf( "Text mode\n" ); + printf( "( %d columns by %d rows)\n", gr_saved_screen.width, gr_saved_screen.height ); + printf( "Char height is %d pixel rows\n", gr_saved_screen.char_height ); + printf( "Cursor of type 0x%x,0x%x is at (%d, %d)\n", gr_saved_screen.cursor_sline, gr_saved_screen.cursor_eline,gr_saved_screen.cursor_x, gr_saved_screen.cursor_y ); + } + } + + return 0; +} + +int isvga() +{ + union REGS regs; + + memset( ®s, 0, sizeof(regs) ); + regs.w.ax = 0x1a00; + int386( 0x10, ®s, ®s ); + + if ( regs.h.al == 0x1a ) + return 1; + + return 0; +} + +void gr_restore_mode() +{ + int i; + + //gr_set_text_25(); + +#ifndef NOGRAPH + gr_palette_fade_out( gr_palette, 32, 0 ); + gr_palette_set_gamma(0); + if ( gr_saved_screen.video_mode == 3 ) { + switch( gr_saved_screen.height ) { + case 43: gr_set_text_43(); break; + case 50: gr_set_text_50(); break; + default: gr_set_text_25(); break; + } + } else { + gr_set_misc_mode(gr_saved_screen.video_mode); + } + if (gr_saved_screen.is_graphics==0) { + gr_sync_display(); + gr_sync_display(); + gr_palette_read( gr_pal_default ); + gr_palette_clear(); + for (i=0; i < gr_saved_screen.width*gr_saved_screen.height; i++ ) + pTextMemory[i]=gr_saved_screen.video_memory[i]; + gr_setcursor( gr_saved_screen.cursor_x, gr_saved_screen.cursor_y, gr_saved_screen.cursor_sline, gr_saved_screen.cursor_eline ); + gr_palette_faded_out = 1; + gr_palette_fade_in( gr_pal_default, 32, 0 ); + } +#endif + +} + +void gr_close() +{ + if (gr_installed==1) + { + gr_installed = 0; + gr_restore_mode(); + free(grd_curscreen); + if( gr_saved_screen.video_memory ) { + free(gr_saved_screen.video_memory); + gr_saved_screen.video_memory = NULL; + } + } +} + +#ifndef __DJGPP__ +int gr_vesa_setmode( int mode ) +{ + int retcode; + + retcode=gr_vesa_checkmode( mode ); + if ( retcode ) return retcode; + + return gr_vesa_setmodea( mode ); +} +#endif + + +int gr_set_mode(u_int32_t mode) +{ + int retcode; + unsigned int w,h,t,data, r; + + //JOHNgr_disable_default_palette_loading(); +#ifdef NOGRAPH +return 0; +#endif + switch(mode) + { + case SM_ORIGINAL: + return 0; + case SM(320,200)://0: + if (!isvga()) return 1; + gr_set_misc_mode(0x13); + w = 320; r = 320; h = 200; t=BM_LINEAR; data = (int)gr_video_memory; + break; + case SM(640,400)://SM_640x400V: + retcode = gr_vesa_setmode( 0x100 ); + if (retcode !=0 ) return retcode; + w = 640; r = 640; h = 400; t=BM_SVGA; data = 0; + break; + case SM(640,480)://SM_640x480V: + retcode = gr_vesa_setmode( 0x101 ); + if (retcode !=0 ) return retcode; + w = 640; r = 640; h = 480; t=BM_SVGA; data = 0; + break; + case SM(800,600)://SM_800x600V: + retcode = gr_vesa_setmode( 0x103 ); + if (retcode !=0 ) return retcode; + w = 800; r = 800; h = 600; t=BM_SVGA; data = 0; + break; + case SM(1024,768)://SM_1024x768V: + retcode = gr_vesa_setmode( 0x105 ); + if (retcode !=0 ) return retcode; + w = 1024; r = 1024; h = 768; t=BM_SVGA; data = 0; + break; +/* case SM_640x480V15: + retcode = gr_vesa_setmode( 0x110 ); + if (retcode !=0 ) return retcode; + w = 640; r = 640*2; h=480; t=BM_SVGA15; data = 0; + break; + case SM_800x600V15: + retcode = gr_vesa_setmode( 0x113 ); + if (retcode !=0 ) return retcode; + w = 800; r = 800*2; h=600; t=BM_SVGA15; data = 0; + break;*/ +// case 19: + case SM(320,100): + if (!isvga()) return 1; + gr_set_misc_mode(0x13); +// { +// ubyte x; +// x = inp( 0x3c5 ); +// x |= 8; +// outp( 0x3c5, x ); +// } + gr_set_cellheight( 3 ); + + w = 320; r = 320; h = 100; t=BM_LINEAR; data = (int)gr_video_memory; + break; +/* case 20: + retcode = gr_vesa_setmode( 0x102 ); + //gr_enable_default_palette_loading(); + if (retcode !=0 ) return retcode; + gr_16_to_256(); + gr_set_linear(); + //gr_set_cellheight( 1 ); + gr_vesa_setlogical( 400 ); + w = 400; r = 400; h = 600; t=BM_SVGA; data = 0; + break; + case 21: + if (!isvga()) return 1; + gr_set_misc_mode(0xd); + gr_16_to_256(); + gr_set_linear(); + gr_set_cellheight( 3 ); + w = 160; r = 160; h = 100; t=BM_LINEAR; data = (int)gr_video_memory; + break; + case //22: // 3dmax 320x400 + if (!isvga()) return 1; + gr_set_3dbios_mode(0x31); + //w = 320; r = 320/4; h = 400; t=BM_MODEX; data = 0; + w = 320; r = 320; h = 400; t=BM_SVGA; data = 0; + break;*/ + default: + if (!isvga()) return 1; + if (mode==SM(320,240)) + w = gr_modex_setmode( 2 ); + else if (mode==SM(320,400)) + w = gr_modex_setmode( 6 ); + else + Error("unhandled vid mode\n"); + //gr_enable_default_palette_loading(); + h = w & 0xffff; w = w >> 16; r = w / 4;t = BM_MODEX; data = 0; + break; + } + gr_palette_clear(); + + memset( grd_curscreen, 0, sizeof(grs_screen)); + grd_curscreen->sc_mode = mode; + grd_curscreen->sc_w = w; + grd_curscreen->sc_h = h; + grd_curscreen->sc_aspect = fixdiv(grd_curscreen->sc_w*3,grd_curscreen->sc_h*4); + grd_curscreen->sc_canvas.cv_bitmap.bm_x = 0; + grd_curscreen->sc_canvas.cv_bitmap.bm_y = 0; + grd_curscreen->sc_canvas.cv_bitmap.bm_w = w; + grd_curscreen->sc_canvas.cv_bitmap.bm_h = h; + grd_curscreen->sc_canvas.cv_bitmap.bm_rowsize = r; + grd_curscreen->sc_canvas.cv_bitmap.bm_type = t; + grd_curscreen->sc_canvas.cv_bitmap.bm_data = (unsigned char *)data; + VGA_current_mode = mode; + gr_set_current_canvas(NULL); + + //gr_enable_default_palette_loading(); +// gamefont_choose_game_font(w,h); + + return 0; +} + +int gr_init(void) +{ + int org_gamma; + int retcode; + int mode = SM(320,200); + + // Only do this function once! + if (gr_installed==1) + return 3; + +#ifdef __DJGPP__ + if (!__djgpp_nearptr_enable()) { + printf("nearptr enable=%x\n", __dpmi_error); + return 10; + } +#ifndef SAVEGR + gr_video_memory = (unsigned char *)(__djgpp_conventional_base + 0xa0000); +#else + gr_video_memory=(unsigned char *)-1; +#endif + pVideoMode = (volatile ubyte *)(__djgpp_conventional_base+0x449); + pNumColumns = (volatile ushort *)(__djgpp_conventional_base+0x44a); + pNumRows = (volatile ubyte *)(__djgpp_conventional_base+0x484); + pCharHeight = (volatile ushort *)(__djgpp_conventional_base+0x485); + pCursorPos = (volatile ushort *)(__djgpp_conventional_base+0x450); + pCursorType = (volatile ushort *)(__djgpp_conventional_base+0x460); + pTextMemory = (volatile ushort *)(__djgpp_conventional_base+0xb8000); +#endif +#ifndef __DJGPP__ + if (gr_init_A0000()) + return 10; +#endif + + // Save the current text screen mode + if (gr_save_mode()==1) + return 2; + +#ifndef NOGRAPH + // Save the current palette, and fade it out to black. + gr_palette_read( gr_pal_default ); + gr_palette_faded_out = 0; + org_gamma = gr_palette_get_gamma(); + gr_palette_set_gamma( 0 ); + gr_palette_fade_out( gr_pal_default, 32, 0 ); + gr_palette_clear(); + gr_palette_set_gamma( org_gamma ); + gr_sync_display(); + gr_sync_display(); +#endif + +#ifdef __DJGPP__ +#ifdef SAVEGR + __djgpp_nearptr_disable(); +#endif +#endif + + MALLOC( grd_curscreen,grs_screen,1 ); + memset( grd_curscreen, 0, sizeof(grs_screen)); + + // Set the mode. + if ((retcode=gr_set_mode(mode))) + { + gr_restore_mode(); + return retcode; + } + //JOHNgr_disable_default_palette_loading(); + + // Set all the screen, canvas, and bitmap variables that + // aren't set by the gr_set_mode call: + grd_curscreen->sc_canvas.cv_color = 0; + grd_curscreen->sc_canvas.cv_drawmode = 0; + grd_curscreen->sc_canvas.cv_font = NULL; + grd_curscreen->sc_canvas.cv_font_fg_color = 0; + grd_curscreen->sc_canvas.cv_font_bg_color = 0; + gr_set_current_canvas( &grd_curscreen->sc_canvas ); + +#if 0 + if (!dpmi_allocate_selector( &gr_fade_table, 256*GR_FADE_LEVELS, &gr_fade_table_selector )) + Error( "Error allocating fade table selector!" ); + + if (!dpmi_allocate_selector( &gr_palette, 256*3, &gr_palette_selector )) + Error( "Error allocating palette selector!" ); +#endif + +// if (!dpmi_allocate_selector( &gr_inverse_table, 32*32*32, &gr_inverse_table_selector )) +// Error( "Error allocating inverse table selector!" ); + + + // Set flags indicating that this is installed. + gr_installed = 1; +#ifdef __GNUC__ + + atexit((void (*)) gr_close); +#else + atexit(gr_close); +#endif + return 0; +} + +int gr_mode13_checkmode() +{ + if (isvga()) + return 0; + else + return 1; +} + +// 0=Mode set OK +// 1=No VGA adapter installed +// 2=Program doesn't support this VESA granularity +// 3=Monitor doesn't support that VESA mode.: +// 4=Video card doesn't support that VESA mode. +// 5=No VESA driver found. +// 6=Bad Status after VESA call/ +// 7=Not enough DOS memory to call VESA functions. +// 8=Error using DPMI. +// 9=Error setting logical line width. +// 10=Error allocating selector for A0000h +// 11=Not a valid mode support by gr.lib + +int gr_check_mode(u_int32_t mode) +{ + switch(mode) + { + case SM(320,100)://19: + case SM(320,200): + case SM(320,240): + case SM(360,200): + case SM(360,240): + case SM(376,282): + case SM(320,400): + case SM(320,480): + case SM(360,400): + case SM(360,480): + case SM(360,360): + case SM(376,308): + case SM(376,564): return gr_mode13_checkmode(); + case SM(640,400): return gr_vesa_checkmode( 0x100 ); + case SM(640,480): return gr_vesa_checkmode( 0x101 ); + case SM(800,600): return gr_vesa_checkmode( 0x103 ); + case SM(1024,768): return gr_vesa_setmode( 0x105 ); +// case SM_640x480V15: return gr_vesa_setmode( 0x110 ); +// case SM_800x600V15: return gr_vesa_setmode( 0x113 ); + } + return 11; +} + +/* Palette Stuff Starts Here... */ + +void gr_palette_step_up( int r, int g, int b ) +{ + int i; + ubyte *p; + int temp; + + if (gr_palette_faded_out) return; + + if ( (r==last_r) && (g==last_g) && (b==last_b) ) return; + + last_r = r; last_g = g; last_b = b; + + outp( 0x3c6, 0xff ); + outp( 0x3c8, 0 ); + p=gr_palette; + + for (i=0; i<256; i++ ) { + temp = (int)(*p++) + r + gr_palette_gamma; + if (temp<0) temp=0; + else if (temp>63) temp=63; + outp( 0x3c9, temp ); + temp = (int)(*p++) + g + gr_palette_gamma; + if (temp<0) temp=0; + else if (temp>63) temp=63; + outp( 0x3c9, temp ); + temp = (int)(*p++) + b + gr_palette_gamma; + if (temp<0) temp=0; + else if (temp>63) temp=63; + outp( 0x3c9, temp ); + } +} + + +void gr_palette_clear() +{ + int i; + outp( 0x3c6, 0xff ); + outp( 0x3c8, 0 ); + for (i=0; i<768; i++ ) { + outp( 0x3c9, 0 ); + } + gr_palette_faded_out = 1; +} + +void gr_palette_load( ubyte * pal ) +{ + int i; + ubyte c; + outp( 0x3c6, 0xff ); + outp( 0x3c8, 0 ); + for (i=0; i<768; i++ ) { + c = pal[i] + gr_palette_gamma; + if ( c > 63 ) c = 63; + outp( 0x3c9,c); + gr_current_pal[i] = pal[i]; + } + gr_palette_faded_out = 0; + + init_computed_colors(); +} + + +int gr_palette_fade_out(ubyte *pal, int nsteps, int allow_keys ) +{ + ubyte c; + int i,j; + fix fade_palette[768]; + fix fade_palette_delta[768]; + + if (gr_palette_faded_out) return 0; + + if (!pal) + pal = gr_current_pal; + + for (i=0; i<768; i++ ) { + fade_palette[i] = i2f(pal[i]+gr_palette_gamma); + fade_palette_delta[i] = fade_palette[i] / nsteps; + } + + for (j=0; j 63 ) c = 63; + outp( 0x3c9, c ); + } + } + gr_palette_faded_out = 1; + return 0; +} + +int gr_palette_fade_in(ubyte *pal, int nsteps, int allow_keys) +{ + int i,j; + ubyte c; + fix fade_palette[768]; + fix fade_palette_delta[768]; + + + if (!gr_palette_faded_out) return 0; + + for (i=0; i<768; i++ ) { + gr_current_pal[i] = pal[i]; + fade_palette[i] = 0; + fade_palette_delta[i] = i2f(pal[i]+gr_palette_gamma) / nsteps; + } + + for (j=0; j i2f(pal[i]+gr_palette_gamma) ) + fade_palette[i] = i2f(pal[i]+gr_palette_gamma); + c = f2i(fade_palette[i]); + if ( c > 63 ) c = 63; + outp( 0x3c9, c ); + } + } + gr_palette_faded_out = 0; + return 0; +} + +void gr_palette_read(ubyte * palette) +{ + int i; + outp( 0x3c6, 0xff ); + outp( 0x3c7, 0 ); + for (i=0; i<768; i++ ) { + *palette++ = inp( 0x3c9 ); + } +} + +void gr_update(void) +{ } + + +#endif // __ENV_DJGPP__ -- 2.39.2