TweetFollow Us on Twitter

Rose
Volume Number:3
Issue Number:1
Column Tag:Assembly Language Lab

Rose Curve Generator

By Victor Barger, Waunakee, WI

An application of mathematics which produces fascinating designs is the graphing of trigonometric functions using polar coordinates. Each function leads to a beautiful design which bears a strong resemblance to a flower, such as the rose. With its excellent graphics capabilities and superior user interface, the Macintosh is perfect for quickly plotting “rose” functions on the screen with a program simple enough that anyone can use it. The application described in this article takes full advantage of these capabilities to allow the user to experience the graphic beauty of trigonometry.

Using Rose Curves

After launching Rose Curves, a window will open in the center of the screen and the default function will be drawn inside. (See Figure 1) Both the standard apple menu and a Control menu will be in the menu bar. The apple menu contains the item “About Rose Curves...” and the names of all desk accessories available to the user from the System file. Under the Control menu are two options: Change Parameters and Quit. When the Change Parameters item is selected a window similar to the one in Figure 2 is opened in the center of the screen. With this window the user can select the function to be drawn, choose the size of the drawing and indicate whether the drawing should be multilayered. Function and size are selected by clicking on the appropriate function name or size. For example, selecting cos (sin 100r) gives the design in Figure 3. If multilayered is selected, the function will be drawn at the original size and then shrunk repeatedly to create a “layered” effect, making the design more interesting: See Figure 4.

Entering the Program

Start up the Macintosh 68000 Development System. The startup disk should be titled ‘MDS1’ and the external disk ‘MDS2.’ The applications Edit, Asm, Link, Exec and RMaker should be on MDS1 and a folder entitled ‘.D Files’ with SysEqu.D, ToolEqu.D, QuickEqu.D, and MacTraps.D inside on MDS2. To make Rose Curves work on a Macintosh 512 with the old ROM, FixMath.Txt and FixMath.Rel must also be in the .D Files folder (The information on where to get these two files is under How Rose Curves Works). FixTraps.Txt and FixTraps.Rel are files which were distributed by Apple Computer under the Apple Software Supplement to aid assembly language programmers in calculating basic arithmetic and trigonometric functions. As the program is presented here, you have everything you need to type the program in and run it on a new ROM machine, since the FixTraps necessary for this program are explicitly defined with the ".TRAPS" statement at the start of the program. The program may also be entered into the new MPW assembler, or assembled with the Consulair C system, which includes the complete MDS assembler built-in.

To create the program, simply assemble the Rose.Asm listing. Then compile the resource file with RMaker. Finally execute the linker on the link file listing and the program object file and resource object file (both ".REL" files) will be linked together, an application generated, and the cute rose application icon should appear on the disk. Double click "Rose Curves" and your in business making fascinating polar coordinate art.

How Rose Curves Works

The program begins by initializing the standard managers, initializing its variables, setting up the menu bar and opening the window. The initialized variables are Equation, Scale, RealScale, Multilayered and drawn. Equation contains the item number of the selected function in the Change Parameters dialog. To obtain the real equation number, subtract 3 from Equation. Scale is the item number of the selected scale or “size” and RealScale is the actual scalar multiplied on each point before drawing it. Multilayered determines whether the rose will be layered. Finally, drawn is a boolean expression which determines whether the window needs to be updated by redrawing the rose (false) or simply by copying the rose from the offscreen bitmap (true). The offscreen bitmap is also created in this routine. To create a bitmap, create an area in memory with space for a pointer, a word and a rectangle. In Rose Curves, this appears at the end of the program under the label windowBitMap. Now select the rectangle of the bitmap and calculate the rowbytes with the equation

       rowbytes = int((xright - xleft)/8+1)

If rowbytes is odd, round it up. Suppose our rectangle is 0, 0, 50, 96 (remember that a QuickDraw rectangle is stored as y1, x1, y2, x2). Then rowbytes would be 14 and the bitmap would look like this:

myBitMapDC.L0  ;pointer to bitmap storage
 DC14 ;rowbytes
 DC0, 0, 50, 96  ;boundsRect

The size of the bitmap storage must be determined before it can be created. Use the equation

 size = rowbytes * (ybottom - ytop)

To create the bitmap, use the following routine.

 move.l #size,D0
 _NewPtr;allocate new pointer
 lea  myBitMap,A1
 move.l A0,(A1)  ;put the pointer to the
 ;storage in myBitMap

To copy a picture from the current window to myBitMap, use this routine

 pea  aPort(A5)  ;storage for the port
 _GetPort ;get the current port
 move.l aPort(A5),A0 ;put the port pointer in A0
 pea  portBits(A0) ;push ptr to port’s bitmap
 pea  myBitMap ;push ptr to our bitMap
 pea  srcRect  ;push srcRect
 pea  dstRect  ;push dstRect
 clr  -(SP) ;srcCopy
 clr.l  -(SP)  ;no mask region
 _CopyBits;copy the bits

Finally, remember to dispose of the bitmap’s storage after finishing with it. This is accomplished simply with

move.l  myBitMap,A0
 _DisposPtr

