home *** CD-ROM | disk | FTP | other *** search
/ The Party 1994: Try This At Home / disk_image.bin / source / rotate / rotate.asm < prev    next >
Assembly Source File  |  1993-02-14  |  11KB  |  333 lines

  1. ─────────────────────────────────────────────────────────────────────────────
  2. ;
  3. ;     TITLE: 2d rotate
  4. ;WRITTEN BY: DRAEDEN /VLA CODER /iCE VGA CODER
  5. ;       FOR: Phantasm, (206) 232-5912
  6. ;               The first programing oriented board to hit the 206 area.
  7. ;               Any questions regarding this or ANY code in any language
  8. ;               can, and will be answered on Phantasm.
  9. ;               Send messages to 'Draeden' or post in the VLA programming
  10. ;               section.
  11. ;
  12. ;            The Deep (TDT/VLA), (305) 888-7724
  13. ;               Our first distribution site.  Messages will also be answered
  14. ;               if posted at this location.
  15. ;               Send messages to 'The Kabal'.
  16. ;
  17. ;      DATE: 02/13/93
  18. ;
  19. ;     NOTES: Compiled with TASM, TLINK
  20. ;            Must have a 386 or better to run. Any speed.
  21. ;            This program was chosen as an example because it utilizes
  22. ;            a lot of the neat little tricks you can do in assembly,
  23. ;            mainly Structures (STRUC), Unions (UNION), INCLUDEs,
  24. ;            the REPT macro, and the DUP() macro.
  25. ;
  26. ;ASSOCIATED FILES:
  27. ;
  28. ;       BWPRINT.ASM =>  Displays signed and unsigned bytes, words, or
  29. ;                    >  double words
  30. ;
  31. ;       SINCOS.DW   =>  Contains data for the sine and cosine operations
  32. ;
  33. ;       ROTATE.TXT  =>  A text file that further explains how to rotate
  34. ;                    >  objects, what BWPRINT.ASM does, and
  35. ;                    >  what the SINCOS.DW file is.
  36. ;
  37. ;       MAKE.BAT    =>  The file that'll put it all together into an .EXE
  38. ;
  39. ─────────────────────────────────────────────────────────────────────────────
  40.     
  41.     DOSSEG          ;tells compiler to sort segments according to the
  42.                     ;DOS standards- code, data, stack
  43.     .MODEL SMALL
  44.     .STACK 200h     ;sets up a 512 byte stack
  45.     .DATA           ;starts the data segment (empty)
  46.     .CODE           ;starts the code segment
  47.     .386            ;tells compiler to allow 386 instructions
  48.     ASSUME CS:@CODE, DS:@CODE
  49.                     ;tells compiler to assume offsets are taken from
  50.                     ;the code segment
  51.     LOCALS          ;turns local labels on eg. @@local:
  52.  
  53. ─────────────────────────────────────────────────────────────────────────────
  54.  
  55. ;=== GLOBALS  -used to link multiple programs together
  56.  
  57. GLOBAL  PrintByte:PROC, PrintWord:PROC, PrintBig:PROC
  58.     ;above is for the file BWPRINT.ASM
  59.  
  60. ─────────────────────────────────────────────────────────────────────────────
  61.  
  62. ;=== Data Includes -include physically puts the file in this one on compile
  63.                     
  64. INCLUDE sincos.dw       ;Labels SINE: and COSINE: contains sine(0-255)*256
  65.  
  66. ─────────────────────────────────────────────────────────────────────────────
  67.  
  68. ;=== DATA Structures
  69.     
  70.     Angle_Union     UNION
  71.         B       db  0
  72.         W       dw  0
  73.     Angle_Union     ENDS    ;creates a new data type (eg. DW, DB, DD) called
  74.                             ;Angle_Union. Used just like in C
  75.     Point_Struc     STRUC
  76.         X       dw  ?
  77.         Y       dw  ?
  78.     Point_Struc     ENDS    ;Create a structure (or a record)
  79.  
  80. ─────────────────────────────────────────────────────────────────────────────
  81.  
  82. ;=== DATA
  83.  
  84. NumPts      EQU 8
  85.  
  86. XYCord      Point_Struc <-50,50>,<50,50>,<-50,-50>,<50,-50>
  87.             Point_Struc <-30,30>,<30,30>,<-30,-30>,<30,-30>
  88.     ;sets up data for the corners of a 2d box
  89.  
  90. RotCord     Point_Struc NumPts DUP(<>)
  91.  
  92. OldDi       dw  NumPts DUP (0)  ;holds di for quick erasing
  93.  
  94. Angle       Angle_Union <?,?>   ; the '?' defaults to zero, but you can't
  95.                                 ;specify in a Union
  96. AngleVel    db  1       ;angle velocity
  97.  
  98. AddX        dw  160     ;amount to ADD to each X cordinate
  99. AddY        dw  100     ;amount to ADD to each Y cord
  100.  
  101. Palette     db  3 dup (0)   ;sets up a palette that fades from (0,0,0) to
  102.     i = 1                   ;(15*4,15*3,15*2) in 16 steps
  103.     REPT    15
  104.             db  4*i,3*i,2*i
  105.         i=i+1
  106.     ENDM
  107.  
  108. Color       db  15
  109.  
  110. AngleMsg    db  "ANGLE: $"
  111. AngleVelMsg db  "VELOCITY: $"
  112.  
  113. ─────────────────────────────────────────────────────────────────────────────
  114. ;=== Code Includes  ;none.
  115. ─────────────────────────────────────────────────────────────────────────────
  116.  
  117. ;=== SUBROUTINES
  118.  
  119.     ;DESTROYS: ax, edx, edi, si, ebp
  120.     ;Input: BX= X CX= Y which are rotated Angle degrees
  121.     ;OutPut:BX= X CX= Y
  122. RotateXY proc near
  123.     push    ds
  124.     mov     ax,cs                   ;the basic formula for rotations:
  125.     mov     ds,ax                   ; X := cos(angle) * x - sin(Xan) * y
  126.                                     ; Y := sin(angle) * x + cos(Xan) * y
  127.     mov     si,[Angle.W]
  128.     add     si,si                   ; si = angle*2
  129.     mov     ax,[Cosine+si]          ; ax = cos(angle)
  130.     imul    bx                      ; ax = cos(angle) * x
  131.     shl     edx,16                  ; put dx in high edx
  132.     mov     dx,ax                   ; save all 32 bits
  133.     mov     edi,edx                 ; store for later use
  134.  
  135.     mov     ax,[Sine+si]            ; ax = sin(angle)
  136.     imul    cx                      ; ax = sin(angle) * y
  137.     shl     edx,16
  138.     mov     dx,ax
  139.     sub     edi,edx                 ; edi = edi-eax=cos(angle)*x-sin(angle)*y
  140.     sar     edi,8                   ; remove the "256-factor"
  141.     mov     ebp,edi                 ; ebp = x-coordinate
  142.  
  143.     mov     ax,[Sine+si]            ; ax = sin(angle x)
  144.     imul    bx                      ; ax = sin(angle x) * x
  145.     shl     edx,16
  146.     mov     dx,ax
  147.     mov     edi,edx
  148.  
  149.     mov     ax,[Cosine+si]          ; ax = cos(angle x)
  150.     imul    cx                      ; ax = cos(angle x) * y
  151.     shl     edx,16
  152.     mov     dx,ax
  153.     add     edi,edx                 ; di = di-ax = sin(vx)*y + cos(vx)*z
  154.     sar     edi,8                   ; remove the (co)sin "256-factor"
  155.  
  156.     mov     bx,bp                   ; update X
  157.     mov     cx,di                   ; update Y
  158.  
  159.     pop     ds
  160.     ret
  161. RotateXY    ENDP
  162.  
  163.     ;rotates all points and saves them
  164. RotateBox   PROC NEAR
  165.     pushad          ;saves EVERYTHING (extended registers, too), except flags
  166.     mov     ax,cs
  167.     mov     ds,ax
  168.     mov     es,ax
  169.  
  170.     mov     bp,0    ;point counter
  171. @@DoNextPoint:
  172.     mov     bx,[XYCord.X +bp]   ;load in cordinates to rotate
  173.     mov     cx,[XYCord.Y +bp]
  174.     push    bp
  175.     call    RotateXY
  176.     pop     bp
  177.  
  178.     mov     [RotCord.X +bp],bx  ;save rotated cordinates IN A DIFFERENT PLACE
  179.     mov     [RotCord.Y +bp],cx
  180.  
  181.     add     bp,4            ;size of each entry
  182.     cmp     bp,NumPts*4     ;are we done, yet?
  183.     jb      @@DoNextPoint   ;No. Do another
  184.     
  185.     popad
  186.     ret
  187. RotateBox   ENDP
  188.  
  189.     ;draws the dots to the screen
  190. DrawBox     PROC NEAR
  191.     pusha               ;saves only non extended registers
  192.     mov     ax,0a000h   ;segment to VGA memory
  193.     mov     es,ax
  194.     mov     ax,cs
  195.     mov     ds,ax
  196.     
  197.     mov     bp,0        ;point counter
  198.     mov     al,[Color]
  199. @@DoNextPoint:
  200.     mov     si,bp
  201.     add     si,si
  202.     mov     bx,si       ;bx= bp*2
  203.     add     si,si       ;si= bp*4
  204.  
  205.     mov     di,[OldDI+bx]
  206.     mov     BYTE PTR es:[di],0  ;clear out old point
  207.  
  208.         ;pixel location = ScreenWidth*Ypos + Xpos = 320 * (Y+AddY) + X + AddX
  209.     mov     di,[RotCord.Y +si]
  210.     add     di,[AddY]
  211.     imul    di,320
  212.     add     di,[AddX]
  213.     add     di,[RotCord.X +si]
  214.     
  215.     mov     [OldDi+bx],di
  216.     stosb
  217.  
  218.     inc     bp
  219.     cmp     bp,NumPts       ;are we done, yet?
  220.     jb      @@DoNextPoint   ;No. Do another
  221.  
  222.     popa
  223.     ret
  224. DrawBox     ENDP
  225.  
  226. ─────────────────────────────────────────────────────────────────────────────
  227.  
  228. ;=== CODE
  229.  
  230. START:
  231.     mov     ax,cs
  232.     mov     ds,ax
  233.     mov     es,ax
  234.  
  235.     mov     ax,0013h                ;set 320x200x256 mode
  236.     int     10h
  237.     
  238.     mov     dx,offset Palette       ;ES:DX points to palette data
  239.     mov     ax,1012h                ; WRITE palette 
  240.     mov     bx,0                    ;start at color 0                   
  241.     mov     cx,16                   ; and write 16 of 'em
  242.     int     10h
  243.  
  244.     mov     dx,03d5h        ;this bit of code turns the cursor OFF
  245.     mov     al,0ah          ;by setting bit 5 of index 0ah to 0
  246.                             ;(CRT controll register selector = 03d5h)
  247.     mov     ah,0            ;this is done because some video cards
  248.     out     dx,ax           ;do not always turn off the cursor in
  249.                             ;graphics mode
  250.                             ;(note: it also turns all the other bit to 0)
  251. BoxLoop:
  252.     call    RotateBox
  253.     mov     al,[AngleVel]
  254.     add     [Angle.b],al    ;note that by just increasing the byte part, the 
  255.                             ;ranging is automatic (stays in 0-255 range)
  256.     mov     dx,3dah
  257. VRT:
  258.     in      al,dx
  259.     test    al,8
  260.     jnz     VRT         ;wait until Verticle Retrace starts
  261.  
  262. NoVRT:
  263.     in      al,dx
  264.     test    al,8
  265.     jz      NoVRT       ;wait until Verticle Retrace Ends
  266.  
  267.     call    DrawBox  
  268.     
  269.     mov     ah,2
  270.     mov     bx,0
  271.     mov     dx,0
  272.     int     10h         ;set cursor pos to (dl,dh) on page BX
  273.  
  274.     mov     ah,9
  275.     mov     dx,offset AngleMsg
  276.     int     21h
  277.  
  278.     mov     al,[Angle.B]
  279.     clc                 ;says print it unsigned
  280.     call    PrintByte
  281.     
  282.     mov     ah,2
  283.     mov     bx,0
  284.     mov     dx,0014h
  285.     int     10h         ;set cursor pos to (dl,dh) on page BX
  286.  
  287.     mov     ah,9
  288.     mov     dx,offset AngleVelMsg
  289.     int     21h
  290.  
  291.     mov     al,[AngleVel]
  292.     stc                 ;says print it signed
  293.     call    PrintByte
  294.  
  295.     mov     ah,1
  296.     int     16h         ;has a key been pressed? Z flag is set if not
  297.     jz      BoxLoop
  298.     mov     ah,0        ;a key has been pressed, 
  299.     int     16h         ; get it in AX (al= ascii, ah=scan code)
  300.  
  301.     cmp     al,27       ;was it the ESCAPE key?
  302.     je      ByeBye      ;Yup, take off
  303.  
  304.     cmp     al,"+"          ;increases angle velocity
  305.     jne     NotPlus
  306.     inc     [AngleVel]
  307.     jmp     SHORT BoxLoop
  308. NotPlus:
  309.     cmp     al,"-"          ;decreases angle velocity
  310.     jne     NotMinus
  311.     dec     [AngleVel]
  312.     jmp     SHORT BoxLoop
  313. NotMinus:
  314.     cmp     al," "          ;will reset the angle velocity to Zero
  315.     jne     NotSpace
  316.     mov     [AngleVel],0
  317.     jmp     BoxLoop
  318. NotSpace:
  319.     cmp     al,13           ;will reset the angle to zero
  320.     jne     NotEnter
  321.     mov     [Angle.W],0
  322.     jmp     BoxLoop
  323. NotEnter:
  324.  
  325.     jmp     BoxLoop
  326.  
  327. ByeBye:    
  328.     mov     ax,0003h    ;set 80x25x16 text
  329.     int     10h
  330.     mov     ax,4c00h    ;return control to DOS
  331.     int     21h
  332. END START
  333.