This commit was generated by cvs2svn to compensate for changes in r5,
authorBradley Bell <btb@icculus.org>
Fri, 19 Jan 2001 03:34:09 +0000 (03:34 +0000)
committerBradley Bell <btb@icculus.org>
Fri, 19 Jan 2001 03:34:09 +0000 (03:34 +0000)
which included commits to RCS files with non-trunk default branches.

147 files changed:
2d/2dsline.c
2d/bitblt.c
2d/box.c
2d/canvas.c
2d/diff
2d/gpixel.c
2d/line.c
2d/linear.h
2d/pixel.c
README
arch/Makefile.am
arch/Makefile.in
arch/dos/Makefile.am [new file with mode: 0644]
arch/dos/Makefile.in [new file with mode: 0644]
arch/dos/cdrom.c [new file with mode: 0644]
arch/dos/digi.c [new file with mode: 0644]
arch/dos/disk.c
arch/dos/dosgr.c
arch/dos/dpmi.c
arch/dos/findfile.c [new file with mode: 0644]
arch/dos/include/joy.h
arch/dos/include/key.h
arch/dos/include/mouse.h
arch/dos/init.c
arch/dos/joyc.c
arch/dos/joydefs.c
arch/dos/key.c
arch/dos/mouse.c
arch/dos/vesa.c
arch/dos_dpmi.c [new file with mode: 0644]
arch/dos_findfile.c [new file with mode: 0644]
arch/dos_init.c [new file with mode: 0644]
arch/dos_ipx.c [new file with mode: 0644]
arch/dos_modex.asm [new file with mode: 0644]
arch/dos_timer.asm [new file with mode: 0644]
arch/dos_tweak.inc [new file with mode: 0644]
arch/dos_vesa.c [new file with mode: 0644]
arch/dos_vgaregs.inc [new file with mode: 0644]
arch/linux/Makefile.am
arch/linux/Makefile.in
arch/linux/findfile.c
arch/linux/init.c
arch/linux/ipx_bsd.c
arch/linux/ipx_lin.c
arch/linux/ipx_udp.c
arch/linux/linuxnet.c
arch/linux_findfile.c [new file with mode: 0644]
arch/linux_init.c [new file with mode: 0644]
arch/linux_ipx_bsd.c [new file with mode: 0644]
arch/linux_ipx_lin.c [new file with mode: 0644]
arch/linux_ipx_udp.c [new file with mode: 0644]
arch/linux_net.c [new file with mode: 0644]
arch/sdl/Makefile.in
arch/sdl_init.c [new file with mode: 0644]
arch/sdl_timer.c [new file with mode: 0644]
conf.h.in
configure
configure.in
copying [new file with mode: 0644]
djgpp.bat [new file with mode: 0644]
djgpp.sh [new file with mode: 0644]
include/d.bat
include/d_io.h
include/dtypes.inc
include/gr.h
include/grdef.h
include/lst.bat
include/m.bat
include/psmacros.inc
include/pstypes.h
include/pstypes.inc
include/strutil.h
include/test.lnk
include/timer.h
input/Makefile.am
input/Makefile.in
input/dos_joy2.asm [new file with mode: 0644]
input/dos_joyc.c [new file with mode: 0644]
input/dos_joydefs.c [new file with mode: 0644]
input/dos_key.c [new file with mode: 0644]
input/dos_mouse.c [new file with mode: 0644]
input/ggi/Makefile.in
input/ggi_event.c [new file with mode: 0644]
input/ggi_init.c [new file with mode: 0644]
input/ggi_key.c [new file with mode: 0644]
input/ggi_mouse.c [new file with mode: 0644]
input/linux/Makefile.in
input/linux_joydefs.c [new file with mode: 0644]
input/linux_joystick.c [new file with mode: 0644]
input/sdl/Makefile.in
input/sdl_event.c [new file with mode: 0644]
input/sdl_key.c [new file with mode: 0644]
input/sdl_mouse.c [new file with mode: 0644]
main/Makefile.am
main/Makefile.in
main/config.c
main/console.c
main/digi.h
main/gamerend.c
main/inferno.c
main/inferno.ini
main/kconfig.c
main/kludge.c
main/link.bat [new file with mode: 0644]
main/multi.c
main/network.c
maths/vecmat.c
misc/d_io.c
misc/dos_disk.h [new file with mode: 0644]
misc/strutil.c
readme.txt
sound/Makefile.am
sound/Makefile.in
sound/dos_cdrom.c [new file with mode: 0644]
sound/dos_digi.c [new file with mode: 0644]
sound/sdl_cdrom.c
sound/sdl_digi.c
unused/bios/d.bat
unused/bios/dd.bat
unused/bios/joy.asm
unused/bios/key.asm
unused/bios/keys.inc
unused/bios/make0000.bat
unused/bios/make0001.bat
unused/bios/make0100.bat
unused/bios/mouse.asm
unused/bios/oldkey.asm
unused/bios/rbaudio.new
unused/bios/testk.lnk
unused/bios/testm.lnk
unused/bios/timer.asm
unused/bios/x
unused/bios/x.bat
unused/bios/y.bat
unused/vga/dd.bat
unused/vga/framebuf.jas
unused/vga/modex.asm
unused/vga/tweak.inc
unused/vga/vesa.asm
unused/vga/vga.jas
unused/vga/vgaregs.inc
unused/vga/xyz.bat
unused/win95/dd.bat
unused/win95/winckpit.asm
video/Makefile.am
video/Makefile.in
video/dos_gr.c [new file with mode: 0644]

index 6e28cfd..558e263 100644 (file)
@@ -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 );
index 40177b0..3efdc77 100644 (file)
@@ -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 );
index 54b4aae..019838a 100644 (file)
--- 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
index befb02c..3956c37 100644 (file)
@@ -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 2dff4f7..28b32c1 100644 (file)
--- a/2d/diff
+++ b/2d/diff
 13a14
-> #include <conf.h>\r
+> #include <conf.h>
 23c24
-< #include "mem.h"\r
+< #include "mem.h"
 ---
-> #include "u_mem.h"\r
+> #include "u_mem.h"
 31a33
-> #include "bitmap.h"\r
+> #include "bitmap.h"
 133a136
-> \r
+> 
 135a139,156
-> //hack to allow color codes to be embedded in strings -MPM\r
-> //note we subtract one from color, since 255 is "transparent" so it'll never be used, and 0 would otherwise end the string.\r
-> //function must already have orig_color var set (or they could be passed as args...)\r
-> //perhaps some sort of recursive orig_color type thing would be better, but that would be way too much trouble for little gain\r
-> int gr_message_color_level=1;\r
-> #define CHECK_EMBEDDED_COLORS() if ((*text_ptr >= 0x01) && (*text_ptr <= 0x03)) { \\r
->              text_ptr++; \\r
->              if (*text_ptr){ \\r
->                      if (gr_message_color_level >= *(text_ptr-1)) \\r
->                              FG_COLOR = *text_ptr - 1; \\r
->                      text_ptr++; \\r
->              } \\r
->      } \\r
->      else if ((*text_ptr >= 0x04) && (*text_ptr <= 0x06)){ \\r
->              if (gr_message_color_level >= *text_ptr - 3) \\r
->                      FG_COLOR=orig_color; \\r
->              text_ptr++; \\r
->      }\r
+> //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
-< \r
+< 
 ---
-> #ifdef __ENV_MSDOS__ \r
+> #ifdef __ENV_MSDOS__ 
 749a771
-> #endif\r
+> #endif
 975a998
-> #ifndef OGL\r
+> #ifndef OGL
 1049a1073,1336
