home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Party 1994: Try This At Home
/
disk_image.bin
/
source
/
rotate
/
rotate.asm
< prev
next >
Wrap
Assembly Source File
|
1993-02-14
|
11KB
|
333 lines
─────────────────────────────────────────────────────────────────────────────
;
; TITLE: 2d rotate
;WRITTEN BY: DRAEDEN /VLA CODER /iCE VGA CODER
; FOR: Phantasm, (206) 232-5912
; The first programing oriented board to hit the 206 area.
; Any questions regarding this or ANY code in any language
; can, and will be answered on Phantasm.
; Send messages to 'Draeden' or post in the VLA programming
; section.
;
; The Deep (TDT/VLA), (305) 888-7724
; Our first distribution site. Messages will also be answered
; if posted at this location.
; Send messages to 'The Kabal'.
;
; DATE: 02/13/93
;
; NOTES: Compiled with TASM, TLINK
; Must have a 386 or better to run. Any speed.
; This program was chosen as an example because it utilizes
; a lot of the neat little tricks you can do in assembly,
; mainly Structures (STRUC), Unions (UNION), INCLUDEs,
; the REPT macro, and the DUP() macro.
;
;ASSOCIATED FILES:
;
; BWPRINT.ASM => Displays signed and unsigned bytes, words, or
; > double words
;
; SINCOS.DW => Contains data for the sine and cosine operations
;
; ROTATE.TXT => A text file that further explains how to rotate
; > objects, what BWPRINT.ASM does, and
; > what the SINCOS.DW file is.
;
; MAKE.BAT => The file that'll put it all together into an .EXE
;
─────────────────────────────────────────────────────────────────────────────
DOSSEG ;tells compiler to sort segments according to the
;DOS standards- code, data, stack
.MODEL SMALL
.STACK 200h ;sets up a 512 byte stack
.DATA ;starts the data segment (empty)
.CODE ;starts the code segment
.386 ;tells compiler to allow 386 instructions
ASSUME CS:@CODE, DS:@CODE
;tells compiler to assume offsets are taken from
;the code segment
LOCALS ;turns local labels on eg. @@local:
─────────────────────────────────────────────────────────────────────────────
;=== GLOBALS -used to link multiple programs together
GLOBAL PrintByte:PROC, PrintWord:PROC, PrintBig:PROC
;above is for the file BWPRINT.ASM
─────────────────────────────────────────────────────────────────────────────
;=== Data Includes -include physically puts the file in this one on compile
INCLUDE sincos.dw ;Labels SINE: and COSINE: contains sine(0-255)*256
─────────────────────────────────────────────────────────────────────────────
;=== DATA Structures
Angle_Union UNION
B db 0
W dw 0
Angle_Union ENDS ;creates a new data type (eg. DW, DB, DD) called
;Angle_Union. Used just like in C
Point_Struc STRUC
X dw ?
Y dw ?
Point_Struc ENDS ;Create a structure (or a record)
─────────────────────────────────────────────────────────────────────────────
;=== DATA
NumPts EQU 8
XYCord Point_Struc <-50,50>,<50,50>,<-50,-50>,<50,-50>
Point_Struc <-30,30>,<30,30>,<-30,-30>,<30,-30>
;sets up data for the corners of a 2d box
RotCord Point_Struc NumPts DUP(<>)
OldDi dw NumPts DUP (0) ;holds di for quick erasing
Angle Angle_Union <?,?> ; the '?' defaults to zero, but you can't
;specify in a Union
AngleVel db 1 ;angle velocity
AddX dw 160 ;amount to ADD to each X cordinate
AddY dw 100 ;amount to ADD to each Y cord
Palette db 3 dup (0) ;sets up a palette that fades from (0,0,0) to
i = 1 ;(15*4,15*3,15*2) in 16 steps
REPT 15
db 4*i,3*i,2*i
i=i+1
ENDM
Color db 15
AngleMsg db "ANGLE: $"
AngleVelMsg db "VELOCITY: $"
─────────────────────────────────────────────────────────────────────────────
;=== Code Includes ;none.
─────────────────────────────────────────────────────────────────────────────
;=== SUBROUTINES
;DESTROYS: ax, edx, edi, si, ebp
;Input: BX= X CX= Y which are rotated Angle degrees
;OutPut:BX= X CX= Y
RotateXY proc near
push ds
mov ax,cs ;the basic formula for rotations:
mov ds,ax ; X := cos(angle) * x - sin(Xan) * y
; Y := sin(angle) * x + cos(Xan) * y
mov si,[Angle.W]
add si,si ; si = angle*2
mov ax,[Cosine+si] ; ax = cos(angle)
imul bx ; ax = cos(angle) * x
shl edx,16 ; put dx in high edx
mov dx,ax ; save all 32 bits
mov edi,edx ; store for later use
mov ax,[Sine+si] ; ax = sin(angle)
imul cx ; ax = sin(angle) * y
shl edx,16
mov dx,ax
sub edi,edx ; edi = edi-eax=cos(angle)*x-sin(angle)*y
sar edi,8 ; remove the "256-factor"
mov ebp,edi ; ebp = x-coordinate
mov ax,[Sine+si] ; ax = sin(angle x)
imul bx ; ax = sin(angle x) * x
shl edx,16
mov dx,ax
mov edi,edx
mov ax,[Cosine+si] ; ax = cos(angle x)
imul cx ; ax = cos(angle x) * y
shl edx,16
mov dx,ax
add edi,edx ; di = di-ax = sin(vx)*y + cos(vx)*z
sar edi,8 ; remove the (co)sin "256-factor"
mov bx,bp ; update X
mov cx,di ; update Y
pop ds
ret
RotateXY ENDP
;rotates all points and saves them
RotateBox PROC NEAR
pushad ;saves EVERYTHING (extended registers, too), except flags
mov ax,cs
mov ds,ax
mov es,ax
mov bp,0 ;point counter
@@DoNextPoint:
mov bx,[XYCord.X +bp] ;load in cordinates to rotate
mov cx,[XYCord.Y +bp]
push bp
call RotateXY
pop bp
mov [RotCord.X +bp],bx ;save rotated cordinates IN A DIFFERENT PLACE
mov [RotCord.Y +bp],cx
add bp,4 ;size of each entry
cmp bp,NumPts*4 ;are we done, yet?
jb @@DoNextPoint ;No. Do another
popad
ret
RotateBox ENDP
;draws the dots to the screen
DrawBox PROC NEAR
pusha ;saves only non extended registers
mov ax,0a000h ;segment to VGA memory
mov es,ax
mov ax,cs
mov ds,ax
mov bp,0 ;point counter
mov al,[Color]
@@DoNextPoint:
mov si,bp
add si,si
mov bx,si ;bx= bp*2
add si,si ;si= bp*4
mov di,[OldDI+bx]
mov BYTE PTR es:[di],0 ;clear out old point
;pixel location = ScreenWidth*Ypos + Xpos = 320 * (Y+AddY) + X + AddX
mov di,[RotCord.Y +si]
add di,[AddY]
imul di,320
add di,[AddX]
add di,[RotCord.X +si]
mov [OldDi+bx],di
stosb
inc bp
cmp bp,NumPts ;are we done, yet?
jb @@DoNextPoint ;No. Do another
popa
ret
DrawBox ENDP
─────────────────────────────────────────────────────────────────────────────
;=== CODE
START:
mov ax,cs
mov ds,ax
mov es,ax
mov ax,0013h ;set 320x200x256 mode
int 10h
mov dx,offset Palette ;ES:DX points to palette data
mov ax,1012h ; WRITE palette
mov bx,0 ;start at color 0
mov cx,16 ; and write 16 of 'em
int 10h
mov dx,03d5h ;this bit of code turns the cursor OFF
mov al,0ah ;by setting bit 5 of index 0ah to 0
;(CRT controll register selector = 03d5h)
mov ah,0 ;this is done because some video cards
out dx,ax ;do not always turn off the cursor in
;graphics mode
;(note: it also turns all the other bit to 0)
BoxLoop:
call RotateBox
mov al,[AngleVel]
add [Angle.b],al ;note that by just increasing the byte part, the
;ranging is automatic (stays in 0-255 range)
mov dx,3dah
VRT:
in al,dx
test al,8
jnz VRT ;wait until Verticle Retrace starts
NoVRT:
in al,dx
test al,8
jz NoVRT ;wait until Verticle Retrace Ends
call DrawBox
mov ah,2
mov bx,0
mov dx,0
int 10h ;set cursor pos to (dl,dh) on page BX
mov ah,9
mov dx,offset AngleMsg
int 21h
mov al,[Angle.B]
clc ;says print it unsigned
call PrintByte
mov ah,2
mov bx,0
mov dx,0014h
int 10h ;set cursor pos to (dl,dh) on page BX
mov ah,9
mov dx,offset AngleVelMsg
int 21h
mov al,[AngleVel]
stc ;says print it signed
call PrintByte
mov ah,1
int 16h ;has a key been pressed? Z flag is set if not
jz BoxLoop
mov ah,0 ;a key has been pressed,
int 16h ; get it in AX (al= ascii, ah=scan code)
cmp al,27 ;was it the ESCAPE key?
je ByeBye ;Yup, take off
cmp al,"+" ;increases angle velocity
jne NotPlus
inc [AngleVel]
jmp SHORT BoxLoop
NotPlus:
cmp al,"-" ;decreases angle velocity
jne NotMinus
dec [AngleVel]
jmp SHORT BoxLoop
NotMinus:
cmp al," " ;will reset the angle velocity to Zero
jne NotSpace
mov [AngleVel],0
jmp BoxLoop
NotSpace:
cmp al,13 ;will reset the angle to zero
jne NotEnter
mov [Angle.W],0
jmp BoxLoop
NotEnter:
jmp BoxLoop
ByeBye:
mov ax,0003h ;set 80x25x16 text
int 10h
mov ax,4c00h ;return control to DOS
int 21h
END START