antoine-source/appleworksgs/SS/Src/Pie.aii
2023-03-04 03:45:20 +01:00

1 line
12 KiB
Plaintext
Executable File

LOAD 'Macros.dump'
INCLUDE 'SS.equ'
INCLUDE 'Driver.equ'
INCLUDE 'Heap.aii.i'
;------------------------------------------
;
; Equates from procedure S_PieData
;
;------------------------------------------
S_MaxPieCount equ 24
S_PieColWd equ 180
;-----------------------------------------------
;
; Imported addresses
;
;-----------------------------------------------
IMPORT D_ClosePicture
IMPORT D_AlertBox
IMPORT D_CheckPurge
IMPORT D_Deref
IMPORT D_DrawString
IMPORT D_FastMult
IMPORT D_KillFont
IMPORT D_NeedHand
IMPORT D_SelectFont
IMPORT D_Set4Pat
IMPORT X_FormatValue
IMPORT S_ChartTitleLoc
IMPORT S_MissingSlice
IMPORT S_SliceStr
IMPORT S_BadNum
IMPORT S_BigPie
IMPORT S_ChartColors
IMPORT S_Cur2Heap
IMPORT S_GetCellPtr
IMPORT S_ItzaBar
IMPORT S_NoData
IMPORT S_NormalizeRange
IMPORT S_PictRect
IMPORT S_PieRect
IMPORT S_TraverseRange
IMPORT S_GetMinMax
IMPORT S_NoINF
;-----------------------------------------------
;
; Forward addresses and entries
;
;-----------------------------------------------
ENTRY AngleToPt
ENTRY S_Pie360
ENTRY S_PieArray
ENTRY S_PieDiv
ENTRY S_PieLegend
ENTRY S_PieNegFlag
ENTRY S_PieOffset
ENTRY S_PieOne
ENTRY S_PiePict
ENTRY S_PieSliceCount
ENTRY S_PieSum
ENTRY S_PieTotal
ENTRY S_PieTwo
ENTRY S_PieZero
ENTRY S_SlicePie
;---------------------------------------------------------------------------
;
; S_MakePie
;
;
S_MakePie PROC EXPORT
;Using S_CurrentData2
;Using S_ChartData
;Using S_PieData
;Using SANEEQUS
input charthdl:l
output pict:l
local arrayhdl:l,chart:l
local color:w,OldClip:l
local col:w,items:l
local tmp:l,topl:l,botr:l
error err
begin
stz err
H_GetBlockPtr charthdl,chart
call S_NormalizeRange,in=([chart]:#S_CRange:l,[chart]:#S_CRange+4:l)
pulllong botr
pulllong topl
call S_GetMinMax,in=(topl:l,botr:l,#1:w),out=(:l)
tool FCLASSX,in=(:l)
txa
asl a
cmp #2*FCINF
beq @INF
call S_GetMinMax,in=(topl:l,botr:l,#0:w),out=(:l)
tool FCLASSX,in=(:l)
txa
asl a
cmp #2*FCINF
bne @dopie
@INF call D_AlertBox,in=(#1:w,#S_NoINF:l),out=(a:w)
dec err
brl exit
@dopie
subword botr,topl,a
ina
sta tmp
subword botr+2,topl+2,a
ina
sta tmp+2
tool _Multiply,in=(tmp:w,tmp+2:w),out=(items:l)
movelong items,tmp
mull4 tmp
tool _NewRgn,out=(OldClip:l),err=(err)
jcs exit
tool _GetClip,in=(OldClip:l)
tool _ClipRect,in=(#S_PictRect:l)
call D_NeedHand,in=(tmp:l),out=(arrayhdl:l),err=(err)
jcs whoops2
rcall D_Deref,in=(arrayhdl:ax),out=(S_PieArray:ax)
moveX S_PieZero,S_PieTotal
stz S_PieOffset
stz S_PieNegFlag
call S_TraverseRange,in=(topl:l,botr:l,#S_PieSum:l),err=(err)
jcs whoops
lda S_PieOffset
beq @nodata
tool FCMPX,in=(#S_PieTotal:l,#S_PieZero:l) ; any real data?
bvs OpenIt
@nodata call D_AlertBox,in=(#1:w,#S_NoData:l),out=(a:w)
dec err
brl whoops
OpenIt cmpw S_PieOffset,#S_MaxPieCount+1
blt ReallyOpen
call D_AlertBox,in=(#1:w,#S_BigPie:l),out=(a:w)
dec err
brl whoops
ReallyOpen tool _OpenPicture,in=(#S_Pictrect:l),out=(pict:l)
movelong pict,S_PiePict
moveword S_PieOffset,S_PieSliceCount
stz S_PieOffset
stz S_MissingSlice
tool _PicComment,in=(#picLParen:w,#0:w,#0:l)
call S_TraverseRange,in=(topl:l,botr:l,#S_PieDiv:l)
tool _PicComment,in=(#picRParen:w,#0:w,#0:l)
call S_SlicePie,in=(S_PieOffset:w,S_PieArray:l)
; Draw the title, at the bottom...
tool _MoveTo,in=(S_ChartTitleLoc:l)
_PenNormal ; necess. for #'s in case of 0's ==> no colour
jsl D_KillFont
rcall D_SelectFont,in=(#$FFFE:a,#$0800:x,#0:y)
H_GetBlockPtr charthdl,chart
addlong chart,#S_CName,s
Call D_DrawString,in=(:l)
jsl D_ClosePicture
bcs @picErr
call D_CheckPurge
bcs KillIt
lda S_MissingSlice
beq Done
call D_AlertBox,in=(#1:w,#S_SliceStr:l),out=(a:w)
bra exit
@picErr
KillIt tool _KillPicture,in=(pict:l)
call D_CheckPurge
dec err
; cmpl items,#25
; blt Done
Done _PenNormal
whoops tool _DisposeHandle,in=(arrayhdl:l)
whoops2 tool _SetClip,in=(OldClip:l)
tool _DisposeRgn,in=(OldClip:l)
exit return
ENDP
;---------------------------------------------------------------------------
;
; S_PieSum
;
; check cell for negative value, RETURN error if found.
; add value to S_PieTotal
S_PieSum PROC EXPORT
;Using SANEEQUS
;Using S_PieData
;Using S_ChartData
;Using S_CurrentData2
input cell:l
local ptr:l,cellptr:l
error err
BEGIN +b
stz err
call S_GetCellPtr,in=(Cell:l),out=(CellPtr:l)
ora CellPtr
jeq Exit
addlong cellptr,#S_CellFormat,ptr
lda [ptr]
and #S_CellTypeValue
cmp #S_CellTypeText
beq Exit
AddLong cellptr,#S_CellValue,ptr
lda S_ItzaBar
bne ThatsAll
tool FCMPX,in=(ptr:l,#S_PieZero:l)
bpl Positive
lda S_PieNegFlag
bne DidFlag
dec S_PieNegFlag
DidFlag lda S_PieNegFlag
bmi DoAdd
bozo call D_AlertBox,in=(#1:w,#S_BadNum:l),out=(a:w)
dec err
bra exit
Positive lda S_PieNegFlag
bne DidNegFlag2
inc S_PieNegFlag
DidNegFlag2 lda S_PieNegFlag
bmi bozo
DoAdd tool FADDX,in=(ptr:l,#S_PieTotal:l)
ThatsAll inc S_PieOffset
exit RETURN
ENDP
;---------------------------------------------------------------------------
;
; S_PieDiv
;
; calculate size of each slice.
S_PieDiv PROC EXPORT
;Using S_ChartData
;Using S_PieData
;Using SANEEQUS
;Using S_CurrentData2
input cell:l
local p1:w,percent:r,a1:w,angle:r
local cellptr:l
local ptr:l,tmp:l,color:w,count:w,skip:w
error err
BEGIN +b
stz err
call S_GetCellPtr,in=(Cell:l),out=(CellPtr:l)
ora CellPtr
jeq Exit
AddLong cellptr,#S_CellValue,cellptr
moveX [cellptr],percent
tool FCMPX,in=(#S_PieTotal:l,#S_PieZero:l)
bne DoDiv
moveX S_PieOne,percent
bra DidDiv
DoDiv tool FDIVX,in=(#S_PieTotal:l,!percent:l)
DidDiv moveX percent,angle
lda S_PieOffset
asl a
addlong a,S_PieArray,ptr
tool FMULX,in=(#S_Pie360:l,!angle:l)
tool FX2I,in=(!angle:l,!tmp:l)
moveword tmp,[ptr]
beq NoColor
stz skip
moveword S_PieOffset,color
bra DoLegend
NoColor inc skip
inc S_MissingSlice
DoLegend call S_PieLegend,in=(S_PieOffset:w,!percent:l,cellptr:l,skip:w)
inc S_PieOffset
exit RETURN
ENDP
;---------------------------------------------------------------------------
;
; S_PieLegend
;
; Draw a single legend.
; ^^^^^^
; Rect of color, percentage, value.
S_PieLegend PROC EXPORT
;Using S_ChartData
;Using S_PieData
input entry:w,percent:l,value:l,skip:w
local offset:w,tmprect:r,string:l,col:w,colors:l
local inccolor:w,ptr:l,drawcolor:w
BEGIN
stz inccolor
lda S_PieSliceCount
dec a
cmp entry
bne ContLegend
cmp #0
beq ContLegend
inc inccolor
ContLegend movelong #S_ChartColors,colors
tool _UDivide,in=(entry:w,#12:w),out=(entry:w,col:w)
rcall D_FastMult,in=(entry:x,#13:y),out=(tmprect:a)
rcall D_FastMult,in=(#S_PieColWd:x,col:y),out=(col:a)
addword col,#S_PieLegendH,tmprect+2
addword tmprect,#8,tmprect+4
addword col,#S_PieLegendH+16,tmprect+6
tool _PicComment,in=(#picLParen:w,#0:w,#0:l)
lda skip
bne Didcolor
lda entry
asl a
tay
bne Do4Pat
lda inccolor
asl a ; 0 = blue, 2= red...
asl a
tay
Do4Pat call D_Set4Pat,in=([colors]:y:w)
tool _PaintRect,in=(!tmprect:l)
_PenNormal
tool _SetPenSize,in=(#2:w,#1:w)
tool _FrameRect,in=(!tmprect:l)
DidColor
moveword tmprect+4,tmprect
addword col,#S_PieLegendH+24,a
tool _MoveTo,in=(a:w,tmprect:w)
_PenNormal ; necess. for #'s in case of 0's ==> no colour
jsl D_KillFont
rcall D_SelectFont,in=(#$FFFE:a,#$0800:x,#0:y)
in #60:w,#$11000:l,percent:l
out a:w,string:l,a:w
xcall X_FormatValue
Call D_DrawString,in=(string:l)
addword col,#S_PieLegendH+80,a
tool _MoveTo,in=(a:w,tmprect:w)
sublong value,#S_CellValue-S_CellFormat,ptr
in #80:w,[ptr]:l,value:l
out a:w,string:l,drawcolor:w
xcall X_FormatValue
lda DrawColor
pha
xba
ora 1,s
sta 1,s
asl a
asl a
asl a
asl a
ora 1,s
sta 1,s
_SetForeColor
Call D_DrawString,in=(string:l)
tool _PicComment,in=(#picRParen:w,#0:w,#0:l)
RETURN
ENDP
;---------------------------------------------------------------------------
;
; S_SlicePie (count,array)
; count:w Number of slices. 1-15, inclusive
; array:l array[count] of angles for slicing.
;
; Routine to actually draw pie. Assumes PICT has already been
; opened or whatever offsets necessary have been made.
;
; Pie is drawn as the circle inscribed in the rect [0,0,150,300]
;
S_SlicePie PROC EXPORT
;Using S_ChartData
;Using S_PieData
input count:w,array:l
local color:w,arc:w,tmp:l,colortab:l
local offset:w,comment:w,single:w
BEGIN
lda count
jeq exit
sta single
stz comment
stz color
stz offset
stz arc
movelong #S_ChartColors,colortab
loop lda color
asl a
tay
call D_Set4Pat,in=([colortab]:y:w)
lda offset
asl a
tay
moveword [array]:y,tmp
jeq DidArc
cmpw single,#1 ; in case of 1 item, full circle.
beq DoPaint
cmpw count,#1
bne DoComment
subword #360,arc,tmp ; subvert round-off errors on last slice.
DoComment tool _PicComment,in=(#picLParen:w,#0:w,#0:l) ; Avoid grouping
inc comment ; single objects.
DoPaint tool _PaintArc,in=(#S_PieRect:l,arc:w,tmp:w)
_PenNormal
tool _SetPenSize,in=(#2:w,#1:w)
tool _FrameArc,in=(#S_PieRect:l,arc:w,tmp:w)
subword tmp,arc,a
cmp #360 ; no slices -- one pie.
beq DidArc
call AngleToPt,in=(arc:w),out=(a:w,x:w)
pha
phx
_MoveTo
tool _LineTo,in=(#S_PieHCtr:w,#S_PieVCtr:w)
addword arc,tmp,arc
call AngleToPt,in=(arc:w),out=(a:w,x:w)
pha
phx
_MoveTo
tool _LineTo,in=(#S_PieHCtr:w,#S_PieVCtr:w)
lda comment
beq DidArc
tool _PicComment,in=(#picRParen:w,#0:w,#0:l)
stz comment
DidArc lda color
inc a
cmp #12
bne ContColor
lda count
dec a
dec a ; Last color.
bne OKFirst
lda #2 ; Red
bra ContColor
OKFirst lda #0
ContColor sta color
inc offset
dec count
jne loop
exit RETURN
ENDP
****************************************************************
*
* AngleToPt - take a reference rect and an angle to a point.
*
* Notes: The point RETURNed lies on the ellipse inscribed in the
* rectangle.
*
*
****************************************************************
AngleToPt PROC EXPORT
;Using SANEEQUS
;Using S_PieData
;Using S_ChartData
input angle:w ; angle
output point:l ; point (value)
local tmp:l
BEGIN
lda angle
Loop360 cmp #360
blt Did360
subword a,#360,a
bra Loop360
Did360 sta angle
; Convert deg->rad
; y = (-cos(a)+1) ; 1/2 ; (rect_bot - rect_top) + rect_top
; x = (sin(a)+1) ; 1/2 ; (rect_right - rect_left) + rect_left
tool FI2X,in=(!angle:l,#FlP1:l)
tool FMULX,in=(#PI:l,#FlP1:l)
tool FMULX,in=(#S_PieTwo:l,#FlP1:l)
moveX S_Pie360,FlP3
tool FDIVX,in=(#FlP3:l,#FlP1:l)
moveX FlP1,Flp2
tool FCOSX,in=(#FlP1:l)
tool FSINX,in=(#FlP2:l)
moveX FlP1,FlP3
moveX S_PieOne,FlP1
tool FSUBX,in=(#FlP3:l,#FlP1:l)
tool FADDX,in=(#S_PieOne:l,#FlP2:l)
subword S_PieRect+4,#1,tmp
tool FI2X,in=(!tmp:l,#FlP3:l)
tool FMULX,in=(#FlP3:l,#FlP1:l)
moveX S_PieTwo,FlP3
tool FDIVX,in=(#FlP3:l,#FlP1:l)
tool FX2I,in=(#FlP1:l,!point:l)
subword S_PieRect+6,#1,tmp
tool FI2X,in=(!tmp:l,#FlP3:l)
tool FMULX,in=(#FlP3:l,#FlP2:l)
moveX S_PieTwo,FlP3
tool FDIVX,in=(#FlP3:l,#FlP2:l)
tool FX2I,in=(#FlP2:l,!point+2:l)
RETURN
PI DC.X "3.14159265358979323846264338327950288419716939937511"
FlP1 DS.B 10
FlP2 DS.B 10
FlP3 DS.B 10
ENDP
;--------------------------------------------
Fix2Int PROC EXPORT
tay
bpl exit
inx
exit txa
rtl
ENDP
;--------------------------------------------
;
; S_PieData
;
S_PieData PROC EXPORT
EXPORT S_PieNegFlag
EXPORT S_PiePict
EXPORT S_PieOffset
EXPORT S_PieSliceCount
EXPORT S_PieArray
EXPORT S_PieTotal
EXPORT S_PieZero
EXPORT S_Pie360
EXPORT S_PieTwo
EXPORT S_PieOne
S_PieNegFlag DS.W 1
S_PiePict DS.L 1
S_PieOffset DS.W 1
S_PieSliceCount DS.W 1
S_PieArray DS.L 1
S_PieTotal DS.B 10
S_PieZero DC.X "0.0"
S_Pie360 DC.X "360.0"
S_PieTwo DC.X "2.0"
S_PieOne DC.X "1.0"
ENDP
END