07-08-2025, 05:43 PM
@NakedApe One thing you want to be careful of -- for each _LOAD or _NEW statement in your program, you ***MUST*** have a cooresponding _FREE statement to go with them. (Well, you don't have to have one -- if you prefer a memory leak that uses more and more resources until your program explodes and melts down, I guess that's up to you...
)
Let's look at the code line by line:
Option _Explicit
Dim As Long image, virt, label, font, a
Dim As Integer w, h: w = 260: h = 400
Screen _NewImage(1920, 1080, 32): _FullScreen
$Color:32
font = _LoadFont("futura.ttc", 20)
virt = _NewImage(w, h, 32) ' small virtual screen
image = _CopyImage(virt, 32) ' a copy of virt
label = _CopyImage(image, 33) ' a hardware version
At this point, you have now loaded one font and four images. (Two _NewImage statements and two _CopyImage statements.)
' -----------------------------------------
' print to small "virt" software screen ** GENERATE TILTED SHIP & TARGET LABELS **
_Dest virt: _Font font: Color Yellow
_PrintString (_Width(virt) \ 2 - _PrintWidth("SHIP: ") \ 2, _Height(virt) \ 2 - 10), "SHIP: " '
Color Red
_PrintString (_Width(virt) \ 2 - _PrintWidth("TARG: ") \ 2, _Height(virt) \ 2 + 20), "TARG: " ' adding virt as dest at EOL fails, must use _Dest virt instead
' convert virt to hardware "image"
Here, you still have that single font and 4 images in memory...
image = _CopyImage(virt, 33) '
But here, you just made a fifth image in memory, and overwrote your old image handle without freeing the old image. How the heck are you ever going to free that old image now? You have no reference handle pointing to it, so... ???? You've now trapped the old handle and image in memory forever. HELLO MEMORY LEAK!!
' tweak "image" with _MapTriangle to "label" hardware screen
_MapTriangle (0, 0)-(0, h - 1)-(w - 1, h - 1), image To(-8, 8, -12)-(-8, -8, -4)-(8, -8, -4), label '
_MapTriangle (0, 0)-(w - 1, h - 1)-(w - 1, 0), image To(-8, 8, -12)-(8, -8, -4)-(8, 8, -12), label '
' -----------------------------------------
At this point there are now five images in memory and one font... Nothing has been freed.
font = _LoadFont("futura.ttc", 26) ' ** GENERATE TILTED SHIP ANGLE NUMBERS **
And now, it's the same thing as before. A second font is now loaded, without freeing the old font. You now have two fonts in memory, and you have overwritten and lost the handle on the first one. Once again, how do you ever expect to free that first font from memory?? You don't have the handle to it anymore... ANOTHER MEMORY LEAK!!
Dim As Long virt2, image2, shipCard(359)
Dim As _Unsigned Long col
So we now have two fonts and five images loaded in memory....
virt2 = _NewImage(w, h, 32) '
Errr.... Make that two fonts and six images.
' -------------------
_Source (virt2): col = Point(0, 0) ' <<<< THIS ISN'T WORKING <<<<
_ClearColor col, virt2
' -------------------
image2 = _CopyImage(virt2, 32) '
Two fonts and seven images....
For a = 0 To 359: shipCard(a) = _CopyImage(image2, 33): Next '
_Dest virt2 '
w = 260: h = 500
Cls: _Font font: Color Yellow
OH NOS!!! NOW WE GO INTO A LOOP!!!!!!!!!!
For a = 0 To 359
_PrintString (_Width(virt2) \ 2, _Height(virt2) \ 2 - 10), Str$(a) + " " '
image2 = _CopyImage(virt2, 33) '
_MapTriangle (0, 0)-(0, h - 1)-(w - 1, h - 1), image2 To(-8, 8, -12)-(-8, -8, -4)-(8, -8, -4), shipCard(a) '
_MapTriangle (0, 0)-(w - 1, h - 1)-(w - 1, 0), image2 To(-8, 8, -12)-(8, -8, -4)-(8, 8, -12), shipCard(a) '
Next
We now have two fonts and 367 images loaded in memory, with absolutely no way to reference those 360 image2 images that we just overwrote repeatedly!!!!!
' -----------------------------------------
font = _LoadFont("futura.ttc", 21) ' ** GENERATE TILTED TARGET ANGLE NUMBERS **
Wait... Make that three fonts and 367 images....
Dim As Long virt3, image3, targCard(359)
virt3 = _NewImage(w, h, 32) '
Three fonts and 368 images in memory....
'_Source (virt3): col = Point(0, 0) '
'_ClearColor col, virt3
OMG!! ANOTHER LOOP!!!
image3 = _CopyImage(virt3, 32) '
For a = 0 To 359: targCard(a) = _CopyImage(image3, 33): Next '
Three fonts and now... a SHITLOAD of images in memory...
_Dest virt3 '
w = 260: h = 500
Cls: _Font font: Color Red
WHEE!! ANOTHER LOOP!!!
For a = 0 To 359
_PrintString (_Width(virt3) \ 2, _Height(virt3) \ 2 - 10), Str$(a) + " " '
image3 = _CopyImage(virt3, 33) '
_MapTriangle (0, 0)-(0, h - 1)-(w - 1, h - 1), image3 To(-8, 8, -12)-(-8, -8, -4)-(8, -8, -4), targCard(a) '
_MapTriangle (0, 0)-(w - 1, h - 1)-(w - 1, 0), image3 To(-8, 8, -12)-(8, -8, -4)-(8, 8, -12), targCard(a) '
Next
_Dest 0
Three fonts and ... a METRIC SHIT TON of images!!!!
For a = 0 To 359 ' ** PUT TO SCREEN **
If a < 10 Then
_PutImage (_Width \ 2 - _Width(label) \ 2 - 10, _Height \ 2 - _Height(label) \ 2 + 34), shipCard(a), 0 '
_PutImage (_Width \ 2 - _Width(label) \ 2 - 10, _Height \ 2 - _Height(label) \ 2 - 18), targCard(a), 0 ' <<<< TARGET NUMBERS BLOCK SHIP NUMBERS
End If
If a > 9 _AndAlso a < 100 Then
_PutImage (_Width \ 2 - _Width(label) \ 2 - 30, _Height \ 2 - _Height(label) \ 2 + 34), shipCard(a), 0 '
_PutImage (_Width \ 2 - _Width(label) \ 2 - 30, _Height \ 2 - _Height(label) \ 2 - 18), targCard(a), 0 '
End If
If a >= 100 Then
_PutImage (_Width \ 2 - _Width(label) \ 2 - 50, _Height \ 2 - _Height(label) \ 2 + 34), shipCard(a), 0 '
_PutImage (_Width \ 2 - _Width(label) \ 2 - 45, _Height \ 2 - _Height(label) \ 2 - 18), targCard(a), 0 '
End If
_PutImage (_Width \ 2 - _Width(label) \ 2 - 100, _Height \ 2 - _Height(label) \ 2), label, 0 ' add label last
_Display '
_Delay .025 '
If _KeyHit = 27 Then Exit For
Next
_Delay .5
_FreeImage virt: _FreeImage image: _FreeImage label
_FreeImage virt2: _FreeImage image2
_FreeImage virt3: _FreeImage image3
For a = 0 To 359: _FreeImage shipCard(a): _FreeImage targCard(a): Next
System
So... How many resources are still floating around, never to be freed in the program, before that system call shuts it all down?? Did you keep track?
Seems to me like you have three fonts that are never _FREE and over 360+ images which are never _FREE... And, which you can't easily *EVER* free as you overwrote the handle which references them.
Perhaps you might want to consider writing your own SafeLoad commands such as something like this:
SUB SaveLoadImage (image As String, handle As LONG)
IF handle <> 0 then _FREEIMAGE handle 'free the old image before shooting for a new one.
handle = 0 'reset the handle to 0 to show that the image has been freed at this point
temp_handle = _LOADIMAGE(image)
IF temp_handle < -1 THEN 'it's a valid image
handle = temp_handle
END IF
END SUB
Now, with that little routine, you automatically free up the old handle before overwriting it with a new image. You'd still need to free the handles once you're completely done with them and aren't using them any longer, but a simple routine like this would keep you from overwriting old handles and losing them forever.
It's the type of self/automatic maintenance which I strongly recommend folks get used to doing. It'll catch a boatload of issues for you and can save you from a ton of memory leaks and issues in your code.
)Let's look at the code line by line:
Option _Explicit
Dim As Long image, virt, label, font, a
Dim As Integer w, h: w = 260: h = 400
Screen _NewImage(1920, 1080, 32): _FullScreen
$Color:32
font = _LoadFont("futura.ttc", 20)
virt = _NewImage(w, h, 32) ' small virtual screen
image = _CopyImage(virt, 32) ' a copy of virt
label = _CopyImage(image, 33) ' a hardware version
At this point, you have now loaded one font and four images. (Two _NewImage statements and two _CopyImage statements.)
' -----------------------------------------
' print to small "virt" software screen ** GENERATE TILTED SHIP & TARGET LABELS **
_Dest virt: _Font font: Color Yellow
_PrintString (_Width(virt) \ 2 - _PrintWidth("SHIP: ") \ 2, _Height(virt) \ 2 - 10), "SHIP: " '
Color Red
_PrintString (_Width(virt) \ 2 - _PrintWidth("TARG: ") \ 2, _Height(virt) \ 2 + 20), "TARG: " ' adding virt as dest at EOL fails, must use _Dest virt instead
' convert virt to hardware "image"
Here, you still have that single font and 4 images in memory...
image = _CopyImage(virt, 33) '
But here, you just made a fifth image in memory, and overwrote your old image handle without freeing the old image. How the heck are you ever going to free that old image now? You have no reference handle pointing to it, so... ???? You've now trapped the old handle and image in memory forever. HELLO MEMORY LEAK!!
' tweak "image" with _MapTriangle to "label" hardware screen
_MapTriangle (0, 0)-(0, h - 1)-(w - 1, h - 1), image To(-8, 8, -12)-(-8, -8, -4)-(8, -8, -4), label '
_MapTriangle (0, 0)-(w - 1, h - 1)-(w - 1, 0), image To(-8, 8, -12)-(8, -8, -4)-(8, 8, -12), label '
' -----------------------------------------
At this point there are now five images in memory and one font... Nothing has been freed.
font = _LoadFont("futura.ttc", 26) ' ** GENERATE TILTED SHIP ANGLE NUMBERS **
And now, it's the same thing as before. A second font is now loaded, without freeing the old font. You now have two fonts in memory, and you have overwritten and lost the handle on the first one. Once again, how do you ever expect to free that first font from memory?? You don't have the handle to it anymore... ANOTHER MEMORY LEAK!!
Dim As Long virt2, image2, shipCard(359)
Dim As _Unsigned Long col
So we now have two fonts and five images loaded in memory....
virt2 = _NewImage(w, h, 32) '
Errr.... Make that two fonts and six images.
' -------------------
_Source (virt2): col = Point(0, 0) ' <<<< THIS ISN'T WORKING <<<<
_ClearColor col, virt2
' -------------------
image2 = _CopyImage(virt2, 32) '
Two fonts and seven images....
For a = 0 To 359: shipCard(a) = _CopyImage(image2, 33): Next '
_Dest virt2 '
w = 260: h = 500
Cls: _Font font: Color Yellow
OH NOS!!! NOW WE GO INTO A LOOP!!!!!!!!!!
For a = 0 To 359
_PrintString (_Width(virt2) \ 2, _Height(virt2) \ 2 - 10), Str$(a) + " " '
image2 = _CopyImage(virt2, 33) '
_MapTriangle (0, 0)-(0, h - 1)-(w - 1, h - 1), image2 To(-8, 8, -12)-(-8, -8, -4)-(8, -8, -4), shipCard(a) '
_MapTriangle (0, 0)-(w - 1, h - 1)-(w - 1, 0), image2 To(-8, 8, -12)-(8, -8, -4)-(8, 8, -12), shipCard(a) '
Next
We now have two fonts and 367 images loaded in memory, with absolutely no way to reference those 360 image2 images that we just overwrote repeatedly!!!!!
' -----------------------------------------
font = _LoadFont("futura.ttc", 21) ' ** GENERATE TILTED TARGET ANGLE NUMBERS **
Wait... Make that three fonts and 367 images....
Dim As Long virt3, image3, targCard(359)
virt3 = _NewImage(w, h, 32) '
Three fonts and 368 images in memory....
'_Source (virt3): col = Point(0, 0) '
'_ClearColor col, virt3
OMG!! ANOTHER LOOP!!!
image3 = _CopyImage(virt3, 32) '
For a = 0 To 359: targCard(a) = _CopyImage(image3, 33): Next '
Three fonts and now... a SHITLOAD of images in memory...
_Dest virt3 '
w = 260: h = 500
Cls: _Font font: Color Red
WHEE!! ANOTHER LOOP!!!
For a = 0 To 359
_PrintString (_Width(virt3) \ 2, _Height(virt3) \ 2 - 10), Str$(a) + " " '
image3 = _CopyImage(virt3, 33) '
_MapTriangle (0, 0)-(0, h - 1)-(w - 1, h - 1), image3 To(-8, 8, -12)-(-8, -8, -4)-(8, -8, -4), targCard(a) '
_MapTriangle (0, 0)-(w - 1, h - 1)-(w - 1, 0), image3 To(-8, 8, -12)-(8, -8, -4)-(8, 8, -12), targCard(a) '
Next
_Dest 0
Three fonts and ... a METRIC SHIT TON of images!!!!
For a = 0 To 359 ' ** PUT TO SCREEN **
If a < 10 Then
_PutImage (_Width \ 2 - _Width(label) \ 2 - 10, _Height \ 2 - _Height(label) \ 2 + 34), shipCard(a), 0 '
_PutImage (_Width \ 2 - _Width(label) \ 2 - 10, _Height \ 2 - _Height(label) \ 2 - 18), targCard(a), 0 ' <<<< TARGET NUMBERS BLOCK SHIP NUMBERS
End If
If a > 9 _AndAlso a < 100 Then
_PutImage (_Width \ 2 - _Width(label) \ 2 - 30, _Height \ 2 - _Height(label) \ 2 + 34), shipCard(a), 0 '
_PutImage (_Width \ 2 - _Width(label) \ 2 - 30, _Height \ 2 - _Height(label) \ 2 - 18), targCard(a), 0 '
End If
If a >= 100 Then
_PutImage (_Width \ 2 - _Width(label) \ 2 - 50, _Height \ 2 - _Height(label) \ 2 + 34), shipCard(a), 0 '
_PutImage (_Width \ 2 - _Width(label) \ 2 - 45, _Height \ 2 - _Height(label) \ 2 - 18), targCard(a), 0 '
End If
_PutImage (_Width \ 2 - _Width(label) \ 2 - 100, _Height \ 2 - _Height(label) \ 2), label, 0 ' add label last
_Display '
_Delay .025 '
If _KeyHit = 27 Then Exit For
Next
_Delay .5
_FreeImage virt: _FreeImage image: _FreeImage label
_FreeImage virt2: _FreeImage image2
_FreeImage virt3: _FreeImage image3
For a = 0 To 359: _FreeImage shipCard(a): _FreeImage targCard(a): Next
System
So... How many resources are still floating around, never to be freed in the program, before that system call shuts it all down?? Did you keep track?
Seems to me like you have three fonts that are never _FREE and over 360+ images which are never _FREE... And, which you can't easily *EVER* free as you overwrote the handle which references them.
Perhaps you might want to consider writing your own SafeLoad commands such as something like this:
SUB SaveLoadImage (image As String, handle As LONG)
IF handle <> 0 then _FREEIMAGE handle 'free the old image before shooting for a new one.
handle = 0 'reset the handle to 0 to show that the image has been freed at this point
temp_handle = _LOADIMAGE(image)
IF temp_handle < -1 THEN 'it's a valid image
handle = temp_handle
END IF
END SUB
Now, with that little routine, you automatically free up the old handle before overwriting it with a new image. You'd still need to free the handles once you're completely done with them and aren't using them any longer, but a simple routine like this would keep you from overwriting old handles and losing them forever.
It's the type of self/automatic maintenance which I strongly recommend folks get used to doing. It'll catch a boatload of issues for you and can save you from a ton of memory leaks and issues in your code.