The EventLoop allows desk accessories to perform their periodic events by calling _SystemTask and, if an event occurs, branches to HandleEvent which transfers execution to the appropriate routine: Activate, Update, KeyDown or MouseDown. The Activate routine activates or deactivates the Rose Curves window depending on what the user requested. Update updates the window by either drawing the curve or using _CopyBits, depending on whether the curve had been drawn previously. KeyDown checks if the command-key was down when the KeyDown event occurred by testing bit eight of the ModifyReg. If bit eight equals one, a command-key was pressed and _MenuKey is called to determine the appropriate menuNumber and itemNumber for Choices, the routine which handles menu selections. MouseDown finds the area the mouse was clicked in using _FindWindow and jumps to the appropriate routine to handle the click.

Several other important routines are SystemEvent, InMenu, UnhiliteMenu, NextEvent InAppleMenu and ParameterChange. SystemEvent passes mouse clicks in system windows to the system for it to handle. InMenu converts a mouse click in the menu bar to the correct menuNumber and itemNumber for Choices. Choices then calls InAppleMenu if the click was in the apple menu, calls ParameterChange if the first item in the Control menu was selected, or quits to the Finder if Quit was selected. UnhiliteMenu unhighlights all menus in the menu bar and NextEvent returns to the EventLoop. InAppleMenu either displays the InfoAlert About Rose Curves... or opens the selected desk accessory using _OpenDeskAccessory. Finally, ParameterChange opens the parameter dialog, hilights the buttons which correspond to the Equation, Scale and Multilayered variables and monitors the user’s actions until the dialog is dismissed with the OK or Cancel button. If OK was selected, ParameterChange updates the variables Equation, Scale, RealScale and Multilayered before closing the dialog and returning to the EventLoop.

The heart of the program lies in the DrawRose subroutine. Before outlining how it operates, an explanation of the fixed-point math routines is needed. Fixed-point math is not as accurate as floating-point math, but much faster. With graphics programs, speed is often much more important than accuracy, especially when there is the possibility of losing the user’s attention. Since Apple elected not to implement the fixed-point routines into the old toolbox, they released the file's FixTraps. Txt and FixMath.Rel in the Apple Software Supplement of May 6, 1985. These files are available from local user groups, bulletin boards, Apple dealerships or directly from Apple. FixTraps.Txt includes a nice description of the “toolbox additions” and FixMath.Rel contains the actual routines. To use the fixed-point routines on a Macintosh with the old ROM, type ‘INCLUDE FixTraps.Txt’ at the beginning of your .Asm file. Also include the line ‘FixTraps’ after the name of the application under development in the .Link file. To use the fixed-point routines on a Macintosh with the new ROM, simply define the trap using .TRAP at the beginning of the ASM file as we did in our listing here. The complete list of new fixed-point traps is as follows:

Long2Fix $A83F

FracSin $A848

FracSqrt $A849

FracMul $A84A

FracDiv $A84B

FixAtan2 $A818

FixDiv $A84D

Fix2Long $A840

Fix2Frac $A841

Frac2Fix $A842

Fix2X $A843

X2Fix $A844

Frac2X $A845

X2Frac $A846

FracCos $A847

The fixed-point routines support three types of numbers: longint (long integer), fixed, and fract (fractional). Type longint represents integers between ±2147483647, type fixed represents fractional quantities between ±32768 with about 5 digits of accuracy and type fract represents fractional quantities between ±2 with about 9 digits of accuracy. Rose Curves uses _FracSin, _FracCos, _FixMul and _FracMul to perform its arithmetic operations. These routines work like any other toolbox trap: space is cleared on the stack for the result, the parameters are pushed on the stack and the trap is called. The Pascal definitions for these routines are

function FracSin( x : Fixed ) : Fract
function FracCos( x : Fixed ) : Fract
function FixMul( x, y : Fixed ) : Fixed
function FracMul( x, y : Fract ) : Fract

With _FixMul and _FracMul it is possible to pass parameters of different types than specified. For example, one could pass x as type longint and y as type fixed to _FixMul and the result would be type longint. The following table contains the result types for multiplying different types using _FixMul and _FracMul.

_FixMul _FracMul

x y result x y result

fixed fixed fixed fract fract fract

longint fixed longint longint fract longint

fixed longint longint fract longint longint

fract fixed fract fixed fract fixed

fixed fract fract fract fixed fixed

Note: To convert a number to type Fract, multiply it by 65536. To convert a number to type Fixed, multiply it by 32768.

DrawRose begins by changing the cursor to a watch, setting the counter to 721 steps (1 + 360° x 1/increment), the increment to 572 (.5° in fixed-point radians) and the present angle to 0. It then loops until the counter is zero, evaluating the current function (bsr EvalFunction), converting the function result to rectangular coordinates and scaling and centering the points. After completing each layer, the program decreases the scale by 20 and redraws the curve if multilayered was selected. After drawing all of the layers, the variable drawn is set to true and the image in the window is copied onto the offscreen bitmap for future update events.

Possible Modifications

