From 0baed69d7aedf3da649522dc1062adb3b2dc99c7 Mon Sep 17 00:00:00 2001 From: Svjatoslav Agejenko Date: Sun, 24 Aug 2025 23:03:04 +0300 Subject: [PATCH] Better code readability --- Games/Pomppu Paavo/Pomppu Paavo.bas | 103 ++++++++++++++++++---------- 1 file changed, 68 insertions(+), 35 deletions(-) diff --git a/Games/Pomppu Paavo/Pomppu Paavo.bas b/Games/Pomppu Paavo/Pomppu Paavo.bas index 57cd220..7017b72 100755 --- a/Games/Pomppu Paavo/Pomppu Paavo.bas +++ b/Games/Pomppu Paavo/Pomppu Paavo.bas @@ -1,4 +1,4 @@ -DECLARE SUB RenderSpriteFromFile (p%, o%, m%, fr%, teler%) +DECLARE SUB RenderSpriteFromFile (p%, O%, m%, fr%, teler%) ' Pomppu Paavo ' ' This program is free software: released under Creative Commons Zero (CC0) license @@ -75,6 +75,7 @@ DIM SHARED PlayerRunLeft2SpriteSmall(51) DIM SHARED PlayerJumpingSpriteSmall(51) DIM SHARED DoorSpriteSmall(50) +' Define keyboard control sequences leftArrowKey$ = CHR$(0) + "K" rightArrowKey$ = CHR$(0) + "M" upArrowKey$ = CHR$(0) + "H" @@ -236,7 +237,8 @@ PUT (Companion1PositionX%, Companion1PositionY%), HedgehogSprite, OR GET (Companion2PositionX%, Companion2PositionY%)-(Companion2PositionX% + 10, Companion2PositionY% + 10), HedgehogSprite2 PUT (Companion2PositionX%, Companion2PositionY%), HedgehogSprite, OR -' Create short delay using sound command (workaround for no built-in delay) +' Create short delay using sound command (workaround since QBasic lacks built-in sub-second delay) +' SOUND 0,0.8 creates an inaudible tone that takes approximately 8 milliseconds to process SOUND 0, .8 ' Check collisions with terrain (z = solid block) @@ -647,46 +649,77 @@ NEXT e 123 END SUB -SUB RenderSpriteFromFile (p, o, m, fr, teler) -' Renders a sprite on screen loaded from file "img/.i01" +SUB RenderSpriteFromFile (x%, y%, spriteID%, animationFrame%, scaleFactor%) ' -' File format: First line = height (number of rows) -' Subsequent lines = strings of digit characters ('0'-'3') representing pixel colors +' Renders a sprite on screen by loading pixel data from external file +' File format explanation: +' - First line contains height (number of rows) +' - Subsequent lines contain strings of digit characters: +' '0' = transparent/background +' '1'-'3' = color indexes (mapped to current palette) +' Example file for 3x2 sprite: +' 2 +' 123 +' 010 +' +' Parameters: +' x%, y% = Top-left drawing position +' spriteID% = Which sprite file to load (img/.i01) +' animationFrame% = Special handling: +' 1 = normal rendering +' 50 = horizontally flipped +' Other values = scaled rendering (value = scale factor) +' scaleFactor% = Pixel scaling factor (1 = full size, 2 = half size) + DIM rowText AS STRING -fileName$ = "img/" + LTRIM$(STR$(m)) + ".i01" +fileName$ = "img/" + LTRIM$(STR$(spriteID%)) + ".i01" OPEN fileName$ FOR INPUT AS #1 INPUT #1, height% -DIM ao(1 TO 100) AS STRING -FOR a = 1 TO height% -LINE INPUT #1, ao(a) -NEXT a +DIM spritePixelRows(1 TO 100) AS STRING +FOR rowIndex% = 1 TO height% + LINE INPUT #1, spritePixelRows(rowIndex%) +NEXT rowIndex% CLOSE #1 -IF fr = 50 THEN GOTO DrawFlippedSprite -IF fr > 1 THEN GOTO DrawScaledSprite -FOR a = 1 TO 100 ' Normal sprite -IF ao(a) = "" THEN GOTO FinishDrawing -FOR b = 1 TO LEN(ao(a)) -PSET ((p + b) \ teler, (o + a) \ teler), ASC(RIGHT$(LEFT$(ao(a), b), 1)) - 48 -NEXT b -NEXT a + +' Handle special rendering modes based on animationFrame parameter +IF animationFrame% = 50 THEN GOTO DrawFlippedSprite +IF animationFrame% > 1 THEN GOTO DrawScaledSprite + +' Normal rendering mode (1:1 pixels) +FOR rowIndex% = 1 TO 100 + IF spritePixelRows(rowIndex%) = "" THEN GOTO FinishDrawing + FOR columnIndex% = 1 TO LEN(spritePixelRows(rowIndex%)) + ' Convert character digit to numeric color value (0-3) + pixelColor% = ASC(RIGHT$(LEFT$(spritePixelRows(rowIndex%), columnIndex%), 1)) - 48 + ' Calculate actual screen position considering scaleFactor + PSET ((x% + columnIndex%) \ scaleFactor%, (y% + rowIndex%) \ scaleFactor%), pixelColor% + NEXT columnIndex% +NEXT rowIndex% GOTO FinishDrawing -DrawScaledSprite: ' Scaled sprite -FOR a = 1 TO 100 -IF ao(a) = "" THEN GOTO FinishDrawing -FOR b = 1 TO LEN(ao(a)) -c = ASC(RIGHT$(LEFT$(ao(a), b), 1)) - 48 -LINE (p + (b * fr), o + (a * fr))-(p + (b * fr) + fr, o + (a * fr) + fr), c, BF -NEXT b -NEXT a + +DrawScaledSprite: +' Scaled rendering mode (stretches pixels) +FOR rowIndex% = 1 TO 100 + IF spritePixelRows(rowIndex%) = "" THEN GOTO FinishDrawing + FOR columnIndex% = 1 TO LEN(spritePixelRows(rowIndex%)) + pixelColor% = ASC(RIGHT$(LEFT$(spritePixelRows(rowIndex%), columnIndex%), 1)) - 48 + ' Draw filled rectangle instead of single pixel + LINE (x% + (columnIndex% * animationFrame%), y% + (rowIndex% * animationFrame%))-(x% + (columnIndex% * animationFrame%) + animationFrame%, y% + (rowIndex% * animationFrame%) + animationFrame%), pixelColor%, BF + NEXT columnIndex% +NEXT rowIndex% GOTO FinishDrawing -DrawFlippedSprite: ' Horizontally flipped sprite -FOR a = 1 TO 100 -IF ao(a) = "" THEN GOTO FinishDrawing -FOR b = 1 TO LEN(ao(a)) -PSET ((p + (LEN(ao(a)) - b + 1)) \ teler, (o + a) \ teler), ASC(RIGHT$(LEFT$(ao(a), b), 1)) - 48 -NEXT b -NEXT a + +DrawFlippedSprite: +' Horizontally flipped rendering +FOR rowIndex% = 1 TO 100 + IF spritePixelRows(rowIndex%) = "" THEN GOTO FinishDrawing + FOR columnIndex% = 1 TO LEN(spritePixelRows(rowIndex%)) + ' Note: X position is mirrored (right-to-left) + PSET ((x% + (LEN(spritePixelRows(rowIndex%)) - columnIndex% + 1)) \ scaleFactor%, (y% + rowIndex%) \ scaleFactor%), ASC(RIGHT$(LEFT$(spritePixelRows(rowIndex%), columnIndex%), 1)) - 48 + NEXT columnIndex% +NEXT rowIndex% + FinishDrawing: -ERASE ao +ERASE spritePixelRows END SUB -- 2.20.1