-> #else // OGL\r
-> \r
-> #include "../main/inferno.h"\r
-> #include "ogl_init.h"\r
-> #include "args.h"\r
-> //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\r
-> \r
-> int pow2ize(int x);//from ogl.c\r
-> \r
-> int get_font_total_width(grs_font * font){\r
->      if (font->ft_flags & FT_PROPORTIONAL){\r
->              int i,w=0,c=font->ft_minchar;\r
->              for (i=0;c<=font->ft_maxchar;i++,c++){\r
->                      if (font->ft_widths[i]<0)\r
->                              Error("heh?\n");\r
->                      w+=font->ft_widths[i];\r
->              }\r
->              return w;\r
->      }else{\r
->              return font->ft_w*(font->ft_maxchar-font->ft_minchar+1);\r
->      }\r
-> }\r
-> void ogl_font_choose_size(grs_font * font,int gap,int *rw,int *rh){\r
->      int     nchars = font->ft_maxchar-font->ft_minchar+1;\r
->      int r,x,y,nc=0,smallest=999999,smallr=-1,tries;\r
->      int smallprop=10000;\r
->      int h,w;\r
->      for (h=32;h<=256;h*=2){\r
-> //           h=pow2ize(font->ft_h*rows+gap*(rows-1));\r
->              if (font->ft_h>h)continue;\r
->              r=(h/(font->ft_h+gap));\r
->              w=pow2ize((get_font_total_width(font)+(nchars-r)*gap)/r);\r
->              tries=0;\r
->              do {\r
->                      if (tries)\r
->                              w=pow2ize(w+1);\r
->                      if(tries>3){\r
->                              mprintf((0,"failed to fit (%ix%i, %ic)\n",w,h,nc));\r
->                              break;\r
->                      }\r
->                      nc=0;\r
->                      y=0;\r
->                      while(y+font->ft_h<=h){\r
->                              x=0;\r
->                              while (x<w){\r
->                                      if (nc==nchars)\r
->                                              break;\r
->                                      if (font->ft_flags & FT_PROPORTIONAL){\r
->                                              if (x+font->ft_widths[nc]+gap>w)break;\r
->                                              x+=font->ft_widths[nc++]+gap;\r
->                                      }else{\r
->                                              if (x+font->ft_w+gap>w)break;\r
->                                              x+=font->ft_w+gap;\r
->                                              nc++;\r
->                                      }\r
->                              }\r
->                              if (nc==nchars)\r
->                                      break;\r
->                              y+=font->ft_h+gap;\r
->                      }\r
->                      \r
->                      tries++;\r
->              }while(nc!=nchars);\r
->              if (nc!=nchars)\r
->                      continue;\r
->              mprintf((0,"fit: %ix%i  %i tries\n",w,h,tries));\r
-> \r
->              if (w*h==smallest){//this gives squarer sizes priority (ie, 128x128 would be better than 512*32)\r
->                      if (w>=h){\r
->                              if (w/h<smallprop){\r
->                                      smallprop=w/h;\r
->                                      smallest++;//hack\r
->                              }\r
->                      }else{\r
->                              if (h/w<smallprop){\r
->                                      smallprop=h/w;\r
->                                      smallest++;//hack\r
->                              }\r
->                      }\r
->              }\r
->              if (w*h<smallest){\r
->                      smallr=1;\r
->                      smallest=w*h;\r
->                      *rw=w;\r
->                      *rh=h;\r
->              }\r
->      }\r
->      if (smallr<=0)\r
->              Error("couldn't fit font?\n");\r
->      mprintf((0,"using %ix%i\n",*rw,*rh));\r
->      printf("using %ix%i\n",*rw,*rh);\r
->      \r
-> }\r
-> \r
-> void ogl_init_font(grs_font * font){\r
->      int     nchars = font->ft_maxchar-font->ft_minchar+1;\r
->      int i,w,h,tw,th,x,y,curx=0,cury=0;\r
->      char *fp;\r
->      //      char data[32*32*4];\r
->      char *data;\r
->      int gap=0;//having a gap just wastes ram, since we don't filter text textures at all.\r
->      //      char s[2];\r
->      ogl_font_choose_size(font,gap,&tw,&th);\r
->      data=malloc(tw*th);\r
->      gr_init_bitmap(&font->ft_parent_bitmap,BM_LINEAR,0,0,tw,th,tw,data);\r
-> \r
->      font->ft_parent_bitmap.gltexture=ogl_get_free_texture();\r
-> \r
->      font->ft_bitmaps=(grs_bitmap*)malloc( nchars * sizeof(grs_bitmap));\r
->      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));\r
->      //      s[1]=0;\r
->      h=font->ft_h;\r
->      //      sleep(5);\r
-> \r
->      for(i=0;i<nchars;i++){\r
->              //              s[0]=font->ft_minchar+i;\r
->              //              gr_get_string_size(s,&w,&h,&aw);\r
->              if (font->ft_flags & FT_PROPORTIONAL)\r
->                      w=font->ft_widths[i];\r
->              else\r
->                      w=font->ft_w;\r
-> //           mprintf((0,"char %i(%ix%i): ",i,w,h));\r
->              if (w<1 || w>256){\r
->                      mprintf((0,"grr\n"));continue;\r
->              }\r
->              if (curx+w+gap>tw){\r
->                      cury+=h+gap;\r
->                      curx=0;\r
->              }\r
->              if (cury+h>th)\r
->                      Error("font doesn't really fit (%i/%i)?\n",i,nchars);\r
->              if (font->ft_flags & FT_COLOR) {\r
->                      if (font->ft_flags & FT_PROPORTIONAL)\r
->                              fp = font->ft_chars[i];\r
->                      else\r
->                              fp = font->ft_data + i * w*h;\r
->                      for (y=0;y<h;y++)\r
->                              for (x=0;x<w;x++){\r
->                                      font->ft_parent_bitmap.bm_data[curx+x+(cury+y)*tw]=fp[x+y*w];\r
->                              }\r
-> \r
->                      //                      gr_init_bitmap(&font->ft_bitmaps[i],BM_LINEAR,0,0,w,h,w,font->);\r
->              }else{\r
->                      int BitMask,bits=0,white=gr_find_closest_color(63,63,63);\r
->                      //                      if (w*h>sizeof(data))\r
->                      //                              Error("ogl_init_font: toobig\n");\r
->                      if (font->ft_flags & FT_PROPORTIONAL)\r
->                              fp = font->ft_chars[i];\r
->                      else\r
->                              fp = font->ft_data + i * BITS_TO_BYTES(w)*h;\r
->                      for (y=0;y<h;y++){\r
->                              BitMask=0;\r
->                              for (x=0; x< w; x++ )\r
->                              {\r
->                                      if (BitMask==0) {\r
->                                              bits = *fp++;\r
->                                              BitMask = 0x80;\r
->                                      }\r
-> \r
->                                      if (bits & BitMask)\r
->                                              font->ft_parent_bitmap.bm_data[curx+x+(cury+y)*tw]=white;\r
->                                      else\r
->                                              font->ft_parent_bitmap.bm_data[curx+x+(cury+y)*tw]=255;\r
->                                      BitMask >>= 1;\r
->                              }\r
->                      }\r
->              }\r
->              gr_init_sub_bitmap(&font->ft_bitmaps[i],&font->ft_parent_bitmap,curx,cury,w,h);\r
-> \r
->              curx+=w+gap;\r
->      }\r
->      if (!(font->ft_flags & FT_COLOR)) {\r
->              //use GL_INTENSITY instead of GL_RGB\r
->              if (ogl_intensity4_ok){\r
->                      font->ft_parent_bitmap.gltexture->internalformat=GL_INTENSITY4;\r
->                      font->ft_parent_bitmap.gltexture->format=GL_LUMINANCE;\r
->              }else if (ogl_luminance4_alpha4_ok){\r
->                      font->ft_parent_bitmap.gltexture->internalformat=GL_LUMINANCE4_ALPHA4;\r
->                      font->ft_parent_bitmap.gltexture->format=GL_LUMINANCE_ALPHA;\r
->              }else if (ogl_rgba2_ok){\r
->                      font->ft_parent_bitmap.gltexture->internalformat=GL_RGBA2;\r
->                      font->ft_parent_bitmap.gltexture->format=GL_RGBA;\r
->              }else{\r
->                      font->ft_parent_bitmap.gltexture->internalformat=ogl_rgba_format;\r
->                      font->ft_parent_bitmap.gltexture->format=GL_RGBA;\r
->              }\r
->      }\r
->      ogl_loadbmtexture_m(&font->ft_parent_bitmap,0);\r
-> }\r
-> \r
-> int ogl_internal_string(int x, int y, char *s )\r
-> {\r
->      ubyte * text_ptr, * next_row, * text_ptr1;\r
->      int width, spacing,letter;\r
->      int xx,yy;\r
->      int orig_color=FG_COLOR;//to allow easy reseting to default string color with colored strings -MPM\r
-> \r
->      next_row = s;\r
-> \r
->      yy = y;\r
-> \r
->      if (grd_curscreen->sc_canvas.cv_bitmap.bm_type != BM_OGL)\r
->              Error("carp.\n");\r
->      while (next_row != NULL)\r
->      {\r
->              text_ptr1 = next_row;\r
->              next_row = NULL;\r
-> \r
->              text_ptr = text_ptr1;\r
-> \r
->              xx = x;\r
-> \r
->              if (xx==0x8000)                 //centered\r
->                      xx = get_centered_x(text_ptr);\r
-> \r
->              while (*text_ptr)\r
->              {\r
->                      if (*text_ptr == '\n' )\r
->                      {\r
->                              next_row = &text_ptr[1];\r
->                              yy += FHEIGHT;\r
->                              break;\r
->                      }\r
-> \r
->                      letter = *text_ptr-FMINCHAR;\r
-> \r
->                      get_char_width(text_ptr[0],text_ptr[1],&width,&spacing);\r
-> \r
->                      if (!INFONT(letter) || *text_ptr<=0x06) {       //not in font, draw as space\r
->                              CHECK_EMBEDDED_COLORS() else{\r
->                                      xx += spacing;\r
->                                      text_ptr++;\r
->                              }\r
->                              continue;\r
->                      }\r
->                      \r
-> //                   ogl_ubitblt(FONT->ft_bitmaps[letter].bm_w,FONT->ft_bitmaps[letter].bm_h,xx,yy,0,0,&FONT->ft_bitmaps[letter],NULL);\r
-> //                   if (*text_ptr>='0' && *text_ptr<='9'){\r
->                      printf("%p\n",&FONT->ft_bitmaps[letter]);\r
->                      if (FFLAGS&FT_COLOR)\r
->                              gr_ubitmapm(xx,yy,&FONT->ft_bitmaps[letter]);\r
->                      else{\r
->                              if (grd_curcanv->cv_bitmap.bm_type==BM_OGL)\r
->                                      ogl_ubitmapm_c(xx,yy,&FONT->ft_bitmaps[letter],FG_COLOR);\r
->                              else\r
->                                      Error("ogl_internal_string: non-color string to non-ogl dest\n");\r
-> //                                   gr_ubitmapm(xx,yy,&FONT->ft_bitmaps[letter]);//ignores color..\r
->                      }\r
->                      //}\r
-> \r
->                      xx += spacing;\r
-> \r
->                      text_ptr++;\r
->              }\r
-> \r
->      }\r
->      return 0;\r
-> }\r
-> int gr_internal_color_string(int x, int y, char *s ){\r
->      return ogl_internal_string(x,y,s);\r
-> }\r
-> \r
-> #endif // OGL\r
-> \r
+> #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<w){
+>                                      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){
+>                                      smallprop=w/h;
+>                                      smallest++;//hack
+>                              }
+>                      }else{
+>                              if (h/w<smallprop){
+>                                      smallprop=h/w;
+>                                      smallest++;//hack
+>                              }
+>                      }
+>              }
+>              if (w*h<smallest){
+>                      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<nchars;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<h;y++)
+>                              for (x=0;x<w;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<h;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__\r
+> #ifdef __ENV_MSDOS__
 1123a1412
-> #endif\r
+> #endif
 1248a1538,1539
-> #define swapshort(a) (a)\r
-> #define swapint(a) (a)\r
+> #define swapshort(a) (a)
+> #define swapint(a) (a)
 1251a1543
->      old_grs_font *oldfont;\r
+>      old_grs_font *oldfont;
 1284c1576,1578
-<      font = (grs_font *) malloc(datasize);\r
+<      font = (grs_font *) malloc(datasize);
 ---
->      oldfont = (old_grs_font *) malloc(datasize);\r
->      font = (grs_font *) malloc(sizeof(grs_font));\r
->      font->oldfont = oldfont;\r
+>      oldfont = (old_grs_font *) malloc(datasize);
+>      font = (grs_font *) malloc(sizeof(grs_font));
+>      font->oldfont = oldfont;
 1288c1582,1590
-<      cfread(font,1,datasize,fontfile);\r
+<      cfread(font,1,datasize,fontfile);
 ---
->      cfread(oldfont,1,datasize,fontfile);\r
->         font->ft_flags=swapshort(oldfont->ft_flags);\r
->         font->ft_w=swapshort(oldfont->ft_w);\r
->         font->ft_h=swapshort(oldfont->ft_h);\r
->         font->ft_baseline=swapshort(oldfont->ft_baseline);\r
->         font->ft_maxchar=oldfont->ft_maxchar;\r
->         font->ft_minchar=oldfont->ft_minchar;\r
->         font->ft_bytewidth=swapshort(oldfont->ft_bytewidth);\r
-> \r
+>      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));\r
+<              font->ft_widths = (short *) (((int) font->ft_widths) + ((ubyte *) font));
 ---