Rose Curves could be improved in several ways. The most obvious way would be to add more functions to the program. To accomplish this, add the “function” buttons in the Rose.R file and add the subroutines to evaluate the new functions to Rose.Asm. Note that the displacement to the function must be included in the equation table for the new subroutine to be executed. To do this, add the line DC functionLabel-EquationTable after the line DC Six-EquationTable. As more functions are added, keep adding the labels to the equation table. The second improvement would be to decrease the time required to draw the rose when multilayered is on. To do this, copy the image of the rose into an offscreen bitmap using _CopyBits after the first rose has been drawn. Then shrink CopyBits’ dstRect and copy the rose from the offscreen bitmap onto the screen. Although many times faster, this method greatly reduces the accuracy with which layers are drawn since they are being scaled by _CopyBits, not mathematically graphed. An option to this problem would be to include a checkbox in the Change Parameters dialog titled ‘Accurate Multilayers.’ If selected, Rose Curves would draw the layers using its normal drawing routine. If not, Rose Curves would use the copy-and-shrink method, thus giving the user the choice of accuracy or speed.

;File: Rose.Asm
;---------------------------------------------
;Rose Curves draws curves expressed as a
; function of r and theta.
;Written by Victor Barger on April 2, 1986.
;---------------------------------------------
 INCLUDEMacTraps.D
 INCLUDEQuickEqu.D
 INCLUDEToolEqu.D
;---------------------------------------------
 .trap  _FracMul $A84A  ;New Roms
 .trap  _FracCos $A847
 .trap  _FracSin $A848
;----------------------------------------------
Radians EQU D3
TopButton EQU  D3
BottomButtonEQU  D4
ModifyReg EQU  D4
Increment EQU  D4
MenuReg EQU D5
Counter EQU D5
CheckBoxEQU D6
MenuItemReg EQU  D6
FuncResultEQU  A4

AppleMenuID EQU  1
ControlMenuID  EQU 2

ParamDlgIDEQU  2000
DrawWindIDEQU  2001
InfoAlertID EQU  2002

InitialScaleEQU  13
RealInitScale  EQU 460
;-------------------------------------------------
Start
 bsr  InitManagers ;initialize managers
 bsr  InitVariables;initialize variables
 bsr  SetupMenu  ;setup the menu
 bsr  SetupWindow;draw the window

EventLoop
 _SystemTask;periodic actions for da's
 clr  -(SP)
 move #$0FFF,-(SP)
 pea  EventRecord
 _GetNextEvent   ;get the next event
 move (SP)+,D0
 beq.s  EventLoop;no event, loop back
 bsr  HandleEvent;handle the event
 beq.s  EventLoop;if 0, continue; else quit
 rts

Beep
 move #12,-(SP)
 _SysBeep
 rts
;---------------------------------------------------
InitManagers
 pea  -4(A5)
 _InitGraf
 _InitFonts
 move.l #$0000FFFF,D0
 _FlushEvents
 _InitWindows
 _InitMenus
 clr.l  -(SP)
 _InitDialogs
 _TEInit
 _InitCursor
 rts
;---------------------------------------------------
InitVariables
 move #3,Equation(A5)
 move #InitialScale,Scale(A5)
 move.l #RealInitScale,RealScale(A5)
 clr  Multilayered(A5)  ;not multilayered
 move.l #11520,D0
 _NewPtr;create a new bit map
 lea  windowBitMap,A1
 move.l A0,(A1)  ;remember the pointer
 clr  drawn(A5)  ;not drawn yet
 rts
;-----------------------------------------------------
SetupMenu
 clr.l  -(SP)
 move #AppleMenuID,-(SP)
 _GetRMenu;get the apple menu
 move.l (SP),AppleMenu(A5)
 move.l (SP),-(SP)
 clr  -(SP)
 _InsertMenu;insert the menu in the menu bar
 move.l #'DRVR',-(SP)
 _AddResMenu;add the DA's to the apple menu

 clr.l  -(SP)
 move #ControlMenuID,-(SP)
 _GetRMenu;get the control menu
 clr  -(SP)
 _InsertMenu;insert the menu in the menu bar

 _DrawMenuBar    ;draw the new menu bar
 rts
;------------------------------------------------------
SetupWindow
 clr.l  -(SP)
 move #DrawWindID,-(SP)
 pea  WindowStorage(A5)
 move.l #-1,-(SP)
 _GetNewWindow   ;get the RoseCurves Window
 move.l (SP),DrawPtr(A5)
 _SetPort ;set the new grafport
 rts
;------------------------------------------------------
HandleEvent
 move Modify,ModifyReg
 move What,D0
 add  D0,D0
 move EventTable(D0),D0
 jmp  EventTable(D0)

EventTable
 DCNextEvent-EventTable
 DCMouseDown-EventTable
 DCNextEvent-EventTable
 DCKeyDown-EventTable
 DCNextEvent-EventTable
 DCKeyDown-EventTable
 DCUpdate-EventTable
 DCNextEvent-EventTable
 DCActivate-EventTable
 DCNextEvent-EventTable
 DCNextEvent-EventTable
