]> 4ch.mooo.com Git - 16.git/commitdiff
wwww
authorsparky4 <sparky4@cock.li>
Wed, 9 Dec 2015 16:31:09 +0000 (10:31 -0600)
committersparky4 <sparky4@cock.li>
Wed, 9 Dec 2015 16:31:09 +0000 (10:31 -0600)
43 files changed:
16/mxbb.asm [new file with mode: 0755]
16/x/MODEX.BAK [deleted file]
16/x/MODEX.LBR
16/x/makefile.wat [new file with mode: 0755]
16/x/modex.lbr
16/xw/modex/demo01.c [new file with mode: 0755]
16/xw/mxbb.asm
16/xw_/default.fnt [new file with mode: 0755]
16/xw_/makefile [new file with mode: 0755]
16/xw_/makefile.bcc [new file with mode: 0755]
16/xw_/modex.bak [moved from 16/x/modex.bak with 100% similarity]
16/xw_/modex.def [new file with mode: 0755]
16/xw_/modex.h [new file with mode: 0755]
16/xw_/modex.lbr [new file with mode: 0755]
16/xw_/modex.pas [new file with mode: 0755]
16/xw_/modex/DEMO01.EXE [new file with mode: 0755]
16/xw_/modex/DEMO01.PAS [new file with mode: 0755]
16/xw_/modex/DEMO02.EXE [new file with mode: 0755]
16/xw_/modex/DEMO02.PAS [new file with mode: 0755]
16/xw_/modex/DEMO03.EXE [new file with mode: 0755]
16/xw_/modex/DEMO03.PAS [new file with mode: 0755]
16/xw_/modex/DEMO04.DAT [new file with mode: 0755]
16/xw_/modex/DEMO04.EXE [new file with mode: 0755]
16/xw_/modex/DEMO04.PAS [new file with mode: 0755]
16/xw_/modex/DEMO05.EXE [new file with mode: 0755]
16/xw_/modex/DEMO05.PAS [new file with mode: 0755]
16/xw_/modex/DEMO06.DAT [new file with mode: 0755]
16/xw_/modex/DEMO06.EXE [new file with mode: 0755]
16/xw_/modex/DEMO06.PAS [new file with mode: 0755]
16/xw_/modex/DEMO07.EXE [new file with mode: 0755]
16/xw_/modex/DEMO07.PAS [new file with mode: 0755]
16/xw_/modex/MATH.INC [new file with mode: 0755]
16/xw_/modex/PLASMA.PAS [new file with mode: 0755]
16/xw_/modex/QIX2.EXE [new file with mode: 0755]
16/xw_/modex/QIX2.PAS [new file with mode: 0755]
16/xw_/modex/README.TXT [new file with mode: 0755]
16/xw_/modex/SINCOS.INC [new file with mode: 0755]
16/xw_/modex/THREED.ASM [new file with mode: 0755]
16/xw_/modex/THREED.H [new file with mode: 0755]
16/xw_/modex/THREED.PAS [new file with mode: 0755]
16/xw_/modex/demo01.c [new file with mode: 0755]
16/xw_/readme.txt [new file with mode: 0755]
makefile

diff --git a/16/mxbb.asm b/16/mxbb.asm
new file mode 100755 (executable)
index 0000000..a403c63
--- /dev/null
@@ -0,0 +1,208 @@
+.387
+               PUBLIC  MXBITBLT
+               EXTRN   SUBHORIZONTALLINEINFO:BYTE
+               EXTRN   MX_VIDEOSEGMENT:BYTE
+               EXTRN   MX_BYTESPERLINE:BYTE
+MX_TEXT                SEGMENT PARA PUBLIC USE16 'CODE'
+               ASSUME CS:MX_TEXT, DS:DGROUP, SS:DGROUP
+MXBITBLT:
+       push            bp
+       mov             bp,sp
+       sub             sp,16H
+       push            ds
+       push            si
+       push            es
+       push            di
+       cmp             word ptr 0cH[bp],0
+       je              L$2
+       mov             ax,word ptr 10H[bp]
+       and             al,3
+       mov             dx,word ptr 8[bp]
+       and             dl,3
+       mov             bx,offset L$10
+       cmp             al,dl
+       jne             L$1
+       mov             bx,offset L$3
+L$1:
+       call            bx
+L$2:
+       xor             ax,ax
+       pop             di
+       pop             es
+       pop             si
+       pop             ds
+       mov             sp,bp
+       pop             bp
+       retf            0cH
+L$3:
+       mov             bx,word ptr 8[bp]
+       mov             ax,word ptr 6[bp]
+       mov             cx,word ptr 0cH[bp]
+       call            near ptr MX_TEXT:SUBHORIZONTALLINEINFO
+       mov             byte ptr -14H[bp],al
+       mov             byte ptr -16H[bp],ah
+       mov             word ptr 0cH[bp],cx
+       mov             ax,word ptr cs:MX_VIDEOSEGMENT
+       mov             ds,ax
+       mov             es,ax
+       mov             ax,word ptr 0eH[bp]
+       mul             word ptr cs:MX_BYTESPERLINE
+       mov             si,word ptr 10H[bp]
+       shr             si,1
+       shr             si,1
+       add             si,ax
+       mov             dx,3ceH
+       mov             ax,4105H
+       out             dx,ax
+       cld
+       mov             ah,byte ptr -14H[bp]
+       or              ah,ah
+       je              L$5
+       mov             dx,3c4H
+       mov             al,2
+       out             dx,ax
+       mov             ax,word ptr cs:MX_BYTESPERLINE
+       dec             ax
+       mov             cx,word ptr 0aH[bp]
+       push            si
+       push            di
+L$4:
+       movsb
+       add             si,ax
+       add             di,ax
+       dec             cx
+       jne             L$4
+       pop             di
+       pop             si
+       inc             si
+       inc             di
+L$5:
+       mov             bx,word ptr 0cH[bp]
+       test            bx,bx
+       je              L$7
+       mov             dx,3c4H
+       mov             ax,0f02H
+       out             dx,ax
+       mov             ax,word ptr cs:MX_BYTESPERLINE
+       sub             ax,bx
+       mov             dx,word ptr 0aH[bp]
+       push            si
+       push            di
+L$6:
+       mov             cx,bx
+       rep movsb
+       add             si,ax
+       add             di,ax
+       dec             dx
+       jne             L$6
+       pop             di
+       pop             si
+       add             si,bx
+       add             di,bx
+L$7:
+       mov             ah,byte ptr -16H[bp]
+       or              ah,ah
+       je              L$9
+       mov             dx,3c4H
+       mov             al,2
+       out             dx,ax
+       mov             ax,word ptr cs:MX_BYTESPERLINE
+       dec             ax
+       mov             cx,word ptr 0aH[bp]
+L$8:
+       movsb
+       add             si,ax
+       add             di,ax
+       dec             cx
+       jne             L$8
+L$9:
+       mov             dx,3ceH
+       mov             ax,4005H
+       out             dx,ax
+       ret
+L$10:
+       mov             cx,word ptr 0cH[bp]
+       mov             bx,cx
+       shr             bx,1
+       shr             bx,1
+       and             cl,3
+       mov             al,8
+       shr             al,cl
+       mov             si,6
+L$11:
+       mov             word ptr -8[bp+si],bx
+       shr             al,1
+       adc             bx,0
+       dec             si
+       dec             si
+       jge             L$11
+       mov             ax,word ptr cs:MX_VIDEOSEGMENT
+       mov             ds,ax
+       mov             es,ax
+       mov             ax,word ptr 0eH[bp]
+       mul             word ptr cs:MX_BYTESPERLINE
+       mov             si,word ptr 10H[bp]
+       shr             si,1
+       shr             si,1
+       add             si,ax
+       mov             word ptr -0aH[bp],si
+       mov             ax,word ptr 6[bp]
+       mul             word ptr cs:MX_BYTESPERLINE
+       mov             di,word ptr 8[bp]
+       shr             di,1
+       shr             di,1
+       add             di,ax
+       mov             word ptr -0cH[bp],di
+       mov             ax,word ptr 10H[bp]
+       and             al,3
+       mov             byte ptr -10H[bp],al
+       mov             cx,word ptr 8[bp]
+       and             cl,3
+       mov             al,11H
+       shl             al,cl
+       mov             byte ptr -12H[bp],al
+       cld
+       mov             byte ptr -0eH[bp],4
+       lea             bx,-8[bp]
+L$12:
+       cmp             word ptr ss:[bx],0
+       je              L$15
+       mov             ah,byte ptr -12H[bp]
+       and             ah,0fH
+       mov             al,2
+       mov             dx,3c4H
+       out             dx,ax
+       mov             ah,byte ptr -10H[bp]
+       mov             al,4
+       mov             dx,3ceH
+       out             dx,ax
+       mov             dx,word ptr 0aH[bp]
+       mov             ax,word ptr cs:MX_BYTESPERLINE
+       sub             ax,word ptr ss:[bx]
+L$13:
+       mov             cx,word ptr ss:[bx]
+       shr             cx,1
+       rep movsw
+       rcl             cx,1
+       rep movsb
+       add             si,ax
+       add             di,ax
+       dec             dx
+       jne             L$13
+       inc             bx
+       inc             bx
+       inc             byte ptr -10H[bp]
+       and             byte ptr -10H[bp],3
+       jne             L$14
+       inc             word ptr -0aH[bp]
+L$14:
+       rol             byte ptr -12H[bp],1
+       adc             word ptr -0cH[bp],0
+       mov             si,word ptr -0aH[bp]
+       mov             di,word ptr -0cH[bp]
+       dec             byte ptr -0eH[bp]
+       jne             L$12
+L$15:
+       ret
+MX_TEXT                ENDS
+               END
diff --git a/16/x/MODEX.BAK b/16/x/MODEX.BAK
deleted file mode 100755 (executable)
index 560a1c6..0000000
Binary files a/16/x/MODEX.BAK and /dev/null differ
index 93fc78010fd4f29fa241364ff2bd21d6cbbc9ac9..b1ec26b6e76c2ce8588a1b574c6eeef593005221 100755 (executable)
@@ -21,7 +21,6 @@
 +-MXPI.OBJ &\r
 +-MXPN.OBJ &\r
 +-MXPP.OBJ &\r
-+-MXPT.OBJ &\r
 +-MXRA.OBJ &\r
 +-MXRP.OBJ &\r
 +-MXSA.OBJ &\r
diff --git a/16/x/makefile.wat b/16/x/makefile.wat
new file mode 100755 (executable)
index 0000000..7d76ead
--- /dev/null
@@ -0,0 +1,59 @@
+!ifdef __LINUX__
+REMOVECOMMAND=rm -f
+COPYCOMMAND=cp -f
+DIRSEP=/
+OBJ=o
+!else
+REMOVECOMMAND=del
+COPYCOMMAND=copy /y
+DIRSEP=\
+OBJ=obj
+!endif
+
+TARGET_OS = dos
+
+DISS=wdis -a
+REDR=">" ..$(DIRSEP)xw_$(DIRSEP)
+
+all:
+       @beep
+
+pee: .symbolic
+$(DISS) MXBB.OBJ $(REDR)mxbb.asm
+$(DISS) MXCC.OBJ $(REDR)mxcc.asm
+$(DISS) MXCG.OBJ $(REDR)mxcg.asm
+$(DISS) MXCL.OBJ $(REDR)mxcl.asm
+$(DISS) MXCR.OBJ $(REDR)mxcl.asm
+$(DISS) MXFB.OBJ $(REDR)mxfb.asm
+$(DISS) MXFP.OBJ $(REDR)mxfp.asm
+$(DISS) MXGC.OBJ $(REDR)mxgc.asm
+$(DISS) MXGI.OBJ $(REDR)mxgi.asm
+$(DISS) MXGM.OBJ $(REDR)mxgm.asm
+$(DISS) MXGP.OBJ $(REDR)mxgp.asm
+$(DISS) MXGV.OBJ $(REDR)mxgv.asm
+$(DISS) MXHL.OBJ $(REDR)mxhl.asm
+$(DISS) MXIT.OBJ $(REDR)mxit.asm
+$(DISS) MXLL.OBJ $(REDR)mxll.asm
+$(DISS) MXLN.OBJ $(REDR)mxln.asm
+$(DISS) MXOT.OBJ $(REDR)mxot.asm
+$(DISS) MXPB.OBJ $(REDR)mxpb.asm
+$(DISS) MXPF.OBJ $(REDR)mxpf.asm
+$(DISS) MXPG.OBJ $(REDR)mxpg.asm
+$(DISS) MXPI.OBJ $(REDR)mxpi.asm
+$(DISS) MXPN.OBJ $(REDR)mxpn.asm
+$(DISS) MXPP.OBJ $(REDR)mxpp.asm
+$(DISS) MXRA.OBJ $(REDR)mxra.asm
+$(DISS) MXRP.OBJ $(REDR)mxrp.asm
+$(DISS) MXSA.OBJ $(REDR)mxsa.asm
+$(DISS) MXSC.OBJ $(REDR)mxsc.asm
+$(DISS) MXSI.OBJ $(REDR)mxsi.asm
+$(DISS) MXSL.OBJ $(REDR)mxsl.asm
+$(DISS) MXSM.OBJ $(REDR)mxsm.asm
+$(DISS) MXSP.OBJ $(REDR)mxsp.asm
+$(DISS) MXSS.OBJ $(REDR)mxss.asm
+$(DISS) MXTL.OBJ $(REDR)mxtl.asm
+$(DISS) MXVS.OBJ $(REDR)mxvs.asm
+$(DISS) MXWD.OBJ $(REDR)mxwd.asm
+$(DISS) MXWM.OBJ $(REDR)mxwm.asm
+$(DISS) MXWP.OBJ $(REDR)mxwp.asm
+$(DISS) MXWR.OBJ $(REDR)mxwr.asm
index 93fc78010fd4f29fa241364ff2bd21d6cbbc9ac9..b1ec26b6e76c2ce8588a1b574c6eeef593005221 100755 (executable)
@@ -21,7 +21,6 @@
 +-MXPI.OBJ &\r
 +-MXPN.OBJ &\r
 +-MXPP.OBJ &\r
-+-MXPT.OBJ &\r
 +-MXRA.OBJ &\r
 +-MXRP.OBJ &\r
 +-MXSA.OBJ &\r
diff --git a/16/xw/modex/demo01.c b/16/xw/modex/demo01.c
new file mode 100755 (executable)
index 0000000..0908fdf
--- /dev/null
@@ -0,0 +1,125 @@
+/*\r
+    DEMO01 - Sprites, page flipping and palette rotation\r
+    Copyright (c) 1994 Alessandro Scotti\r
+*/\r
+uses Crt, Modex;\r
+\r
+#DEFINE MAX_SPRITE 100\r
+type\r
+  (* Sprite structure *)\r
+  TSprite = record\r
+    X, Y : integer;                        (* Sprite coordinates *)\r
+    DX,DY: integer;                        (* Deltas for sprite movement *)\r
+    W, H : integer;                        (* Sprite width and height *)\r
+    Image: array[ 1..16, 1..16 ] of byte;  (* Sprite image data *)\r
+  end;\r
+  (* RGB color structure *)\r
+  TRgb    = record\r
+    R, G, B: byte;\r
+  end;\r
+var\r
+  S      : array[ 1..MAX_SPRITE ] of TSprite;   (* An array of sprites *)\r
+  Palette: array[ byte ] of TRgb;               (* Palette *)\r
+  Page   : word;                                (* Page offset *)\r
+  I      : word;\r
+\r
+(* Initializes a sprite structure *)\r
+procedure sxInit( var S: TSprite );\r
+var\r
+  I: word;\r
+begin\r
+  S.X := Random( 320 );  (* Initialize position with random values *)\r
+  S.Y := Random( 240 );\r
+  S.DX := Random( 7 )-3; (* Initialize speed with random values *)\r
+  S.DY := Random( 7 )-3;\r
+  S.W := 16;             (* Size is fixed in this program *)\r
+  S.H := 16;\r
+  (* The image is a square with a hole inside *)\r
+  FillChar( S.Image, SizeOf(S.Image), Random(15)+1 );\r
+  for I:=5 to 12 do FillChar( S.Image[ I, 5 ], 8, 0 );\r
+end;\r
+\r
+(* Moves a sprite *)\r
+procedure sxMove( var S: TSprite );\r
+begin\r
+  Inc( S.X, S.DX );     (* Get new position *)\r
+  Inc( S.Y, S.DY );\r
+  (* Check sprite position, change delta if needed *)\r
+  if( S.X > 320 ) then begin\r
+    S.X := 320;\r
+    S.DX := -S.DX;\r
+  end;\r
+  if( S.X < -16 ) then begin\r
+    S.X := -16;\r
+    S.DX := -S.DX;\r
+  end;\r
+  if( S.Y > 240 ) then begin\r
+    S.Y := 240;\r
+    S.DY := -S.DY;\r
+  end;\r
+  if( S.Y < -16 ) then begin\r
+    S.Y := -16;\r
+    S.DY := -S.DY;\r
+  end;\r
+  (* Draw the sprite, note the Page offset added to the *)\r
+  (* Y coordinate of the image *)\r
+  mxPutImage( @S.Image, S.X, Page+S.Y, S.W, S.H, OP_TRANS );\r
+end;\r
+\r
+begin\r
+  (* Initialize library *)\r
+  mxInit;\r
+\r
+  (* Enter graphics mode *)\r
+  mxSetMode( MX_320x240 );\r
+\r
+  (* Print initialization message *)\r
+  mxSetTextColor( 15, OP_TRANS );\r
+  mxOutStr( 4, 4, 'Initializing...' );\r
+\r
+  (* Initialize sprites *)\r
+  for I:=1 to MAX_SPRITE do sxInit( S[I] );\r
+\r
+  (* Draw background *)\r
+  for I:=1 to 192 do begin\r
+    mxCircle( 160, 480+120, I, I+63 );\r
+    mxCircle( 161, 480+120, I, I+63 );\r
+  end;\r
+\r
+  (* Compute and set palette *)\r
+  for I:=1 to 192 do with Palette[I+63] do begin\r
+    R := 0;\r
+    G := 0;\r
+    B := 0;\r
+    if( I < 64 ) then\r
+      R := I shr 1+31\r
+    else if( I < 128 ) then\r
+      G := (I-64) shr 1+31\r
+    else\r
+      B := (I-128) shr 1+31;\r
+  end;\r
+  mxSetPalette( @Palette[64], 64, 192 );\r
+\r
+  (* Main loop *)\r
+  Page := 240;\r
+  while( not KeyPressed ) do begin\r
+    (* Set clip region to current page *)\r
+    mxSetClipRegion( 0, Page, 320, 240 );\r
+    mxSetClip( TRUE );\r
+    (* Restore background *)\r
+    mxBitBlt( 0, 480, 320, 240, 0, Page );\r
+    (* Draw sprites *)\r
+    for I:=1 to MAX_SPRITE do sxMove( S[I] );\r
+    (* Print message *)\r
+    mxOutStr( 4, Page+4, 'Some sprites moving...' );\r
+    (* Flip page *)\r
+    mxStartLine( Page );\r
+    Page := 240-Page;\r
+    (* Animate palette *)\r
+    mxSetPalette( @Palette[64], 64, 192 );\r
+    mxRotatePalette( @Palette[64], 192, 3 );\r
+  end;\r
+\r
+  mxSetMode( MX_TEXT );\r
+  mxTerm;\r
+end.\r
index 190fa7b270114f2f89fbc99a4ce64986780ed1b8..ed24a27c21102d91f872b8027893cf5fc9d5bf1c 100755 (executable)
@@ -47,7 +47,7 @@ mxBitBlt        PROC    FAR
                 WritePlane:BYTE,        \\r
                 LeftMask:BYTE,          \\r
                 RightMask:BYTE          = AUTO_SIZE\r
-        .enter  AUTO_SIZE\r
+       .enter  AUTO_SIZE\r
         .push   ds, si, es, di\r
 \r
 ; Exit now if null width\r
