;3D Rotate ; (C)1996 by Andreas Ess ;Hmm... There seems to be an error. I couldn't find it. Perhaps you are able to. ;If so, please send me a letter: ; Andreas Ess ; Tufers 156 ; A-6811 Goefis ; Austria/Europe ;----------------------------------------------------------------------------- #INCLUDE "TI-85.H" ;----------------------------------------------------------------------------- ;TEXT-MEM Vars: ;----------------------------------------------------------------------------- XSin = TEXT_MEM XCos = TEXT_MEM+2 YSin = TEXT_MEM+4 YCos = TEXT_MEM+6 ZSin = TEXT_MEM+8 ZCos = TEXT_MEM+10 Temp = TEXT_MEM+12 HelpX = TEXT_MEM+14 HelpY = TEXT_MEM+16 HelpZ = TEXT_MEM+18 RotatePoint = TEXT_MEM+20 RotateAngel = TEXT_MEM+37 SREM = TEXT_MEM+38 SQUOT = TEXT_MEM+39 XDeg = TEXT_MEM+40 YDeg = TEXT_MEM+42 ZDeg = TEXT_MEM+44 ;----------------------------------------------------------------------------- ;The program: ;----------------------------------------------------------------------------- .org 0 .db "3D ROTATION v0.1 BY AE",0 Start: di ROM_CALL(CLEARLCD) ld a, 4 ;set memory page 4 (graphic routines are here) out (5), a ;needed if FIND_PIXEL is going to be used ld b, 8 ld hl, (PROGRAM_ADDR) ld de, Cube add hl, de ex de, hl ld hl, RotatePoint CALL_(RotatePrj) WaitFirst: ld hl, RotatePoint ld b, 8 CALL_(DrawPoints) call GET_KEY cp 0 jr z, WaitFirst WaitKey: ld hl, (XDeg) inc hl ld de, 359 and a sbc hl, de jr nz, SaveXDeg ld hl, 0 SaveXDeg: ld (XDeg), hl ld b, 8 ld hl, (PROGRAM_ADDR) ld de, Cube add hl, de ex de, hl ld hl, RotatePoint CALL_(RotatePrj) ROM_CALL(CLEARLCD) ld hl, RotatePoint ld b, 8 CALL_(DrawPoints) CALL_(Delay) CALL_(Delay) CALL_(Delay) CALL_(Delay) CALL_(Delay) CALL_(Delay) call GET_KEY cp 0 jr z, WaitKey ei ret ;----------------------------------------------------------------------------- ;RotatePrj: This rotates a 3D-object and projects it ; INPUT: OUTPUT: ; DE - Base Address of 3D- HL - pointer to list where ; coordinates saved as the rotated and projected ; x byte,y byte,z byte,x byte,... 2D-points are(not base address!) ; HL - Where to save the 2D-points in ; x byte,y byte,x byte,... ; B - number of points ; (XDeg) - X-Rotation ; (YDeg) - Y-Rotation ; (ZDeg) - Rotation around Z-Axis ;----------------------------------------------------------------------------- RotatePrj: ;First, get the offset in the sine & cosine table for A(x-rot): push hl ;save registers push de ld hl, (XDeg) ;compute offset in SineTable add hl, hl ;correct offset = 2*XDeg, ld de, (PROGRAM_ADDR) ;add it to the address of program add hl, de ;and ld de, SineTable ;finally to the offset of SineTable add hl, de call LD_HL_MHL ;load contents of HL into HL ld (XSin), hl ;Save the sine into TEXT_MEM ld hl, (XDeg) add hl, hl ;multiply by 2... ld de, (PROGRAM_ADDR) ;add to program address, add hl, de ld de, CosineTable ;to cosine table offset add hl, de call LD_HL_MHL ld (XCos), hl ;we won't need it any more. pop de ;get original registers again pop hl ;- Rotate Points around X-Axis ----------------------------------------------- ; HelpX = X*XCos-Y*XSin ; HelpY = Y*XCos+X*XSin ; DE - Source WORDS ; HL - Destination BYTES ;----------------------------------------------------------------------------- RotatePointsL: ;now, rotate points... push bc push hl ld h, d ;let HL point to DE ld l, e call LD_HL_MHL ;and load the contents of DE into HL... push de ld de, (XCos) ;so, multiply X with CALL_(MUL16) ;XCos... ld (Temp), hl pop de inc de ;process next word... inc de ld h, d ld l, e call LD_HL_MHL push de ld de, (XSin) CALL_(MUL16) ld de, (Temp) ex de, hl or a sbc hl, de ld (HelpX), hl pop de ;Rotate Y now ld h, d ld l, e call LD_HL_MHL push de ld de, (XCos) CALL_(MUL16) ld (Temp), hl pop de dec de dec de call LD_HL_MHL push de ld de, (XSin) CALL_(MUL16) ld de, (Temp) add hl, de ld (HelpY), hl pop de ;Now we have rotated the points inc de ;process inc de ;Z or X byte(regarding what's X and inc de ;what's the Z-axis... inc de ; ld h, d ld l, e call LD_HL_MHL push de ld de, 20 ;so we've got a viewing space from(-10,-10,-10) ;to (10,10,10) add hl, de add hl, hl add hl, hl add hl, hl add hl, hl ld (HelpZ), hl ;PROJECT IT! ld hl, (HelpX) ld de, (HelpZ) CALL_(SDIV16) ld de, 64 add hl, de ld (Temp), hl pop de inc de inc de pop hl ld a, (Temp) ld (hl), a inc hl push hl push de ld hl, (HelpY) ld de, (HelpZ) CALL_(SDIV16) ld de, 32 add hl, de ld (Temp), hl pop de pop hl ld a, (Temp) ld (hl), a inc hl pop bc ; dec b ;another point? JUMP_NZ(RotatePointsL) ; ret ;----------------------------------------------------------------------------- ;MUL16 : multiplies 2 16-Bit numbers ;----------------------------------------------------------------------------- MUL16: ld c, l ;BC = MULTIPLIER ld b, h ld hl, 0 ;PRODUCT = 0 ld a, 15 ;COUNT = BIT LENGTH - 1 ;Shift and Add-Algorithm ;If MSB of Multiplier is 1, add multipliand to prtial ;product. Shift partial product, multiplier left 1 bit MLP: sla e rl d jr nc, MLP1 add hl, bc MLP1: add hl, hl dec a jr nz, MLP or d ret p add hl, bc ret ;----------------------------------------------------------------------------- ;SDIV16: signed division, uses UDIV16 ;----------------------------------------------------------------------------- SDIV16: push bc ld a, h ld (SREM), a xor d ld (SQUOT), a bit 7, d jr z, CheckDE or a sub a sub e ld e, a sbc a, a sub d ld d, a CheckDE: bit 7, h jr z, DoDiv or a sub a sub l ld l, a sbc a, a sub h ld h, a DoDiv: CALL_(UDIV16) ld a, (SQUOT) bit 7, a jr z, DoRem ;! or a sub a sub l ld l, a sbc a, a sub h ld h, a DoRem: pop bc ret ;----------------------------------------------------------------------------- ;UDIV16: divides HL trough DE ; quotient in HL ; remainder in DE ; carry = 0 ;----------------------------------------------------------------------------- UDIV16: Divide: ld c, l ld a, h ld hl, 0 ;hl = remainder ld b, 16 ;16 bits in dividend or a ;clear carry DivLoop: rl c rla rl l rl h push hl sbc hl, de ccf jr c, Drop ex (sp), hl Drop: inc sp inc sp djnz DivLoop ex de, hl rl c ld l, c rla ld h, a or a ret ;----------------------------------------------------------------------------- ;DrawPoints ;----------------------------------------------------------------------------- DrawPoints: DrawLoop: push bc ld b, (hl) inc hl ld c, (hl) inc hl CALL_(PointOn) pop bc djnz DrawLoop ret ;----------------------------------------------------------------------------- ;PointOn: draws point at b=x, c=y ;----------------------------------------------------------------------------- PointOn: push hl push bc push de ROM_CALL(FIND_PIXEL) ;HL=byte offset in video buffer, A=2^(bit to change) ld de, VIDEO_MEM add hl, de or (hl) ld (hl), a pop de pop bc pop hl ret ;----------------------------------------------------------------------------- ;Delay: waits ;----------------------------------------------------------------------------- Delay: ld bc, $1000 DelayLoop: dec bc ld a, b or c jr nz, DelayLoop ret ;----------------------------------------------------------------------------- ;A Cube ;----------------------------------------------------------------------------- ; Z Y X Cube: .dw 10, -10, 10 .dw -10, -10, 10 .dw -10, 10, 10 .dw 10, 10, 10 .dw 10, -10, -10 .dw -10, -10, -10 .dw -10, 10, -10 .dw 10, 10, -10 ;----------------------------------------------------------------------------- ;Sine & Cosine Tables shifted by 8 ;----------------------------------------------------------------------------- SineTable: .dw $0000,$0004,$0008,$000D,$0011,$0016,$001A,$001F,$0023,$0028,$002C,$0030,$0035,$0039,$003D,$0042 .dw $0046,$004A,$004F,$0053,$0057,$005B,$005F,$0064,$0068,$006C,$0070,$0074,$0078,$007C,$007F,$0083 .dw $0087,$008B,$008F,$0092,$0096,$009A,$009D,$00A1,$00A4,$00A7,$00AB,$00AE,$00B1,$00B5,$00B8,$00BB .dw $00BE,$00C1,$00C4,$00C6,$00C9,$00CC,$00CF,$00D1,$00D4,$00D6,$00D9,$00DB,$00DD,$00DF,$00E2,$00E4 .dw $00E6,$00E8,$00E9,$00EB,$00ED,$00EE,$00F0,$00F2,$00F3,$00F4,$00F6,$00F7,$00F8,$00F9,$00FA,$00FB .dw $00FC,$00FC,$00FD,$00FE,$00FE,$00FF,$00FF,$00FF,$00FF,$00FF,$0100,$00FF,$00FF,$00FF,$00FF,$00FF .dw $00FE,$00FE,$00FD,$00FC,$00FC,$00FB,$00FA,$00F9,$00F8,$00F7,$00F6,$00F4,$00F3,$00F2,$00F0,$00EE .dw $00ED,$00EB,$00E9,$00E8,$00E6,$00E4,$00E2,$00DF,$00DD,$00DB,$00D9,$00D6,$00D4,$00D1,$00CF,$00CC .dw $00C9,$00C6,$00C4,$00C1,$00BE,$00BB,$00B8,$00B5,$00B1,$00AE,$00AB,$00A7,$00A4,$00A1,$009D,$009A .dw $0096,$0092,$008F,$008B,$0087,$0083,$0080,$007C,$0078,$0074,$0070,$006C,$0068,$0064,$005F,$005B .dw $0057,$0053,$004F,$004A,$0046,$0042,$003D,$0039,$0035,$0030,$002C,$0028,$0023,$001F,$001A,$0016 .dw $0011,$000D,$0008,$0004,$0000,$FFFC,$FFF8,$FFF3,$FFEF,$FFEA,$FFE6,$FFE1,$FFDD,$FFD8,$FFD4,$FFD0 .dw $FFCB,$FFC7,$FFC3,$FFBE,$FFBA,$FFB6,$FFB1,$FFAD,$FFA9,$FFA5,$FFA1,$FF9C,$FF98,$FF94,$FF90,$FF8C .dw $FF88,$FF84,$FF81,$FF7D,$FF79,$FF75,$FF71,$FF6E,$FF6A,$FF66,$FF63,$FF5F,$FF5C,$FF59,$FF55,$FF52 .dw $FF4F,$FF4B,$FF48,$FF45,$FF42,$FF3F,$FF3C,$FF3A,$FF37,$FF34,$FF31,$FF2F,$FF2C,$FF2A,$FF27,$FF25 .dw $FF23,$FF21,$FF1E,$FF1C,$FF1A,$FF18,$FF17,$FF15,$FF13,$FF12,$FF10,$FF0E,$FF0D,$FF0C,$FF0A,$FF09 .dw $FF08,$FF07,$FF06,$FF05,$FF04,$FF04,$FF03,$FF02,$FF02,$FF01,$FF01,$FF01,$FF01,$FF01,$FF00,$FF01 .dw $FF01,$FF01,$FF01,$FF01,$FF02,$FF02,$FF03,$FF04,$FF04,$FF05,$FF06,$FF07,$FF08,$FF09,$FF0A,$FF0C .dw $FF0D,$FF0E,$FF10,$FF12,$FF13,$FF15,$FF17,$FF18,$FF1A,$FF1C,$FF1E,$FF21,$FF23,$FF25,$FF27,$FF2A .dw $FF2C,$FF2F,$FF31,$FF34,$FF37,$FF3A,$FF3C,$FF3F,$FF42,$FF45,$FF48,$FF4B,$FF4F,$FF52,$FF55,$FF59 .dw $FF5C,$FF5F,$FF63,$FF66,$FF6A,$FF6E,$FF71,$FF75,$FF79,$FF7D,$FF80,$FF84,$FF88,$FF8C,$FF90,$FF94 .dw $FF98,$FF9C,$FFA1,$FFA5,$FFA9,$FFAD,$FFB1,$FFB6,$FFBA,$FFBE,$FFC3,$FFC7,$FFCB,$FFD0,$FFD4,$FFD8 .dw $FFDD,$FFE1,$FFE6,$FFEA,$FFEF,$FFF3,$FFF8,$FFFC CosineTable: .dw $0100,$00FF,$00FF,$00FF,$00FF,$00FF,$00FE,$00FE,$00FD,$00FC,$00FC,$00FB,$00FA,$00F9,$00F8,$00F7 .dw $00F6,$00F4,$00F3,$00F2,$00F0,$00EE,$00ED,$00EB,$00E9,$00E8,$00E6,$00E4,$00E2,$00DF,$00DD,$00DB .dw $00D9,$00D6,$00D4,$00D1,$00CF,$00CC,$00C9,$00C6,$00C4,$00C1,$00BE,$00BB,$00B8,$00B5,$00B1,$00AE .dw $00AB,$00A7,$00A4,$00A1,$009D,$009A,$0096,$0092,$008F,$008B,$0087,$0083,$0080,$007C,$0078,$0074 .dw $0070,$006C,$0068,$0064,$005F,$005B,$0057,$0053,$004F,$004A,$0046,$0042,$003D,$0039,$0035,$0030 .dw $002C,$0028,$0023,$001F,$001A,$0016,$0011,$000D,$0008,$0004,$0000,$FFFC,$FFF8,$FFF3,$FFEF,$FFEA .dw $FFE6,$FFE1,$FFDD,$FFD8,$FFD4,$FFD0,$FFCB,$FFC7,$FFC3,$FFBE,$FFBA,$FFB6,$FFB1,$FFAD,$FFA9,$FFA5 .dw $FFA1,$FF9C,$FF98,$FF94,$FF90,$FF8C,$FF88,$FF84,$FF81,$FF7D,$FF79,$FF75,$FF71,$FF6E,$FF6A,$FF66 .dw $FF63,$FF5F,$FF5C,$FF59,$FF55,$FF52,$FF4F,$FF4B,$FF48,$FF45,$FF42,$FF3F,$FF3C,$FF3A,$FF37,$FF34 .dw $FF31,$FF2F,$FF2C,$FF2A,$FF27,$FF25,$FF23,$FF21,$FF1E,$FF1C,$FF1A,$FF18,$FF17,$FF15,$FF13,$FF12 .dw $FF10,$FF0E,$FF0D,$FF0C,$FF0A,$FF09,$FF08,$FF07,$FF06,$FF05,$FF04,$FF04,$FF03,$FF02,$FF02,$FF01 .dw $FF01,$FF01,$FF01,$FF01,$FF00,$FF01,$FF01,$FF01,$FF01,$FF01,$FF02,$FF02,$FF03,$FF04,$FF04,$FF05 .dw $FF06,$FF07,$FF08,$FF09,$FF0A,$FF0C,$FF0D,$FF0E,$FF10,$FF12,$FF13,$FF15,$FF17,$FF18,$FF1A,$FF1C .dw $FF1E,$FF21,$FF23,$FF25,$FF27,$FF2A,$FF2C,$FF2F,$FF31,$FF34,$FF37,$FF3A,$FF3C,$FF3F,$FF42,$FF45 .dw $FF48,$FF4B,$FF4F,$FF52,$FF55,$FF59,$FF5C,$FF5F,$FF63,$FF66,$FF6A,$FF6E,$FF71,$FF75,$FF79,$FF7D .dw $FF80,$FF84,$FF88,$FF8C,$FF90,$FF94,$FF98,$FF9C,$FFA1,$FFA5,$FFA9,$FFAD,$FFB1,$FFB6,$FFBA,$FFBE .dw $FFC3,$FFC7,$FFCB,$FFD0,$FFD4,$FFD8,$FFDD,$FFE1,$FFE6,$FFEA,$FFEF,$FFF3,$FFF8,$FFFC,$0000,$0004 .dw $0008,$000D,$0011,$0016,$001A,$001F,$0023,$0028,$002C,$0030,$0035,$0039,$003D,$0042,$0046,$004A .dw $004F,$0053,$0057,$005B,$005F,$0064,$0068,$006C,$0070,$0074,$0078,$007C,$007F,$0083,$0087,$008B .dw $008F,$0092,$0096,$009A,$009D,$00A1,$00A4,$00A7,$00AB,$00AE,$00B1,$00B5,$00B8,$00BB,$00BE,$00C1 .dw $00C4,$00C6,$00C9,$00CC,$00CF,$00D1,$00D4,$00D6,$00D9,$00DB,$00DD,$00DF,$00E2,$00E4,$00E6,$00E8 .dw $00E9,$00EB,$00ED,$00EE,$00F0,$00F2,$00F3,$00F4,$00F6,$00F7,$00F8,$00F9,$00FA,$00FB,$00FC,$00FC .dw $00FD,$00FE,$00FE,$00FF,$00FF,$00FF,$00FF,$00FF .end