;-------------------------------------------------------
Activate
 move.l DrawPtr(A5),D0
 cmp.l  Message,D0 ;was it our window?
 bne  NextEvent  ;no, get next event
 btst #0,ModifyReg ;activate?
 beq  NextEvent  ;no, deactivate

SetOurPort
 move.l DrawPtr(A5),-(SP) ;push pointer to draw window
 _SetPort ;set our port
 bra  NextEvent
;-------------------------------------------------------
Update
 move.l Message,D0 ;get the window ptr
 cmp.l  DrawPtr(A5),D0
 bne  NextEvent

 tst  drawn(A5)
 bne.s  copyIt
 move.l DrawPtr(A5),-(SP) ;push window ptr
 _SetPort ;set the port
 move.l DrawPtr(A5),-(SP)
 _BeginUpdate
 move.l DrawPtr(A5),-(SP)
 _EndUpdate
 pea  windowRect
 _EraseRect
 bsr  DrawRose   ;draw the rose
 bra  NextEvent

copyIt
 move.l DrawPtr(A5),-(SP) ;push window ptr
 _SetPort ;set the port
 move.l DrawPtr(A5),-(SP)
 _BeginUpdate
 pea  windowBitMap ;get the rose from the bitMap
 move.l drawPtr(A5),A0
 pea  portBits(A0) ;put the rose in our window
 pea  windowRect ;same rect for src and dest
 pea  windowRect
 clr  -(SP) ;srcCopy
 clr.l  -(SP)    ;no maskRgn
 _CopyBits;copy It
 move.l DrawPtr(A5),-(SP)
 _EndUpdate
 bra  NextEvent
;-----------------------------------------------------
KeyDown
 btst #8,ModifyReg ;is the command key down?
 beq  NextEvent  ;no, exit
 clr.l  -(SP)    ;space for menu and item
 move Message+2,-(SP);get character
 _MenuKey ;see if its a command
 move (SP)+,MenuReg;preserve menu
 move (SP)+,MenuItemReg ;and Menu item
 bra.s  Choices
;------------------------------------------------------
MouseDown
 clr  -(SP) ;space for result
 move.l Point,-(SP);get mouse coordinates
 pea  WWindow    ;push event window
 _FindWindow;find the window
 move (SP)+,D0   ;get region number
 add  D0,D0 ;*2 for index into table
 move WindowTable(D0),D0  ;point to routine offset
 jmp  WindowTable(D0);jump to routine
 
WindowTable
 DCNextEvent-WindowTable  ;in desk (not used)
 DCInMenu-WindowTable;in menu bar
 DCSystemEvent-WindowTable;in system window
 DCNextEvent-WindowTable  ;in content (not used)
 DCNextEvent-WindowTable  ;in drag (not used)
 DCNextEvent-WindowTable  ;in grow (not used)
 DCQuitRoutine-WindowTable;in go away
;-----------------------------------------------------
SystemEvent
 pea  EventRecord;ptr to the event record
 move.l WWindow,-(SP);push window ptr
 _SystemClick    ;let system take care of it
 bra  NextEvent  ;next event
;-------------------------------------------------------
InMenu
 clr.l  -(SP)    ;space for menu choice
 move.l Point,-(SP);mouse at time of event
 _MenuSelect;menu select
 move (SP)+,MenuReg;preserve menu
 move (SP)+,MenuItemReg ;preserve menu item

Choices
 cmp  #2,MenuReg ;was it the control menu?
 bne.s  NotQuit  ;no
 cmp  #2,MenuItemReg ;Quit selected?
 bne.s  NotQuit  ;no, continue
 bsr  UnHiliteMenu ;unhilight the menu bar
QuitRoutine
 move.l DrawPtr(A5),-(SP) ;push ptr to draw window
 _CloseWindow    ;close the window
 move.l windowBitMap,A0
 _DisposPtr ;dispose of the bitmap
 move #-1,D0;say it was Quit
 rts

NotQuit
 cmp  #1,MenuReg ;in apple menu?
 beq.s  InAppleMenu;yes, go do apple menu
 cmp  #2,MenuReg ;in file menu?
 beq  ParameterChange;yes

ChoiceReturn
 bsr  UnHiliteMenu ;unhilight the menu bar
 ;fall through get next event
;---------------------------------------------------------
NextEvent
 moveq  #0,D0    ;say it's not Quit
 rts    ;return to event loop
;--------------------------------------------------------
UnhiliteMenu
 clr  -(SP) ;all menus
 _HiLiteMenu;unhilite every one
 rts
;--------------------------------------------------------
InAppleMenu
 cmp  #1,MenuItemReg
 beq.s  Info

 move.l AppleMenu(A5),-(SP)
 move MenuItemReg,-(SP)
 pea  DeskName
 _GetItem ;get name of the desk accessory
 clr  -(SP)
 pea  DeskName
 _OpenDeskAcc    ;open the desk accessory
 move (SP)+,D0

RestoreOurPort
 bsr  SetOurPort
 bra  ChoiceReturn

