Qbasicnews.com

Full Version: Guess what? MORE OPTIMIZING! :)
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
OK, I'm in my college CS class and I'm really bored, so I went and programmed a scroller. The problem is... I get 16 FPS and it's not even full screen. Here I thought my DrawSprite routine was fast... anyway, here's the code, try to get it zippity zappy. If you have to convert the graphics to N13 (double the memory, no more DEF SEG though) so be it.

Code:
DEFINT A-Z
'$DYNAMIC
DECLARE SUB DrawSprite (Sprite(), X, Y, frame)
DECLARE SUB nPrint (Xpos%, Ypos%, Text$, col%)
DECLARE SUB Scroll ()
DIM SHARED buffer(32001), lutsegy(199) AS LONG, Map(21, 14), CamX, CamY
buffer(0) = 2560: buffer(1) = 200
CONST minXXwin = 99, minYYwin = 49
CONST maxXXwin = 219, maxYYwin = 149
FOR n& = 0 TO 199
lutsegy(n&) = n& * 320 + 4
NEXT

SCREEN 13
FOR Y = 0 TO 15
FOR X = 0 TO 15
  PSET (X, Y), RND * 15 + 16
NEXT
NEXT
DIM SHARED tiles((16 * 16) \ 2 + 1)
GET (0, 0)-(15, 15), tiles

t# = TIMER
DO
Scroll
nPrint 100, 20, "Mmm, Scrolling...", 24
PUT (0, 0), buffer, PSET
REDIM buffer(32001): buffer(0) = 2560: buffer(1) = 200
CamX = CamX + 1
CamY = CamY + 1
LOOP UNTIL LEN(INKEY$)
PRINT CamX / (TIMER - t#)

SUB DrawSprite (Sprite(), X, Y, frame)
DIM addr AS LONG
TileW = Sprite(0) \ 8
TileH = Sprite(1)
TW = TileW - 1
TH = TileH - 1
TF = frame - 1
TP = TileW * TileH
IF TF AND 1 THEN
    ToffsBYT = (frame * 4) + TF + TP * TF
ELSE
    ToffsBYT = frame * 4 + TP * TF
END IF

xLeft = X
xRight = X + TW
yTop = Y
yBot = Y + TH

IF xLeft < minXXwin THEN
  sum = minXXwin - xLeft
  IF sum < 0 THEN sum = -sum
  IF sum > TW THEN EXIT SUB
  CLIPadd = sum
  CLIPleft = sum
  xLeft = minXXwin
END IF

IF xRight > maxXXwin THEN
  sum = xRight - maxXXwin
  IF sum < 0 THEN sum = -sum
  IF sum > TW THEN EXIT SUB
  CLIPadd = sum
  xRight = maxXXwin
END IF

IF yTop < minYYwin THEN
  sum = minYYwin - yTop
  IF sum > TH THEN EXIT SUB
  CLIPtop = sum * TileW
  yTop = minYYwin
END IF

IF yBot > maxYYwin THEN
  sum = yBot - maxYYwin
  IF sum > TH THEN EXIT SUB
  yBot = maxYYwin
END IF

t = ToffsBYT + CLIPleft + CLIPtop

addr = lutsegy(yTop)

FOR yy = yTop TO yBot
  FOR xx = xLeft TO xRight
    DEF SEG = VARSEG(Sprite(0))
      c = PEEK(t)
    DEF SEG = VARSEG(buffer(0))
      POKE addr + xx, c
    t = t + 1
  NEXT
  t = t + CLIPadd
  addr = addr + 320
NEXT

END SUB

REM $STATIC
SUB nPrint (Xpos%, Ypos%, Text$, col%)
X% = Xpos%
Y% = Ypos%
FOR I% = 0 TO LEN(Text$) - 1
  X% = X% + 8
  Offset% = 8 * ASC(MID$(Text$, I% + 1, 1)) + 14
  FOR J% = 0 TO 7
    DEF SEG = &HFFA6
    Bit% = PEEK(Offset% + J%)
    DEF SEG = VARSEG(buffer(0))
    IF Bit% AND 1 THEN POKE X% + lutsegy(Y% + J%), col% + J%
    IF Bit% AND 2 THEN POKE X% - 1 + lutsegy(Y% + J%), col% + J%
    IF Bit% AND 4 THEN POKE X% - 2 + lutsegy(Y% + J%), col% + J%
    IF Bit% AND 8 THEN POKE X% - 3 + lutsegy(Y% + J%), col% + J%
    IF Bit% AND 16 THEN POKE X% - 4 + lutsegy(Y% + J%), col% + J%
    IF Bit% AND 32 THEN POKE X% - 5 + lutsegy(Y% + J%), col% + J%
    IF Bit% AND 64 THEN POKE X% - 6 + lutsegy(Y% + J%), col% + J%
    IF Bit% AND 128 THEN POKE X% - 7 + lutsegy(Y% + J%), col% + J%
  NEXT J%
NEXT I%

END SUB

SUB Scroll
CamXtile = CamX \ 16
CamYtile = CamY \ 16
ppX = CamX AND 15
ppY = CamY AND 15
FOR Y = 0 TO 14
FOR X = 0 TO 21
  'xt = x + CamXtile
  tile = Map(X, Y) + 1
  DrawSprite tiles(), X * 16 - ppX, Y * 16 - ppY, tile
NEXT
NEXT
END SUB
bah... pureqb.

if all the tiles are the same size, make an extra blit routine (or just render it in the drawmap sub, which would be faster) that only does 16x16 or whatever the tile size is, and then unroll the x loop. and while it would take up extra memory, it would be faster to store your sprite info in a linear array instead of having to switch your def seg every pixel twice and peek it into another variable. just store the values in integers.
How do you unroll a loop? Wanna... do it for me? Tongue
erm...

Code:
n = sx + sy * 320&
for x = 0 to 15
  rx = rx + 16
  poke n, sprite(x)
  poke n + 1, sprite(rx + 1)
  poke n + 2, sprite(rx + 2)
  poke n + 3, sprite(rx + 3)
  poke n + 4, sprite(rx + 4)
  poke n + 5, sprite(rx + 5)
  poke n + 6, sprite(rx + 6)
  poke n + 7, sprite(rx + 7)
  poke n + 8, sprite(rx + 8)
  poke n + 9, sprite(rx + 9)
  poke n + 10, sprite(rx + 10)
  poke n + 11, sprite(rx + 11)
  poke n + 12, sprite(rx + 12)
  poke n + 13, sprite(rx + 13)
  poke n + 14, sprite(rx + 14)
  poke n + 15, sprite(rx + 15)
  n = n + 320
next x
That's why macro replacement functions of C/C++ unroll short loops! I HATE THE QB COMPILER! :evil:
Enough with the macros already...
Fine..
Fine.
You guys remind me of the "dude" scene in Baseketball. Speaking of which, I'm gonna download that right now! (Gotta love broadband and CDRs)