home *** CD-ROM | disk | FTP | other *** search
/ The Party 1994: Try This At Home / disk_image.bin / source / gallery / a_gallry.asm < prev    next >
Assembly Source File  |  1994-06-15  |  14KB  |  555 lines

  1. ; A_GALLRY.ASM -- Main program // A.R-M. 7/93
  2.  
  3. ; (some minor mods, ARM 6/94)
  4.  
  5. ; Assemble with /DSYNCHRO=0 to synchronize with DEMOVT's ticks
  6. ;                        =1 to synchronize with timer
  7. ;                        =2 to run w/o synchronization (when debugging)
  8.  
  9. ;               /DFRAMES =0 to count frames rendered (var PICTURECOUNT)
  10.  
  11. IFNDEF SYNCHRO
  12.         SYNCHRO = 2     ; (default: neither DemoVT nor timer)
  13. ENDIF
  14.  
  15.         Ideal
  16.         MODEL FarStack Compact, Pascal
  17.         Radix 10
  18.         P286
  19.  
  20.         STACK 16384d   ; actually, this program probably doesn't even
  21.                        ; use 1k of stack, but you can't trust residents!
  22.  
  23. MACRO   DefWall   south, west, north, east
  24.           IRP name, <south,west,north,east>
  25.             dw  offset name, seg name
  26.           ENDM
  27.         ENDM
  28.  
  29. MACRO   DefTex name
  30.         FARDATA S_&name
  31. EXTRN   W_&name : Byte
  32.         ENDM
  33.  
  34.         INCLUDE "globals.inc"
  35.         INCLUDE "a_ray_t.inc"
  36.  
  37.         CODESEG
  38.  
  39. ;*EXTRN PonPaletaInicial : NEAR       ; (last minute hack)
  40. ;*EXTRN PonPaletaFinal : NEAR
  41.  
  42. IF SYNCHRO EQ 0
  43.  EXTRN   InitMusic      : NEAR      ; This is VT stuff...
  44.  EXTRN   CallMusic      : NEAR      ; ...I don't understand it either! }:-)
  45.  EXTRN   VTConnectTimer : NEAR
  46.  EXTRN   VTDisconnectTimer : NEAR
  47.  EXTRN   VTGetTickCounter : NEAR
  48.  EXTRN   VTBeginSync    : NEAR
  49.  EXTRN   VTWaitForStart : NEAR
  50. ENDIF
  51.  
  52. EXTRN   RasterOff      : NEAR
  53. EXTRN   RasterOn       : NEAR
  54. EXTRN   InitPageMode   : NEAR
  55. EXTRN   SetActivePage  : NEAR
  56. EXTRN   SetViewPage    : NEAR
  57. EXTRN   BlankPage      : NEAR
  58.  
  59. EXTRN   Render         : NEAR
  60. EXTRN   EyeHeight      : NEAR
  61. EXTRN   InitProjection : NEAR
  62. EXTRN   ReFloor        : NEAR
  63.  
  64. EXTRN InitColumnMemory : NEAR
  65.         DATASEG
  66.  
  67. EXTRN FogDensity : Byte
  68.  
  69.         ScriptPtr DD    ?   ; seg:ofs to script
  70.         IF SYNCHRO NE 0
  71.           TIMER     DD    ?
  72.         ENDIF
  73.         TIMER0    DD    ?   ; timer count when animation started
  74.         LastTimer DD    ?   ; last timer count (to avoid repeating same scene)
  75.         DONE      DW    ?   ; =1 when end of script reached
  76.         CurPage   DW    0   ; current page, I use pages 0,1,2 of the 0..3 available
  77.  
  78. ;*   YaCambiadaPaleta DB 0
  79.  
  80.         LastEye   DW    255d   ; last eye height (to avoid recalculating proj parms)
  81.         LastFog   DB    255d   ; last fog density (3..10) (avoid loading new fog textures)
  82.  
  83.         IFDEF FRAMES
  84.            PICTURECOUNT DW 0      ; this is only for speed measurements,
  85.         ENDIF                     ; it counts total no. of scenes generated
  86.  
  87.         RAY       SRay  <>     ; position&attitude of observer for ray trace
  88.  
  89. ; * Assign textures to block walls *
  90.  
  91. ; Each line defines 4 textures for SWNE walls of blocks with
  92. ; codes 1,2,3,...  (0 is empty block)
  93.  
  94.  
  95.         ;        south    west     north     east
  96.  
  97. MapTextures:
  98.  
  99. ; 1  Exterior wall
  100.  
  101.         DefWall w_outsid, w_outsid, w_outsid, w_outsid
  102.  
  103. ; 2..6 "Inconexia" logo (or anything else)
  104.  
  105.         DefWall w_pic9, w_outsid, w_outsid, w_outsid
  106.         DefWall w_pic9, w_outsid, w_outsid, w_outsid
  107.         DefWall w_pic9, w_outsid, w_outsid, w_outsid
  108.         DefWall w_pic9, w_outsid, w_outsid, w_outsid
  109.         DefWall w_pic9, w_outsid, w_outsid, w_outsid
  110.  
  111. ; 7 Entrance wall
  112.  
  113.         DefWall w_outsid, w_indoor, w_outsid, w_outsid
  114.  
  115. ; 8 Indoor white wall
  116.  
  117.         DefWall w_indoor, w_indoor, w_indoor, w_indoor
  118.  
  119. ; 9 -dummy-
  120.  
  121.         DefWall w_indoor, w_indoor, w_indoor, w_indoor
  122.  
  123. ; 10: full screen (320x200 image)
  124.  
  125.         DefWall w_indoor, w_finale, w_indoor, w_indoor
  126.  
  127. ; 11.. pictures
  128.  
  129.         DefWall w_pic1, w_pic1, w_pic1, w_pic1    ; 11
  130.         DefWall w_pic2, w_pic2, w_pic2, w_pic2    ; 12
  131.         DefWall w_indoor, w_pic3, w_indoor, w_indoor    ; 13
  132.         DefWall w_indoor, w_indoor, w_pic4, w_indoor    ; 14
  133.         DefWall w_pic5, w_pic5, w_pic5, w_pic5    ; 15
  134.         DefWall w_pic6, w_pic6, w_pic6, w_pic6    ; 16
  135.         DefWall w_pic7, w_pic7, w_pic7, w_pic7    ; 17
  136.         DefWall w_pic8, w_pic8, w_pic8, w_pic8    ; 18
  137.         DefWall w_pic9, w_pic9, w_pic9, w_pic9    ; 19
  138.         DefWall w_pic10,w_pic10,w_pic10,w_pic10   ; 20
  139.         DefWall w_pic11,w_pic11,w_pic11,w_pic11   ; 21
  140.         DefWall w_pic12,w_pic12,w_pic12,w_pic12   ; 22
  141.         DefWall w_pic13,w_pic13,w_pic13,w_pic13   ; 23
  142.  
  143.         DefWall w_pic3, w_indoor, w_indoor, w_indoor    ; 24-
  144.  
  145.  
  146. ;    └─ end of DATASEG ─┘
  147.  
  148.  
  149. ; * Declare external texture maps *   (these are FARDATA segs)
  150.  
  151.         DefTex  Outsid      ; outdoors wall texture
  152.         DefTex  Indoor      ; indoors wall texture
  153.         DefTex  Finale      ; 320x200 unscaled picture to use in the end
  154.         DefTex  Pic1        ; picture 1
  155.         DefTex  Pic2        ; picture 2
  156.         DefTex  Pic3        ; picture 3
  157.         DefTex  Pic4        ; picture 4
  158.         DefTex  Pic5        ; picture 5
  159.         DefTex  Pic6        ; picture 6
  160.         DefTex  Pic7        ; picture 7
  161.         DefTex  Pic8        ; picture 8
  162.         DefTex  Pic9        ; picture 9
  163.         DefTex  Pic10       ; picture 10
  164.         DefTex  Pic11       ; picture 11
  165.         DefTex  Pic12       ; picture 12
  166.         DefTex  Pic13       ; picture 13
  167. ; Script segment
  168.  
  169.         FARDATA ScriptSeg
  170.  
  171. ; key-frame info structure
  172.  
  173. STRUC  SKey
  174.        Time      dd     ?     ; time (no. counts)
  175.        Xpos      dd     ?     ; X position (in 1/65536 units of map cell)
  176.        Ypos      dd     ?     ; Y position
  177.        Angle     dw     ?     ; bearing in 45°/256/16 units (/16 to avoid rounding errors)
  178.        Eye       db     ?     ; eye height, 1..199
  179.        Fog       db     ?     ; fog density (3..10)
  180.        ENDS
  181.  
  182. Script:
  183.         INCLUDE "data\script.inc"  ; this is the script that will be executed
  184.  
  185. ; code segment
  186.  
  187.         CODESEG
  188.  
  189. IF SYNCHRO EQ 1
  190.         ; Timer interrupt routine (obsolete)
  191.  
  192.         OrgInt08  DD   ?
  193.  
  194.         TimerInt:
  195.           pushf
  196.           push ax
  197.           push ds
  198.  
  199.           mov ax, seg TIMER
  200.           mov ds, ax
  201. P386
  202.           add [TIMER],3   ; increment timer count  (3 ≈ 50Hz/18.1Hz)
  203. P286
  204.           pop ds
  205.           pop ax
  206.           popf
  207.  
  208.         jmp  [dword ptr cs:OrgInt08]  ; continue w/ org int 8 routine...
  209.  
  210.  
  211.         ; Install timer routine (obsolete)
  212.  
  213.         PROC InstallTimer NEAR
  214.         USES ax, bx, dx, ds, es
  215.  
  216.         ; get original INT 08 vector
  217.  
  218.           mov ax, 3508h
  219.           int 21h            ; es:bx -> int8
  220.  
  221.           mov [word ptr cs:OrgInt08], bx
  222.           mov [word ptr cs:OrgInt08+2], es
  223.  
  224.         ; intercept INT 08
  225.  
  226.           mov ax,cs
  227.           mov ds,ax
  228.           mov dx, offset TimerInt
  229.           mov ax, 2508h
  230.           int 21h
  231.  
  232.         ret
  233.         ENDP
  234.  
  235. ; Remove timer routine from INT (obsolete)
  236.  
  237.         PROC KillTimer NEAR
  238.           pusha
  239.  
  240.         ; restore INT 08
  241.  
  242.           push ds
  243.           mov ax,[word ptr cs:OrgInt08+2]
  244.           mov dx, [word ptr cs:OrgInt08]
  245.           mov ds,ax
  246.           mov ax, 2508h
  247.           int 21h
  248.           pop ds
  249.  
  250.           popa
  251.         ret
  252.         ENDP
  253.  
  254. ENDIF           ; if SYNCHRO EQ 1
  255.  
  256.  
  257. ; Script Draw
  258.  
  259.         PROC ScriptDraw NEAR
  260.         ARG Time : dWord
  261. P386
  262.         LOCAL tmT0 : DWORD, T1mT0 : DWORD, DoRefloor : Byte
  263.         pushad
  264.         push fs
  265.  
  266.           push [CurPage]
  267.           call SetActivePage       ; set page where we'll draw...
  268.  
  269.           mov edx, [Time]           ; get time
  270.  
  271.           lfs di, [ScriptPtr]
  272.  
  273. @@KeepUp:
  274.           add di,SIZE SKey
  275.           cmp [fs:di+SKey.Time],edx
  276.           jbe @@KeepUp
  277.  
  278.           mov al, [fs:di+SKey.Fog]
  279.           cmp al, 255d
  280.           sete [byte ptr DONE]
  281.  
  282.           sub di,SIZE SKey           ; fs:di -> SKey w/ .Time <= Time
  283.  
  284.           mov [word ptr ScriptPtr], di
  285.  
  286.           mov eax, [fs:di+SKey.Time]
  287.           mov ebx, [fs:(di+SIZE SKey)+SKey.Time]
  288.           sub ebx, eax
  289.           mov [T1mT0], ebx         ; T1-T0
  290.           mov ebx, [Time]
  291.           sub ebx, eax
  292.           mov [tmT0], ebx          ; t-T0
  293.  
  294.  
  295. ; Plenty of mul's and div's here, but there's something like
  296. ; 50 times more of them per scene to calculate projection,
  297. ; and even so that only makes for a small fraction of total
  298. ; execution time, so hey, who cares! |-)
  299.  
  300. ; interpolate Xpos:
  301.  
  302.           mov eax, [fs:(di+SIZE SKey)+SKey.Xpos]  ; eax = X1
  303.           mov ebx, [fs:di+SKey.Xpos]              ; eax = X0
  304.           sub eax, ebx
  305.           imul [tmT0]            ; eax = (X1-X0)(t-T0)
  306.           idiv [T1mT0]           ; eax = (X1-X0)(t-T0)/(T1-T0)
  307.           add eax, ebx           ; eax = (X1-X0)(t-T0)/(T1-T0)+X0 = X
  308.  
  309.           mov bx, ax
  310.           shr bx,1               ; from 0..65535 to 0..32767
  311.           mov [RAY.FineX], bx
  312.           shr eax,16
  313.           mov [RAY.MapX], al
  314.  
  315. ; interpolate Ypos:
  316.  
  317.           mov eax, [fs:(di+SIZE SKey)+SKey.Ypos]
  318.           mov ebx, [fs:di+SKey.Ypos]
  319.           sub eax, ebx
  320.           imul [tmT0]
  321.           idiv [T1mT0]
  322.           add eax, ebx
  323.  
  324.           mov bx, ax
  325.           shr bx,1
  326.           mov [RAY.FineY], bx
  327.           shr eax,16
  328.           mov [RAY.MapY], al
  329.  
  330. ; interpolate Angle:
  331.  
  332.           movzx eax, [fs:(di+SIZE SKey)+SKey.Angle]
  333.           movzx ebx, [fs:di+SKey.Angle]
  334.           sub eax, ebx
  335.           imul [tmT0]
  336.           idiv [T1mT0]
  337.           add eax, ebx
  338. ;         shr eax,8      ; this has to do w/ the units used in script for angles
  339.  
  340.           mov bx, ax
  341.           xor bh, bh
  342.           mov [RAY.Angle],  bx
  343.           shr ax,8
  344.           and ax,0007
  345.           mov [RAY.Sector], ax
  346.  
  347.           mov [DoRefloor], 0   ; won't load new floor texture if DoRefloor=0
  348.  
  349. ; interpolate Eye height:
  350.  
  351.           xor eax,eax
  352.           mov al, [fs:(di+SIZE SKey)+SKey.Eye]
  353.           xor ebx,ebx
  354.           mov bl, [fs:di+SKey.Eye]
  355.           sub eax, ebx
  356.           imul [tmT0]
  357.           idiv [T1mT0]
  358.           add eax, ebx
  359.  
  360.           cmp ax, [LastEye]
  361.           je @@sameEye
  362.  
  363.           mov [LastEye], ax
  364.           push ax
  365.           call EyeHeight
  366.           mov [DoRefloor], 1   ; new eye height needs new floor texture
  367.  
  368. @@sameEye:
  369.  
  370. ; update Fog if necessary
  371.  
  372.           mov al,[fs:di+SKey.Fog]
  373.           cmp al, [LastFog]
  374.           je @@sameFog
  375.  
  376.           mov [LastFog], al
  377.           mov [FogDensity], al
  378.           mov [DoRefloor], 1     ; new fog density also needs new floor
  379.  
  380. @@sameFog:
  381.  
  382.           cmp [DoRefloor],1
  383.           jne @@norefloor
  384.  
  385.           call ReFloor
  386.  
  387. @@norefloor:
  388.  
  389.           push [CurPage]
  390.           call SetActivePage
  391.  
  392.           push offset RAY          ; pos&att of observer
  393.           push offset MapTextures  ; texture-map map ;-) address
  394.           call Render
  395.  
  396.           mov ax, [CurPage]
  397.           push ax
  398.           call SetViewPage
  399.  
  400.           inc ax                  ; next page
  401.           cmp ax,3                ; use only 0,1, and 2
  402.           jb @@1
  403.           xor ax, ax
  404. @@1:
  405.           mov [CurPage],ax
  406.  
  407.           pop fs
  408.           popad
  409.           ret
  410. P286
  411.           ENDP
  412.  
  413.  
  414. ; === MAIN PROGRAM ===
  415.  
  416.         STARTUPCODE
  417.  
  418. ; initialize video mode
  419.  
  420.           mov ax,13h            ; enter VGA 320x200x256 mode
  421.           int 10h
  422.  
  423.           call RasterOff        ; Disable raster so we don't show
  424.                                 ; garbage on screen while setting up
  425.  
  426.           call InitPageMode     ; initialize memory mapping
  427.  
  428.           push 0
  429.           call SetActivePage
  430.           call BlankPage
  431.  
  432.           push 0
  433.           call SetViewPage      ; start w/ view page 0 (black)
  434.  
  435. ;*    call PonPaletaInicial
  436.  
  437.           call RasterOn         ; Done w/ setup, enable raster again.
  438.  
  439.  
  440.           call InitColumnMemory
  441.  
  442.  
  443. ; initialize projection
  444.  
  445.           push WindowHeight   ; screen height
  446.           push DistToScreen   ; obs dist to screen
  447.           push 100d           ; eye height
  448.           push WallHeight     ; wall height
  449.           call InitProjection
  450.           call ReFloor
  451.  
  452. ; start drawing on page 1
  453.  
  454.           mov [CurPage],1
  455.  
  456. P386
  457.         ; set pointer to beginning of script
  458.  
  459.           mov [word ptr ScriptPtr+2], seg Script
  460.           mov [word ptr ScriptPtr], offset Script
  461.  
  462. ; draw first frame
  463.  
  464.           mov [LastTimer], 0ffffffffh
  465.           mov [TIMER0], 0
  466.  
  467. IF SYNCHRO EQ 1
  468.           mov [TIMER],0            ; reset TIMER
  469.           mov [DONE], 0            ; set DONE to false
  470.           call InstallTimer
  471. ENDIF
  472.  
  473. IF SYNCHRO EQ 0
  474.           call InitMusic
  475.           or al,al
  476.           jz @@bail
  477. ;          call VTdisconnectTimer
  478. call VTconnectTimer
  479.           call VTBeginSync
  480.           call VTWaitForStart
  481.  
  482.           call VTgetTickCounter
  483. xor eax, eax
  484.           mov [TIMER0], eax
  485. ENDIF
  486.  
  487.           push  0
  488.           push  0
  489.           call ScriptDraw
  490.  
  491.  
  492. @@SCRIPT_LOOP:
  493.  
  494.            mov ah,1
  495.            int 16h
  496.            jnz @@LEAVE
  497.  
  498. IF SYNCHRO EQ 0
  499. ;          REPT 16
  500. ;            call CallMusic     ; doctor's orders... :-?
  501. ;          ENDM
  502.  
  503.           call VTGetTickCounter
  504. ELSE
  505.  
  506.   IF SYNCHRO EQ 2
  507.     add [TIMER], 10d
  508.   ENDIF
  509.   mov eax, [TIMER]
  510.  
  511. ENDIF
  512.  
  513. ;*          cmp [YaCambiadaPaleta], 1
  514. ;*          je @@salta
  515.  
  516. ;*          cmp eax, 1970d      ; change pallete at 1970 ticks (hack)
  517. ;*          jb @@salta
  518.  
  519. ;*      push eax
  520. ;*      call PonPaletaFinal
  521. ;*      pop eax
  522. ;*      mov [YaCambiadaPaleta], 1
  523.  
  524. @@salta:
  525.           cmp eax, [LastTimer]
  526.           je @@SCRIPT_LOOP
  527.  
  528.           mov [LastTimer], eax
  529.           sub eax, [TIMER0]
  530.           push eax
  531.           call ScriptDraw
  532.  
  533. IFDEF FRAMES
  534.           inc [PICTURECOUNT]   ; count frames/sec
  535. ENDIF
  536.           cmp [DONE],1
  537.           jne @@SCRIPT_LOOP
  538.  
  539. @@LEAVE:
  540. IF SYNCHRO EQ 1
  541.           call KillTimer
  542. ENDIF
  543. IF SYNCHRO EQ 0
  544. ;          call VTConnectTimer
  545. ENDIF
  546. @@bail:
  547.           mov ax,3             ; reset text mode
  548.           int 10h
  549.  
  550.           mov ax,4c00h         ; done
  551.           int 21h
  552.  
  553.           END
  554.  
  555.