Info
 clr  -(SP)
 move #InfoAlertID,-(SP)
 clr.l  -(SP)
 _Alert ;handle the infoAlert
 move (SP)+,D0
 bra  RestoreOurPort
;---------------------------------------------------------
ParameterChange
 clr.l  -(SP)
 move #ParamDlgID,-(SP)
 pea  DStorage
 move.l #-1,-(SP)
 _GetNewDialog   ;get the dialog
 move.l (SP),ParamDlgPtr(A5);preserve the dialogPtr

 _SetPort ;set the port

 move Equation(A5),TopButton;TopButton = current button
 ;highlighted in top section
 move TopButton,D0
 bsr  FindButton ;sub. to return handle
 move.l itemHandle(A5),-(SP)
 move #1,-(SP)
 _SetCtlValue    ;highlight the button
 
 move Scale(A5),BottomButton;BottomButton = current
 ; button in bottom section
 move BottomButton,D0
 bsr  FindButton
 move.l itemHandle(A5),-(SP)
 move #1,-(SP)
 _SetCtlValue    ;highlight the button

 move Multilayered(A5),CheckBox
 move #17,D0
 bsr  FindButton ;get handle to check-box
 move.l itemHandle(A5),-(SP)
 move CheckBox,-(SP)
 _SetCtlValue    ;check or uncheck it

RepeatLoop
 clr.l  -(SP)
 pea  ItemHit
 _ModalDialog    ;modal dialog

 move ItemHit,D1
 cmp  #2,D1 ;was it Cancel?
 beq  Done;yes
 cmp  #1,D1 ;was it OK?
 beq  SetNewParams ;yes
 cmp  #9,D1 ;was it in the bottom set?
 bge.s  BottomSet;yes

 move TopButton,D0
 move D1,TopButton ;set new button number
 bsr  FindButton ;get handle to last button
 move.l itemHandle(A5),-(SP)
 clr  -(SP)
 _SetCtlValue    ;unhighlight last button

 move TopButton,D0
 bsr  FindButton
 move.l itemHandle(A5),-(SP)
 move #1,-(SP)
 _SetCtlValue    ;highlight new button
 bra.s  RepeatLoop

BottomSet
 cmp  #14,D1;in bottom set?
 bge.s  CheckForBox;no

 move BottomButton,D0
 move D1,BottomButton
 bsr  FindButton ;get handle to last button
 move.l itemHandle(A5),-(SP)
 clr  -(SP)
 _SetCtlValue    ;unhighlight last button

 move BottomButton,D0
 bsr  FindButton
 move.l itemHandle(A5),-(SP)
 move #1,-(SP)
 _SetCtlValue    ;highlight new button
 bra  RepeatLoop

CheckForBox
 cmp  #17,D1;click in the check box?
 bne  RepeatLoop
 cmp  #1,CheckBox
 bne.s  NotOne
 move #0,CheckBox
 bra.s  SetCheck

NotOne
 move #1,CheckBox
SetCheck
 move #17,D0
 bsr  FindButton ;get handle to check-box
 move.l itemHandle(A5),-(SP)
 move CheckBox,-(SP)
 _SetCtlValue    ;check or uncheck it
 bra  RepeatLoop

SetNewParams
 clr  drawn(A5)
 move TopButton,Equation(A5);set new equation number
 move BottomButton,Scale(A5);set new scale
 move CheckBox,Multilayered(A5)  ;set multilayered
 move Scale(A5),D0
 sub  #9,D0
 asl.l  #2,D0
 move.l ScaleTable(D0),RealScale(A5) ;look up real scale

Done
 move.l ParamDlgPtr(A5),-(SP)
 _CloseDialog    ;close the dialog
 bra  RestoreOurPort

ScaleTable
 DC.L 140,220,300,380,460
;------------------------------------------------------
FindButton
 move.l ParamDlgPtr(A5),-(SP)
 move D0,-(SP)
 pea  itemType
 pea  itemHandle(A5)
 pea  dispRect
 _GetDItem;get handle to itemnumber in D0
 rts
;-------------------------------------------------------
;to convert a fract number to type fract, multipy by 65536
DrawRose
 clr.l  -(SP)
 move #4,-(SP)
 _GetCursor ;get the watch cursor (ID=4)
 move.l (SP)+,D0
 move.l D0,A0
 move.l (A0),-(SP)
 _SetCursor ;set the new cursor

 move.l RealScale(A5),-(SP) ;preserve the realScale
DrawRose1
 move #720,Counter ;721 steps (360 x 2)
 move.l #572,Increment    ;572 = .5° increment in radians
 ;(.5Π/180)*65536
 moveq  #0,Radians ;present degrees

