' Dialog flag constants (use + or OR to use more than 1 flag value)
CONST OFN_ALLOWMULTISELECT
= &H200&
' Allows the user to select more than one file, not recommended! CONST OFN_CREATEPROMPT
= &H2000&
' Prompts if a file not found should be created(GetOpenFileName only). CONST OFN_EXTENSIONDIFFERENT
= &H400&
'Allows user to specify file extension other than default extension. CONST OFN_FILEMUSTEXIST
= &H1000&
' Chechs File name exists(GetOpenFileName only). CONST OFN_HIDEREADONLY
= &H4&
' Hides read-only checkbox(GetOpenFileName only) CONST OFN_NOCHANGEDIR
= &H8&
' Restores the current directory to original value if user changed CONST OFN_NODEREFERENCELINKS
= &H100000&
'Returns path and file name of selected shortcut(.LNK) file instead of file referenced. CONST OFN_NONETWORKBUTTON
= &H20000&
' Hides and disables the Network button. CONST OFN_NOREADONLYRETURN
= &H8000&
' Prevents selection of read-only files, or files in read-only subdirectory. CONST OFN_NOVALIDATE
= &H100&
' Allows invalid file name characters. CONST OFN_OVERWRITEPROMPT
= &H2&
' Prompts if file already exists(GetSaveFileName only) CONST OFN_PATHMUSTEXIST
= &H800&
' Checks Path name exists (set with OFN_FILEMUSTEXIST). CONST OFN_READONLY
= &H1&
' Checks read-only checkbox. Returns if checkbox is checked CONST OFN_SHAREAWARE
= &H4000&
' Ignores sharing violations in networking CONST OFN_SHOWHELP
= &H10&
' Shows the help button (useless!) '--------------------------------------------------------------------------------------------
lStructSize
AS LONG ' For the DLL call hwndOwner
AS LONG ' Dialog will hide behind window when not set correctly hInstance
AS LONG ' Handle to a module that contains a dialog box template. lpstrFilter
AS _OFFSET ' Pointer of the string of file filters nFilterIndex
AS LONG ' One based starting filter index to use when dialog is called lpstrFile
AS _OFFSET ' String full of 0's for the selected file name nMaxFile
AS LONG ' Maximum length of the string stuffed with 0's minus 1 lpstrFileTitle
AS _OFFSET ' Same as lpstrFile nMaxFileTitle
AS LONG ' Same as nMaxFile lpstrInitialDir
AS _OFFSET ' Starting directory nFileOffset
AS INTEGER ' Zero-based offset from path beginning to file name string pointed to by lpstrFile nFileExtension
AS INTEGER ' Zero-based offset from path beginning to file extension string pointed to by lpstrFile. lpstrDefExt
AS _OFFSET ' Default/selected file extension hwndOwner
AS _OFFSET ' Dialog will hide behind window when not set correctly hInstance
AS _OFFSET ' Handle to a module that contains a dialog box template. lpstrFilter
AS _OFFSET ' Pointer of the string of file filters nFilterIndex
AS _INTEGER64 ' One based starting filter index to use when dialog is called lpstrFile
AS _OFFSET ' String full of 0's for the selected file name nMaxFile
AS _OFFSET ' Maximum length of the string stuffed with 0's minus 1 lpstrFileTitle
AS _OFFSET ' Same as lpstrFile lpstrInitialDir
AS _OFFSET ' Starting directory nFileOffset
AS _INTEGER64 ' Zero-based offset from path beginning to file name string pointed to by lpstrFile nFileExtension
AS _INTEGER64 'Zero-based offset from path beginning to file extension string pointed to by lpstrFile. lpstrDefExt
AS _OFFSET ' Default/selected file extension
FUNCTION GetOpenFileNameA&
(DIALOGPARAMS
AS FILEDIALOGTYPE
) ' The Open file dialog FUNCTION GetSaveFileNameA&
(DIALOGPARAMS
AS FILEDIALOGTYPE
) ' The Save file dialog
hWnd&
= _WINDOWHANDLE 'FindWindow(0, "Pandemic" + CHR$(0)) 'get window handle using _TITLE string'DIM SHARED i AS INTEGER
state
AS _BYTE '1 = healthy; 2 = contamined; 3 = dead; 4 = recovered
'outer walls
graphlx = 15
hgraphlx
= (_WIDTH / 3 * 2) + 15
'-------------------------------------------------------------------------------------------------------- simulation settings
'variation
maxpeople = 500
totalInfected = 30
peoplesize = 2
sd = 2 'in meters
scale = 5
safedistance = sd * scale
hospitallimit
= INT(maxpeople
* 0.1)dailylimit
= INT(hospitallimit
/ 7)socialdistancing = 0
'chances
chance.infection = 0.6
chance.death = 0.05
chance.recover = 0.8
chance.statechange = 14 'amount in days
chance.reinfection = 0.002
'chance.severity = 0.01
chance.symptoms = 0.7 'chance of showing symptoms when infected. if not infected, the chance is 1/1000 of that
chance.hospite = 0.8 'chance of getting into a hospital when showing symptoms
chance.curing = 0.2 'chance of getting cured in a hospital
chance.laytime = 7
'-------------------------------------------------------------------------------------------------------- replay settings
'replay speed
resolution = 60 'x frames per recorded day
'--------------------------------------------------------------------------------------------------------
c(6) = c(1)
c(7) = c(4)
restart:
frame = 0
IF _FILEEXISTS("replay.dat") THEN KILL "replay.dat" 'prevents playing old replays and sort of bugging out lol saved = 0
o(i).size = peoplesize
o
(i
).x
= 10 + (RND * ((_WIDTH * 2 / 3) - 10)) retry = 0
FOR j
= 1 TO UBOUND(wall
) 'prevent creation of individuals inside walls IF rectCirc
(wall
(j
), o
(i
), collision
) THEN retry = -1
IF dist!
(o
(i
), o
(p
)) <= o
(i
).size
+ safedistance
AND i
<> p
THEN retry = -1
flip = 1
flip = -1
o(i).id = o(i - 1).id + 1
o(i).id = 1
o
(i
).speed
= (0.2 + (RND * 1.5)) * flip
'base speed + random multiplier and random direction o(i).state = 1
FOR i
= 1 TO totalInfected
o(infected).state = 2
retry = 0
FOR j
= 1 TO UBOUND(wall
) 'prevent creation of individuals inside walls IF rectCirc
(wall
(j
), o
(infected
), collision
) THEN retry = -1
initstatechange = chance.statechange
LINE (wall
(i
).x
, wall
(i
).y
)-STEP(wall
(i
).w
, wall
(i
).h
), _RGB32(255), BF
healthy = 0: contamined = 0: dead = 0: recovered = 0: hospitalizedi = 0: hospitalizedh = 0: hospitalizedr = 0
'1 = healthy; 2 = contamined; 3 = dead; 4 = recovered; 5 = hospitalized with infection; 6 = hospitalized without infection
CASE 5, 6, 7: release o
(i
) checksymptoms o(i)
IF o
(i
).symptoms
= 1 THEN hospital o
(i
) CASE 1, 2, 3, 4, 5, 6, 7: show o
(i
) CASE 1: healthy
= healthy
+ 1 CASE 2: contamined
= contamined
+ 1 CASE 4: recovered
= recovered
+ 1 CASE 5: hospitalizedi
= hospitalizedi
+ 1 CASE 6: hospitalizedh
= hospitalizedh
+ 1 CASE 7: hospitalizedr
= hospitalizedr
+ 1
savedata
frame = frame + 1
stat(frame).dailyintake = dailyintake
IF frame
MOD resolution
= 0 THEN dailyintake
= 0 stat(frame).healthy = healthy
stat(frame).contamined = contamined
stat(frame).dead = dead
stat(frame).recovered = recovered
stat(frame).hospitalizedi = hospitalizedi
stat(frame).hospitalizedh = hospitalizedh
stat(frame).hospitalizedr = hospitalizedr
stat(frame).hospitalized = hospitalizedi + hospitalizedh + hospitalizedr
C = 0: R = 0
FOR i
= frame
- resolution
- 1 TO frame
- 1 C = C + stat(i).contact
R = R + stat(i).infections
R = R / stat(frame).contamined
LOCATE textstatusy
, textstatusx
PRINT "Healthy:", healthy
, , "[F5] to restart simulation" LOCATE textstatusy
+ 1, textstatusx
PRINT "Contamined:", contamined
, , "[F6] to replay" LOCATE textstatusy
+ 2, textstatusx
LOCATE textstatusy
+ 3, textstatusx
PRINT "Recovered:", recovered
, , "People:", people
LOCATE textstatusy
+ 4, textstatusx
PRINT LTRIM$(STR$(INT((stat
(frame
).hospitalized
/ hospitallimit
) * 100)));
"% Hospital utilization at ";
LTRIM$(STR$(INT((stat
(frame
).dailyintake
/ dailylimit
) * 100)));
"% intake rate" LOCATE textstatusy
+ 6, textstatusx
PRINT "Day", INT(frame
/ resolution
) + 1, , , "C="; C;
" R="; R
LOCATE textstatusy
+ 7, textstatusx
PRINT "SIMULATION at" + STR$(1 / ((frameend
- framestart
) * resolution
)) + " days per second"
'graph
LINE (graphlx
, graphly
)-(graphux
, graphuy
), _RGB32(0, 0), BF
graphwidth = graphux - graphlx
hgraphwidth = hgraphux - hgraphlx
graphheight = graphuy - graphly
hgraphheight = hgraphuy - hgraphly
LINE (graphlx
+ ((gp
- 1) * graphwidth
/ UBOUND(stat
)), graphly
)-(graphlx
+ (gp
* graphwidth
/ UBOUND(stat
)), graphly
+ (graphheight
* (stat
(gp
).healthy
/ people
))), c
(1), BF
LINE (graphlx
+ ((gp
- 1) * graphwidth
/ UBOUND(stat
)), graphly
+ (graphheight
* (stat
(gp
).healthy
/ people
)))-(graphlx
+ (gp
* graphwidth
/ UBOUND(stat
)), graphly
+ (graphheight
* ((stat
(gp
).healthy
+ stat
(gp
).contamined
) / people
))), c
(2), BF
LINE (graphlx
+ ((gp
- 1) * graphwidth
/ UBOUND(stat
)), graphly
+ (graphheight
* ((stat
(gp
).healthy
+ stat
(gp
).contamined
) / people
)))-(graphlx
+ (gp
* graphwidth
/ UBOUND(stat
)), graphly
+ (graphheight
* ((stat
(gp
).healthy
+ stat
(gp
).contamined
+ stat
(gp
).dead
) / people
))), c
(3), BF
LINE (graphlx
+ ((gp
- 1) * graphwidth
/ UBOUND(stat
)), graphly
+ (graphheight
* ((stat
(gp
).healthy
+ stat
(gp
).contamined
+ stat
(gp
).dead
) / people
)))-(graphlx
+ (gp
* graphwidth
/ UBOUND(stat
)), graphly
+ (graphheight
* ((stat
(gp
).healthy
+ stat
(gp
).contamined
+ stat
(gp
).dead
+ stat
(gp
).recovered
) / people
))), c
(4), BF
LINE (graphlx
+ ((gp
- 1) * graphwidth
/ UBOUND(stat
)), graphly
+ (graphheight
* ((stat
(gp
).healthy
+ stat
(gp
).contamined
+ stat
(gp
).dead
+ stat
(gp
).recovered
) / people
)))-(graphlx
+ (gp
* graphwidth
/ UBOUND(stat
)), graphuy
), c
(5), BF
LINE (graphlx
+ ((gp
- 1) * graphwidth
/ UBOUND(stat
)), graphuy
- (graphheight
* ((stat
(gp
).contamined
- stat
(gp
- 1).contamined
) / people
)))-(graphlx
+ (gp
* graphwidth
/ UBOUND(stat
)), graphuy
- (graphheight
* ((stat
(gp
).contamined
- stat
(gp
- 1).contamined
) / people
))), _RGB32(255), BF
LINE (hgraphlx
+ ((gp
- 1) * hgraphwidth
/ UBOUND(stat
)), hgraphuy
- ((stat
(gp
).dailyintake
/ hospitallimit
) * hgraphheight
))-(hgraphlx
+ (gp
* hgraphwidth
/ UBOUND(stat
)), hgraphuy
), _RGBA(0, 200, 249, 255 / 2), BF
LINE (hgraphlx
+ ((gp
- 1) * hgraphwidth
/ UBOUND(stat
)), hgraphuy
- ((stat
(gp
).hospitalized
/ hospitallimit
) * hgraphheight
))-(hgraphlx
+ (gp
* hgraphwidth
/ UBOUND(stat
)), hgraphuy
), c
(5), BF
endtime
= TIMER - starttime
'replay
restartreplay:
frame = 0
replayspeed = fps / resolution
healthy = 0: contamined = 0: dead = 0: recovered = 0: hospitalizedi = 0: hospitalizedh = 0: hospitalizedr = 0
dailyintake = 0
LINE (wall
(i
).x
, wall
(i
).y
)-STEP(wall
(i
).w
, wall
(i
).h
), _RGB32(255), BF
'1 = healthy; 2 = contamined; 3 = dead; 4 = recovered; 5 = hospitalized with infection; 6 = hospitalized without infection
CASE 1, 2, 3, 4, 5, 6, 7: show o
(i
) CASE 1: healthy
= healthy
+ 1 CASE 2: contamined
= contamined
+ 1 CASE 4: recovered
= recovered
+ 1 CASE 5: hospitalizedi
= hospitalizedi
+ 1 CASE 6: hospitalizedh
= hospitalizedh
+ 1 CASE 7: hospitalizedr
= hospitalizedr
+ 1 stat
(frame
).contact
= stat
(frame
).contact
/ UBOUND(o
) 'stat(frame).contact = 0
frame = frame + 1
stat(frame).dailyintake = dailyintake
stat(frame).healthy = healthy
stat(frame).contamined = contamined
stat(frame).dead = dead
stat(frame).recovered = recovered
stat(frame).hospitalizedi = hospitalizedi
stat(frame).hospitalizedh = hospitalizedh
stat(frame).hospitalizedr = hospitalizedr
stat(frame).hospitalized = hospitalizedi + hospitalizedh + hospitalizedr
hospitalized = stat(frame).hospitalized
LOCATE textstatusy
, textstatusx
PRINT "Healthy:", healthy
, , "[F5] to restart replay" LOCATE textstatusy
+ 1, textstatusx
PRINT "Contamined:", contamined
, , "[F6] to switch to simulation" LOCATE textstatusy
+ 2, textstatusx
LOCATE textstatusy
+ 3, textstatusx
PRINT "Recovered:", recovered
, , "People:", people
LOCATE textstatusy
+ 4, textstatusx
PRINT LTRIM$(STR$(INT((stat
(frame
).hospitalized
/ hospitallimit
) * 100)));
"% Hospital utilization at ";
LTRIM$(STR$(INT((stat
(frame
).dailyintake
/ dailylimit
) * 100)));
"% intake rate" LOCATE textstatusy
+ 6, textstatusx
PRINT "Day", INT(frame
/ resolution
) + 1, , , PRINT "[F1] to save replay to file" PRINT "- Replay saved! -" LOCATE textstatusy
+ 7, textstatusx
PRINT , , , , "[F2] to load replay from file" LOCATE textstatusy
+ 6, textstatusx
PRINT "REPLAY @ "; replayspeed;
" days per second" PRINT "REPLAY @ "; replayspeed;
" day per second" LOCATE textstatusy
+ 5, textstatusx
LINE (graphlx
, graphly
- 20)-(graphux
, graphly
- 5), _RGB32(255), B
LINE (graphlx
, graphly
- 20)-(graphlx
+ (LOC(1) / LOF(1) * (graphux
- graphlx
)), graphly
- 5), _RGB32(255), BF
'graph
graphwidth = graphux - graphlx
hgraphwidth = hgraphux - hgraphlx
graphheight = graphuy - graphly
hgraphheight = hgraphuy - hgraphly
LINE (graphlx
+ ((gp
- 1) * graphwidth
/ UBOUND(stat
)), graphly
)-(graphlx
+ (gp
* graphwidth
/ UBOUND(stat
)), graphly
+ (graphheight
* (stat
(gp
).healthy
/ people
))), c
(1), BF
LINE (graphlx
+ ((gp
- 1) * graphwidth
/ UBOUND(stat
)), graphly
+ (graphheight
* (stat
(gp
).healthy
/ people
)))-(graphlx
+ (gp
* graphwidth
/ UBOUND(stat
)), graphly
+ (graphheight
* ((stat
(gp
).healthy
+ stat
(gp
).contamined
) / people
))), c
(2), BF
LINE (graphlx
+ ((gp
- 1) * graphwidth
/ UBOUND(stat
)), graphly
+ (graphheight
* ((stat
(gp
).healthy
+ stat
(gp
).contamined
) / people
)))-(graphlx
+ (gp
* graphwidth
/ UBOUND(stat
)), graphly
+ (graphheight
* ((stat
(gp
).healthy
+ stat
(gp
).contamined
+ stat
(gp
).dead
) / people
))), c
(3), BF
LINE (graphlx
+ ((gp
- 1) * graphwidth
/ UBOUND(stat
)), graphly
+ (graphheight
* ((stat
(gp
).healthy
+ stat
(gp
).contamined
+ stat
(gp
).dead
) / people
)))-(graphlx
+ (gp
* graphwidth
/ UBOUND(stat
)), graphly
+ (graphheight
* ((stat
(gp
).healthy
+ stat
(gp
).contamined
+ stat
(gp
).dead
+ stat
(gp
).recovered
) / people
))), c
(4), BF
LINE (graphlx
+ ((gp
- 1) * graphwidth
/ UBOUND(stat
)), graphly
+ (graphheight
* ((stat
(gp
).healthy
+ stat
(gp
).contamined
+ stat
(gp
).dead
+ stat
(gp
).recovered
) / people
)))-(graphlx
+ (gp
* graphwidth
/ UBOUND(stat
)), graphuy
), c
(5), BF
LINE (graphlx
+ ((gp
- 1) * graphwidth
/ UBOUND(stat
)), graphuy
- (graphheight
* ((stat
(gp
).contamined
- stat
(gp
- 1).contamined
) / people
)))-(graphlx
+ (gp
* graphwidth
/ UBOUND(stat
)), graphuy
- (graphheight
* ((stat
(gp
).contamined
- stat
(gp
- 1).contamined
) / people
))), _RGB32(255), BF
LINE (hgraphlx
+ ((gp
- 1) * hgraphwidth
/ UBOUND(stat
)), hgraphuy
- ((stat
(gp
).dailyintake
/ hospitallimit
) * hgraphheight
))-(hgraphlx
+ (gp
* hgraphwidth
/ UBOUND(stat
)), hgraphuy
), _RGBA(0, 200, 249, 255 / 2), BF
LINE (hgraphlx
+ ((gp
- 1) * hgraphwidth
/ UBOUND(stat
)), hgraphuy
- ((stat
(gp
).hospitalized
/ hospitallimit
) * hgraphheight
))-(hgraphlx
+ (gp
* hgraphwidth
/ UBOUND(stat
)), hgraphuy
), c
(5), BF
LOCATE textstatusy
+ 5, textstatusx
loadreplay
restartreplay = 0
PRINT "[F5] to restart replay. [F6] to start a new simulation."
saved = 1
' Do the Open File dialog call!
Filter$ = "Pandemic Replay (*.prp)"
Flags& = OFN_FILEMUSTEXIST + OFN_NOCHANGEDIR + OFN_READONLY ' add flag constants here
OFile$ = GetOpenFileName$("Open Pandemic Replay", ".\", Filter$, 1, Flags&, hWnd&)
IF OFile$
<> "" THEN ' Display Open dialog results restartreplay = 1
SUB pandemicWindow
(lx
, ly
, ux
, uy
) addWall lx, ly + 15, ux - lx, 4
addWall lx, uy, ux - lx - 1, 4
addWall lx, ly, 3, uy - ly
addWall ux - 4, ly + 4, 3, uy - ly
SUB checksymptoms
(this
AS object
) this.symptoms = 1
IF RND * 100000 <= chance.symptoms
THEN '1/1000 chance to show symptoms anyway this.symptoms = 1
SUB hospital
(this
AS object
) IF RND * 100 <= chance.hospite
* 100 AND hospitalized
< hospitallimit
AND dailyintake
< dailylimit
THEN 'only puts you in hospital if you're rich enough $$$$ dailyintake = dailyintake + 1
hospitalized = hospitalized + 1
this.x
= (_WIDTH / 3 * 2) + (this.x
/ 2) this.state = 5 'hospitalized with infection
this.state = 6 'hospitalized healthy
this.state = 7 'hospitalized recovered
this.intake = frame
SUB cure
(this
AS object
) IF this.state
= 5 THEN this.state
= 7 this.symptoms = 0
SUB release
(this
AS object
) IF INT((frame
- this.intake
) / resolution
) >= chance.laytime
+ (RND * (chance.laytime
/ 2)) - (chance.laytime
/ 4) THEN hospitalized = hospitalized - 1
this.state = 2
this.state = 1
this.state = 4
this.symptoms = 0
this.x
= (this.x
- (_WIDTH / 3 * 2)) * 2
SUB evolve
(this
AS object
) 'IF (frame - this.start) / resolution >= (chance.statechange / 2) * RND + (chance.statechange * 0.25) THEN 'if severity occurs, it does so before death
' IF RND * 100 <= chance.severity * 100 THEN 'severity is only relevant when infected
' this.severity = this.severity + 1
' END IF
'END IF
IF INT((frame
- this.start
) / resolution
) >= chance.statechange
+ (RND * (chance.statechange
* 0.5)) THEN this.start = frame
this.state = 3
this.symptoms = 0
this.state = 4
this.symptoms = 0
SUB show
(this
AS object
) IF this.state
= 5 OR this.state
= 6 OR this.state
= 7 THEN CircleFill this.x
, this.y
, this.size
+ 2, c
(5) IF this.symptoms
= 1 THEN CircleFill this.x
, this.y
, this.size
+ 1, _RGB32(255) CircleFill this.x, this.y, this.size, c(this.state)
SUB move
(this
AS object
)
this.x = this.x + (this.xv * this.speed)
this.y = this.y + (this.yv * this.speed)
IF rectCirc
(wall
(i
), this
, collision
) THEN collType = (collision.x + collision.y)
CASE 10, 12: this.xv
= this.xv
* -1 CASE 17, 33: this.yv
= this.yv
* -1 this.xv = this.xv * -1
this.yv = this.yv * -1
person = 0
IF dist
(o
(i
), this
) < this.size
+ (safedistance
* (RND + 0.5)) AND o
(i
).id
<> this.id
AND RND * 100 <= socialdistancing
THEN 'different chance of recognizing safedistance than the infection person = person + 1
moveid(person).id = o(i).id
moveid(person).xv = o(i).xv
moveid(person).yv = o(i).yv
IF dist
(o
(i
), this
) < this.size
+ (safedistance
* RND) AND o
(i
).id
<> this.id
THEN stat(frame).contact = stat(frame).contact + 1
stat(frame).infections = stat(frame).infections + 1
this.state = 2
this.start = frame
stat(frame).infections = stat(frame).infections + 1
this.state = 2
this.start = frame
v.xv = 0
v.yv = 0
v.xv
= v.xv
+ (moveid
(p
).xv
/ UBOUND(moveid
)) v.yv
= v.yv
+ (moveid
(p
).yv
/ UBOUND(moveid
)) this.xv = -this.xv
this.yv = -this.yv
' CX = center x coordinate
' CY = center y coordinate
' R = radius
' C = fill color
RadiusError = -Radius
X = Radius
Y = 0
LINE (CX
- X
, CY
)-(CX
+ X
, CY
), C
, BF
RadiusError = RadiusError + Y * 2 + 1
LINE (CX
- Y
, CY
- X
)-(CX
+ Y
, CY
- X
), C
, BF
LINE (CX
- Y
, CY
+ X
)-(CX
+ Y
, CY
+ X
), C
, BF
X = X - 1
RadiusError = RadiusError - X * 2
Y = Y + 1
LINE (CX
- X
, CY
- Y
)-(CX
+ X
, CY
- Y
), C
, BF
LINE (CX
- X
, CY
+ Y
)-(CX
+ X
, CY
+ Y
), C
, BF
FUNCTION rectCirc%%
(rect
AS object
, circ
AS object
, collision
AS object
) 'adapted from http://www.jeffreythompson.org/collision-detection/circle-rect.php
test.x = circ.x
test.y = circ.y
collision.x = 1
test.x = rect.x
collision.x = 2
test.x = rect.x + rect.w
collision.x = 4
collision.y = 8
test.y = rect.y
collision.y = 16
test.y = rect.y + rect.h
collision.y = 32
rectCirc%% = (dist(circ, test) <= circ.size)
x1! = o1.x
y1! = o1.y
x2! = o2.x
y2! = o2.y
dist!
= _HYPOT((x2!
- x1!
), (y2!
- y1!
))
FUNCTION map!
(value!
, minRange!
, maxRange!
, newMinRange!
, newMaxRange!
) map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
FUNCTION GetOpenFileName$
(Title$
, InitialDir$
, Filter$
, FilterIndex
, Flags&
, hWnd&
) ' Title$ - The dialog title.
' InitialDir$ - If this left blank, it will use the directory where the last opened file is
' located. Specify ".\" if you want to always use the current directory.
' Filter$ - File filters separated by pipes (|) in the same format as using VB6 common dialogs.
' FilterIndex - The initial file filter to use. Will be altered by user during the call.
' Flags& - Dialog flags. Will be altered by the user during the call.
' hWnd& - Your program's window handle that should be aquired by the FindWindow function.
'
' Returns: Blank when cancel is clicked otherwise, the file name selected by the user.
' FilterIndex and Flags& will be changed depending on the user's selections.
DIM OpenCall
AS FILEDIALOGTYPE
' Needed for dialog call
fFilter$ = Filter$
FOR R
= 1 TO LEN(fFilter$
) ' Replace the pipes with character zero fFilter$
= fFilter$
+ CHR$(0)
lpstrFile$
= STRING$(2048, 0) ' For the returned file name lpstrDefExt$
= STRING$(10, 0) ' Extension will not be added when this is not specified OpenCall.lStructSize
= LEN(OpenCall
) OpenCall.hwndOwner = hWnd&
OpenCall.lpstrFilter
= _OFFSET(fFilter$
) OpenCall.nFilterIndex = FilterIndex
OpenCall.lpstrFile
= _OFFSET(lpstrFile$
) OpenCall.nMaxFile
= LEN(lpstrFile$
) - 1 OpenCall.lpstrFileTitle = OpenCall.lpstrFile
OpenCall.nMaxFileTitle = OpenCall.nMaxFile
OpenCall.lpstrInitialDir
= _OFFSET(InitialDir$
) OpenCall.lpstrTitle
= _OFFSET(Title$
) OpenCall.lpstrDefExt
= _OFFSET(lpstrDefExt$
) OpenCall.flags = Flags&
Result = GetOpenFileNameA&(OpenCall) ' Do Open File dialog call!
IF Result
THEN ' Trim the remaining zeros Flags& = OpenCall.flags
FilterIndex = OpenCall.nFilterIndex
FUNCTION GetSaveFileName$
(Title$
, InitialDir$
, Filter$
, FilterIndex
, Flags&
, hWnd&
) ' Title$ - The dialog title.
' InitialDir$ - If this left blank, it will use the directory where the last opened file is
' located. Specify ".\" if you want to always use the current directory.
' Filter$ - File filters separated by pipes (|) in the same format as VB6 common dialogs.
' FilterIndex - The initial file filter to use. Will be altered by user during the call.
' Flags& - Dialog flags. Will be altered by the user during the call.
' hWnd& - Your program's window handle that should be aquired by the FindWindow function.
' Returns: Blank when cancel is clicked otherwise, the file name entered by the user.
' FilterIndex and Flags& will be changed depending on the user's selections.
DIM SaveCall
AS FILEDIALOGTYPE
' Needed for dialog call
fFilter$ = Filter$
FOR R
= 1 TO LEN(fFilter$
) ' Replace the pipes with zeros fFilter$
= fFilter$
+ CHR$(0)
lpstrFile$
= STRING$(2048, 0) ' For the returned file name lpstrDefExt$
= STRING$(10, 0) ' Extension will not be added when this is not specified SaveCall.lStructSize
= LEN(SaveCall
) SaveCall.hwndOwner = hWnd&
SaveCall.lpstrFilter
= _OFFSET(fFilter$
) SaveCall.nFilterIndex = FilterIndex
SaveCall.lpstrFile
= _OFFSET(lpstrFile$
) SaveCall.nMaxFile
= LEN(lpstrFile$
) - 1 SaveCall.lpstrFileTitle = SaveCall.lpstrFile
SaveCall.nMaxFileTitle = SaveCall.nMaxFile
SaveCall.lpstrInitialDir
= _OFFSET(InitialDir$
) SaveCall.lpstrTitle
= _OFFSET(Title$
) SaveCall.lpstrDefExt
= _OFFSET(lpstrDefExt$
) SaveCall.flags = Flags&
Result& = GetSaveFileNameA&(SaveCall) ' Do dialog call!
IF Result&
THEN ' Trim the remaining zeros Flags& = SaveCall.flags
FilterIndex = SaveCall.nFilterIndex