; ; Turtle-Library V3.0 ; ; 04.01.90 ; ; Thomas Albers ; INCDIR "DevpacAm:include/" INCLUDE "exec.offsets" INCLUDE "graphics.offsets" INCLUDE "mathffp.offsets" INCLUDE "mathtrans.offsets" INCLUDE "exec/types.i" INCLUDE "exec/alerts.i" INCLUDE "exec/initializers.i" INCLUDE "exec/libraries.i" INCLUDE "exec/lists.i" INCLUDE "exec/resident.i" INCLUDE "graphics/rastport.i" ExecBase = 4 ;TurtleBase STRUCTURE TurtleBase,LIB_SIZE ULONG tb_SegList ;pointer to Segment List, ULONG tb_GfxBase ; to Graphics Library, ULONG tb_FFPBase ; to MathFFP Library, ULONG tb_FFPTBase ; and to MathTrans Library LABEL TurLib_SIZEOF ;TurtleHandle STRUCTURE TurtleHandle,0 APTR th_RastPort ;pointer to RastPort FLOAT th_xPosition ;x Position (FFP) FLOAT th_yPosition ;y Position (FFP) UWORD th_angle ;angle of Turtle UWORD th_xStart ;initial x UWORD th_yStart ;initial y UWORD th_aStart ;initial angle UBYTE th_Flags ;flags UBYTE th_FlagStart ;initial flags STRUCT th_PointArray,12 ;points of Turtle triangle LABEL TurtleHandle_SIZEOF ;Flags BITDEF Tur,Hide,0 ;turtle hidden BITDEF Tur,Up,1 ;pen Up BITDEF Tur,xComp,2 ;x compression BITDEF Tur,yComp,3 ;y compression BITDEF Tur,TValid,7 ;triangle valid ;if someone tried to run this Start: MOVEQ #0,D0 RTS Priority = 0 Version = 3 Revision = 2 ;Resident structure for Library Resident: DC.W RTC_MATCHWORD ;magic value DC.L Resident ;pointer to beginning DC.L EndCode ; and end of structure DC.B RTF_AUTOINIT ;type DC.B Version ;version DC.B NT_LIBRARY ;node type DC.B Priority ;priority DC.L TurtName ;library name DC.L InfoStrg ;info string DC.L InitData ;initialisisation data TurtName DC.B "turtle.library",0 InfoStrg DC.B "turtle.library V3.2 (04 Jan 1990) by Thomas Albers",13,10,0 GfxName DC.B "graphics.library",0 FFPName DC.B "mathffp.library",0 FFPTName DC.B "mathtrans.library",0 EVEN InitData: DC.L TurLib_SIZEOF ;size of Library base DC.L FuncTable ;function table DC.L DataTable ;table for InitStruct DC.L LibInit ;initialisation routine FuncTable: DC.L Open DC.L Close DC.L Expunge DC.L ExtFunc DC.L CreateTurtle DC.L ReturnTurtle DC.L TurnLeft DC.L TurnRight DC.L PenUp DC.L PenDown DC.L HideTurtle DC.L ShowTurtle DC.L SetAngle DC.L SetPosition DC.L ResetTurtle DC.L Forward DC.L -1 DataTable: INITBYTE LN_TYPE,NT_LIBRARY INITLONG LN_NAME,TurtName INITBYTE LIB_FLAGS,LIBF_SUMUSED|LIBF_CHANGED INITWORD LIB_VERSION,Version INITWORD LIB_REVISION,Revision INITLONG LIB_IDSTRING,InfoStrg DC.L 0 LibInit: ;This routine is called after the library has been loaded from disk ;D0: Pointer to Library ;A0: Pointer to Segment list MOVEM.L A5-A6,-(SP) MOVE.L ExecBase,A6 MOVE.L D0,A5 ;pointer to Library MOVE.L A0,tb_SegList(A5) ;save pointer to Segment list LEA GfxName,A1 ;open Graphics Library MOVEQ #0,D0 JSR _LVOOpenLibrary(A6) MOVE.L D0,tb_GfxBase(A5) BEQ.S .LibIni1 ;error? LEA FFPName,A1 ;open MathFFP Library MOVEQ #0,D0 JSR _LVOOpenLibrary(A6) MOVE.L D0,tb_FFPBase(A5) BEQ.S .LibIni2 ;error? LEA FFPTName,A1 ;open MathTrans Library MOVEQ #0,D0 JSR _LVOOpenLibrary(A6) MOVE.L D0,tb_FFPTBase(A5) BEQ.S .LibIni3 ;error? MOVE.L A5,D0 ;allright, return Pointer to Library MOVEM.L (SP)+,A5-A6 RTS .LibIni3 MOVE.L tb_FFPBase(A5),A1 ;error, close Libraries JSR _LVOCloseLibrary(A6) .LibIni2 MOVE.L tb_GfxBase(A5),A1 JSR _LVOCloseLibrary(A6) .LibIni1 CLR.L D0 ;and return 0 MOVEM.L (SP)+,A5-A6 RTS Open: ;This routine is called each time when the library is opened ;A6: Pointer to Library ADDQ.W #1,LIB_OPENCNT(A6) ;increase Open count BCLR #LIBB_DELEXP,LIB_FLAGS(A6) ;no Delayed Expunge MOVE.L A6,D0 ;return pointer to Library RTS Close: ;This routine gets called each time the library is closed ;A6: Pointer to Library SUBQ.W #1,LIB_OPENCNT(A6) ;decrease Open count BNE.S .Clos1 ;still open BTST #LIBB_DELEXP,LIB_FLAGS(A6) ;Delayed Expunge? BNE.S Expunge ;yes, do it .Clos1 CLR.L D0 ;return 0 (no Expunge) RTS Expunge: ;This routine is used to clear the library from memory ;A6: Pointer to Library TST.W LIB_OPENCNT(A6) ;library still open? BEQ.S .Expung1 ;no, remove it BSET #LIBB_DELEXP,LIB_FLAGS(A6) ;set Delayed Expunge flag CLR.L D0 ;and return 0 RTS .Expung1 MOVEM.L D2-D3/A4-A6,-(SP) MOVE.L A6,A5 ;pointer to library MOVE.L ExecBase,A6 MOVE.L tb_SegList(A5),D2 ;pointer to Segment list MOVEQ #8,D3 ;close Libraries .Expung2 MOVE.L tb_GfxBase(A5,D3.W),A1 JSR _LVOCloseLibrary(A6) SUBQ.W #4,D3 BPL.S .Expung2 MOVE.L A5,A1 ;remove library from library list JSR _LVORemove(A6) CLR.L D0 MOVE.L A5,A1 MOVE.W LIB_NEGSIZE(A5),D0 SUB.L D0,A1 ;pointer to beginning of library ADD.W LIB_POSSIZE(A5),D0 ;length JSR _LVOFreeMem(A6) ;return memory MOVE.L D2,D0 ;return pointer to Segment list MOVEM.L (SP)+,D2-D3/A5-A6 RTS ExtFunc: ;unused function MOVEQ #0,D0 RTS CreateTurtle: ;create TurtleHandle ; ;A0: pointer to RastPort ;D0: x position ;D1: y position ;D2: angle ;D3: flags MOVEM.L D0-D3/A0/A4-A6,-(SP) MOVE.L A6,A5 MOVE.L ExecBase,A6 MOVEQ #TurtleHandle_SIZEOF,D0 ;allocate memory MOVEQ #0,D1 JSR _LVOAllocMem(A6) TST.L D0 ;error? BEQ.S .Create1 ;yes, return MOVE.L D0,A4 ;pointer to memory MOVE.L tb_FFPBase(A5),A6 MOVE.L 16(SP),th_RastPort(A4) ;store pointer to RastPort MOVE.W 10(SP),th_angle(A4) ; and angle in Handle MOVE.W 10(SP),th_aStart(A4) MOVE.B 15(SP),D0 ;flags BCLR #TurB_TValid,D0 ;clear Triangle Valid flag MOVE.B D0,th_Flags(A4) ;and store it MOVE.B D0,th_FlagStart(A4) MOVE.W 2(SP),D0 ;x position MOVE.W D0,th_xStart(A4) ;as initial position in Handle EXT.L D0 JSR _LVOSPFlt(A6) ;to FFP MOVE.L D0,th_xPosition(A4) ;as actual position MOVE.W 6(SP),D0 ;y position MOVE.W D0,th_yStart(A4) EXT.L D0 JSR _LVOSPFlt(A6) MOVE.L D0,th_yPosition(A4) MOVE.L A4,A0 ;draw triangle MOVE.L A5,A6 BSR DrawTurtle MOVE.L A4,D0 ;return pointer to TurtleHandle .Create1 ADDQ.L #8,SP MOVEM.L (SP)+,D2-D3/A0/A4-A6 RTS ReturnTurtle: ;return TurtleHandle ; ;A0: Zeiger auf Handle MOVE.L A6,-(SP) BSR DrawTurtle ;clear triangle MOVE.L ExecBase,A6 MOVE.L A0,A1 ;and return memory MOVEQ #TurtleHandle_SIZEOF,D0 JSR _LVOFreeMem(A6) MOVE.L (SP)+,A6 RTS TurnRight: ;turn Turtle to the right (negative) ; ;A0: pointer to Turtlehandle ;D0: angle NEG.W D0 ;change sign ;und weiter bei TurnLeft TurnLeft: ;turn Turtle to the left (positive) ; ;A0: pointer to Turtlehandle ;D0: angle BSR DrawTurtle ;clear triangle ADD.W th_Angle(A0),D0 ;new angle EXT.L D0 DIVS #360,D0 ;mod 360 SWAP D0 ;remainder TST.W D0 ;positiv? BPL.S .TurnRi1 ;yes ADD.W #360,D0 ;no, make positive .TurnRi1 MOVE.W D0,th_Angle(A0) ;save angle BCLR #TurB_TValid,th_Flags(A0) ;triangle invalid BRA DrawTurtle ;new triangle PenUp: ;Pen up ; ;A0: pointer to TurtleHandle ; BSET #TurB_Up,th_Flags(A0) ;set Pen Up flag RTS PenDown: ;Pen down ; ;A0: pointer to TurtleHandle ; BCLR #TurB_Up,th_Flags(A0) ;clear Pen Up flag RTS HideTurtle: ;Hide Turtle triangle ; ;A0: pointer to TurtleHandle ; BTST #TurB_Hide,th_Flags(A0) ;already hidden? BNE.S .HideTu1 ;yes BSR DrawTurtle ;clear triangle BSET #TurB_Hide,th_Flags(A0) ;set Hide Turtle flag .HideTu1 RTS ShowTurtle: ;Show Turtle triangle ; ;A0: pointer to TurtleHandle ; BCLR #TurB_Hide,th_Flags(A0) ;clear Hide Turtle flag BEQ.S .ShowTu1 ;already cleared BCLR #TurB_TValid,th_Flags(A0) ;triangle invalid BSR DrawTurtle ;draw it .ShowTu1 RTS SetAngle: ;Set Turtle angle ; ;A0: pointer to TurtleHandle ;D0: new angle ; BSR DrawTurtle ;clear triangle MOVE.W D0,th_Angle(A0) ;new angle BCLR #TurB_TValid,th_Flags(A0) ;triangle invalid BRA DrawTurtle ;draw it SetPosition: ;Set Turtle position ; ;A0: Zeiger auf Turtlehandle ;D0: x position ;D1: y position ; MOVEM.L D0-D1/A4-A6,-(SP) BSR DrawTurtle ;clear triangle MOVE.L A0,A4 ;TurtleHandle MOVE.L A6,A5 MOVE.L tb_FFPBase(A5),A6 ;FFP Library MOVE.W 2(SP),D0 ;x position EXT.L D0 JSR _LVOSPFlt(A6) ;to FFP MOVE.L D0,th_xPosition(A4) ;save it MOVE.W 6(SP),D0 ;y-Position EXT.L D0 JSR _LVOSPFlt(A6) MOVE.L D0,th_yPosition(A4) MOVE.L A5,A6 BCLR #TurB_TValid,th_Flags(A4) ;triangle invalid BSR DrawTurtle ;draw it ADDQ.L #8,SP MOVEM.L (SP)+,A4-A6 RTS ResetTurtle: ;Reset Turtle to initial state ; ;A0: pointer to TurtleHandle ; MOVEM.L A4-A6,-(SP) BSR DrawTurtle ;clear triangle MOVE.L A0,A4 ;pointer to TurtleHandle MOVE.L A6,A5 MOVE.L tb_FFPBase(A5),A6 MOVE.W th_aStart(A4),th_Angle(A4) ;set angle and flags to initial values MOVE.B th_FlagStart(A4),th_Flags(A4) MOVE.W th_xStart(A4),D0 ;initial x position EXT.L D0 JSR _LVOSPFlt(A6) ;to FFP MOVE.L D0,th_xPosition(A4) ;actual x position MOVE.W th_yStart(A4),D0 ;initial y position EXT.L D0 JSR _LVOSPFlt(A6) MOVE.L D0,th_yPosition(A4) MOVE.L A5,A6 BSR DrawTurtle ;draw triangle MOVEM.L (SP)+,A4-A6 RTS Forward: ;Move Turtle ; ;A0: pointer to TurtleHandle ;D0: distance (FFP) ; MOVEM.L D2-D6/A2-A3/A5-A6,-(SP) MOVE.L D0,D2 ;distance MOVE.L A0,A2 ;TurtleHandle MOVE.L A6,A5 ;library BSR DrawTurtle ;clear triangle MOVE.L tb_FFPBase(A5),A6 MOVE.W th_Angle(A2),D0 ;convert angle EXT.L D0 JSR _LVOSPFlt(A6) ;to FFP MOVE.L #$8EFA353B,D1 ; (pi/180) JSR _LVOSPMul(A6) ;and to radians MOVE.L tb_FFPTBase(A5),A6 SUBQ.L #4,SP ;space for cosine on stack MOVE.L SP,D1 JSR _LVOSPSinCos(A6) MOVE.L D0,D5 ;sine MOVE.L (SP)+,D6 ;cosine MOVE.L tb_FFPBase(A5),A6 MOVE.L D2,D1 ;y component of distance: JSR _LVOSPMul(A6) ; yd := d * sin w MOVE.L D0,D1 MOVE.L th_yPosition(A2),D0 ;y position: JSR _LVOSPSub(A6) ; yp := yp-yd MOVE.L D0,D3 MOVE.L D6,D0 ;x component of distance: MOVE.L D2,D1 ; xd := d * cos w JSR _LVOSPMul(A6) MOVE.L th_xPosition(A2),D1 ;x position: JSR _LVOSPAdd(A6) ; xp := xp+xd MOVE.L D0,D2 BTST #TurB_Up,th_Flags(A2) ;Pen up? BNE.S .Forwar1 ;yes MOVE.L th_RastPort(A2),A3 ;Rastport MOVE.L th_yPosition(A2),D0 ;convert old position to integer JSR _LVOSPFix(A6) MOVE.L D0,D4 MOVE.L th_xPosition(A2),D0 JSR _LVOSPFix(A6) MOVE.L tb_GfxBase(A5),A6 MOVE.L A3,A1 ;graphics cursor to old position MOVE.L D4,D1 JSR _LVOMove(A6) MOVE.L tb_FFPBase(A5),A6 MOVE.L D3,D0 ;convert new position to integer JSR _LVOSPFix(A6) MOVE.L D0,D4 MOVE.L D2,D0 JSR _LVOSPFix(A6) MOVE.L tb_GfxBase(A5),A6 MOVE.L A3,A1 ;draw line MOVE.L D4,D1 JSR _LVODraw(A6) .Forwar1 MOVE.L D2,th_xPosition(A2) ;save new position MOVE.L D3,th_yPosition(A2) BTST #TurB_Hide,th_Flags(A2) ;triangle visible? BNE.S .Forwar2 ;no MOVE.L tb_FFPBase(A5),A6 ;yes, calculate coordinates BSR.S CalcTurtle MOVE.L A2,A0 ;and draw it MOVE.L A5,A6 BSR DrawTurtle .Forwar2 MOVEM.L (SP)+,D2-D6/A2-A3/A5-A6 RTS CalcTurtle: ;calculate points of Turtle triangle ; ;D2: x position (FFP) ;D3: y position (FFP) ;D5: sine ;D6: cosine ;A2: pointer to TurtleHandle ;A6: pointer to MathFFP library ; ;This function is private and is not contained in the jump table ; ;Do take care! Register contents are changed! ; MOVE.L D2,D0 ;convert position to integer JSR _LVOSPFix(A6) MOVE.W D0,th_PointArray+4(A2) MOVE.L D3,D0 JSR _LVOSPFix(A6) MOVE.W D0,th_PointArray+6(A2) ;2nd point MOVE.L D2,D0 ;x position MOVE.L D6,D1 ADDQ.B #3,D1 ; cos*8 BTST #TurB_xComp,th_Flags(A2) ; x compression? BEQ.S .CalcTu1 ; no SUBQ.B #1,D1 ; cos*4 .CalcTu1 JSR _LVOSPSub(A6) ;xpos - c*cos MOVE.L D0,D2 ;as x coordinate of center of baseline MOVE.L D3,D0 ;y position MOVE.L D5,D1 ADDQ.B #3,D1 ; sin*8 BTST #TurB_yComp,th_Flags(A2) ; y compression? BEQ.S .CalcTu2 ; no SUBQ.B #1,D1 ; sin*4 .CalcTu2 JSR _LVOSPAdd(A6) ;ypos - c*sin MOVE.L D0,D3 ;as y coordinate of center of baseline MOVE.L D2,D0 ;x center MOVE.L D5,D1 ADDQ.B #2,D1 ; sin*4 BTST #TurB_xComp,th_Flags(A2) ; x compression? BEQ.S .CalcTu3 ; no SUBQ.B #1,D1 ; sin*2 .CalcTu3 MOVE.L D1,D4 ; save sine JSR _LVOSPSub(A6) ;x center - sin JSR _LVOSPFix(A6) ;to integer MOVE.W D0,th_PointArray+0(A2) ;x coordinate of 1st point MOVE.L D2,D0 MOVE.L D4,D1 JSR _LVOSPAdd(A6) ;x center + sin JSR _LVOSPFix(A6) MOVE.W D0,th_PointArray+8(A2) ;x coordinate of 3rd point MOVE.L D3,D0 ;y center MOVE.L D6,D1 ADDQ.B #2,D1 BTST #TurB_yComp,th_Flags(A2) BEQ.S .CalcTu4 SUBQ.B #1,D1 .CalcTu4 MOVE.L D1,D4 JSR _LVOSPSub(A6) ;y center - cos JSR _LVOSPFix(A6) MOVE.W D0,th_PointArray+2(A2) ;y coordinate of 1st point MOVE.L D3,D0 MOVE.L D4,D1 JSR _LVOSPAdd(A6) ;y center + cos JSR _LVOSPFix(A6) MOVE.W D0,th_PointArray+10(A2) ;y coordinate of 3rd point BSET #TurB_TValid,th_Flags(A2) ;triangle valid RTS DrawTurtle: ;draw Turtle triangle ; ;A0: pointer to TurtleHandle ; ;This function is provate and not contained in the jump table ; ;Register contents are not changed! ; BTST #TurB_Hide,th_Flags(A0) ;triangle hidden? BEQ.S .DrawTu2 ;no, draw it RTS .DrawTu2 MOVEM.L D0-D6/A0-A3/A5-A6,-(SP) MOVE.L A0,A2 ;TurtleHandle MOVE.L th_RastPort(A2),A3 ;RastPort MOVE.L A6,A5 ;Library Base BTST #TurB_TValid,th_Flags(A2) ;triangle valid? BNE.S .DrawTu1 ;yes MOVE.L tb_FFPBase(A5),A6 MOVE.W th_Angle(A2),D0 ;convert angle EXT.L D0 JSR _LVOSPFlt(A6) MOVE.L #$8EFA353B,D1 ;to radians JSR _LVOSPMul(A6) MOVE.L tb_FFPTBase(A5),A6 SUBQ.L #4,SP MOVE.L SP,D1 JSR _LVOSPSinCos(A6) MOVE.L D0,D5 ;sine to D5, MOVE.L (SP)+,D6 ;cosine to D6 MOVE.L th_xPosition(A2),D2 ;x position to D2 MOVE.L th_yPosition(A2),D3 ;y position to D3 MOVE.L tb_FFPBase(A5),A6 ;calculate points BSR CalcTurtle .DrawTu1 MOVE.L tb_GfxBase(A5),A6 MOVE.B rp_FgPen(A3),-(SP) ;save FgPen and DrawMode of RastPort MOVE.B rp_DrawMode(A3),-(SP) MOVE.L A3,A1 ;draw into all planes MOVEQ #-1,D0 JSR _LVOSetAPen(A6) MOVE.L A3,A1 ;new DrawMode MOVEQ #RP_JAM1|RP_COMPLEMENT,D0 JSR _LVOSetDrMd(A6) MOVE.L A3,A1 ;graphics cursor to 1st point MOVE.W th_PointArray+0(A2),D0 MOVE.W th_PointArray+2(A2),D1 JSR _LVOMove(A6) MOVE.L A3,A1 ;draw triangle MOVEQ #2,D0 LEA th_PointArray+4(A2),A0 JSR _LVOPolyDraw(A6) MOVE.L A3,A1 ;restore DrawMode MOVE.B (SP)+,D0 JSR _LVOSetDrMd(A6) MOVE.L A3,A1 ;and FgPen MOVE.B (SP)+,D0 JSR _LVOSetAPen(A6) MOVEM.L (SP)+,D0-D6/A0-A3/A5-A6 RTS EndCode: