Memory problem with hardware acceleration. [Resolved] Thanks Mark! - Pete - 10-17-2022
This example will not write to your drive. It is a high score hardware overlay, but I stripped out the file stuff.
The overlay is called repeatedly to mimic a flashing cursor. See CALL underline() sub.
What I find is the repeated call keeps copying a new image, one with the cursor showing, and one hidden. That's just 2 images, but since it keeps getting called, instead of switching images (I don;t no how of if that's possible) it just keeps making more of the same alternating screen copy images, which keeps multiplying the memory usage until other OS systems are affected.
You can monitor what I'm talking about by running Windows Task Manager with this code.
Now according to the wiki, I can't use _FREEIMAGE in the loop because I'm not changing screens. I do use it after the original screen is reactivated.
So is there a way to accomplish this flashing cursor effect in the hardware image without burning up the system's memory?
Code: (Select All) $COLOR:32
REM Main
f1 = 22 ' Sets font size to 22 and calculates the max screen height and width for your desktop.
h = (_DESKTOPHEIGHT - 60) \ f1
w = _DESKTOPWIDTH \ (f1 / 1.66)
WIDTH w, h
_SCREENMOVE 0, 0
fontpath$ = ENVIRON$("SYSTEMROOT") + "\fonts\lucon.ttf" 'Find Windows Folder Path.
font& = _LOADFONT(fontpath$, f1, "monospace")
_FONT font&
_DELAY .25
_RESIZE ON , _SMOOTH ' Allows resizing. Note: this is for slight adjustments. As of this version there is no compensatory function to change the font size during screen size changes.
DIM SHARED Overlay, g.population
g.population = 100000
CALL displayhighscores
SUB displayhighscores
hardware_top = v.top + 7
hardware_left = v.left + 35
score$ = LTRIM$(STR$(g.population))
DIM hs AS STRING * 25
REDIM highscore$(6), hsdata$(6)
DO
FOR i = 1 TO 5
hsdata$(i) = SPACE$(25)
NEXT
IF VAL(score$) > VAL(highscore$(5)) THEN
GOSUB hiscore
i = 14
OUT &H3C8, 0
OUT &H3C9, 20 - i
OUT &H3C9, 20 - i
OUT &H3C9, 20 - i
OUT &H3C8, 8
OUT &H3C9, 30 - i
OUT &H3C9, 30 - i
OUT &H3C9, 30 - i
OUT &H3C8, 7
OUT &H3C9, 30 - i
OUT &H3C9, 30 - i
OUT &H3C9, 30 - i
OUT &H3C8, 3
OUT &H3C9, 30 - i
OUT &H3C9, 30 - i
OUT &H3C9, 30 - i
GOSUB hardware_overlay
COLOR White, 0
t$ = msg$
PSLC 4.6, 41 - LEN(msg$) \ 2, t$
lscr = hardware_left + 6
z3 = TIMER
WHILE -1
initials$ = "": i = 0: nxt = 0
COLOR , _RGB(24, 24, 24): t$ = " " ' Blank initials for redo. Okay to blank at start.
PSL hardware_top + 2 + rank * 2, lscr, t$
_DISPLAY
DO
_LIMIT 30
IF ABS(z3 - TIMER) > .3 THEN ' Flashing cursor
underline hardware_top + 2 + rank * 2, lscr + nxt, 0
_DISPLAY
z3 = TIMER
END IF
ky$ = UCASE$(INKEY$)
IF LEN(ky$) THEN
IF ky$ = CHR$(13) THEN
kflag = 3
ELSEIF ky$ = CHR$(8) AND LEN(initials$) THEN
kflag = 2
ELSEIF ky$ = CHR$(27) THEN
kflag = 4
ELSEIF ky$ >= "A" AND ky$ <= "Z" AND LEN(initials$) < 3 THEN
initials$ = initials$ + ky$
kflag = 1
ELSE
ky$ = "": kflag = 0
END IF
END IF
SELECT CASE kflag
CASE 1
COLOR , _RGB(24, 24, 24)
PSL hardware_top + 2 + rank * 2, lscr + nxt, " "
COLOR Yellow
SOUND 1000, .1
PSL hardware_top + 2 + rank * 2, lscr + nxt, ky$
underline hardware_top + 2 + rank * 2, lscr + nxt, -1
nxt = nxt + 1
underline hardware_top + 2 + rank * 2, lscr + nxt, 0
_DISPLAY
kflag = 0
CASE 2
COLOR , _RGB(24, 24, 24)
underline hardware_top + 2 + rank * 2, lscr + nxt, -1
initials$ = MID$(initials$, 1, LEN(initials$) - 1)
nxt = nxt - 1
PSL hardware_top + 2 + rank * 2, lscr + nxt, " "
COLOR Yellow
SOUND 1000, .1
underline hardware_top + 2 + rank * 2, lscr + nxt, 0
_DISPLAY
kflag = 0
CASE 3
_DELAY 1
l$ = "8"
n$ = "n24": PLAY "L" + l$ + n$
n$ = "n28": PLAY "L" + l$ + n$
n$ = "n28": PLAY "L" + l$ + n$
l$ = "7"
n$ = "n31": PLAY "L" + l$ + n$
l$ = "9"
n$ = "n28": PLAY "L" + l$ + n$
l$ = "3"
n$ = "n31": PLAY "L" + l$ + n$
kflag = 1
_DELAY 1: EXIT DO
CASE 4
EXIT WHILE
END SELECT
LOOP
hsname$ = initials$
MID$(hsdata$(rank), 5, 3) = hsname$ + SPACE$(3 - LEN(hsname$))
OPEN "ascii-invaders-high-score.dat" FOR RANDOM AS #1 LEN = 25
FOR i = 1 TO 5
hs = hsdata$(i)
IF LEFT$(hs, 1) = "" THEN MID$(hs, 1, 2) = "0" + LTRIM$(STR$(i))
PUT #1, i, hs
NEXT
CLOSE #1
EXIT WHILE
WEND
_DISPLAY ' Remove scoreboard.
_DELAY .5
_FREEIMAGE Overlay
_DEST 0 'Reset dest back to the normal screen 0.
_AUTODISPLAY
PALETTE
_DELAY .5
EXIT DO
ELSE
EXIT DO ' Not in the top 5 highest scores so exit sub.
END IF
LOOP
EXIT SUB
hardware_overlay:
Overlay = _NEWIMAGE(_WIDTH * _FONTWIDTH, _HEIGHT * _FONTHEIGHT, 32)
_DEST Overlay
_DISPLAY ' Turn autodisplay off.
font = _LOADFONT("lucon.ttf", 24, "monospace")
IF font <= 0 THEN font = 16
_FONT font
bxy% = hardware_top
bxx% = hardware_left
IF VAL(score$) > VAL(highscore$(1)) THEN
t$ = "HIGH SCORE! Enter Initials!"
ELSE
t$ = "Top 5 Score Enter Initials!"
END IF
COLOR White, 0
PSL bxy% + .8, bxx% + 1, t$
COLOR Yellow, 0
t$ = " " + CHR$(218) + STRING$(27, CHR$(196)) + CHR$(191) + " "
PSL bxy%, bxx% - 1, t$
FOR i = 1 TO 12
t$ = " " + CHR$(179) + STRING$(27, CHR$(32)) + CHR$(179) + " "
PSL bxy% + i, bxx% - 1, t$
NEXT
t$ = " " + CHR$(192) + STRING$(27, CHR$(196)) + CHR$(217) + " "
PSL bxy% + i, bxx% - 1, t$
bxy% = hardware_top + 1
COLOR Black, Yellow
t$ = " NAME SCORE DATE "
PSL bxy% + 1, bxx% + 1, t$
COLOR Yellow, 0
FOR i = 1 TO 5
t$ = hsdata$(i)
PSL bxy% + 1 + i * 2, bxx% + 2, t$
NEXT
_DISPLAY
RETURN
hiscore:
FOR i = 1 TO 5
IF VAL(score$) > VAL(highscore$(i)) THEN rank = i: EXIT FOR
NEXT
hsdata$(6) = SPACE$(25)
MID$(hsdata$(6), 10, 6) = score$
MID$(hsdata$(6), 18, 8) = MID$(DATE$, 1, 6) + MID$(DATE$, 9, 2)
highscore$(6) = score$
FOR i = 1 TO 6
FOR j = 1 TO 6
IF i <> j THEN
IF VAL(highscore$(i)) > VAL(highscore$(j)) THEN
SWAP highscore$(i), highscore$(j)
SWAP hsdata$(i), hsdata$(j)
END IF
END IF
NEXT
NEXT
FOR i = 1 TO 5
MID$(hsdata$(i), 1, 2) = "0" + LTRIM$(STR$(i))
NEXT
RETURN
END SUB
SUB PSLC (y!, x, t$)
_PRINTSTRING ((x - 1) * 8, (y! - 1) * 16), t$
END SUB
SUB PSL (y!, x, t$)
_PRINTSTRING ((x - 1) * _FONTWIDTH, (y! - 1) * _FONTHEIGHT), t$
Overlay_Hardware = _COPYIMAGE(Overlay, 33)
_PUTIMAGE (0, 0), Overlay_Hardware
END SUB
SUB underline (y, x, uflag)
STATIC ucnt
ucnt = -ucnt - 1
IF ucnt OR uflag THEN
LINE ((x - 1) * _FONTWIDTH, y * _FONTHEIGHT)-((x - 1) * _FONTWIDTH + 12, y * _FONTHEIGHT), _RGB(24, 24, 24), BF
ELSE
LINE ((x - 1) * _FONTWIDTH, y * _FONTHEIGHT)-((x - 1) * _FONTWIDTH + 12, y * _FONTHEIGHT), Yellow, BF
END IF
Overlay_Hardware = _COPYIMAGE(Overlay, 33)
_PUTIMAGE (0, 0), Overlay_Hardware
END SUB
Pete
RE: Memory problem with hardware acceleration. - bplus - 10-17-2022
Well I am not buying your reason not to use _FreeImage:
Code: (Select All) Sub PSL (y!, x, t$)
_PrintString ((x - 1) * _FontWidth, (y! - 1) * _FontHeight), t$
Overlay_Hardware = _CopyImage(Overlay, 33)
_PutImage (0, 0), Overlay_Hardware
_FreeImage Overlay_Hardware
End Sub
Sub underline (y, x, uflag)
Static ucnt
ucnt = -ucnt - 1
If ucnt Or uflag Then
Line ((x - 1) * _FontWidth, y * _FontHeight)-((x - 1) * _FontWidth + 12, y * _FontHeight), _RGB(24, 24, 24), BF
Else
Line ((x - 1) * _FontWidth, y * _FontHeight)-((x - 1) * _FontWidth + 12, y * _FontHeight), Yellow, BF
End If
Overlay_Hardware = _CopyImage(Overlay, 33)
_PutImage (0, 0), Overlay_Hardware
_FreeImage Overlay_Hardware
End Sub
Memory seems to be holding steady.
This seems pretty complicated way to get flashing cursor, can't it be done in screen 0 and if not in Screen 0 use a line?
OTOH I don't follow all that you do but you put together some nice looking screens.
RE: Memory problem with hardware acceleration. - Pete - 10-17-2022
Hi Mark,
BINGO. +1.
That worked. QB64 help says you can't free it until you exit the screen. My goof was I was experimenting trying to free it by using...
_FREEIMAGE overlay
instead of...
_FREEIMAGE hardware_overlay
The former was causing errors to pop up.
Thanks!
Pete
PS Yes, you can easily mimic cursor flashing in SCREEN 0, which has a flashing text cursor, SCREEN 12 (no cursor), etc. but it is a bit more involved when using a hardware image overlay. I'm doing it this way for the overlap effect.
|