home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / 4GE_FRAC.ZIP / 4GE-FRAC.ASM next >
Assembly Source File  |  1995-06-13  |  22KB  |  1,126 lines

  1. ; 4ge's Xmas 94 Intro fractalzoom source
  2. ; ======================================
  3.  
  4. ; Copyright (C) 1994/5 Samuel Marshall. All rights reserved. 
  5.  
  6. ; Text and program code by Samuel Marshall, a.k.a. CuteElf / 4ge.
  7.  
  8. ; Contact me at the following email address:
  9.  
  10. ; Samuel.Marshall@durham.ac.uk
  11.  
  12. ; and if you don't get a response, probably it's not during termtime, and
  13. ; I am at home - in which case, I check email here only about once a month
  14. ; (if that). You will get a reply eventually.
  15.  
  16. ; My WWW homepage is
  17.  
  18. ; http://www.dur.ac.uk/~d405ua/
  19.  
  20. ; Enjoy the program... hope it helps you. Don't expect a wonderfully-
  21. ; optimised piece of code, because 1) the zoom routine wasn't really time-
  22. ; critical, and 2) this is the first time I ever wrote a fractal program,
  23. ; in my entire life, and 3) I didn't know how to do fixed-point numbers
  24. ; properly when I wrote this ;)
  25.  
  26.  
  27.  
  28.  
  29. ; General Principles for a real-time fractalzoom using this method
  30. ; ================================================================
  31. ;
  32. ; First, we calculate a fractal at twice the size, each way (i.e. 4 times
  33. ; the area) as the screen display area.
  34. ;
  35. ; We then display that fractal, zoomed-out to half size each way, so that
  36. ; it will exactly fill the screen display area.
  37. ;
  38. ; Then, we calculate another fractal twice the size of the display area,
  39. ; but this one is calculated "zoomed in" so that this fractal is a more
  40. ; detailed view of one-quarter of the area of the fractal just calculated.
  41. ;
  42. ; While we are calculating this, which takes a few seconds, we gradually
  43. ; zoom in the fractal we already have - using standard bitmap-zoom 
  44. ; techniques - until eventually by the time the new fractal is finished,
  45. ; the old fractal will be showing at 1:1 size, and will can then be 
  46. ; seamlessly replaced on the display by the new fractal at 1:2. Then
  47. ; repeat.
  48. ;
  49. ; Note: the fractal being DISPLAYED, i.e. the one that's already been
  50. ; calculated, can be zoomed to any point at all within the region, but
  51. ; this decision must be known in advance so that the next fractal is
  52. ; calculated from the right point. That's why you can't change the direction
  53. ; "realtime", only every so often.
  54.  
  55. ; I would include references here but I worked the method out myself with
  56. ; no help from anything or anyone, so there aren't any... (oh, by the
  57. ; way, I assume this is the standard method everyone else uses too, it's
  58. ; nothing special or anything, just that I reinvented the wheel one more
  59. ; time ;)
  60.  
  61. ; More details are included in the individual function descriptions.
  62.  
  63. .MODEL tiny
  64. .386
  65. .CODE
  66.  
  67. .STARTUP
  68. jmp start
  69.  
  70. Getch:
  71. mov ax,0
  72. int 16h
  73. ret
  74.  
  75. ; You can probably change height without messing things up, but
  76. ; changing the width will I think need some work.
  77.  
  78. FRACWIDTH equ 256
  79. FRACHEIGHT equ 128
  80.  
  81. ; Fractal parameter
  82. frac    dd 3
  83.  
  84. ; Memory
  85. enlargebufferseg        dw 0    ; segment address of the 64*32 enlarge buf.
  86. textureseg              dw 0    ; the segment address of texture to display.
  87. fractalseg              dw 0    ; the segment address of texture to create
  88.  
  89. ;====================================================================
  90. ;ZOOMTEXTURE - display picture at given zoom fraction
  91. ;--------------------------------------------------------------------
  92.  
  93. ; This is pretty obvious; just a standard, fixed-point bitmap
  94. ; display routine. The only extra bit you might notice is that
  95. ; it doubles each pixel, so as to get a larger screen display without
  96. ; taking too long to calculate the fractals.
  97.  
  98. ; Data_______________________________________________________________
  99.  
  100. lfrac   dw 0    
  101. hfrac   dw 0    ; texture pixels per real pixel
  102. hfracb  db 0    ; same but a byte
  103.  
  104. ystart  db 0
  105. xstart  db 0    ; where to start, in texturemap
  106.  
  107. oldbx   dw 0
  108. oldss   dw 0
  109.  
  110. yfracpos dw 0   ; fractional y-position
  111.  
  112. stopat  dw 0    ; where to stop in screen ram
  113.  
  114. ; Source_____________________________________________________________
  115.  
  116. ZoomTexture:
  117. push ax
  118. push bx
  119. push cx
  120. push dx
  121. push si
  122. push di
  123.  
  124. mov di,screenstart      ; start position on display memory
  125. mov stopat,di
  126. add stopat,FRACHEIGHT*320    ; stop position on display memory
  127. mov bh,ystart
  128. mov bl,xstart           ; start position on texture memory
  129.  
  130. mov ax,hfrac
  131. mov hfracb,al
  132. mov dx,lfrac
  133.  
  134. mov ax,ss
  135. mov oldss,ax
  136. mov ax,textureseg
  137. mov ss,ax
  138.  
  139.   ZoomYLoop:
  140.  
  141.   mov si,FRACWIDTH/2
  142.   mov oldbx,bx
  143.   mov cx,0
  144.  
  145.     ZoomXLoop:
  146.  
  147.     mov al,ss:[bx]
  148.     mov ah,al
  149.     mov es:[di],ax
  150.     mov es:[di+320],ax
  151.     add di,2
  152.     add cx,lfrac
  153.     adc bx,hfrac
  154.  
  155.     dec si
  156.     jnz ZoomXLoop
  157.  
  158.   mov bx,oldbx
  159.  
  160.   add yfracpos,dx
  161.   adc bh,hfracb
  162.  
  163.   add di,640-FRACWIDTH
  164.   cmp di,stopat
  165.   jb ZoomYLoop
  166.  
  167. mov ax,oldss
  168. mov ss,ax
  169.  
  170. ; Check for keypress
  171. mov ah,1
  172. int 16h
  173. jz zt_afterkeyhit  
  174.  
  175. jmp dfs_keyhit
  176.  
  177. zt_afterkeyhit:
  178.  
  179. pop di
  180. pop si
  181. pop dx
  182. pop cx
  183. pop bx
  184. pop ax
  185. ret
  186.  
  187. ;====================================================================
  188. ;CALCULATE - work out one pixel of Mandelbrot fractal
  189. ;--------------------------------------------------------------------
  190.  
  191. ; The fractal formula used, with coordinates x,y, is:
  192. ; A = B = 0. Colour=starting colour.
  193. ;
  194. ; new A = a squared - b squared - x
  195. ; new B = 2 * a * b - y
  196. ;
  197. ; If A squared + B squared > some number frac, then stop.
  198. ; If been round loop more than colour limit (64) times, then stop too.
  199. ;
  200. ; Otherwise, work out next A and B, and increment the colour we're going
  201. ; to use for the pixel.
  202. ;
  203. ; When we get out of the loop, that colour value is the one to draw at
  204. ; this pixel.
  205.  
  206. ; Note:
  207. ; The fixed point sections of this are pretty crap; there are proper ways
  208. ; to do fixed point (I think...) so for god's sake don't copy those
  209. ; bits for your own fixed point code.
  210.  
  211. ; Data_______________________________________________________________
  212.  
  213. colour  db 0    ; colour to plot the pixel
  214.  
  215. esign    db 0    ; esign of multiplication result
  216.  
  217. la      dd 0
  218. ha      dd 0    
  219. lb      dd 0
  220. hb      dd 0    ; a,b from a+bi. Low and high words thereof.
  221.  
  222. lasq    dd 0
  223. hasq    dd 0
  224. lbsq    dd 0
  225. hbsq    dd 0    ; a squared, b squared, low and high words.
  226.  
  227. lnewa   dd 0
  228. hnewa   dd 0    ; temporary storage for `new' veresion of `a'.
  229.  
  230. lx      dd 0
  231. hx      dd 0
  232. ly      dd 0
  233. hy      dd 0    ; co-oredinates in complex plane of this point
  234.  
  235. ; Source_____________________________________________________________
  236.  
  237. Calculate:
  238.   push eax
  239.   push ebx
  240.   push ecx
  241.   push edx
  242.   push esi
  243.   push edi
  244.  
  245. ; 0) Fix up the x,y data to specific point
  246. ;  mov lx,2621
  247. ;  mov hx,1
  248. ;  mov ly,11107
  249. ;  mov hy,1
  250.  
  251. ; 1) setup colour
  252.   mov colour,32
  253.  
  254. ; 2) clear the a,b and squared variables
  255.   mov la,0
  256.   mov ha,0
  257.   mov lb,0
  258.   mov hb,0
  259.   mov lasq,0
  260.   mov hasq,0
  261.   mov lbsq,0
  262.   mov hbsq,0
  263.  
  264.   CalcLoop:
  265.  
  266.   ; 3) increment colour
  267.   inc colour
  268.  
  269.   ; 4) set up a-squared
  270. asquared:  
  271.   mov eax,lasq
  272.   mov edx,hasq
  273.  
  274. minusbsquared:
  275.   ; 5) subtract b-squared
  276.   sub eax,lbsq
  277.   sbb edx,hbsq
  278.  
  279. minusx:  
  280.   ; 6) subtract x and store result in new-a
  281.   sub eax,lx
  282.   sbb edx,hx
  283.   mov lnewa,eax
  284.   mov hnewa,edx
  285.  
  286.   ; 7) multiply a and b
  287.   
  288. atimesb:
  289.   ; a. setup variables
  290.   mov ebx,la
  291.   mov ecx,ha
  292.   mov esi,lb
  293.   mov edi,hb
  294.  
  295. fixesigns:  
  296.   ; b. sort out esigns to be poesitive
  297.   mov esign,0
  298.   cmp ecx,0
  299.   jge ecxok_1
  300.     xor ecx,0ffffffffh
  301.     xor ebx,0ffffffffh
  302.     add ebx,1
  303.     adc ecx,0
  304.     inc esign
  305.   ecxok_1:
  306.   cmp edi,0
  307.   jge ediok_1
  308.     xor edi,0ffffffffh
  309.     xor esi,0ffffffffh
  310.     add esi,1
  311.     adc edi,0
  312.     inc esign
  313.   ediok_1:
  314.  
  315. multiply:
  316.   ; c. multiply the two numbers
  317.   mov hb,0
  318.   mov eax,ebx
  319.   mov edx,esi
  320.   mul edx
  321.   mov lb,edx
  322.   mov eax,ebx
  323.   mov edx,edi
  324.   mul edx
  325.   add lb,eax
  326.   adc hb,edx
  327.   mov eax,ecx
  328.   mov edx,esi
  329.   mul edx
  330.   add lb,eax
  331.   adc hb,edx
  332.   mov eax,ecx
  333.   mov edx,edi
  334.   mul edx
  335.   add hb,eax
  336.  
  337. fixresultesign:
  338.   ; d. fix the esign of the result
  339.   test esign,1
  340.   jz esignok_1
  341.     xor hb,0ffffffffh
  342.     xor lb,0ffffffffh
  343.     add lx,1
  344.     adc hb,0
  345.   esignok_1:
  346.  
  347. doublenumber:
  348.   ; 8) Add this to itself, (with carry)
  349.   mov eax,lb
  350.   mov edx,hb
  351.   add eax,eax
  352.   adc edx,edx
  353.  
  354. subtracty:
  355.   ; 9) Subtract y and store in b
  356.   sub eax,ly
  357.   sbb edx,hy
  358.   mov lb,eax
  359.   mov hb,edx
  360.  
  361.   ; 10) Update a from new-a : combined with
  362.   ; 11) Square a and store in a-squared
  363.   ; a. setup variable
  364. starttosquare:  
  365.   mov ebx,lnewa
  366.   mov ecx,hnewa
  367.   mov la,ebx
  368.   mov ha,ecx
  369.  
  370. fixesign:
  371.   ; b. sort out esign to be poesitive
  372.   cmp ecx,0
  373.   jge ecxok_2
  374.     xor ecx,0ffffffffh
  375.     xor ebx,0ffffffffh
  376.     add ebx,1
  377.     adc ecx,0
  378.   ecxok_2:
  379.  
  380. squareit:
  381.   ; c. square data
  382.   mov hasq,0
  383.   mov eax,ebx
  384.   mul eax
  385.   mov lasq,edx
  386.   mov eax,ebx
  387.   mul ecx
  388.   add lasq,eax
  389.   adc hasq,edx
  390.   add lasq,eax
  391.   adc hasq,edx
  392.   mov eax,ecx
  393.   mul eax
  394.   add hasq,eax
  395.  
  396. sametosquareb:
  397.   ; 12) Square b and store in b-squared
  398.   ; a. setup variable
  399.   mov ebx,lb
  400.   mov ecx,hb
  401.  
  402.   ; b. sort out esign to be poesitive
  403.   cmp ecx,0
  404.   jge ecxok_3
  405.     xor ecx,0ffffffffh
  406.     xor ebx,0ffffffffh
  407.     add ebx,1
  408.     adc ecx,0
  409.   ecxok_3:
  410.  
  411.   ; c. square data
  412.   mov hbsq,0
  413.   mov eax,ebx
  414.   mul eax
  415.   mov lbsq,edx
  416.   mov eax,ebx
  417.   mul ecx
  418.   add lbsq,eax
  419.   adc hbsq,edx
  420.   add lbsq,eax
  421.   adc hbsq,edx
  422.   mov eax,ecx
  423.   mul eax
  424.   add hbsq,eax
  425.  
  426. asquaredaddbsquared:  
  427.   ; 13) Setup a-squared
  428.   mov eax,lasq
  429.   mov edx,hasq
  430.  
  431.   ; 14) Add b-squared
  432.   add eax,lbsq
  433.   adc edx,hbsq
  434.  
  435.   ; 15) Compare with *n*, stop if >
  436.   cmp edx,frac
  437.   jg CalcFinish
  438.  
  439.   ; 16) If colour > *c*, stop
  440.   cmp colour,63
  441.   jg CalcFinish
  442.  
  443. jmp CalcLoop
  444.  
  445. CalcFinish:
  446. ; 17) Return pixel colour
  447. pop edi
  448. pop esi
  449. pop edx
  450. pop ecx
  451. pop ebx
  452. pop eax
  453. mov al,colour
  454. ret
  455.  
  456. ;====================================================================
  457. ;FRACTAL - loop round to draw a 256x256 fractal using Calculate
  458. ;--------------------------------------------------------------------
  459.  
  460. ; Basically, this just uses fixed-point to go through all the 
  461. ; x and y coordinates corresponding to SCREEN x and y.
  462. ; If you're confused about the "normaltime", "othertime", etc crap
  463. ; in the zooming-in section, well, I *think* this is because the
  464. ; Y-position sometimes needs to start at a half-pixel (i.e. "othertime")
  465. ; but usually ("normaltime") starts on a whole pixel.
  466.  
  467. ; Note, it would be possible to speed this up by 1/4, simply by re-using
  468. ; the relevant pixels from the fractal calculated last: see this diagram
  469.  
  470. ; We're zooming in to top left corner.
  471.  
  472. ; Original fractal      Fractal needs calculating next
  473. ;
  474. ; abcd....              a?b?c?d?
  475. ; efgh....              ????????
  476. ; ijkl....              e?f?g?h?
  477. ; mnop....              ????????
  478. ; ........              i?j?k?l?
  479. ; ........              ????????
  480. ; ........              m?n?o?p?
  481. ; ........              ????????
  482. ;
  483. ; where "." has been calculated on original fractal, but will not be used
  484. ; for the new one, and ? represents what actually needs to be calculated
  485. ; in the new one. (a,b,c,... could be copied from the old one).
  486. ;
  487. ; Actually, this routine doesn't copy over a,b,c,..., they are recalculated.
  488.  
  489. ; Data_______________________________________________________________
  490.  
  491. lxcentre     dd 0
  492. hxcentre     dd 0
  493. lycentre     dd 0
  494. hycentre     dd 0    ; co-ordinates of the window's centre, not used here
  495.                      ; (they are used in the main loop...)
  496.  
  497. lxs     dd 0
  498. hxs     dd 0
  499. lys     dd 0
  500. hys     dd 0    ; co-oredinates of the window's top left corner
  501.  
  502. lxi     dd 0
  503. hxi     dd 0
  504. lyi     dd 0
  505. hyi     dd 0    ; amount to increment fractal parameter per pixel
  506.  
  507. ycount  dw 0
  508. xcount  dw 0    ; loop counters
  509.  
  510. nodraw  db 1    ; whether or not to draw the last one
  511.  
  512. ydirection db 1
  513. xdirection db 1 ; direction of the zoom (0 = left/up, 1=centre, 2=rt/down)
  514. newxdirection db 1
  515. newydirection db 1
  516.  
  517.  
  518. screenstart     dw 0    ; screen edisplay offset
  519.  
  520. ; Source_____________________________________________________________
  521.  
  522. Fractal:
  523. push eax
  524. push ebx
  525. push ecx
  526. push edx
  527. push esi
  528. push edi
  529.  
  530. ; 1) Initialise x and y parameters of fractal to xstart,ystart
  531. mov eax,lxs
  532. mov edx,hxs
  533. mov lx,eax
  534. mov hx,edx
  535. mov eax,lys
  536. mov edx,hys
  537. mov ly,eax
  538. mov hy,edx
  539.  
  540. ; 1.5) Initialise zoom parameters
  541. mov lfrac,1024*63
  542. mov hfrac,1
  543. mov ystart,0
  544. mov xstart,0
  545.  
  546. ; 2) Set up screen pointer
  547. push es
  548. mov ax,fractalseg
  549. mov es,ax
  550. mov edi,0
  551.  
  552. mov ycount,FRACHEIGHT
  553.   FracYLoop:
  554.  
  555.   mov xcount,FRACWIDTH
  556.     FracXLoop:
  557.     
  558.     ; 3) Calculate pixel
  559.     call Calculate
  560.  
  561.     ; 4) Draw pixel
  562.     mov es:[edi],al
  563.  
  564.     ; 5) Add X increment to X
  565.     mov eax,lxi
  566.     mov edx,hxi
  567.     add lx,eax
  568.     adc hx,edx
  569.  
  570.     ; 6) Increment screen poesition
  571.     inc edi
  572.     
  573.     ; 7) If count >127, stop
  574.     dec xcount
  575.     jnz FracXLoop
  576.  
  577.   ; 8) Set X to xstart
  578.   mov eax,lxs
  579.   mov edx,hxs
  580.   mov lx,eax
  581.   mov hx,edx
  582.  
  583.   ; 10) Add Y increment to Y
  584.   mov eax,lxi
  585.   mov edx,hxi
  586.   add ly,eax
  587.   adc hy,edx
  588.  
  589.   ; 10.5) Draw zoomed last fractal if count%2==0
  590.   mov ax,ycount
  591.   and al,1
  592.   jnz notthistime
  593.     push es
  594.     mov ax,0a000h
  595.     mov es,ax
  596.   ; Update zoom position
  597.     mov yfracpos,0
  598.     mov al,xdirection
  599.     add xstart,al
  600.     cmp ydirection,0
  601.     je normaltime
  602.     cmp ydirection,2
  603.     jne ydirection1
  604.     inc ystart
  605.     jmp normaltime
  606.     ydirection1:
  607.     test ycount,2
  608.     jz othertime
  609.     inc ystart
  610.     jmp normaltime
  611.   
  612.   othertime:
  613.     mov yfracpos,8000h
  614.  
  615.   normaltime:
  616.     cmp nodraw,0
  617.     jne dontdraw
  618.     call ZoomTexture
  619.     dontdraw:
  620.     pop es
  621.     sub lfrac,1024
  622.  
  623.   notthistime:
  624.  
  625.   ; 11) If count>127, stop
  626.   dec ycount
  627.   jnz FracYLoop
  628.  
  629. pop es
  630.  
  631. pop edi
  632. pop esi
  633. pop edx
  634. pop ecx
  635. pop ebx
  636. pop eax
  637. ret
  638.  
  639. ;====================================================================
  640. ; SWITCHTEXTURES - switch around the two buffers
  641. ;--------------------------------------------------------------------
  642.  
  643. ; This just changes the two buffers when one has been finished; so
  644. ; that the new fractal becomes the one that gets drawn to screen, and 
  645. ; the old fractal will get written over by the one newly being
  646. ; calculated.
  647.  
  648. ; This is a separate function, because if you decide to implement
  649. ; the 25% saving described above, you'll need to copy over those
  650. ; re-cycled pixels at some point, and this is a good time to do that.
  651.  
  652. ; Source_____________________________________________________________
  653.  
  654. SwitchTextures:
  655. push ax
  656. push bx
  657.  
  658. mov ax,fractalseg
  659. mov bx,textureseg
  660. mov fractalseg,bx
  661. mov textureseg,ax
  662.  
  663. pop bx
  664. pop ax
  665. ret
  666.  
  667. ;====================================================================
  668. ;DOBACKGROUND - the background for lo-res part of demo
  669. ;--------------------------------------------------------------------
  670.  
  671. ; Just draws the swirly background things, very simple.
  672.  
  673. DoBackground:
  674. push ax
  675. push bx
  676. push cx
  677. push di
  678.  
  679. push es
  680.  
  681. mov ax,0a000h
  682. mov es,ax
  683.  
  684. mov bx,0        ; bh=y, bl=x
  685.  
  686. mov di,0
  687. mov cx,64000
  688. mov al,0
  689. rep stosb
  690.  
  691. mov di,0
  692.  
  693. db_loop:
  694.   mov al,bh
  695.   mul bl
  696.   and al,0fh
  697.   add al,16
  698.   mov es:[di],al
  699.   inc di
  700.   inc bx
  701.   cmp bl,0
  702.   jne notnextline
  703.   add di,320-256
  704. notnextline:
  705.   cmp bx,256*193
  706.   jb db_loop
  707.  
  708. mov si,0
  709. mov di,256
  710. push ds
  711. push es
  712. pop ds
  713. mov dx,192
  714.  
  715. copy_loop:
  716.   mov cx,32
  717.   rep movsw
  718.   add si,320-64
  719.   add di,320-64
  720.   dec dx
  721.   jnz copy_loop
  722.  
  723. pop ds
  724.  
  725. ;mov di,256*193
  726. ;mov cx,8*320
  727. ;mov al,0
  728. ;rep stosb
  729.  
  730. pop es
  731.  
  732. pop di
  733. pop cx
  734. pop bx
  735. pop ax
  736.  
  737. ret
  738.  
  739. ;====================================================================
  740. ;DRAWSQUARE - fills a square, for showing which way things are going
  741. ;--------------------------------------------------------------------
  742.  
  743. ; I won't bother explaining this, you can all manage to draw a square
  744. ; by now...
  745.  
  746. DrawSquare:
  747. push ax
  748. push dx
  749. push si
  750. push di
  751. push es
  752.  
  753. mov si,ax
  754. mov ax,0a000h
  755. mov es,ax
  756.  
  757. ; bh=starty, ax(now si)=startx
  758. ; dx=width and height
  759. ; cl=colour
  760. push dx
  761. mov di,bx
  762. shr di,8
  763. mov ax,320
  764. mul di
  765. add ax,si
  766. mov di,ax
  767. pop dx
  768.  
  769. mov al,cl
  770.  
  771. mov si,dx
  772. ds_yloop:
  773.   mov cx,dx
  774.   rep stosb
  775.   add di,320
  776.   sub di,dx
  777.   dec si
  778.   jnz ds_yloop
  779.  
  780. pop es
  781. pop di
  782. pop si
  783. pop dx
  784. pop ax
  785. ret
  786.  
  787. ;====================================================================
  788. ;DRAWDIRECTIONSQUARES - draw the motion direction indicators
  789. ;--------------------------------------------------------------------
  790.  
  791. ; this is pretty trivial too.
  792.  
  793. DrawDirectionSquares:
  794. push ax
  795. push bx
  796. push cx
  797. push dx
  798. push si
  799. push di
  800.  
  801. ; Clear all squares
  802. mov bh,0        ; was 16
  803. mov ax,0        ; was 16
  804. mov cl,0
  805. mov dx,32
  806.  
  807. mov si,3
  808. dds_yloop:
  809.   mov di,3
  810.   dds_xloop:
  811.     cmp di,2
  812.     jne dds_drawit
  813.     cmp si,2
  814.     je dds_skipit
  815.  
  816.     dds_drawit:
  817.     call DrawSquare
  818.  
  819.     dds_skipit:
  820.     add ax,9*16
  821.     dec di
  822.     jnz dds_xloop
  823.   mov ax,0      
  824.   add bh,5*16   
  825.   dec si
  826.   jnz dds_yloop
  827.  
  828. ; Draw chosen square
  829. cmp newydirection,1
  830. jne drawchosen
  831. cmp newxdirection,1
  832. je afterchosen
  833.  
  834. drawchosen:
  835. mov ah,0
  836. mov al,newydirection
  837. imul ax,5*16    
  838. mov bh,al
  839. mov eax,0
  840. mov al,newxdirection
  841. mov si,9*16
  842. mul si
  843. mov dx,32               ; square side length
  844. mov cl,1
  845. call DrawSquare
  846. add bh,4
  847. add ax,4
  848. sub dx,8
  849. mov cl,0
  850. call DrawSquare         ; clear the inside
  851.  
  852. afterchosen:
  853. ; Draw actual (current) square
  854. cmp ydirection,1
  855. jne drawcurrent
  856. cmp xdirection,1
  857. je aftercurrent
  858.  
  859. drawcurrent:
  860. mov ah,0
  861. mov al,ydirection
  862. imul ax,5*16  
  863. add ax,0        
  864. mov bh,al
  865. mov ah,0
  866. mov al,xdirection
  867. mov si,9*16
  868. mul si
  869. add bh,4
  870. add ax,4                ; current square start now in bx.
  871. mov dx,24               ; square side length
  872. mov cl,2
  873. call DrawSquare
  874.  
  875. aftercurrent:
  876. pop di
  877. pop si
  878. pop dx
  879. pop cx
  880. pop bx
  881. pop ax
  882. ret
  883.  
  884. ;====================================================================
  885. ;DOFRACTALSECTION - the controllable fractals part of the demo
  886. ;--------------------------------------------------------------------
  887.  
  888. ; hopefully what with the background you have already read, this
  889. ; routine is self-explanatory.
  890.  
  891. DoFractalSection:
  892. ; Now setup fractal parameters
  893. ; Start at preplanned position
  894. mov hxcentre,000000000h
  895. mov lxcentre,04afadfffh
  896. mov hycentre,0fffffffeh
  897. mov lycentre,08f71bfffh
  898.  
  899. ; and increment by 1/64 per pixel
  900. mov hxi,0
  901. mov lxi,1024*65536
  902. mov hyi,0
  903. mov lyi,1024*65536
  904.  
  905. mov screenstart,33*320+32
  906.  
  907. dfs_fracloop:
  908.  
  909. ; Calculate new hxcentre etc depending on xdirection,ydirection
  910. ; (new position = FW/4*(xdirection+1),FH/4*(ydirection+1) on the display)
  911.  
  912. ; xcentre=xcentre+fw/4*(xdirection-1)*xi 
  913. cmp xdirection,1
  914. je xchangedone
  915. mov edx,FRACWIDTH/2
  916. mov eax,lxi
  917. mul edx
  918. cmp xdirection,2
  919. jne xchangeminus
  920.   add lxcentre,eax
  921.   adc hxcentre,edx
  922.   jmp xchangedone
  923. xchangeminus:
  924.   sub lxcentre,eax
  925.   sbb hxcentre,edx
  926. xchangedone:
  927.  
  928. ; Same for Y:
  929. cmp ydirection,1
  930. je ychangedone
  931. mov edx,FRACHEIGHT/2
  932. mov eax,lyi
  933. mul edx
  934. cmp ydirection,2
  935. jne ychangeminus
  936.   add lycentre,eax
  937.   adc hycentre,edx
  938.   jmp ychangedone
  939. ychangeminus:
  940.   sub lycentre,eax
  941.   sbb hycentre,edx
  942. ychangedone:
  943.  
  944. ; Calculate start hxs,lxs hys,lys to keep hxcentre in middle (at 128,128)
  945.  
  946. ; xs=xcentre-128*xi ys=ycentre-128*yi
  947. mov eax,lxi
  948. mov edx,FRACWIDTH/2
  949. mul edx
  950. mov ebx,eax     ; bx is l(xi*128)
  951. mov ecx,edx     ; cx is h(xi*128)
  952. xor ebx,0ffffffffh
  953. xor ecx,0ffffffffh
  954. inc ecx         ; cx:bx now negative'd
  955. add ebx,lxcentre
  956. adc ecx,hxcentre
  957. mov lxs,ebx
  958. mov hxs,ecx
  959.  
  960. ; Same for Y:
  961. mov eax,lyi
  962. mov edx,FRACHEIGHT/2
  963. mul edx
  964. mov ebx,eax     ; bx is l(xi*128)
  965. mov ecx,edx     ; cx is h(xi*128)
  966. xor ebx,0ffffffffh
  967. xor ecx,0ffffffffh
  968. inc ecx         ; cx:bx now negative'd
  969. add ebx,lycentre
  970. adc ecx,hycentre
  971. mov lys,ebx
  972. mov hys,ecx
  973.  
  974. ; Calculate next fractal while we zoom the last one
  975. call Fractal
  976.  
  977. ; Switch the texture buffers, including copying 1/4 of the pixels
  978. call SwitchTextures
  979.  
  980. cmp nodraw,1
  981. jne alreadydrawing
  982. mov nodraw,0
  983. call DoBackground
  984. mov cx,0
  985. alreadydrawing:
  986.  
  987. ; Double magnification
  988. mov eax,lxi
  989. mov edx,hxi
  990. shr eax,1
  991. shr edx,1
  992. mov lxi,eax
  993. mov hxi,edx
  994. mov lyi,eax
  995. mov hyi,edx
  996.  
  997. ; Update direction
  998. mov al,newxdirection
  999. mov xdirection,al
  1000. mov al,newydirection
  1001. mov ydirection,al
  1002.  
  1003. call DrawDirectionSquares
  1004.  
  1005. jmp dfs_fracloop
  1006.  
  1007. dfs_keyhit:
  1008.  
  1009. call Getch
  1010.  
  1011. cmp al,'7'
  1012. jne not7
  1013. mov newxdirection,0
  1014. mov newydirection,0
  1015. not7:
  1016.  
  1017. cmp al,'4'
  1018. jne not4
  1019. mov newxdirection,0
  1020. mov newydirection,1
  1021. not4:
  1022.  
  1023. cmp al,'1'
  1024. jne not1
  1025. mov newxdirection,0
  1026. mov newydirection,2
  1027. not1:
  1028.  
  1029. cmp al,'8'
  1030. jne not8
  1031. mov newxdirection,1
  1032. mov newydirection,0
  1033. not8:
  1034.  
  1035. cmp al,'5'
  1036. jne not5
  1037. mov newxdirection,1
  1038. mov newydirection,1
  1039. not5:
  1040.  
  1041. cmp al,'2'
  1042. jne not2
  1043. mov newxdirection,1
  1044. mov newydirection,2
  1045. not2:
  1046.  
  1047. cmp al,'9'
  1048. jne not9
  1049. mov newxdirection,2
  1050. mov newydirection,0
  1051. not9:
  1052.  
  1053. cmp al,'6'
  1054. jne not6
  1055. mov newxdirection,2
  1056. mov newydirection,1
  1057. not6:
  1058.  
  1059. cmp al,'3'
  1060. jne not3
  1061. mov newxdirection,2
  1062. mov newydirection,2
  1063. not3:
  1064.  
  1065. cmp al,27
  1066. je breakout
  1067.  
  1068. call DrawDirectionSquares
  1069.  
  1070. donethecentrechange:
  1071. jmp zt_afterkeyhit    
  1072.  
  1073. ;====================================================================
  1074. ;MAIN SECTION & MISC
  1075. ;--------------------------------------------------------------------
  1076.  
  1077. Init:
  1078. push ax
  1079. push bx
  1080. ; 1) Setup ES segment
  1081. mov ax,0a000h
  1082. mov es,ax
  1083. ; 2) Allocate RAM
  1084. ; This is a COM program, so we just set the segments to spare
  1085. ; space in memory. (well, hopefully spare space :) 
  1086. push cs
  1087. pop ax
  1088. add ax,4096     ; textureseg is 64k above our segment
  1089. mov textureseg,ax
  1090. add ax,4096     ; and fractalseg is 128k above
  1091. mov fractalseg,ax
  1092. sub ax,4096
  1093. sub ax,2048     ; enlargebuffer is 1/2 way through our segment.
  1094. mov enlargebufferseg,ax
  1095. ; 3) Do graphics mode
  1096. mov ax,0013h
  1097. int 10h
  1098. pop bx
  1099. pop ax
  1100. ret
  1101.  
  1102. Shutdown:
  1103. push ax
  1104. mov ax,0003h
  1105. int 10h
  1106. pop ax
  1107. ret
  1108.  
  1109. message db 'Thanks for watching the modified version of 4ge',39,'S XMaS 94 iNTRo.'
  1110. db 13,10,13,10
  1111. db 'Get 4ge-xmas.zip from ftp.cdrom.com for the full version, Tseng gfx only.',13,10,13,10,'$'
  1112.  
  1113. Start:
  1114. call Init
  1115. call DoFractalSection
  1116. breakout:
  1117. call Shutdown
  1118. mov ah,09h
  1119. mov dx,offset message
  1120. int 21h
  1121.  
  1122. int 20h
  1123.  
  1124. END
  1125.  
  1126.