nextDegree
 bsr  EvalFunction ;evaluate fn r(Radians)

 sub  #14,SP
 move.l Radians,-(SP)
 _FracSin
 move.l FuncResult,-(SP)
 _FracMul ;y = fn r(Radians) * sin(Radians)
 move.l RealScale(A5),-(SP)
 _FixMul;y = y * realScale
 _HiWord
 move (SP)+,y(A5);y = int(y)

 sub  #14,SP
 move.l Radians,-(SP)
 _FracCos
 move.l FuncResult,-(SP)
 _FracMul ;x = fn r(Radians) * cos(Radians)
 move.l RealScale(A5),-(SP)
 _FixMul;x = x * realScale
 _HiWord
 move (SP)+,x(A5);x = int(x)

 move x(A5),D0
 add  #154,D0
 move D0,-(SP)   ;x = x + 154

 move y(A5),D0
 add  #144,D0
 move D0,-(SP)   ;y = y + 144

 tst  Radians
 bne.s  NotFirst
 _MoveTo;moveto x,y if first point
 bra.s  Skip

NotFirst
 _LineTo;else lineto x,y
Skip
 add.l  Increment,Radians ;Radians = Radians + Increment
 dbra Counter,nextDegree  ;loop back
 cmp  #1,Multilayered(A5) ;another layer?
 bne.s  NoExtraLayers;no
 move.l #20,D0
 sub.l  D0,RealScale(A5)  ;decrease the real scale by 20
 cmp.l  RealScale(A5),D0  ;is the real scale = 20?
 bne  DrawRose1  ;no, do next layer

NoExtraLayers
 move #1,drawn(A5) ;the rose has been drawn
 move.l drawPtr(A5),A0
 pea  portBits(A0) ;put the rose in our window
 pea  windowBitMap ;get from offscreen bitmap
 pea  windowRect ;same size windowRect
 pea  windowRect
 clr  -(SP) ;srcCopy
 clr.l  -(SP)    ;no mask region
 _CopyBits;copy the bits
 move.l (SP)+,RealScale(A5)
 _InitCursor
 rts
;----------------------------------------------------
EvalFunction
 move Equation(A5),D0
 sub  #3,D0
 add  D0,D0
 move EquationTable(D0),D0
 jmp  EquationTable(D0)

EquationTable
 DCOne-EquationTable ;sin 4r
 DCTwo-EquationTable ;cos (2 sin r)
 DCThree-EquationTable  ;cos (2 sin 2r)
 DCFour-EquationTable;cos (sin 100r)
 DCFive-EquationTable;cos (sin 8 r)
 DCSix-EquationTable ;cos (4 sin 2r)
;-------------------------------------------------------
None
 move.l #0,FuncResult
 rts
;-------------------------------------------------------
One
 ;sin 4r
 clr.l  -(SP)
 move.l Radians,D0
 asl.l  #2,D0
 move.l D0,-(SP)
 _FracSin
 move.l (SP)+,FuncResult ;fn r(Radians) = sin (Radians * 4)
 rts
;-------------------------------------------------------
Two
 ;cos (2 sin r)
 subq #8,SP
 move.l Radians,-(SP)
 _FracSin
 move.l (SP),D0
 asr.l  #7,D0
 asr.l  #6,D0    ;convert to fixed x 2
 move.l D0,(SP)
 _FracCos
 move.l (SP)+,FuncResult  ;fn r(Radians) = cos (2 sin r)
 rts
;--------------------------------------------------------
Three
 ;cos (2 sin 2r)
 subq #8,SP
 move.l Radians,D0
 asl.l  #1,D0
 move.l D0,-(SP)
 _FracSin
 move.l (SP),D0
 asr.l  #7,D0
 asr.l  #6,D0    ;convert to fixed x 2
 move.l D0,(SP)
 _FracCos
 move.l (SP)+,FuncResult  ;fn r(Radians) = cos (2 sin 2r)
 rts
;-------------------------------------------------------
Four
 ;cos (sin 100r)
 sub  #12,SP
 move.l Radians,-(SP)
 move.l #3276800,-(SP)
 _FixMul
 _FracSin
 move.l (SP),D0
 asr.l  #7,D0
 asr.l  #7,D0    ;convert to fixed
 move.l D0,(SP)
 _FracCos
 move.l (SP)+,FuncResult  ;fn r(Radians) = cos (sin 100r)
 rts
;--------------------------------------------------------
Five
 ;cos (sin 8 r)
 subq #8,SP
 move.l Radians,D0
 asl.l  #3,D0
 move.l D0,-(SP)
 _FracSin
 move.l (SP),D0
 asr.l  #7,D0
 asr.l  #7,D0
 move.l D0,(SP)
 _FracCos
 move.l (SP)+,FuncResult  ;fn r(Radians) = cos (sin 8r)
 rts
;---------------------------------------------------------
Six
 ;cos (4 sin 2r)
 subq #8,SP
 move.l Radians,D0
 asl.l  #1,D0
 move.l D0,-(SP)
 _FracSin
 move.l (SP),D0
 asr.l  #7,D0
 asr.l  #5,D0
 move.l D0,(SP)
 _FracCos
 move.l (SP)+,FuncResult  ;fn r(Radians) = cos (4 sin 2r)
 rts
;------------------ Local Variables -----------------
EventRecord
 What:  DC0
 Message: DC.L 0
 When:  DC.L0
 Point: DC.L0
 Modify:DC0
 WWindow: DC.L 0

windowRectDC0,0,288,308
windowBitMapDC.L 0
 DC40
 DC0,0,288,308

