home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
database
/
dscalc.zip
/
DSCALC.SC
next >
Wrap
Text File
|
1990-01-23
|
180KB
|
5,301 lines
;-- library creation, errorchecking, messaging routine
if version() < 3 then
message "Sorry, version 3 or higher of Paradox required for DSCalc."
for x from 1 to 5
beep
sleep 250
endfor
return false
endif
if version() > 3 then
beep beep
style reverse
clear
@ 00,00 ?? format("w80,al",
"Warning! Creating the DSCalc library under" +
" a Version greater than 3 of Paradox ")
@ 01,00 ?? format("w80,al",
"will not allow you to run the calculator i" +
"n version 3 of Paradox.")
@ 02,00 ?? format("w80,al",
"Creating the library under version 3 will " +
"allow you to use the calculator with")
@ 03,00 ?? format("w80,al",
"a version greater than 3 of Paradox however.")
@ 04,00 ?? format("w80,al",
"Press [F2] to continue, any other key to cancel creating the library.")
key.pressed.s = getchar()
if key.pressed.s <> -60 then
message "Creating of the library has been canceled!"
for x from 1 to 5
beep
sleep 250
endfor
sleep 2500
return false
endif
endif
? "Creating the DSCalc Library."
if not isassigned(ds.aplib.a) or
not isdirname(ds.aplib.a) then
ds.aplib.a = "dscalc"
endif
createlib ds.aplib.a size 65
;-------------------------------------------------------------------------------
; ds.calc.v()
;-------------------------------------------------------------------------------
; purpose: main level procedure for displaying and operating this application
proc closed ds.calc.v(
ds.aplib.a, ;-- the library name for autolib
ds.tape.length.s, ;-- number of entries allowed in the tape
ds.set.swap.n, ;-- the setswap value
ds.save.memory.l, ;-- logical flag to save memory arrays
ds.custom.lib.a, ;-- name of custom library
ds.print.tape.a) ;-- "ON" or "OFF to allow/disallow printing
private
ds.neg.key.a, ;-- alpha string ala DETK to determine whether
;-- to accept or reject keys pressed by the user
ds.pos.key.a, ;-- neg.key to process negative ascii values
;-- pos.key to process positive ascii values
ds.char.s, ;-- ascii value assigned with getchar()
ds.char.was.v, ;-- the previous key pressed. it may also
;-- hold the value "No" if the previous key
;-- need not be determined
ds.key.type.a, ;-- value extracted from ds.neg.key.a or
;-- ds.pos.key.a based on the value in ds.char.s
autolib, ;-- allows declaration of a private autolib
ds.tape.count.s, ;-- array element number for ds.tape.r,
;-- ds.tape.function.r, ds.decimal.r and
;-- ds.total.was.r arrays
ds.tape.r, ;-- array of tape entries
ds.tape.function.r, ;-- sign array associated with ds.tape.r
;-- "-", "+", "/", "*" or "="
ds.memory.r, ;-- memory array
ds.decimal.r, ;-- logical storage array to determine
;-- format of the value stored in ds.tape.r
ds.total.was.r, ;-- array of sub totals created
ds.total.element.num.was.s, ;-- remembers the last array element that
;-- stores a value in the ds.total.was.r array
ds.memory.element.r, ;-- a listing of array elements for ds.memory.r
ds.rebuild.l, ;-- logical flag determines when the calculator
;-- need to be re-displayed on the screen
ds.loop.counter.s, ;-- a general loop counter
ds.press.it.a ;-- saves from having to type
;-- "Press any key to continue." a few hundred
;-- times
;-- define the private autolib for this application
autolib = ds.aplib.a
;-- set this global variable
ds.press.it.a = "Press any key to continue."
;-- set up arrays, global variables, etc.
ds.set.vars.u("all")
;-- setup the setswap value
setswap ds.set.swap.n
;-- define the memory arrays from a previous session when ds.save.memory.l
;-- is set to true
if ds.save.memory.l and
isfile( privdir() + "dssvmem.sc") then
play privdir() + "dssvmem"
endif
;-- define the variables that determine if a key stroke is legal
;-- two variables are used as the maximum length of a variable is
;-- 255 characters and there are 398 possible keys values that can be
;-- accepted with a getchar()
;-- this may be a bit of an overkill but it allows a lot of customizing
;-- quite easily using the dskeys.sc to re-define the acceptable keys
;-- used in this application
ds.neg.key.a="iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiisiiiiiiiiiiiissiii"+
"iisisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiissiiiiiiiiiiiiiiii"+
"iiiii"
ds.pos.key.a="iiiiiiisiiiisiiiiiiiiiiiiieiiiiiiiiiiiiiississsrrrrrrrrrriiisiii"+
"iisiiiiiiiiisiiiiiiiiiiiiiiiiiiiiisiiiiiiiiisiiiiiiiiiiiiiiiiisi"+
"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"+
"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"
cursor off
;-- places a picture of a calculator on the screen
ds.calc.screen.u()
;-- the main loop in the application. this loop will not be exited until
;-- the user chooses to stop using the calculator. all other procedures
;-- are called from within this loop or from procedures that this loop calls
while true
;-- error checking so that the array size will not be exceeded
if ds.tape.count.s < ds.tape.length.s then
ds.char.s = getchar()
else
;-- ds.error.u sets up and displays various messages
;-- to the user as required
ds.error.u(
"SORRY! YOU HAVE REACHED THE LIMIT OF THE TAPE!" +
" ALL ENTRIES WILL BE CLEARED!",
"Press any key to clear the calculator and continue.")
;-- sometimes paradox "erases" the last column on the canvas
;-- this has something to do with the prompt placed
;-- regarding selection of menu choices
;-- at least this did happen in version 2
;-- this little trick brings back the last line on the screen!
canvas off
message ""
@ 22,78 clear eol
canvas on
;-- pass on a clear the calculator keypress
ds.char.s = -111
endif
;-- determine what type of key was pressed by extracting the
;-- letter from ds.neg.key.a or ds.pos.key.a
if ds.char.s > 0 then
ds.key.type.a = substr(ds.pos.key.a,ds.char.s,1)
else
ds.key.type.a = substr(ds.neg.key.a,1-ds.char.s,1)
endif
;-- this switch processes the key that was pressed
switch
;-- illegal
case ds.key.type.a = "i" :
beep
;-- regular
case ds.key.type.a = "r" :
;-- press the key on the calculator
ds.key.press.u()
;-- actually process it
ds.regular.u()
;-- now display and/or update the calculator screen
ds.display.u()
;-- special keys get processed in this loop
case ds.key.type.a = "s" :
ds.special.key.u()
;-- process the request to exit
case ds.key.type.a = "e" :
ds.exit.v()
;-- again, make the bottom line re-appear
canvas off
message ""
@ 22,78 clear eol
canvas on
;-- process the returned value of ds.exit.v
switch
;-- the canceled the exit
case retval = "No " :
loop
;-- the do want to leave with a value so now another switch
case retval :
;-- process the last value in the tape and
;-- make the proper assignment to retval
switch
;-- returns the current entry in the calculator
;-- only if there is a single entry
case ds.tape.count.s = 1 and
isassigned(ds.tape.r[ds.tape.count.s]) and
ds.tape.r[ds.tape.count.s] <> blanknum() :
retval = numval(ds.tape.r[ds.tape.count.s])
;-- returns the current entry in the calculator
case ds.tape.count.s > 1 and
isassigned(ds.tape.r[ds.tape.count.s]) and
ds.tape.r[ds.tape.count.s] <> blanknum() :
retval = numval(ds.tape.r[ds.tape.count.s])
;-- returns the last assigned tape entry
case ds.tape.count.s > 1 and
isassigned(ds.tape.r[ds.tape.count.s-1]) and
ds.tape.r[ds.tape.count.s-1] <> blanknum() :
retval = numval(ds.tape.r[ds.tape.count.s-1])
;-- in case there is no usable entry to return
otherwise :
retval= false
endswitch
;-- the last possible retval of ds.exit.v
;-- probably not required but what the hey
case not retval :
retval = false
endswitch
;-- if the last value in the tape did not have a
;-- numeric value the re-assign retval
if lower(retval) = "error" then
retval = false
endif
;-- save the memory variables if saving is enabled
if ds.save.memory.l then
@ 00,00 clear eol ?? "Working"
style blink ?? "....."
@ 01,00 clear eol style
?? "Saving Memory Arrays."
ds.save.memory.u()
endif
return retval
endswitch
endwhile
endproc
?? "." message memleft() writelib ds.aplib.a ds.calc.v
release procs ds.calc.v
;-------------------------------------------------------------------------------
; ds.calc.screen.u()
;-------------------------------------------------------------------------------
; purpose: places the calculator on the screen
proc ds.calc.screen.u()
;-- inform the user something is happening
@ 00,00 clear eol ?? "Working"
style blink ?? "....."
@ 01,00 clear eol style
;-- turns the canvas off
canvas off
clear
style
;-- place the main prompt on the screen
ds.main.prompt.u()
;-- set the reverse video mode
style reverse
;-- set a margin for this block
setmargin 43
@ 2,43
text
╔═════ [Alt-F7] Review/Print ═════╗
║ Tape Function ║
╟──────────────────────────┬──────╢
endtext
;-- now turn it off
setmargin off
;-- normal video
style
;-- fill in the rest of the calculator
@ 2,0
text
┌───────────────────────────┐
│░░░░░░░░░░░░░░░░░░░░░░░░░░░│
│░░╔═════════════════════╗░░│
│░░║ ║░░│ ║ │ ║
│░░╚═════════════════════╝░░│ ║ │ ║
│░░░░░░░░░░░░░░░░░░░░░░░░░░░│ ║ │ ║
│░░┌───┐ ┌───┐ ┌───┐░░░░░░│ ║ │ ║
│░░│ 7 │ │ 8 │ │ 9 │░░ + ░│ Add ║ │ ║
│░░└───┘ └───┘ └───┘░░░░░░│ ║ │ ║
│░░┌───┐ ┌───┐ ┌───┐░░ - ░│ Subtract ║ │ ║
│░░│ 4 │ │ 5 │ │ 6 │░░░░░░│ ║ │ ║
│░░└───┘ └───┘ └───┘░░ * ░│ Multiply ║ │ ║
│░░┌───┐ ┌───┐ ┌───┐░░░░░░│ ║ │ ║
│░░│ 1 │ │ 2 │ │ 3 │░░ / ░│ Divide ║ │ ║
│░░└───┘ └───┘ └───┘░░░░░░│ ║ │ ║
│░░ ┌───────┐ ┌───┐ ░░░░░░│ ║ │ ║
│░░ │ 0 │ │ . │ ░░ = ░│ Equals or ║ │ ║
│░░ └───────┘ └───┘ ░░░░░░│ Enter ║ │ ║
│░░░░░░░░░░░░░░░░░░░░░░░░░░░│ ║ │ ║
│░░░ [Alt-C] = Clear All ░░░│ ║ │ ║
│░░░ [C] = Clear Entry ░░░│ ║ │ ║
│░░░░░░ [M]= Memory ░░░░░░░░│ ║ │ ║
└───────────────────────────┘ ╚ Tape Entries Left = ═══╧══════╝
endtext
;-- displays number of tape entries left in the array
@ 24,65 ?? strval(ds.tape.length.s-1) + " "
;-- turn the canvas back on
canvas on
endproc
?? "." message memleft() writelib ds.aplib.a ds.calc.screen.u
release procs ds.calc.screen.u
;-------------------------------------------------------------------------------
; ds.exit.v()
;-------------------------------------------------------------------------------
; purpose: displays the exit menu and the choices
proc ds.exit.v()
private
ds.exit.choice.a
showmenu
"No " : " Do not exit DSCalc.",
"Return " : " Return with the last entry in the calculator.",
"Esc " : " Return without the a value."
to ds.exit.choice.a
switch
;-- user wanted to return to using the calculator
case ds.exit.choice.a = "No " :
return ds.exit.choice.a
;-- user wants the last entry returned
case ds.exit.choice.a = "Return " :
return true
;-- "Esc " or "Esc" was selected
otherwise : return false
endswitch
endproc
?? "." message memleft() writelib ds.aplib.a ds.exit.v
release procs ds.exit.v
;-------------------------------------------------------------------------------
; ds.regular.u()
;-------------------------------------------------------------------------------
; purpose: handles keys that are defined as "regular" keys. no special
; handling. unless changed, the only regular keys are the
; numbers 0 through 9
proc ds.regular.u()
;-- the ds.char.r array elements are stored as strings
;-- this way the strings can be added together to create ]
;-- whole number
;-- if the element was numeric, then when attempting
;-- to type in "12", the variable would become 3
;-- so if it is previously assigned add the strings
if isassigned(ds.tape.r[ds.tape.count.s]) then
ds.tape.r[ds.tape.count.s] =
strval(ds.tape.r[ds.tape.count.s]) +
strval(chr(ds.char.s))
else
ds.tape.r[ds.tape.count.s] =
chr(ds.char.s)
endif
switch
;-- this case eliminates leading zeros
case numval(ds.tape.r[ds.tape.count.s]) = 0 and
not ds.decimal.r[ds.tape.count.s] :
ds.tape.r[ds.tape.count.s] = blanknum()
beep
;-- this case allows negatives and negative decimals
case numval(ds.tape.r[ds.tape.count.s]) = "error" and
len(ds.tape.r[ds.tape.count.s]) = 2 :
ds.tape.r[ds.tape.count.s] = "-0."
endswitch
endproc
?? "." message memleft() writelib ds.aplib.a ds.regular.u
release procs ds.regular.u
;-------------------------------------------------------------------------------
; ds.special.key.u()
;-------------------------------------------------------------------------------
; purpose: handles the "special" keys accepted by the program. these include
; the math keys, help systems, clear entries, clear the calculator,
; etc.
proc ds.special.key.u()
switch
; alt-f7 - review-print tape
case ds.char.s = -110 :
;-- clear the top 2 lines
@ 00,00 clear eol
@ 01,00 clear eol
;-- call the procedure that processes this request
ds.review.print.u()
;-- this variable is set to true if the screen needs to
;-- be "refreshed"
if ds.rebuild.l then
;-- if it does then do_it!
ds.rebuild.l()
else
;-- replace the main prompt
ds.main.prompt.u()
endif
;-- place the appropriate entry into the calculator screen
ds.display.u()
;-- alt-f8 or alt-c indicates to reset and clear the calculator
case ds.char.s = -111 or
ds.char.s = -46 :
;-- re-assign the variable to the value used by the other procedures
ds.char.s = -111
;-- toggle the keypad on
ds.key.press.u()
;-- a slight delay for effect
sleep 250
;-- re-assign it again to clear the keypad
ds.char.s = 1000
;-- toggle the keypad off
ds.key.press.u()
;-- clear the calculator window
@ 05,04 ?? spaces(21)
;-- reset the required variables
ds.set.vars.u("some")
;-- now clear and re-display the screen
ds.calc.screen.u()
;-- [f8], ctrlbackspace, C or c indicates
;-- to clear the current entry only
case ds.char.s = -66 or
ds.char.s = 127 or
ds.char.s = 99 or
ds.char.s = 67 :
;-- re-assign the variable to the value used by the other procedures
ds.char.s = -66
;-- toggle the keypad on
ds.key.press.u()
;-- a slight delay for effect
sleep 250
;-- re-assign it again to clear the keypad
ds.char.s = 1000
;-- reset the current array element
ds.decimal.r[ds.tape.count.s] = false
;-- toggle the keypad off
ds.key.press.u()
;-- reset the current array element
ds.tape.r[ds.tape.count.s] = blanknum()
;-- clear the calculator window
@ 05,04 ?? spaces(21)
;-- the user opted to see the menu by pressing [f10]
case ds.char.s = -68 :
;-- clear the top 2 lines
@ 00,00 clear eol
@ 01,00 clear eol
;-- so call the menu procedure
ds.menu.u()
;-- this variable is set to true if the screen needs to
;-- be "refreshed"
if ds.rebuild.l then
;-- if it does then do_it!
ds.rebuild.l()
else
;-- replace the main prompt
ds.main.prompt.u()
endif
;-- re-display the calculator window
ds.display.u()
;-- [f2], = or enter indicates to calculate the total
case ds.char.s = -60 or
ds.char.s = 61 or
ds.char.s = 13 :
;-- re-assign the variable to the value used by the other procedures
ds.char.s = 61
;-- toggle the keypad on
ds.key.press.u()
;-- now actually compute the total
ds.total.u()
;-- toggle the keypad off
ds.key.press.u()
;-- re-display the main prompt
ds.main.prompt.u()
;-- user wants some help! presses [f1]
case ds.char.s = -59 :
;-- clear the top 2 lines
@ 00,00 clear eol
@ 01,00 clear eol
;-- call the help routine
ds.help.menu.u()
;-- this variable is set to true if the screen needs to
;-- be "refreshed"
if ds.rebuild.l then
;-- if it does then do_it!
ds.rebuild.l()
;-- replace the main prompt
ds.main.prompt.u()
endif
;-- the user pressed the backspace key to delete the last
;-- character typed in. nice touch! try this on a regular
;-- calculator some time!
case ds.char.s = 8 :
;-- toggle the keypad off as 8 is not a valid
;-- keypad key
ds.key.press.u()
;-- this only works if the array element is assigned a value
;-- and it's length is > 1
if isassigned(ds.tape.r[ds.tape.count.s]) and
len(ds.tape.r[ds.tape.count.s]) > 1 then
;-- find out the last key pressed
ds.char.was.v =
substr(ds.tape.r[ds.tape.count.s],len(ds.tape.r[ds.tape.count.s]),1)
;-- shorten the string by one character
ds.tape.r[ds.tape.count.s] =
substr(ds.tape.r[ds.tape.count.s],1,len(ds.tape.r[ds.tape.count.s])-1)
;-- if the last character was a period, reset the array
;-- element that defines the variable as a whole or fractional
;-- value for display purposes
if asc(ds.char.was.v) = 46 then
ds.decimal.r[ds.tape.count.s] = false
endif
;-- re-display the new value in the calculator window
ds.display.u()
else
;-- re-assign the arrays as required just in case
ds.tape.r[ds.tape.count.s] = blanknum()
ds.decimal.r[ds.tape.count.s] = false
;-- beep at the user, there really wasn't anything
;-- to backspace anyway
beep
;-- clear the calculator window
@ 05,04 ?? spaces(21)
endif
;-- user wants to indicate that the value is to be multiplied (*),
;-- added (+) or divided (/) into the preceding value
case ds.char.s = 42 or ; multiply *
ds.char.s = 43 or ; add +
ds.char.s = 47 : ; divide /
;-- toggle the keypad on
ds.key.press.u()
;-- add it to the tape window
ds.tape.display.l()
;-- subtract takes special processing. the user may be indicating
;-- that the number is negative.
case ds.char.s = 45 :
;-- this is a negative number
if not isassigned(ds.tape.r[ds.tape.count.s]) or
len(ds.tape.r[ds.tape.count.s]) = 0 then
;-- toggle the keypad on
ds.key.press.u()
;-- so it becomes a regular key instead of special
ds.regular.u()
;-- update the calculator window
ds.display.u()
else
;-- here it is added it to the tape window
;-- because they want to subtract it!
ds.tape.display.l()
endif
;-- user is indication a decimal
case ds.char.s = 46 :
;-- toggle the keypad on
ds.key.press.u()
;-- if it's already a decimal, beep at them for being dumb!
if ds.decimal.r[ds.tape.count.s] then
beep
else
;-- set the array variable as appropriate
ds.decimal.r[ds.tape.count.s] = true
;-- it now becomes a regular key
ds.regular.u()
;-- update/display the calculator window
ds.display.u()
endif
; user pressed M or m for memory
case ds.char.s = 77 or
ds.char.s = 109 :
;-- re-assign the variable to the value used by the other procedures
ds.char.s = 77
;-- toggle the keypad on
ds.key.press.u()
;-- clear the top 2 lines
@ 00,00 clear eol
@ 01,00 clear eol
;-- call the memory procedure
ds.memory.u()
;-- replace the main prompt
ds.main.prompt.u()
endswitch
endproc
?? "." message memleft() writelib ds.aplib.a ds.special.key.u
release procs ds.special.key.u
;-------------------------------------------------------------------------------
; ds.key.press.u()
;-------------------------------------------------------------------------------
; purpose: simulates pressing a key on the keypad by toggling styles
proc ds.key.press.u()
;-- there was a previous key to turn off so turn
;-- it off with this call
if lower(ds.char.was.v) <> "no" then
ds.key.press.toggle.u(ds.char.was.v)
endif
;-- this sets up a slight flicker between turning
;-- one key off and the next one on
if ds.char.was.v = ds.char.s then
sleep 50
endif
;-- re-assign the variable for the next call to this procedure
ds.char.was.v = ds.char.s
;-- set the style
style reverse
;-- toggle the last key pressed on
ds.key.press.toggle.u(ds.char.s)
;-- reset the style
style
endproc
?? "." message memleft() writelib ds.aplib.a ds.key.press.u
release procs ds.key.press.u
;-------------------------------------------------------------------------------
; ds.key.press.toggle.u(ds.char.s)
;-------------------------------------------------------------------------------
; purpose: repaints the required area of the screen with the appropriate key
; that was pressed
proc ds.key.press.toggle.u(
ds.char.s) ;-- passed parameter for the following
;-- case statement
switch
case ds.char.s = 48 : @ 18,07 ?? " 0 "
case ds.char.s = 49 : @ 15,04 ?? " 1 "
case ds.char.s = 50 : @ 15,11 ?? " 2 "
case ds.char.s = 51 : @ 15,18 ?? " 3 "
case ds.char.s = 52 : @ 12,04 ?? " 4 "
case ds.char.s = 53 : @ 12,11 ?? " 5 "
case ds.char.s = 54 : @ 12,18 ?? " 6 "
case ds.char.s = 55 : @ 09,04 ?? " 7 "
case ds.char.s = 56 : @ 09,11 ?? " 8 "
case ds.char.s = 57 : @ 09,18 ?? " 9 "
case ds.char.s = -111 : @ 21,05 ?? "[Alt-C]"
case ds.char.s = -66 : @ 22,06 ?? "[C]"
case ds.char.s = 61 : @ 18,24 ?? " = "
case ds.char.s = 42 : @ 13,24 ?? " * "
case ds.char.s = 43 : @ 09,24 ?? " + "
case ds.char.s = 45 : @ 11,24 ?? " - "
case ds.char.s = 46 : @ 18,16 ?? " . "
case ds.char.s = 47 : @ 15,24 ?? " / "
case ds.char.s = 77 : @ 23,08 ?? "[M]"
endswitch
endproc
?? "." message memleft() writelib ds.aplib.a ds.key.press.toggle.u
release procs ds.key.press.toggle.u
;-------------------------------------------------------------------------------
; ds.display.u()
;-------------------------------------------------------------------------------
; purpose: displays the value of the current tape element in the calculator
; window
proc ds.display.u()
switch
;-- no assignment yet or is was re-assigned to
;-- blanknum()
case not isassigned(ds.tape.r[ds.tape.count.s]) or
ds.tape.r[ds.tape.count.s] = blanknum() :
;-- clear the window
@ 05,04 ?? spaces(21)
;-- indicates a negative number or zero or
;-- the value is a decimal
;-- decimal values are not formatted with commas as there
;-- would need to be a special case for the number places
;-- after the decimal to be displayed and formatted
;-- correctly
;-- this became cumbersome so it was decided to take
;-- this approach
case ds.tape.r[ds.tape.count.s] = "-" or
numval(ds.tape.r[ds.tape.count.s]) = 0 or
ds.decimal.r[ds.tape.count.s] :
;-- no special formatting to display the variable
@ 05,04 ?? format("w20,ar",strval(ds.tape.r[ds.tape.count.s]))
;-- non-decimals
case not ds.decimal.r[ds.tape.count.s] :
;-- format with commas
@ 05,04 ?? format("w20,ar,ec",numval(ds.tape.r[ds.tape.count.s]))
endswitch
endproc
?? "." message memleft() writelib ds.aplib.a ds.display.u
release procs ds.display.u
;-------------------------------------------------------------------------------
; ds.set.vars.u()
;-------------------------------------------------------------------------------
; purpose: sets/reset some or all of the variables used in this program
; called in the initial start up and during clear alls of the
; calculator and clearing memory, etc.
proc ds.set.vars.u(
all.or.some.a) ;-- this variable controls which variables
;-- need to be set/reset
private
ds.loop.counter.s ;-- a loop counter
;-- sets memory variables as required based on the passed parameter
if lower(all.or.some.a) = "all" or
lower(all.or.some.a) = "memory" then
;-- defines the arrays. if they were previously defined,
;-- this will clear all of the elements
;-- these arrays are used in a showarray
array ds.memory.r[20]
array ds.memory.element.r[20]
;-- go through this loop and assign elements of the arrays
;-- except the first
for ds.loop.counter.s from 2 to 20
ds.memory.r[ds.loop.counter.s] = "Not Assigned"
ds.memory.element.r[ds.loop.counter.s] = strval(ds.loop.counter.s-1)
endfor
;-- assign the first elements of the arrays
ds.memory.element.r[1] = "Select »"
ds.memory.r[1] = "Use the [] [" + chr(26) +
"] keys to select the Memory # then press [Enter]." +
" [Esc] to leave."
;-- if all we were doing was resetting the memory arrays, return
if lower(all.or.some.a) = "memory" then
return
endif
endif
;-- this sets/resets user defined/default variables
;-- from the calling parameters to ds.calc.v
if lower(all.or.some.a) = "all" then
;-- define the array size of the tape based on
;-- called parameter or assign it the default
;-- this is incremented by one as the application uses the last
;-- element in totals, etc.
if isassigned(ds.tape.length.s) then
;-- since you can't check the numval of a number,
;-- all tests are performed on the numval of
;-- the strval of the variable
switch
;-- a number wasn't passed
case lower(numval(strval(ds.tape.length.s))) = "error" :
ds.tape.length.s = 51
;-- an out of range number
case (numval(strval(ds.tape.length.s)) < 20) or
(numval(strval(ds.tape.length.s)) > 500) :
ds.tape.length.s = 51
;-- assign the value that was passed here
otherwise :
ds.tape.length.s = int(numval(strval(ds.tape.length.s))+1)
endswitch
else
;-- default setting if no parameter was passed
ds.tape.length.s = 51
endif
;-- here the setswap point is determined
if isassigned(ds.set.swap.n) then
switch
;-- checking for a number
case lower(numval(strval(ds.set.swap.n))) = "error" :
ds.set.swap.n = 35000
;-- checking to see if it exceeds the maximum allowed
case numval(strval(ds.set.swap.n)) > memleft() :
ds.set.swap.n = 35000
;-- checking for below the minimum
case numval(strval(ds.set.swap.n)) < 35000 :
ds.set.swap.n = 35000
;-- to get here none of the above needed to be true
otherwise :
ds.set.swap.n = int(numval(strval(ds.set.swap.n)))
endswitch
else
;-- default setting for setswap
ds.set.swap.n = 35000
endif
;-- here error checking is performed on the ds.save.memory
;-- parameter
if isassigned(ds.save.memory.l) and
lower(type(ds.save.memory.l)) <> "l" then
if lower(ds.save.memory.l) = "true" then
ds.save.memory.l = true
else
ds.save.memory.l = false
endif
endif
if not isassigned(ds.save.memory.l) then
ds.save.memory.l = false
endif
endif
;-- here the arrays are defined or re-defined
;-- re-defining an array effectively releases any
;-- assignments to any element in the array
;-- the tape itself
array ds.tape.r[ds.tape.length.s]
;-- the function sign displayed with the corresponding
;-- tape element
array ds.tape.function.r[ds.tape.length.s]
;-- whether or not the tape entries' corresponding
;-- element has a decimal in it
array ds.decimal.r[ds.tape.length.s]
;-- an array that keeps subtotals
array ds.total.was.r[ds.tape.length.s]
;-- the counter that keeps track of which element
;-- we are working with
ds.tape.count.s = 1
;-- initial setting of some of the variables
;-- no previous key to un-press
ds.char.was.v = "no"
;-- the first element is not a decimal
ds.decimal.r[1] = false
;-- the previous sub-total array element that was assigned
ds.total.element.num.was.s = 1
;-- initial assignment
ds.total.was.r[1] = 0
;-- initially false, changed to true as required
ds.rebuild.l = false
endproc
?? "." message memleft() writelib ds.aplib.a ds.set.vars.u
release procs ds.set.vars.u
;-------------------------------------------------------------------------------
; ds.tape.display.l()
;-------------------------------------------------------------------------------
; purpose: displays the tape entries in the tape window
proc ds.tape.display.l()
private
ds.loop.counter.s, ;-- a loop counter
position.pointer.s ;-- this variable is used for @ to position
;-- text to be displayed to the screen
;-- if there are is nothing to display then there is nothing to do
if not isassigned(ds.tape.r[ds.tape.count.s]) or
lower(numval(strval(ds.tape.r[ds.tape.count.s]))) = "error" then
beep
;-- inform calling procedure of failure
return false
endif
;-- make an assignment to this array element based on the key
;-- last pressed by the user
ds.tape.function.r[ds.tape.count.s] = ds.char.s
;-- clear the calculator window
@ 05,04 ?? spaces(21)
;-- if there are less entries in the calculator then 19
;-- we simply add the entry to the end of the list
if ds.tape.count.s < 19 then
;-- only if not the first entry
if ds.tape.count.s > 1 then
;-- if it's a sub-total then display the = sign
;-- with the previous entry in and set intense mode
;-- other wise set normal video mode
if ds.tape.function.r[ds.tape.count.s-1] = 61 then
@ ds.tape.count.s+3,73 ?? chr(ds.tape.function.r[ds.tape.count.s-1])
style intense
else
style
endif
endif
;-- use the format appropriate for the tape type ie. decimal or non-decimal
@ ds.tape.count.s+4,45
if ds.decimal.r[ds.tape.count.s] then
?? format("w20.15,ar",numval(ds.tape.r[ds.tape.count.s]))
else
?? format("w20,ar,ec",numval(ds.tape.r[ds.tape.count.s]))
endif
;-- display the function that goes along with this entry
@ ds.tape.count.s+4,73 ?? chr(ds.tape.function.r[ds.tape.count.s])
else
;-- turn the canvas off
canvas off
;-- define the position
position.pointer.s = 6
;-- this informs the user that there is more to the tape
;-- that they can no longer see
style reverse
@ 05,43 ?? "║ More │ ║"
style
;-- this loop places the last 17 entries in the tape into the tape
;-- window
for ds.loop.counter.s from (ds.tape.count.s - 17) to ds.tape.count.s
;-- set the style for totals if the previous tape
;-- function was a =
if ds.tape.function.r[ds.loop.counter.s-1] = 61 then
style intense
else
style
endif
;-- place the cursor at the right position
@ position.pointer.s,45
;-- select proper format to display the tape entry
if ds.decimal.r[ds.loop.counter.s] then
?? format("w20.15,ar",numval(ds.tape.r[ds.loop.counter.s]))
else
?? format("w20,ar,ec",numval(ds.tape.r[ds.loop.counter.s]))
endif
;-- place the corresponding function character
@ position.pointer.s,73
?? chr(ds.tape.function.r[ds.loop.counter.s])
;-- increment the pointer by 1
position.pointer.s = position.pointer.s + 1
endfor
;-- turn the canvas back on
canvas on
endif
;-- now some beeps and style differences if the tape
;-- is running low on entries
switch
;-- more than 5 entries left, just set normal style
case ds.tape.length.s - ds.tape.count.s - 1 > 5 :
style
;-- only 5, intense and a beep
case ds.tape.length.s - ds.tape.count.s - 1 = 5 :
style intense
beep
;-- 4 left, another style - 2 beeps
case ds.tape.length.s - ds.tape.count.s - 1 = 4 :
style reverse
beep beep
;-- 3 left, blink and 3 beeps
case ds.tape.length.s - ds.tape.count.s - 1 = 3 :
style blink, intense
beep beep beep
;-- 2 left, reverse and 4 beeps
case ds.tape.length.s - ds.tape.count.s - 1 = 2 :
style blink, reverse
beep beep beep beep
;-- one left, blinking reverse., 5 beeps
case ds.tape.length.s - ds.tape.count.s - 1 <= 1 :
style blink, reverse
beep beep beep beep beep
endswitch
;-- display number of entries left
@ 24,65 ?? strval(ds.tape.length.s-ds.tape.count.s-1) + " "
;-- increment the array counter for the next entry
ds.tape.count.s = ds.tape.count.s + 1
;-- set the decimal array element
ds.decimal.r[ds.tape.count.s] = false
;-- make sure style is back to normal
style
;-- inform calling procedure of successful completion
return true
endproc
?? "." message memleft() writelib ds.aplib.a ds.tape.display.l
release procs ds.tape.display.l
;-------------------------------------------------------------------------------
; ds.total.u()
;-------------------------------------------------------------------------------
; purpose: computes the total
proc ds.total.u()
private
ds.loop.counter.s ;-- a loop counter
switch
;-- nothing to total with less then 2 entries
case ds.tape.count.s < 2 :
beep
return
;-- if the last element is assigned and it's non-numeric and
;-- it's not blank, can't do any processing
case isassigned(ds.tape.r[ds.tape.count.s]) and
lower(numval(strval(ds.tape.r[ds.tape.count.s]))) = "error" and
not isblank(ds.tape.r[ds.tape.count.s]) :
beep
return
;-- if it's not assigned or 0 and there are only 2 entries,
;-- nothing to compute
case (not isassigned(ds.tape.r[ds.tape.count.s]) or
numval(strval(ds.tape.r[ds.tape.count.s])) = 0) and
ds.tape.count.s = 2 :
beep
return
;-- if it's not assigned or 0 and then a case statement
;-- so the following otherwise will not be executed
case (not isassigned(ds.tape.r[ds.tape.count.s]) or
numval(strval(ds.tape.r[ds.tape.count.s])) = 0 ) :
;-- add the last entry to the tape window which
;-- increments ds.tape.count.s by 1
;-- that's the reason for the previous case
otherwise : ds.tape.display.l()
endswitch
;-- if the total element counter is not 1 then
;-- assign the last tape element the last total that
;-- was computed
if ds.total.element.num.was.s <> 1 then
ds.tape.r[ds.tape.count.s] =
strval(ds.total.was.r[ds.total.element.num.was.s])
endif
;-- if the total element counter is not 1 then
if ds.total.element.num.was.s <> 1 then
;-- loop
for ds.loop.counter.s
;-- from the previous total element plus 1
from (ds.total.element.num.was.s + 1)
;-- to the previous element
to (ds.tape.count.s - 1)
;-- execute the functions (+-*/)
execute "ds.tape.r[ds.tape.count.s]=numval(ds.tape.r[ds.tape.count.s])" +
chr(ds.tape.function.r[ds.loop.counter.s-1]) +
"numval(ds.tape.r[ds.loop.counter.s])"
;-- convert to a string
ds.tape.r[ds.tape.count.s] = strval(ds.tape.r[ds.tape.count.s])
endfor
;-- if it is 1
else
;-- let the currently entry = the first entry
ds.tape.r[ds.tape.count.s] = ds.tape.r[1]
;-- calculate the second to the next to last entries
for ds.loop.counter.s from 2 to (ds.tape.count.s - 1)
;-- execute the functions (+-*/)
execute "ds.tape.r[ds.tape.count.s]=numval(ds.tape.r[ds.tape.count.s])" +
chr(ds.tape.function.r[ds.loop.counter.s-1]) +
"numval(ds.tape.r[ds.loop.counter.s])"
;-- convert to a string
ds.tape.r[ds.tape.count.s] = strval(ds.tape.r[ds.tape.count.s])
endfor
endif
;-- re-position which element has the previous total
ds.total.element.num.was.s = ds.tape.count.s
;-- make the assignment to the proper array element
ds.total.was.r[ds.total.element.num.was.s] = strval(ds.tape.r[ds.tape.count.s])
;-- identify that this is a total value
ds.tape.function.r[ds.tape.count.s-1] = 61
;-- determine if the total has a decimal in it or not
ds.set.decimal.u()
;-- to toggle the key pad off
ds.char.s = 1000
;-- set the style for a total value
style intense
;-- display it in the calculator window
ds.display.u()
;-- back to normal style
style
;-- increment the array element counter
ds.tape.count.s = ds.tape.count.s + 1
;-- turn the keypad off
ds.key.press.u()
;-- place a prompt on the top 2 lines
@ 00,00
?? format("w80,ac",
"Press a function key to continue the tape (i.e. +, -, /, *, = )")
@ 01,00
?? format("w80,ac",
"or [Alt-F8] to clear the calculator and start a new tape.")
;-- wait to get an acceptable key to exit this loop
while true
;-- a getchar waiting for something to be pressed
ds.char.s = getchar()
switch
;-- user opted to clear the calculator by
;-- pressing [alt][f8] or [alt][c]
case ds.char.s = -111 or
ds.char.s = -46 :
;-- reset ds.char.s if required
ds.char.s = -111
;-- clear the calculator window
@ 05,04 ?? spaces(21)
;-- re-define the arrays
ds.set.vars.u("some")
;-- re-paint the calculator
ds.calc.screen.u()
;-- all done
return
;-- user pressed a function key
case ds.char.s = 42 or ; multiply
ds.char.s = 43 or ; add
ds.char.s = 45 or ; subtract
ds.char.s = 47 : ; divide
;-- leave the loop
quitloop
;-- user pressed enter, = or [f2]
case ds.char.s = -60 or ; f2
ds.char.s = 61 or ; =
ds.char.s = 13 : ; enter
;-- default to add and let the user decide
;-- to clearall, memory, etc.
ds.char.s = 43
;-- leave the loop
quitloop
;-- need to press something so beep at them
otherwise :
beep
endswitch
endwhile
;-- assign the tape function pressed
ds.tape.function.r[ds.tape.count.s-1] = ds.char.s
;-- the call to ds.tape.display.l will
;-- increment ds.tape.count.s by 1 so adjust
;-- it down so it will be right
ds.tape.count.s = ds.tape.count.s - 1
;-- display the tape
ds.tape.display.l()
endproc
?? "." message memleft() writelib ds.aplib.a ds.total.u
release procs ds.total.u
;-------------------------------------------------------------------------------
; ds.save.memory.u()
;-------------------------------------------------------------------------------
; purpose: creates the file dssvmem.sc in the private directory so that
; it can be played later to retrieve memory the next time
; the calculator is used
; the individual elements could have been printed in for loops,
; however I believe this approach might be just a tad faster
proc ds.save.memory.u()
private
ds.file.to.print ;-- file to print to
;-- define the file name
;-- this may not be required but if somehow
;-- privdir() returns " " instead of "" then the
;-- print file might bomb
if isblank(privdir()) then
ds.file.to.print = "dssvmem.sc"
else
ds.file.to.print = privdir() + "dssvmem.sc"
endif
;-- delete current file if it exists
;-- this will work in any sysmode
if isfile(ds.file.to.print) then
run norefresh "del " + ds.file.to.print
endif
;-- define the array
print file ds.file.to.print
"array ds.memory.r[20]\n",
;-- save the first element of the array
;-- this takes special handling as the escape character
;-- used to display the left arrow sets up an end-of-file marker
"ds.memory.r[1]=\"Use the [] [\"+chr(26)+\"",
"] keys to select the Memory # then press [Enter].",
" [Esc] to leave.\"\n",
;-- and save the rest of the elements of that array
"ds.memory.r[2]=\"" + ds.memory.r[2] + "\"\n",
"ds.memory.r[3]=\"" + ds.memory.r[3] + "\"\n",
"ds.memory.r[4]=\"" + ds.memory.r[4] + "\"\n",
"ds.memory.r[5]=\"" + ds.memory.r[5] + "\"\n",
"ds.memory.r[6]=\"" + ds.memory.r[6] + "\"\n",
"ds.memory.r[7]=\"" + ds.memory.r[7] + "\"\n",
"ds.memory.r[8]=\"" + ds.memory.r[8] + "\"\n",
"ds.memory.r[9]=\"" + ds.memory.r[9] + "\"\n",
"ds.memory.r[10]=\"" + ds.memory.r[10] + "\"\n",
"ds.memory.r[11]=\"" + ds.memory.r[11] + "\"\n",
"ds.memory.r[12]=\"" + ds.memory.r[12] + "\"\n",
"ds.memory.r[13]=\"" + ds.memory.r[13] + "\"\n",
"ds.memory.r[14]=\"" + ds.memory.r[14] + "\"\n",
"ds.memory.r[15]=\"" + ds.memory.r[15] + "\"\n",
"ds.memory.r[16]=\"" + ds.memory.r[16] + "\"\n",
"ds.memory.r[17]=\"" + ds.memory.r[17] + "\"\n",
"ds.memory.r[18]=\"" + ds.memory.r[18] + "\"\n",
"ds.memory.r[19]=\"" + ds.memory.r[19] + "\"\n",
"ds.memory.r[20]=\"" + ds.memory.r[20] + "\"\n",
;-- define this array
;print file ds.file.to.print
"array ds.memory.element.r[20]\n",
;-- and save the elements of that array
"ds.memory.element.r[1]=\"" + ds.memory.element.r[1] + "\"\n",
"ds.memory.element.r[2]=\"" + ds.memory.element.r[2] + "\"\n",
"ds.memory.element.r[3]=\"" + ds.memory.element.r[3] + "\"\n",
"ds.memory.element.r[4]=\"" + ds.memory.element.r[4] + "\"\n",
"ds.memory.element.r[5]=\"" + ds.memory.element.r[5] + "\"\n",
"ds.memory.element.r[6]=\"" + ds.memory.element.r[6] + "\"\n",
"ds.memory.element.r[7]=\"" + ds.memory.element.r[7] + "\"\n",
"ds.memory.element.r[8]=\"" + ds.memory.element.r[8] + "\"\n",
"ds.memory.element.r[9]=\"" + ds.memory.element.r[9] + "\"\n",
"ds.memory.element.r[10]=\"" + ds.memory.element.r[10] + "\"\n",
"ds.memory.element.r[11]=\"" + ds.memory.element.r[11] + "\"\n",
"ds.memory.element.r[12]=\"" + ds.memory.element.r[12] + "\"\n",
"ds.memory.element.r[13]=\"" + ds.memory.element.r[13] + "\"\n",
"ds.memory.element.r[14]=\"" + ds.memory.element.r[14] + "\"\n",
"ds.memory.element.r[15]=\"" + ds.memory.element.r[15] + "\"\n",
"ds.memory.element.r[16]=\"" + ds.memory.element.r[16] + "\"\n",
"ds.memory.element.r[17]=\"" + ds.memory.element.r[17] + "\"\n",
"ds.memory.element.r[18]=\"" + ds.memory.element.r[18] + "\"\n",
"ds.memory.element.r[19]=\"" + ds.memory.element.r[19] + "\"\n",
"ds.memory.element.r[20]=\"" + ds.memory.element.r[20] + "\"\n"
endproc
?? "." message memleft() writelib ds.aplib.a ds.save.memory.u
release procs ds.save.memory.u
;-------------------------------------------------------------------------------
; ds.memory.u()
;-------------------------------------------------------------------------------
; purpose: displays the memory menu
proc ds.memory.u()
private
ds.memory.choice.a, ;-- menu choice variable
ds.array.element.num.s, ;-- which tape element to use
ds.array.to.show.v ;-- array element to display
;-- initialize the default menu choice
ds.memory.choice.a = "Add "
;-- stay in this loop until the user opts to exit
while true
;-- memory menu choices
showmenu
"Add " : " Add to Memory.",
"Subtract " : " Subtract from memory.",
"Recall " : " Recall from Memory.",
"Display " : " Display Memory.",
"Clear " : " Clear ALL Memory.",
"Esc " : " Return to DSCalc."
default ds.memory.choice.a
to ds.memory.choice.a
;-- re-displays the last line which is occasionally blanked out
;-- by paradox - this is used throughout the application
;-- in some case, it may not be required as I threw it
;-- in where ever I thought it might be needed
canvas off
message ""
@ 22,78 clear eol
canvas on
;-- turns the keypad off
ds.char.s = 1000
ds.key.press.u()
;-- okay, what was selected
switch
;-- user opted to cancel
case ds.memory.choice.a = "Esc " or
ds.memory.choice.a = "Esc" :
;-- re-displays the last line
canvas off
message ""
@ 22,78 clear eol
canvas on
return
case ds.memory.choice.a = "Clear " :
;-- clears the memory arrays
ds.set.vars.u("memory")
;-- but doesn't exit
loop
;-- all other menu choices are handled here
otherwise :
;-- default menu choice
ds.array.to.show.v = "Select »"
;-- a loop until they are done working with the arrays
while true
;-- display the element numbers on the top line and
;-- the contents on the prompt line
showarray ds.memory.element.r ds.memory.r
default ds.array.to.show.v
to ds.array.to.show.v
;-- opted to cancel
if ds.array.to.show.v = "Esc" or
ds.array.to.show.v = "Select »" then
canvas off
message ""
@ 22,78 clear eol
canvas on
quitloop
else
;-- otherwise convert the selected menu option
;-- to a number to decide further handling
ds.array.to.show.v = numval(ds.array.to.show.v)
endif
canvas off
message ""
@ 22,78 clear eol
canvas on
;-- this handles the initial choice, ie. what to do
;-- with the memory elements
switch
;-- this case handles adding and subtracting
case ds.memory.choice.a = "Add " or
ds.memory.choice.a = "Subtract " :
;-- if it is currently a non numeric value, then
;-- assign it = 0
if lower(numval(ds.memory.r[ds.array.to.show.v+1])) =
"error" then
ds.memory.r[ds.array.to.show.v+1] = "0"
endif
;-- handle the adding and subtracting based on
;-- the current tape position
switch
;-- the first entry of the tape is handled here
case ds.tape.count.s = 1 and
(not isassigned(ds.tape.r[ds.tape.count.s]) or
isblank(ds.tape.r[ds.tape.count.s]) or
lower(strval(numval(ds.tape.r[ds.tape.count.s]))) =
"error") :
;-- beep the error
beep
;-- set up a error trap
ds.array.element.num.s = "error"
;-- this handles the current entry
case isassigned(ds.tape.r[ds.tape.count.s]) and
ds.tape.r[ds.tape.count.s] <> blanknum() and
lower(numval(ds.tape.r[ds.tape.count.s])) <> "error":
;-- the current element is a number so use it
ds.array.element.num.s = ds.tape.count.s
;-- the current entry was illegal so this check the
;-- previous entry
case isassigned(ds.tape.r[ds.tape.count.s-1]) and
ds.tape.r[ds.tape.count.s-1] <> blanknum() and
lower(numval(ds.tape.r[ds.tape.count.s-1])) <>
"error":
;-- the use the previous element
ds.array.element.num.s = ds.tape.count.s - 1
;-- everything failed the test!
otherwise :
;-- shame shame
beep
;-- set up a error trap
ds.array.element.num.s = "error"
endswitch
;-- if there was no error process here
if lower(ds.array.element.num.s) <> "error" then
;-- if add then add it to the current value
if lower(ds.memory.choice.a) = "add " then
ds.memory.r[ds.array.to.show.v+1] =
numval(ds.memory.r[ds.array.to.show.v+1]) +
numval(ds.tape.r[ds.array.element.num.s])
;-- otherwise subtract
else
ds.memory.r[ds.array.to.show.v+1] =
numval(ds.memory.r[ds.array.to.show.v+1]) -
numval(ds.tape.r[ds.array.element.num.s])
endif
;-- shouldn't be an error here but just in case
if lower(ds.memory.r[ds.array.to.show.v+1]) = "error" then
ds.memory.r[ds.array.to.show.v+1] = "Not Assigned"
;-- else store the string value
else
ds.memory.r[ds.array.to.show.v+1] =
strval(ds.memory.r[ds.array.to.show.v+1])
endif
endif
;-- user wants to recall the value
case ds.memory.choice.a = "Recall " :
;-- if there is a number then
if lower(numval(ds.memory.r[ds.array.to.show.v+1]))
<> "error" then
;-- recall it into the current tape entry
ds.tape.r[ds.tape.count.s] =
strval(ds.memory.r[ds.array.to.show.v+1])
;-- set the decimal array element
ds.set.decimal.u()
;-- display it in the window
ds.display.u()
;-- all done
return
;-- nothing to recall
else
beep
endif
endswitch
;-- re-assign the variable to the sting value of itself
;-- otherwise the showarray crashes - it doesn't
;-- work with numbers
ds.array.to.show.v = strval(ds.array.to.show.v)
endwhile
endswitch
;-- that last line again
canvas off
message ""
@ 22,78 clear eol
canvas on
endwhile
endproc
?? "." message memleft() writelib ds.aplib.a ds.memory.u
release procs ds.memory.u
;-------------------------------------------------------------------------------
; ds.rebuild.l()
;-------------------------------------------------------------------------------
; purpose: rebuilds the tape when it has been covered with a help screen
; or otherwise erased
proc ds.rebuild.l()
private
ds.loop.counter.s, ;-- another loop counter
ds.end.of.loop.s ;-- a variable to end the loop
;-- places the calculator on the screen
ds.calc.screen.u()
;-- clears the keypad
ds.char.s = 1000
ds.key.press.u()
;-- if greater then 19 entries then ds.tape.display.l procedure
;-- handles this very nicely
if ds.tape.count.s > 19 then
;-- needs to be decreased by one
ds.tape.count.s = ds.tape.count.s - 1
;-- get the last key pressed for the procedure call
ds.char.s = asc(ds.tape.function.r[ds.tape.count.s])
;-- repaint the tape in the tape window
ds.tape.display.l()
;-- ds.tape.display.l need to be called one entry at a time
else
;-- determine how many times
ds.end.of.loop.s = ds.tape.count.s - 1
;-- turn the canvas off
canvas off
;-- place each tape entry back in the tape window
for ds.loop.counter.s from 1 to ds.end.of.loop.s
;-- fake out the procedure by altering the
;-- element pointer
ds.tape.count.s = ds.loop.counter.s
;-- get the last key pressed for the procedure call
ds.char.s = asc(ds.tape.function.r[ds.loop.counter.s])
;-- define the ds.decimal.r array elements
;-- must have had a bug here that's why the check
;-- the elements should be assigned already
if search(".",ds.tape.r[ds.loop.counter.s]) = 0 then
ds.decimal.r[ds.loop.counter.s] = false
else
ds.decimal.r[ds.loop.counter.s] = true
endif
;-- display the tape entry
ds.tape.display.l()
endfor
;-- turn the canvas on
canvas on
endif
;-- if the current entry is assigned and it's not blank
;-- then place it in the window
if isassigned(ds.tape.r[ds.tape.count.s]) and
not isblank(ds.tape.r[ds.tape.count.s]) then
;-- check decimal status
ds.set.decimal.u()
;-- paint it in the calculator window
ds.display.u()
;-- this not isblank is probably an overkill but what the hey
if not isblank(ds.tape.r[ds.tape.count.s]) then
;-- now what was the last key pressed?
ds.char.s =
asc( ;-- ascii is what we want
substr( ;-- part of a string
strval( ;-- the string val
ds.tape.r[ds.tape.count.s]), ;-- of this array element
len( ;-- starting position of the substr
ds.tape.r[ds.tape.count.s] ;-- is the length of the string
),1 ;-- only 1 character
) ;-- did you understand this?
) ;-- I didn't
else
ds.char.s = 1000 ;-- to turn the keypad off
endif
endif
endproc
?? "." message memleft() writelib ds.aplib.a ds.rebuild.l
release procs ds.rebuild.l
;-------------------------------------------------------------------------------
; ds.math.u()
;-------------------------------------------------------------------------------
; purpose: displays the math menu choices
proc ds.math.u()
private
ds.math.choice.a, ;-- variable assigned by showmenu
ds.tape.to.use.s ;-- which ds.tape.r element to use
;-- set to false, if required will be changed to true
ds.rebuild.l = false
;-- bottom line recovery
canvas off
message ""
@ 22,78 clear eol
canvas on
;-- display a menu of choices
showmenu
"ABS " : " Absolute value of the last entry.",
"EXP " : " Exponential value of the last entry.",
"INT " : " Integer part of the last entry.",
"LN " : " Natural logarithm value of the last entry.",
"LOG " : " Base 10 logarithm value of the last entry.",
"MOD " : " Remainder of one number divided by another number.",
"PI " : " Return the value of Pi.",
"POW " : " Raises the last entry to a power.",
"RAND " : " Returns a random number between 0 and 1.",
"ROUND " : " Rounds the last entry to a specified number of digits.",
"SQRT " : " Returns the square root of the last entry.",
"Esc " : " Return to what you were doing before pressing [F10]."
to ds.math.choice.a
;-- bottom line recovery
canvas off
message ""
@ 22,78 clear eol
canvas on
;-- process the selected choice
switch
;-- user opted to leave this menu without selecting a menu item
case ds.math.choice.a = "Esc " or
ds.math.choice.a = "Esc" :
return
;-- call the appropriate procedure that handles mod
case ds.math.choice.a = "MOD " :
style reverse
ds.math.mod.u()
style
return
;-- enter the value of pi into the latest tape array element
case ds.math.choice.a = "PI " :
ds.tape.r[ds.tape.count.s] = strval(pi())
ds.decimal.r[ds.tape.count.s] = true
return
;-- enter a random number into the latest tape array element
case ds.math.choice.a = "RAND " :
ds.tape.r[ds.tape.count.s] = strval(rand())
ds.decimal.r[ds.tape.count.s] = true
return
;-- all other functions require at least 1 valid entry in the tape
case ds.tape.count.s = 1 and
not isassigned(ds.tape.r[1]) or
isblank(ds.tape.r[1]) or
lower(strval(numval(ds.tape.r[1]))) = "error" :
;-- display a error message
ds.error.u(
"Sorry, there must be at least one entry in the calculator" +
" to perform the",
"requested calculation. Press any key" +
" to continue.")
return
endswitch
ds.math.proc.1.u(ds.math.choice.a)
endproc
?? "." message memleft() writelib ds.aplib.a ds.math.u
release procs ds.math.u
;-------------------------------------------------------------------------------
; ds.math.proc.1.u()
;-------------------------------------------------------------------------------
; purpose: handles the other possible menu choices from ds.math.u
; this procedure was created to hold the size of ds.math.u down
proc ds.math.proc.1.u(
ds.math.choice.a) ;-- the menu choice selected from ds.math.u
;-- identify which tape element to use
if (not isassigned(ds.tape.r[ds.tape.count.s])) or
(ds.tape.r[ds.tape.count.s] = blanknum()) or
(lower(numval(ds.tape.r[ds.tape.count.s])) = "error") then
ds.tape.to.use.s = ds.tape.count.s - 1
else
ds.tape.to.use.s = ds.tape.count.s
endif
;-- handle the other possible choices
switch
;-- convert the last entry to the absolute value of that entry
case ds.math.choice.a = "ABS " :
ds.tape.r[ds.tape.count.s] =
strval(abs(numval(ds.tape.r[ds.tape.to.use.s])))
;-- set the decimal array element
ds.set.decimal.u()
;-- the exponential value
case ds.math.choice.a = "EXP " :
;-- version 2 used to choke on this if the value was
;-- out of this range
;-- version 3 returns error but this is still here because it
;-- need to be handled somehow anyway
if numval(ds.tape.r[ds.tape.to.use.s]) < -708 or
numval(ds.tape.r[ds.tape.to.use.s]) > 709 then
;-- display the error message
ds.error.u(
"Sorry, the exponential of a number less than -708" +
" or greater than 709 can not",
"be computed. " +
" Press any key to continue.")
else
;-- make the conversion
ds.tape.r[ds.tape.count.s] =
strval(exp(numval(ds.tape.r[ds.tape.to.use.s])))
;-- set the decimal array element
ds.set.decimal.u()
endif
;-- convert to an integer
case ds.math.choice.a = "INT " :
;-- this one's easy
ds.tape.r[ds.tape.count.s] =
strval(int(numval(ds.tape.r[ds.tape.to.use.s])))
;-- set the decimal array element
ds.decimal.r[ds.tape.count.s] = false
;-- natural logarithm
case ds.math.choice.a = "LN " :
;-- version 2 used to choke on this if the value was
;-- out of this range
;-- version 3 returns error but this is still here because it
;-- need to be handled somehow anyway
if numval(ds.tape.r[ds.tape.to.use.s]) <= 0 then
;-- display the error message
ds.error.u(
"Sorry, the natural logarithm can not be computed" +
" on a number less than or",
"equal to zero. " +
" Press any key to continue.")
else
;-- make the conversion
ds.tape.r[ds.tape.count.s] =
strval(ln(numval(ds.tape.r[ds.tape.to.use.s])))
;-- set the decimal array element
ds.set.decimal.u()
endif
case ds.math.choice.a = "LOG " :
;-- version 2 used to choke on this if the value was
;-- out of this range
;-- version 3 returns error but this is still here because it
;-- need to be handled somehow anyway
if numval(ds.tape.r[ds.tape.to.use.s]) <=0 then
;-- display the error message
ds.error.u(
"Sorry, the base 10 logarithm can not be computed on a number less then or",
"equal to zero. Press any key to continue.")
else
;-- make the conversion
ds.tape.r[ds.tape.count.s] =
strval(log(numval(ds.tape.r[ds.tape.to.use.s])))
;-- set the decimal array element
ds.set.decimal.u()
endif
;-- takes another proc
case ds.math.choice.a = "POW " :
ds.math.pow.u()
style
;-- so does this one
case ds.math.choice.a = "ROUND " :
style reverse
ds.math.round.u()
style
;-- get square man!
case ds.math.choice.a = "SQRT " :
;-- you can only do a square root on a positive number
;-- version 2 hangs with this one
if numval(ds.tape.r[ds.tape.to.use.s]) >= 0 then
ds.tape.r[ds.tape.count.s] =
strval(sqrt(numval(ds.tape.r[ds.tape.to.use.s])))
ds.set.decimal.u()
else
ds.error.u(
"Sorry, you can not compute the Square Root of a negative number.",
;-- there's that variable I assigned way back in the beginning!
ds.press.it.a)
endif
endswitch
endproc
?? "." message memleft() writelib ds.aplib.a ds.math.proc.1.u
release procs ds.math.proc.1.u
;-------------------------------------------------------------------------------
; ds.math.mod.u()
;-------------------------------------------------------------------------------
; purpose: prompts the user for 2 values and computes the modulas of those
; numbers
proc ds.math.mod.u()
private
ds.dividend.n, ;-- the dividend
ds.divisor.n ;-- the divisor
;-- clear the top two lines
@ 1,0 clear eol
@ 0,0 clear eol
;-- turn the cursor on
cursor normal
;-- place a prompt
?? "Enter the dividend: "
;-- get a value
accept "n" to ds.dividend.n
;-- user left blank or pressed escape
if not isassigned(ds.dividend.n) or
isblank(ds.dividend.n) then
return
endif
;-- place another prompt on the next line
? " To be divided by: "
;-- get a value
accept "n" to ds.divisor.n
;-- user left blank or pressed escape
if not isassigned(ds.divisor.n) or
isblank(ds.divisor.n) then
return
endif
;-- make the conversion
ds.tape.r[ds.tape.count.s] = mod(ds.dividend.n,ds.divisor.n)
;-- the following statement is necessary because paradox cannot properly handle
;-- mod(x,y) if either x or y are not whole numbers and the remainder is truly 0
;-- this problem has been been reported to borland
;-- this was true in version 2 however I haven't tested to see if it
;-- was corrected in version 3
if ds.tape.r[ds.tape.count.s] = ds.dividend.n then
;-- make it the string "0"
ds.tape.r[ds.tape.count.s] = "0"
;-- set this variable
ds.decimal.r[ds.tape.count.s] = false
else
;-- convert it to a string
ds.tape.r[ds.tape.count.s] = strval(ds.tape.r[ds.tape.count.s])
;-- set the decimal array
ds.set.decimal.u()
endif
endproc
?? "." message memleft() writelib ds.aplib.a ds.math.mod.u
release procs ds.math.mod.u
;-------------------------------------------------------------------------------
; ds.math.pow.u()
;-------------------------------------------------------------------------------
; purpose: converts the current entry to a specified power
; this math function caused me the most trouble
; most of the math functions in version 2 would crash, ie. lock up the
; computer when they were out of range even though the manual
; stated the returned value would be "Error"
; through a lot of testing, I determined the acceptable ranges for
; all of the math functions accept this one
; I could find no pattern or relationship that I could test that
; would not lock up the computer
; if you convert this script to run under version 2 this procedure may
; cause your computer to lock up and you will have to reboot
proc ds.math.pow.u()
private
ds.power.n ;-- the power to raise the last value to
;-- clear the top 2 lines
@ 01,00 clear eol
@ 00,00 clear eol
;-- set the style
style reverse
;-- enter a prompt
?? "Enter the power: "
;-- turn the cursor on
cursor normal
;-- get a value
accept "n" to ds.power.n
;== user pressed escape or left the entry blank
if not retval or
isblank(ds.power.n) then
return
endif
;-- do_it!
ds.tape.r[ds.tape.count.s] =
strval(pow(numval(ds.tape.r[ds.tape.to.use.s]),ds.power.n))
;-- set the decimal array element
ds.set.decimal.u()
if lower( ds.tape.r[ds.tape.count.s] ) = "error" then
ds.error.u(
"Sorry, the computer could not handle the requested calculation.",
;-- there's that global variable again!
ds.press.it.a )
endif
endproc
?? "." message memleft() writelib ds.aplib.a ds.math.pow.u
release procs ds.math.pow.u
;-------------------------------------------------------------------------------
; ds.math.round.u()
;-------------------------------------------------------------------------------
; purpose: rounds a number to a given number of places
proc ds.math.round.u()
private
ds.round.s ;-- the number of places to round to
;-- clear the top 2 lines
@ 1,0 clear eol
@ 0,0 clear eol
;-- place a prompt
?? "Enter a whole number between -15 and 15 to round the last entry to: "
;-- turn the cursor on
cursor normal
;-- get a legal value
;-- you can round to a negative number of places, ie the nearest thousand
accept "s" min -15 max 15 picture "[-]#[#]" to ds.round.s
;-- if assigned and not blank, round the value
if isassigned(ds.round.s) and
not isblank(ds.round.s) then
;-- the round function sometimes returns the wrong value
;-- so decimals need to be adjusted a bit to make it
;-- work correctly
if ds.round.s > 0 then
ds.tape.r[ds.tape.to.use.s] =
strval(
numval(ds.tape.r[ds.tape.to.use.s]) +
numval("." + fill(0,ds.round.s+1) + "1")
)
endif
;-- round it the specified number of places
ds.tape.r[ds.tape.count.s] =
strval(round(numval(ds.tape.r[ds.tape.to.use.s]),ds.round.s))
;-- set the decimal array element
ds.set.decimal.u()
endif
endproc
?? "." message memleft() writelib ds.aplib.a ds.math.round.u
release procs ds.math.round.u
;-------------------------------------------------------------------------------
; ds.set.decimal.u()
;-------------------------------------------------------------------------------
; purpose: sets the array element ds.decimal.r to true or false by searching
; the string for a period
; this originally attempted to compare the value of the number
; against the integer of the number to perform this function
; however, doing this on a large number took as long a 15 seconds
; on a 25mhz 386
; the current routine runs very fast however
proc ds.set.decimal.u()
;-- search for a period in the string
if search(".",ds.tape.r[ds.tape.count.s]) = 0 then
ds.decimal.r[ds.tape.count.s] = false
else
ds.decimal.r[ds.tape.count.s] = true
endif
endproc
?? "." message memleft() writelib ds.aplib.a ds.set.decimal.u
release procs ds.set.decimal.u
;-------------------------------------------------------------------------------
; ds.menu.u()
;-------------------------------------------------------------------------------
; purpose: displays the menu when [f10] is pressed - a special key
proc ds.menu.u()
private
ds.menu.choice.a, ;-- private menu choice variable
errorproc, ;-- private errorproc used for the call to ds.custom.v()
autolib, ;-- autolib is private here as it is re-defined to
;-- to attempt to read the procedure ds.custom.v
ds.not.defined.a ;-- returned value of the errorproc that indicates
;-- if the procedure existed or not
;-- re-set the autolib because it is declared
;-- as a private variable in this procedure
autolib = ds.aplib.a
;-- initial setting of this variable
ds.rebuild.l = false
;-- display the choices
showmenu
"Mathematical " : " Perform Mathematical functions.",
"Trigonometry " : " Perform Trigonometry calculations.",
"Financial " : " Perform Financial calculations.",
"Custom " : " Perform Custom Designed calculations.",
"Esc " : " Return to what you were doing before pressing [F10]."
to ds.menu.choice.a
switch
;-- call the proper procedure
case ds.menu.choice.a = "Mathematical " :
ds.math.u()
;-- call up the trig procedures
case ds.menu.choice.a = "Trigonometry " :
;-- assign retval for the following while loop
retval = "dsloop"
;-- until ds.trig.a returns a value other then
;-- "dsloop" then call the procedure again
while (lower(retval) = "dsloop")
ds.trig.a()
endwhile
;-- reset this variable, the calculator need to be
;-- re-painted on the screen
ds.rebuild.l = true
;-- call the financial procedure
case ds.menu.choice.a = "Financial " :
ds.finance.u()
;-- this was fun, the procedure and/or the library
;-- may not exist at all
case ds.menu.choice.a = "Custom " :
;-- bottom line re-appearer
canvas off
message ""
@ 22,78 clear eol
canvas on
;-- define the errorproc
;-- I parted from the normal pbe notation here as
;-- ds.oops.1 always returns a 1 - to step over
;-- the offending command
errorproc = "ds.oops.1"
;-- read it into memory
readlib ds.aplib.a ds.oops.1
;-- reset the autolib to the custom library name
;-- passed in the parameter to ds.calc.v
;-- I could try a isfile on the library but this works
;-- so why fix it
autolib = ds.custom.lib.a
;-- attempt to call this procedure from
;-- the custom library
;-- if it does not exist, then ds.oops.1 returns 1 to step
;-- over this call
ds.custom.v()
;-- reset the errorproc
errorproc = ""
;-- reset the autolib
autolib = ds.aplib.a
;-- ds.not.defined.a would have been assigned in the errorproc
;-- if it was called
;-- make an assignment if it isn't for the next if statement
if not isassigned(ds.not.defined.a) then
ds.not.defined.a = "ok"
endif
;-- if the error proc wasn't called, assure that the returned value
;-- from ds,custom.v was really a numeric value
if lower(ds.not.defined.a) <> "noproc" then
if lower(numval(strval(retval))) <> "error" then
;-- okay, make the assignment to the tape entry
ds.tape.r[ds.tape.count.s] = strval(retval)
;-- set the ds.decimal.r array element
ds.set.decimal.u()
endif
;-- set the variable to re-paint the canvas
ds.rebuild.l = true
endif
endswitch
;-- bottom line re-appearer
if lower(ds.menu.choice.a) <> "trigonometry " then
cursor off
message ""
@ 22,78 clear eol
canvas on
else
cursor off
message ""
@ 22,78 ?? " ║"
canvas on
endif
;-- replace the main prompt message
ds.main.prompt.u()
return
endproc
?? "." message memleft() writelib ds.aplib.a ds.menu.u
release procs ds.menu.u
;-------------------------------------------------------------------------------
; ds.finance.u()
;-------------------------------------------------------------------------------
; purpose: displays the financial menu choices
proc ds.finance.u()
private
ds.finance.choice.a ;-- menu choice variable
;-- bottom line re-appearer
canvas off
message ""
@ 22,78 clear eol
canvas on
;-- display menu choices
showmenu
"Future Value " : " The future value of a series of equal payments.",
"Periodic Payment " : " The periodic payment to pay off a loan.",
"Present Value " : " The present value of a series of equal payments.",
"Esc " : " Return to what you were doing before pressing [F10]."
to ds.finance.choice.a
;-- bottom line re-appearer
canvas off
message ""
@ 22,78 clear eol
canvas on
style reverse
switch
;-- call the appropriate procedure passing the
;-- menu choice variable
case ds.finance.choice.a = "Future Value " or
ds.finance.choice.a = "Present Value " :
ds.finance.values.l(ds.finance.choice.a)
;-- call the appropriate procedure
case ds.finance.choice.a = "Periodic Payment " :
ds.finance.payment.l()
endswitch
style
;-- user opted to quit so set retval for the
;-- next if statement
if ds.finance.choice.a = "Esc" or
ds.finance.choice.a = "Esc " then
retval = false
endif
;-- retval set above or from the called procedures
;-- if required, call the procedure used to set the
;-- tape decimal array element
if retval then
ds.set.decimal.u()
endif
endproc
?? "." message memleft() writelib ds.aplib.a ds.finance.u
release procs ds.finance.u
;-------------------------------------------------------------------------------
; ds.finance.values.l(ds.finance.choice.a)
;-------------------------------------------------------------------------------
; purpose: computes the future or present values of payments, interest rates and
; periods
proc ds.finance.values.l(
ds.finance.choice.a) ;-- which function to use
private
ds.payment.c, ;-- payment amount used in the computation
ds.interest.n, ;-- interest amount used in the computation
ds.periods.s ;-- number of monthly periods used in the computation
;-- clear the top 2 lines
@ 01,00 clear eol
@ 00,00 clear eol
;-- turn the cursor on
cursor normal
;-- place a prompt on the screen
?? "Enter the periodic payment: "
;-- get a dollar value for the payment
accept "$"
;-- min of 1 please
min 1
to ds.payment.c
;-- user pressed escape or left the entry blank
if not isassigned(ds.payment.c) or
isblank(ds.payment.c) then
return false
endif
;-- reposition the cursor
@ 00,00
;-- place the next prompt on the screen
?? "Enter the yearly interest rate {##.###}: "
;-- get a numeric value
accept "n"
;-- I like this one - now if I can get the bank to agree!
min .001
;-- nasty loan shark interest rate!
max 99.999
;-- give them a picture to help them
picture "{[#][#].[#][#][#],[#].[#][#][#],[#]}"
to ds.interest.n
;-- user pressed escape or left the entry blank
if not isassigned(ds.interest.n) or
isblank(ds.interest.n) then
return false
endif
;-- convert it to the interest per period
;-- 12 = months / 100 to convert to the decimal of the percentage
ds.interest.n = ds.interest.n / 12 / 100
;-- reposition the cursor
@ 00,00
;-- place the next prompt on the screen
?? "Enter the number of periods (in months): "
;-- get a short numeric value
accept "s"
;-- my kind of payment!
min 1
;-- okay, a max of 85 years
;-- sometimes fv(..) and pv(..) will blow up on large numbers
;-- as they use the pow() function somehow.
max 1020
to ds.periods.s
;-- user pressed escape or left the entry blank
if not isassigned(ds.periods.s) or
isblank(ds.periods.s) then
return false
endif
;-- perform the proper function for the selected choice
if lower(ds.finance.choice.a) = "future value " then
ds.tape.r[ds.tape.count.s] =
strval(fv(ds.payment.c,ds.interest.n,ds.periods.s))
else
ds.tape.r[ds.tape.count.s] =
strval(pv(ds.payment.c,ds.interest.n,ds.periods.s))
endif
;-- inform the calling procedure that this procedure
;-- completed successfully
return true
endproc
?? "." message memleft() writelib ds.aplib.a ds.finance.values.l
release procs ds.finance.values.l
;-------------------------------------------------------------------------------
; ds.finance.payment.l()
;-------------------------------------------------------------------------------
; purpose: computes the payment on a given loan for a given interest for a
; given number of months
proc ds.finance.payment.l()
private
ds.principal.c, ;-- principal amount used in the computation
ds.interest.n, ;-- interest amount used in the computation
ds.periods.s ;-- number of monthly periods used in the computation
;-- clear the top 2 lines
@ 01,00 clear eol
@ 00,00 clear eol
;-- turn the cursor on
cursor normal
;-- place the next prompt on the screen
?? "Enter the loan principal payment: "
;-- get a dollar value for the principal
accept "$"
;-- my kind of loan!
min 1 to
ds.principal.c
;-- user pressed escape or left the entry blank
if not isassigned(ds.principal.c) or
isblank(ds.principal.c) then
return false
endif
;-- reposition the cursor
@ 00,00
;-- place the next prompt on the screen
?? "Enter the yearly interest rate {##.###}: "
;-- get a numeric value
accept "n"
;-- I like this one - now if I can get the bank to agree!
min .001
;-- nasty loan shark interest rate!
max 99.999
;-- give them a picture to help them
picture "{[#][#].[#][#][#],[#].[#][#][#],[#]}"
to ds.interest.n
;-- user pressed escape or left the entry blank
if not isassigned(ds.interest.n) or
isblank(ds.interest.n) then
return false
endif
;-- convert it to the interest per period
;-- 12 = months / 100 to convert to the decimal of the percentage
ds.interest.n = ds.interest.n / 12 / 100
;-- reposition the cursor
@ 00,00
;-- place the next prompt on the screen
?? "Enter the number of periods (in months): "
;-- get a short numeric value
accept "s"
;-- my kind of loan!
min 1
;-- okay, a max of 85 years
;-- sometimes pmt(..) will blow up on large numbers
;-- as it uses the pow() function somehow.
max 1020
to ds.periods.s
;-- user pressed escape or left the entry blank
if not isassigned(ds.periods.s) or
isblank(ds.periods.s) then
return false
endif
;-- perform the proper function
ds.tape.r[ds.tape.count.s] =
strval(pmt(ds.principal.c,ds.interest.n,ds.periods.s))
;-- inform the calling procedure that this procedure
;-- completed successfully
return true
endproc
?? "." message memleft() writelib ds.aplib.a ds.finance.payment.l
release procs ds.finance.payment.l
;-------------------------------------------------------------------------------
; ds.main.prompt.u()
;-------------------------------------------------------------------------------
; purpose: displays the main prompt on the top 2 lines of the screen
proc ds.main.prompt.u()
@ 00,00
?? format("w80,ac",
"Press [F10] for special functions and formulas, [F1] for help.")
@ 01,00
?? format("w80,ac",
"Press [Esc] to return to what you were doing.")
endproc
?? "." message memleft() writelib ds.aplib.a ds.main.prompt.u
release procs ds.main.prompt.u
;-------------------------------------------------------------------------------
; ds.trig.a()
;-------------------------------------------------------------------------------
; purpose: main procedure for the trig module of ds.calc.v
proc ds.trig.a()
private
ds.trig.choice.s, ;-- the highlight menu choice selected by the
;-- user from the choices in the menu box on the
;-- right hand side of the screen
ds.movement.key.s, ;-- the movement key pressed to move the
;-- highlighted menu bar
ds.trig.choice.was.s, ;-- what the previous highlighted menu choice
;-- was so that it can be turned off
ds.side.a.n, ;-- variable that holds the length of side a
;-- of the triangle
ds.side.b.n, ;-- " side b
ds.side.c.n, ;-- " side c
ds.degrees.a.s, ;-- variable that holds the angle in degrees of
;-- angle a of the triangle
ds.degrees.b.s, ;-- " angle b
ds.degrees.c.s, ;-- " angle c
ds.minutes.a.s, ;-- variable that holds the angles' minutes of
;-- angle a of the triangle
ds.minutes.b.s, ;-- " angle b
ds.minutes.c.s, ;-- " angle c
ds.seconds.a.s, ;-- variable that holds the angles' seconds of
;-- angle a of the triangle
ds.seconds.b.s, ;-- " angle b
ds.seconds.c.s, ;-- " angle c
ds.radians.a.s, ;-- variable that holds the angles' radian value of
;-- angle a of the triangle
ds.radians.b.s, ;-- " angle b
ds.radians.c.s, ;-- " angle c
ds.precision.choice.s, ;-- variable that is used when angles need to be
;-- entered to determine what need to be accepted
;-- from the user, ie. degrees, degrees & minutes,
;-- degrees, minutes & seconds or radians
ds.periphery.n, ;-- the variable which holds the calculated
;-- periphery of the triangle
ds.area.n, ;-- the variable which holds the calculated
;-- area of the triangle
ds.trig.loop.getchar.s ;-- variable assigned with getchar() that the user
;-- presses to indicate what he wishes to do next
;-- initialize the variable
ds.trig.choice.s = 1
;-- paint the trig screen
ds.trig.screen.u()
;-- stay here till the program says you can leave!
while true
;-- get a keystroke from the user
ds.movement.key.s = getchar()
;-- now determine what the user pressed
switch
;-- pressed escape, let me out of here!
case ds.movement.key.s = 27 :
;-- return escape to the calling procedure
return ds.movement.key.s
;-- user made a selection [enter]
case ds.movement.key.s = 13 :
;-- leave the while true loop to do some other processing
quitloop
otherwise :
;-- move the highlight menu bar per the key pressed
ds.trig.selection.l()
;-- non legal keys make me want to beep!
if not retval then
beep
endif
endswitch
endwhile
;-- user pressed enter, selecting a menu choice
;-- to get this far
;-- for these choices, we need to find out how the user
;-- wants to enter the angles
if ds.trig.choice.s > 3 and
ds.trig.choice.s < 13 then
;-- call the procedure that sets the variable
;-- based on user input
ds.set.trig.precision.l()
else
;-- this variable = 0 when no angles,
;-- all the sides are entered by the user
ds.precision.choice.s = 0
retval = true
endif
;-- user escaped out of ds.set.trig.precision.l()
;-- and it returned false
if not retval then
;-- this indicates to the calling procedure
;-- to return to this procedure again
;-- this is necessary to clear all of the private variables
;-- as private variables can not be released except by
;-- exiting the procedure that declared them as private
;-- otherwise, values in various variables may be left
;-- from another "loop" and would be used when they
;-- don't apply
return "dsloop"
endif
;-- set the style
style reverse
;-- get the info from the user
switch
;-- gets the lengths of the sides, no angles
;-- required per selected choice
case ds.precision.choice.s = 0 :
;-- call the procedure that gets the lengths of sides
ds.trig.get.sides.l(ds.trig.choice.s)
;-- user choose to enter the angles in degrees
;-- and/or minutes and/or seconds
case ds.precision.choice.s > 0 and
ds.precision.choice.s < 4 :
;-- this procedure gets this info
ds.trig.get.angles.dms.l(ds.trig.choice.s)
;-- gets the angles in radians
case ds.precision.choice.s = 4 :
;-- this procedure gets this info
ds.trig.get.angles.radians.l(ds.trig.choice.s)
endswitch
;-- turn style back to normal mode
style
;-- and turn the cursor off
cursor off
;-- user quit out of one of the previous procedures,
;-- this call clears the variables and starts this procedure again
if not retval then
return "dsloop"
endif
;-- converts known angles in degrees and.or minutes
;-- and/or seconds to radians
;-- all of the trig functions require radians
if ds.precision.choice.s >0 and
ds.precision.choice.s <4 then
ds.convert.degrees.u()
endif
;-- user supplied two angles
if ds.trig.choice.s = 10 then
;-- and they gave me some bum info!
if (round((ds.radians.a.s + ds.radians.b.s),15) >= 3.141592653589) then
ds.error.u(
"The angles supplied for A and B can not be greater" +
" than or equal to 180°!",
ds.press.it.a)
return "dsloop"
endif
endif
;-- based on the fact we know two angles
;-- based on the choice selected, compute the third
;-- remaining angle
if ds.trig.choice.s > 3 and
ds.trig.choice.s < 11 then
ds.compute.third.angle.u()
endif
;-- now based on the choice (and the known values),
;-- select the proper set of calculations needed
;-- to compute the unknowns
switch
case ds.trig.choice.s > 0 and
ds.trig.choice.s < 4 :
ds.trig.calc.set.1.u()
case ds.trig.choice.s > 3 and
ds.trig.choice.s < 10 :
ds.trig.calc.set.2.u()
case ds.trig.choice.s = 10 :
ds.trig.calc.set.3.u()
case ds.trig.choice.s = 11 :
ds.trig.calc.set.4.u()
case ds.trig.choice.s = 12 :
ds.trig.calc.set.5.u()
otherwise :
ds.trig.calc.set.6.u()
endswitch
;-- at this point, all of the angles are known in
;-- radians, so compute the unknown degrees, minutes,
;-- and seconds
ds.trig.convert.radians.u()
;-- now the periphery can ge calculated based on
;-- the total of the three sides
ds.periphery.n = ds.side.a.n + ds.side.b.n + ds.side.c.n
;-- and finally display the answer
ds.trig.display.answer.u()
;-- set the style for the prompt
style reverse
;-- now find out what the user wants to do next
@ 00,00
?? format("w80,ac","Press any key to clear the work" +
" space and re-calculate another triangle.")
@ 01,00
?? format("w80,ac","Press [Esc] to return to the calculator.")
;-- reset to normal style
style
;-- and get a keystroke from the user
ds.trig.loop.getchar.s = getchar()
;-- user wants to do another
if ds.trig.loop.getchar.s <> 27 then
return "dsloop"
else
;-- or display a menu to determine a value
;-- to be returned to the calculator window
ds.trig.return.menu.u()
;-- don't come back to this procedure
return "escape"
endif
endproc
?? "." message memleft() writelib ds.aplib.a ds.trig.a
release procs ds.trig.a
;-------------------------------------------------------------------------------
; ds.trig.return.menu.u()
;-------------------------------------------------------------------------------
; purpose: displays a menu of choices upon leaving the trig module to determine
; if the user wishes to return a value to the calculator window
proc ds.trig.return.menu.u()
private
ds.trig.return.choice.a ;-- menu choice selection
;-- stay in the loop until a selection is
;-- made that allows leaving the loop
while true
;-- display menu choices
showmenu
"Side " : " Return the value of a side to the calculator.",
"Radian " : " Return the value of an angle to the calculator.",
"Periphery " : " Return the value of the periphery of" +
" the triangle to the calculator.",
"Area " : " Return the value of the area of the " +
"triangle to the calculator.",
"Esc " : " Return to the calculator with out a value."
to ds.trig.return.choice.a
;-- bottom line restorer
canvas off
message ""
@ 22,78 ?? " ║"
canvas on
;-- evaluate the selected choice
switch
;-- if side, another menu
case ds.trig.return.choice.a = "Side " :
;-- get which side to return
showmenu
"Side a " : " Return side \"a\".",
"Side b " : " Return side \"b\".",
"Side c " : " Return side \"c\".",
"Esc " : " Return to the previous menu."
to ds.trig.return.choice.a
;-- evaluate the choice
switch
;-- go back to the previous menu
case ds.trig.return.choice.a = "Esc" or
ds.trig.return.choice.a = "Esc " :
;-- bottom line restorer
canvas off
message ""
@ 22,78 ?? " ║"
canvas on
loop
;-- user choose side a
case ds.trig.return.choice.a = "Side a " :
;-- make assignment to the tape variable
ds.tape.r[ds.tape.count.s] = strval(ds.side.a.n)
;-- set the decimal array
ds.set.decimal.u()
;-- user choose side b
case ds.trig.return.choice.a = "Side b " :
;-- make assignment to the tape variable
ds.tape.r[ds.tape.count.s] = strval(ds.side.b.n)
;-- set the decimal array
ds.set.decimal.u()
;-- user choose side c
case ds.trig.return.choice.a = "Side c " :
;-- make assignment to the tape variable
ds.tape.r[ds.tape.count.s] = strval(ds.side.c.n)
;-- set the decimal array
ds.set.decimal.u()
endswitch
;-- if radian, another menu
case ds.trig.return.choice.a = "Radian " :
;-- get which radian to return
showmenu
"Radian of A " : " Return the radian of angle \"A\".",
"Radian of B " : " Return the radian of angle \"B\".",
"Radian of C " : " Return the radian of angle \"C\".",
"Esc " : " Return to the previous menu."
to ds.trig.return.choice.a
switch
;-- go back to the previous menu
case ds.trig.return.choice.a = "Esc" or
ds.trig.return.choice.a = "Esc " :
;-- bottom line restorer
canvas off
message ""
@ 22,78 ?? " ║"
canvas on
loop
;-- user choose radian a
case ds.trig.return.choice.a = "Radian of A " :
;-- make assignment to the tape variable
ds.tape.r[ds.tape.count.s] = strval(ds.radians.a.s)
;-- set the decimal array
ds.set.decimal.u()
;-- user choose radian b
case ds.trig.return.choice.a = "Radian of B " :
;-- make assignment to the tape variable
ds.tape.r[ds.tape.count.s] = strval(ds.radians.b.s)
;-- set the decimal array
ds.set.decimal.u()
;-- user choose radian c
case ds.trig.return.choice.a = "Radian of C " :
;-- make assignment to the tape variable
ds.tape.r[ds.tape.count.s] = strval(ds.radians.c.s)
;-- set the decimal array
ds.set.decimal.u()
endswitch
;-- user choose periphery
case ds.trig.return.choice.a = "Periphery " :
;-- make assignment to the tape variable
ds.tape.r[ds.tape.count.s] = strval(ds.periphery.n)
;-- set the decimal array
ds.set.decimal.u()
;-- user choose area
case ds.trig.return.choice.a = "Area " :
;-- make assignment to the tape variable
ds.tape.r[ds.tape.count.s] = strval(ds.area.n)
;-- set the decimal array
ds.set.decimal.u()
endswitch
;-- back to where we came from
return
endwhile
endproc
?? "." message memleft() writelib ds.aplib.a ds.trig.return.menu.u
release procs ds.trig.return.menu.u
;-------------------------------------------------------------------------------
; ds.trig.screen.u()
;-------------------------------------------------------------------------------
; purpose: displays the trig screen
proc ds.trig.screen.u()
;-- inform the user something is happening
@ 00,00 clear eol ?? "Working"
style blink ?? "....."
@ 01,00 clear eol style
;-- turn the canvas off
canvas off
;-- display the trig prompt lines
@ 00,00 ?? format("w80,ac",
"Use the cursor keys to select the appropriate" +
" menu choice to input the known")
@ 01,00 ?? format("w80,ac",
"values of either a right or oblique angle" +
" triangle and press [Enter].")
;-- place the screen on the canvas
text
╔══════════════════════════════════════════════════════════════════════════════╗
║ ║
║ Angle C = ╔═════════════════╦══════════════════╗ ║
║ Radians = ║ Right Angle ║ Oblique Angle ║ ║
║ ╠═════════════════╬══════════════════╣ ║
║ ║ Angle A = 90° ║ Known values: ║ ║
║ ║ Known values: ║ Side a with ║ ║
║ ║ ║ Angles A & B ║ ║
║ Side a = ║ Sides a & c ║ ║ ║
║ ║ Sides b & c ║ Sides a & b with ║ ║
║ ║ Side a; Angle B ║ Angle C ║ ║
║ ║ Side a; Angle C ║ ║ ║
║ Side b = ║ Side b; Angle B ║ Sides a & b with ║ ║
║ ║ Side b; Angle C ║ Angle A ║ ║
║ ║ Side c; Angle B ║ ║ ║
║ ║ Side c; Angle C ║ Sides a, b & c ║ ║
║ ╚═════════════════╩══════════════════╝ ║
║ Angle A = ║
║ Radians = Angle B = ║
║ Radians = ║
║ Side c = Periphery = ║
║ Area = ║
╚═══════════════════ Press [Esc] to return to the calculator ══════════════════╝
endtext
;-- highlight the default menu selection
style reverse
@ 09,42 ?? "Sides a & b "
;-- style back to normal
style
;-- turn the canvas back on
canvas on
endproc
?? "." message memleft() writelib ds.aplib.a ds.trig.screen.u
release procs ds.trig.screen.u
;-------------------------------------------------------------------------------
; ds.trig.selection.l()
;-------------------------------------------------------------------------------
; purpose: determines the key pressed and moves the highlighted menu choice
; accordingly
proc ds.trig.selection.l()
;-- only accept the four movement keys and
;-- home and end
if ds.movement.key.s > -71 or
ds.movement.key.s < -80 or
ds.movement.key.s = -73 or
ds.movement.key.s = -74 or
ds.movement.key.s = -76 or
ds.movement.key.s = -78 then
return false
endif
;-- set the was variable to turn the previous
;-- highlighted menu selection off
ds.trig.choice.was.s = ds.trig.choice.s
;-- evaluate the movement required
switch
;-- user pressed home
case ds.movement.key.s = -71 :
;-- was already there
if ds.trig.choice.s = 1 then
beep
return true
else
;-- set the position to be highlighted
ds.trig.choice.s = 1
endif
;-- user pressed end
case ds.movement.key.s = -79 :
;-- was already there
if ds.trig.choice.s = 13 then
beep
return true
else
;-- set the position to be highlighted
ds.trig.choice.s = 13
endif
;-- user pressed up or left
case ds.movement.key.s = -72 or
ds.movement.key.s = -75 :
;-- adjust the position down one number
ds.trig.choice.s = ds.trig.choice.s - 1
;-- oops, went to far, reset to the last choice
if ds.trig.choice.s = 0 then
ds.trig.choice.s = 13
endif
;-- user pressed down or right
case ds.movement.key.s = -77 or
ds.movement.key.s = -80 :
;-- adjust the position up one number
ds.trig.choice.s = ds.trig.choice.s + 1
;-- oops, went to far, reset to the first choice
if ds.trig.choice.s = 14 then
ds.trig.choice.s = 1
endif
endswitch
;-- set the highlight style
style reverse
;-- toggle the new position on
ds.trig.choice.toggle.u(ds.trig.choice.s)
;-- normal style
style
;-- toggle the old position off
ds.trig.choice.toggle.u(ds.trig.choice.was.s)
return true
endproc
?? "." message memleft() writelib ds.aplib.a ds.trig.selection.l
release procs ds.trig.selection.l
;-------------------------------------------------------------------------------
; ds.trig.choice.toggle.u()
;-------------------------------------------------------------------------------
; purpose: toggles the menu choice on and off depending on the key pressed
proc ds.trig.choice.toggle.u(
ds.trig.choice.s) ;-- passed parameter for the following
;-- case statement
;-- evaluate where to update the screen
switch
case ds.trig.choice.s = 1 :
@ 09,42 ?? "Sides a & b "
case ds.trig.choice.s = 2 :
@ 10,42 ?? "Sides a & c "
case ds.trig.choice.s = 3 :
@ 11,42 ?? "Sides b & c "
case ds.trig.choice.s = 4 :
@ 12,42 ?? "Side a; Angle B"
case ds.trig.choice.s = 5 :
@ 13,42 ?? "Side a; Angle C"
case ds.trig.choice.s = 6 :
@ 14,42 ?? "Side b; Angle B"
case ds.trig.choice.s = 7 :
@ 15,42 ?? "Side b; Angle C"
case ds.trig.choice.s = 8 :
@ 16,42 ?? "Side c; Angle B"
case ds.trig.choice.s = 9 :
@ 17,42 ?? "Side c; Angle C"
case ds.trig.choice.s = 10 :
@ 08,60 ?? "Side a with "
@ 09,60 ?? " Angles A & B "
case ds.trig.choice.s = 11 :
@ 11,60 ?? "Sides a & b with"
@ 12,60 ?? " Angle C "
case ds.trig.choice.s = 12 :
@ 14,60 ?? "Sides a & b with"
@ 15,60 ?? " Angle A "
case ds.trig.choice.s = 13 :
@ 17,60 ?? "Sides a, b & c "
endswitch
endproc
?? "." message memleft() writelib ds.aplib.a ds.trig.choice.toggle.u
release procs ds.trig.choice.toggle.u
;-------------------------------------------------------------------------------
; ds.set.trig.precision.l()
;-------------------------------------------------------------------------------
; purpose: when angles need to be entered to do the trig, this procedure
; gets from the user what he/she will enter so that other procedures
; know how many prompts and what to accept for input of that data
proc ds.set.trig.precision.l()
;-- turn the cursor on
cursor normal
;-- highlight the following
style reverse
;-- place the prompt on the screen
@ 00,00 ?? format("w80,al",
"Will you be entering Angles in 1.(Degrees only)," +
" 2.(Degrees and Minutes),")
@ 01,00 ?? format("w80,al",
"3.(Degrees, Minutes and Seconds) or in 4.(Radians)? " +
"Enter Choice:")
;-- place the cursor
@ 01,66
;-- get the users selection
accept "s"
picture"{1,2,3,4}"
to ds.precision.choice.s
;-- turn the cursor off
cursor off
;-- reset to normal style
style
;-- user pressed esc or left the prompt blank
if not isassigned(ds.precision.choice.s) or
isblank(ds.precision.choice.s) then
;-- return false to cancel
return false
endif
;-- return true to continue
return true
endproc
?? "." message memleft() writelib ds.aplib.a ds.set.trig.precision.l
release procs ds.set.trig.precision.l
;-------------------------------------------------------------------------------
; ds.trig.get.sides.l(ds.trig.choice.s)
;-------------------------------------------------------------------------------
; purpose: this procedure gets the sides required of the triangle
proc ds.trig.get.sides.l(
ds.trig.choice.s) ;-- this value determines which
;--accept statements to use
;-- clear the top 2 lines
@ 01,00 clear eol
@ 00,00 clear eol
;-- turn the cursor on
cursor normal
;-- these menu choices use this accept statement
if ds.trig.choice.s < 3 or
ds.trig.choice.s = 13 then
;-- the prompt
?? "Enter the length of side a: "
;-- get the info
accept "n"
;-- kind of small but where to draw the line?
min .00000000001
;-- well, they could still press esc
required
to ds.side.a.n
;-- did they press esc?
if not isassigned(ds.side.a.n) then
return false
endif
@ 00,00
endif
;-- and these menu choices use this accept statement
if ds.trig.choice.s = 1 or
ds.trig.choice.s = 3 or
ds.trig.choice.s = 13 then
;-- the prompt
?? "Enter the length of side b: "
;-- get the info
accept "n"
;-- kind of small but where to draw the line?
min .00000000001
;-- well, they could still press esc
required
to ds.side.b.n
;-- did they press esc?
if not isassigned(ds.side.b.n) then
return false
endif
@ 00,00
endif
;-- and these menu choices use this accept statement
if ds.trig.choice.s = 2 or
ds.trig.choice.s = 3 or
ds.trig.choice.s = 13 then
;-- the prompt
?? "Enter the length of side c: "
;-- get the info
accept "n"
;-- kind of small but where to draw the line?
min .00000000001
;-- well, they could still press esc
required
to ds.side.c.n
;-- did they press esc?
if not isassigned(ds.side.c.n) then
return false
endif
endif
;-- some error trapping here
if ds.trig.choice.s <> 13 then
;-- side a was assigned so compare it to the other
;-- known value and do some error checking
;-- if the error check is tripped, inform the user what
;-- the error was
if isassigned(ds.side.a.n) then
switch
case isassigned(ds.side.b.n) :
if ds.side.b.n >= ds.side.a.n then
ds.error.u(
"The length of side b can not be greater than or" +
" equal to side a!",
ds.press.it.a)
return false
endif
case isassigned(ds.side.c.n) :
if ds.side.c.n >= ds.side.a.n then
ds.error.u("The length of side c can not be greater" +
" than or equal to side a!",
ds.press.it.a)
return false
endif
endswitch
endif
else
;-- all three sides were entered, so check if the sides can
;-- intersect into a triangle
if (round(ds.side.a.n,15) >= round((ds.side.b.n + ds.side.c.n),15)) or
(round(ds.side.b.n,15) >= round((ds.side.a.n + ds.side.c.n),15)) or
(round(ds.side.c.n,15) >= round((ds.side.a.n + ds.side.b.n),15)) then
ds.error.u(
"The length of any 1 side can not be greater" +
" than or equal to the other 2 sides!",
ds.press.it.a)
return false
endif
endif
;-- passed the test
return true
endproc
?? "." message memleft() writelib ds.aplib.a ds.trig.get.sides.l
release procs ds.trig.get.sides.l
;-------------------------------------------------------------------------------
; ds.trig.get.angles.dms.l(ds.trig.choice.s)
;-------------------------------------------------------------------------------
; purpose: gets from the user the angles in degrees and/or minutes
; and/or seconds
proc ds.trig.get.angles.dms.l(
ds.trig.choice.s) ;-- which choice, which angles to get
private
ds.side.a, ;-- variable used in prompt of accept statement
ds.angle.a, ;-- variable used in prompt of accept statement
ds.min.a, ;-- variable used in prompt of accept statement
ds.sec.a, ;-- variable used in prompt of accept statement
ds.side.value.n, ;-- variable used in hold value of ds.side.(a,b or c).n
ds.degrees.value.s, ;-- variable used in hold value of
;-- ds.degrees.(a,b or c).s
ds.minutes.value.s, ;-- variable used in hold value of
;-- ds.minutes.(a,b or c).s
ds.seconds.value.s ;-- variable used in hold value of
;-- ds.seconds.(a,b or c).s
;-- clear the top 2 lines
@ 01,00 clear eol
@ 00,00 clear eol
;-- turn cursor on
cursor normal
;-- evaluate what info to accept based on the menu choice
switch
;-- call the following routine for these menu choices
case ds.trig.choice.s > 3 and
ds.trig.choice.s < 10 :
ds.trig.get.dms.1.l()
;-- based on the return value, continue or return
if not retval then
return false
endif
;-- and call the following routine for these menu choices
case ds.trig.choice.s = 10 :
ds.trig.get.dms.2.l()
;-- based on the return value, continue or return
if not retval then
return false
endif
;-- all other menu choices will be processed here
otherwise :
;-- the prompt
?? "Enter the length of side a: "
;-- get a value
accept "n"
min .00000000001
required
to ds.side.a.n
;-- user pressed escape or left the value blank
if not isassigned(ds.side.a.n) then
return false
endif
;-- move the cursor
@ 00,00
;-- the next prompt
?? "Enter the length of side b: "
;-- get a value
accept "n"
min .00000000001
required
to ds.side.b.n
;-- reposition the cursor
@ 00,00
switch
;-- user left the previous entry blank or pressed escape
case not isassigned(ds.side.b.n) :
return false
;-- this menu choice, make these assignments to these variables
case ds.trig.choice.s = 11 :
ds.angle.a = "C"
ds.min.a = "C"
ds.sec.a = "C"
;-- all other menu choices, make these assignments to these variables
otherwise :
ds.angle.a = "A"
ds.min.a = "A"
ds.sec.a = "A"
endswitch
;-- a prompt for degrees
?? "Enter the degrees of angle " + ds.angle.a + ": "
;-- get the info
accept "s"
min 0 max 179
required
to ds.degrees.value.s
;-- user escaped or left entry blank
if not isassigned(ds.degrees.value.s) then
return false
endif
;-- user wants to enter minutes
if ds.precision.choice.s > 1 then
;-- reposition the cursor
@ 00,00
;-- next prompt
?? "Enter the minutes of angle " + ds.min.a + ": "
;-- get the value
accept "s"
min 0
max 59
required
to ds.minutes.value.s
;-- was one really entered?
if not isassigned(ds.minutes.value.s) then
return false
endif
else
;-- make an assignment
ds.minutes.value.s = 0
endif
;-- user wants to enter seconds
if ds.precision.choice.s = 3 then
;-- reposition the cursor
@ 00,00
;-- next prompt
?? "Enter the seconds of angle " + ds.sec.a + ": "
;-- get the value
accept "s"
min 0
max 59
required
to ds.seconds.value.s
;-- was one really entered?
if not isassigned(ds.seconds.value.s) then
return false
endif
else
;-- make an assignment
ds.seconds.value.s = 0
endif
;-- error checking on entered values
switch
;-- user entered a bunch of zeros!
case ds.degrees.value.s +
ds.minutes.value.s +
ds.seconds.value.s = 0 :
ds.error.u(
"NO ANGLE ENTERED FOR ANGLE " + ds.angle.a + "!",
ds.press.it.a)
return false
;-- make the assignments if this menu choice was selected
case ds.trig.choice.s = 11 :
ds.degrees.c.s = ds.degrees.value.s
ds.minutes.c.s = ds.minutes.value.s
ds.seconds.c.s = ds.seconds.value.s
;-- all other menu choices processed here
otherwise:
ds.degrees.a.s = ds.degrees.value.s
ds.minutes.a.s = ds.minutes.value.s
ds.seconds.a.s = ds.seconds.value.s
endswitch
endswitch
;-- good input, true means continue
return true
endproc
?? "." message memleft() writelib ds.aplib.a ds.trig.get.angles.dms.l
release procs ds.trig.get.angles.dms.l
;-------------------------------------------------------------------------------
; ds.trig.get.dms.1.l()
;-------------------------------------------------------------------------------
; purpose: same as above accept this procedure was created to keep
; ds.trig.get.angles.dms.l's size down
proc ds.trig.get.dms.1.l()
;-- make variable assignments per the selected menu choice
switch
case ds.trig.choice.s = 4 :
ds.side.a = "a"
ds.angle.a = "B"
ds.min.a = "B"
ds.sec.a = "B"
case ds.trig.choice.s = 5 :
ds.side.a = "a"
ds.angle.a = "C"
ds.min.a = "C"
ds.sec.a = "C"
case ds.trig.choice.s = 6 :
ds.side.a = "b"
ds.angle.a = "B"
ds.min.a = "B"
ds.sec.a = "B"
case ds.trig.choice.s = 7 :
ds.side.a = "b"
ds.angle.a = "C"
ds.min.a = "C"
ds.sec.a = "C"
case ds.trig.choice.s = 8 :
ds.side.a = "c"
ds.angle.a = "B"
ds.min.a = "B"
ds.sec.a = "B"
case ds.trig.choice.s = 9 :
ds.side.a = "c"
ds.angle.a = "C"
ds.min.a = "C"
ds.sec.a = "C"
endswitch
?? "Enter the length of side " + ds.side.a + ": "
accept "n"
min .00000000001
required
to ds.side.value.n
if not isassigned(ds.side.value.n) then
return false
endif
@ 00,00
?? "Enter the degrees of angle " + ds.angle.a + ": "
accept "s"
min 0
max 89
required
to ds.degrees.value.s
if not isassigned(ds.degrees.value.s) then
return false
endif
if ds.precision.choice.s > 1 then
@ 00,00
?? "Enter the minutes of angle " + ds.min.a +": "
accept "s"
min 0
max 59
required
to ds.minutes.value.s
if not isassigned(ds.minutes.value.s) then
return false
endif
else
ds.minutes.value.s = 0
endif
if ds.precision.choice.s = 3 then
@ 00,00
?? "Enter the seconds of angle " + ds.sec.a + ": "
accept "s"
min 0
max 59
required
to ds.seconds.value.s
if not isassigned(ds.seconds.value.s) then
return false
endif
else
ds.seconds.value.s = 0
endif
switch
case ds.degrees.value.s + ds.minutes.value.s + ds.seconds.value.s = 0 :
ds.error.u(
"NO ANGLE ENTERED FOR ANGLE " + ds.angle.a + "!",
ds.press.it.a)
return false
case ds.trig.choice.s = 4 :
ds.side.a.n = ds.side.value.n
ds.degrees.b.s = ds.degrees.value.s
ds.minutes.b.s = ds.minutes.value.s
ds.seconds.b.s = ds.seconds.value.s
case ds.trig.choice.s = 5 :
ds.side.a.n = ds.side.value.n
ds.degrees.c.s = ds.degrees.value.s
ds.minutes.c.s = ds.minutes.value.s
ds.seconds.c.s = ds.seconds.value.s
case ds.trig.choice.s = 6 :
ds.side.b.n = ds.side.value.n
ds.degrees.b.s = ds.degrees.value.s
ds.minutes.b.s = ds.minutes.value.s
ds.seconds.b.s = ds.seconds.value.s
case ds.trig.choice.s = 7 :
ds.side.b.n = ds.side.value.n
ds.degrees.c.s = ds.degrees.value.s
ds.minutes.c.s = ds.minutes.value.s
ds.seconds.c.s = ds.seconds.value.s
case ds.trig.choice.s = 8 :
ds.side.c.n = ds.side.value.n
ds.degrees.b.s = ds.degrees.value.s
ds.minutes.b.s = ds.minutes.value.s
ds.seconds.b.s = ds.seconds.value.s
case ds.trig.choice.s = 9 :
ds.side.c.n = ds.side.value.n
ds.degrees.c.s = ds.degrees.value.s
ds.minutes.c.s = ds.minutes.value.s
ds.seconds.c.s = ds.seconds.value.s
endswitch
return true
endproc
?? "." message memleft() writelib ds.aplib.a ds.trig.get.dms.1.l
release procs ds.trig.get.dms.1.l
;-------------------------------------------------------------------------------
; ds.trig.get.dms.2.l()
;-------------------------------------------------------------------------------
; purpose: same as above accept this procedure was created to keep
; ds.trig.get.angles.dms.l's size down
proc ds.trig.get.dms.2.l()
?? "Enter the length of side a: "
accept "n"
min .00000000001
required
to ds.side.a.n
if not isassigned(ds.side.a.n) then
return false
endif
@ 00,00
?? "Enter the degrees of angle A: "
accept "s"
min 0
max 179
required
to ds.degrees.a.s
if not isassigned(ds.degrees.a.s) then
return false
endif
if ds.precision.choice.s > 1 then
@ 00,00
?? "Enter the minutes of angle A: "
accept "s"
min 0
max 59
required
to ds.minutes.a.s
if not isassigned(ds.minutes.a.s) then
return false
endif
else
ds.minutes.a.s = 0
endif
if ds.precision.choice.s = 3 then
@ 00,00
?? "Enter the seconds of angle A: "
accept "s"
min 0
max 59
required
to ds.seconds.a.s
if not isassigned(ds.seconds.a.s) then
return false
endif
else
ds.seconds.a.s = 0
endif
@ 00,00
if ds.degrees.a.s + ds.minutes.a.s + ds.seconds.a.s = 0 then
ds.error.u(
"NO ANGLE ENTERED FOR ANGLE A!",
ds.press.it.a)
return false
endif
?? "Enter the degrees of angle B: "
accept "s"
min 0
max 179
required
to ds.degrees.b.s
if not isassigned(ds.degrees.b.s) then
return false
endif
if ds.precision.choice.s > 1 then
@ 00,00
?? "Enter the minutes of angle B: "
accept "s"
min 0
max 59
required
to ds.minutes.b.s
if not isassigned(ds.minutes.b.s) then
return false
endif
else
ds.minutes.b.s = 0
endif
if ds.precision.choice.s = 3 then
@ 00,00
?? "Enter the seconds of Angle B: "
accept "s"
min 0
max 59
required
to ds.seconds.b.s
if not isassigned(ds.seconds.b.s) then
return false
endif
else
ds.seconds.b.s = 0
endif
if ds.degrees.b.s + ds.minutes.b.s + ds.seconds.b.s = 0 then
ds.error.u(
"NO ANGLE ENTERED FOR ANGLE B!",
ds.press.it.a)
return false
endif
return true
endproc
?? "." message memleft() writelib ds.aplib.a ds.trig.get.dms.2.l
release procs ds.trig.get.dms.2.l
;-------------------------------------------------------------------------------
; ds.trig.get.angles.radians.l(ds.trig.choice.s)
;-------------------------------------------------------------------------------
; purpose: same as ds.trig.get.angles.dms.u except this procedure gets the
; values of the angles in radians
proc ds.trig.get.angles.radians.l(
ds.trig.choice.s) ;-- the selected menu choice
private
ds.side.a,
ds.radian.a,
ds.side.value.n,
ds.radian.value.n
@ 01,00 clear eol
@ 00,00 clear eol
cursor normal
switch
case ds.trig.choice.s > 3 and
ds.trig.choice.s < 10 :
ds.trig.get.radians.1.l()
if not retval then
return false
endif
case ds.trig.choice.s = 10 :
ds.trig.get.radians.2.l()
if not retval then
return false
endif
otherwise :
?? "Enter the length of side a: "
accept "n"
min .00000000001
required
to ds.side.a.n
if not isassigned(ds.side.a.n) then
return false
endif
@ 00,00
?? "Enter the length of side b: "
accept "n"
min .00000000001
required
to ds.side.b.n
@ 00,00
switch
case not isassigned(ds.side.b.n) :
return false
case ds.trig.choice.s = 11 :
ds.radian.a = "C"
otherwise :
ds.radian.a = "A"
endswitch
?? "Enter the radians of angle " + ds.radian.a + ": "
accept "n"
min .0000048481368
max 3.141587805452
required
to ds.radian.value.n
switch
case not isassigned(ds.radian.value.n) :
return false
case ds.trig.choice.s = 11 :
ds.radians.c.s = ds.radian.value.n
otherwise :
ds.radians.a.s = ds.radian.value.n
endswitch
endswitch
return true
endproc
?? "." message memleft() writelib ds.aplib.a ds.trig.get.angles.radians.l
release procs ds.trig.get.angles.radians.l
;-------------------------------------------------------------------------------
; ds.trig.get.radians.1.l()
;-------------------------------------------------------------------------------
; purpose: same as above ds.trig.get.angles.radians.l except used
; to keep procedure size down
proc ds.trig.get.radians.1.l()
switch
case ds.trig.choice.s = 4 :
ds.side.a = "a"
ds.radian.a = "B"
case ds.trig.choice.s = 5 :
ds.side.a = "a"
ds.radian.a = "C"
case ds.trig.choice.s = 6 :
ds.side.a = "b"
ds.radian.a = "B"
case ds.trig.choice.s = 7 :
ds.side.a = "b"
ds.radian.a = "C"
case ds.trig.choice.s = 8 :
ds.side.a = "c"
ds.radian.a = "B"
case ds.trig.choice.s = 9 :
ds.side.a = "c"
ds.radian.a = "C"
endswitch
?? "Enter the length of side " + ds.side.a + ": "
accept "n"
min .00000000001
required
to ds.side.value.n
if not isassigned(ds.side.value.n) then
return false
endif
@ 00,00
?? "Enter the radians of angle " + ds.radian.a + ": "
accept "n"
min .0000048481368
max 1.570791478658
required
to ds.radian.value.n
switch
case not isassigned(ds.radian.value.n) :
return false
case ds.trig.choice.s = 4 :
ds.side.a.n = ds.side.value.n
ds.radians.b.s = ds.radian.value.n
case ds.trig.choice.s = 5 :
ds.side.a.n = ds.side.value.n
ds.radians.c.s = ds.radian.value.n
case ds.trig.choice.s = 6 :
ds.side.b.n = ds.side.value.n
ds.radians.b.s = ds.radian.value.n
case ds.trig.choice.s = 7 :
ds.side.b.n = ds.side.value.n
ds.radians.c.s = ds.radian.value.n
case ds.trig.choice.s = 8 :
ds.side.c.n = ds.side.value.n
ds.radians.b.s = ds.radian.value.n
case ds.trig.choice.s = 9 :
ds.side.c.n = ds.side.value.n
ds.radians.c.s = ds.radian.value.n
endswitch
return true
endproc
?? "." message memleft() writelib ds.aplib.a ds.trig.get.radians.1.l
release procs ds.trig.get.radians.1.l
;-------------------------------------------------------------------------------
; ds.trig.get.radians.2.l()
;-------------------------------------------------------------------------------
; purpose: same as above ds.trig.get.angles.radians.l except used
; to keep procedure size down
proc ds.trig.get.radians.2.l()
?? "Enter the length of side a: "
accept "n"
min .00000000001
required
to ds.side.a.n
if not isassigned(ds.side.a.n) then
return false
endif
@ 00,00
?? "Enter the radians of angle A: "
accept "n"
min .0000048481368
max 3.141587805452
required
to ds.radians.a.s
if not isassigned(ds.radians.a.s) then
return false
endif
@ 00,00
?? "Enter the radians of angle B: "
accept "n" min .0000048481368 max 3.141587805452 required to ds.radians.b.s
if not isassigned(ds.radians.b.s) then
return false
endif
return true
endproc
?? "." message memleft() writelib ds.aplib.a ds.trig.get.radians.2.l
release procs ds.trig.get.radians.2.l
;-------------------------------------------------------------------------------
; ds.convert.degrees.u()
;-------------------------------------------------------------------------------
; purpose: converts angles in degrees, minutes and seconds to radians
proc ds.convert.degrees.u()
if ds.trig.choice.s < 10 then
ds.radians.a.s = 1.570796326794
ds.degrees.a.s = 90
ds.minutes.a.s = 0
ds.seconds.a.s = 0
endif
if isassigned(ds.degrees.a.s) and
ds.trig.choice.s > 9 then
ds.radians.a.s = round(ds.degrees.a.s * .0174532925199,15)
if isassigned(ds.minutes.a.s) then
ds.radians.a.s =
round(ds.radians.a.s + ds.minutes.a.s * .0002908882086,15)
endif
if isassigned(ds.seconds.a.s) then
ds.radians.a.s =
round(ds.radians.a.s + ds.seconds.a.s * .0000048481368,15)
endif
endif
if isassigned(ds.degrees.b.s) then
ds.radians.b.s = round(ds.degrees.b.s * .0174532925199,15)
if isassigned(ds.minutes.b.s) then
ds.radians.b.s =
round(ds.radians.b.s + ds.minutes.b.s * .0002908882086,15)
endif
if isassigned(ds.seconds.b.s) then
ds.radians.b.s =
round(ds.radians.b.s + ds.seconds.b.s * .0000048481368,15)
endif
endif
if isassigned(ds.degrees.c.s) then
ds.radians.c.s = round(ds.degrees.c.s * .0174532925199,15)
if isassigned(ds.minutes.c.s) then
ds.radians.c.s =
round(ds.radians.c.s + ds.minutes.c.s * .0002908882086,15)
endif
if isassigned(ds.seconds.c.s) then
ds.radians.c.s =
round(ds.radians.c.s + ds.seconds.c.s * .0000048481368,15)
endif
endif
endproc
?? "." message memleft() writelib ds.aplib.a ds.convert.degrees.u
release procs ds.convert.degrees.u
;-------------------------------------------------------------------------------
; ds.compute.third.angle.u()
;-------------------------------------------------------------------------------
; purpose: computes the third angle when the other 2 are known
proc ds.compute.third.angle.u()
if ds.trig.choice.s < 10 then
ds.radians.a.s = 1.570796326794
ds.degrees.a.s = 90
ds.minutes.a.s = 0
ds.seconds.a.s = 0
endif
switch
case isassigned(ds.radians.a.s) and
isassigned(ds.radians.b.s) :
ds.radians.c.s =
round(3.141592653589 - ds.radians.a.s - ds.radians.b.s,15)
case isassigned(ds.radians.a.s) and
isassigned(ds.radians.c.s) :
ds.radians.b.s =
round(3.141592653589 - ds.radians.a.s - ds.radians.c.s,15)
case isassigned(ds.radians.b.s) and
isassigned(ds.radians.c.s) :
ds.radians.a.s =
round(3.141592653589 - ds.radians.b.s - ds.radians.c.s,15)
endswitch
endproc
?? "." message memleft() writelib ds.aplib.a ds.compute.third.angle.u
release procs ds.compute.third.angle.u
;-------------------------------------------------------------------------------
; ds.trig.calc.set.1.u()
;-------------------------------------------------------------------------------
; purpose: calculates trig answers - set 1 of 6
proc ds.trig.calc.set.1.u()
switch
case isassigned(ds.side.a.n) and isassigned(ds.side.b.n) :
ds.side.c.n =
round(sqrt(round(((ds.side.a.n*ds.side.a.n)-
(ds.side.b.n*ds.side.b.n)),15)),15)
case isassigned(ds.side.a.n) and isassigned(ds.side.c.n) :
ds.side.b.n =
round(sqrt(round(((ds.side.a.n*ds.side.a.n)-
(ds.side.c.n*ds.side.c.n)),15)),15)
case isassigned(ds.side.b.n) and isassigned(ds.side.c.n) :
ds.side.a.n =
round(sqrt(round(((ds.side.b.n*ds.side.b.n)+
(ds.side.c.n*ds.side.c.n)),15)),15)
endswitch
ds.radians.b.s = round(asin(round(ds.side.b.n/ds.side.a.n,15)),15)
ds.radians.c.s = round(asin(round(ds.side.c.n/ds.side.a.n,15)),15)
ds.radians.a.s = 1.570796326794
ds.degrees.a.s = 90
ds.minutes.a.s = 0
ds.seconds.a.s = 0
ds.area.n = round(ds.side.b.n * ds.side.c.n / 2 ,15)
endproc
?? "." message memleft() writelib ds.aplib.a ds.trig.calc.set.1.u
release procs ds.trig.calc.set.1.u
;-------------------------------------------------------------------------------
; ds.trig.calc.set.2.u()
;-------------------------------------------------------------------------------
; purpose: calculates trig answers - set 2 of 6
proc ds.trig.calc.set.2.u()
switch
case isassigned(ds.side.a.n) :
ds.side.b.n = round(ds.side.a.n * sin(ds.radians.b.s),15)
ds.side.c.n = round(ds.side.a.n * cos(ds.radians.b.s),15)
case isassigned(ds.side.b.n) :
ds.side.a.n = round(ds.side.b.n / sin(ds.radians.b.s),15)
ds.side.c.n = round(ds.side.b.n * tan(ds.radians.c.s),15)
case isassigned(ds.side.c.n) :
ds.side.a.n = round(ds.side.c.n / cos(ds.radians.b.s),15)
ds.side.b.n = round(ds.side.c.n * tan(ds.radians.b.s),15)
endswitch
ds.area.n = round(ds.side.b.n * ds.side.c.n / 2,15)
ds.radians.a.s = 1.570796326794
ds.degrees.a.s = 90
ds.minutes.a.s = 0
ds.seconds.a.s = 0
endproc
?? "." message memleft() writelib ds.aplib.a ds.trig.calc.set.2.u
release procs ds.trig.calc.set.2.u
;-------------------------------------------------------------------------------
; ds.trig.calc.set.3.u()
;-------------------------------------------------------------------------------
; purpose: calculates trig answers - set 3 of 6
proc ds.trig.calc.set.3.u()
switch
case isassigned(ds.side.a.n) :
ds.side.b.n =
round(ds.side.a.n * sin(ds.radians.b.s) / sin(ds.radians.a.s),15)
ds.side.c.n =
round(ds.side.a.n * sin(ds.radians.c.s) / sin(ds.radians.a.s),15)
case isassigned(ds.side.b.n) :
ds.side.a.n =
round(ds.side.b.n * sin(ds.radians.c.s) / sin(ds.radians.b.s),15)
ds.side.c.n =
round(ds.side.b.n * sin(ds.radians.a.s) / sin(ds.radians.b.s),15)
case isassigned(ds.side.c.n) :
ds.side.a.n =
round(ds.side.c.n * sin(ds.radians.a.s) / sin(ds.radians.c.s),15)
ds.side.b.n =
round(ds.side.c.n * sin(ds.radians.b.s) / sin(ds.radians.c.s),15)
endswitch
ds.area.n = round(ds.side.a.n * ds.side.b.n * sin(ds.radians.c.s) / 2,15)
endproc
?? "." message memleft() writelib ds.aplib.a ds.trig.calc.set.3.u
release procs ds.trig.calc.set.3.u
;-------------------------------------------------------------------------------
; ds.trig.calc.set.4.u()
;-------------------------------------------------------------------------------
; purpose: calculates trig answers - set 4 of 6
proc ds.trig.calc.set.4.u()
ds.radians.a.s =
round(atan(((ds.side.a.n*sin(ds.radians.c.s))/
(ds.side.b.n-(ds.side.a.n*cos(ds.radians.c.s))))),15)
ds.side.c.n =
round(ds.side.a.n*sin(ds.radians.c.s)/sin(ds.radians.a.s),15)
ds.radians.b.s =
round(atan(((ds.side.b.n*sin(ds.radians.a.s))/
(ds.side.c.n-(ds.side.b.n*cos(ds.radians.a.s))))),15)
ds.area.n =
round(ds.side.a.n * ds.side.b.n * sin(ds.radians.c.s) / 2,15)
endproc
?? "." message memleft() writelib ds.aplib.a ds.trig.calc.set.4.u
release procs ds.trig.calc.set.4.u
;-------------------------------------------------------------------------------
; ds.trig.calc.set.5.u()
;-------------------------------------------------------------------------------
; purpose: calculates trig answers - set 5 of 6
proc ds.trig.calc.set.5.u()
ds.radians.b.s =
round(asin((ds.side.b.n * sin(ds.radians.a.s) / ds.side.a.n)),15)
ds.radians.c.s =
round(3.141592653589 - (ds.radians.a.s + ds.radians.b.s),15)
ds.side.c.n =
round(ds.side.a.n * sin(ds.radians.c.s) / sin(ds.radians.a.s),15)
ds.area.n =
round(ds.side.a.n * ds.side.b.n * sin(ds.radians.c.s) / 2,15)
endproc
?? "." message memleft() writelib ds.aplib.a ds.trig.calc.set.5.u
release procs ds.trig.calc.set.5.u
;-------------------------------------------------------------------------------
; ds.trig.calc.set.6.u()
;-------------------------------------------------------------------------------
; purpose: calculates trig answers - set 6 of 6
proc ds.trig.calc.set.6.u()
ds.radians.a.s =
round(acos(((ds.side.b.n*ds.side.b.n+ds.side.c.n*
ds.side.c.n-ds.side.a.n*ds.side.a.n)/(2*ds.side.b.n*ds.side.c.n))),15)
ds.radians.b.s =
round(acos(((ds.side.a.n*ds.side.a.n+ds.side.c.n*
ds.side.c.n-ds.side.b.n*ds.side.b.n)/(2*ds.side.a.n*ds.side.c.n))),15)
ds.radians.c.s =
round(acos(((ds.side.a.n*ds.side.a.n+ds.side.b.n*
ds.side.b.n-ds.side.c.n*ds.side.c.n)/(2*ds.side.a.n*ds.side.b.n))),15)
ds.area.n =
round(ds.side.a.n * ds.side.b.n * sin(ds.radians.c.s) / 2,15)
endproc
?? "." message memleft() writelib ds.aplib.a ds.trig.calc.set.6.u
release procs ds.trig.calc.set.6.u
;-------------------------------------------------------------------------------
; ds.trig.convert.radians.u()
;-------------------------------------------------------------------------------
; purpose: converts known radians to degrees, minutes and seconds
proc ds.trig.convert.radians.u()
private
ds.remainder.n ;-- used to handle the remainder after extracting the
;-- degrees and minutes from the radians
if ds.trig.choice.s >9 then
ds.degrees.a.s = int(ds.radians.a.s / .0174532925199)
ds.remainder.n = round(ds.radians.a.s - ds.degrees.a.s * .0174532925199,15)
ds.minutes.a.s = int(ds.remainder.n / .0002908882086)
ds.remainder.n = round(ds.remainder.n - ds.minutes.a.s * .0002908882086,15)
ds.seconds.a.s = int(round((ds.remainder.n / .0000048481368),0))
endif
ds.degrees.b.s = int(ds.radians.b.s / .0174532925199)
ds.remainder.n = round(ds.radians.b.s - ds.degrees.b.s * .0174532925199,15)
ds.minutes.b.s = int(ds.remainder.n / .0002908882086)
ds.remainder.n = round(ds.remainder.n - ds.minutes.b.s * .0002908882086,15)
ds.seconds.b.s = int(round((ds.remainder.n / .0000048481368),0))
ds.degrees.c.s = int(ds.radians.c.s / .0174532925199)
ds.remainder.n = round(ds.radians.c.s - ds.degrees.c.s * .0174532925199,15)
ds.minutes.c.s = int(ds.remainder.n / .0002908882086)
ds.remainder.n = round(ds.remainder.n - ds.minutes.c.s * .0002908882086,15)
ds.seconds.c.s = int(round((ds.remainder.n / .0000048481368),0))
endproc
?? "." message memleft() writelib ds.aplib.a ds.trig.convert.radians.u
release procs ds.trig.convert.radians.u
;-------------------------------------------------------------------------------
; ds.trig.display.answer.u()
;-------------------------------------------------------------------------------
; purpose: formats and displays the answers to the trig problem presented
proc ds.trig.display.answer.u()
private
ds.line.1.a,
ds.line.2.a,
ds.line.3.a,
ds.line.4.a,
ds.line.5.a,
ds.line.6.a,
ds.line.7.a,
ds.line.8.a,
ds.line.9.a,
ds.line.10.a,
ds.line.11.a
ds.line.1.a = format("w4,ar",ds.degrees.c.s) +
"° " +
format("w3,ar",ds.minutes.c.s) +
"' " +
format("w3,ar",ds.seconds.c.s) + "\""
ds.line.2.a = format("w15.15,al",ds.radians.c.s)
ds.line.3.a = format("w15.15,al",ds.side.a.n)
ds.line.4.a = format("w15.15,al",ds.side.b.n)
ds.line.5.a = format("w4,ar",ds.degrees.a.s) +
"° " +
format("w3,ar",ds.minutes.a.s) +
"' " +
format("w3,ar",ds.seconds.a.s) + "\""
ds.line.6.a = format("w15.15,al",ds.radians.a.s)
ds.line.7.a = format("w4,ar",ds.degrees.b.s) +
"° " + format("w3,ar",ds.minutes.b.s) +
"' " +
format("w3,ar",ds.seconds.b.s) + "\""
ds.line.8.a = format("w15.15,al",ds.radians.b.s)
ds.line.9.a = format("w15.15,al",ds.side.c.n)
ds.line.10.a = format("w15.15,al",ds.periphery.n)
ds.line.11.a = format("w15.15,al",ds.area.n)
style reverse
@ 04,16 ?? ds.line.1.a
@ 05,16 ?? ds.line.2.a
@ 11,17 ?? ds.line.3.a
@ 15,05 ?? ds.line.4.a
@ 19,15 ?? ds.line.5.a
@ 20,15 ?? ds.line.6.a
@ 20,46 ?? ds.line.7.a
@ 21,46 ?? ds.line.8.a
@ 23,05 ?? ds.line.9.a
@ 22,58 ?? ds.line.10.a
@ 23,58 ?? ds.line.11.a
style
endproc
?? "." message memleft() writelib ds.aplib.a ds.trig.display.answer.u
release procs ds.trig.display.answer.u
;-------------------------------------------------------------------------------
; ds.review.print.u()
;-------------------------------------------------------------------------------
; purpose: displays the appropriate menu choice depending on the parameter
; passed in the call to ds.calc.v that turns the printing option
; on or leaves it off
proc ds.review.print.u()
private
ds.menu.choice.a ;-- selected menu choice
ds.rebuild.l = false ;-- initialize the variable
;-- display the proper menu for the current state of the
;-- tape display window and whether printing is turned
;-- on or off
;-- there is no review required if all of the tape entries
;-- can be seen on the screen currently
switch
;-- less than 20 entries and no printing
case ds.tape.count.s < 20 and
(not isassigned(ds.print.tape.a) or
lower(ds.print.tape.a) <> "on") :
ds.error.u(
"Sorry, the print function is not enabled at this time.",
ds.press.it.a)
ds.main.prompt.u()
return
;-- less than 20 entries and printing enabled
case ds.tape.count.s < 20 and
isassigned(ds.print.tape.a) and
lower(ds.print.tape.a) = "on" :
showmenu
"Print " : " Print the tape.",
"Esc " : " Cancel printing and return to the calculator."
to ds.menu.choice.a
canvas off
message ""
@ 22,78 clear eol
canvas on
if ds.menu.choice.a = "Print " then
ds.print.tape.u()
else
return
endif
;-- greater than 19 entries and no printing
case ds.tape.count.s > 19 and
not isassigned(ds.print.tape.a) or
lower(ds.print.tape.a) <> "on" :
showmenu
"Review " : " Review the tape.",
"Esc " : " Return to the calculator."
to ds.menu.choice.a
canvas off
message ""
@ 22,78 clear eol
canvas on
if ds.menu.choice.a = "Review " then
ds.review.tape.u()
ds.rebuild.l = true
else
return
endif
;-- greater than 19 entries and printing enabled
otherwise:
showmenu
"Review " : " Review the tape.",
"Print " : " Print the tape.",
"Esc " : " Return to the calculator."
to ds.menu.choice.a
canvas off
message ""
@ 22,78 clear eol
canvas on
switch
case ds.menu.choice.a = "Review " :
ds.review.tape.u()
ds.rebuild.l = true
case ds.menu.choice.a = "Print " :
ds.print.tape.u()
otherwise :
return
endswitch
endswitch
endproc
?? "." message memleft() writelib ds.aplib.a ds.review.print.u
release procs ds.review.print.u
;-------------------------------------------------------------------------------
; ds.review.tape.u()
;-------------------------------------------------------------------------------
; purpose: re-runs the tape through the tape window pausing on each screen
; until a key is pressed
proc ds.review.tape.u()
Private
ds.number.of.loops.1.s, ;-- number of loops in a for statement
ds.number.of.loops.2.s, ;-- and another one
ds.loop.counter.1.s, ;-- a loop counter
ds.loop.counter.2.s, ;-- and another one
ds.at.position.s, ;-- where to print to the screen
ds.get.char.s, ;-- used to capture a keystroke
ds.clear.position.s ;-- another screen positioner
style reverse
@ 00,00
?? format("w80,ac",
"After reviewing each section of the tape, press any key" +
" to continue and view")
@ 01,00 ?? format("w80,ac",
"the next section. At the end of the tape, you" +
" will return to normal mode.")
style
;-- how many screens to re-run
ds.number.of.loops.1.s = int(ds.tape.count.s/18)
;-- adjust as required
if ds.number.of.loops.1.s <> ds.tape.count.s/18 then
ds.number.of.loops.1.s = ds.number.of.loops.1.s + 1
endif
;-- initialize the variable
ds.number.of.loops.2.s = 1
;-- for the number of times the tape need to be re-run
for ds.loop.counter.1.s from 1 to ds.number.of.loops.1.s
;-- start here
ds.at.position.s = 6
;-- turn the canvas off
canvas off
;-- first time through place this at the top of the tape
if ds.loop.counter.1.s = 1 then
style reverse
@ 05,43 ?? "║ │ ║"
style blink, reverse
@ 05,44 ?? " Tape Review Mode"
style
else
;-- if not the first time, place this at the top of the tape
style reverse
@ 05,43 ?? "║ │ ║"
style blink, reverse
@ 05,44 ?? " Tape Review Mode "
style
endif
;-- place the tape entries on the screen
for ds.loop.counter.2.s
from ds.number.of.loops.2.s
to (ds.number.of.loops.2.s + 17)
;-- this if clears to the bottom of the tape
;-- any entries placed there earlier
if ds.loop.counter.2.s > ds.tape.count.s or
(ds.loop.counter.2.s = ds.tape.count.s and
(not isassigned(ds.tape.r[ds.tape.count.s]) or
ds.tape.r[ds.tape.count.s] = blanknum() or
lower(numval(ds.tape.r[ds.tape.count.s])) = "error" or
not isassigned(ds.tape.function.r[ds.tape.count.s]))) then
for ds.clear.position.s from ds.at.position.s to 23
@ ds.clear.position.s,43 ?? "║ │ ║"
endfor
quitloop
else
;-- set the style for totals or regular tape entries
if ds.loop.counter.2.s > 1 then
if ds.tape.function.r[ds.loop.counter.2.s-1] = 61 then
style intense
else
style
endif
endif
;-- place the tape entry on the screen using
;-- the proper format for the number type
if ds.decimal.r[ds.loop.counter.2.s] then
@ ds.at.position.s,45
?? format("w20.15,ar",numval(ds.tape.r[ds.loop.counter.2.s]))
else
@ ds.at.position.s,45
?? format("w20,ar,ec",numval(ds.tape.r[ds.loop.counter.2.s]))
endif
;-- place the function key
@ ds.at.position.s,73 ?? chr(ds.tape.function.r[ds.loop.counter.2.s])
style
;-- increment the position pointer
ds.at.position.s = ds.at.position.s + 1
endif
endfor
;-- turn the canvas on
canvas on
ds.get.char.s = getchar()
;-- reset the variable for the next set
ds.number.of.loops.2.s = ds.loop.counter.2.s
endfor
endproc
?? "." message memleft() writelib ds.aplib.a ds.review.tape.u
release procs ds.review.tape.u
;-------------------------------------------------------------------------------
; ds.print.tape.u()
;-------------------------------------------------------------------------------
; purpose: sends the tape to the attached printer
proc ds.print.tape.u()
private
ds.loop.counter.s ;-- a loop counter
;-- only if the printer is on
if printerstatus() then
;-- double check, some machines return true the first time,
;-- false the second
if printerstatus() then
;-- for networks
open printer
;-- the header
print " Tape Entry #:\n"
for ds.loop.counter.s from 1 to ds.tape.count.s
;-- the footer
if not isassigned(ds.tape.function.r[ds.loop.counter.s]) then
print "\n" + " ** End of Tape **\n"
quitloop
else
;-- pick the proper format
if ds.decimal.r[ds.loop.counter.s] then
print format("w20.15,ar",
numval(ds.tape.r[ds.loop.counter.s])) +
" " +
chr(ds.tape.function.r[ds.loop.counter.s])
else
print format("w20,ar,ec",
numval(ds.tape.r[ds.loop.counter.s])) +
" " +
chr(ds.tape.function.r[ds.loop.counter.s])
endif
;-- print the tape entry number
print " : " + strval(ds.loop.counter.s) + "\n"
endif
endfor
;-- spit the page out
print "\f"
;-- close the printer
close printer
return
endif
endif
ds.error.u(
"Please turn on or reset your printer before attempting to print the tape.",
"Press any key to continue.")
ds.main.prompt.u()
return
endproc
?? "." message memleft() writelib ds.aplib.a ds.print.tape.u
release procs ds.print.tape.u
;-------------------------------------------------------------------------------
; ds.error.u()
;-------------------------------------------------------------------------------
; purpose: displays error messages on the top 2 lines of the screen
proc ds.error.u(
ds.line.1.a, ;-- passed parameters to this procedure
ds.line.2.a) ;-- of the message to be displayed
private
ds.get.char.s ;-- keystroke to get
style reverse
canvas off
@ 00,00 ?? format("w80,ac",ds.line.1.a)
@ 01,00 ?? format("w80,ac",ds.line.2.a)
canvas on
style
while charwaiting()
ds.get.char.s = getchar()
endwhile
for ds.get.char.s from 1 to 4
beep
sleep 250
endfor
ds.get.char.s = getchar()
@ 01,00 clear eol
@ 00,00 clear eol
endproc
?? "." message memleft() writelib ds.aplib.a ds.error.u
release procs ds.error.u
;-------------------------------------------------------------------------------
; ds.oops.1()
;-------------------------------------------------------------------------------
; purpose: errorproc to be called when no custom added in procedures exist
proc ds.oops.1()
private
autolib
autolib = ds.aplib.a
;-- bottom line restorer
canvas off
message ""
@ 22,78 clear eol
canvas on
;-- was there a proc?
if lower(errormessage()) =
"run error: procedure ds.custom.v is not defined" then
ds.error.u(
"Sorry, no custom formulas have been added into the calculator.",
ds.press.it.a)
ds.not.defined.a = "noproc"
else
;-- some other unknown error tripped us up!
;-- display that message to the user
ds.error.u(errormessage(),
ds.press.it.a)
endif
;-- attempt to step over the offending line of code
return 1
endproc
?? "." message memleft() writelib ds.aplib.a ds.oops.1
release procs ds.oops.1
;-------------------------------------------------------------------------------
; ds.help.menu.u()
;-------------------------------------------------------------------------------
; purpose: displays the dscalc help menu
proc ds.help.menu.u()
private
ds.help.choice.a ;-- menu choice selected
;-- initialize this variable
ds.rebuild.l = true
showmenu
"Basic " : " Basic information about the use of DSCalc.",
"Memory " : " How to use the Memory functions of the calculator.",
"Specials " : " How to call up and use the special" +
" Functions and Formulas Menu.",
"The Tape " : " How to Review and/or Print the tape.",
"General " : " Some general tips on using DSCalc.",
"Info " : " Information about the author of DSCalc.",
"Esc " : " Return to what you were doing before asking for help."
to ds.help.choice.a
canvas off
message ""
@ 22,78 clear eol
canvas on
;-- evaluate the menu item selected and call
;-- the appropriate procedure or exit
switch
case ds.help.choice.a = "Esc" or
ds.help.choice.a = "Esc " :
ds.rebuild.l = false
case ds.help.choice.a = "Basic " :
ds.basic.help.u()
case ds.help.choice.a = "Memory " :
ds.memory.help.u()
case ds.help.choice.a = "Specials " :
ds.specials.help.u()
case ds.help.choice.a = "The Tape " :
DS.Tape.Help.u()
case ds.help.choice.a = "General " :
ds.general.help.u()
case ds.help.choice.a = "Info " :
ds.info.help.u()
endswitch
endproc
?? "." message memleft() writelib ds.aplib.a ds.help.menu.u
release procs ds.help.menu.u
;-------------------------------------------------------------------------------
; ds.basic.help.u()
;-------------------------------------------------------------------------------
; purpose: displays the main help screen
proc ds.basic.help.u()
private
ds.get.char.s
@ 00,00
canvas off
text
╔══════════════════════════════════════════════════════════════════════════════╗
║ ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ Since the keypad for the calculator is the standard computer keyboard there ║
║ may be some slight adjustments required from what you are accustomed to. ║
║ ║
║ There are also some special keys that may be used that are not shown on the ║
║ screen that make this calculator easier to use. (i.e. [Backspace] clears ║
║ one digit at a time from the right of the calculator window.) ║
║ ║
║ The basic keys and a brief definition of their use in the calculator are: ║
║ ║
║ + : Used to indicate addition. ║
║ - : Used to indicate subtraction or negative numbers. ║
║ * : Used to indicate multiplication. ║
║ / : Used to indicate division. ║
║ . : Used to indicate a decimal. ║
║ = : Used to tell DSCalc to perform the calculations. ║
║ (Also [Enter] and [F2].) ║
║ [Alt-C] : Completely clear the calculator (Except memory values.) ║
║ [C] : Clear just the current entry. (Also [Ctrl-BackSpace].) ║
║ [M] : Call up the Memory Menu. ║
║ [F10] : Call up the Special Functions and Formulas Menu. ║
║ [Alt-F7] : Review and/or Print the tape. ║
╚═════════════════ ═════════════════╝
endtext
style reverse
@ 01,10
?? " DSCalc is similar in use to most four function calculators. "
style
style intense
@ 24,18
?? " Press any key to return to the calculator. "
style
canvas on
ds.get.char.s = getchar()
endproc
?? "." message memleft() writelib ds.aplib.a ds.basic.help.u
release procs ds.basic.help.u
;-------------------------------------------------------------------------------
; ds.memory.help.u()
;-------------------------------------------------------------------------------
; purpose: displays the memory help screen
proc ds.memory.help.u()
private
ds.get.char.s
@ 00,00
canvas off
text
╔══════════════════════════════════════════════════════════════════════════════╗
║ ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ By pressing "M" or "m" while in the calculator, DSCalc will present on the ║
║ top two lines the Memory menu and prompts. ║
║ ║
║ By highlighting a specific choice with the cursor keys on the top line, the ║
║ second line will reveal some more information about that particular choice. ║
║ To select the choice, either press the first letter of the choice or when ║
║ that choice is highlighted, press the [Enter] key. ║
║ ║
║ After selecting the appropriate Memory function, use the cursor keys to ║
║ highlight the memory location number and the second line will reveal either ║
║ "Not Assigned" or the value that is kept in that Memory location. ║
║ ║
║ If you had selected "Add " or "Subtract " from the Memory menu, after ║
║ highlighting a Memory location, pressing the [Enter] key will add to or ║
║ subtract from that location the last entry in the calculator and then show ║
║ you the result on the second line. Selecting "Recall " will recall that ║
║ value and enter it into the calculator window. (Any current entry will be ║
║ overwritten with the recalled value.) The "Display " function simply lets ║
║ you view the stored memory values with no manipulation and the "Clear " ║
║ function clears all of the stored values from memory. Use the [Esc] key to ║
║ cancel and/or return to the previous Menu and/or the calculator. ║
╚═════════════════ ═════════════════╝
endtext
style reverse
@ 01,05
?? " DSCalc has the capability to store and use nineteen memory values. "
style
style intense
@ 24,18
?? " Press any key to return to the calculator. "
style
canvas on
ds.get.char.s = getchar()
endproc
?? "." message memleft() writelib ds.aplib.a ds.memory.help.u
release procs ds.memory.help.u
;-------------------------------------------------------------------------------
; ds.specials.help.u()
;-------------------------------------------------------------------------------
; purpose: displays the specials help screen
proc ds.specials.help.u()
private
ds.special.choice.a
@ 02,00
canvas off
text
╔══════════════════════════════════════════════════════════════════════════════╗
║ ║
║ ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ You can call up the Special Functions and Formulas Menu by pressing the ║
║ [F10] key when the top two lines on the screen display the message: ║
║ ║
║ "Press [F10] for special functions and formulas, [F1] for help." ║
║ "Press [Esc] to return to what you were doing." ║
║ ║
║ After pressing the [F10] key, a Menu will appear on the top two lines like ║
║ the Menu that now appears on the top two lines of this screen. ║
║ ║
║ To select a Menu choice (True when any menu appears on the top two lines of ║
║ this program), use the cursor keys to highlight your choice and press the ║
║ [Enter] key or press the letter key corresponding to the first letter of ║
║ your choice. (When there is more than one choice starting with the same ║
║ letter or number, you must highlight your choice and press the [Enter] key.) ║
║ ║
║ Select one of the above choices for more help with Mathematical, ║
║ Trigonometry, Financial or the Custom functions or press [Esc] to return ║
║ to the calculator. ║
╚══════════════════════════════════════════════════════════════════════════════╝
endtext
style reverse
@ 03,04
?? " DSCalc has a Special Functions and Formulas Menu for Mathematical, "
@ 04,04
?? " Trigonometry, Financial and user defined customized formulas. "
style
canvas on
showmenu
"Mathematical " : " Help with Mathematical functions.",
"Trigonometry " : " Help with Trigonometry calculations.",
"Financial " : " Help with Financial calculations.",
"Custom " : " Help with Custom Designed calculations.",
"Esc " : " Return to what you were doing."
to ds.special.choice.a
switch
case ds.special.choice.a = "Mathematical " :
ds.math.help.u()
case ds.special.choice.a = "Trigonometry " :
ds.trig.help.u()
case ds.special.choice.a = "Financial " :
ds.finance.help.u()
case ds.special.choice.a = "Custom " :
ds.custom.help.u()
endswitch
canvas off
message ""
@ 22,78 clear eol
canvas on
return
endproc
?? "." message memleft() writelib ds.aplib.a ds.specials.help.u
release procs ds.specials.help.u
;-------------------------------------------------------------------------------
; ds.math.help.u()
;-------------------------------------------------------------------------------
; purpose: displays the math help screen
proc ds.math.help.u()
private
ds.get.char.s
@ 00,00
canvas off
text
╔══════════════════════════════════════════════════════════════════════════════╗
║ ║
║ ║
║ ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ The following math functions require at least one entry in the calculator. ║
║ ABS : The absolute value (always positive.) of a number. ║
║ EXP : The exponential (base e) of a number. ║
║ INT : The integer part of a number (i.e. the whole part of a number). ║
║ LN : The natural logarithm of a number. ║
║ LOG : The base 10 logarithm of a number. ║
║ SQRT : The square root of a number. ║
╟──────────────────────────────────────────────────────────────────────────────╢
║ The next group of functions require at least one entry and an additional ║
║ number is required to be supplied via a prompt on the top lines. ║
║ POW : Raises the last entry to a given power. ║
║ ROUND : Round the last entry to a specified number of places. (A whole ║
║ number between -15 and 15) ║
╟──────────────────────────────────────────────────────────────────────────────╢
║ MOD : The remainder of one number divided by another. ║
╟──────────────────────────────────────────────────────────────────────────────╢
║ PI : Returns the value of PI (3.141592653589) ║
║ RAND : Returns a random decimal number between 0 and 1. ║
║ ║
╚═════════════════ ═════════════════╝
endtext
style reverse
@ 01,03
?? " DSCalc will perform the following mathematical functions: "
@ 02,03
?? " (Note: The resulting answer will be displayed in the calculator window, "
@ 03,03
?? " replacing any value already there.) "
style
style intense
@ 24,18
?? " Press any key to return to the calculator. "
style
canvas on
ds.get.char.s = getchar()
endproc
?? "." message memleft() writelib ds.aplib.a ds.math.help.u
release procs ds.math.help.u
;-------------------------------------------------------------------------------
; ds.trig.help.u()
;-------------------------------------------------------------------------------
; purpose: displays the trig help screen
proc ds.trig.help.u()
private
ds.get.char.s
@ 00,00
canvas off
text
╔══════════════════════════════════════════════════════════════════════════════╗
║ ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ The Trigonometry section of DSCalc was designed for ease of use without ║
║ having to dig out your Trig tables and formulas. DSCalc performs all of the ║
║ Trig functions automatically. After selecting the Trigonometry Menu choice, ║
║ the Trig screen will appear with a "Menu" box on the right hand side of the ║
║ screen. The box is divided into two columns. The column on the left is for ║
║ Right Angle Triangles (Any triangle having one angle of 90°) and the right ║
║ column is for Oblique Triangles (A triangle that does not have a 90° angle). ║
║ Use the cursor keys to select the appropriate choice for the known values. ║
║ You will be prompted on the top lines for the information and DSCalc will ║
║ do the rest. ║
║ ║
║ When there is a known angle to be input, DSCalc will prompt you to let it ║
║ know what precision you will be imputing the angle. Angles may be input as ║
║ Degrees, Degrees with Minutes, Degrees with Minutes and Seconds or as ║
║ Radians. ║
║ ║
║ After you have completed the triangle, you may return the answer to the ║
║ calculator by pressing [Esc] and then selecting the appropriate menu choice. ║
║ ║
║ Note: The precision of any answer is only accurate to 15 places. It is up to ║
║ the user to determine to what place to round off the answer to. ║
╚═════════════════ ═════════════════╝
endtext
style reverse
@ 01,08
?? " DSCalc performs Trigonometry functions simply and quickly. "
style
style intense
@ 24,18
?? " Press any key to return to the calculator. "
style
canvas on
ds.get.char.s = getchar()
endproc
?? "." message memleft() writelib ds.aplib.a ds.trig.help.u
release procs ds.trig.help.u
;-------------------------------------------------------------------------------
; ds.finance.help.u()
;-------------------------------------------------------------------------------
; purpose: displays the financial help screen
proc ds.finance.help.u()
private
ds.get.char.s
@ 00,00
canvas off
text
╔══════════════════════════════════════════════════════════════════════════════╗
║ ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ DSCalc will perform the following financial functions when the appropriate ║
║ information is supplied at the prompts on the top line of the screen: ║
║ ║
║ FV : The future value of a series of equal payments. This function is ║
║ sometimes called the compound value of an annuity. It will calculate ║
║ the amount accumulated in a annuity fund by making regular payments ║
║ over a specified period of time at a specified interest rate. ║
║ ║
║ PMT : The periodic payment to pay off a loan. This formula returns the ║
║ amount of the payment required to pay off a loan amount over a given ║
║ time span at a specific interest rate. ║
║ ║
║ PV : The present value of a series of equal payments. This function is ║
║ sometimes called the present value of an annuity. By supplying the ║
║ the amount of a payment, the interest rate and the number of pay ║
║ periods, this formula will compute the size of a loan that could be ║
║ paid off with that payment or how much money would be required in an ║
║ annuity fund to supply a given amount of money over a specified time ║
║ period. ║
║ ║
║ (Note: The maximum time period is 1020 months for the above formulas.) ║
╚═════════════════ ═════════════════╝
endtext
style reverse
@ 01,21
?? " Financial Functions with DSCalc "
style
style intense
@ 24,18
?? " Press any key to return to the calculator. "
style
canvas on
ds.get.char.s = getchar()
endproc
?? "." message memleft() writelib ds.aplib.a ds.finance.help.u
release procs ds.finance.help.u
;-------------------------------------------------------------------------
; ds.custom.help.u()
;-------------------------------------------------------------------------
; purpose: displays the custom help screen
proc ds.custom.help.u()
private
ds.get.char.s
@ 00,00
canvas off
text
╔══════════════════════════════════════════════════════════════════════════════╗
║ ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ ║
║ ║
║ Custom formulas may be added into to DSCalc for specific formulas that are ║
║ used frequently by the user. ║
║ ║
║ ║
║ ║
║ If selecting the Custom menu choice results in an error message on the top ║
║ two lines of the screen, then there have not been any custom formulas added ║
║ to the calculator. ║
║ ║
║ ║
║ ║
║ If you wish to add a custom formula to the calculator, refer to the script ║
║ "DSCustom.sc" supplied with this program as an example of how to add on your ║
║ own formulas to the calculator. ║
║ ║
║ ║
║ ║
║ ║
║ ║
╚═════════════════ ═════════════════╝
endtext
style reverse
@ 01,21
?? " Custom add on formulas for DSCalc "
style
style intense
@ 24,18
?? " Press any key to return to the calculator. "
style
canvas on
ds.get.char.s = getchar()
endproc
?? "." message memleft() writelib ds.aplib.a ds.custom.help.u
release procs ds.custom.help.u
;-------------------------------------------------------------------------------
; ds.tape.help.u()
;-------------------------------------------------------------------------------
; purpose: displays the tape help screen
proc ds.tape.help.u()
private
ds.get.char.s
@ 00,00
canvas off
text
╔══════════════════════════════════════════════════════════════════════════════╗
║ ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ Select Review/Print by holding down the [Alt] key and then press [F7]. ║
║ ║
║ Printing the tape: ║
║ Printing of the tape is a function that is either "On" or "Off" by the way ║
║ that DSCalc is started. If the print function is not turned "On" when the ║
║ calculator is started, then the tape may not be printed. Otherwise, DSCalc ║
║ sends the contents to the default printer. DSCalc checks twice to see if ║
║ the printer is ready before attempting to print the tape. Printer status ║
║ is checked twice as some computers will return "True" the first time that ║
║ the printer status is checked. Note: Printer status is ALWAYS returned as ║
║ "True" on any port other then LPT1. Print size will be determined by ║
║ the current printer settings. A "Form Feed" is generated at the end of the ║
║ tape. ║
║ ║
║ Reviewing the tape: ║
║ Review of the tape is only possible when the tape is longer than the screen.║
║ This may be determined by the " More " at the top of the tape box. ║
║ Once the review mode has started, the entire tape must be reviewed. After ║
║ viewing each section of the tape, press a key to view the next section. ║
║ After the entire tape has been reviewed, you will be returned to the normal ║
║ calculator mode. ║
╚═════════════════ ═════════════════╝
endtext
style reverse
@ 01,20
?? " Reviewing and/or Printing of the Tape "
style
style intense
@ 24,18
?? " Press any key to return to the calculator. "
style
canvas on
ds.get.char.s = getchar()
endproc
?? "." message memleft() writelib ds.aplib.a ds.tape.help.u
release procs ds.tape.help.u
;-------------------------------------------------------------------------------
; ds.general.help.u()
;-------------------------------------------------------------------------------
; purpose: displays the general help screen
proc ds.general.help.u()
private
ds.get.char.s
@ 00,00
canvas off
text
╔══════════════════════════════════════════════════════════════════════════════╗
║ ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ DSCalc is only accurate to 15 places! It is the users responsibility to ║
║ determine the accuracy of any answer calculated with this calculator. ║
║ ║
║ The [Esc] key may be used at almost any point to cancel the current ║
║ operation including but not limited to any value requested on the top two ║
║ lines of the screen. ║
║ ║
║ Keys defined like [Alt-F7] (Print/Review the tape) or [Alt-C] (Clear-All) ║
║ require that the first key ([Alt]) be held down and while holding that key ║
║ down, press the second key (Such as [F7] or [C]) to perform that function. ║
║ ║
║ There may be alternate keys to some of the function keys. [Enter] and [F2] ║
║ perform the same as the [=] key. [Ctrl-Backspace] and [F8] perform the ║
║ same functions as [C] (Clear Entry). [Alt-F8] is the same as [Alt-C] ║
║ (Clear All). ║
║ ║
║ Leading zeros are NOT allowed. ║
║ ║
║ [Backspace] deletes ONE digit at a time from the calculator window. ║
║ ║
║ ║
╚═════════════════ ═════════════════╝
endtext
style reverse
@ 01,13
?? " Some general information and tips about DSCalc "
style
style intense
@ 24,18
?? " Press any key to return to the calculator. "
style
canvas on
ds.get.char.s = getchar()
endproc
?? "." message memleft() writelib ds.aplib.a ds.general.help.u
release procs ds.general.help.u
;-------------------------------------------------------------------------------
; ds.info.help.u()
;-------------------------------------------------------------------------------
; purpose: displays the info screen
proc ds.info.help.u()
private
ds.get.char.s
@ 00,00
canvas off
text
╔══════════════════════════════════════════════════════════════════════════════╗
║ ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ DSCalc CopyRighted 1989, 1990: Version 1.10 ║
║ All rights reserved ║
║ Dave Schlieder ║
║ Shared Logic, Inc. ║
║ 1016 Second Street ║
║ Encinitas, Ca. 92024 ║
║ (619)943-1086 ║
║ ║
║ This program has been released to the public domain and can be used or ║
║ modified in any way. It was written as an exercise in learning programming ║
║ techniques and string and numeric manipulation. I hope you find this ║
║ program enlightening and educational. ║
║ ║
║ ║
║ Although the procedures are Copyright 1989,1990 Dave Schlieder you are hereby║
║ granted the use of any of these Procs in your scripts, provided that you ║
║ retain the original names of my procedures. ║
║ (I usually include an acknowledgement in my script comments if I use other ║
║ peoples' code in this way.) ║
║ If you distribute them, please do so UNALTERED. ║
║ ║
╚═════════════════ ═════════════════╝
endtext
style reverse
@ 01,17
?? " Who to contact for information about DSCalc "
style
style intense
@ 24,18
?? " Press any key to return to the calculator. "
style
canvas on
ds.get.char.s = getchar()
endproc
?? "." message memleft() writelib ds.aplib.a ds.info.help.u
release procs ds.info.help.u