home *** CD-ROM | disk | FTP | other *** search
/ Fujiology Archive / fujiology_archive_v1_0.iso / !FALCON / LINEOUT / DELTA.ZIP / DELTASRC.ZIP / DELTA.SRC / VOXEL2.SO < prev    next >
Text File  |  2003-01-04  |  20KB  |  1,011 lines

  1. ; A voxelspace rout for delta demo.
  2. ; Based on the one in FungleBeats. Slightly faster when tilt is turned off.
  3. ; Perspective correct and free directional.
  4.  
  5. ;======= OBJECT EQUATES ========
  6.  
  7. Voxel.GENERATE:    =    1
  8.  
  9. ; Voxel controlling values
  10. raylength:    =    64            ; The bigger, the further the view stretches.
  11. tunnelvision:    =    12            ; The lower, the wider the view.
  12.  
  13.             RSRESET
  14. Voxel.heightMap:    RS.B    256*256
  15. Voxel.colorMap:        RS.W    256*256
  16. Voxel.zheight_tbl:    RS.W    raylength*$100
  17. Voxel.cosMulTable:    RS.W    160*raylength
  18. Voxel.BLOCK_SIZE:    RS.B    0
  19.  
  20. ;======= OBJECT TABLE ========
  21.  
  22. * Must be first in object!!
  23. Voxel.table:
  24.     DC.L    DEMOFXMAINLOOP
  25.     DC.L    INIT_DEMOFX
  26.     DC.L    rts
  27.     DC.L    Voxel.setForward
  28.     DC.L    Voxel.goLeft
  29.     DC.L    Voxel.goRight
  30.     DC.L    Voxel.setFall
  31.     DC.L    0
  32.  
  33. ;======= INIT SUBROUTINE ========
  34.  
  35. * OUTPUT: d0.l: 0   = All clear.
  36. *               neg = Error! Not initialized!
  37. INIT_DEMOFX:
  38.     move.l    #Voxel.BLOCK_SIZE,d0
  39.     bsr.l    Mem.register
  40.  
  41. .success:
  42.     moveq    #0,d0
  43.     rts
  44. .error:    moveq    #-1,d0
  45.     rts
  46.  
  47. Voxel.initRealtime:
  48.     bsr.l    Mem.getBlock
  49.     move.l    d0,Voxel.baseAdr
  50.  
  51. ; perspective, rotation precalcs
  52.     bsr    CALC_PERSPTABLES
  53.     bsr    CALC_DISTTABLE
  54.  
  55.     bsr    Voxel.calcCosMulTable
  56.  
  57. ; texture precalcs
  58.     lea    Voxel.goldInstTable,a1
  59.     lea    Voxel.goldPal,a0
  60.     bsr.l    Pal.makeGradientHc
  61.  
  62.     lea    Voxel.chromeInstTable,a1
  63.     lea    Voxel.chromePal,a0
  64.     bsr.l    Pal.makeGradientHc
  65.  
  66.     bsr    Voxel.genMaps
  67.  
  68.     bsr    Voxel.setFall
  69.  
  70.     move.w    monitormode,d0
  71.     cmpi.w    #vga60,d0
  72.     beq.s    .vga60
  73.     cmpi.w    #vga100,d0
  74.     beq.s    .vga100
  75.     cmpi.w    #rgb50,d0
  76.     beq.s    .rgb50
  77. * Unknown monitormode..
  78. .vga60:    move.l    #Voxel.paintVga60,Voxel.paintRout
  79.     move.l    #vga60_16bit_160_200,Voxel.resRout
  80.     rts
  81. .vga100:move.l    #Voxel.paintVga100,Voxel.paintRout
  82.     move.l    #vga100_16bit_160_100,Voxel.resRout
  83.     rts
  84. .rgb50:    move.l    #Voxel.paintRgb50,Voxel.paintRout
  85.     move.l    #rgb50_16bit_320_100,Voxel.resRout
  86.     rts
  87.  
  88. ;======= SCREENINIT SUBROUTINE ========
  89.  
  90. INIT_DEMOFXSCREEN:
  91.     movea.l    scr,a0
  92.     bra.l    CLEAR_320100TSCR
  93.  
  94. ;======= MAINLOOP SUBROUTINE ========
  95.  
  96. DEMOFXMAINLOOP:
  97.     move.l    frmcnt,d0
  98.     sub.l    lastframecount,d0
  99.     bne.s    .init_done
  100.     move.l    d0,-(sp)
  101.     bsr    Voxel.initRealtime
  102.     move.l    (sp)+,d0
  103. .init_done:
  104.     cmpi.l    #3,d0
  105.     bhs.s    .end_screeninit
  106.     bsr    INIT_DEMOFXSCREEN
  107. .end_screeninit:
  108.  
  109.     bsr    UPDATE_OBSERVER
  110.  
  111.     tst.w    Voxel.fallOn
  112.     beq.s    .fall_done
  113.     bsr    Voxel.fallDown
  114. .fall_done:
  115.  
  116.     IFNE    Voxel.GENERATE
  117.     movea.l    Voxel.baseAdr,a1
  118.     movea.l    a1,a2
  119.     adda.l    #Voxel.colorMap,a1
  120.     adda.l    #Voxel.heightMap,a2
  121.     ELSE
  122.     lea    color_pic+20,a1
  123.     lea    height_pic,a2
  124.     ENDC
  125.  
  126.     move.l    Voxel.paintRout,a0
  127.     jsr    (a0)
  128.  
  129.     lea    skyadr_tbl,a0
  130.     move.l    (a0)+,d0
  131.     move.l    (a0)+,-8(a0)
  132.     move.l    (a0),-4(a0)
  133.     move.l    d0,(a0)
  134.  
  135.     lea    scr,a0
  136.     move.l    (a0)+,d0
  137.     move.l    (a0)+,d1
  138.     move.l    (a0),-4(a0)
  139.     move.l    d0,(a0)
  140.     move.l    d1,-8(a0)
  141.  
  142.     movea.l    Voxel.resRout,a0
  143.     suba.l    a1,a1
  144.     move.l    d0,a2
  145. .again:    bsr.l    Screen.requestUpdate
  146.     tst.l    d0
  147.     bmi.s    .again
  148.     clr.l    Voxel.resRout
  149.     rts
  150.  
  151. ;======= OBJECT SUBROUTINES ========
  152.  
  153.     TEXT
  154.  
  155. Voxel.setForward:
  156.     move.w    #64,speed
  157.     rts
  158.  
  159. Voxel.goLeft:
  160.     move.w    playerangle,Voxel.oldAngle
  161.     move.l    $04BC.w,Voxel.turnStart
  162.     move.w    #-1,Voxel.turnDirection
  163.     rts
  164.  
  165. Voxel.goRight:
  166.     move.w    playerangle,Voxel.oldAngle
  167.     move.l    $04BC.w,Voxel.turnStart
  168.     move.w    #+1,Voxel.turnDirection
  169.     rts
  170.  
  171. Voxel.setFall:
  172.     clr.w    Voxel.turnDirection
  173.     clr.w    playerangle
  174.     clr.w    Voxel.oldAngle
  175.     clr.w    playerx
  176.     clr.w    playery
  177.     st    Voxel.fallOn
  178.     move.l    $04BA.w,Voxel.fallStart
  179.     rts
  180.  
  181. Voxel.fallDown:
  182.     move.l    $04BA.w,d0
  183.     sub.l    Voxel.fallStart,d0
  184.     lsl.l    #3,d0
  185.     neg.l    d0
  186.     addi.w    #8000,d0
  187.     cmpi.w    #2000,d0
  188.     bhs.s    .ok
  189.     move.w    #2000,elevation
  190.     clr.w    Voxel.fallOn
  191.     rts
  192. .ok    move.w    d0,elevation
  193.     rts
  194.  
  195. ; Generates heightfield and texture...
  196. Voxel.genMaps:
  197.     move.w    #256,d6
  198.     move.w    #256,d7
  199.     movea.l    Voxel.baseAdr,a0
  200.     adda.l    #Voxel.colorMap,a0
  201.     bsr    Voxel.genMarble
  202.  
  203. ; First, generate the heightfield.
  204. ; This is simply done by scaling up a blocky maze to 8*8 blocks.
  205. ; 32*32 -> 256*256
  206.     lea    Voxel.maze+788,a1
  207.     movea.l    Voxel.baseAdr,a0
  208.     adda.l    #Voxel.heightMap,a0
  209.     moveq    #32-1,d7
  210.  
  211. .h_yloop:
  212.     moveq    #32-1,d6
  213.  
  214. .h_xloop:
  215.     move.b    (a1)+,d0
  216.     lsr.b    #3,d0
  217.     move.w    d0,d1
  218.     lsl.w    #8,d1
  219.     move.b    d0,d1
  220.     move.l    d1,d2
  221.     swap    d2
  222.     move.w    d1,d2
  223.     moveq    #8-1,d5
  224.  
  225. .h_blockloop:
  226.     move.l    d2,(a0)+
  227.     move.l    d2,(a0)+
  228.     adda.w    #256-8,a0
  229.     dbf    d5,.h_blockloop
  230.  
  231.     suba.w    #256*8-8,a0
  232.     dbf    d6,.h_xloop
  233.  
  234.     adda.w    #256*7,a0
  235.     dbf    d7,.h_yloop
  236.  
  237. ; Secondly, make the colortexture.
  238.     movea.l    Voxel.baseAdr,a0
  239.     movea.l    a0,a1
  240.     adda.l    #Voxel.colorMap,a0
  241.     adda.l    #Voxel.heightMap,a1
  242.     lea    Voxel.chromePal,a2
  243.     lea    Voxel.goldPal,a3
  244.     move.w    #256-1,d7
  245.     clr.l    d1
  246.  
  247. .c_yloop:
  248.     move.w    #256-1,d6    
  249.  
  250. .c_xloop:
  251.     move.w    (a0),d1
  252.     move.b    (a1)+,d0
  253.     beq.s    .dark
  254.     move.w    (a2,d1.l*2),(a0)+
  255.     bra.s    .next
  256. .dark:    move.w    (a3,d1.l*2),(a0)+
  257. .next:    dbf    d6,.c_xloop
  258.  
  259.     dbf    d7,.c_yloop
  260.     rts
  261.  
  262. ; Very small and nice 'marble' texture generator.
  263. ; Ripped from lost 4ktro by lucky/inter.
  264. ; INPUT:
  265. ; d6.w=width (w)
  266. ; d7.w=height (w)
  267. ; a0: dst buffer (w*h words)
  268. Voxel.genMarble:
  269.     move.l      A0,-(SP)
  270.  
  271. ; Make a row of noise...
  272.     move.w      D6,D0
  273.     bra.s       marmor_w6
  274. marmor_l0:
  275.     move.w      D1,(A0)+
  276. marmor_w6:
  277.     rol.l       #5,D5
  278.     eori.l      #$3551462F,D5
  279.     addq.l      #1,D5
  280.     move.w      D5,D2
  281.     and.w       #7,D2
  282.     cmp.w       #7,D2
  283.     bne.s       marmor_w4
  284.     moveq       #6,D2
  285. marmor_w4:
  286.     add.w       D2,D1
  287.     subq.w      #3,D1
  288.     bpl.s       marmor_w0
  289.     moveq       #0,D1
  290. marmor_w0:
  291.     cmp.w       #$27,D1
  292.     ble.s       marmor_w1
  293.     moveq       #$27,D1
  294. marmor_w1:
  295.     dbra        D0,marmor_l0
  296.  
  297. ; Back to rowstart...
  298.     move.w      D6,D0
  299.     neg.w       D0
  300.     lsl.w       #1,D0
  301.     lea         0(A0,D0.w),A1
  302.  
  303. ; Average and add a pass of noise to the whole texture (?).
  304. ; a1,a2,a3 lag behind a0, so output hights are 'recycled' for averaging.
  305. ; Nice trick. Very fast.
  306.     lea         2(A1),A2
  307.     lea         4(A2),A3
  308.     move.w      D7,D0
  309.     subq.w      #1,D0
  310.     mulu.w      D6,D0                ; d0.w=w*(h-1)
  311.     subq.w      #1,D0
  312. marmor_l1:
  313.     move.w      (A2)+,D1
  314.     add.w       D1,D1
  315.     add.w       (A1)+,D1
  316.     add.w       (A3)+,D1
  317.     lsr.w       #2,D1
  318.     move.l    d5,d2
  319.     rol.l       #5,D5
  320.     eori.l      #-$3A5E8A3B,D5
  321.     addq.l      #7,D5
  322.     move.w      D5,D2
  323.     and.w       #7,D2
  324.     cmp.w       #7,D2
  325.     bne.s       marmor_w5
  326.     moveq       #6,D2
  327. marmor_w5:
  328.     add.w       D2,D1
  329.     subq.w      #3,D1
  330.     bpl.s       marmor_w2
  331.     moveq       #0,D1
  332. marmor_w2:
  333.     cmp.w       #39,D1
  334.     ble.s       marmor_w3
  335.     moveq       #39,D1
  336. marmor_w3:
  337.     move.w      D1,(A0)+
  338.     dbra        D0,marmor_l1
  339.  
  340.     movea.l     (SP)+,A0
  341.     rts         
  342.  
  343. UPDATE_OBSERVER:
  344. ; Perform turn if required.
  345.     move.w    Voxel.turnDirection,d0
  346.     beq.s    .no_turn
  347.     move.w    $04BC.w,d1
  348.     sub.w    Voxel.turnStart,d1
  349.     mulu.w    #6,d1
  350.     cmpi.w    #sintbllen*5/16,d1
  351.     blt.s    .angle_ok
  352.     move.w    #sintbllen*5/16,d1
  353.     clr.w    Voxel.turnDirection
  354. .angle_ok:
  355.     muls.w    d0,d1
  356.     add.w    Voxel.oldAngle,d1
  357.     move.w    d1,playerangle
  358. .no_turn:
  359.  
  360. ; Update player position..
  361.     move.w    speed(pc),d3
  362.     move.l    $4ba.w,d1
  363.     move.l    d1,d2
  364.     sub.l    .last4ba(pc),d1
  365.     move.l    d2,.last4ba
  366.     muls.w    d1,d3
  367.     asr.w    #4,d3
  368.     move.w    playerangle,d0
  369.     Do_SinModulo    d0
  370.     move.w    (xanglestep_tbl,d0.w*2),d1
  371.     move.w    (yanglestep_tbl,d0.w*2),d2
  372.     muls.w    d3,d1
  373.     muls.w    d3,d2
  374.     asr.w    #4,d1
  375.     asr.w    #4,d2
  376.     add.w    d1,playerx
  377.     add.w    d2,playery
  378.     rts
  379.  
  380. .last4ba:
  381.     DC.L    0
  382. speed:    DC.W    0
  383.  
  384. CALC_PERSPTABLES:
  385. ; Calculate conventional 1/Z-table first.
  386.     lea    persp_tbl,a0
  387.     move.l    #$FFFF,d1
  388.     moveq    #1,d7
  389.     move.w    #raylength,d6
  390. .loop:    move.l    d1,d0
  391.     move.w    d7,d4
  392.     divu.w    d4,d0
  393.     move.w    d0,(a0)+
  394.     addq.w    #1,d7
  395.     cmp.w    d6,d7
  396.     bls.s    .loop
  397.  
  398. ; Then calculate precalced 2d-height for the 256 3d-heights at every Z
  399. ; point.
  400. ; 2d_height = get2dHeight(h,z)
  401.     movea.l    Voxel.baseAdr,a0
  402.     adda.l    #Voxel.zheight_tbl,a0
  403.     lea    persp_tbl,a1
  404.     move.w    #raylength-1,d7
  405.  
  406. .loop2:    move.w    (a1)+,d3                ; d3.w=1/z
  407.     clr.w    d2
  408.  
  409. .inloop2:
  410.     move.w    d3,d0
  411.     mulu.w    d2,d0
  412.     lsl.l    #5,d0                    ; Increase height a bit
  413.     tst.w    d0
  414.     swap    d0
  415.     bpl.s    .end_round
  416.     addq.w    #1,d0
  417. .end_round:
  418.     move.w    d0,(a0)+
  419.     addq.b    #1,d2
  420.     bne.s    .inloop2
  421.  
  422.     dbf    d7,.loop2
  423.  
  424.     rts
  425.  
  426. CALC_DISTTABLE:
  427.     lea    xanglestep_tbl,a0
  428.     lea    yanglestep_tbl,a1
  429.     lea    sine_tbl,a2
  430.     move.w    eyedistance,d2
  431.     move.w    raydistance,d3
  432.     move.w    #tunnelvision,d6
  433.     move.w    #sintbllen-1,d7
  434. .loop    movem.w    (a2)+,d0-d1            * Get next sin and cos.
  435.     move.w    d0,d4
  436.     move.w    d1,d5
  437.     muls.w    d2,d4
  438.     muls.w    d2,d5
  439.     muls.w    d3,d0
  440.     muls.w    d3,d1
  441.     sub.l    d4,d0
  442.     sub.l    d5,d1
  443.     asr.l    #8,d0
  444.     divs.w    d6,d0
  445.     move.w    d0,(a1)+
  446.     asr.l    #8,d1
  447.     divs.w    d6,d1
  448.     move.w    d1,(a0)+
  449.     dbra    d7,.loop
  450.     rts
  451.  
  452. Voxel.calcCosMulTable:
  453.     movea.l    Voxel.baseAdr,a0
  454.     adda.l    #Voxel.cosMulTable,a0
  455.     lea    sine_tbl,a1
  456.     move.w    #-240,d0            ; d0.w=a
  457.  
  458. .columnloop:    
  459.     move.w    d0,d2
  460.     Do_SinModulo    d2
  461.     Get_Cos    a1,d2,d1            ; d1.w=cos(a)
  462.     moveq    #0,d7                ; d7.w=dist
  463.  
  464. .rayloop:
  465.     move.w    d7,d2
  466.     muls.w    d1,d2
  467.     add.l    d2,d2
  468.     swap    d2                ; d2.w=cos(a)*dist
  469.     tst.w    d2
  470.     bpl.s    .end_round
  471.     addq.w    #1,d2
  472. .end_round:
  473.     move.w    d2,(a0)+            ; Store cos(a)*dist.
  474.     addq.w    #1,d7
  475.     cmpi.w    #raylength,d7
  476.     blt.s    .rayloop
  477.  
  478.     addq.w    #3,d0
  479.     cmpi.w    #240,d0
  480.     blt.s    .columnloop
  481.     rts
  482.  
  483. ; Draw the Voxel.
  484. ; INPUT:
  485. ; a1: color map
  486. ; a2: height-field
  487. Voxel.paintVga100:
  488. ; Initialize projected heigth for this evelation and roll.
  489.     lea    Voxel.persp_tbl(pc),a0
  490.     move.w    roll,d3
  491.     move.w    elevation,d1
  492.     moveq    #1,d7
  493.     move.l    #$FFFF,d2
  494.  
  495. .proj_heigth_loop:
  496.     move.l    d2,d0
  497.     move.w    d7,d4
  498.     divu.w    d4,d0
  499.     mulu.w    d1,d0
  500.     tst.w    d0
  501.     swap    d0
  502.     bpl.s    .end_round
  503.     addq.w    #1,d0
  504. .end_round:
  505.     add.w    d3,d0
  506.     move.w    d0,(a0)+
  507.     addq.w    #1,d7
  508.     cmpi.w    #raylength,d7
  509.     blt.s    .proj_heigth_loop
  510.  
  511. ; Initialize angle of first ray..
  512.     moveq    #0,d1
  513.     move.w    playerangle(pc),d1
  514.     subi.w    #240,d1
  515.     Do_SinModulo    d1
  516.     move.w    d1,Voxel.rayangle
  517.  
  518. ; Plot voxel.
  519.     movea.l    skyadr_tbl,a5
  520.     movea.l    scr,a0
  521.     adda.l    #160*99*2,a0
  522.     move.w    #160-1,d7
  523.     move.l    a0,Voxel.screen
  524.     clr.l    d2
  525.     move.w    Voxel.rayangle(pc),d0
  526.     move.l    #-160*2,d6
  527.     movea.l    Voxel.baseAdr,a6
  528.     adda.l    #Voxel.cosMulTable,a6
  529.     lea    Voxel.persp_tbl(pc),a4
  530.     clr.l    d4
  531.  
  532. .column_loop:
  533.     move.w    d7,d1
  534.     subi.w    #160/2-1,d1
  535.     muls.w    tiltx(pc),d1
  536.     swap    d1
  537.     move.w    d1,Voxel.tiltfactor
  538.  
  539.     swap    d7
  540.     move.w    playerx(pc),d1
  541.     move.w    playery(pc),d2
  542.     lea    Voxel.gxstep(pc),a3
  543.     move.w    (xanglestep_tbl,d0.w*2),(a3)+
  544.     move.w    (yanglestep_tbl,d0.w*2),(a3)+
  545.  
  546.     move.w    Voxel.rayangle(pc),d0
  547.     sub.w    playerangle(pc),d0
  548.     Do_SinModulo    d0
  549.     move.w    (sine_tbl+2,d0.w*4),Voxel.cos
  550.  
  551.     moveq    #100,d0                * topmountain:=scrlines
  552.     movea.l    Voxel.baseAdr,a3
  553.     adda.l    #Voxel.zheight_tbl,a3
  554.     move.w    #raylength-1,d7            * Number of steps in ray..
  555. .rayloop:
  556.     move.l    d2,d5
  557.     move.w    d1,d4
  558.     lsr.w    #8,d4
  559.     move.b    d4,d5                ; d5.l=position in map
  560.     move.w    (a6)+,d4            ; d4.w=z=distance*cos(a)
  561.     move.w    (a4,d4.l*2),d3            ; d3.w=elevation/z+roll
  562.     lsl.l    #8,d4                ; d4.l=z*$100
  563.     move.b    (a2,d5.l),d4            ; d4.l=z*$100+h
  564.     sub.w    (a3,d4.l*2),d3            ; d3.w= projected h = elevation/z+roll-h/z
  565. ; d3.w= ph = (elevation-h)/z + roll
  566. ;    add.w    Voxel.tiltfactor(pc),d3        ; Add tilt.
  567.     move.w    d0,d4
  568.     sub.w    d3,d4
  569. ; d4.w = dph = top - ph
  570.     ble.s    .endl
  571. ; Projected height out of screen?
  572.     tst.w    d3
  573.     bpl.s    .draw_line
  574.     lea    (a6,d7.w*2),a6            ; a6: next z column
  575.     move.w    d0,d4
  576.     beq.s    .next_column
  577.     clr.w    d7                ; End of ray.
  578.     clr.l    d3                ; ph=0
  579. .draw_line:
  580.     move.w    (a1,d5.l*2),d5            ; d5.w=color
  581.     subq.w    #1,d4
  582. .pixlp:    move.w    d5,(a0)
  583.     adda.l    d6,a0                ; Go up one screenline.
  584.     dbf    d4,.pixlp
  585.     move.w    d3,d0                ; top=ph
  586. ; Move to next map-pos.
  587. .endl:    add.w    Voxel.gxstep(pc),d1
  588.     add.w    Voxel.gystep(pc),d2
  589.     dbf    d7,.rayloop
  590.  
  591. .next_column:
  592. ; Restore background slice.
  593.     move.w    (a5),d1
  594.     move.w    d0,(a5)+
  595.     sub.w    d1,d0
  596.     ble.s    .no_background_restore
  597.     subq.w    #1,d0
  598.     clr.w    d1
  599. .restore_loop:
  600.     move.w    d1,(a0)
  601.     adda.l    d6,a0                * Go up one screenline.
  602.     dbf    d0,.restore_loop
  603. .no_background_restore:
  604. ; Increase angle..
  605.     move.w    Voxel.rayangle(pc),d0
  606.     addq.w    #3,d0
  607.     Do_SinModulo    d0
  608.     move.w    d0,Voxel.rayangle
  609. ; Kick in next vertical screenline and loop..
  610.     addq.l    #2,Voxel.screen
  611.     movea.l    Voxel.screen(pc),a0
  612.     swap    d7
  613.     dbf    d7,.column_loop
  614.     rts
  615.  
  616. ; Draw the Voxel.
  617. ; INPUT:
  618. ; a1: color map
  619. ; a2: height-field
  620. Voxel.paintVga60:
  621. ; Initialize projected heigth for this evelation and roll.
  622.     lea    Voxel.persp_tbl(pc),a0
  623.     move.w    roll,d3
  624.     move.w    elevation,d1
  625.     moveq    #1,d7
  626.     move.l    #$FFFF,d2
  627.  
  628. .proj_heigth_loop:
  629.     move.l    d2,d0
  630.     move.w    d7,d4
  631.     divu.w    d4,d0
  632.     mulu.w    d1,d0
  633.     tst.w    d0
  634.     swap    d0
  635.     bpl.s    .end_round
  636.     addq.w    #1,d0
  637. .end_round:
  638.     add.w    d3,d0
  639.     move.w    d0,(a0)+
  640.     addq.w    #1,d7
  641.     cmpi.w    #raylength,d7
  642.     blt.s    .proj_heigth_loop
  643.  
  644. ; Initialize angle of first ray..
  645.     moveq    #0,d1
  646.     move.w    playerangle(pc),d1
  647.     subi.w    #240,d1
  648.     Do_SinModulo    d1
  649.     move.w    d1,Voxel.rayangle
  650.  
  651. ; Plot voxel.
  652.     movea.l    skyadr_tbl,a5
  653.     movea.l    scr,a0
  654.     adda.l    #160*199*2,a0
  655.     move.w    #160-1,d7
  656.     move.l    a0,Voxel.screen
  657.     clr.l    d2
  658.     move.w    Voxel.rayangle(pc),d0
  659.     move.l    #-160*2,d6
  660.     movea.l    Voxel.baseAdr,a6
  661.     adda.l    #Voxel.cosMulTable,a6
  662.     lea    Voxel.persp_tbl(pc),a4
  663.     clr.l    d4
  664.  
  665. .column_loop:
  666.     move.w    d7,d1
  667.     subi.w    #160/2-1,d1
  668.     muls.w    tiltx(pc),d1
  669.     swap    d1
  670.     move.w    d1,Voxel.tiltfactor
  671.  
  672.     swap    d7
  673.     move.w    playerx(pc),d1
  674.     move.w    playery(pc),d2
  675.     lea    Voxel.gxstep(pc),a3
  676.     move.w    (xanglestep_tbl,d0.w*2),(a3)+
  677.     move.w    (yanglestep_tbl,d0.w*2),(a3)+
  678.  
  679.     move.w    Voxel.rayangle(pc),d0
  680.     sub.w    playerangle(pc),d0
  681.     Do_SinModulo    d0
  682.     move.w    (sine_tbl+2,d0.w*4),Voxel.cos
  683.  
  684.     moveq    #100,d0                * topmountain:=scrlines
  685.     movea.l    Voxel.baseAdr,a3
  686.     adda.l    #Voxel.zheight_tbl,a3
  687.     move.w    #raylength-1,d7            * Number of steps in ray..
  688. .rayloop:
  689.     move.l    d2,d5
  690.     move.w    d1,d4
  691.     lsr.w    #8,d4
  692.     move.b    d4,d5                ; d5.l=position in map
  693.     move.w    (a6)+,d4            ; d4.w=z=distance*cos(a)
  694.     move.w    (a4,d4.l*2),d3            ; d3.w=elevation/z+roll
  695.     lsl.l    #8,d4                ; d4.l=z*$100
  696.     move.b    (a2,d5.l),d4            ; d4.l=z*$100+h
  697.     sub.w    (a3,d4.l*2),d3            ; d3.w= projected h = elevation/z+roll-h/z
  698. ; d3.w= ph = (elevation-h)/z + roll
  699. ;    add.w    Voxel.tiltfactor(pc),d3        ; Add tilt.
  700.     move.w    d0,d4
  701.     sub.w    d3,d4
  702. ; d4.w = dph = top - ph
  703.     ble.s    .endl
  704. ; Projected height out of screen?
  705.     tst.w    d3
  706.     bpl.s    .draw_line
  707.     lea    (a6,d7.w*2),a6            ; a6: next z column
  708.     move.w    d0,d4
  709.     beq.s    .next_column
  710.     clr.w    d7                ; End of ray.
  711.     clr.l    d3                ; ph=0
  712. .draw_line:
  713.     move.w    (a1,d5.l*2),d5            ; d5.w=color
  714.     subq.w    #1,d4
  715. .pixlp:    REPT    2
  716.     move.w    d5,(a0)
  717.     adda.l    d6,a0                ; Go up one screenline.
  718.     ENDR
  719.     dbf    d4,.pixlp
  720.     move.w    d3,d0                ; top=ph
  721. ; Move to next map-pos.
  722. .endl:    add.w    Voxel.gxstep(pc),d1
  723.     add.w    Voxel.gystep(pc),d2
  724.     dbf    d7,.rayloop
  725.  
  726. .next_column:
  727. ; Restore background slice.
  728.     move.w    (a5),d1
  729.     move.w    d0,(a5)+
  730.     sub.w    d1,d0
  731.     ble.s    .no_background_restore
  732.     subq.w    #1,d0
  733.     clr.w    d1
  734. .restore_loop:
  735.     REPT    2
  736.     move.w    d1,(a0)
  737.     adda.l    d6,a0                * Go up one screenline.
  738.     ENDR
  739.     dbf    d0,.restore_loop
  740. .no_background_restore:
  741. ; Increase angle..
  742.     move.w    Voxel.rayangle(pc),d0
  743.     addq.w    #3,d0
  744.     Do_SinModulo    d0
  745.     move.w    d0,Voxel.rayangle
  746. ; Kick in next vertical screenline and loop..
  747.     addq.l    #2,Voxel.screen
  748.     movea.l    Voxel.screen(pc),a0
  749.     swap    d7
  750.     dbf    d7,.column_loop
  751.     rts
  752.  
  753. ; Draw the Voxel.
  754. ; INPUT:
  755. ; a1: color map
  756. ; a2: height-field
  757. Voxel.paintRgb50:
  758. ; Initialize projected heigth for this evelation and roll.
  759.     lea    Voxel.persp_tbl(pc),a0
  760.     move.w    roll,d3
  761.     move.w    elevation,d1
  762.     moveq    #1,d7
  763.     move.l    #$FFFF,d2
  764.  
  765. .proj_heigth_loop:
  766.     move.l    d2,d0
  767.     move.w    d7,d4
  768.     divu.w    d4,d0
  769.     mulu.w    d1,d0
  770.     tst.w    d0
  771.     swap    d0
  772.     bpl.s    .end_round
  773.     addq.w    #1,d0
  774. .end_round:
  775.     add.w    d3,d0
  776.     move.w    d0,(a0)+
  777.     addq.w    #1,d7
  778.     cmpi.w    #raylength,d7
  779.     blt.s    .proj_heigth_loop
  780.  
  781. ; Initialize angle of first ray..
  782.     moveq    #0,d1
  783.     move.w    playerangle(pc),d1
  784.     subi.w    #240,d1
  785.     Do_SinModulo    d1
  786.     move.w    d1,Voxel.rayangle
  787.  
  788. ; Plot voxel.
  789.     movea.l    skyadr_tbl,a5
  790.     movea.l    scr,a0
  791.     adda.l    #160*99*4,a0
  792.     move.w    #160-1,d7
  793.     move.l    a0,Voxel.screen
  794.     clr.l    d2
  795.     move.w    Voxel.rayangle(pc),d0
  796.     move.l    #-160*4,d6
  797.     movea.l    Voxel.baseAdr,a6
  798.     adda.l    #Voxel.cosMulTable,a6
  799.     lea    Voxel.persp_tbl(pc),a4
  800.     clr.l    d4
  801.  
  802. .column_loop:
  803.     move.w    d7,d1
  804.     subi.w    #160/2-1,d1
  805.     muls.w    tiltx(pc),d1
  806.     swap    d1
  807.     move.w    d1,Voxel.tiltfactor
  808.  
  809.     swap    d7
  810.     move.w    playerx(pc),d1
  811.     move.w    playery(pc),d2
  812.     lea    Voxel.gxstep(pc),a3
  813.     move.w    (xanglestep_tbl,d0.w*2),(a3)+
  814.     move.w    (yanglestep_tbl,d0.w*2),(a3)+
  815.  
  816.     move.w    Voxel.rayangle(pc),d0
  817.     sub.w    playerangle(pc),d0
  818.     Do_SinModulo    d0
  819.     move.w    (sine_tbl+2,d0.w*4),Voxel.cos
  820.  
  821.     moveq    #100,d0                * topmountain:=scrlines
  822.     movea.l    Voxel.baseAdr,a3
  823.     adda.l    #Voxel.zheight_tbl,a3
  824.     move.w    #raylength-1,d7            * Number of steps in ray..
  825. .rayloop:
  826.     move.l    d2,d5
  827.     move.w    d1,d4
  828.     lsr.w    #8,d4
  829.     move.b    d4,d5                ; d5.l=position in map
  830.     move.w    (a6)+,d4            ; d4.w=z=distance*cos(a)
  831.     move.w    (a4,d4.l*2),d3            ; d3.w=elevation/z+roll
  832.     lsl.l    #8,d4                ; d4.l=z*$100
  833.     move.b    (a2,d5.l),d4            ; d4.l=z*$100+h
  834.     sub.w    (a3,d4.l*2),d3            ; d3.w= projected h = elevation/z+roll-h/z
  835. ; d3.w= ph = (elevation-h)/z + roll
  836. ;    add.w    Voxel.tiltfactor(pc),d3        ; Add tilt.
  837.     move.w    d0,d4
  838.     sub.w    d3,d4
  839. ; d4.w = dph = top - ph
  840.     ble.s    .endl
  841. ; Projected height out of screen?
  842.     tst.w    d3
  843.     bpl.s    .draw_line
  844.     lea    (a6,d7.w*2),a6            ; a6: next z column
  845.     move.w    d0,d4
  846.     beq.s    .next_column
  847.     clr.w    d7                ; End of ray.
  848.     clr.l    d3                ; ph=0
  849. .draw_line:
  850.     move.w    (a1,d5.l*2),d5            ; d5.w=color
  851.     move.w    d5,d0
  852.     swap    d5
  853.     move.w    d0,d5
  854.     subq.w    #1,d4
  855. .pixlp:    move.l    d5,(a0)
  856.     adda.l    d6,a0                ; Go up one screenline.
  857.     dbf    d4,.pixlp
  858.     move.w    d3,d0                ; top=ph
  859. ; Move to next map-pos.
  860. .endl:    add.w    Voxel.gxstep(pc),d1
  861.     add.w    Voxel.gystep(pc),d2
  862.     dbf    d7,.rayloop
  863.  
  864. .next_column:
  865. ; Restore background slice.
  866.     move.w    (a5),d1
  867.     move.w    d0,(a5)+
  868.     sub.w    d1,d0
  869.     ble.s    .no_background_restore
  870.     subq.w    #1,d0
  871.     clr.l    d1
  872. .restore_loop:
  873.     move.l    d1,(a0)
  874.     adda.l    d6,a0                * Go up one screenline.
  875.     dbf    d0,.restore_loop
  876. .no_background_restore:
  877. ; Increase angle..
  878.     move.w    Voxel.rayangle(pc),d0
  879.     addq.w    #3,d0
  880.     Do_SinModulo    d0
  881.     move.w    d0,Voxel.rayangle
  882. ; Kick in next vertical screenline and loop..
  883.     addq.l    #4,Voxel.screen
  884.     movea.l    Voxel.screen(pc),a0
  885.     swap    d7
  886.     dbf    d7,.column_loop
  887.     rts
  888.  
  889. Voxel.screen:
  890.     DS.L    1
  891. Voxel.cos:
  892.     DS.W    1
  893. Voxel.rayangle:
  894.     DS.W    1                * Angle of current ray
  895. Voxel.gxstep:
  896.     DS.W    1
  897. Voxel.gystep:
  898.     DS.W    1                * Fixed point step value of ray
  899. Voxel.tiltfactor:
  900.     DS.W    1
  901. Voxel.persp_tbl:
  902.     DS.L    raylength
  903.  
  904. * View Variables
  905. playerangle:
  906.     DC.W    0                * Viewer's direction
  907. playerx:DC.W    0                * Viewer's coordinates
  908. playery:DC.W    0
  909. tiltx:    DC.L    0
  910.  
  911. ;======= OBJECT DATA ========
  912.  
  913.     DATA
  914.  
  915.     IFEQ    Voxel.GENERATE
  916. height_pic:
  917.     INCBIN    HEIGHT.PC8            * Ground_image
  918. color_pic:
  919.     INCBIN    GROUND.APX            * Color_image
  920.     ENDC
  921.  
  922. Voxel.maze:
  923.     INCBIN    MAZE.APX
  924.  
  925. skyadr_tbl:
  926.     DC.L    sky1_tbl
  927.     DC.L    sky2_tbl
  928.     DC.L    sky3_tbl
  929.  
  930. elevation:
  931.     DC.W    2000
  932. raydistance:
  933.     DC.W    64                * Length of rays
  934. cloudx: DC.W    0                * Cloud position
  935. eyedistance:
  936.     DC.W    64+32                * Changes perspective
  937. roll:    DC.W    0
  938.  
  939. Voxel.goldInstTable:
  940.     DC.W    (.end-.start)/4-1
  941.     DC.W    3
  942. .start:    DC.L    $00000000
  943.     DC.L    $5F1F0000
  944.     DC.L    $9F5F0000
  945.     DC.L    $CF9F0000
  946.     DC.L    $FFFF0000
  947.     DC.L    $FFFF00FF
  948.     DC.L    $FFFF00FF
  949.     DC.L    $FFFF00FF
  950.     DC.L    $FFFF00FF
  951. .end:
  952.  
  953. Voxel.chromeInstTable:
  954.     DC.W    (.end-.start)/4-1
  955.     DC.W    3
  956. .start:    DC.L    $0F000000
  957.     DC.L    $4F2F002F
  958.     DC.L    $847F007F
  959.     DC.L    $C4BF00BF
  960.     DC.L    $FFFF00FF
  961.     DC.L    $FFFF00FF
  962.     DC.L    $FFFF00FF
  963.     DC.L    $FFFF00FF
  964.     DC.L    $FFFF00FF
  965. .end:
  966.  
  967. ;======= OBJECT RESERVES ========
  968.  
  969.     BSS
  970.  
  971. Voxel.resRout:
  972.     DS.L    1
  973.  
  974. Voxel.goldPal:
  975.     DS.W    256
  976. Voxel.chromePal:
  977.     DS.W    256
  978.  
  979. xanglestep_tbl:
  980.     DS.W    sintbllen
  981. yanglestep_tbl:
  982.     DS.W    sintbllen
  983.  
  984. * Heightfield tables
  985. persp_tbl:
  986.     DS.W    raylength
  987.  
  988. * Sky heighttables.
  989. sky1_tbl:
  990.     DS.W    160
  991. sky2_tbl:
  992.     DS.W    160
  993. sky3_tbl:
  994.     DS.W    160
  995.  
  996. Voxel.paintRout:
  997.     DS.L    1
  998. Voxel.oldAngle:
  999.     DS.W    1
  1000. Voxel.turnStart:
  1001.     DS.W    1
  1002. Voxel.turnDirection:
  1003.     DS.W    1
  1004.  
  1005. Voxel.fallOn:
  1006.     DS.W    1
  1007. Voxel.fallStart:
  1008.     DS.L    1
  1009.  
  1010. Voxel.baseAdr:
  1011.     DS.L    1