ItemHit DC0
itemTypeDC0
dispRectDC0,0,0,0
DStorageDCB DWindLen,0
DeskNameDCB 16,0
;-------------- Application Globals ----------------
WindowStorage  DSWindowSize ;storage for draw window
DrawPtr DS.L1    ;pointer to draw window
AppleMenu DS.L 1 ;apple menu
EquationDS1 ;equation number
Scale   DS1 ;scale
RealScale DS.L 1 ;longint real scale
MultiLayeredDS 1 ;multilayered (0 = false, 1 = true)
ParamDlgPtr DS.L 1 ;pointer to the parameter dialog
itemHandleDS.L 1 ;itemHandle
yDS1    ;y-value
xDS1    ;x-value
drawn   DS1
;--------------------------------------------------------
 END
 

Community Search:
MacTech Search:

Software Updates via MacUpdate

EtreCheck Pro 6.0.2 - For troubleshootin...
EtreCheck is an app that displays the important details of your system configuration and allow you to copy that information to the Clipboard. It is meant to be used with Apple Support Communities to... Read more
BitTorrent 7.4.3 - Official client of th...
BitTorrent is a protocol for distributing files. It identifies content by URL and is designed to integrate seamlessly with the web. Its advantage over plain HTTP is that when multiple downloads of... Read more
Adobe Premiere Pro CC 2019 13.1.3 - Digi...
Premiere Pro CC 2019 is available as part of Adobe Creative Cloud for as little as $52.99/month. The price on display is a price for annual by-monthly plan for Adobe Premiere Pro only Adobe Premiere... Read more
ffWorks 1.3.1 - Convert multimedia files...
ffWorks, focused on simplicity, brings a fresh approach to the use of FFmpeg, allowing you to create ultra-high-quality movies without the need to write a single line of code on the command-line.... Read more
BetterTouchTool 3.134 - Customize multi-...
BetterTouchTool adds many new, fully customizable gestures to the Magic Mouse, Multi-Touch MacBook trackpad, and Magic Trackpad. These gestures are customizable: Magic Mouse: Pinch in / out (zoom)... Read more
TextMate 2.0.rc.28 - Code/markup editor...
TextMate is a versatile plain text editor with a unique and innovative feature set which caused it to win an Apple Design Award for Best Mac OS X Developer Tool in August 2006 A rapidly growing... Read more
BetterTouchTool 3.132 - Customize multi-...
BetterTouchTool adds many new, fully customizable gestures to the Magic Mouse, Multi-Touch MacBook trackpad, and Magic Trackpad. These gestures are customizable: Magic Mouse: Pinch in / out (zoom)... Read more
calibre 3.45.2 - Complete e-book library...
Calibre is a complete e-book library manager. Organize your collection, convert your books to multiple formats, and sync with all of your devices. Let Calibre be your multi-tasking digital librarian... Read more
calibre 3.45.2 - Complete e-book library...
Calibre is a complete e-book library manager. Organize your collection, convert your books to multiple formats, and sync with all of your devices. Let Calibre be your multi-tasking digital librarian... Read more
BetterTouchTool 3.132 - Customize multi-...
BetterTouchTool adds many new, fully customizable gestures to the Magic Mouse, Multi-Touch MacBook trackpad, and Magic Trackpad. These gestures are customizable: Magic Mouse: Pinch in / out (zoom)... Read more

Latest Forum Discussions

See All

TEPPEN guide - Tips and tricks for new p...
TEPPEN is a wild game that nobody asked for, but I’m sure glad it exists. Who would’ve thought that a CCG featuring Capcom characters could be so cool and weird? In case you’re not completely sure what TEPPEN is, make sure to check out our review... | Read more »
Dr. Mario World guide - Other games that...
We now live in a post-Dr. Mario World world, and I gotta say, things don’t feel too different. Nintendo continues to squirt out bad games on phones, causing all but the most stalwart fans of mobile games to question why they even bother... | Read more »
Strategy RPG Brown Dust introduces its b...
Epic turn-based RPG Brown Dust is set to turn 500 days old next week, and to celebrate, Neowiz has just unveiled its biggest and most exciting update yet, offering a host of new rewards, increased gacha rates, and a brand new feature that will... | Read more »
Dr. Mario World is yet another disappoin...
As soon as I booted up Dr. Mario World, I knew I wasn’t going to have fun with it. Nintendo’s record on phones thus far has been pretty spotty, with things trending downward as of late. [Read more] | Read more »
Retro Space Shooter P.3 is now available...
Shoot-em-ups tend to be a dime a dozen on the App Store, but every so often you come across one gem that aims to shake up the genre in a unique way. Developer Devjgame’s P.3 is the latest game seeking to do so this, working as a love letter to the... | Read more »
Void Tyrant guide - Guildins guide
I’ve still been putting a lot of time into Void Tyrant since it officially released last week, and it’s surprising how much stuff there is to uncover in such a simple-looking game. Just toray, I finished spending my Guildins on all available... | Read more »
Tactical RPG Brown Dust celebrates the s...
Neowiz is set to celebrate the summer by launching a 2-month long festival in its smash-hit RPG Brown Dust. The event kicks off today, and it’s divided into 4 parts, each of which will last two weeks. Brown Dust is all about collecting, upgrading,... | Read more »
Flappy Royale is an incredibly clever ta...
I spent the better part of my weekend playing Flappy Royale. I didn’t necessarily want to. I just felt like I had to. It’s a hypnotic experience that’s way too easy to just keep playing. | Read more »
Void Tyrant guide - General tips and tri...
Void Tyrant is a card-based dungeon-crawler that doesn’t fit in the mold of other games in the genre. Between the Blackjack-style combat and strange gear system alone, you’re left to your own devices to figure out how best to use everything to your... | Read more »
Webzen’s latest RPG First Hero is offici...
You might be busy sending your hulking Dark Knight into the midst of battle in Webzen’s other recent release: the long-anticipated MU Origin 2. But for something a little different, the South Korean publisher has launched First Hero. Released today... | Read more »