diff --git a/16/xw_/default.fnt b/16/xw_/default.fnt
new file mode 100755 (executable)
index 0000000..12eb22c
--- /dev/null
@@ -0,0 +1,260 @@
+;\r
+; MODEX library default font\r
+; Copyright (c) 1993-1994 by Alessandro Scotti\r
+;\r
+  DB    000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h  ; #0\r
+  DB   07Eh, 081h, 0A5h, 081h, 0A5h, 099h, 081h, 07Eh  ; #1\r
+  DB   07Eh, 0FFh, 0DBh, 0FFh, 0DBh, 0E7h, 0FFh, 07Eh  ; #2\r
+  DB   06Ch, 0FEh, 0FEh, 0FEh, 07Ch, 038h, 010h, 000h  ; #3\r
+  DB   010h, 038h, 07Ch, 0FEh, 07Ch, 038h, 010h, 000h  ; #4\r
+  DB   010h, 038h, 010h, 054h, 0FEh, 054h, 010h, 0FEh  ; #5\r
+  DB   010h, 038h, 07Ch, 0FEh, 0FEh, 07Ch, 010h, 0FEh  ; #6\r
+  DB   000h, 018h, 03Ch, 07Eh, 07Eh, 03Ch, 018h, 000h  ; #7\r
+  DB   0FFh, 0E7h, 0C3h, 081h, 081h, 0C3h, 0E7h, 0FFh  ; #8\r
+  DB   000h, 03Ch, 066h, 042h, 042h, 066h, 03Ch, 000h  ; #9\r
+  DB   0FFh, 0C3h, 099h, 0BDh, 0BDh, 099h, 0C3h, 0FFh  ; #10\r
+  DB   007h, 003h, 005h, 078h, 084h, 084h, 084h, 078h  ; #11\r
+  DB   07Ch, 082h, 082h, 082h, 07Ch, 010h, 038h, 010h  ; #12\r
+  DB   01Ch, 010h, 01Ch, 010h, 010h, 010h, 030h, 030h  ; #13\r
+  DB   03Eh, 022h, 03Eh, 022h, 022h, 026h, 066h, 060h  ; #14\r
+  DB   099h, 05Ah, 03Ch, 0E7h, 0E7h, 03Ch, 05Ah, 099h  ; #15\r
+  DB   000h, 010h, 030h, 070h, 0F0h, 070h, 030h, 010h  ; #16\r
+  DB   000h, 080h, 0C0h, 0E0h, 0F0h, 0E0h, 0C0h, 080h  ; #17\r
+  DB   010h, 038h, 054h, 010h, 010h, 054h, 038h, 010h  ; #18\r
+  DB   048h, 048h, 048h, 048h, 048h, 000h, 048h, 000h  ; #19\r
+  DB   07Eh, 092h, 092h, 072h, 012h, 012h, 012h, 000h  ; #20\r
+  DB   03Ch, 022h, 018h, 024h, 024h, 018h, 044h, 03Ch  ; #21\r
+  DB   000h, 000h, 000h, 000h, 000h, 03Eh, 03Eh, 000h  ; #22\r
+  DB   038h, 054h, 010h, 010h, 010h, 054h, 038h, 0FEh  ; #23\r
+  DB   000h, 010h, 038h, 054h, 010h, 010h, 010h, 000h  ; #24\r
+  DB   000h, 010h, 010h, 010h, 054h, 038h, 010h, 000h  ; #25\r
+  DB   000h, 008h, 004h, 0FEh, 004h, 008h, 000h, 000h  ; #26\r
+  DB   000h, 020h, 040h, 0FEh, 040h, 020h, 000h, 000h  ; #27\r
+  DB   000h, 000h, 080h, 080h, 080h, 0FCh, 000h, 000h  ; #28\r
+  DB   000h, 024h, 042h, 0FFh, 042h, 024h, 000h, 000h  ; #29\r
+  DB   000h, 000h, 010h, 038h, 07Ch, 0FEh, 000h, 000h  ; #30\r
+  DB   000h, 000h, 0FEh, 07Ch, 038h, 010h, 000h, 000h  ; #31\r
+  DB   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h  ;  \r
+  DB   010h, 010h, 010h, 010h, 010h, 000h, 010h, 000h  ; !\r
+  DB   000h, 024h, 024h, 000h, 000h, 000h, 000h, 000h  ; "\r
+  DB   024h, 024h, 07Eh, 024h, 07Eh, 024h, 024h, 000h  ; #\r
+  DB   038h, 054h, 050h, 038h, 014h, 054h, 038h, 010h  ; $\r
+  DB   000h, 002h, 044h, 008h, 010h, 020h, 042h, 000h  ; %\r
+  DB   038h, 044h, 038h, 060h, 094h, 088h, 074h, 000h  ; &\r
+  DB   020h, 020h, 040h, 000h, 000h, 000h, 000h, 000h  ; '\r
+  DB   010h, 020h, 040h, 040h, 040h, 020h, 010h, 000h  ; (\r
+  DB   040h, 020h, 010h, 010h, 010h, 020h, 040h, 000h  ; )\r
+  DB   000h, 024h, 018h, 07Eh, 018h, 024h, 000h, 000h  ; *\r
+  DB   000h, 010h, 010h, 07Ch, 010h, 010h, 000h, 000h  ; +\r
+  DB   000h, 000h, 000h, 000h, 000h, 010h, 010h, 020h  ; ,\r
+  DB   000h, 000h, 000h, 0FCh, 000h, 000h, 000h, 000h  ; -\r
+  DB   000h, 000h, 000h, 000h, 000h, 000h, 010h, 000h  ; .\r
+  DB   000h, 004h, 008h, 010h, 020h, 040h, 080h, 000h  ; /\r
+  DB   07Ch, 0C6h, 08Ah, 092h, 0A2h, 0C6h, 07Ch, 000h  ; 0\r
+  DB   010h, 030h, 010h, 010h, 010h, 010h, 038h, 000h  ; 1\r
+  DB   078h, 084h, 004h, 018h, 060h, 080h, 0FCh, 000h  ; 2\r
+  DB   078h, 084h, 004h, 038h, 004h, 084h, 078h, 000h  ; 3\r
+  DB   01Ch, 024h, 044h, 084h, 0FEh, 004h, 00Eh, 000h  ; 4\r
+  DB   0FCh, 080h, 0F8h, 004h, 004h, 084h, 078h, 000h  ; 5\r
+  DB   078h, 084h, 080h, 0F8h, 084h, 084h, 078h, 000h  ; 6\r
+  DB   0FCh, 004h, 004h, 008h, 010h, 020h, 020h, 000h  ; 7\r
+  DB   078h, 084h, 084h, 078h, 084h, 084h, 078h, 000h  ; 8\r
+  DB   078h, 084h, 084h, 07Ch, 004h, 084h, 078h, 000h  ; 9\r
+  DB   000h, 000h, 010h, 000h, 000h, 000h, 010h, 000h  ; :\r
+  DB   000h, 000h, 010h, 000h, 000h, 010h, 010h, 020h  ; ;\r
+  DB   008h, 010h, 020h, 040h, 020h, 010h, 008h, 000h  ; <\r
+  DB   000h, 000h, 0FCh, 000h, 000h, 0FCh, 000h, 000h  ; =\r
+  DB   040h, 020h, 010h, 008h, 010h, 020h, 040h, 000h  ; >\r
+  DB   078h, 084h, 004h, 008h, 010h, 000h, 010h, 000h  ; ?\r
+  DB   07Ch, 082h, 0BAh, 0A6h, 0BEh, 080h, 07Ch, 000h  ; @\r
+  DB   078h, 084h, 084h, 0FCh, 084h, 084h, 084h, 000h  ; A\r
+  DB   0F8h, 084h, 084h, 0F8h, 084h, 084h, 0F8h, 000h  ; B\r
+  DB   078h, 084h, 080h, 080h, 080h, 084h, 078h, 000h  ; C\r
+  DB   0F0h, 088h, 084h, 084h, 084h, 088h, 0F0h, 000h  ; D\r
+  DB   0FCh, 080h, 080h, 0F0h, 080h, 080h, 0FCh, 000h  ; E\r
+  DB   0FCh, 080h, 080h, 0F0h, 080h, 080h, 080h, 000h  ; F\r
+  DB   078h, 084h, 080h, 09Ch, 084h, 084h, 078h, 000h  ; G\r
+  DB   084h, 084h, 084h, 0FCh, 084h, 084h, 084h, 000h  ; H\r
+  DB   038h, 010h, 010h, 010h, 010h, 010h, 038h, 000h  ; I\r
+  DB   01Ch, 008h, 008h, 008h, 088h, 088h, 070h, 000h  ; J\r
+  DB   084h, 088h, 090h, 0E0h, 090h, 088h, 084h, 000h  ; K\r
+  DB   080h, 080h, 080h, 080h, 080h, 080h, 0FCh, 000h  ; L\r
+  DB   0C6h, 0AAh, 092h, 082h, 082h, 082h, 082h, 000h  ; M\r
+  DB   082h, 0C2h, 0A2h, 092h, 08Ah, 086h, 082h, 000h  ; N\r
+  DB   078h, 084h, 084h, 084h, 084h, 084h, 078h, 000h  ; O\r
+  DB   0F8h, 084h, 084h, 0F8h, 080h, 080h, 080h, 000h  ; P\r
+  DB   078h, 084h, 084h, 084h, 094h, 088h, 076h, 000h  ; Q\r
+  DB   0F8h, 084h, 084h, 0F8h, 090h, 088h, 084h, 000h  ; R\r
+  DB   078h, 084h, 080h, 078h, 004h, 084h, 078h, 000h  ; S\r
+  DB   0FEh, 010h, 010h, 010h, 010h, 010h, 010h, 000h  ; T\r
+  DB   084h, 084h, 084h, 084h, 084h, 084h, 078h, 000h  ; U\r
+  DB   084h, 084h, 084h, 084h, 084h, 048h, 030h, 000h  ; V\r
+  DB   082h, 082h, 082h, 082h, 092h, 0AAh, 0C6h, 000h  ; W\r
+  DB   082h, 044h, 028h, 010h, 028h, 044h, 082h, 000h  ; X\r
+  DB   044h, 044h, 044h, 038h, 010h, 010h, 010h, 000h  ; Y\r
+  DB   0FEh, 004h, 008h, 010h, 020h, 040h, 0FEh, 000h  ; Z\r
+  DB   078h, 040h, 040h, 040h, 040h, 040h, 078h, 000h  ; [\r
+  DB   000h, 080h, 040h, 020h, 010h, 008h, 004h, 000h  ; \\r
+  DB   078h, 008h, 008h, 008h, 008h, 008h, 078h, 000h  ; ]\r
+  DB   010h, 028h, 044h, 082h, 000h, 000h, 000h, 000h  ; ^\r
+  DB   000h, 000h, 000h, 000h, 000h, 000h, 000h, 0FFh  ; _\r
+  DB   020h, 020h, 010h, 000h, 000h, 000h, 000h, 000h  ; `\r
+  DB   000h, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h  ; a\r
+  DB   000h, 040h, 040h, 078h, 044h, 044h, 078h, 000h  ; b\r
+  DB   000h, 000h, 03Ch, 040h, 040h, 040h, 03Ch, 000h  ; c\r
+  DB   000h, 004h, 004h, 03Ch, 044h, 044h, 03Ch, 000h  ; d\r
+  DB   000h, 000h, 038h, 044h, 07Ch, 040h, 03Ch, 000h  ; e\r
+  DB   000h, 00Ch, 010h, 03Ch, 010h, 010h, 010h, 000h  ; f\r
+  DB   000h, 000h, 03Ch, 044h, 044h, 03Ch, 004h, 038h  ; g\r
+  DB   000h, 040h, 040h, 078h, 044h, 044h, 044h, 000h  ; h\r
+  DB   000h, 010h, 000h, 010h, 010h, 010h, 010h, 000h  ; i\r
+  DB   000h, 004h, 000h, 004h, 004h, 004h, 044h, 038h  ; j\r
+  DB   000h, 040h, 040h, 050h, 060h, 050h, 048h, 000h  ; k\r
+  DB   000h, 030h, 010h, 010h, 010h, 010h, 010h, 000h  ; l\r
+  DB   000h, 000h, 068h, 054h, 054h, 044h, 044h, 000h  ; m\r
+  DB   000h, 000h, 078h, 044h, 044h, 044h, 044h, 000h  ; n\r
+  DB   000h, 000h, 038h, 044h, 044h, 044h, 038h, 000h  ; o\r
+  DB   000h, 000h, 078h, 044h, 044h, 078h, 040h, 040h  ; p\r
+  DB   000h, 000h, 03Ch, 044h, 044h, 03Ch, 004h, 004h  ; q\r
+  DB   000h, 000h, 05Ch, 060h, 040h, 040h, 040h, 000h  ; r\r
+  DB   000h, 000h, 038h, 040h, 07Ch, 004h, 07Ch, 000h  ; s\r
+  DB   000h, 010h, 038h, 010h, 010h, 010h, 018h, 000h  ; t\r
+  DB   000h, 000h, 044h, 044h, 044h, 044h, 038h, 000h  ; u\r
+  DB   000h, 000h, 044h, 044h, 044h, 028h, 010h, 000h  ; v\r
+  DB   000h, 000h, 044h, 044h, 054h, 054h, 06Ch, 000h  ; w\r
+  DB   000h, 000h, 044h, 028h, 010h, 028h, 044h, 000h  ; x\r
+  DB   000h, 000h, 044h, 044h, 044h, 03Ch, 004h, 07Ch  ; y\r
+  DB   000h, 000h, 07Ch, 004h, 038h, 040h, 07Ch, 000h  ; z\r
+  DB   000h, 008h, 010h, 010h, 030h, 010h, 010h, 008h  ; {\r
+  DB   000h, 010h, 010h, 010h, 000h, 010h, 010h, 010h  ; |\r
+  DB   000h, 020h, 010h, 010h, 018h, 010h, 010h, 020h  ; }\r
+  DB   064h, 098h, 000h, 000h, 000h, 000h, 000h, 000h  ; ~\r
+  DB   000h, 010h, 028h, 044h, 082h, 082h, 0FEh, 000h  ; \7f\r
+  DB   07Ch, 080h, 080h, 080h, 080h, 07Ch, 004h, 07Ch  ; #128\r
+  DB   000h, 028h, 000h, 044h, 044h, 044h, 038h, 000h  ; #129\r
+  DB   03Ch, 000h, 07Ch, 044h, 07Ch, 040h, 07Ch, 000h  ; #130\r
+  DB   07Eh, 081h, 038h, 004h, 03Ch, 044h, 07Ch, 000h  ; #131\r
+  DB   024h, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h  ; #132\r
+  DB   078h, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h  ; #133\r
+  DB   018h, 018h, 038h, 004h, 03Ch, 044h, 07Ch, 000h  ; #134\r
+  DB   000h, 000h, 078h, 080h, 080h, 078h, 008h, 038h  ; #135\r
+  DB   07Ch, 082h, 038h, 044h, 07Ch, 040h, 03Ch, 000h  ; #136\r
+  DB   048h, 000h, 038h, 044h, 07Ch, 040h, 03Ch, 000h  ; #137\r
+  DB   078h, 000h, 038h, 044h, 07Ch, 040h, 03Ch, 000h  ; #138\r
+  DB   000h, 028h, 000h, 010h, 010h, 010h, 010h, 000h  ; #139\r
+  DB   010h, 028h, 000h, 010h, 010h, 010h, 010h, 000h  ; #140\r
+  DB   000h, 030h, 000h, 010h, 010h, 010h, 010h, 000h  ; #141\r
+  DB   048h, 000h, 078h, 084h, 0FCh, 084h, 084h, 000h  ; #142\r
+  DB   030h, 030h, 078h, 084h, 0FCh, 084h, 084h, 000h  ; #143\r
+  DB   038h, 000h, 0FCh, 080h, 0F0h, 080h, 0FCh, 000h  ; #144\r
+  DB   000h, 000h, 07Eh, 008h, 07Eh, 048h, 07Eh, 000h  ; #145\r
+  DB   07Eh, 090h, 090h, 0FCh, 090h, 090h, 09Eh, 000h  ; #146\r
+  DB   07Ch, 082h, 038h, 044h, 044h, 044h, 038h, 000h  ; #147\r
+  DB   028h, 000h, 038h, 044h, 044h, 044h, 038h, 000h  ; #148\r
+  DB   070h, 000h, 038h, 044h, 044h, 044h, 038h, 000h  ; #149\r
+  DB   038h, 044h, 000h, 044h, 044h, 044h, 038h, 000h  ; #150\r
+  DB   070h, 000h, 044h, 044h, 044h, 044h, 038h, 000h  ; #151\r
+  DB   028h, 000h, 044h, 044h, 044h, 03Ch, 004h, 07Ch  ; #152\r
+  DB   048h, 000h, 078h, 084h, 084h, 084h, 078h, 000h  ; #153\r
+  DB   048h, 000h, 084h, 084h, 084h, 084h, 078h, 000h  ; #154\r
+  DB   000h, 010h, 038h, 040h, 040h, 040h, 038h, 010h  ; #155\r
+  DB   038h, 044h, 040h, 0E0h, 040h, 040h, 082h, 0FCh  ; #156\r
+  DB   044h, 07Ch, 010h, 07Ch, 010h, 07Ch, 010h, 000h  ; #157\r
+  DB   0F0h, 088h, 08Ah, 0F7h, 082h, 082h, 082h, 000h  ; #158\r
+  DB   00Ch, 012h, 010h, 018h, 030h, 010h, 090h, 060h  ; #159\r
+  DB   03Ch, 000h, 038h, 004h, 03Ch, 044h, 07Ch, 000h  ; #160\r
+  DB   000h, 018h, 000h, 010h, 010h, 010h, 010h, 000h  ; #161\r
+  DB   01Ch, 000h, 038h, 044h, 044h, 044h, 038h, 000h  ; #162\r
+  DB   01Ch, 000h, 044h, 044h, 044h, 044h, 038h, 000h  ; #163\r
+  DB   07Ch, 000h, 078h, 044h, 044h, 044h, 044h, 000h  ; #164\r
+  DB   07Ch, 000h, 044h, 064h, 054h, 04Ch, 044h, 000h  ; #165\r
+  DB   018h, 024h, 024h, 01Eh, 000h, 03Eh, 000h, 000h  ; #166\r
+  DB   01Ch, 022h, 022h, 01Ch, 000h, 03Eh, 000h, 000h  ; #167\r
+  DB   010h, 000h, 010h, 020h, 040h, 042h, 03Ch, 000h  ; #168\r
+  DB   000h, 000h, 000h, 0FCh, 080h, 080h, 000h, 000h  ; #169\r
+  DB   000h, 000h, 000h, 0FCh, 004h, 004h, 000h, 000h  ; #170\r
+  DB   040h, 044h, 048h, 057h, 021h, 047h, 004h, 007h  ; #171\r
+  DB   040h, 044h, 048h, 052h, 026h, 04Ah, 01Fh, 002h  ; #172\r
+  DB   010h, 000h, 010h, 010h, 010h, 010h, 010h, 000h  ; #173\r
+  DB   000h, 024h, 048h, 090h, 048h, 024h, 000h, 000h  ; #174\r
+  DB   000h, 048h, 024h, 012h, 024h, 048h, 000h, 000h  ; #175\r
+  DB   022h, 088h, 022h, 088h, 022h, 088h, 022h, 088h  ; #176\r
+  DB   055h, 0AAh, 055h, 0AAh, 055h, 0AAh, 055h, 0AAh  ; #177\r
+  DB   0DBh, 077h, 0DBh, 0EEh, 0DBh, 077h, 0DBh, 0EEh  ; #178\r
+  DB   018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h  ; #179\r
+  DB   018h, 018h, 018h, 018h, 0F8h, 018h, 018h, 018h  ; #180\r
+  DB   018h, 018h, 0F8h, 018h, 0F8h, 018h, 018h, 018h  ; #181\r
+  DB   036h, 036h, 036h, 036h, 0F6h, 036h, 036h, 036h  ; #182\r
+  DB   000h, 000h, 000h, 000h, 0FEh, 036h, 036h, 036h  ; #183\r
+  DB   000h, 000h, 0F8h, 018h, 0F8h, 018h, 018h, 018h  ; #184\r
+  DB   036h, 036h, 0F6h, 006h, 0F6h, 036h, 036h, 036h  ; #185\r
+  DB   036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h  ; #186\r
+  DB   000h, 000h, 0FEh, 006h, 0F6h, 036h, 036h, 036h  ; #187\r
+  DB   036h, 036h, 0F6h, 006h, 0FEh, 000h, 000h, 000h  ; #188\r
+  DB   036h, 036h, 036h, 036h, 0FEh, 000h, 000h, 000h  ; #189\r
+  DB   018h, 018h, 0F8h, 018h, 0F8h, 000h, 000h, 000h  ; #190\r
+  DB   000h, 000h, 000h, 000h, 0F8h, 018h, 018h, 018h  ; #191\r
+  DB   018h, 018h, 018h, 018h, 01Fh, 000h, 000h, 000h  ; #192\r
+  DB   018h, 018h, 018h, 018h, 0FFh, 000h, 000h, 000h  ; #193\r
+  DB   000h, 000h, 000h, 000h, 0FFh, 018h, 018h, 018h  ; #194\r
+  DB   018h, 018h, 018h, 018h, 01Fh, 018h, 018h, 018h  ; #195\r
+  DB   000h, 000h, 000h, 000h, 0FFh, 000h, 000h, 000h  ; #196\r
+  DB   018h, 018h, 018h, 018h, 0FFh, 018h, 018h, 018h  ; #197\r
+  DB   018h, 018h, 01Fh, 018h, 01Fh, 018h, 018h, 018h  ; #198\r
+  DB   036h, 036h, 036h, 036h, 037h, 036h, 036h, 036h  ; #199\r
+  DB   036h, 036h, 037h, 030h, 03Fh, 000h, 000h, 000h  ; #200\r
+  DB   000h, 000h, 03Fh, 030h, 037h, 036h, 036h, 036h  ; #201\r
+  DB   036h, 036h, 0F7h, 000h, 0FFh, 000h, 000h, 000h  ; #202\r
+  DB   000h, 000h, 0FFh, 000h, 0F7h, 036h, 036h, 036h  ; #203\r
+  DB   036h, 036h, 037h, 030h, 037h, 036h, 036h, 036h  ; #204\r
+  DB   000h, 000h, 0FFh, 000h, 0FFh, 000h, 000h, 000h  ; #205\r
+  DB   036h, 036h, 0F7h, 000h, 0F7h, 036h, 036h, 036h  ; #206\r
+  DB   018h, 018h, 0FFh, 000h, 0FFh, 000h, 000h, 000h  ; #207\r
+  DB   036h, 036h, 036h, 036h, 0FFh, 000h, 000h, 000h  ; #208\r
+  DB   000h, 000h, 0FFh, 000h, 0FFh, 018h, 018h, 018h  ; #209\r
+  DB   000h, 000h, 000h, 000h, 0FFh, 036h, 036h, 036h  ; #210\r
+  DB   036h, 036h, 036h, 036h, 03Fh, 000h, 000h, 000h  ; #211\r
+  DB   018h, 018h, 01Fh, 018h, 01Fh, 000h, 000h, 000h  ; #212\r
+  DB   000h, 000h, 01Fh, 018h, 01Fh, 018h, 018h, 018h  ; #213\r
+  DB   000h, 000h, 000h, 000h, 03Fh, 036h, 036h, 036h  ; #214\r
+  DB   036h, 036h, 036h, 036h, 0FFh, 036h, 036h, 036h  ; #215\r
+  DB   018h, 018h, 0FFh, 018h, 0FFh, 018h, 018h, 018h  ; #216\r
+  DB   018h, 018h, 018h, 018h, 0F8h, 000h, 000h, 000h  ; #217\r
+  DB   000h, 000h, 000h, 000h, 01Fh, 018h, 018h, 018h  ; #218\r
+  DB   0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh  ; #219\r
+  DB   000h, 000h, 000h, 000h, 0FFh, 0FFh, 0FFh, 0FFh  ; #220\r
+  DB   0F0h, 0F0h, 0F0h, 0F0h, 0F0h, 0F0h, 0F0h, 0F0h  ; #221\r
+  DB   00Fh, 00Fh, 00Fh, 00Fh, 00Fh, 00Fh, 00Fh, 00Fh  ; #222\r
+  DB   0FFh, 0FFh, 0FFh, 0FFh, 000h, 000h, 000h, 000h  ; #223\r
+  DB   000h, 000h, 062h, 094h, 088h, 094h, 062h, 000h  ; #224\r
+  DB   000h, 0F0h, 088h, 0F0h, 088h, 088h, 0F0h, 080h  ; #225\r
+  DB   000h, 0F8h, 088h, 080h, 080h, 080h, 080h, 000h  ; #226\r
+  DB   000h, 0FCh, 048h, 048h, 048h, 048h, 048h, 000h  ; #227\r
+  DB   0FCh, 084h, 040h, 020h, 040h, 084h, 0FCh, 000h  ; #228\r
+  DB   03Ch, 040h, 038h, 044h, 044h, 044h, 038h, 000h  ; #229\r
+  DB   000h, 000h, 044h, 044h, 044h, 078h, 040h, 040h  ; #230\r
+  DB   000h, 036h, 048h, 008h, 008h, 008h, 008h, 000h  ; #231\r
+  DB   038h, 010h, 038h, 044h, 044h, 038h, 010h, 038h  ; #232\r
+  DB   078h, 084h, 084h, 0FCh, 084h, 084h, 078h, 000h  ; #233\r
+  DB   078h, 084h, 084h, 084h, 048h, 048h, 0CCh, 000h  ; #234\r
+  DB   078h, 004h, 038h, 044h, 044h, 044h, 038h, 000h  ; #235\r
+  DB   000h, 000h, 06Ch, 092h, 092h, 06Ch, 000h, 000h  ; #236\r
+  DB   000h, 000h, 03Ah, 044h, 05Ah, 022h, 05Ch, 000h  ; #237\r
+  DB   018h, 020h, 040h, 078h, 040h, 020h, 018h, 000h  ; #238\r
+  DB   078h, 084h, 084h, 084h, 084h, 084h, 084h, 000h  ; #239\r
+  DB   000h, 0FCh, 000h, 0FCh, 000h, 0FCh, 000h, 000h  ; #240\r
+  DB   020h, 020h, 0F8h, 020h, 020h, 000h, 0F8h, 000h  ; #241\r
+  DB   020h, 010h, 008h, 010h, 020h, 000h, 07Ch, 000h  ; #242\r
+  DB   008h, 010h, 020h, 010h, 008h, 000h, 07Ch, 000h  ; #243\r
+  DB   00Ch, 012h, 010h, 010h, 010h, 010h, 010h, 010h  ; #244\r
+  DB   010h, 010h, 010h, 010h, 010h, 010h, 090h, 060h  ; #245\r
+  DB   000h, 010h, 000h, 07Ch, 000h, 010h, 000h, 000h  ; #246\r
+  DB   000h, 032h, 04Ch, 000h, 032h, 04Ch, 000h, 000h  ; #247\r
+  DB   038h, 044h, 044h, 038h, 000h, 000h, 000h, 000h  ; #248\r
+  DB   000h, 000h, 000h, 018h, 018h, 000h, 000h, 000h  ; #249\r
+  DB   000h, 000h, 000h, 000h, 018h, 000h, 000h, 000h  ; #250\r
+  DB   00Eh, 008h, 008h, 008h, 048h, 028h, 018h, 008h  ; #251\r
+  DB   038h, 024h, 024h, 024h, 024h, 000h, 000h, 000h  ; #252\r
+  DB   03Ch, 004h, 03Ch, 020h, 03Ch, 000h, 000h, 000h  ; #253\r
+  DB   000h, 000h, 03Ch, 03Ch, 03Ch, 03Ch, 000h, 000h  ; #254\r
+  DB   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h  ; #255\r
diff --git a/16/xw_/makefile b/16/xw_/makefile
new file mode 100755 (executable)
index 0000000..298ec30
--- /dev/null
@@ -0,0 +1,134 @@
+#\r
+# MODEX library makefile (for Borland MAKE)\r
+# Copyright (c) 1993,1994 by Alessandro Scotti\r
+#\r
+!ifdef __LINUX__\r
+REMOVECOMMAND=rm -f\r
+COPYCOMMAND=cp -f\r
+DIRSEP=/\r
+OBJ=o\r
+!else\r
+REMOVECOMMAND=del\r
+COPYCOMMAND=copy /y\r
+DIRSEP=\\r
+OBJ=obj\r
+!endif\r
+LIBINCS = modex.def\r
+\r
+LIBOBJS = mxbb.$(OBJ) mxcc.$(OBJ) mxcg.$(OBJ) mxcl.$(OBJ) mxcr.$(OBJ) mxel.$(OBJ) mxfb.$(OBJ) mxfp.$(OBJ) mxgc.$(OBJ) mxgi.$(OBJ) mxgm.$(OBJ) mxgp.$(OBJ) mxgv.$(OBJ) mxhl.$(OBJ) mxit.$(OBJ) mxll.$(OBJ) mxln.$(OBJ) mxot.$(OBJ) mxpb.$(OBJ) mxpf.$(OBJ) mxpg.$(OBJ) mxpi.$(OBJ) mxpn.$(OBJ) mxpp.$(OBJ) mxra.$(OBJ) mxrp.$(OBJ) mxsa.$(OBJ) mxsc.$(OBJ) mxsi.$(OBJ) mxsl.$(OBJ) mxsm.$(OBJ) mxsp.$(OBJ) mxss.$(OBJ) mxtl.$(OBJ) mxvs.$(OBJ) mxwd.$(OBJ) mxwm.$(OBJ) mxwp.$(OBJ) mxwr.$(OBJ)\r
+\r
+#\r
+# ASM compiler\r
+#\r
+ASMC =wasm\r
+ASMO =-mh -0\r
+\r
+#\r
+# PAS compiler\r
+#\r
+#PASC = tpc\r
+#PASO = /m -$D- -$L- -$S-\r
+\r
+#\r
+# LIB maker, uses response file\r
+#\r
+LIBC = wlib\r
+\r
+# .asm.obj:\r
+#              $(ASMC) $(ASMO) $<\r
+\r
+mxbb.$(OBJ): mxbb.asm\r
+       $(ASMC) $(ASMO) mxbb.asm\r
+mxcc.$(OBJ): mxcc.asm\r
+       $(ASMC) $(ASMO) mxcc.asm\r
+mxcg.$(OBJ): mxcg.asm\r
+       $(ASMC) $(ASMO) mxcg.asm\r
+mxcl.$(OBJ): mxcl.asm\r
+       $(ASMC) $(ASMO) mxcl.asm\r
+mxcr.$(OBJ): mxcr.asm\r
+       $(ASMC) $(ASMO) mxcr.asm\r
+mxel.$(OBJ): mxel.asm\r
+       $(ASMC) $(ASMO) mxel.asm\r
+mxfb.$(OBJ): mxfb.asm\r
+       $(ASMC) $(ASMO) mxfb.asm\r
+mxfp.$(OBJ): mxfp.asm\r
+       $(ASMC) $(ASMO) mxfp.asm\r
+mxgc.$(OBJ): mxgc.asm\r
+       $(ASMC) $(ASMO) mxgc.asm\r
+mxgi.$(OBJ): mxgi.asm\r
+       $(ASMC) $(ASMO) mxgi.asm\r
+mxgm.$(OBJ): mxgm.asm\r
+       $(ASMC) $(ASMO) mxgm.asm\r
+mxgp.$(OBJ): mxgp.asm\r
+       $(ASMC) $(ASMO) mxgp.asm\r
+mxgv.$(OBJ): mxgv.asm\r
+       $(ASMC) $(ASMO) mxgv.asm\r
+mxhl.$(OBJ): mxhl.asm\r
+       $(ASMC) $(ASMO) mxhl.asm\r
+mxit.$(OBJ): mxit.asm\r
+       $(ASMC) $(ASMO) mxit.asm\r
+mxll.$(OBJ): mxll.asm\r
+       $(ASMC) $(ASMO) mxll.asm\r
+mxln.$(OBJ): mxln.asm\r
+       $(ASMC) $(ASMO) mxln.asm\r
+mxot.$(OBJ): mxot.asm\r
+       $(ASMC) $(ASMO) mxot.asm\r
+mxpb.$(OBJ): mxpb.asm\r
+       $(ASMC) $(ASMO) mxpb.asm\r
+mxpf.$(OBJ): mxpf.asm\r
+       $(ASMC) $(ASMO) mxpf.asm\r
+mxpg.$(OBJ): mxpg.asm\r
+       $(ASMC) $(ASMO) mxpg.asm\r
+mxpi.$(OBJ): mxpi.asm\r
+       $(ASMC) $(ASMO) mxpi.asm\r
+mxpn.$(OBJ): mxpn.asm\r
+       $(ASMC) $(ASMO) mxpn.asm\r
+mxpp.$(OBJ): mxpp.asm\r
+       $(ASMC) $(ASMO) mxpp.asm\r
+mxra.$(OBJ): mxra.asm\r
+       $(ASMC) $(ASMO) mxra.asm\r
+mxrp.$(OBJ): mxrp.asm\r
+       $(ASMC) $(ASMO) mxrp.asm\r
+mxsa.$(OBJ): mxsa.asm\r
+       $(ASMC) $(ASMO) mxsa.asm\r
+mxsc.$(OBJ): mxsc.asm\r
+       $(ASMC) $(ASMO) mxsc.asm\r
+mxsi.$(OBJ): mxsi.asm\r
+       $(ASMC) $(ASMO) mxsi.asm\r
+mxsl.$(OBJ): mxsl.asm\r
+       $(ASMC) $(ASMO) mxsl.asm\r
+mxsm.$(OBJ): mxsm.asm\r
+       $(ASMC) $(ASMO) mxsm.asm\r
+mxsp.$(OBJ): mxsp.asm\r
+       $(ASMC) $(ASMO) mxsp.asm\r
+mxss.$(OBJ): mxss.asm\r
+       $(ASMC) $(ASMO) mxss.asm\r
+mxtl.$(OBJ): mxtl.asm\r
+       $(ASMC) $(ASMO) mxtl.asm\r
+mxvs.$(OBJ): mxvs.asm\r
+       $(ASMC) $(ASMO) mxvs.asm\r
+mxwd.$(OBJ): mxwd.asm\r
+       $(ASMC) $(ASMO) mxwd.asm\r
+mxwm.$(OBJ): mxwm.asm\r
+       $(ASMC) $(ASMO) mxwm.asm\r
+mxwp.$(OBJ): mxwp.asm\r
+       $(ASMC) $(ASMO) mxwp.asm\r
+mxwr.$(OBJ): mxwr.asm\r
+       $(ASMC) $(ASMO) mxwr.asm\r
+\r
+all: $(LIBOBJS) modex.lib\r
+# modex.tpu modex.tpp\r
+\r
+#modex.tpu: $(LIBOBJS) modex.pas\r
+#        $(PASC) $(PASO) modex\r
+#        copy modex.tpu ..\r
+#        copy modex.pas ..\r
+\r
+#modex.tpp: $(LIBOBJS) modex.pas\r
+#        $(PASC) /cp $(PASO) modex\r
+#        copy modex.tpp ..\r
+\r
+modex.lib: modex.lbr $(LIBOBJS)\r
+       $(LIBC) modex.lib @modex.lbr\r
+\r
+$(LIBOBJS):   modex.def\r
diff --git a/16/xw_/makefile.bcc b/16/xw_/makefile.bcc
new file mode 100755 (executable)
index 0000000..d3ad8b7
--- /dev/null
@@ -0,0 +1,81 @@
+#\r
+# MODEX library makefile (for Borland MAKE)\r
+# Copyright (c) 1993,1994 by Alessandro Scotti\r
+#\r
+LIBINCS = MODEX.DEF\r
+\r
+LIBOBJS = MXBB.OBJ \\r
+          MXCC.OBJ \\r
+          MXCG.OBJ \\r
+          MXCL.OBJ \\r
+          MXCR.OBJ \\r
+          MXFB.OBJ \\r
+          MXFP.OBJ \\r
+          MXGC.OBJ \\r
+          MXGI.OBJ \\r
+          MXGM.OBJ \\r
+          MXGP.OBJ \\r
+          MXGV.OBJ \\r
+          MXHL.OBJ \\r
+          MXIT.OBJ \\r
+          MXLL.OBJ \\r
+          MXLN.OBJ \\r
+          MXOT.OBJ \\r
+          MXPB.OBJ \\r
+          MXPF.OBJ \\r
+          MXPG.OBJ \\r
+          MXPI.OBJ \\r
+          MXPN.OBJ \\r
+          MXPP.OBJ \\r
+          MXRA.OBJ \\r
+          MXRP.OBJ \\r
+          MXSA.OBJ \\r
+          MXSC.OBJ \\r
+          MXSI.OBJ \\r
+          MXSL.OBJ \\r
+          MXSM.OBJ \\r
+          MXSP.OBJ \\r
+          MXSS.OBJ \\r
+          MXTL.OBJ \\r
+          MXVS.OBJ \\r
+          MXWD.OBJ \\r
+          MXWM.OBJ \\r
+          MXWP.OBJ \\r
+          MXWR.OBJ\r
+\r
+#\r
+# ASM compiler\r
+#\r
+ASMC = tasm\r
+ASMO = /m5 /p\r
+\r
+#\r
+# PAS compiler\r
+#\r
+PASC = tpc\r
+PASO = /m -$D- -$L- -$S-\r
+\r
+#\r
+# LIB maker, uses response file\r
+#\r
+LIBC = tlib\r
+\r
+.asm.obj:\r
+        $(ASMC) $(ASMO) $<\r
+\r
+target: modex.lib
+# modex.tpu modex.tpp\r
+\r
+#modex.tpu: $(LIBOBJS) modex.pas\r
+#        $(PASC) $(PASO) modex\r
+#        copy modex.tpu ..\r
+#        copy modex.pas ..\r
+\r
+#modex.tpp: $(LIBOBJS) modex.pas\r
+#        $(PASC) /cp $(PASO) modex\r
+#        copy modex.tpp ..\r
+\r
+modex.lib: modex.lbr $(LIBOBJS)\r
+        $(LIBC) modex.lib @modex.lbr\r
+\r
+$(LIBOBJS):   modex.def\r
similarity index 100%
rename from 16/x/modex.bak
rename to 16/xw_/modex.bak
diff --git a/16/xw_/modex.def b/16/xw_/modex.def
new file mode 100755 (executable)
index 0000000..7977a4a
--- /dev/null
@@ -0,0 +1,163 @@
+;------------------------------------------------------------\r
+;\r
+; MODEX.DEF - Include file\r
+; Copyright (c) 1993-1994 by Alessandro Scotti\r
+;\r
+;JUMPS\r
+;LOCALS\r
+\r
+TRUE            EQU     1       ; Boolean constants\r
+FALSE           EQU     0\r
+\r
+USE286  = FALSE                  ; TRUE enables 80286 instructions\r
+USE386  = FALSE                  ; TRUE enables 80386 (and 80286) instructions\r
+\r
+IF USE286 EQ TRUE\r
+        P286\r
+ENDIF\r
+\r
+IF USE386 EQ TRUE\r
+        P386\r
+        USE286  = TRUE\r
+ENDIF\r
+\r
+MXVERSION       EQU     0128h   ; Library version (1.40)\r
+\r
+;------------------------------------------------------------\r
+;\r
+; VGA definitions\r
+;\r
+MISC    EQU     3C2h            ; Miscellaneous output\r
+TS      EQU     3C4h            ; Timing Sequencer index register\r
+GDC     EQU     3CEh            ; Graphics Data Controller index register\r
+CRTC    EQU     3D4h            ; CRTC index register\r
+STATUS  EQU     3DAh            ; Input Status register one\r
+\r
+;------------------------------------------------------------\r
+;\r
+; Raster operators\r
+;\r
+OP_SET          EQU     0\r
+OP_MOVE         EQU     0       ; Same as OP_SET\r
+OP_AND          EQU     1\r
+OP_OR           EQU     2\r
+OP_XOR          EQU     3\r
+OP_TRANS        EQU     4\r
+OP_ADD          EQU     5       ; Must be last op\r
+\r
+;------------------------------------------------------------\r
+;\r
+; Polygon fill functions\r
+;\r
+POLYSCANBUFSIZE EQU     4*1024\r
+\r
+;------------------------------------------------------------\r
+; Macro to push registers, variables or flags onto the stack\r
+; Usage: .push "loc16"[,"loc16"...]\r
+; where "loc16" is a 16-bit register, a word-sized variable or the\r
+; keyword "FLAGS".\r
+; Exmpl: .push ax, flags, var1\r
+;        .pop  ax, flags, var1\r
+;\r
+.push   MACRO   r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10\r
+    IFNB <r10>\r
+        .ERROR <.PUSH has more than 10 arguments>\r
+    ENDIF\r
+    IRP $reg, <r0, r1, r2, r3, r4, r5, r6, r7, r8, r9>\r
+        IFB <$reg>                      ;; Is argument blank?\r
+            EXITM                       ;; Yes, exit\r
+        ELSEIFIDNI <$reg>, <FLAGS>      ;; Is argument the keyword "FLAGS"?\r
+            pushf                       ;; Yes, push flags\r
+        ELSE\r
+            push    $reg                ;; Push argument\r
+        ENDIF\r
+    ENDM\r
+ENDM\r
+\r
+;------------------------------------------------------------\r
+; Macro to pop registers, variables or flags from the stack\r
+; Usage: .pop "loc16"[,"loc16"...]\r
+; where "loc16" is a 16-bit register, a word-sized variable or the\r
+; keyword "FLAGS".\r
+; Exmpl: .push ax, flags, var1\r
+;        .pop  ax, flags, var1\r
+;\r
+.pop    MACRO   r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10\r
+    IFNB <r10>\r
+        .ERROR <.POP has more than 10 arguments>\r
+    ENDIF\r
+    IRP $reg, <r9, r8, r7, r6, r5, r4, r3, r2, r1, r0>\r
+        IFNB <$reg>                     ;; Is argument non-blank?\r
+            IFIDNI <$reg>, <FLAGS>      ;; Yes, is it the keyword "FLAGS"?\r
+                popf                    ;; Yes, pop flags\r
+            ELSE\r
+                pop     $reg            ;; Pop argument\r
+            ENDIF\r
+        ENDIF\r
+    ENDM\r
+ENDM\r
+\r
+;------------------------------------------------------------\r
+;\r
+.enter  MACRO   localsize\r
+    IF USE286 EQ TRUE\r
+        enter   localsize, 0\r
+    ELSE\r
+        push    bp\r
+        mov     bp, sp\r
+        sub     sp, localsize\r
+    ENDIF\r
+ENDM\r
+\r
+;------------------------------------------------------------\r
+;\r
+;.leave  MACRO   argsize\r
+;    IF USE286 EQ TRUE\r
+;        leave\r
+;    ELSE\r
+;        mov     sp, bp\r
+;        pop     bp\r
+;    ENDIF\r
+;    IFNB <argspace>\r
+;        ret     argsize\r
+;    ELSE\r
+;        ret\r
+;    ENDIF\r
+;ENDM\r
+\r
+;------------------------------------------------------------\r
+;\r
+;.shr    MACRO   arg, count\r
+;    IF USE286 EQ TRUE\r
+;        shr     arg, count\r
+;    ELSE\r
+;        $temp = count\r
+;        WHILE $temp GT 0\r
+;            shr arg, 1\r
+;            $temp = $temp-1\r
+;        ENDM\r
+;    ENDIF\r
+;ENDM\r
+\r
+;------------------------------------------------------------\r
+;\r
+;.shl    MACRO   arg, count\r
+;    IF USE286 EQ TRUE\r
+;        shl     arg, count\r
+;    ELSE\r
+;        $temp = count\r
+;        WHILE $temp GT 0\r
+;            shl arg, 1\r
+;            $temp = $temp-1\r
+;        ENDM\r
+;    ENDIF\r
+;ENDM\r
+\r
+;------------------------------------------------------------\r
+;\r
+;.chk386 MACRO   name, jump\r
+;    IF USE386 EQ FALSE\r
+;        .OUT    "Warning: ", <name>, " needs a 386 or better to run!"\r
+;        jmp     @@jump\r
+;    ENDIF\r
+;ENDM\r
diff --git a/16/xw_/modex.h b/16/xw_/modex.h
new file mode 100755 (executable)
index 0000000..2c1f1eb
--- /dev/null
@@ -0,0 +1,153 @@
+/*\r
+    MODEX.H - C/C++ include file for the MODEX library\r
+    Copyright (c) 1994 Alessandro Scotti\r
+*/\r
+\r
+#ifndef _MODEX_H_               // Avoid nested inclusions\r
+#define _MODEX_H_\r
+\r
+//\r
+// Video modes\r
+//\r
+#define MX_TEXT     0           // 80x25 text\r
+#define MX_320x175  1           // 320x175x256\r
+#define MX_320x200  2           // 320x200x256, 4 pages, aspect 6:5\r
+#define MX_320x240  3           // 320x240x256, 3 pages, aspect 1:1\r
+#define MX_320x350  4           // 320x350x256\r
+#define MX_320x400  5           // 320x400x256, 2 pages\r
+#define MX_320x480  6           // 320x480x256, 1 page\r
+#define MX_360x175  7           // 360x175x256\r
+#define MX_360x200  8           // 360x200x256, 3 pages\r
+#define MX_360x240  9           // 360x240x256, 2 pages\r
+#define MX_360x350  10          // 360x350x256\r
+#define MX_360x400  11          // 360x400x256, 1 page\r
+#define MX_360x480  12          // 360x480x256, 1 page\r
+#define MX_400x600  13          // 400x600x256, 1 page\r
+\r
+//\r
+// Fade effects\r
+//\r
+#define MX_FADEIN   0\r
+#define MX_FADEOUT  1\r
+\r
+//\r
+// Raster ops\r
+//\r
+#define OP_SET      0           // No operator\r
+#define OP_AND      1           // And\r
+#define OP_OR       2           // Or\r
+#define OP_XOR      3           // Xor\r
+#define OP_TRANS    4           // Transparent\r
+#define OP_ADD      5           // Additive\r
+#define OP_MOVE     0           // Alias for OP_SET\r
+\r
+//\r
+// Temporary definitions\r
+//\r
+#define MXBYTE      unsigned char\r
+#define MXBOOL      short int\r
+#define MXSINT      short int\r
+#define MXUINT      unsigned short int\r
+#define MXAPI       far pascal\r
+#define MXPTR       void far *\r
+\r
+// Functions\r
+\r
+#ifdef __cplusplus                      // Avoid C++ name mangling\r
+extern "C" {\r
+#endif\r
+\r
+//\r
+// Initialization\r
+//\r
+MXSINT  MXAPI mxInit( void );             // Returns 0 if successful\r
+void    MXAPI mxTerm( void );\r
+MXUINT  MXAPI mxGetVersion( void );\r
+//\r
+// Mode setting\r
+//\r
+void    MXAPI mxChangeMode( MXUINT mode );\r
+void    MXAPI mxSetMode( MXUINT mode );\r
+void    MXAPI mxGetAspect( MXUINT far *aspectx, MXUINT far *aspecty );\r
+void    MXAPI mxGetScreenSize( MXUINT far *width, MXUINT far *height );\r
+//\r
+// Hardware support\r
+//\r
+void    MXAPI mxWriteMode( MXBYTE wm );\r
+void    MXAPI mxSplitScreen( MXUINT line );\r
+void    MXAPI mxStartAddress( MXUINT sa );\r
+void    MXAPI mxStartLine( MXUINT sl );\r
+void    MXAPI mxWaitDisplay( void );\r
+void    MXAPI mxWaitRetrace( void );\r
+void    MXAPI mxWritePlane( MXBYTE wp );\r
+void    MXAPI mxReadPlane( MXBYTE rp );\r
+void    MXAPI mxRowAddress( MXBYTE ra );\r
+//\r
+// Virtual screen\r
+//\r
+void    MXAPI mxGetVirtualScreen( MXUINT far *width, MXUINT far *height );\r
+void    MXAPI mxSetVirtualScreen( MXUINT width, MXUINT height );\r
+void    MXAPI mxPan( MXUINT x, MXUINT y );\r
+//\r
+// Clipping\r
+//\r
+MXBOOL  MXAPI mxGetClip( void );\r
+MXBOOL  MXAPI mxGetClipRegion( MXSINT far *x, MXSINT far *y, MXSINT far *w, MXSINT far *h );\r
+MXBOOL  MXAPI mxSetClip( MXBOOL );\r
+void    MXAPI mxSetClipRegion( MXUINT x, MXUINT y, MXUINT width, MXUINT height );\r
+//\r
+// Graphics\r
+//\r
+void    MXAPI mxBitBlt( MXSINT sx, MXSINT sy, MXUINT width, MXUINT height, MXSINT dx, MXSINT dy );\r
+void    MXAPI mxFillBox( MXSINT x, MXSINT y, MXUINT width, MXUINT height, MXUINT color, MXUINT op );\r
+MXBYTE  MXAPI mxGetPixel( MXSINT x, MXSINT y );\r
+void    MXAPI mxPutPixel( MXSINT x, MXSINT y, MXBYTE color );\r
+void    MXAPI mxLine( MXSINT x1, MXSINT y1, MXSINT x2, MXSINT y2, MXUINT color, MXUINT op );\r
+void    MXAPI mxGetImage( MXPTR img, MXSINT x, MXSINT y, MXUINT width, MXUINT height );\r
+void    MXAPI mxPutImage( MXPTR img, MXSINT x, MXSINT y, MXUINT w, MXUINT h, MXUINT op );\r
+void    MXAPI mxPutTile( MXPTR tile, MXSINT x, MXSINT y, MXUINT width, MXUINT height );\r
+void    MXAPI mxTransPutTile( MXPTR tile, MXSINT x, MXSINT y, MXUINT w, MXUINT h );\r
+void    MXAPI mxCircle( MXSINT x, MXSINT y, MXUINT radius, MXBYTE color );\r
+void    MXAPI mxStretchImage( MXPTR img, MXSINT x, MXSINT y, MXUINT w, MXUINT h, MXUINT neww, MXUINT newh, MXUINT op );\r
+//\r
+// Palette\r
+//\r
+void    MXAPI mxColorToGray( MXPTR source, MXPTR dest, MXUINT count );\r
+void    MXAPI mxGammaCorrect( MXPTR source, MXPTR dest, MXUINT count );\r
+void    MXAPI mxGetColor( MXUINT index, MXSINT far *r, MXSINT far *g, MXSINT far *b );\r
+void    MXAPI mxSetColor( MXUINT index, MXSINT red, MXSINT green, MXSINT blue );\r
+void    MXAPI mxGetPalette( MXPTR palette, MXUINT index, MXUINT count );\r
+void    MXAPI mxSetPalette( MXPTR palette, MXUINT index, MXUINT count );\r
+void    MXAPI mxFadePalette( MXPTR, MXUINT, MXUINT, MXUINT, MXUINT, MXUINT, MXUINT );\r
+void    MXAPI mxRotatePalette( MXPTR palette, MXUINT count, MXSINT step );\r
+//\r
+// Text\r
+//\r
+MXSINT  MXAPI mxSetFont( MXPTR font, MXUINT charwidth, MXUINT charheight );\r
+void    MXAPI mxSetTextColor( MXUINT color, MXUINT op );\r
+void    MXAPI mxGetTextStep( MXSINT far *deltax, MXSINT far *deltay );\r
+void    MXAPI mxSetTextStep( MXSINT deltax, MXSINT deltay );\r
+void    MXAPI mxOutChar( MXSINT x, MXSINT y, char c );\r
+void    MXAPI mxOutText( MXSINT x, MXSINT y, char far *sz );\r
+//\r
+// Convex polygons\r
+//\r
+void    MXAPI mxFillPoly( MXUINT, MXPTR, MXPTR, MXUINT, MXUINT );\r
+void    MXAPI mxGouraudPoly( MXUINT, MXPTR, MXPTR, MXPTR, MXUINT, MXUINT );\r
+void    MXAPI mxTexturePoly( MXUINT, MXPTR, MXPTR, MXPTR, MXPTR, MXUINT, MXUINT );\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+//\r
+// Remove temporary defines\r
+//\r
+#undef  MXBYTE\r
+#undef  MXBOOL\r
+#undef  MXSINT\r
+#undef  MXUINT\r
+#undef  MXPTR\r
+#undef  MXAPI\r
+\r
+#endif  // _MODEX_H_\r
diff --git a/16/xw_/modex.lbr b/16/xw_/modex.lbr
new file mode 100755 (executable)
index 0000000..93fc780
--- /dev/null
@@ -0,0 +1,39 @@
++-MXBB.OBJ &\r
++-MXCC.OBJ &\r
++-MXCG.OBJ &\r
++-MXCL.OBJ &\r
++-MXCR.OBJ &\r
++-MXFB.OBJ &\r
++-MXFP.OBJ &\r
++-MXGC.OBJ &\r
++-MXGI.OBJ &\r
++-MXGM.OBJ &\r
++-MXGP.OBJ &\r
++-MXGV.OBJ &\r
++-MXHL.OBJ &\r
++-MXIT.OBJ &\r
++-MXLL.OBJ &\r
++-MXLN.OBJ &\r
++-MXOT.OBJ &\r
++-MXPB.OBJ &\r
++-MXPF.OBJ &\r
++-MXPG.OBJ &\r
++-MXPI.OBJ &\r
++-MXPN.OBJ &\r
++-MXPP.OBJ &\r
++-MXPT.OBJ &\r
++-MXRA.OBJ &\r
++-MXRP.OBJ &\r
++-MXSA.OBJ &\r
++-MXSC.OBJ &\r
++-MXSI.OBJ &\r
++-MXSL.OBJ &\r
++-MXSM.OBJ &\r
++-MXSP.OBJ &\r
++-MXSS.OBJ &\r
++-MXTL.OBJ &\r
++-MXVS.OBJ &\r
++-MXWD.OBJ &\r
++-MXWM.OBJ &\r
++-MXWP.OBJ &\r
++-MXWR.OBJ\r
diff --git a/16/xw_/modex.pas b/16/xw_/modex.pas
new file mode 100755 (executable)
index 0000000..7d9d26e
--- /dev/null
@@ -0,0 +1,194 @@
+(*\r
+   Turbo Pascal interface to the MODEX library\r
+   Copyright (c) 1993,1994 by Alessandro Scotti\r
+*)\r
+unit ModeX;\r
+interface\r
+\r
+const\r
+  (* Video modes *)\r
+  MX_TEXT       = 0;\r
+  MX_320x175    = 1;\r
+  MX_320x200    = 2;\r
+  MX_320x240    = 3;\r
+  MX_320x350    = 4;\r
+  MX_320x400    = 5;\r
+  MX_320x480    = 6;\r
+  MX_360x175    = 7;\r
+  MX_360x200    = 8;\r
+  MX_360x240    = 9;\r
+  MX_360x350    = 10;\r
+  MX_360x400    = 11;\r
+  MX_360x480    = 12;\r
+  MX_400x600    = 13;\r
+\r
+  (* Fade effects *)\r
+  MX_FADEIN     = 0;\r
+  MX_FADEOUT    = 1;\r
+\r
+  (* Raster ops *)\r
+  OP_SET        = 0;\r
+  OP_AND        = 1;\r
+  OP_OR         = 2;\r
+  OP_XOR        = 3;\r
+  OP_TRANS      = 4;\r
+  OP_ADD        = 5;\r
+  OP_MOVE       = 0;                    (* Alias for OP_SET *)\r
+\r
+procedure mxBitBlt( SX, SY: integer; Width, Height: word; DX, DY: integer );\r
+procedure mxCircle( CX, CY: integer; Radius: word; Color: byte );\r
+procedure mxChangeMode( Mode: word );\r
+procedure mxColorToGray( ColorPalette, GrayPalette: pointer; Count: word );\r
+procedure mxFadePalette( Palette: pointer; Cmd, Start, Count, R, G, B: word );\r
+procedure mxFillBox( X, Y: integer; Width, Height: word; Color: byte; Op: word );\r
+procedure mxGammaCorrect( ColorPalette, GammaPalette: pointer; Count: word );\r
+procedure mxGetAspect( var AspectX, AspectY: word );\r
+function  mxGetClipRegion( var X1, Y1, Width, Height: word ): boolean;\r
+function  mxGetClip: boolean;\r
+procedure mxGetImage( Image: pointer; X, Y: integer; Width, Height: word );\r
+procedure mxGetPalette( Palette: pointer; Start, Count: word );\r
+function  mxGetPixel( X, Y: word ): byte;\r
+procedure mxGetScreenSize( var Width, Height: word );\r
+procedure mxGetTextStep( var DeltaX, DeltaY: integer );\r
+function  mxGetVersion: word;\r
+procedure mxGetVirtualScreen( var Width, Height: word );\r
+procedure mxInit;\r
+procedure mxLine( X1, Y1, X2, Y2: integer; Color, Op: word );\r
+procedure mxOutChar( X, Y: integer; C: char );\r
+procedure mxOutText( X, Y: integer; S: pointer );\r
+procedure mxPan( X, Y: word );\r
+procedure mxPutImage( Image: pointer; X, Y: integer; Width, Height, Op: word );\r
+procedure mxPutPixel( X, Y: word; C: byte );\r
+procedure mxPutTile( Tile: pointer; X, Y: integer; Width, Height: word );\r
+procedure mxReadPlane( Plane: byte );\r
+procedure mxRotatePalette( Palette: pointer; Count: word; Step: integer );\r
+procedure mxRowAddress( RowAddress: byte );\r
+function  mxSetClip( Clip: boolean ): boolean;\r
+procedure mxSetClipRegion( X1, Y1, Width, Height: word );\r
+procedure mxSetColor( Index, R, G, B: word );\r
+procedure mxSetFont( Font: pointer; Width, Height: word );\r
+procedure mxSetMode( Mode: word );\r
+procedure mxSetPalette( Palette: pointer; Start, Count: word );\r
+procedure mxSetTextColor( Color, Op: word );\r
+procedure mxSetTextStep( DeltaX, DeltaY: integer );\r
+procedure mxSetVirtualScreen( Width, Height: word );\r
+procedure mxStretchImage( Image: pointer; X, Y: integer; Width, Height, NewWidth, NewHeight, Op: word );\r
+procedure mxSplitScreen( Line: word );\r
+procedure mxStartAddress( StartAddress: word );\r
+procedure mxStartLine( Line: word );\r
+procedure mxTerm;\r
+procedure mxTransPutTile( Tile: pointer; X, Y: integer; Width, Height: word );\r
+procedure mxWaitDisplay;\r
+procedure mxWaitRetrace;\r
+procedure mxWriteMode( Mode: byte );\r
+procedure mxWritePlane( Plane: byte );\r
+\r
+procedure mxFillPoly( Count: word; var Map, Points; Color: word );\r
+procedure mxGouraudPoly( Count: word; var Map, Points, Colors; BaseColor: word );\r
+procedure mxTexturePoly( Count: word; var Map, Points, ImgPoints, Texture; Width: word );\r
+\r
+procedure mxOutStr( X, Y: integer; S: string );\r
+\r
+implementation\r
+\r
+procedure mxBitBlt;                                             external;\r
+procedure mxChangeMode( Mode: word );                           external;\r
+procedure mxCircle;                                             external;\r
+procedure mxColorToGray;                                        external;\r
+procedure mxFadePalette;                                        external;\r
+procedure mxFillBox;                                            external;\r
+procedure mxGammaCorrect;                                       external;\r
+procedure mxGetAspect( var AspectX, AspectY: word );            external;\r
+function  mxGetClipRegion;                                      external;\r
+function  mxGetClip: boolean;                                   external;\r
+procedure mxGetImage;                                           external;\r
+procedure mxGetPalette( Palette: pointer; Start, Count: word ); external;\r
+function  mxGetPixel( X, Y: word ): byte;                       external;\r
+procedure mxGetScreenSize( var Width, Height: word );           external;\r
+procedure mxGetTextStep( var DeltaX, DeltaY: integer );         external;\r
+function  mxGetVersion: word;                                   external;\r
+procedure mxGetVirtualScreen( var Width, Height: word );        external;\r
+procedure mxInit;                                               external;\r
+procedure mxLine( X1, Y1, X2, Y2: integer; Color, Op: word );   external;\r
+procedure mxOutChar( X, Y: integer; C: char );                  external;\r
+procedure mxOutText( X, Y: integer; S: pointer );               external;\r
+procedure mxPan( X, Y: word );                                  external;\r
+procedure mxPutImage;                                           external;\r
+procedure mxPutPixel( X, Y: word; C: byte );                    external;\r
+procedure mxPutTile;                                            external;\r
+procedure mxReadPlane( Plane: byte );                           external;\r
+procedure mxRotatePalette;                                      external;\r
+procedure mxRowAddress( RowAddress: byte );                     external;\r
+function  mxSetClip( Clip: boolean ): boolean;                  external;\r
+procedure mxSetClipRegion( X1, Y1, Width, Height: word );       external;\r
+procedure mxSetColor( Index, R, G, B: word );                   external;\r
+procedure mxSetFont( Font: pointer; Width, Height: word );      external;\r
+procedure mxSetMode( Mode: word );                              external;\r
+procedure mxSetPalette( Palette: pointer; Start, Count: word ); external;\r
+procedure mxSetTextColor( Color, Op: word );                    external;\r
+procedure mxSetTextStep( DeltaX, DeltaY: integer );             external;\r
+procedure mxSetVirtualScreen( Width, Height: word );            external;\r
+procedure mxSplitScreen( Line: word );                          external;\r
+procedure mxStartAddress( StartAddress: word );                 external;\r
+procedure mxStartLine;                                          external;\r
+procedure mxStretchImage;                                       external;\r
+procedure mxTerm;                                               external;\r
+procedure mxTransPutTile;                                       external;\r
+procedure mxWaitDisplay;                                        external;\r
+procedure mxWaitRetrace;                                        external;\r
+procedure mxWriteMode( Mode: byte );                            external;\r
+procedure mxWritePlane( Plane: byte );                          external;\r
+\r
+procedure mxFillPoly;                                           external;\r
+procedure mxGouraudPoly;                                        external;\r
+procedure mxTexturePoly;                                        external;\r
+{$L MXPB}\r
+{$L MXPF}\r
+{$L MXPG}\r
+{$L MXPT}\r
+\r
+{$L MXBB}\r
+{$L MXCC}\r
+{$L MXCG}\r
+{$L MXCL}\r
+{$L MXCR}\r
+{$L MXFB}\r
+{$L MXFP}\r
+{$L MXGI}\r
+{$L MXGM}\r
+{$L MXGP}\r
+{$L MXGV}\r
+{$L MXHL}\r
+{$L MXIT}\r
+{$L MXLN}\r
+{$L MXOT}\r
+{$L MXPI}\r
+{$L MXPN}\r
+{$L MXPP}\r
+{$L MXRA}\r
+{$L MXRP}\r
+{$L MXSA}\r
+{$L MXSC}\r
+{$L MXSI}\r
+{$L MXSL}\r
+{$L MXSM}\r
+{$L MXSP}\r
+{$L MXSS}\r
+{$L MXTL}\r
+{$L MXVS}\r
+{$L MXWD}\r
+{$L MXWM}\r
+{$L MXWP}\r
+{$L MXWR}\r
+\r
+(*\r
+   Prints a Turbo Pascal string.\r
+   Note: BP 7.0 supports ASCIIZ strings (PChar type).\r
+*)\r
+procedure mxOutStr;\r
+begin\r
+  S := S + #0;\r
+  mxOutText( X, Y, @S[1] );\r
+end;\r
+\r
+end.\r
diff --git a/16/xw_/modex/DEMO01.EXE b/16/xw_/modex/DEMO01.EXE
new file mode 100755 (executable)
index 0000000..28caff8
Binary files /dev/null and b/16/xw_/modex/DEMO01.EXE differ
diff --git a/16/xw_/modex/DEMO01.PAS b/16/xw_/modex/DEMO01.PAS
new file mode 100755 (executable)
index 0000000..c684acd
--- /dev/null
@@ -0,0 +1,126 @@
+(*\r
+    DEMO01 - Sprites, page flipping and palette rotation\r
+    Copyright (c) 1994 Alessandro Scotti\r
+*)\r
+uses Crt, Modex;\r
+\r
+const\r
+  MAX_SPRITE = 100;\r
+type\r
+  (* Sprite structure *)\r
+  TSprite = record\r
+    X, Y : integer;                        (* Sprite coordinates *)\r
+    DX,DY: integer;                        (* Deltas for sprite movement *)\r
+    W, H : integer;                        (* Sprite width and height *)\r
+    Image: array[ 1..16, 1..16 ] of byte;  (* Sprite image data *)\r
+  end;\r
+  (* RGB color structure *)\r
+  TRgb    = record\r
+    R, G, B: byte;\r
+  end;\r
+var\r
+  S      : array[ 1..MAX_SPRITE ] of TSprite;   (* An array of sprites *)\r
+  Palette: array[ byte ] of TRgb;               (* Palette *)\r
+  Page   : word;                                (* Page offset *)\r
+  I      : word;\r
+\r
+(* Initializes a sprite structure *)\r
+procedure sxInit( var S: TSprite );\r
+var\r
+  I: word;\r
+begin\r
+  S.X := Random( 320 );  (* Initialize position with random values *)\r
+  S.Y := Random( 240 );\r
+  S.DX := Random( 7 )-3; (* Initialize speed with random values *)\r
+  S.DY := Random( 7 )-3;\r
+  S.W := 16;             (* Size is fixed in this program *)\r
+  S.H := 16;\r
+  (* The image is a square with a hole inside *)\r
+  FillChar( S.Image, SizeOf(S.Image), Random(15)+1 );\r
+  for I:=5 to 12 do FillChar( S.Image[ I, 5 ], 8, 0 );\r
+end;\r
+\r
+(* Moves a sprite *)\r
+procedure sxMove( var S: TSprite );\r
+begin\r
+  Inc( S.X, S.DX );     (* Get new position *)\r
+  Inc( S.Y, S.DY );\r
+  (* Check sprite position, change delta if needed *)\r
+  if( S.X > 320 ) then begin\r
+    S.X := 320;\r
+    S.DX := -S.DX;\r
+  end;\r
+  if( S.X < -16 ) then begin\r
+    S.X := -16;\r
+    S.DX := -S.DX;\r
+  end;\r
+  if( S.Y > 240 ) then begin\r
+    S.Y := 240;\r
+    S.DY := -S.DY;\r
+  end;\r
+  if( S.Y < -16 ) then begin\r
+    S.Y := -16;\r
+    S.DY := -S.DY;\r
+  end;\r
+  (* Draw the sprite, note the Page offset added to the *)\r
+  (* Y coordinate of the image *)\r
+  mxPutImage( @S.Image, S.X, Page+S.Y, S.W, S.H, OP_TRANS );\r
+end;\r
+\r
+begin\r
+  (* Initialize library *)\r
+  mxInit;\r
+\r
+  (* Enter graphics mode *)\r
+  mxSetMode( MX_320x240 );\r
+\r
+  (* Print initialization message *)\r
+  mxSetTextColor( 15, OP_TRANS );\r
+  mxOutStr( 4, 4, 'Initializing...' );\r
+\r
+  (* Initialize sprites *)\r
+  for I:=1 to MAX_SPRITE do sxInit( S[I] );\r
+\r
+  (* Draw background *)\r
+  for I:=1 to 192 do begin\r
+    mxCircle( 160, 480+120, I, I+63 );\r
+    mxCircle( 161, 480+120, I, I+63 );\r
+  end;\r
+\r
+  (* Compute and set palette *)\r
+  for I:=1 to 192 do with Palette[I+63] do begin\r
+    R := 0;\r
+    G := 0;\r
+    B := 0;\r
+    if( I < 64 ) then\r
+      R := I shr 1+31\r
+    else if( I < 128 ) then\r
+      G := (I-64) shr 1+31\r
+    else\r
+      B := (I-128) shr 1+31;\r
+  end;\r
+  mxSetPalette( @Palette[64], 64, 192 );\r
+\r
+  (* Main loop *)\r
+  Page := 240;\r
+  while( not KeyPressed ) do begin\r
+    (* Set clip region to current page *)\r
+    mxSetClipRegion( 0, Page, 320, 240 );\r
+    mxSetClip( TRUE );\r
+    (* Restore background *)\r
+    mxBitBlt( 0, 480, 320, 240, 0, Page );\r
+    (* Draw sprites *)\r
+    for I:=1 to MAX_SPRITE do sxMove( S[I] );\r
+    (* Print message *)\r
+    mxOutStr( 4, Page+4, 'Some sprites moving...' );\r
+    (* Flip page *)\r
+    mxStartLine( Page );\r
+    Page := 240-Page;\r
+    (* Animate palette *)\r
+    mxSetPalette( @Palette[64], 64, 192 );\r
+    mxRotatePalette( @Palette[64], 192, 3 );\r
+  end;\r
+\r
+  mxSetMode( MX_TEXT );\r
+  mxTerm;\r
+end.\r
diff --git a/16/xw_/modex/DEMO02.EXE b/16/xw_/modex/DEMO02.EXE
new file mode 100755 (executable)
index 0000000..14e7dc7
Binary files /dev/null and b/16/xw_/modex/DEMO02.EXE differ
diff --git a/16/xw_/modex/DEMO02.PAS b/16/xw_/modex/DEMO02.PAS
new file mode 100755 (executable)
index 0000000..6b4fb6f
--- /dev/null
@@ -0,0 +1,125 @@
+(*\r
+    DEMO02 - Texture mapping and palette rotation\r
+    (c) 1994 by Alessandro Scotti\r
+*)\r
+uses Crt, Modex, Plasma, Threed;\r
+\r
+const\r
+  LSIZE = 85;\r
+  Trans : TPoint = ( X:0; Y:0; Z:0 );\r
+type\r
+  T2DPoint = record\r
+    X, Y: integer;\r
+  end;\r
+  TTexture = record\r
+    Desc   : array[ 0..3 ] of T2DPoint;\r
+    Width  : word;\r
+    Data   : array[ 1..64*64 ] of byte;\r
+  end;\r
+  TQuad = record\r
+    VtxCnt : word;\r
+    Vtx    : array[ 0..3 ] of word;\r
+    Texture: word;\r
+  end;\r
+var\r
+  Vtx   : array[ 0..7 ] of TPoint;\r
+  XVtx  : array[ 0..7 ] of TPoint;\r
+  VVtx  : array[ 0..7 ] of T2DPoint;\r
+  Face  : array[ 0..5 ] of TQuad;\r
+  Txts  : array[ 0..5 ] of TTexture;\r
+  Nrm   : array[ 0..5 ] of TPoint;\r
+  XNrm  : array[ 0..5 ] of TPoint;\r
+  Page  : word;\r
+  Palette: array[ byte ] of record R, G, B: byte; end;\r
+\r
+(* Make a 64x64 plasma to be used as texture *)\r
+procedure MakeTexture( Idx: word );\r
+var\r
+  I: word;\r
+begin\r
+  mxFillBox( 0, 0, 64, 64, 0, OP_SET );\r
+  MakePlasma( 0, 0, 64, 64, 96, Random(192)+1, Random(192)+1, Random(192)+1 );\r
+  mxGetImage( @Txts[Idx].Data, 0, 0, 64, 64 );\r
+  (* Texture vertexes are 8:8 fixed, add $80 (0.5) for best results *)\r
+  with Txts[Idx] do begin\r
+    Desc[0].X := $80; Desc[0].Y := $80;\r
+    Desc[1].X := $80; Desc[1].Y := $3F80;\r
+    Desc[2].X := $3F80; Desc[2].Y := $3F80;\r
+    Desc[3].X := $3F80; Desc[3].Y := $80;\r
+    Width := 64;\r
+  end;\r
+end;\r
+\r
+procedure Init;\r
+var\r
+  I: integer;\r
+begin\r
+  (* Build vertexes for a cube *)\r
+  with Vtx[0] do begin X:=-LSIZE; Y:=-LSIZE; Z:=-LSIZE; end;\r
+  with Vtx[1] do begin X:=+LSIZE; Y:=-LSIZE; Z:=-LSIZE; end;\r
+  with Vtx[2] do begin X:=-LSIZE; Y:=+LSIZE; Z:=-LSIZE; end;\r
+  with Vtx[3] do begin X:=+LSIZE; Y:=+LSIZE; Z:=-LSIZE; end;\r
+  with Vtx[4] do begin X:=-LSIZE; Y:=-LSIZE; Z:=+LSIZE; end;\r
+  with Vtx[5] do begin X:=+LSIZE; Y:=-LSIZE; Z:=+LSIZE; end;\r
+  with Vtx[6] do begin X:=-LSIZE; Y:=+LSIZE; Z:=+LSIZE; end;\r
+  with Vtx[7] do begin X:=+LSIZE; Y:=+LSIZE; Z:=+LSIZE; end;\r
+  for I:=0 to 7 do begin          (* Make points 16:16 fixed *)\r
+    Vtx[I].X := Vtx[I].X*$10000;\r
+    Vtx[I].Y := Vtx[I].Y*$10000;\r
+    Vtx[I].Z := Vtx[I].Z*$10000;\r
+  end;\r
+  (* Build faces *)\r
+  with Face[0] do begin Vtx[0]:=0; Vtx[1]:=2; Vtx[2]:=3; Vtx[3]:=1; end;\r
+  with Face[1] do begin Vtx[0]:=4; Vtx[1]:=5; Vtx[2]:=7; Vtx[3]:=6; end;\r
+  with Face[2] do begin Vtx[0]:=0; Vtx[1]:=1; Vtx[2]:=5; Vtx[3]:=4; end;\r
+  with Face[3] do begin Vtx[0]:=1; Vtx[1]:=3; Vtx[2]:=7; Vtx[3]:=5; end;\r
+  with Face[4] do begin Vtx[0]:=2; Vtx[1]:=0; Vtx[2]:=4; Vtx[3]:=6; end;\r
+  with Face[5] do begin Vtx[0]:=7; Vtx[1]:=3; Vtx[2]:=2; Vtx[3]:=6; end;\r
+  for I:=0 to 5 do Face[I].Texture := I;\r
+  (* Build textures and palette *)\r
+  Randomize;\r
+  FillChar( Palette, SizeOf(Palette), 0 );\r
+  MakePlasmaPalette( Palette, PAL_RGB );\r
+  mxSetPalette( @Palette, 0, 193 );\r
+  for I:=0 to 5 do MakeTexture( I );\r
+end;\r
+\r
+var\r
+  AX, AY, AZ: byte;\r
+  I: word;\r
+begin\r
+  mxInit;\r
+  mxSetMode( MX_320x240 );\r
+  Init;\r
+  Page := 240;          (* Start with hidden page *)\r
+\r
+  AX := 0;\r
+  AY := 0;\r
+  AZ := 0;\r
+  (* Init 3D transforms, perspective is intentionally exaggerated *)\r
+  tdSetTranslation( Trans );\r
+  tdSetPerspective( 400*$10000, $10000, $10000 );\r
+  (* Main loop, all magic here! *)\r
+  while( not KeyPressed ) do begin\r
+    tdSetRotation( AX, AY, AZ );                (* Set new angles *)\r
+    tdTransform( Vtx, XVtx, 8 );                (* 3D transform points *)\r
+    tdTransformToImage( XVtx, VVtx, 8, 160, 120+Page );\r
+    Inc( AX, 1 );                               (* Bump angles *)\r
+    Inc( AY, 1 );\r
+    Inc( AZ, 2 );\r
+    mxSetClipRegion( 0, Page, 320, 240 );       (* Set clip to new page *)\r
+    mxSetClip( TRUE );\r
+    mxFillBox( 0, Page, 320, 240, 0, OP_MOVE ); (* Clear screen *)\r
+    mxRotatePalette( @Palette[1], 192, 3 );     (* Rotate palette *)\r
+    (* Draw cube: backface culling is straighforward in this case, so *)\r
+    (* it can be handled by the polygon filling procedure *)\r
+    for I:=0 to 5 do\r
+      mxTexturePoly( 4, Face[I].Vtx, VVtx, Txts[I].Desc, Txts[I].Data, Txts[I].Width );\r
+    mxStartLine( Page );                        (* Flip pages *)\r
+    mxSetPalette( @Palette[1], 1, 192 );        (* Set new palette *)\r
+    Page := 240-Page;\r
+  end;\r
+\r
+  mxSetMode( MX_TEXT );\r
+  mxTerm;\r
+end.\r
diff --git a/16/xw_/modex/DEMO03.EXE b/16/xw_/modex/DEMO03.EXE
new file mode 100755 (executable)
index 0000000..c646c4b
Binary files /dev/null and b/16/xw_/modex/DEMO03.EXE differ
diff --git a/16/xw_/modex/DEMO03.PAS b/16/xw_/modex/DEMO03.PAS
new file mode 100755 (executable)
index 0000000..01d10f4
--- /dev/null
@@ -0,0 +1,152 @@
+(*\r
+    DEMO03 - Simple star animation, morphs between a cube and a sphere\r
+    (c) 1994 by Alessandro Scotti\r
+*)\r
+uses Crt, Modex, Threed;\r
+\r
+const\r
+  MAXVTX = 1000;        (* Number of points *)\r
+  EDGE = 70;            (* Length of cube edge *)\r
+  RADIUS = 90;          (* Radius of sphere *)\r
+  WAITCOUNT = 192;      (* Frames to wait for non-morphing shapes *)\r
+  MS = 32;              (* Number of steps for morphing *)\r
+  Trans : TPoint = ( X:0; Y:0; Z:0 );\r
+  InitMorph1: array[ 0..3 ] of integer = ( 0, MS, 0, 0 );\r
+  InitMorph2: array[ 0..3 ] of integer = ( 0, 0, 0, MS );\r
+  InitDelta1: array[ 0..3 ] of integer = ( 0, -1, 0, +1 );\r
+  InitDelta2: array[ 0..3 ] of integer = ( 0, +1, 0, -1 );\r
+type\r
+  T2DPoint = record\r
+    X, Y: integer;\r
+  end;\r
+  T3DPointArray = array[ 0..MAXVTX-1 ] of TPoint;\r
+  P3DPointArray = ^T3DPointArray;\r
+var\r
+  CubeVtx, SphereVtx, Vtx, XVtx: P3DPointArray;\r
+  VVtx  : array[ 0..MAXVTX-1 ] of T2DPoint;\r
+  Page  : word;\r
+  Status, Count, Delta1, Delta2, Morph1, Morph2: integer;\r
+\r
+procedure Swap( var A, B: longint );\r
+var\r
+  L: longint;\r
+begin\r
+  L := A; A := B; B := L;\r
+end;\r
+\r
+function Toggle( A: longint ): longint;\r
+begin\r
+  Toggle := A;\r
+  if( Random(2) = 0 ) then Toggle := -A;\r
+end;\r
+\r
+procedure Init;\r
+label Retry;\r
+var\r
+  I: integer;\r
+begin\r
+  New( CubeVtx );\r
+  New( SphereVtx );\r
+  New( Vtx );\r
+  New( XVtx );\r
+  (* Build vertexes (yes, I know this piece of code is terrible) *)\r
+  Randomize;\r
+  for I:=0 to MAXVTX-1 do begin\r
+    with CubeVtx^[I] do begin\r
+      (* Build cube *)\r
+      X := (longint(Random(2*EDGE))-EDGE)*$10000;\r
+      Y := (longint(Random(2*EDGE))-EDGE)*$10000;\r
+      Z := Toggle( EDGE*$10000 );\r
+      case Random(3) of\r
+        0: Swap( X, Z );\r
+        1: Swap( Y, Z );\r
+      end;\r
+    end;\r
+    with SphereVtx^[I] do begin\r
+      (* Build sphere *)\r
+Retry:\r
+      X := (longint(Random(2*RADIUS))-RADIUS);\r
+      Y := (longint(Random(2*RADIUS))-RADIUS);\r
+      if( X*X+Y*Y > RADIUS*RADIUS ) then goto Retry;\r
+      Z := Toggle( Round( Sqrt( Abs( RADIUS*RADIUS-X*X-Y*Y ) ) ) );\r
+      case Random(3) of\r
+        0: Swap( X, Z );\r
+        1: Swap( Y, Z );\r
+      end;\r
+      X := X * $10000; Y := Y * $10000; Z := Z * $10000;\r
+    end;\r
+  end;\r
+  (* Initialize morphing *)\r
+  Move( CubeVtx^, Vtx^, SizeOf(Vtx^) );\r
+  Status := 0;\r
+  Count := WAITCOUNT;\r
+end;\r
+\r
+procedure Morph;\r
+var\r
+  I: integer;\r
+begin\r
+  (* Fully unoptimized, slowest loop I could think of! *)\r
+  for I:=0 to MAXVTX-1 do begin\r
+    Vtx^[I].X := ((CubeVtx^[I].X * Morph1)+(SphereVtx^[I].X * Morph2)) div MS;\r
+    Vtx^[I].Y := ((CubeVtx^[I].Y * Morph1)+(SphereVtx^[I].Y * Morph2)) div MS;\r
+    Vtx^[I].Z := ((CubeVtx^[I].Z * Morph1)+(SphereVtx^[I].Z * Morph2)) div MS;\r
+  end;\r
+end;\r
+\r
+var\r
+  AX, AY, AZ: byte;\r
+  I: word;\r
+  C: char;\r
+begin\r
+  mxInit;\r
+  mxSetMode( MX_320x240 );\r
+  Init;\r
+  Page := 240;          (* Start with hidden page *)\r
+\r
+  AX := 0;\r
+  AY := 0;\r
+  AZ := 0;\r
+  (* Init 3D transforms, perspective is intentionally exaggerated *)\r
+  tdSetTranslation( Trans );\r
+  tdSetPerspective( 400*$10000, $10000, $10000 );\r
+  C := #0;\r
+  repeat\r
+    tdSetRotation( AX, AY, AZ );                (* Set new angles *)\r
+    tdTransform( Vtx^, XVtx^, MAXVTX );         (* 3D transform points *)\r
+    tdTransformToImage( XVtx^, VVtx, MAXVTX, 160, 120+Page );\r
+    Inc( AX, 1 );                               (* Bump angles *)\r
+    Inc( AY, 1 );\r
+    Inc( AZ, 2 );\r
+    mxSetClipRegion( 0, Page, 320, 240 );       (* Set clip to new page *)\r
+    mxSetClip( TRUE );\r
+    mxFillBox( 0, Page, 320, 240, 0, OP_MOVE ); (* Clear screen *)\r
+    (* Draw points *)\r
+    for I:=0 to MAXVTX-1 do\r
+      mxPutPixel( VVtx[I].X, VVtx[I].Y, 128 + XVtx^[I].Z shr 18 );\r
+    mxStartLine( Page );                        (* Flip pages *)\r
+    Page := 240-Page;\r
+    (* Morph *)\r
+    if( Odd(Status) ) then begin\r
+      Morph;\r
+      Inc( Morph1, Delta1 );\r
+      Inc( Morph2, Delta2 );\r
+      if( Morph1 < 0 )or( Morph2 < 0 ) then Inc( Status );\r
+      if( Status = 4 ) then Status := 0;\r
+    end\r
+    else begin\r
+      Dec( Count );\r
+      if( Count < 0 ) then begin\r
+        Inc( Status );\r
+        Count :=  WAITCOUNT;\r
+        Morph1 := InitMorph1[Status];\r
+        Morph2 := InitMorph2[Status];\r
+        Delta1 := InitDelta1[Status];\r
+        Delta2 := InitDelta2[Status];\r
+      end;\r
+    end;\r
+  until( KeyPressed );\r
+\r
+  mxSetMode( MX_TEXT );\r
+  mxTerm;\r
+end.\r
diff --git a/16/xw_/modex/DEMO04.DAT b/16/xw_/modex/DEMO04.DAT
new file mode 100755 (executable)
index 0000000..72aaad0
Binary files /dev/null and b/16/xw_/modex/DEMO04.DAT differ
diff --git a/16/xw_/modex/DEMO04.EXE b/16/xw_/modex/DEMO04.EXE
new file mode 100755 (executable)
index 0000000..1fec5e8
Binary files /dev/null and b/16/xw_/modex/DEMO04.EXE differ
diff --git a/16/xw_/modex/DEMO04.PAS b/16/xw_/modex/DEMO04.PAS
new file mode 100755 (executable)
index 0000000..1a94631
--- /dev/null
@@ -0,0 +1,198 @@
+(*\r
+    DEMO04 - Multiple textures and triple buffering (3 pages)\r
+    (c) 1994 by Alessandro Scotti\r
+*)\r
+uses Crt, Modex, Threed;\r
+\r
+const\r
+  MAXVTX = 256;\r
+  MAXCUB = 2;\r
+  MAXTXT = 2;\r
+  Trans : TPoint = ( X:0; Y:0; Z:0 );\r
+  TxtSunDial: array[ 0..7 ] of word = (\r
+    $7F80,$0080, $0080,$0080, $0080,$7E80, $7F80,$7E80 );\r
+  TxtSapphire : array[ 0..7 ] of word = (\r
+    $0080,$0080, $0080,$1F80, $1F80,$1F80, $1F80,$0080 );\r
+  TxtMarble: array[ 0..7 ] of word = (\r
+    $0080,$8080, $0080,$FD80, $7F80,$FD80, $7F80,$8080 );\r
+type\r
+  T2DPoint = record\r
+    X, Y: integer;\r
+  end;\r
+  TTexture = record\r
+    Desc   : array[ 0..3 ] of record X, Y: word end;\r
+    Width  : word;\r
+    Data   : pointer;\r
+  end;\r
+  TQuad = record\r
+    Vtx    : array[ 0..3 ] of word;\r
+    Texture: word;\r
+  end;\r
+  TCube    = record\r
+    Face   : array[ 0..5 ] of TQuad;\r
+    Base   : integer;\r
+  end;\r
+var\r
+  Vtx, XVtx: array[ 0..MAXVTX ] of TPoint;\r
+  VVtx     : array[ 0..MAXVTX ] of T2DPoint;\r
+  Cube     : array[ 0..MAXCUB ] of TCube;\r
+  ZList    : array[ 0..MAXCUB ] of integer;\r
+  VtxCnt   : word;\r
+  Txts     : array[ 0..MAXTXT ] of TTexture;\r
+  Page     : word;\r
+  Palette  : array[ byte ] of record R, G, B: byte; end;\r
+  TxtDat1, TxtDat2: pointer;\r
+\r
+(* Add a new entry to the vertex array *)\r
+procedure AddVtx( PX, PY, PZ: longint );\r
+begin\r
+  with Vtx[VtxCnt] do begin X:=PX*$10000; Y:=PY*$10000; Z:=PZ*$10000; end;\r
+  Inc( VtxCnt );\r
+end;\r
+\r
+procedure MakeCube( var C: TCube; X1,Y1,Z1, X2,Y2,Z2, TX,TY,TZ, Texture: integer );\r
+const\r
+  FaceIdx: array[ 0..23 ] of integer = (\r
+    0,1,2,3, 0,4,5,1, 1,5,6,2, 2,6,7,3, 3,7,4,0, 6,5,4,7 );\r
+var\r
+  I, VC: integer;\r
+begin\r
+  VC := VtxCnt;\r
+  C.Base := VC;\r
+  AddVtx( X1+TX, Y1+TY, Z1+TZ );\r
+  AddVtx( X2+TX, Y1+TY, Z1+TZ );\r
+  AddVtx( X2+TX, Y2+TY, Z1+TZ );\r
+  AddVtx( X1+TX, Y2+TY, Z1+TZ );\r
+  AddVtx( X1+TX, Y1+TY, Z2+TZ );\r
+  AddVtx( X2+TX, Y1+TY, Z2+TZ );\r
+  AddVtx( X2+TX, Y2+TY, Z2+TZ );\r
+  AddVtx( X1+TX, Y2+TY, Z2+TZ );\r
+  for I:=0 to 23 do C.Face[I shr 2].Vtx[I and 3] := VC+FaceIdx[I];\r
+  for I:=0 to 5 do C.Face[I].Texture := Texture;\r
+end;\r
+\r
+procedure MakeTexture( Idx: integer; var VtxData );\r
+var\r
+  P: ^word;\r
+  I: integer;\r
+begin\r
+  P := @VtxData;\r
+  with Txts[Idx] do begin\r
+    for I:=0 to 3 do begin\r
+      Desc[I].X := P^; Inc( P );\r
+      Desc[I].Y := P^; Inc( P );\r
+    end;\r
+    Width := 129;\r
+    Data := TxtDat1;\r
+  end;\r
+end;\r
+\r
+procedure Init;\r
+var\r
+  I: integer;\r
+  V: integer;\r
+  F: file;\r
+  P: array[ 1..768 ] of byte;\r
+begin\r
+  (* Initialize objects *)\r
+  VtxCnt := 0;\r
+  MakeCube( Cube[0], -64,-64,8, 64,64,-8, 0,0,0, 1 );   (* Sundial *)\r
+  Cube[0].Face[0].Texture := 0;\r
+  V := VtxCnt;\r
+  MakeCube( Cube[1], -16,-16,16, 16,16,-16, 0,0,0, 2 ); (* Sapphire *)\r
+  tdSetTranslation( Trans );\r
+  tdSetRotation( 32, 32, 00 );\r
+  tdRotate( Vtx[V], XVtx[V], 8 );       (* Got to rotate this cube *)\r
+  for I:=V to V+7 do begin\r
+    Vtx[I].X := XVtx[I].X;\r
+    Vtx[I].Y := XVtx[I].Y;\r
+    Vtx[I].Z := XVtx[I].Z + 100*$10000;\r
+  end;\r
+  MakeCube( Cube[2], -64,-4,48, 64,4,-48, 0,68,56, 1 ); (* Marble *)\r
+  (* Load texture and palette *)\r
+  Assign( F, 'DEMO04.DAT' );\r
+  Reset( F, 1 );\r
+  BlockRead( F, P, SizeOf(P) );\r
+  mxSetPalette( @P, 0, 256 );\r
+  GetMem( TxtDat1, 63*1024 );\r
+  BlockRead( F, TxtDat1^, 129*286 );\r
+  Close( F );\r
+  TxtDat2 := Ptr( Seg(TxtDat1^), Ofs(TxtDat1^)+129*254 );\r
+  (* Init textures *)\r
+  MakeTexture( 0, TxtSundial );\r
+  MakeTexture( 1, TxtMarble );\r
+  MakeTexture( 2, TxtSapphire );\r
+  Txts[2].Data := TxtDat2;\r
+end;\r
+\r
+(* Sort procedure, not worth optimizing with only a few objects *)\r
+procedure SortObjects;\r
+var\r
+  I, J, K: integer;\r
+  ZMax: array[ 0..MAXCUB ] of longint;\r
+  ZI: integer;\r
+  L: longint;\r
+begin\r
+  for I:=0 to MAXCUB do begin\r
+    L := XVtx[Cube[I].Base].Z;\r
+    for J:=1 to 7 do\r
+      if( L > XVtx[Cube[I].Base+J].Z ) then L := XVtx[Cube[I].Base+J].Z;\r
+    ZMax[I] := L;\r
+    ZList[I] := I;\r
+  end;\r
+  for I:=0 to MAXCUB-1 do begin\r
+    ZI := I;\r
+    for J:=I+1 to MAXCUB do\r
+      if( ZMax[ZList[J]] > ZMax[ZList[ZI]] ) then ZI := J;\r
+    if( ZI <> I ) then begin\r
+      K := ZList[I];\r
+      ZList[I] := ZList[ZI];\r
+      ZList[ZI] := K;\r
+    end;\r
+  end;\r
+end;\r
+\r
+var\r
+  AX, AY, AZ: byte;\r
+  I, J, K: word;\r
+begin\r
+  mxInit;\r
+  mxSetMode( MX_320x240 );\r
+  Init;\r
+  Page := 240;          (* Start with hidden page *)\r
+\r
+  (* Init 3D transforms, perspective is intentionally exaggerated *)\r
+  AX := 0; AY := 0; AZ := 0;\r
+  tdSetTranslation( Trans );\r
+  tdSetPerspective( 600*$10000, $10000, $10000 );\r
+  (* Main loop, all magic here! *)\r
+  while( not KeyPressed ) do begin\r
+    tdSetRotation( AX, AY, AZ );                (* Set new angles *)\r
+    tdTransform( Vtx, XVtx, VtxCnt );           (* 3D transform points *)\r
+    tdTransformToImage( XVtx, VVtx, VtxCnt, 160, 120+Page );\r
+    Inc( AX, 1 );                               (* Bump angles *)\r
+    Inc( AY, 2 );\r
+    Inc( AZ, 1 );\r
+    mxSetClipRegion( 0, Page, 320, 240 );       (* Set clip to new page *)\r
+    mxSetClip( TRUE );\r
+    mxFillBox( 0, Page, 320, 240, 0, OP_MOVE ); (* Clear screen *)\r
+    (* Draw objects *)\r
+    SortObjects;\r
+    for I:=0 to MAXCUB do with Cube[ZList[I]] do begin\r
+      for J:=0 to 5 do begin\r
+        K := Face[J].Texture;\r
+        mxTexturePoly( 4, Face[J].Vtx, VVtx, Txts[K].Desc, Txts[K].Data^, Txts[K].Width );\r
+      end;\r
+    end;\r
+    (* Flip page: at 320x240 the Start Address Register Low is always zero *)\r
+    case Page of\r
+      0  : begin PortW[$3D4] := $000C; Page := 240; end;\r
+      240: begin PortW[$3D4] := $4B0C; Page := 480; end;\r
+      480: begin PortW[$3D4] := $960C; Page := 0; end;\r
+    end;\r
+    mxWaitRetrace; (* If the frame rate seems low, try to remove this line *)\r
+  end;\r
+\r
+  mxSetMode( MX_TEXT );\r
+  mxTerm;\r
+end.\r
diff --git a/16/xw_/modex/DEMO05.EXE b/16/xw_/modex/DEMO05.EXE
new file mode 100755 (executable)
index 0000000..21a7c20
Binary files /dev/null and b/16/xw_/modex/DEMO05.EXE differ
diff --git a/16/xw_/modex/DEMO05.PAS b/16/xw_/modex/DEMO05.PAS
new file mode 100755 (executable)
index 0000000..819c5cf
--- /dev/null
@@ -0,0 +1,131 @@
+(*\r
+   DEMO05 - A Gouraud-shaded rotating torus\r
+   (c) 1994 Alessandro Scotti\r
+*)\r
+uses Crt, Modex, Threed;\r
+\r
+(* Define ALTPAL for alternate palette *)\r
+{$define ALTPAL}\r
+\r
+const\r
+  MAXVTX1 = 15; RADIUS1 = 70;   (* MAXVTX1+1 must be multiple of 4 *)\r
+  MAXVTX2 = 15; RADIUS2 = 30;\r
+  MAXVTX  = (MAXVTX1+1)*(MAXVTX2+1)-1;\r
+  MAXFACE = MAXVTX;\r
+  Trans : TPoint = ( X:0; Y:0; Z:0 );           (* Object translation *)\r
+  Light : TPoint = ( X:0; Y:0; Z:-63*$10000 );  (* Light direction *)\r
+type\r
+  TQuad   = record\r
+    QVtx  : array[ 0..3 ] of integer;\r
+  end;\r
+var\r
+  Vtx, XVtx : array[ 0..MAXVTX ] of TPoint;     (* Points *)\r
+  VVtx      : array[ 0..MAXVTX ] of record X, Y: integer end;\r
+  Face      : array[ 0..MAXFACE ] of TQuad;     (* Polys *)\r
+  Culled    : array[ 0..MAXFACE ] of integer;\r
+  GNrm,XGNrm: array[ 0..MAXVTX ] of TVector;    (* Gouraud normals *)\r
+  VtxLight  : array[ 0..MAXVTX ] of integer;    (* Points brightness *)\r
+  Page      : word;\r
+\r
+function GetVtx( I1, I2: integer ): integer;\r
+begin\r
+  GetVtx := (I1 mod (MAXVTX1+1))*(MAXVTX2+1) + I2 mod (MAXVTX2+1);\r
+end;\r
+\r
+procedure Init;\r
+var\r
+  R, N, X, Y, Z: real;\r
+  I, J, K, V: integer;\r
+begin\r
+  (* Build vertexes *)\r
+  for I:=0 to MAXVTX1 do begin\r
+    K := (I + (MAXVTX1+1) shr 2) mod (MAXVTX1+1);\r
+    R := RADIUS1 + RADIUS2*Cos( 2*K*Pi / (MAXVTX1+1) );\r
+    for J:=0 to MAXVTX2 do begin\r
+      V := I*(MAXVTX2+1)+J;                     (* Index of current vertex *)\r
+      (* Compute coordinates of current vertex *)\r
+      X := R*Cos(2*J*Pi / (MAXVTX2+1));         (* Get coordinates *)\r
+      Y := R*Sin(2*J*Pi / (MAXVTX2+1));\r
+      Z := RADIUS2*Sin(2*K*Pi / (MAXVTX1+1));\r
+      Vtx[V].X := Round( X )*$10000;            (* Save coordinates *)\r
+      Vtx[V].Y := Round( Y )*$10000;\r
+      Vtx[V].Z := Round( Z )*$10000;\r
+      (* Compute direction of Gouraud normal thru current vertex *)\r
+      X := X - RADIUS1*Cos(2*J*Pi / (MAXVTX2+1));\r
+      Y := Y - RADIUS1*Sin(2*J*Pi / (MAXVTX2+1));\r
+      N := Sqrt( X*X + Y*Y + Z*Z );             (* Get vector length *)\r
+      GNrm[V].X := Trunc( X*$10000/N );         (* Save normal vector *)\r
+      GNrm[V].Y := Trunc( Y*$10000/N );\r
+      GNrm[V].Z := Trunc( Z*$10000/N );\r
+    end;\r
+  end;\r
+  (* Generate faces so that depth-sorting is not needed: there are still *)\r
+  (* some *very* little errors, but this is the best I could devise *)\r
+  J := 0;\r
+  K := 0;\r
+  for I:=0 to MAXFACE do with Face[I] do begin\r
+    QVtx[0] := GetVtx( J, K );\r
+    QVtx[1] := GetVtx( J, K+1 );\r
+    QVtx[2] := GetVtx( J+1, K+1 );\r
+    QVtx[3] := GetVtx( J+1, K );\r
+    Inc( K );\r
+    if( K > MAXVTX2 ) then begin\r
+      K := 0;\r
+      Inc( J );\r
+    end;\r
+  end;\r
+{$ifndef ALTPAL}\r
+  for I:=0 to 63 do mxSetColor( I+64, 0, 0, I );     (* Blue palette *)\r
+{$else}\r
+  for I:=0 to 31 do mxSetColor(I+64, 0, I shl 1, 0); (* Green neon palette *)\r
+  for I:=32 to 63 do mxSetColor ( I+64, (I-32) shl 1, 63, (I-32) shl 1 );\r
+{$endif}\r
+end;\r
+\r
+var\r
+  AX, AY, AZ: byte;\r
+  I: word;\r
+begin\r
+  mxInit;\r
+  mxSetMode( MX_320x240 );\r
+  Init;\r
+  Page := 240;          (* Start with hidden page *)\r
+\r
+  AX := 0;\r
+  AY := 0;\r
+  AZ := 0;\r
+  (* Init 3D transforms, perspective is intentionally exaggerated *)\r
+  tdSetTranslation( Trans );\r
+  tdSetLight( Light );\r
+  tdSetPerspective( 400*$10000, $10000, $10000 );\r
+  (* Main loop, all magic here! *)\r
+  while( not KeyPressed ) do begin\r
+    tdSetRotation( AX, AY, AZ );                (* Set new angles *)\r
+    tdTransform( Vtx, XVtx, MAXVTX+1 );         (* 3D transform points *)\r
+    tdTransformToImage( XVtx, VVtx, MAXVTX+1, 160, 120+Page );\r
+    tdRotate( GNrm, XGNrm, MAXVTX+1 );          (* Rotate Gouraud normals *)\r
+    tdTransformLight( XGNrm, VtxLight, MAXVTX+1 );\r
+    (* Backplane culling is not really needed here! *)\r
+    FillChar( Culled, SizeOf(Culled), 0 );\r
+    tdBackPlaneCull( Face, XVtx, Culled, MAXFACE+1, SizeOf(TQuad) );\r
+    Inc( AX, 1 );                               (* Bump angles *)\r
+    Inc( AY, 2 );\r
+    Inc( AZ, 3 );\r
+    mxSetClipRegion( 0, Page, 320, 240 );       (* Set clip to new page *)\r
+    mxSetClip( TRUE );\r
+    mxFillBox( 0, Page, 320, 240, 0, OP_MOVE ); (* Clear screen *)\r
+    (* Draw polygons *)\r
+    for I:=0 to MAXFACE do with Face[I] do\r
+      if( Culled[I] >= 0 ) then mxGouraudPoly( 4, QVtx, VVtx, VtxLight, 64 );\r
+    (* Flip page: at 320x240 the Start Address Register Low is always zero *)\r
+    case Page of\r
+      0  : begin PortW[$3D4] := $000C; Page := 240; end;\r
+      240: begin PortW[$3D4] := $4B0C; Page := 480; end;\r
+      480: begin PortW[$3D4] := $960C; Page := 0; end;\r
+    end;\r
+    mxWaitRetrace; (* Uncomment this instruction if screen flickers *)\r
+  end;\r
+\r
+  mxSetMode( MX_TEXT );\r
+  mxTerm;\r
+end.\r
diff --git a/16/xw_/modex/DEMO06.DAT b/16/xw_/modex/DEMO06.DAT
new file mode 100755 (executable)
index 0000000..1ac2c2b
Binary files /dev/null and b/16/xw_/modex/DEMO06.DAT differ
diff --git a/16/xw_/modex/DEMO06.EXE b/16/xw_/modex/DEMO06.EXE
new file mode 100755 (executable)
index 0000000..f1308e8
Binary files /dev/null and b/16/xw_/modex/DEMO06.EXE differ
diff --git a/16/xw_/modex/DEMO06.PAS b/16/xw_/modex/DEMO06.PAS
new file mode 100755 (executable)
index 0000000..f26af06
--- /dev/null
@@ -0,0 +1,135 @@
+(*\r
+    DEMO06 - Magnifying glass\r
+    (c) 1994 Alessandro Scotti\r
+*)\r
+uses Crt, Modex;\r
+\r
+const\r
+  R = 40;               (* Lens radius *)\r
+  K : real = 1.8;       (* Magnifying factor, less makes a stronger lens *)\r
+type\r
+  TLine   = array[ 0..319 ] of byte;\r
+  PLine   = ^TLine;\r
+  TScreen = array[ 0..239 ] of PLine;\r
+var\r
+  VScreen: TScreen;                             (* Virtual screen *)\r
+  BallX  : array[ 0..R, 0..R ] of integer;\r
+  BallY  : array[ 0..R, 0..R ] of integer;\r
+  Sprite : array[ -R..R, -R..R ] of byte;\r
+  Page   : word;\r
+\r
+(* Returns "lens-view" coordinates of X,Y *)\r
+procedure GetCoords( var X, Y: integer );\r
+var\r
+  LR, Z, SinA, SinB, TgB, Q: real;\r
+begin\r
+  LR := Sqrt( X*X + Y*Y );\r
+  if( LR = 0 ) then Exit;\r
+  if( LR < R ) then begin\r
+    Z := Sqrt( R*R - LR*LR );\r
+    SinA := LR / R;\r
+    SinB := SinA / K;\r
+    TgB := SinB / Sqrt( 1-SinB*SinB );\r
+    Q := LR - TgB*Z;\r
+    X := Round( X * ( Q/LR ) );\r
+    Y := Round( Y * ( Q/LR ) );\r
+  end;\r
+end;\r
+\r
+procedure Init;\r
+var\r
+  F      : file;\r
+  Palette: array[ 0..767 ] of record R, G, B: byte; end;\r
+  X, Y,\r
+  X2, Y2 : integer;\r
+begin\r
+  (* Load background image *)\r
+  Assign( F, 'demo06.dat' );\r
+  Reset( F, 1 );\r
+  BlockRead( F, Palette, 768 );\r
+  mxSetPalette( @Palette, 0, 256 );\r
+  for Y:=0 to 239 do begin\r
+    New( VScreen[Y] );\r
+    BlockRead( F, VScreen[Y]^, 320 );\r
+    mxPutImage( VScreen[Y], 0, 480+Y, 320, 1, OP_MOVE );\r
+  end;\r
+  Close( F );\r
+  (* Build lens *)\r
+  for X:=0 to R do begin\r
+    for Y:=0 to R do begin\r
+      X2 := X;\r
+      Y2 := Y;\r
+      GetCoords( X2, Y2 );\r
+      BallX[X, Y] := X2;\r
+      BallY[X, Y] := Y2;\r
+    end;\r
+  end;\r
+end;\r
+\r
+procedure PutLens( OX, OY: integer );\r
+var\r
+  X, Y: integer;\r
+begin\r
+  for X:=0 to R do begin\r
+    for Y:=0 to R do begin\r
+      Sprite[Y][X] := VScreen[ OY+BallY[X,Y] ]^[ OX+BallX[X,Y] ];\r
+      Sprite[Y][-X] := VScreen[ OY+BallY[X,Y] ]^[ OX-BallX[X,Y] ];\r
+      Sprite[-Y][X] := VScreen[ OY-BallY[X,Y] ]^[ OX+BallX[X,Y] ];\r
+      Sprite[-Y][-X] := VScreen[ OY-BallY[X,Y] ]^[ OX-BallX[X,Y] ];\r
+    end;\r
+  end;\r
+  (* Draw the sprite *)\r
+  mxPutImage( @Sprite, OX-R, OY-R+Page, 2*R+1, 2*R+1, OP_MOVE );\r
+end;\r
+\r
+function Delta: integer;\r
+begin\r
+  Delta := Random(3)+2;\r
+end;\r
+\r
+procedure Check( Cond: boolean; var Coord, DeltaC: integer; NewCoord, Sign: integer );\r
+begin\r
+  if( Cond ) then begin\r
+    Coord := NewCoord;\r
+    DeltaC := Sign*Delta;\r
+  end;\r
+end;\r
+\r
+var\r
+  X, Y, DX, DY: integer;\r
+  C: char;\r
+begin\r
+  mxInit;\r
+  mxSetMode( MX_320x240 );\r
+  Init;\r
+  Page := 240;\r
+  X := R;\r
+  Y := R;\r
+  Randomize;\r
+  DX := Delta;\r
+  DY := Delta;\r
+\r
+  (* Main loop *)\r
+  repeat\r
+    (* Update video *)\r
+    mxBitBlt( 0, 480, 320, 240, 0, Page );\r
+    PutLens( X, Y );\r
+    mxCircle( X, Page+Y, R, 0 );\r
+    (* Update lens coordinates *)\r
+    Inc( X, DX );\r
+    Check( X+R >= 319, X, DX, 319-R, -1 );\r
+    Check( X <= R, X, DX, R, +1 );\r
+    Inc( Y, DY );\r
+    Check( Y+R >= 239, Y, DY, 239-R, -1 );\r
+    Check( Y <= R, Y, DY, R, +1 );\r
+    (* Flip pages: double buffering, avoid wait for display *)\r
+    case Page of\r
+      0  : begin PortW[$3D4] := $000C; Page := 240; end;\r
+      240: begin PortW[$3D4] := $4B0C; Page := 0; end;\r
+    end;\r
+    mxWaitRetrace; (* Wait for hidden page to show *)\r
+  until( KeyPressed );\r
+\r
+  mxSetMode( MX_TEXT );\r
+  mxTerm;\r
+end.\r
diff --git a/16/xw_/modex/DEMO07.EXE b/16/xw_/modex/DEMO07.EXE
new file mode 100755 (executable)
index 0000000..8a40116
Binary files /dev/null and b/16/xw_/modex/DEMO07.EXE differ
diff --git a/16/xw_/modex/DEMO07.PAS b/16/xw_/modex/DEMO07.PAS
new file mode 100755 (executable)
index 0000000..04fff79
--- /dev/null
@@ -0,0 +1,68 @@
+(*\r
+    DEMO07 - Hardware scrolling\r
+    Copyright (c) 1994 Alessandro Scotti\r
+*)\r
+uses Crt, Modex;\r
+\r
+const\r
+  (* Change this if scrolling seems jerky (this simple program does *)\r
+  (* not handle vertical retrace/display very well) *)\r
+  STEPS = 5;\r
+\r
+procedure Check( Cond: boolean; var Coord, DeltaC: integer; NewCoord, Sign: integer );\r
+begin\r
+  if( Cond ) then begin\r
+    Coord := NewCoord;\r
+    DeltaC := Sign*(Random(3)+2);\r
+  end;\r
+end;\r
+\r
+var\r
+  I, X, Y, DX, DY: integer;\r
+begin\r
+  (* Initialize library and graphics mode *)\r
+  mxInit;\r
+  mxSetMode( MX_320x200 );\r
+  (* Set a 640x400 virtual screen *)\r
+  mxSetVirtualScreen( 640, 400 );\r
+  mxSetClip( TRUE );\r
+\r
+  X := 0;\r
+  Y := 0;\r
+  DX := 1;\r
+  DY := 1;\r
+\r
+  (* Main loop: draw lines, circles, points and rectangles in separate *)\r
+  (* 320x200 windows, while smoothly panning virtual screen *)\r
+  while( not KeyPressed ) do begin\r
+    (* Points *)\r
+    mxSetClipRegion( 0, 0, 320, 200 );\r
+    for I:=1 to STEPS do\r
+      mxPutPixel( Random(320), Random(200), Random(16) );\r
+    (* Lines *)\r
+    mxSetClipRegion( 0, 200, 320, 200 );\r
+    for I:=1 to STEPS do\r
+      mxLine( Random(320), Random(200)+200, Random(320), Random(200)+200, Random(16), OP_SET );\r
+    (* Circles *)\r
+    mxSetClipRegion( 320, 0, 320, 200 );\r
+    for I:=1 to STEPS do\r
+      mxCircle( Random(320)+320, Random(200), Random(100), Random(16) );\r
+    (* Boxes *)\r
+    mxSetClipRegion( 320, 200, 320, 200 );\r
+    for I:=1 to STEPS do\r
+      mxFillBox( Random(320)+320, Random(200)+200, Random(100)+1, Random(100)+1, Random(16), OP_SET );\r
+    (* Pan *)\r
+    Inc( X, DX );\r
+    Check( X+320 >= 639, X, DX, 319, -1 );\r
+    Check( X < 0, X, DX, 0, +1 );\r
+    Inc( Y, DY );\r
+    Check( Y+200 >= 399, Y, DY, 199, -1 );\r
+    Check( Y < 0, Y, DY, 0, +1 );\r
+    mxPan( X, Y );\r
+    mxWaitRetrace;\r
+  end;\r
+\r
+  (* Shutdown *)\r
+  mxSetMode( MX_TEXT );\r
+  mxTerm;\r
+end.\r
diff --git a/16/xw_/modex/MATH.INC b/16/xw_/modex/MATH.INC
new file mode 100755 (executable)
index 0000000..742af41
--- /dev/null
@@ -0,0 +1,34 @@
+;\r
+; MATH.INC - Include file for THREED.ASM\r
+;\r
+\r
+; 3-dimensional point, coordinates in fixed format (16:16)\r
+;\r
+TPOINT  STRUC\r
+        X       DD      ?\r
+        Y       DD      ?\r
+        Z       DD      ?\r
+TPOINT  ENDS\r
+\r
+; 2-dimensional point, coordinates in integer format\r
+;\r
+TIMAGEPOINT     STRUC\r
+        IX      DW      ?\r
+        IY      DW      ?\r
+TIMAGEPOINT     ENDS\r
+\r
+; Fixed-point divide: EAX = EAX / arg\r
+;\r
+.xdiv   MACRO   arg\r
+        xor     edx, edx\r
+        shld    edx, eax, 16\r
+        shl     eax, 16\r
+        idiv    arg\r
+ENDM\r
+\r
+; Fixed-point multiply: EAX = EAX * arg\r
+;\r
+.xmul   MACRO   arg\r
+        imul    arg\r
+        shrd    eax, edx, 16\r
+ENDM\r
diff --git a/16/xw_/modex/PLASMA.PAS b/16/xw_/modex/PLASMA.PAS
new file mode 100755 (executable)
index 0000000..237e292
--- /dev/null
@@ -0,0 +1,103 @@
+unit Plasma;\r
+interface\r
+\r
+const\r
+  PAL_RGB       = 0;\r
+  PAL_CLOUDS    = 1;\r
+  PAL_LANDSCAPE = 2;\r
+\r
+procedure MakePlasma( X, Y: integer; W, H: word; C1, C2, C3, C4: byte );\r
+procedure MakePlasmaPalette( var Palette; What: word );\r
+\r
+implementation uses Modex;\r
+\r
+procedure NewColor( XA, YA, X, Y, XB, YB: integer );\r
+var\r
+  Color: longint;\r
+begin\r
+  Color := Abs( XA-XB )+Abs( YA-YB );\r
+  Color := Random( Color shl 1 )-Color;\r
+  Color := (Color+mxGetPixel( XA, YA )+mxGetPixel( XB, YB )+1) shr 1;\r
+  if( Color < 1 ) then Color := 1;\r
+  if( Color > 192 ) then Color := 192;\r
+  if( mxGetPixel( X, Y ) = 0 ) then\r
+    mxPutPixel( X, Y, Lo(Color) );\r
+end;\r
+\r
+procedure Divide( X1, Y1, X2, Y2: integer );\r
+var\r
+  X, Y, Color: integer;\r
+begin\r
+  if not( (X2-X1<2)and(Y2-Y1<2) ) then begin\r
+    X := (X1+X2) shr 1;\r
+    Y := (Y1+Y2) shr 1;\r
+    NewColor( X1, Y1, X, Y1, X2, Y1 );\r
+    NewColor( X2, Y1, X2, Y, X2, Y2 );\r
+    NewColor( X1, Y2, X, Y2, X2, Y2 );\r
+    NewColor( X1, Y1, X1, Y, X1, Y2 );\r
+    Color := (mxGetPixel( X1, Y1 )+mxGetPixel( X2, Y1 )+\r
+              mxGetPixel( X2, Y2 )+mxGetPixel( X1, Y2 )) shr 2;\r
+    mxPutPixel( X, Y, Color );\r
+    Divide( X1, Y1, X, Y );\r
+    Divide( X, Y1, X2, Y );\r
+    Divide( X, Y, X2, Y2 );\r
+    Divide( X1, Y, X, Y2 );\r
+  end;\r
+end;\r
+\r
+procedure MakePlasma;\r
+begin\r
+  Dec( W );\r
+  Dec( H );\r
+  mxPutPixel( X, Y, C1 );\r
+  mxPutPixel( X, Y+H, C2 );\r
+  mxPutPixel( X+W, Y+H, C3 );\r
+  mxPutPixel( X+W, Y, C4 );\r
+  Divide( X, Y, X+W, Y+H );\r
+end;\r
+\r
+procedure MakePlasmaPalette;\r
+type\r
+  TPal = array[ byte ] of record R, G, B: byte end;\r
+var\r
+  I: word;\r
+begin\r
+  FillChar( TPal(Palette)[1], 192*3, 0 );\r
+  case What of\r
+    PAL_CLOUDS:\r
+      for I:=1 to 192 do begin\r
+        TPal(Palette)[I].R := Abs( I-96 )*63 div 96;\r
+        TPal(Palette)[I].G := Abs( I-96 )*63 div 96;\r
+        TPal(Palette)[I].B := 63;\r
+      end;\r
+    PAL_LANDSCAPE:\r
+      begin\r
+        for I:=0 to 31 do begin\r
+          TPal(Palette)[I+1].R := I;\r
+          TPal(Palette)[I+1].G := I;\r
+          TPal(Palette)[I+1].B := I + I shr 1+15;\r
+        end;\r
+        for I:=32 to 63 do begin\r
+          TPal(Palette)[I+1].R := 0;\r
+          TPal(Palette)[I+1].G := I;\r
+          TPal(Palette)[I+1].B := 0;\r
+        end;\r
+        for I:=64 to 191 do begin\r
+          TPal(Palette)[I+1].R := (I-64) div 3 + 15;\r
+          TPal(Palette)[I+1].G := (I-64) div 3 + 15;\r
+          TPal(Palette)[I+1].B := (I-64) div 3 + 15;\r
+        end;\r
+      end;\r
+    else\r
+      for I:=1 to 64 do begin\r
+        TPal(Palette)[I].G := I-1;\r
+        TPal(Palette)[I].B := 64-I;\r
+        TPal(Palette)[I+64].R := I-1;\r
+        TPal(Palette)[I+64].G := 64-I;\r
+        TPal(Palette)[I+128].B := I-1;\r
+        TPal(Palette)[I+128].R := 64-I;\r
+      end;\r
+  end;\r
+end;\r
+\r
+end.
\ No newline at end of file
diff --git a/16/xw_/modex/QIX2.EXE b/16/xw_/modex/QIX2.EXE
new file mode 100755 (executable)
index 0000000..a10d7db
Binary files /dev/null and b/16/xw_/modex/QIX2.EXE differ
diff --git a/16/xw_/modex/QIX2.PAS b/16/xw_/modex/QIX2.PAS
new file mode 100755 (executable)
index 0000000..d1b5979
--- /dev/null
@@ -0,0 +1,210 @@
+{$E-,N+}\r
+uses Crt, Modex;\r
+\r
+const\r
+  DEFVERT = 12;         (* Vertex count *)\r
+  DEFREPL = 3;          (* Repetition count *)\r
+  DEFQIXS = 2;          (* Qixs *)\r
+  FADESPEED = 48;\r
+type\r
+  TPoint = record\r
+    X, Y : integer;\r
+  end;\r
+  TRGB = record\r
+    R, G, B: byte;\r
+  end;\r
+  TQix = record\r
+    Color: integer;\r
+    Vert : array[ 0..DEFVERT-1, 0..DEFREPL-1 ] of TPoint;\r
+    Delta: array[ 0..DEFVERT-1 ] of TPoint;\r
+  end;\r
+var\r
+  Page : integer;\r
+  MaxX,\r
+  MaxY : word;\r
+  Qix  : array[ 0..DEFQIXS-1 ] of TQix;\r
+  Pal  : array[ byte ] of TRGB;\r
+\r
+type\r
+  TReal = double;\r
+  TRPoint = record\r
+    X, Y: TReal;\r
+  end;\r
+  TMatrix = array[ 0..3, 0..3 ] of TReal;\r
+var\r
+  M: TMatrix;\r
+  G: array[ 0..DEFVERT-1 ] of TRPoint;\r
+  C: array[ 0..DEFVERT-1 ] of TRPoint;\r
+\r
+procedure BumpPal( Idx, DR, DG, DB, Steps: integer );\r
+var\r
+  I: integer;\r
+begin\r
+  for I:=1 to Steps do begin\r
+    Pal[Idx+1].R := Pal[Idx].R + DR;\r
+    Pal[Idx+1].G := Pal[Idx].G + DG;\r
+    Pal[Idx+1].B := Pal[Idx].B + DB;\r
+    Inc( Idx );\r
+  end;\r
+end;\r
+\r
+procedure InitPalette;\r
+begin\r
+  with Pal[0] do begin R:=0; G:=0; B:=0; end;\r
+  with Pal[1] do begin R:=0; G:=0; B:=62; end;\r
+  BumpPal( 1,   0, 2, -2,  31 );\r
+  BumpPal( 32,  2, -2, 0,  31 );\r
+  BumpPal( 63,  -2, 2, 2,  31 );\r
+  BumpPal( 94,  2, 0, -2,  31 );\r
+  BumpPal( 125, -2, -2, 2, 31 );\r
+end;\r
+\r
+procedure Init( var Qix: TQix; Color: integer );\r
+var\r
+  I: integer;\r
+begin\r
+  FillChar( Qix.Vert, SizeOf(Qix.Vert), 0 );\r
+  for I:=0 to DEFVERT-1 do begin\r
+    Qix.Vert[I, DEFREPL-1].X := Random( MaxX );\r
+    Qix.Vert[I, DEFREPL-1].Y := Random( MaxY );\r
+    Qix.Delta[I].X := Random(5)+1;\r
+    Qix.Delta[I].Y := Random(5)+1;\r
+  end;\r
+  Qix.Color := Color;\r
+\r
+  (* Initialize matrix (Catmull-Rom) *)\r
+  M[0,0] := -1/2; M[0,1] := 3/2; M[0,2] := -3/2; M[0,3] := 1/2;\r
+  M[1,0] := 1; M[1,1] := -5/2; M[1,2] := 2; M[1,3] := -1/2;\r
+  M[2,0] := -1/2; M[2,1] := 0; M[2,2] := 1/2; M[2,3] := 0;\r
+  M[3,0] := 0; M[3,1] := 1; M[3,2] := 0; M[3,3] := 0;\r
+end;\r
+\r
+procedure mxBezier( var Qix: TQix; I0, Idx, N: integer );\r
+var\r
+  I, J: integer;\r
+  T, T2, T3: TReal;\r
+  X0, Y0, X, Y: TReal;\r
+  Delta: TReal;\r
+begin\r
+  (* Compute coefficients *)\r
+  for I:=0 to 3 do begin\r
+    C[I].X := 0;\r
+    for J:=0 to 3 do C[I].X := C[I].X + M[I,J]*Qix.Vert[(I0+J) mod DEFVERT,Idx].X;\r
+    C[I].Y := 0;\r
+    for J:=0 to 3 do C[I].Y := C[I].Y + M[I,J]*Qix.Vert[(I0+J) mod DEFVERT,Idx].Y;\r
+  end;\r
+  X0 := C[3].X;\r
+  Y0 := C[3].Y;\r
+  Delta := 1 / N;\r
+  T := 0;\r
+  for I:=1 to N do begin\r
+    T := T + Delta;\r
+    T2 := T*T;\r
+    T3 := T*T2;\r
+    X := C[0].X*T3 + C[1].X*T2 + C[2].X*T + C[3].X;\r
+    Y := C[0].Y*T3 + C[1].Y*T2 + C[2].Y*T + C[3].Y;\r
+    mxLine( Round(X0), Page+Round(Y0), Round(X), Page+Round(Y), Qix.Color, OP_SET );\r
+    X0 := X;\r
+    Y0 := Y;\r
+  end;\r
+end;\r
+\r
+procedure Plot( var Qix: TQix; Idx: integer );\r
+var\r
+  I, J: integer;\r
+begin\r
+  for I:=0 to DEFVERT-1 do begin\r
+    mxBezier( Qix, I, Idx, 12 );\r
+  end;\r
+end;\r
+\r
+procedure Update( var Qix: TQix; Idx: integer );\r
+var\r
+  I: integer;\r
+begin\r
+  for I:=0 to DEFVERT-1 do with Qix do begin\r
+    Inc( Vert[I,Idx].X, Delta[I].X );\r
+    if( Vert[I,Idx].X < 0 ) then begin\r
+      Vert[I,Idx].X := 0;\r
+      Delta[I].X := Random( 5 )+1;\r
+    end;\r
+    if( Vert[I,Idx].X > MaxX ) then begin\r
+      Vert[I,Idx].X := MaxX;\r
+      Delta[I].X := -Random( 5 )-1;\r
+    end;\r
+    Inc( Vert[I,Idx].Y, Delta[I].Y );\r
+    if( Vert[I,Idx].Y < 0 ) then begin\r
+      Vert[I,Idx].Y := 0;\r
+      Delta[I].Y := Random( 5 )+1;\r
+    end;\r
+    if( Vert[I,Idx].Y > MaxY ) then begin\r
+      Vert[I,Idx].Y := MaxY;\r
+      Delta[I].Y := -Random( 5 )-1;\r
+    end;\r
+  end;\r
+end;\r
+\r
+procedure Copy( var Qix: TQix; Dest, Src: integer );\r
+var\r
+  I: integer;\r
+begin\r
+  for I:=0 to DEFVERT-1 do with Qix do begin\r
+    Vert[I,Dest].X := Vert[I,Src].X;\r
+    Vert[I,Dest].Y := Vert[I,Src].Y;\r
+  end;\r
+end;\r
+\r
+procedure AnimateQix;\r
+var\r
+  Q, Idx, I, J, P, Count: integer;\r
+begin\r
+  Count := 0;\r
+  P := DEFREPL-1;\r
+  I := 0;\r
+  J := 1;\r
+  repeat\r
+    mxSetClipRegion( 0, Page, MaxX+1, MaxY+1 );\r
+    mxSetClip( TRUE );\r
+    mxFillBox( 0, Page, MaxX+1, MaxY+1, 0, OP_SET );\r
+    for Q:=0 to DEFQIXS-1 do begin\r
+      Copy( Qix[Q], I, P );\r
+      Update( Qix[Q], I );\r
+      for Idx:=0 to DEFREPL-1 do begin\r
+        Plot( Qix[Q], Idx );\r
+      end;\r
+    end;\r
+    I := (I+1) mod DEFREPL;\r
+    J := (J+1) mod DEFREPL;\r
+    P := (P+1) mod DEFREPL;\r
+    Inc( Count );\r
+    mxStartLine( Page );\r
+    if( Count >= FADESPEED ) then begin\r
+      for Q:=0 to DEFQIXS-1 do begin\r
+        Inc( Qix[Q].Color );\r
+        if( Qix[Q].Color > 156 ) then\r
+          Qix[Q].Color := 1;\r
+      end;\r
+      Count := 0;\r
+    end;\r
+    Page := 240-Page;\r
+  until( KeyPressed );\r
+end;\r
+\r
+var\r
+  I: integer;\r
+begin\r
+  Randomize;\r
+  mxInit;\r
+  mxSetMode( MX_320x240 );\r
+  mxGetScreenSize( MaxX, MaxY );\r
+  for I:=0 to DEFQIXS-1 do\r
+    Init( Qix[I], (I*(155 div DEFQIXS)) mod 155 + 1 );\r
+  InitPalette;\r
+  mxSetPalette( @Pal, 0, 157 );\r
+  Page := 240;\r
+  Dec( MaxX );\r
+  Dec( MaxY );\r
+  AnimateQix;\r
+  mxSetMode( MX_TEXT );\r
+  mxTerm;\r
+end.\r
diff --git a/16/xw_/modex/README.TXT b/16/xw_/modex/README.TXT
new file mode 100755 (executable)
index 0000000..306e8b9
--- /dev/null
@@ -0,0 +1,8 @@
+ModeX - A graphical library for DOS programs\r
+Copyright (c) 1993-1994 Alessandro Scotti\r
+http://www.ascotti.org/\r
+\r
+Please look at the above site in the "Art of..." and\r
+then in the "Old programs" section for more information.\r
+\r
+\r
diff --git a/16/xw_/modex/SINCOS.INC b/16/xw_/modex/SINCOS.INC
new file mode 100755 (executable)
index 0000000..6986eee
--- /dev/null
@@ -0,0 +1,518 @@
+;\r
+; SINCOS.INC - Sin/cos tables for THREED.ASM\r
+;\r
+\r
+tblSin  LABEL DWORD\r
+  DD    0\r
+  DD    411733\r
+  DD    823219\r
+  DD    1234209\r
+  DD    1644455\r
+  DD    2053710\r
+  DD    2461729\r
+  DD    2868265\r
+  DD    3273072\r
+  DD    3675909\r
+  DD    4076531\r
+  DD    4474698\r
+  DD    4870169\r
+  DD    5262706\r
+  DD    5652074\r
+  DD    6038037\r
+  DD    6420363\r
+  DD    6798821\r
+  DD    7173184\r
+  DD    7543226\r
+  DD    7908725\r
+  DD    8269459\r
+  DD    8625213\r
+  DD    8975771\r
+  DD    9320922\r
+  DD    9660458\r
+  DD    9994176\r
+  DD    10321873\r
+  DD    10643353\r
+  DD    10958422\r
+  DD    11266890\r
+  DD    11568571\r
+  DD    11863283\r
+  DD    12150850\r
+  DD    12431097\r
+  DD    12703856\r
+  DD    12968963\r
+  DD    13226258\r
+  DD    13475586\r
+  DD    13716797\r
+  DD    13949745\r
+  DD    14174291\r
+  DD    14390298\r
+  DD    14597637\r
+  DD    14796184\r
+  DD    14985817\r
+  DD    15166424\r
+  DD    15337895\r
+  DD    15500126\r
+  DD    15653022\r
+  DD    15796488\r
+  DD    15930439\r
+  DD    16054795\r
+  DD    16169479\r
+  DD    16274424\r
+  DD    16369565\r
+  DD    16454846\r
+  DD    16530216\r
+  DD    16595628\r
+  DD    16651044\r
+  DD    16696429\r
+  DD    16731757\r
+  DD    16757007\r
+  DD    16772163\r
+  DD    16777216\r
+  DD    16772163\r
+  DD    16757007\r
+  DD    16731757\r
+  DD    16696429\r
+  DD    16651044\r
+  DD    16595628\r
+  DD    16530216\r
+  DD    16454846\r
+  DD    16369565\r
+  DD    16274424\r
+  DD    16169479\r
+  DD    16054795\r
+  DD    15930439\r
+  DD    15796488\r
+  DD    15653022\r
+  DD    15500126\r
+  DD    15337895\r
+  DD    15166424\r
+  DD    14985817\r
+  DD    14796184\r
+  DD    14597637\r
+  DD    14390298\r
+  DD    14174291\r
+  DD    13949745\r
+  DD    13716797\r
+  DD    13475586\r
+  DD    13226258\r
+  DD    12968963\r
+  DD    12703856\r
+  DD    12431097\r
+  DD    12150850\r
+  DD    11863283\r
+  DD    11568571\r
+  DD    11266890\r
+  DD    10958422\r
+  DD    10643353\r
+  DD    10321873\r
+  DD    9994176\r
+  DD    9660458\r
+  DD    9320922\r
+  DD    8975771\r
+  DD    8625213\r
+  DD    8269459\r
+  DD    7908725\r
+  DD    7543226\r
+  DD    7173184\r
+  DD    6798821\r
+  DD    6420363\r
+  DD    6038037\r
+  DD    5652074\r
+  DD    5262706\r
+  DD    4870169\r
+  DD    4474698\r
+  DD    4076531\r
+  DD    3675909\r
+  DD    3273072\r
+  DD    2868265\r
+  DD    2461729\r
+  DD    2053710\r
+  DD    1644455\r
+  DD    1234209\r
+  DD    823219\r
+  DD    411733\r
+  DD    0\r
+  DD    -411733\r
+  DD    -823219\r
+  DD    -1234209\r
+  DD    -1644455\r
+  DD    -2053710\r
+  DD    -2461729\r
+  DD    -2868265\r
+  DD    -3273072\r
+  DD    -3675909\r
+  DD    -4076531\r
+  DD    -4474698\r
+  DD    -4870169\r
+  DD    -5262706\r
+  DD    -5652074\r
+  DD    -6038037\r
+  DD    -6420363\r
+  DD    -6798821\r
+  DD    -7173184\r
+  DD    -7543226\r
+  DD    -7908725\r
+  DD    -8269459\r
+  DD    -8625213\r
+  DD    -8975771\r
+  DD    -9320922\r
+  DD    -9660458\r
+  DD    -9994176\r
+  DD    -10321873\r
+  DD    -10643353\r
+  DD    -10958422\r
+  DD    -11266890\r
+  DD    -11568571\r
+  DD    -11863283\r
+  DD    -12150850\r
+  DD    -12431097\r
+  DD    -12703856\r
+  DD    -12968963\r
+  DD    -13226258\r
+  DD    -13475586\r
+  DD    -13716797\r
+  DD    -13949745\r
+  DD    -14174291\r
+  DD    -14390298\r
+  DD    -14597637\r
+  DD    -14796184\r
+  DD    -14985817\r
+  DD    -15166424\r
+  DD    -15337895\r
+  DD    -15500126\r
+  DD    -15653022\r
+  DD    -15796488\r
+  DD    -15930439\r
+  DD    -16054795\r
+  DD    -16169479\r
+  DD    -16274424\r
+  DD    -16369565\r
+  DD    -16454846\r
+  DD    -16530216\r
+  DD    -16595628\r
+  DD    -16651044\r
+  DD    -16696429\r
+  DD    -16731757\r
+  DD    -16757007\r
+  DD    -16772163\r
+  DD    -16777216\r
+  DD    -16772163\r
+  DD    -16757007\r
+  DD    -16731757\r
+  DD    -16696429\r
+  DD    -16651044\r
+  DD    -16595628\r
+  DD    -16530216\r
+  DD    -16454846\r
+  DD    -16369565\r
+  DD    -16274424\r
+  DD    -16169479\r
+  DD    -16054795\r
+  DD    -15930439\r
+  DD    -15796488\r
+  DD    -15653022\r
+  DD    -15500126\r
+  DD    -15337895\r
+  DD    -15166424\r
+  DD    -14985817\r
+  DD    -14796184\r
+  DD    -14597637\r
+  DD    -14390298\r
+  DD    -14174291\r
+  DD    -13949745\r
+  DD    -13716797\r
+  DD    -13475586\r
+  DD    -13226258\r
+  DD    -12968963\r
+  DD    -12703856\r
+  DD    -12431097\r
+  DD    -12150850\r
+  DD    -11863283\r
+  DD    -11568571\r
+  DD    -11266890\r
+  DD    -10958422\r
+  DD    -10643353\r
+  DD    -10321873\r
+  DD    -9994176\r
+  DD    -9660458\r
+  DD    -9320922\r
+  DD    -8975771\r
+  DD    -8625213\r
+  DD    -8269459\r
+  DD    -7908725\r
+  DD    -7543226\r
+  DD    -7173184\r
+  DD    -6798821\r
+  DD    -6420363\r
+  DD    -6038037\r
+  DD    -5652074\r
+  DD    -5262706\r
+  DD    -4870169\r
+  DD    -4474698\r
+  DD    -4076531\r
+  DD    -3675909\r
+  DD    -3273072\r
+  DD    -2868265\r
+  DD    -2461729\r
+  DD    -2053710\r
+  DD    -1644455\r
+  DD    -1234209\r
+  DD    -823219\r
+  DD    -411733\r
+tblCos  LABEL DWORD\r
+  DD    16777216\r
+  DD    16772163\r
+  DD    16757007\r
+  DD    16731757\r
+  DD    16696429\r
+  DD    16651044\r
+  DD    16595628\r
+  DD    16530216\r
+  DD    16454846\r
+  DD    16369565\r
+  DD    16274424\r
+  DD    16169479\r
+  DD    16054795\r
+  DD    15930439\r
+  DD    15796488\r
+  DD    15653022\r
+  DD    15500126\r
+  DD    15337895\r
+  DD    15166424\r
+  DD    14985817\r
+  DD    14796184\r
+  DD    14597637\r
+  DD    14390298\r
+  DD    14174291\r
+  DD    13949745\r
+  DD    13716797\r
+  DD    13475586\r
+  DD    13226258\r
+  DD    12968963\r
+  DD    12703856\r
+  DD    12431097\r
+  DD    12150850\r
+  DD    11863283\r
+  DD    11568571\r
+  DD    11266890\r
+  DD    10958422\r
+  DD    10643353\r
+  DD    10321873\r
+  DD    9994176\r
+  DD    9660458\r
+  DD    9320922\r
+  DD    8975771\r
+  DD    8625213\r
+  DD    8269459\r
+  DD    7908725\r
+  DD    7543226\r
+  DD    7173184\r
+  DD    6798821\r
+  DD    6420363\r
+  DD    6038037\r
+  DD    5652074\r
+  DD    5262706\r
+  DD    4870169\r
+  DD    4474698\r
+  DD    4076531\r
+  DD    3675909\r
+  DD    3273072\r
+  DD    2868265\r
+  DD    2461729\r
+  DD    2053710\r
+  DD    1644455\r
+  DD    1234209\r
+  DD    823219\r
+  DD    411733\r
+  DD    0\r
+  DD    -411733\r
+  DD    -823219\r
+  DD    -1234209\r
+  DD    -1644455\r
+  DD    -2053710\r
+  DD    -2461729\r
+  DD    -2868265\r
+  DD    -3273072\r
+  DD    -3675909\r
+  DD    -4076531\r
+  DD    -4474698\r
+  DD    -4870169\r
+  DD    -5262706\r
+  DD    -5652074\r
+  DD    -6038037\r
+  DD    -6420363\r
+  DD    -6798821\r
+  DD    -7173184\r
+  DD    -7543226\r
+  DD    -7908725\r
+  DD    -8269459\r
+  DD    -8625213\r
+  DD    -8975771\r
+  DD    -9320922\r
+  DD    -9660458\r
+  DD    -9994176\r
+  DD    -10321873\r
+  DD    -10643353\r
+  DD    -10958422\r
+  DD    -11266890\r
+  DD    -11568571\r
+  DD    -11863283\r
+  DD    -12150850\r
+  DD    -12431097\r
+  DD    -12703856\r
+  DD    -12968963\r
+  DD    -13226258\r
+  DD    -13475586\r
+  DD    -13716797\r
+  DD    -13949745\r
+  DD    -14174291\r
+  DD    -14390298\r
+  DD    -14597637\r
+  DD    -14796184\r
+  DD    -14985817\r
+  DD    -15166424\r
+  DD    -15337895\r
+  DD    -15500126\r
+  DD    -15653022\r
+  DD    -15796488\r
+  DD    -15930439\r
+  DD    -16054795\r
+  DD    -16169479\r
+  DD    -16274424\r
+  DD    -16369565\r
+  DD    -16454846\r
+  DD    -16530216\r
+  DD    -16595628\r
+  DD    -16651044\r
+  DD    -16696429\r
+  DD    -16731757\r
+  DD    -16757007\r
+  DD    -16772163\r
+  DD    -16777216\r
+  DD    -16772163\r
+  DD    -16757007\r
+  DD    -16731757\r
+  DD    -16696429\r
+  DD    -16651044\r
+  DD    -16595628\r
+  DD    -16530216\r
+  DD    -16454846\r
+  DD    -16369565\r
+  DD    -16274424\r
+  DD    -16169479\r
+  DD    -16054795\r
+  DD    -15930439\r
+  DD    -15796488\r
+  DD    -15653022\r
+  DD    -15500126\r
+  DD    -15337895\r
+  DD    -15166424\r
+  DD    -14985817\r
+  DD    -14796184\r
+  DD    -14597637\r
+  DD    -14390298\r
+  DD    -14174291\r
+  DD    -13949745\r
+  DD    -13716797\r
+  DD    -13475586\r
+  DD    -13226258\r
+  DD    -12968963\r
+  DD    -12703856\r
+  DD    -12431097\r
+  DD    -12150850\r
+  DD    -11863283\r
+  DD    -11568571\r
+  DD    -11266890\r
+  DD    -10958422\r
+  DD    -10643353\r
+  DD    -10321873\r
+  DD    -9994176\r
+  DD    -9660458\r
+  DD    -9320922\r
+  DD    -8975771\r
+  DD    -8625213\r
+  DD    -8269459\r
+  DD    -7908725\r
+  DD    -7543226\r
+  DD    -7173184\r
+  DD    -6798821\r
+  DD    -6420363\r
+  DD    -6038037\r
+  DD    -5652074\r
+  DD    -5262706\r
+  DD    -4870169\r
+  DD    -4474698\r
+  DD    -4076531\r
+  DD    -3675909\r
+  DD    -3273072\r
+  DD    -2868265\r
+  DD    -2461729\r
+  DD    -2053710\r
+  DD    -1644455\r
+  DD    -1234209\r
+  DD    -823219\r
+  DD    -411733\r
+  DD    0\r
+  DD    411733\r
+  DD    823219\r
+  DD    1234209\r
+  DD    1644455\r
+  DD    2053710\r
+  DD    2461729\r
+  DD    2868265\r
+  DD    3273072\r
+  DD    3675909\r
+  DD    4076531\r
+  DD    4474698\r
+  DD    4870169\r
+  DD    5262706\r
+  DD    5652074\r
+  DD    6038037\r
+  DD    6420363\r
+  DD    6798821\r
+  DD    7173184\r
+  DD    7543226\r
+  DD    7908725\r
+  DD    8269459\r
+  DD    8625213\r
+  DD    8975771\r
+  DD    9320922\r
+  DD    9660458\r
+  DD    9994176\r
+  DD    10321873\r
+  DD    10643353\r
+  DD    10958422\r
+  DD    11266890\r
+  DD    11568571\r
+  DD    11863283\r
+  DD    12150850\r
+  DD    12431097\r
+  DD    12703856\r
+  DD    12968963\r
+  DD    13226258\r
+  DD    13475586\r
+  DD    13716797\r
+  DD    13949745\r
+  DD    14174291\r
+  DD    14390298\r
+  DD    14597637\r
+  DD    14796184\r
+  DD    14985817\r
+  DD    15166424\r
+  DD    15337895\r
+  DD    15500126\r
+  DD    15653022\r
+  DD    15796488\r
+  DD    15930439\r
+  DD    16054795\r
+  DD    16169479\r
+  DD    16274424\r
+  DD    16369565\r
+  DD    16454846\r
+  DD    16530216\r
+  DD    16595628\r
+  DD    16651044\r
+  DD    16696429\r
+  DD    16731757\r
+  DD    16757007\r
+  DD    16772163\r
diff --git a/16/xw_/modex/THREED.ASM b/16/xw_/modex/THREED.ASM
new file mode 100755 (executable)
index 0000000..5ecd3ba
--- /dev/null
@@ -0,0 +1,872 @@
+COMMENT /\r
+        Fixed-point math functions and 3D transforms\r
+        Copyright (c) 1993,94 by Alessandro Scotti\r
+/\r
+WARN    PRO\r
+P386\r
+JUMPS\r
+LOCALS\r
+\r
+INCLUDE MATH.INC\r
+\r
+PUBLIC  tdFixedMul\r
+PUBLIC  tdGetNormal\r
+PUBLIC  tdRotate\r
+PUBLIC  tdGetSurfaceLight\r
+PUBLIC  tdSetLight\r
+PUBLIC  tdSetRotation\r
+PUBLIC  tdSetTranslation\r
+PUBLIC  tdTransform\r
+PUBLIC  tdTransformToImage\r
+PUBLIC  tdTransformLight\r
+PUBLIC  tdBackPlaneCull\r
+PUBLIC  tdSetPerspective\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Data segment\r
+;\r
+MATH_DATA       SEGMENT USE16 PARA PUBLIC 'DATA'\r
+                ASSUME ds:MATH_DATA\r
+\r
+INCLUDE         SINCOS.INC              ; Fixed 8:24 sin/cos table\r
+\r
+XRotation       TPOINT  <>              ; 3x3 rotation matrix\r
+YRotation       TPOINT  <>\r
+ZRotation       TPOINT  <>\r
+\r
+Translation     TPOINT  <>              ; Translation vector\r
+\r
+Light           TPOINT  <>              ; Light vector\r
+AmbientLight    DW      00              ; Ambient light\r
+\r
+XScale                  DD      10000h  ; Scaling factor for X coordinate\r
+YScale                  DD      10000h  ; Scaling factor for Y coordinate\r
+PerspectiveDistance     DD      20000000h\r
+\r
+MATH_DATA       ENDS\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Code segment\r
+;\r
+MATH_TEXT       SEGMENT USE16 PARA PUBLIC 'CODE'\r
+                ASSUME cs:MATH_TEXT, es:NOTHING, fs:NOTHING\r
+\r
+tdSetPerspective        PROC PASCAL FAR\r
+        ARG     Perspective:DWORD,      \\r
+                ScaleX:DWORD,           \\r
+                ScaleY:DWORD\r
+        USES    ds\r
+\r
+        mov     ax, SEG MATH_DATA\r
+        mov     ds, ax\r
+        ASSUME  ds:MATH_DATA\r
+\r
+        mov     eax, [Perspective]\r
+        mov     [PerspectiveDistance], eax\r
+        mov     eax, [ScaleX]\r
+        mov     [XScale], eax\r
+        mov     eax, [ScaleY]\r
+        mov     [YScale], eax\r
+\r
+        ret\r
+tdSetPerspective        ENDP\r
+\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Sets the rotation matrix.\r
+;\r
+; Input:\r
+;       RX      = X-axis rotation angle\r
+;       RY      = X-axis rotation angle\r
+;       RZ      = X-axis rotation angle\r
+; Output:\r
+;       none\r
+;\r
+tdSetRotation   PROC PASCAL FAR\r
+        ARG     RX:WORD,        \\r
+                RY:WORD,        \\r
+                RZ:WORD\r
+        USES    ds, si, di\r
+\r
+        mov     ax, SEG MATH_DATA\r
+        mov     ds, ax\r
+        ASSUME  ds:MATH_DATA\r
+\r
+        mov     bx, [RZ]\r
+        mov     si, [RY]\r
+        mov     di, [RX]\r
+        shl     bx, 2\r
+        shl     si, 2\r
+        shl     di, 2\r
+\r
+        push    ebp                     ; We use EBP as a scratch register\r
+\r
+; Set X rotation\r
+        mov     eax, tblCos[bx]\r
+        imul    tblCos[si]\r
+        mov     [XRotation.X], edx\r
+\r
+        mov     eax, tblSin[bx]\r
+        imul    tblCos[si]\r
+        mov     [XRotation.Y], edx\r
+\r
+        mov     eax, tblSin[si]\r
+        sar     eax, 8                  ; Convert fixed 8:24 to fixed 16:16\r
+        mov     [XRotation.Z], eax\r
+\r
+; Set Y rotation\r
+        mov     eax, tblCos[bx]\r
+        imul    tblSin[si]              ; EDX:EAX = fixed 16:48\r
+        shrd    eax, edx, 24            ; EAX = fixed 8:24\r
+        imul    tblSin[di]              ; EDX:EAX = fixed 16:48\r
+        mov     ebp, eax\r
+        mov     ecx, edx\r
+        mov     eax, tblSin[bx]\r
+        imul    tblCos[di]\r
+        add     eax, ebp\r
+        adc     edx, ecx                ; EDX:EAX = fixed 16:48\r
+        neg     edx\r
+        mov     [YRotation.X], edx\r
+\r
+        mov     eax, tblSin[bx]\r
+        imul    tblSin[si]\r
+        shrd    eax, edx, 24\r
+        imul    tblSin[di]\r
+        mov     ebp, eax\r
+        mov     ecx, edx\r
+        mov     eax, tblCos[bx]\r
+        imul    tblCos[di]\r
+        sub     eax, ebp\r
+        sbb     edx, ecx\r
+        mov     [YRotation.Y], edx\r
+\r
+        mov     eax, tblCos[si]\r
+        imul    tblSin[di]\r
+        mov     [YRotation.Z], edx\r
+\r
+; Set Z rotation\r
+        mov     eax, tblCos[bx]\r
+        imul    tblSin[si]\r
+        shrd    eax, edx, 24\r
+        imul    tblCos[di]\r
+        mov     ebp, eax\r
+        mov     ecx, edx\r
+        mov     eax, tblSin[bx]\r
+        imul    tblSin[di]\r
+        sub     eax, ebp\r
+        sbb     edx, ecx\r
+        mov     [ZRotation.X], edx\r
+\r
+        mov     eax, tblSin[bx]\r
+        imul    tblSin[si]\r
+        shrd    eax, edx, 24\r
+        imul    tblCos[di]\r
+        mov     ebp, eax\r
+        mov     ecx, edx\r
+        mov     eax, tblCos[bx]\r
+        imul    tblSin[di]\r
+        add     eax, ebp\r
+        add     edx, ecx\r
+        neg     edx\r
+        mov     [ZRotation.Y], edx\r
+\r
+        mov     eax, tblCos[si]\r
+        imul    tblCos[di]\r
+        mov     [ZRotation.Z], edx\r
+\r
+        pop     ebp                     ; Restore EBP\r
+\r
+        ret\r
+tdSetRotation   ENDP\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Sets the translation vector.\r
+;\r
+; Input:\r
+;       TV      = pointer to translation vector\r
+; Output:\r
+;       none\r
+;\r
+tdSetTranslation        PROC PASCAL FAR\r
+        ARG     TV:DWORD\r
+        USES    ds, es, di\r
+\r
+        mov     ax, SEG MATH_DATA\r
+        mov     ds, ax\r
+        ASSUME  ds:MATH_DATA\r
+\r
+        les     di, [TV]\r
+        mov     eax, es:[di].X\r
+        mov     [Translation.X], eax\r
+        mov     eax, es:[di].Y\r
+        mov     [Translation.Y], eax\r
+        mov     eax, es:[di].Z\r
+        mov     [Translation.Z], eax\r
+\r
+        ret\r
+tdSetTranslation        ENDP\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Transforms an array of TPOINT.\r
+;\r
+; Input:\r
+;       Source  = pointer to source array of TPOINT\r
+;       Dest    = pointer to destination array of TPOINT\r
+;       Count   = number of entries to transform\r
+; Output:\r
+;       none\r
+;\r
+tdTransform     PROC PASCAL FAR\r
+        ARG     Source:DWORD,   \\r
+                Dest:DWORD,     \\r
+                Count:WORD\r
+        LOCAL   Adjust:DWORD\r
+        USES    ds, si, es, di, fs\r
+\r
+        mov     ax, SEG MATH_DATA\r
+        mov     ds, ax\r
+        ASSUME  ds:MATH_DATA\r
+\r
+        lfs     si, [Source]\r
+        les     di, [Dest]\r
+\r
+        ALIGN   DWORD\r
+@@Loop:\r
+; Transform Z coordinate\r
+        mov     eax, fs:[si].X\r
+        imul    [ZRotation.X]\r
+        mov     ecx, eax\r
+        mov     ebx, edx\r
+        mov     eax, fs:[si].Y\r
+        imul    [ZRotation.Y]\r
+        add     ecx, eax\r
+        adc     ebx, edx\r
+        mov     eax, fs:[si].Z\r
+        imul    [ZRotation.Z]\r
+        add     eax, ecx\r
+        adc     edx, ebx\r
+        mov     ebx, eax\r
+        shrd    eax, edx, 16\r
+        add     eax, [Translation.Z]    ; EAX = new Z coord (fixed 16:16)\r
+        mov     es:[di].Z, eax\r
+; Get perspective factor\r
+        mov     ebx, [PerspectiveDistance]\r
+        sub     eax, ebx\r
+        neg     eax                     ; EAX = PD - Z\r
+        xor     edx, edx\r
+        shld    edx, eax, 16\r
+        shl     eax, 16\r
+        idiv    ebx                     ; EAX = fixed 16:16 result\r
+        mov     [Adjust], eax\r
+\r
+; Transform X coordinate\r
+        mov     eax, fs:[si].X\r
+        imul    [XRotation.X]\r
+        mov     ecx, eax\r
+        mov     ebx, edx\r
+        mov     eax, fs:[si].Y\r
+        imul    [XRotation.Y]\r
+        add     ecx, eax\r
+        adc     ebx, edx\r
+        mov     eax, fs:[si].Z\r
+        imul    [XRotation.Z]\r
+        add     eax, ecx\r
+        adc     edx, ebx\r
+        shrd    eax, edx, 16\r
+        add     eax, [Translation.X]\r
+        imul    [Adjust]\r
+        shrd    eax, edx, 16\r
+        mov     es:[di].X, eax\r
+\r
+; Transform Y coordinate\r
+        mov     eax, fs:[si].X\r
+        imul    [YRotation.X]\r
+        mov     ecx, eax\r
+        mov     ebx, edx\r
+        mov     eax, fs:[si].Y\r
+        imul    [YRotation.Y]\r
+        add     ecx, eax\r
+        adc     ebx, edx\r
+        mov     eax, fs:[si].Z\r
+        imul    [YRotation.Z]\r
+        add     eax, ecx\r
+        adc     edx, ebx\r
+        shrd    eax, edx, 16\r
+        add     eax, [Translation.Y]\r
+        imul    [Adjust]\r
+        shrd    eax, edx, 16\r
+        mov     es:[di].Y, eax\r
+\r
+        add     si, SIZE TPOINT\r
+        add     di, SIZE TPOINT\r
+        dec     [Count]\r
+        jnz     @@Loop\r
+\r
+        ret\r
+tdTransform     ENDP\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Transforms an array of TPOINT into an array of TIMAGEPOINT.\r
+;\r
+; Input:\r
+;       Source  = pointer to source array of TPOINT\r
+;       Dest    = pointer to destination array of TIMAGEPOINT\r
+;       Count   = number of entries to transform\r
+;       DeltaX  = translation distance for the X coordinate\r
+;       DeltaY  = translation distance for the Y coordinate\r
+; Output:\r
+;       the maximum Z value\r
+;\r
+tdTransformToImage      PROC PASCAL FAR\r
+        ARG     Source:DWORD,   \\r
+                Dest:DWORD,     \\r
+                Count:WORD,     \\r
+                DeltaX:WORD,    \\r
+                DeltaY:WORD\r
+        LOCAL   Adjust:DWORD,   \\r
+                Max:DWORD\r
+        USES    ds, si, es, di, fs\r
+\r
+        mov     ax, SEG MATH_DATA\r
+        mov     ds, ax\r
+        ASSUME  ds:MATH_DATA\r
+\r
+        lfs     si, [Source]\r
+        les     di, [Dest]\r
+        mov     [Max], 80000000h\r
+\r
+@@Loop:\r
+; Check max Z\r
+        mov     eax, fs:[si].Z\r
+        cmp     eax, [Max]\r
+        jle     @@1\r
+        mov     [Max], eax\r
+@@1:\r
+\r
+; Transform X coordinate\r
+        mov     ax, WORD PTR fs:[si].X[2]\r
+        add     ax, [DeltaX]\r
+        mov     es:[di].IX, ax\r
+\r
+; Transform Y coordinate\r
+        mov     ax, WORD PTR fs:[si].Y[2]\r
+        add     ax, [DeltaY]\r
+        mov     es:[di].IY, ax\r
+\r
+        add     si, SIZE TPOINT\r
+        add     di, SIZE TIMAGEPOINT\r
+        dec     [Count]\r
+        jnz     @@Loop\r
+\r
+        mov     eax, [Max]\r
+        shld    edx, eax, 16\r
+        ret\r
+tdTransformToImage      ENDP\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Sets the light source.\r
+;\r
+; Input:\r
+;       Light   = pointer to light vector\r
+; Output:\r
+;       none\r
+;\r
+tdSetLight      PROC PASCAL FAR\r
+        ARG     L:DWORD\r
+        USES    ds, es, di\r
+\r
+        mov     ax, SEG MATH_DATA\r
+        mov     ds, ax\r
+        ASSUME  ds:MATH_DATA\r
+\r
+        les     di, [L]\r
+        mov     eax, es:[di].X\r
+        mov     [Light.X], eax\r
+        mov     eax, es:[di].Y\r
+        mov     [Light.Y], eax\r
+        mov     eax, es:[di].Z\r
+        mov     [Light.Z], eax\r
+\r
+        ret\r
+tdSetLight      ENDP\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Computes light intensity for an array of surfaces.\r
+;\r
+; Input:\r
+;       Normals = pointer to an array of surface normals\r
+;       Lights  = pointer to an array of integer to be filled with\r
+;                 light intensity\r
+;       Count   = number of elements to transform\r
+; Output:\r
+;       none\r
+;\r
+tdTransformLight        PROC PASCAL FAR\r
+        ARG     Normals:DWORD,  \\r
+                Lights:DWORD,   \\r
+                Count:WORD\r
+        USES    ds, si, es, di, fs\r
+\r
+        mov     ax, SEG MATH_DATA\r
+        mov     fs, ax\r
+        ASSUME  fs:MATH_DATA\r
+\r
+        lds     si, [Normals]\r
+        les     di, [Lights]\r
+        ASSUME  ds:NOTHING\r
+\r
+; Intensity is given by the dot product between the Light vector and\r
+; the surface normal\r
+@@Loop:\r
+        mov     eax, ds:[si].Z\r
+        imul    [Light.Z]\r
+        mov     ebx, eax\r
+        mov     ecx, edx\r
+        mov     eax, ds:[si].Y\r
+        imul    [Light.Y]\r
+        add     ebx, eax\r
+        adc     ecx, edx\r
+        mov     eax, ds:[si].X\r
+        imul    [Light.X]\r
+        add     eax, ebx\r
+        adc     edx, ecx                ; EDX:EAX = fixed 32:32 intensity\r
+        add     dx, [AmbientLight]\r
+        test    dx, dx\r
+        jg      @@1\r
+        xor     dx, dx                  ; Return 0 for no light\r
+@@1:\r
+        mov     es:[di], dx\r
+        inc     di\r
+        inc     di\r
+        add     si, SIZE TPOINT\r
+        dec     [Count]\r
+        jnz     @@Loop\r
+\r
+        ASSUME  fs:NOTHING\r
+        ret\r
+tdTransformLight        ENDP\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Returns the light value given the normal to a surface.\r
+;\r
+; Input:\r
+;       Normal  = pointer to TPOINT surface normal vector\r
+; Output:\r
+;       AX      = light intensity (>=0)\r
+; Notes:\r
+;       the normal is rotated according to the current setting.\r
+;\r
+tdGetSurfaceLight       PROC PASCAL FAR\r
+        ARG     Normal:DWORD\r
+        USES    ds, esi, es, di\r
+\r
+        mov     ax, SEG MATH_DATA\r
+        mov     ds, ax\r
+        ASSUME  ds:MATH_DATA\r
+\r
+        les     di, [Normal]\r
+\r
+; Transform Z coordinate\r
+        mov     eax, es:[di].X\r
+        imul    [ZRotation.X]\r
+        mov     ecx, eax\r
+        mov     ebx, edx\r
+        mov     eax, es:[di].Y\r
+        imul    [ZRotation.Y]\r
+        add     ecx, eax\r
+        adc     ebx, edx\r
+        mov     eax, es:[di].Z\r
+        imul    [ZRotation.Z]\r
+        add     eax, ecx\r
+        adc     edx, ebx\r
+        shrd    eax, edx, 16\r
+        imul    [Light.Z]\r
+        shrd    eax, edx, 16\r
+        mov     esi, eax\r
+\r
+; Transform X coordinate\r
+        mov     eax, es:[di].X\r
+        imul    [XRotation.X]\r
+        mov     ecx, eax\r
+        mov     ebx, edx\r
+        mov     eax, es:[di].Y\r
+        imul    [XRotation.Y]\r
+        add     ecx, eax\r
+        adc     ebx, edx\r
+        mov     eax, es:[di].Z\r
+        imul    [XRotation.Z]\r
+        add     eax, ecx\r
+        adc     edx, ebx\r
+        shrd    eax, edx, 16\r
+        imul    [Light.X]\r
+        shrd    eax, edx, 16\r
+        add     esi, eax\r
+\r
+; Transform Y coordinate\r
+        mov     eax, es:[di].X\r
+        imul    [YRotation.X]\r
+        mov     ecx, eax\r
+        mov     ebx, edx\r
+        mov     eax, es:[di].Y\r
+        imul    [YRotation.Y]\r
+        add     ecx, eax\r
+        adc     ebx, edx\r
+        mov     eax, es:[di].Z\r
+        imul    [YRotation.Z]\r
+        add     eax, ecx\r
+        adc     edx, ebx\r
+        shrd    eax, edx, 16\r
+        imul    [Light.X]\r
+        shrd    eax, edx, 16\r
+        add     eax, esi\r
+        shr     eax, 16\r
+\r
+; Add ambient light\r
+        add     ax, [AmbientLight]\r
+        test    ax, ax\r
+        jge     @@Exit\r
+        xor     ax, ax\r
+\r
+@@Exit:\r
+        ret\r
+tdGetSurfaceLight       ENDP\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Rotates an array of TPOINT.\r
+;\r
+; Input:\r
+;       Source  = pointer to source array of TPOINT\r
+;       Dest    = pointer to destination array of TPOINT\r
+;       Count   = number of entries to transform\r
+; Output:\r
+;       none\r
+;\r
+tdRotate        PROC PASCAL FAR\r
+        ARG     Source:DWORD,   \\r
+                Dest:DWORD,     \\r
+                Count:WORD\r
+        USES    ds, si, es, di, fs\r
+\r
+        mov     ax, SEG MATH_DATA\r
+        mov     ds, ax\r
+        ASSUME  ds:MATH_DATA\r
+\r
+        lfs     si, [Source]\r
+        les     di, [Dest]\r
+\r
+@@Loop:\r
+; Transform Z coordinate\r
+        mov     eax, fs:[si].X\r
+        imul    [ZRotation.X]\r
+        mov     ecx, eax\r
+        mov     ebx, edx\r
+        mov     eax, fs:[si].Y\r
+        imul    [ZRotation.Y]\r
+        add     ecx, eax\r
+        adc     ebx, edx\r
+        mov     eax, fs:[si].Z\r
+        imul    [ZRotation.Z]\r
+        add     eax, ecx\r
+        adc     edx, ebx\r
+        shrd    eax, edx, 16\r
+        mov     es:[di].Z, eax\r
+\r
+; Transform X coordinate\r
+        mov     eax, fs:[si].X\r
+        imul    [XRotation.X]\r
+        mov     ecx, eax\r
+        mov     ebx, edx\r
+        mov     eax, fs:[si].Y\r
+        imul    [XRotation.Y]\r
+        add     ecx, eax\r
+        adc     ebx, edx\r
+        mov     eax, fs:[si].Z\r
+        imul    [XRotation.Z]\r
+        add     eax, ecx\r
+        adc     edx, ebx\r
+        shrd    eax, edx, 16\r
+        mov     es:[di].X, eax\r
+\r
+; Transform Y coordinate\r
+        mov     eax, fs:[si].X\r
+        imul    [YRotation.X]\r
+        mov     ecx, eax\r
+        mov     ebx, edx\r
+        mov     eax, fs:[si].Y\r
+        imul    [YRotation.Y]\r
+        add     ecx, eax\r
+        adc     ebx, edx\r
+        mov     eax, fs:[si].Z\r
+        imul    [YRotation.Z]\r
+        add     eax, ecx\r
+        adc     edx, ebx\r
+        shrd    eax, edx, 16\r
+        mov     es:[di].Y, eax\r
+\r
+        add     si, SIZE TPOINT\r
+        add     di, SIZE TPOINT\r
+        dec     [Count]\r
+        jnz     @@Loop\r
+\r
+        ret\r
+tdRotate        ENDP\r
+\r
+tdFixedMul      PROC PASCAL FAR\r
+        ARG     F1:DWORD,       \\r
+                F2:DWORD\r
+\r
+        mov     eax, [F1]\r
+        imul    [F2]\r
+        shr     eax, 16\r
+\r
+        ret\r
+tdFixedMul      ENDP\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Returns in EAX the square root of EDX:EAX.\r
+;\r
+subSqrt PROC NEAR\r
+        push    esi\r
+        push    edi\r
+\r
+        add     eax, eax\r
+        adc     edx, 0\r
+        mov     eax, edx                ; Just discard the low bits\r
+\r
+        mov     esi, eax\r
+        xor     edi, edi\r
+        shld    edi, esi, 16\r
+        shl     esi, 16\r
+@@Loop:\r
+        mov     ebx, eax\r
+        mul     eax\r
+        add     eax, esi\r
+        adc     edx, edi\r
+        shrd    eax, edx, 1\r
+        shr     edx, 1\r
+        div     ebx\r
+        cmp     eax, ebx\r
+        jne     @@Loop\r
+\r
+; Adjust EAX\r
+        shl     eax, 8\r
+\r
+        pop     edi\r
+        pop     esi\r
+        ret\r
+subSqrt ENDP\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Finds the unitary normal to a given surface.\r
+;\r
+; Input:\r
+;       Dest            = pointer to TPOINT (vector) result\r
+;       P1, P2, P3      = pointer to TPOINT points on surface\r
+; Output:\r
+;       none\r
+; Notes:\r
+;       the normal is given by the cross-product between (P3-P1) and\r
+;       (P2-P1), so its orientation depends on the parameters order.\r
+;\r
+tdGetNormal     PROC PASCAL FAR\r
+        ARG     Dest:DWORD,     \\r
+                P1:DWORD,       \\r
+                P2:DWORD,       \\r
+                P3:DWORD\r
+        LOCAL   V1:TPOINT,      \\r
+                V2:TPOINT,      \\r
+                N:TPOINT\r
+        USES    ds, si, es, di\r
+\r
+; Get vector V1\r
+        lds     si, [P1]\r
+        les     di, [P3]\r
+        mov     eax, es:[di].X\r
+        sub     eax, ds:[si].X\r
+        mov     [V1.X], eax\r
+        mov     eax, es:[di].Y\r
+        sub     eax, ds:[si].Y\r
+        mov     [V1.Y], eax\r
+        mov     eax, es:[di].Z\r
+        sub     eax, ds:[si].Z\r
+        mov     [V1.Z], eax\r
+\r
+; Get vector V2\r
+        les     di, [P2]\r
+        mov     eax, es:[di].X\r
+        sub     eax, ds:[si].X\r
+        mov     [V2.X], eax\r
+        mov     eax, es:[di].Y\r
+        sub     eax, ds:[si].Y\r
+        mov     [V2.Y], eax\r
+        mov     eax, es:[di].Z\r
+        sub     eax, ds:[si].Z\r
+        mov     [V2.Z], eax\r
+\r
+; Get normal vector (V1 x V2)\r
+        mov     eax, [V1.Z]\r
+        imul    [V2.Y]\r
+        mov     ebx, eax\r
+        mov     ecx, edx\r
+        mov     eax, [V1.Y]\r
+        imul    [V2.Z]\r
+        sub     eax, ebx\r
+        sbb     edx, ecx\r
+        shrd    eax, edx, 16\r
+        mov     [N.X], eax\r
+\r
+        mov     eax, [V1.X]\r
+        imul    [V2.Z]\r
+        mov     ebx, eax\r
+        mov     ecx, edx\r
+        mov     eax, [V1.Z]\r
+        imul    [V2.X]\r
+        sub     eax, ebx\r
+        sbb     edx, ecx\r
+        shrd    eax, edx, 16\r
+        mov     [N.Y], eax\r
+\r
+        mov     eax, [V1.Y]\r
+        imul    [V2.X]\r
+        mov     ebx, eax\r
+        mov     ecx, edx\r
+        mov     eax, [V1.X]\r
+        imul    [V2.Y]\r
+        sub     eax, ebx\r
+        sbb     edx, ecx\r
+        shrd    eax, edx, 16\r
+        mov     [N.Z], eax\r
+\r
+; Get normal length\r
+        mov     eax, [N.X]\r
+        imul    eax\r
+        mov     ebx, eax\r
+        mov     ecx, edx\r
+        mov     eax, [N.Y]\r
+        imul    eax\r
+        add     ebx, eax\r
+        adc     ecx, edx\r
+        mov     eax, [N.Z]\r
+        imul    eax\r
+        add     eax, ebx\r
+        adc     edx, ecx                ; EDX:EAX = N.X*N.X + N.Y*N.Y + N.Z*N.Z\r
+        call    subSqrt                 ; EAX = normal length\r
+        mov     ebx, eax\r
+\r
+; Adjust vector and save it\r
+        les     di, [Dest]\r
+        mov     eax, [N.X]\r
+        cdq\r
+        shld    edx, eax, 16\r
+        shl     eax, 16\r
+        idiv    ebx\r
+        mov     es:[di].X, eax\r
+        mov     eax, [N.Y]\r
+        cdq\r
+        shld    edx, eax, 16\r
+        shl     eax, 16\r
+        idiv    ebx\r
+        mov     es:[di].Y, eax\r
+        mov     eax, [N.Z]\r
+        cdq\r
+        shld    edx, eax, 16\r
+        shl     eax, 16\r
+        idiv    ebx\r
+        mov     es:[di].Z, eax\r
+\r
+        ret\r
+tdGetNormal     ENDP\r
+\r
+TPOLY   STRUC\r
+        Vtx     DW      4 DUP(?)\r
+TPOLY   ENDS\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Performs surface removal on an array of polygons.\r
+;\r
+; Input:\r
+;       Poly    = pointer to an array of TPOLY\r
+;       Vertex  = pointer to an array of TPOINT\r
+;       Dest    = pointer to an array of integer\r
+;       Count   = number of polygons to check\r
+;       Step    = size of TPOLY structure\r
+; Output:\r
+;       if the n-th polygon is invisible the n-th entry of the\r
+;       Dest array is set to -1, other entries are not modified\r
+;       (so it's possible to use the Light array for Dest, because\r
+;       the light intensity is always >= 0)\r
+;\r
+tdBackPlaneCull PROC PASCAL FAR\r
+        ARG     Step:WORD,      \\r
+                Poly:DWORD,     \\r
+                Vertex:DWORD,   \\r
+                Dest:DWORD,     \\r
+                Count:WORD\r
+        USES    ds, si, es, di, fs\r
+        ASSUME  ds:NOTHING\r
+\r
+        mov     ds, WORD PTR Vertex[2]\r
+        les     di, [Poly]\r
+        mov     fs, WORD PTR Dest[2]\r
+\r
+@@Loop:\r
+        mov     ax, es:[di].Vtx[2]      ; Index of 2nd vertex\r
+        shl     ax, 2\r
+        mov     bx, ax\r
+        shl     ax, 1\r
+        add     bx, ax                  ; BX = index*SIZE TPOINT\r
+        add     bx, WORD PTR [Vertex]   ; BX = offset of 2nd vertex\r
+        mov     ax, es:[di].Vtx[4]      ; Index of 3rd vertex\r
+        shl     ax, 2\r
+        mov     si, ax\r
+        shl     ax, 1\r
+        add     si, ax\r
+        add     si, WORD PTR [Vertex]   ; SI = offset of 3rd vertex\r
+        mov     ecx, ds:[si].X\r
+        sub     ecx, ds:[bx].X          ; ECX = V3.X-V2.X\r
+        mov     edx, ds:[si].Y\r
+        sub     edx, ds:[bx].Y          ; EDX = V3.Y-V2.Y\r
+        mov     ax, es:[di].Vtx[0]      ; Index of 1st vertex\r
+        shl     ax, 2\r
+        mov     si, ax\r
+        shl     ax, 1\r
+        add     si, ax\r
+        add     si, WORD PTR [Vertex]   ; SI = offset of 1st vertex\r
+        mov     eax, ds:[si].X\r
+        sub     eax, ds:[bx].X          ; EAX = V1.X-V2.X\r
+        mov     esi, ds:[si].Y\r
+        sub     esi, ds:[bx].Y          ; ESI = V1.Y-V2.Y\r
+        imul    edx\r
+        mov     ebx, eax\r
+        xchg    ecx, edx                ; ECX:EBX = (V1.X-V2.X)*(V3.Y-V2.Y)\r
+        mov     eax, esi\r
+        imul    edx                     ; EDX:EAX = (V1.Y-V2.Y)*(V3.X-V2.X)\r
+        sub     eax, ebx\r
+        sbb     edx, ecx\r
+        jl      @@Next                  ; Polygon is visible\r
+        mov     bx, WORD PTR [Dest]     ; FS:BX -> current Dest entry\r
+        mov     WORD PTR fs:[bx], -1    ; Remove polygon\r
+@@Next:\r
+        add     WORD PTR [Dest], 2      ; Next entry for dest\r
+        add     di, [Step]              ; Next polygon\r
+        dec     [Count]\r
+        jnz     @@Loop\r
+\r
+        ret\r
+tdBackPlaneCull ENDP\r
+\r
+MATH_TEXT       ENDS\r
+END\r
diff --git a/16/xw_/modex/THREED.H b/16/xw_/modex/THREED.H
new file mode 100755 (executable)
index 0000000..b993ef8
--- /dev/null
@@ -0,0 +1,32 @@
+typedef struct {\r
+    long    x, y, z;\r
+} TVECTOR;\r
+\r
+#define PVECTOR TVECTOR far *\r
+\r
+#define TPOINT  TVECTOR\r
+#define PPOINT  PVECTOR\r
+\r
+#define VPTR    void far *\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+long far pascal tdFixedMul( long, long );\r
+int  far pascal tdGetSurfaceLight( PPOINT );\r
+long far pascal tdTransformToImage( VPTR, VPTR, short, short, short );\r
+\r
+void far pascal tdBackPlaneCull( VPTR, VPTR, VPTR, short, short );\r
+void far pascal tdGetNormal( VPTR, PPOINT, PPOINT, PPOINT );\r
+void far pascal tdRotate( VPTR, VPTR, short );\r
+void far pascal tdSetLight( PVECTOR );\r
+void far pascal tdSetRotation( short, short, short );\r
+void far pascal tdSetTranslation( PVECTOR );\r
+void far pascal tdSetPerspective( long, long, long );\r
+void far pascal tdTransform( VPTR, VPTR, short );\r
+void far pascal tdTransformLight( VPTR, VPTR, short );\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
diff --git a/16/xw_/modex/THREED.PAS b/16/xw_/modex/THREED.PAS
new file mode 100755 (executable)
index 0000000..8b712c9
--- /dev/null
@@ -0,0 +1,40 @@
+unit ThreeD;\r
+interface\r
+\r
+type\r
+  TVector       = record\r
+    X, Y, Z     : longint;\r
+  end;\r
+  TPoint        = TVector;\r
+\r
+function tdFixedMul( F1, F2: longint ): longint;\r
+function tdGetSurfaceLight( var Normal: TPoint ): integer;\r
+function tdTransformToImage( var Source, Dest; Count, DeltaX, DeltaY: integer ): longint;\r
+\r
+procedure tdBackPlaneCull( var Poly, Vertex, Dest; Count, Step: word );\r
+procedure tdGetNormal( var Dest, P1, P2, P3: TVector );\r
+procedure tdRotate( var Source, Dest; Count: word );\r
+procedure tdSetLight( var Light: TVector );\r
+procedure tdSetRotation( RX, RY, RZ: word );\r
+procedure tdSetTranslation( var TV: TVector );\r
+procedure tdSetPerspective( PD, XF, YF: longint );\r
+procedure tdTransform( var Source, Dest; Count: word );\r
+procedure tdTransformLight( var Source, Dest; Count: word );\r
+\r
+implementation\r
+\r
+function tdGetSurfaceLight;                             external;\r
+procedure tdSetRotation( RX, RY, RZ: word );            external;\r
+procedure tdGetNormal;                                  external;\r
+procedure tdSetTranslation( var TV: TVector );          external;\r
+procedure tdTransform( var Source, Dest; Count: word ); external;\r
+procedure tdRotate;                                     external;\r
+function  tdTransformToImage;                           external;\r
+procedure tdSetLight( var Light: TVector );             external;\r
+procedure tdSetPerspective;                             external;\r
+procedure tdTransformLight;                             external;\r
+function tdFixedMul( F1, F2: longint ): longint;        external;\r
+procedure tdBackPlaneCull;                              external;\r
+{$L THREED}\r
+\r
+end.\r
diff --git a/16/xw_/modex/demo01.c b/16/xw_/modex/demo01.c
new file mode 100755 (executable)
index 0000000..0908fdf
--- /dev/null
@@ -0,0 +1,125 @@
+/*\r
+    DEMO01 - Sprites, page flipping and palette rotation\r
+    Copyright (c) 1994 Alessandro Scotti\r
+*/\r
+uses Crt, Modex;\r
+\r
+#DEFINE MAX_SPRITE 100\r
+type\r
+  (* Sprite structure *)\r
+  TSprite = record\r
+    X, Y : integer;                        (* Sprite coordinates *)\r
+    DX,DY: integer;                        (* Deltas for sprite movement *)\r
+    W, H : integer;                        (* Sprite width and height *)\r
+    Image: array[ 1..16, 1..16 ] of byte;  (* Sprite image data *)\r
+  end;\r
+  (* RGB color structure *)\r
+  TRgb    = record\r
+    R, G, B: byte;\r
+  end;\r
+var\r
+  S      : array[ 1..MAX_SPRITE ] of TSprite;   (* An array of sprites *)\r
+  Palette: array[ byte ] of TRgb;               (* Palette *)\r
+  Page   : word;                                (* Page offset *)\r
+  I      : word;\r
+\r
+(* Initializes a sprite structure *)\r
+procedure sxInit( var S: TSprite );\r
+var\r
+  I: word;\r
+begin\r
+  S.X := Random( 320 );  (* Initialize position with random values *)\r
+  S.Y := Random( 240 );\r
+  S.DX := Random( 7 )-3; (* Initialize speed with random values *)\r
+  S.DY := Random( 7 )-3;\r
+  S.W := 16;             (* Size is fixed in this program *)\r
+  S.H := 16;\r
+  (* The image is a square with a hole inside *)\r
+  FillChar( S.Image, SizeOf(S.Image), Random(15)+1 );\r
+  for I:=5 to 12 do FillChar( S.Image[ I, 5 ], 8, 0 );\r
+end;\r
+\r
+(* Moves a sprite *)\r
+procedure sxMove( var S: TSprite );\r
+begin\r
+  Inc( S.X, S.DX );     (* Get new position *)\r
+  Inc( S.Y, S.DY );\r
+  (* Check sprite position, change delta if needed *)\r
+  if( S.X > 320 ) then begin\r
+    S.X := 320;\r
+    S.DX := -S.DX;\r
+  end;\r
+  if( S.X < -16 ) then begin\r
+    S.X := -16;\r
+    S.DX := -S.DX;\r
+  end;\r
+  if( S.Y > 240 ) then begin\r
+    S.Y := 240;\r
+    S.DY := -S.DY;\r
+  end;\r
+  if( S.Y < -16 ) then begin\r
+    S.Y := -16;\r
+    S.DY := -S.DY;\r
+  end;\r
+  (* Draw the sprite, note the Page offset added to the *)\r
+  (* Y coordinate of the image *)\r
+  mxPutImage( @S.Image, S.X, Page+S.Y, S.W, S.H, OP_TRANS );\r
+end;\r
+\r
+begin\r
+  (* Initialize library *)\r
+  mxInit;\r
+\r
+  (* Enter graphics mode *)\r
+  mxSetMode( MX_320x240 );\r
+\r
+  (* Print initialization message *)\r
+  mxSetTextColor( 15, OP_TRANS );\r
+  mxOutStr( 4, 4, 'Initializing...' );\r
+\r
+  (* Initialize sprites *)\r
+  for I:=1 to MAX_SPRITE do sxInit( S[I] );\r
+\r
+  (* Draw background *)\r
+  for I:=1 to 192 do begin\r
+    mxCircle( 160, 480+120, I, I+63 );\r
+    mxCircle( 161, 480+120, I, I+63 );\r
+  end;\r
+\r
+  (* Compute and set palette *)\r
+  for I:=1 to 192 do with Palette[I+63] do begin\r
+    R := 0;\r
+    G := 0;\r
+    B := 0;\r
+    if( I < 64 ) then\r
+      R := I shr 1+31\r
+    else if( I < 128 ) then\r
+      G := (I-64) shr 1+31\r
+    else\r
+      B := (I-128) shr 1+31;\r
+  end;\r
+  mxSetPalette( @Palette[64], 64, 192 );\r
+\r
+  (* Main loop *)\r
+  Page := 240;\r
+  while( not KeyPressed ) do begin\r
+    (* Set clip region to current page *)\r
+    mxSetClipRegion( 0, Page, 320, 240 );\r
+    mxSetClip( TRUE );\r
+    (* Restore background *)\r
+    mxBitBlt( 0, 480, 320, 240, 0, Page );\r
+    (* Draw sprites *)\r
+    for I:=1 to MAX_SPRITE do sxMove( S[I] );\r
+    (* Print message *)\r
+    mxOutStr( 4, Page+4, 'Some sprites moving...' );\r
+    (* Flip page *)\r
+    mxStartLine( Page );\r
+    Page := 240-Page;\r
+    (* Animate palette *)\r
+    mxSetPalette( @Palette[64], 64, 192 );\r
+    mxRotatePalette( @Palette[64], 192, 3 );\r
+  end;\r
+\r
+  mxSetMode( MX_TEXT );\r
+  mxTerm;\r
+end.\r
diff --git a/16/xw_/readme.txt b/16/xw_/readme.txt
new file mode 100755 (executable)
index 0000000..306e8b9
--- /dev/null
@@ -0,0 +1,8 @@
+ModeX - A graphical library for DOS programs\r
+Copyright (c) 1993-1994 Alessandro Scotti\r
+http://www.ascotti.org/\r
+\r
+Please look at the above site in the "Art of..." and\r
+then in the "Old programs" section for more information.\r
+\r
+\r
index c0f971a16d370391101ee427e83886a7c6fd3338..7e02f9ba25f979521753a9c33e180cad07a76ca3 100755 (executable)
--- a/makefile
+++ b/makefile
@@ -426,18 +426,25 @@ comp: .symbolic
        @upx -9 -qqq x-demo.exe
 
 updatelibs: .symbolic
-       cd $(JSMNLIB)
-       git pull
-       cd ../../../
+       @cd $(JSMNLIB)
+       @git pull
+       @cd ../../../
 
 xlib: .symbolic
        @cd 16/xlib
        @wmake clean
        @wmake all
-       cd ../../
+       @cd ../../
 
 mx: .symbolic
        @cd 16/xw
 #      @wmake clean
        @wmake all
-       cd ../../
+       @cd ../../
+
+x: .symbolic
+       @cd 16/x
+       @wmake -f makefile.wat pee
+       @cd ../xw_/
+       @wmake all
+       @cd ../../