->              font->ft_widths = (short *) (((int) oldfont->ft_widths) + ((ubyte *) oldfont));\r
+>              font->ft_widths = (short *) (((int) oldfont->ft_widths) + ((ubyte *) oldfont));
 1311c1613
-<                      font->ft_widths[i] = SWAPSHORT(font->ft_widths[i]);\r
+<                      font->ft_widths[i] = SWAPSHORT(font->ft_widths[i]);
 ---
->                      font->ft_widths[i] = swapshort(oldfont->ft_widths[i]);\r
+>                      font->ft_widths[i] = swapshort(oldfont->ft_widths[i]);
 1314c1616
-<              font->ft_data = ((int) font->ft_data) + ((ubyte *) font);\r
+<              font->ft_data = ((int) font->ft_data) + ((ubyte *) font);
 ---
->              font->ft_data = ((int) oldfont->ft_data) + ((ubyte *) oldfont);\r
+>              font->ft_data = ((int) oldfont->ft_data) + ((ubyte *) oldfont);
 1330c1632
-<              font->ft_data = ((unsigned char *) font) + sizeof(*font);\r
+<              font->ft_data = ((unsigned char *) font) + sizeof(*font);
 ---
->              font->ft_data = ((unsigned char *) oldfont) + sizeof(*oldfont);\r
+>              font->ft_data = ((unsigned char *) oldfont) + sizeof(*oldfont);
 1339c1641
-<              font->ft_kerndata = ((int) font->ft_kerndata) + ((ubyte *) font);\r
+<              font->ft_kerndata = ((int) font->ft_kerndata) + ((ubyte *) font);
 ---
->              font->ft_kerndata = swapint(((int) oldfont->ft_kerndata) + ((ubyte *) oldfont));\r
+>              font->ft_kerndata = swapint(((int) oldfont->ft_kerndata) + ((ubyte *) oldfont));
 1386a1689,1692
-> \r
-> #ifdef OGL\r
->      ogl_init_font(font);\r
-> #endif\r
+> 
+> #ifdef OGL
+>      ogl_init_font(font);
+> #endif
index 736c97a..d1e0b68 100644 (file)
@@ -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;
index 3b28ed3..b9f34f6 100644 (file)
--- 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;             
index 811f11c..8f0e973 100644 (file)
@@ -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
 