Price Scanner via MacPrices.net

Price drop! Clearance 12″ 1.2GHz Silver MacBo...
Amazon has dropped their price on the recently-discontinued 12″ 1.2GHz Silver MacBook to $849.99 shipped. That’s $450 off Apple’s original MSRP for this model, and it’s the cheapest price available... Read more
Apple’s 21″ 3.0GHz 4K iMac drops to only $936...
Abt Electronics has dropped their price on clearance, previous-generation 21″ 3.0GHz 4K iMacs to only $936 shipped. That’s $363 off Apple’s original MSRP, and it’s the cheapest price we’ve seen so... Read more
Amazon’s Prime Day savings on Apple 11″ iPad...
Amazon has new 2018 Apple 11″ iPad Pros in stock today and on sale for up to $250 off Apple’s MSRP as part of their Prime Day sale (but Prime membership is NOT required for these savings). These are... Read more
Prime Day Apple iPhone deal: $100 off all iPh...
Boost Mobile is offering Apple’s new 2018 iPhone Xr, iPhone Xs, and Xs Max for $100 off MSRP. Their discount reduces the cost of an Xs to $899 for the 64GB models and $999 for the 64GB Xs Max. Price... Read more
Clearance 13″ 2.3GHz Dual-Core MacBook Pros a...
Focus Camera has clearance 2017 13″ 2.3GHz/128GB non-Touch Bar Dual-Core MacBook Pros on sale for $169 off Apple’s original MSRP. Shipping is free. Focus charges sales tax for NY & NJ residents... Read more
Amazon Prime Day deal: 9.7″ Apple iPads for $...
Amazon is offering new 9.7″ WiFi iPads with Apple Pencil support for $80-$100 off MSRP as part of their Prime Day sale, starting at only $249. These are the same iPads found in Apple’s retail and... Read more
Amazon Prime Day deal: 10% (up to $20) off Ap...
Amazon is offering discounts on new 2019 Apple AirPods ranging up to $20 (10%) off MSRP as part of their Prime Day sales. Shipping is free: – AirPods with Charging Case: $144.99 $15 off MSRP –... Read more
Amazon Prime Day deal: $50-$80 off Apple Watc...
Amazon has Apple Watch Series 4 and Series 3 models on sale for $50-$80 off Apple’s MSRP as part of their Prime Day deals with prices starting at only $199. Choose Amazon as the seller rather than a... Read more
Amazon Prime Day deal: 50% discount on Apple...
Amazon has Apple Smart Keyboards for current-generation 10″ iPad Airs and previous-generation 10″ iPad Pros on sale today for $79.50 shipped as part of their early Prime Day deals. That’s a 50%... Read more
Abt drops prices on clearance 2018 MacBook Ai...
Abt Electronics has dropped prices on clearance 2018 13″ MacBook Airs by $201 with models now available starting at only $998. Shipping is free: – 13″ 1.6GHz/128GB MacBook Air (Space Gray, Silver, or... Read more

Jobs Board

*Apple* Graders/Inspectors (Seasonal/Hourly/...
…requirements. #COVAentryleveljobs ## Minimum Qualifications Some knowledge of agricultural and/or the apple industry is helpful as well as the ability to comprehend, Read more
Best Buy *Apple* Computing Master - Best Bu...
**710003BR** **Job Title:** Best Buy Apple Computing Master **Job Category:** Store Associates **Location Number:** 000171-Winchester Road-Store **Job Description:** Read more
Best Buy *Apple* Computing Master - Best Bu...
**709786BR** **Job Title:** Best Buy Apple Computing Master **Job Category:** Sales **Location Number:** 000430-Orange Park-Store **Job Description:** **What does a Read more
Geek Squad *Apple* Master Consultation Agen...
**709918BR** **Job Title:** Geek Squad Apple Master Consultation Agent **Job Category:** Services/Installation/Repair **Location Number:** 000106-Palmdale-Store Read more
*Apple* Systems Architect/Engineer, Vice Pre...
…its vision to be the world's most trusted financial group. **Summary:** Apple Systems Architect/Engineer with strong knowledge of products and services related to Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.