index ab5cbf6..a0c9951 100644 (file)
@@ -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 d78a083..73c52cc 100644 (file)
--- a/README
+++ b/README
-Ok folks, this is the d2x port of descent 2.\r
-At this stage most of descent 2 works under linux:\r
-\r
-Known bugs/unintentional features/missing stuff:\r
-* Serial support doesn't work. (UDP and IPX networking does)\r
-* Movies (unlikely ever to be supported)\r
-* Sound glitches (due to stuff I haven't implemented)\r
-* The mouse support is at the same level as it was in d1x (as in, it kind of works)\r
-* Something went screwy with the control config system, it kinda got "d1xed"...\r
-* 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 =)\r
-\r
-Basically, to compile this under linux:\r
-You need the SDL 1.0 or greater, and a thread-safe X server.\r
-Do a ./autogen.sh then a make. Cross your fingers and pray, it worked on my machine.\r
-\r
-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...\r
-\r
-There are two ways to report bugs and give feedback:\r
-1) Get on the descent-source mailing list by sending an email to majordomo@warpcore.org with the body as: "subscribe descent-source <your email address>". 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.\r
-\r
-2) Send feedback directly to me, peterhawkins@ozemail.com.au. I'll try to get back to you ASAP, depending on real-life concerns =)\r
-\r
-\r
-/* THE OLD README FOLLOWS */\r
-Legal Stuff:\r
-\r
-THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX\r
-SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO\r
-END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A\r
-ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS\r
-IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS\r
-SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE\r
-FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE\r
-CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS\r
-AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  \r
-COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.\r
-\r
-We make no warranties as to the usability or correctness of this code.\r
-\r
-============================================\r
-Message from Matt Toschlog & Mike Kulas:\r
-\r
-Descent fans:\r
-\r
-Here, finally, is the source for Descent II.  We've been so busy with \r
-Descent 3, Mercenary, FreeSpace, FreeSpace 2, and several other \r
-projects that we haven't given much thought to this old code.  But we \r
-know that many of you are eager to get it, so here you go.\r
-\r
-We were amazed and impressed at the cool things people did with \r
-the Descent source we released a few years ago.  It touches us \r
-deeply how devoted some people are to the Descent series, and we \r
-look forward to seeing what people can do with this Descent II \r
-source.\r
-\r
-Matt Toschlog               Mike Kulas\r
-Outrage Entertainment       Volition, Inc.\r
-\r
-============================================\r
-\r
-About the Source Code:\r
-\r
-Included is almost all the source code to Descent 2, ver. 1.2.  We removed\r
-all code to which we did not own the copyright.  This mainly involved low-\r
-level sound and modem code and the movie code.    \r
-\r
-The Descent Network has agreed to provide a list of mirror locations where \r
-this code can be downloaded. The location is:\r
-\r
-http://www.descent2.com/ddn/sources/descent2\r
-\r
-The following tools were used in the development of Descent:\r
-Watcom C/C++, version 9.5\r
-Microsoft Macro Assembler, version 6.1x\r
-Opus Make, version 6.01\r
-\r
-Have fun with the code!\r
-Parallax Software Corporation\r
-12/14/1999\r
-\r
-\r
-As Packaged the code currently will not compile. Some code had to be removed\r
-to release it, therefore you will get some missing file errors when building.\r
-\r
-Much of this code is very close to the Descent 1 source code. Many people have\r
-put effort into porting that code, so if you are interested in porting D2, you\r
-should be able to take advantage of some of that work.\r
-\r
-A few good web sites to check out are:\r
-\r
-The D1X Project:\r
-http://d1x.warpcore.org\r
-\r
-The Descent Network:\r
-http://www.descent-network.com\r
-\r
+===========
+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 <your email address>". 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
+
index 4f88f13..8c4c899 100644 (file)
@@ -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
index 7398866..367b002 100644 (file)
@@ -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 (file)
index 0000000..80b046e
--- /dev/null
@@ -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 (file)
index 0000000..785002a
--- /dev/null
@@ -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 (file)
index 0000000..7d92839
--- /dev/null
@@ -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 <conf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#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 (file)
index 0000000..d224d97
--- /dev/null
@@ -0,0 +1,810 @@
+// SDL digital audio support
+
+#include <conf.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#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<MAX_SOUND_SLOTS; i++)
+ {
+  if (!SoundSlots[i].playing) return i;
+ }
+ return -1;
+}
+
+int digi_start_sound(int soundnum, fix volume, fix pan, int unknown1, int unknown2, int unknown3, int unknown4)
+{
+ int ntries;
+ int slot;
+
+ if (!digi_initialised) return -1;
+
+ //added on 980905 by adb from original source to add sound kill system
+ // play at most digi_max_channel samples, if possible kill sample with low volume
+ ntries = 0;
+
+TryNextChannel:
+ if ( (SampleHandles[next_handle] >= 0) && (SoundSlots[SampleHandles[next_handle]].playing)  )
+ {
+  if ( (SoundSlots[SampleHandles[next_handle]].volume > digi_volume) && (ntries<digi_max_channels) )
+  {
+   //mprintf(( 0, "Not stopping loud sound %d.\n", next_handle ));
+   next_handle++;
+   if ( next_handle >= 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<digi_max_channels; i++)
+  if (SampleHandles[i] == channel)
+   SampleHandles[i] = -1;
+}
+//end edit by adb
+
+int digi_start_sound_object(int obj)
+{
+ int slot;
+
+ if (!digi_initialised) return -1;
+ slot = get_free_slot();
+
+ if (slot<0) return -1;
+
+
+ SoundSlots[slot].soundno = SoundObjects[obj].soundnum;
+ SoundSlots[slot].samples = GameSounds[SoundObjects[obj].soundnum].data;
+ SoundSlots[slot].length = GameSounds[SoundObjects[obj].soundnum].length;
+ SoundSlots[slot].volume = fixmul(digi_volume, SoundObjects[obj].volume);
+ SoundSlots[slot].pan = SoundObjects[obj].pan;
+ SoundSlots[slot].position = 0;
+ SoundSlots[slot].looped = (SoundObjects[obj].flags & SOF_PLAY_FOREVER);
+ SoundSlots[slot].playing = 1;
+
+ SoundObjects[obj].signature = next_signature++;
+ SoundObjects[obj].handle = slot;
+
+ SoundObjects[obj].flags |= SOF_PLAYING;
+ //added on 980905 by adb to add sound kill system from original sos digi.c
+ reset_sounds_on_channel(slot);
+ //end edit by adb
+ return 0;
+}
+
+
+// Play the given sound number.
+// Volume is max at F1_0.
+void digi_play_sample( int soundno, fix max_volume )
+{
+#ifdef NEWDEMO
+       if ( Newdemo_state == ND_STATE_RECORDING )
+               newdemo_record_sound( soundno );
+#endif
+       soundno = digi_xlat_sound(soundno);
+
+       if (!digi_initialised) return;
+
+       if (soundno < 0 ) return;
+
+       digi_start_sound(soundno, max_volume, F0_5, 0, 0, 0, 0);
+}
+
+// Play the given sound number. If the sound is already playing,
+// restart it.
+void digi_play_sample_once( int soundno, fix max_volume )
+{
+       int i;
+
+#ifdef NEWDEMO
+       if ( Newdemo_state == ND_STATE_RECORDING )
+               newdemo_record_sound( soundno );
+#endif
+       soundno = digi_xlat_sound(soundno);
+
+       if (!digi_initialised) return;
+
+       if (soundno < 0 ) return;
+
+        for (i=0; i < MAX_SOUND_SLOTS; i++)
+          if (SoundSlots[i].soundno == soundno)
+            SoundSlots[i].playing = 0;
+       digi_start_sound(soundno, max_volume, F0_5, 0, 0, 0, 0);
+
+}
+
+void digi_play_sample_3d( int soundno, int angle, int volume, int no_dups ) // Volume from 0-0x7fff
+{
+       no_dups = 1;
+
+#ifdef NEWDEMO
+       if ( Newdemo_state == ND_STATE_RECORDING )              {
+               if ( no_dups )
+                       newdemo_record_sound_3d_once( soundno, angle, volume );
+               else
+                       newdemo_record_sound_3d( soundno, angle, volume );
+       }
+#endif
+       soundno = digi_xlat_sound(soundno);
+
+       if (!digi_initialised) return;
+       if (soundno < 0 ) return;
+
+       if (volume < MIN_VOLUME ) return;
+       digi_start_sound(soundno, volume, angle, 0, 0, 0, 0);
+}
+
+void digi_get_sound_loc( vms_matrix * listener, vms_vector * listener_pos, int listener_seg, vms_vector * sound_pos, int sound_seg, fix max_volume, int *volume, int *pan, fix max_distance )
+{        
+       vms_vector      vector_to_sound;
+       fix angle_from_ear, cosang,sinang;
+       fix distance;
+       fix path_distance;
+
+       *volume = 0;
+       *pan = 0;
+
+       max_distance = (max_distance*5)/4;              // Make all sounds travel 1.25 times as far.
+
+       //      Warning: Made the vm_vec_normalized_dir be vm_vec_normalized_dir_quick and got illegal values to acos in the fang computation.
+       distance = vm_vec_normalized_dir_quick( &vector_to_sound, sound_pos, listener_pos );
+               
+       if (distance < max_distance )   {
+               int num_search_segs = f2i(max_distance/20);
+               if ( num_search_segs < 1 ) num_search_segs = 1;
+
+               path_distance = find_connected_distance(listener_pos, listener_seg, sound_pos, sound_seg, num_search_segs, WID_RENDPAST_FLAG );
+               if ( path_distance > -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; i<MAX_SOUND_OBJECTS; i++ )
+               if (SoundObjects[i].flags==0)
+                  break;
+
+       if (i==MAX_SOUND_OBJECTS) {
+               mprintf((1, "Too many sound objects!\n" ));
+               return -1;
+       }
+
+       SoundObjects[i].signature=next_signature++;
+       SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_OBJ;
+       if ( forever )
+               SoundObjects[i].flags |= SOF_PLAY_FOREVER;
+       SoundObjects[i].lo_objnum = objnum;
+       SoundObjects[i].lo_objsignature = Objects[objnum].signature;
+       SoundObjects[i].max_volume = max_volume;
+       SoundObjects[i].max_distance = max_distance;
+       SoundObjects[i].volume = 0;
+       SoundObjects[i].pan = 0;
+       SoundObjects[i].soundnum = soundnum;
+
+       objp = &Objects[SoundObjects[i].lo_objnum];
+       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 (!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; i<MAX_SOUND_OBJECTS; i++ )
+               if (SoundObjects[i].flags==0)
+                       break;
+       
+       if (i==MAX_SOUND_OBJECTS) {
+               mprintf((1, "Too many sound objects!\n" ));
+               return -1;
+       }
+
+
+       SoundObjects[i].signature=next_signature++;
+       SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_POS;
+       if ( forever )
+               SoundObjects[i].flags |= SOF_PLAY_FOREVER;
+       SoundObjects[i].lp_segnum = segnum;
+       SoundObjects[i].lp_sidenum = sidenum;
+       SoundObjects[i].lp_position = *pos;
+       SoundObjects[i].soundnum = soundnum;
+       SoundObjects[i].max_volume = max_volume;
+       SoundObjects[i].max_distance = max_distance;
+       SoundObjects[i].volume = 0;
+       SoundObjects[i].pan = 0;
+       digi_get_sound_loc( &Viewer->orient, &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<MAX_SOUND_OBJECTS; i++ )    {
+               if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_POS) )  {
+                       if ((SoundObjects[i].lp_segnum == segnum) && (SoundObjects[i].soundnum==soundnum ) && (SoundObjects[i].lp_sidenum==sidenum) ) {
+                               if ( SoundObjects[i].flags & SOF_PLAYING )      {
+                                       SoundSlots[SoundObjects[i].handle].playing = 0;
+                               }
+                               SoundObjects[i].flags = 0;      // Mark as dead, so some other sound can use this sound
+                               killed++;
+                       }
+               }
+       }
+       // If this assert happens, it means that there were 2 sounds
+       // that got deleted. Weird, get John.
+       if ( killed > 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<MAX_SOUND_OBJECTS; i++ )    {
+               if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_OBJ ) ) {
+                       if (SoundObjects[i].lo_objnum == objnum)   {
+                               if ( SoundObjects[i].flags & SOF_PLAYING )      {
+                                     SoundSlots[SoundObjects[i].handle].playing = 0;
+                               }
+                               SoundObjects[i].flags = 0;      // Mark as dead, so some other sound can use this sound
+                               killed++;
+                       }
+               }
+       }
+       // If this assert happens, it means that there were 2 sounds
+       // that got deleted. Weird, get John.
+       if ( killed > 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; i<MAX_SOUND_OBJECTS; i++ )    {
+               if ( SoundObjects[i].flags & SOF_USED ) {
+                       oldvolume = SoundObjects[i].volume;
+                       oldpan = SoundObjects[i].pan;
+
+                       if ( !(SoundObjects[i].flags & SOF_PLAY_FOREVER) )      {
+                               // Check if its done.
+                               if (SoundObjects[i].flags & SOF_PLAYING) {
+                                       if (!SoundSlots[SoundObjects[i].handle].playing) {
+                                               SoundObjects[i].flags = 0;      // Mark as dead, so some other sound can use this sound
+                                               continue;               // Go on to next sound...
+                                       }
+                               }
+                       }                       
+               
+                       if ( SoundObjects[i].flags & SOF_LINK_TO_POS )  {
+                               digi_get_sound_loc( &Viewer->orient, &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<MAX_SOUND_OBJECTS; i++ )    {
+               if (digi_sounds_initialized) {
+                       if ( SoundObjects[i].flags & SOF_PLAYING )      {
+                               SoundSlots[SoundObjects[i].handle].playing=0;
+                       }
+               }
+               SoundObjects[i].flags = 0;      // Mark as dead, so some other sound can use this sound
+       }
+       digi_sounds_initialized = 1;
+}
+
+//added on 980905 by adb from original source to make sfx volume work
+void digi_set_digi_volume( int dvolume )
+{
+       dvolume = fixmuldiv( dvolume, SOUND_MAX_VOLUME, 0x7fff);
+       if ( dvolume > 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
index 13088eb..0d18ecf 100644 (file)
@@ -1,6 +1,7 @@
+#include <conf.h>
 #include <dos.h>
 #include <limits.h>
-#include "types.h"
+#include "pstypes.h"
 #include "error.h"
 
 unsigned long getdiskfree() {
index 3d7fec0..24724d6 100644 (file)
@@ -1,5 +1,7 @@
 // Graphics functions for DOS.
 
+#include <conf.h>
+
 #include <stdio.h>
 #include <string.h>
 #include <io.h>
@@ -15,8 +17,6 @@
 #include "modex.h"
 #include "error.h"
 
-#include "gamefont.h"
-
 #ifdef __DJGPP__
 #include <sys/nearptr.h>
 #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, &regs, &regs );
 
-       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... */
index 8cb2a2f..9bd503c 100644 (file)
@@ -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 <conf.h>
+#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 <i86.h>
 #include <dos.h>
 #include <stdio.h>
 #include <string.h>
 #include <malloc.h>
 #include <stdlib.h>
-#include <conio.h>
 
-#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 (file)
index 0000000..4db5c8c
--- /dev/null
@@ -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 <conf.h>
+#ifdef __ENV_DJGPP__
+
+#include <dos.h>
+#include <string.h>
+
+#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__
index 63a8ad9..2178640 100644 (file)
@@ -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
index 0f9daa4..ba2937a 100644 (file)
@@ -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
index 28a5cd0..43b86b7 100644 (file)
@@ -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
index 72748b0..3f74ec4 100644 (file)
@@ -1,3 +1,6 @@
+#include <conf.h>
+#ifdef __ENV_DJGPP__
+
 #include <stdio.h>
 #include <string.h>
 #ifdef __DJGPP__
@@ -7,6 +10,7 @@
 
 #include "../../main/inferno.h"
 #include "../../main/text.h"
+#include "console.h"
 #include "args.h"
 #include "error.h"
 
 #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__
index 442873a..410e7a3 100644 (file)
@@ -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 <conf.h>
 
 #include <stdlib.h>
 #include <stdio.h>
-#include <conio.h>
 #include <dos.h>
-#include <i86.h>
 
 //#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();
index e9b7451..4444f14 100644 (file)
@@ -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 <conf.h>
 
 #include <stdlib.h>
 #include <stdio.h>
@@ -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];
index bec3d31..3688200 100644 (file)
@@ -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 <conf.h>
 #include <stdlib.h>
 #include <stdio.h>
-#include <conio.h>
 #include <dos.h>
-#include <i86.h>
 
 //#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;
index 37e9b53..da635a0 100644 (file)
@@ -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 <conf.h>
 
 #ifdef __DJGPP__
 #include <dpmi.h>
@@ -80,9 +78,9 @@ _go32_dpmi_registers handler_regs;
 
 #include <stdlib.h>
 #include <stdio.h>
-#include <conio.h>
+//#include <conio.h>
 #include <dos.h>
-#include <i86.h>
+//#include <i86.h>
 #include <string.h>
 
 #include "error.h"
index 5479130..fd965b5 100644 (file)
@@ -1,3 +1,7 @@
+#include <conf.h>
+#ifdef __ENV_DJGPP__
+
+
 #include <string.h>
 #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 (file)
index 0000000..9bd503c
--- /dev/null
@@ -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 <conf.h>
+#ifdef __ENV_DJGPP__
+
+#ifdef __DJGPP__
+#define _BORLAND_DOS_REGS 1
+#define far
+#include <sys/segments.h>
+#include <sys/nearptr.h>
+#include <crt0.h>
+#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 <dos.h>
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+#include <stdlib.h>
+
+#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(&regs,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, &regs, &regs, &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(&regs,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, &regs, &regs, &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(&regs,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, &regs, &regs);
+       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(&regs,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, &regs, &regs);
+       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(&regs,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, &regs, &regs);            // 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(&regs,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, &regs, &regs);            // 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(&regs,0,sizeof(regs));
+       regs.w.ax = 0;                                                  // DPMI Allocate Selector
+       regs.w.cx = 1;                                                  // Allocate 1 selector
+       int386 (0x31, &regs, &regs);            // 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(&regs,0,sizeof(regs));
+       regs.x.eax = 0x400;                                                     // DPMI Get Memory Info
+   int386( 0x31, &regs, &regs );
+       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(&regs,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, &regs, &regs, &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(&regs,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, &regs, &regs );
+       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 (file)
index 0000000..4db5c8c
--- /dev/null
@@ -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 <conf.h>
+#ifdef __ENV_DJGPP__
+
+#include <dos.h>
+#include <string.h>
+
+#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 (file)
index 0000000..2143a5b
--- /dev/null
@@ -0,0 +1,370 @@
+#include <conf.h>
+#ifdef __ENV_DJGPP__
+
+#include <stdio.h>
+#include <string.h>
+#ifdef __DJGPP__
+#define _BORLAND_DOS_REGS 1
+#endif
+#include <dos.h>
+
+#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(&regs,0,sizeof(regs));
+        regs.x.eax = 0x8400;
+        regs.x.edx = 0xF0;
+        int386( 0x15, &regs, &regs );
+       if ( ( regs.x.eax & 0xFFFF ) == 0x4753 /*'SG'*/ )
+                return 1;
+        else
+                return 0;
+}
+
+void check_dos_version()
+{
+        int major, minor;
+        union REGS regs;
+
+        memset(&regs,0,sizeof(regs));
+        regs.x.eax = 0x3000;                                                    // Get MS-DOS Version Number
+        int386( 0x21, &regs, &regs );
+
+        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<l; i++ ) {
+                if (c==0) {
+                        if (i) *p++=',';
+            c = 3;
+        }
+        c--;
+        *p++ = buffer[i];
+    }
+        *p++ = '\0';
+}
+
+void check_memory()
+{
+        char text[32];
+
+        printf( "\n%s\n", TXT_AVAILABLE_MEMORY);
+        printf( "----------------\n" );
+        mem_int_to_string( dpmi_dos_memory/1024, text );
+        printf( "Conventional: %7s KB\n", text );
+        mem_int_to_string( dpmi_physical_memory/1024, text );
+        printf( "Extended:     %7s KB\n", text );
+        if ( dpmi_available_memory > 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<stack_size; sil++ )    {
+//NO_STACK_SIZE_CHECK           stack--;
+//NO_STACK_SIZE_CHECK           *stack = 0xface0123;
+//NO_STACK_SIZE_CHECK   }
+//NO_STACK_SIZE_CHECK
+//NO_STACK_SIZE_CHECK   ret_value = descent_main( argc, argv );         // Rename main to be descent_main
+//NO_STACK_SIZE_CHECK 
+//NO_STACK_SIZE_CHECK   for ( sil=0; sil<stack_size; sil++ )    {
+//NO_STACK_SIZE_CHECK           if ( *stack == 0xface0123 )     
+//NO_STACK_SIZE_CHECK                   unused_stack_space++;
+//NO_STACK_SIZE_CHECK           stack++;
+//NO_STACK_SIZE_CHECK   }
+//NO_STACK_SIZE_CHECK 
+//NO_STACK_SIZE_CHECK   mprintf(( 0, "Program used %d/%d stack space\n", (stack_size - unused_stack_space)*4, stack_size*4 ));
+//NO_STACK_SIZE_CHECK   key_getch();
+//NO_STACK_SIZE_CHECK 
+//NO_STACK_SIZE_CHECK   return ret_value;
+//NO_STACK_SIZE_CHECK }
+
+extern int digi_timer_rate;
+
+#ifdef __WATCOMC__
+#pragma off (check_stack)
+int __far descent_critical_error_handler(unsigned deverror, unsigned errcode, unsigned __far * devhdr )
+{
+        devhdr = devhdr;
+        descent_critical_error++;
+        descent_critical_deverror = deverror;
+        descent_critical_errcode = errcode;
+        return _HARDERR_FAIL;
+}
+void chandler_end (void)  // dummy functions
+{
+}
+#pragma on (check_stack)
+#endif
+
+void arch_init_start() {
+       // Initialize DPMI before anything else!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+        // (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);
+        con_printf(CON_VERBOSE, "Initializing DPMI services... ");
+        dpmi_init(1);             // Before anything
+        con_printf(CON_VERBOSE, "\n" );
+
+#ifndef __GNUC__
+        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" );
+        }
+        if (!dpmi_lock_region(&descent_critical_error,sizeof(int)))     {
+                Error( "Unable to lock critial error handler" );
+        }
+        if (!dpmi_lock_region(&descent_critical_deverror,sizeof(unsigned)))     {
+                Error( "Unable to lock critial error handler" );
+        }
+        if (!dpmi_lock_region(&descent_critical_errcode,sizeof(unsigned)))      {
+                Error( "Unable to lock critial error handler" );
+        }
+        _harderr((void *) descent_critical_error_handler );
+        //Above line modified by KRB, added (void *) cast
+        //for the compiler.
+#endif
+}
+
+void arch_init() {
+        if ( !args_find( "-nodoscheck" ))
+                check_dos_version();
+        
+        if ( !args_find( "-nofilecheck" ))
+                dos_check_file_handles(5);
+
+        if ( !args_find( "-nomemcheck" ))
+                check_memory();
+
+       #ifndef NDEBUG
+                minit();
+                mopen( 0, 9, 1, 78, 15, "Debug Spew");
+                mopen( 1, 2, 1, 78,  5, "Errors & Serious Warnings");
+        #endif
+
+/*        if (!WVIDEO_running)
+                mprintf((0,"WVIDEO_running = %d\n",WVIDEO_running));*/
+
+        //if (!WVIDEO_running) install_int3_handler();
+
+
+        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
+
+        con_printf(CON_VERBOSE, "\n%s", TXT_VERBOSE_3);
+        key_init();
+        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 {
+                con_printf(CON_VERBOSE, "\n%s", TXT_VERBOSE_5);
+        }
+        if (!args_find( "-nojoystick" ))  {
+                con_printf(CON_VERBOSE, "\n%s", TXT_VERBOSE_6);
+                joy_init();
+                if ( args_find( "-joyslow" ))     {
+                        con_printf(CON_VERBOSE, "\n%s", TXT_VERBOSE_7);
+                        joy_set_slow_reading(JOY_SLOW_READINGS);
+                }
+                if ( args_find( "-joypolled" ))   {
+                        con_printf(CON_VERBOSE, "\n%s", TXT_VERBOSE_8);
+                        joy_set_slow_reading(JOY_POLLED_READINGS);
+                }
+                if ( args_find( "-joybios" ))     {
+                        con_printf(CON_VERBOSE, "\n%s", TXT_VERBOSE_9);
+                        joy_set_slow_reading(JOY_BIOS_READINGS);
+                }
+                if ( args_find( "-joynice" ))     {
+                        con_printf(CON_VERBOSE, "\n%s", "Using nice joystick poller..." );
+                        joy_set_slow_reading(JOY_FRIENDLY_READINGS);
+                }
+                if ( args_find( "-gameport" ))    {
+                        if ( init_gameport() )  {                       
+                                joy_set_slow_reading(JOY_BIOS_READINGS);
+                        } else {
+                                Error( "\nCouldn't initialize the Notebook Gameport.\nMake sure the NG driver is loaded.\n" );
+                        }
+                }
+        } else {
+                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_ipx.c b/arch/dos_ipx.c
new file mode 100644 (file)
index 0000000..88b2399
--- /dev/null
@@ -0,0 +1,753 @@
+/*
+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 <conf.h>
+
+#ifdef __ENV_DJGPP__
+
+#ifdef __GNUC__
+#define _BORLAND_DOS_REGS 1
+#define far
+#endif
+
+#include <dos.h>
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#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<ipx_num_packets; i++ )      {
+               if ( !packets[i].ecb.in_use )   {
+                       got_new_packet( &packets[i].ecb );
+                       packets[i].ecb.in_use = 0;
+                       ipx_listen_for_packet(&packets[i].ecb);
+               }                       
+       }
+
+       best = -1;
+       n = 0;
+       best_id = -1;
+
+       for (i=0; i<=largest_packet_index; i++ )        {
+               if ( packet_buffers[i].packetnum > -1 ) {
+                       n++;
+                       if ( best == -1 || (packet_buffers[i].packetnum<best) ) {
+                               best = packet_buffers[i].packetnum;
+                               best_id = i;
+                       }
+               }                       
+       }
+
+       //mprintf( (0, "Best id = %d, pn = %d, last_ecb = %x, len=%x, ne = %d\n", best_id, best, last_ecb, lastlen, neterrors ));
+       //mprintf( (1, "<%d> ", 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<MAX_PACKETS; i++ )  {
+               packet_buffers[i].packetnum = -1;
+               packet_free_list[i] = i;
+       }
+       num_packets = 0;
+       largest_packet_index = 0;
+
+       // Get the IPX vector
+       memset(&rregs,0,sizeof(dpmi_real_regs));
+       rregs.eax=0x00007a00;
+       dpmi_real_int386x( 0x2f, &rregs );
+
+       if ( (rregs.eax & 0xFF) != 0xFF )       {
+               return 3;   
+       }
+       ipx_vector_offset = rregs.edi & 0xFFFF;
+       ipx_vector_segment = rregs.es;
+       //printf( "IPX entry point at %.4x:%.4x\n", ipx_vector_segment, ipx_vector_offset );
+
+       // Open a socket for IPX
+
+       memset(&rregs,0,sizeof(dpmi_real_regs));
+       swab( (char *)&socket_number,(char *)&ipx_socket, 2 );
+       rregs.edx = ipx_socket;
+       rregs.eax = ipx_socket_life;
+       rregs.ebx = 0;  // Open socket
+       dpmi_real_int386x( 0x7A, &rregs );
+       
+       ipx_socket = rregs.edx & 0xFFFF;
+       
+       if ( rregs.eax & 0xFF ) {
+               //mprintf( (1, "IPX error opening channel %d\n", socket_number-IPX_DEFAULT_SOCKET ));
+               return -2;
+       }
+       
+       ipx_installed = 1;
+
+       // Find our internetwork address
+       ipx_real_buffer = dpmi_get_temp_low_buffer( 1024 );     // 1k block
+       if ( ipx_real_buffer == NULL )  {
+               //printf( "Error allocation realmode memory\n" );
+               return -4;
+       }
+
+       memset(&rregs,0,sizeof(dpmi_real_regs));
+       rregs.ebx = 9;          // Get internetwork address
+       rregs.esi = DPMI_real_offset(ipx_real_buffer);
+       rregs.es = DPMI_real_segment(ipx_real_buffer);
+       dpmi_real_int386x( 0x7A, &rregs );
+
+       if ( rregs.eax & 0xFF ) {
+               //printf( "Error getting internetwork address!\n" );
+               return -2;
+       }
+
+       memcpy( &ipx_network, ipx_real_buffer, 4 );
+       memcpy( &ipx_my_node, &ipx_real_buffer[4], 6 );
+
+       Ipx_num_networks = 0;
+       memcpy( &Ipx_networks[Ipx_num_networks++], &ipx_network, 4 );
+
+       if ( show_address )     {
+               printf( "My IPX addresss is " );
+               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] );
+               printf( "\n" );
+       }
+
+       packets = dpmi_real_malloc( sizeof(ipx_packet)*ipx_num_packets, &ipx_packets_selector );
+       if ( packets == NULL )  {
+               //printf( "Couldn't allocate real memory for %d packets\n", ipx_num_packets );
+               return -4;
+       }
+#if 0 /* adb: not needed, fails with cwsdpmi */
+       if (!dpmi_lock_region( packets, sizeof(ipx_packet)*ipx_num_packets ))   {
+               //printf( "Couldn't lock real memory for %d packets\n", ipx_num_packets );
+               return -4;
+       }
+#endif
+       memset( packets, 0, sizeof(ipx_packet)*ipx_num_packets );
+
+       for (i=1; i<ipx_num_packets; i++ )      {
+               packets[i].ecb.in_use = 0x1d;
+               //packets[i].ecb.in_use = 0;
+               packets[i].ecb.socket_id = ipx_socket;
+               packets[i].ecb.fragment_count = 1;
+               packets[i].ecb.fragment_pointer[0] = DPMI_real_offset(&packets[i].ipx);
+               packets[i].ecb.fragment_pointer[1] = DPMI_real_segment(&packets[i].ipx);
+               packets[i].ecb.fragment_size = sizeof(ipx_packet)-sizeof(ecb_header);                   //-sizeof(ecb_header);
+
+               ipx_listen_for_packet(&packets[i].ecb);
+       }
+
+       packets[0].ecb.socket_id = ipx_socket;
+       packets[0].ecb.fragment_count = 1;
+       packets[0].ecb.fragment_pointer[0] = DPMI_real_offset(&packets[0].ipx);
+       packets[0].ecb.fragment_pointer[1] = DPMI_real_segment(&packets[0].ipx);
+       packets[0].ipx.packet_type = 4;         // IPX packet
+       packets[0].ipx.destination.socket_id = ipx_socket;
+//     memcpy( packets[0].ipx.destination.network_id, &ipx_network, 4 );
+       memset( packets[0].ipx.destination.network_id, 0, 4 );
+
+       return 0;
+}
+
+void ipx_send_packet_data( ubyte * data, int datasize, ubyte *network, ubyte *address, ubyte *immediate_address )
+{
+       assert(ipx_installed);
+
+       if ( datasize >= 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; i++ )     {
+               if ( memcmp( &Ipx_networks[i], &ipx_network, 4 ) )      {
+                       ipx_get_local_target( (ubyte *)&Ipx_networks[i], broadcast, local_address );
+                       ipx_send_packet_data( data, datasize, (ubyte *)&Ipx_networks[i], broadcast, local_address );
+               } else {
+                       ipx_send_packet_data( data, datasize, (ubyte *)&Ipx_networks[i], broadcast, broadcast );
+               }
+       }
+
+       //OLDipx_send_packet_data( data, datasize, (ubyte *)&ipx_network, broadcast, broadcast );
+
+       // Send directly to all users not on my network or in the network list.
+       for (i=0; i<Ipx_num_users; i++ )        {
+               if ( memcmp( Ipx_users[i].network, &ipx_network, 4 ) )  {
+                       for (j=0; j<Ipx_num_networks; j++ )             {
+                               if (!memcmp( Ipx_users[i].network, &Ipx_networks[j], 4 ))
+                                       goto SkipUser;
+                       }
+                       ipx_send_packet_data( data, datasize, Ipx_users[i].network, Ipx_users[i].node, Ipx_users[i].address );
+SkipUser:
+                       j = 0;
+               }
+       }
+}
+
+// Sends a non-localized packet... needs 4 byte server, 6 byte address
+void ipx_send_internetwork_packet_data( ubyte * data, int datasize, ubyte * server, ubyte *address )
+{
+       ubyte local_address[6];
+
+       if ( (*(uint *)server) != 0 )   {
+               ipx_get_local_target( server, address, local_address );
+               ipx_send_packet_data( data, datasize, server, address, local_address );
+       } else {
+               // Old method, no server info.
+               ipx_send_packet_data( data, datasize, server, address, address );
+       }
+}
+
+int ipx_change_default_socket( ushort socket_number )
+{
+       int i;
+       WORD new_ipx_socket;
+       dpmi_real_regs rregs;
+
+       if ( !ipx_installed ) return -3;
+
+       // Open a new socket    
+       memset(&rregs,0,sizeof(dpmi_real_regs));
+       swab( (char *)&socket_number,(char *)&new_ipx_socket, 2 );
+       rregs.edx = new_ipx_socket;
+       rregs.eax = ipx_socket_life;
+       rregs.ebx = 0;  // Open socket
+       dpmi_real_int386x( 0x7A, &rregs );
+       
+       new_ipx_socket = rregs.edx & 0xFFFF;
+       
+       if ( rregs.eax & 0xFF ) {
+               //printf( (1, "IPX error opening channel %d\n", socket_number-IPX_DEFAULT_SOCKET ));
+               return -2;
+       }
+
+       for (i=1; i<ipx_num_packets; i++ )      {
+               ipx_cancel_listen_for_packet(&packets[i].ecb);
+       }
+
+       // Close existing socket...
+       memset(&rregs,0,sizeof(dpmi_real_regs));
+       rregs.edx = ipx_socket;
+       rregs.ebx = 1;  // Close socket
+       dpmi_real_int386x( 0x7A, &rregs );
+
+       ipx_socket = new_ipx_socket;
+
+       // Repost all listen requests on the new socket...      
+       for (i=1; i<ipx_num_packets; i++ )      {
+               packets[i].ecb.in_use = 0;
+               packets[i].ecb.socket_id = ipx_socket;
+               ipx_listen_for_packet(&packets[i].ecb);
+       }
+
+       packets[0].ecb.socket_id = ipx_socket;
+       packets[0].ipx.destination.socket_id = ipx_socket;
+
+       ipx_packetnum = 0;
+       // init packet buffers.
+       for (i=0; i<MAX_PACKETS; i++ )  {
+               packet_buffers[i].packetnum = -1;
+               packet_free_list[i] = i;
+       }
+       num_packets = 0;
+       largest_packet_index = 0;
+
+       return 0;
+}
+
+void ipx_read_user_file(char * filename)
+{
+       FILE * fp;
+       user_address tmp;
+       char temp_line[132], *p1;
+       int n, ln=0;
+
+       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';
+                n = sscanf( temp_line, "%2x%2x%2x%2x/%2x%2x%2x%2x%2x%2x",(unsigned int *)&tmp.network[0],(unsigned int *) &tmp.network[1],(unsigned int *) &tmp.network[2],(unsigned int *) &tmp.network[3],(unsigned int *) &tmp.node[0],(unsigned int *) &tmp.node[1],(unsigned int *) &tmp.node[2],(unsigned int *)&tmp.node[3],(unsigned int *) &tmp.node[4],(unsigned int *) &tmp.node[5] );
+               if ( n != 10 ) continue;
+               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;
+
+       if (!filename) return;
+
+       fp = fopen( filename, "rt" );
+       if ( !fp ) return;
+
+       printf( "Using Networks:\n" );
+       for (i=0; i<Ipx_num_networks; i++ )             {
+               ubyte * n1 = (ubyte *)&Ipx_networks[i];
+               printf("* %02x%02x%02x%02x\n", n1[0], n1[1], n1[2], n1[3] );
+       }
+
+       while (fgets(temp_line, 132, fp)) {
+               ln++;
+               p1 = strchr(temp_line,'\n'); if (p1) *p1 = '\0';
+               p1 = strchr(temp_line,';'); if (p1) *p1 = '\0';
+                n = sscanf( temp_line, "%2x%2x%2x%2x",(unsigned int *) &tmp.network[0],(unsigned int *) &tmp.network[1],(unsigned int *) &tmp.network[2],(unsigned int *) &tmp.network[3] );
+               if ( n != 4 ) continue;
+               if ( Ipx_num_networks < MAX_NETWORKS  ) {
+                       int j;
+                       for (j=0; j<Ipx_num_networks; j++ )     
+                               if ( !memcmp( &Ipx_networks[j], tmp.network, 4 ) )
+                                       break;
+                       if ( 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);
+
+}
+
+//---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 (file)
index 0000000..d85f061
--- /dev/null
@@ -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 (file)
index 0000000..e738fe6
--- /dev/null
@@ -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 (file)
index 0000000..4523ba0
--- /dev/null
@@ -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 (file)
index 0000000..fd965b5
--- /dev/null
@@ -0,0 +1,140 @@
+#include <conf.h>
+#ifdef __ENV_DJGPP__
+
+
+#include <string.h>
+#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 (file)
index 0000000..5434bfd
--- /dev/null
@@ -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
index c0749e0..4c991ca 100644 (file)
@@ -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
index 66efad5..48a44fe 100644 (file)
@@ -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:
index 70ab4ed..6fcb350 100644 (file)
@@ -1,4 +1,6 @@
 #include <conf.h>
+#ifdef __ENV_LINUX__
+
 #include <stdlib.h>
 #include <string.h>
 #include <glob.h>
@@ -51,3 +53,6 @@ int FileFindClose(void)
  globfree(&glob_a);
  return 0;
 }
+
+
+#endif // __ENV_LINUX__
index 3d4fa7e..41330ae 100644 (file)
@@ -1,5 +1,7 @@
 // linux init.c - added Matt Mueller 9/6/98
 #include <conf.h>
+#ifdef __ENV_LINUX__
+
 #include <stdlib.h>
 #include <stdio.h>
 #include "pstypes.h"
@@ -44,3 +46,6 @@ void arch_init()
        //end addition -MM
     key_init();
 }
+
+
+#endif // __ENV_LINUX__
index 9e78b86..de7f671 100644 (file)
@@ -1,6 +1,7 @@
 /* IPX driver using BSD style sockets */
 /* Mostly taken from dosemu */
 #include <conf.h>
+#ifdef __ENV_LINUX__
 #ifdef NETWORK
 
 #include <stdio.h>
@@ -226,3 +227,4 @@ struct ipx_driver ipx_bsd = {
        ipx_general_PacketReady
 };
 #endif // NETWORK
+#endif // __ENV_LINUX__
index 91ab95a..459d420 100644 (file)
@@ -1,4 +1,7 @@
 #include <conf.h>
+
+#ifdef __ENV_LINUX__
+
 #ifdef NETWORK
 #include <stdio.h>
 #include <sys/types.h>
@@ -212,3 +215,4 @@ int ipx_linux_ReceivePacket(ipx_socket_t *s, char *buffer, int bufsize,
        return size;
 }
 #endif // NETWORK
+#endif // __ENV_LINUX__
index c369a28..48a1125 100644 (file)
@@ -59,6 +59,7 @@
  */
 
 #include <conf.h>
+#ifdef __ENV_LINUX__
 #ifdef NETWORK
 #include <stdio.h>
 #include <string.h>
@@ -589,3 +590,4 @@ struct ipx_driver ipx_udp = {
        ipx_general_PacketReady
 };
 #endif // NETWORK
+#endif // __ENV_LINUX__
index c06b938..e96f724 100644 (file)
@@ -12,6 +12,7 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
 */
 #include <conf.h>
 
+#ifdef __ENV_LINUX__
 #ifdef NETWORK
 #include <stdlib.h>
 #include <stdio.h>
@@ -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 (file)
index 0000000..6fcb350
--- /dev/null
@@ -0,0 +1,58 @@
+#include <conf.h>
+#ifdef __ENV_LINUX__
+
+#include <stdlib.h>
+#include <string.h>
+#include <glob.h>
+#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 (file)
index 0000000..41330ae
--- /dev/null
@@ -0,0 +1,51 @@
+// linux init.c - added Matt Mueller 9/6/98
+#include <conf.h>
+#ifdef __ENV_LINUX__
+
+#include <stdlib.h>
+#include <stdio.h>
+#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 (file)
index 0000000..de7f671
--- /dev/null
@@ -0,0 +1,230 @@
+/* IPX driver using BSD style sockets */
+/* Mostly taken from dosemu */
+#include <conf.h>
+#ifdef __ENV_LINUX__
+#ifdef NETWORK
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <string.h>
+
+#ifdef HAVE_NETIPX_IPX_H
+#include <netipx/ipx.h>
+#else
+# include <linux/ipx.h>
+# ifndef IPX_TYPE
+#  define IPX_TYPE 1
+# endif
+#endif
+
+#include <netinet/in.h>
+#include <unistd.h>
+#include <errno.h>
+
+#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 (file)
index 0000000..459d420
--- /dev/null
@@ -0,0 +1,218 @@
+#include <conf.h>
+
+#ifdef __ENV_LINUX__
+
+#ifdef NETWORK
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <string.h>
+
+#ifdef HAVE_NETIPX_IPX_H
+#include <netipx/ipx.h>
+#else
+# include <linux/ipx.h>
+# ifndef IPX_TYPE
+#  define IPX_TYPE 1
+# endif
+#endif
+
+#include <netinet/in.h>
+#include <unistd.h>
+#include <errno.h>
+#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 (file)
index 0000000..48a1125
--- /dev/null
@@ -0,0 +1,593 @@
+/* IPX driver for native Linux TCP/IP networking (UDP implementation)
+ *   Version 0.99.2
+ * Contact Jan [Lace] Kratochvil <short@ucw.cz> for assistance
+ * (no "It somehow doesn't work! What should I do?" complaints, please)
+ * Special thanks to Vojtech Pavlik <vojtech@ucw.cz> 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 <jay@kali.net>.
+ * 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 <conf.h>
+#ifdef __ENV_LINUX__
+#ifdef NETWORK
+#include <stdio.h>
+#include <string.h>
+#include <netinet/in.h> /* for htons & co. */
+#include <unistd.h>
+#include <stdarg.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <ctype.h>
+
+#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