Qbasicnews.com

Full Version: Floormapping optimization.
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3 4 5
Hey, I decided to join this place after some nudging from Mofu, so... I guess I'll start out with a question.

How can I optimize this floormapping code to be realllly reallllllly fast, like pasco's floormapper?

Note: I tried to make this pure qb, but I wouldn't let me blit the buffer to the screen with PUT, so I had to use gslib's pcopy.
::EDIT::
Ok, I fixed it, code updated.

::EDIT 2::
Lithium gave me some advice on the MOD, so that's updated.
Code:
'$DYNAMIC
DEFINT A-Z
DIM SHARED PIC(63, 63)
DIM SHARED buffer(32001) AS INTEGER
DIM SHARED Sine(1920) AS SINGLE, Cosine(1920) AS SINGLE
DIM SHARED Raylength(99), lsy(199) AS LONG, presum AS LONG

t# = TIMER
CameraHeight = 100
CameraDistance = 128

FOR i# = 0 TO 6.28165 STEP 6.28165 / 1920
Sine(a) = SIN(i#)
Cosine(a) = COS(i#)
a = a + 1
NEXT

FOR y = 0 TO 63
FOR x = 0 TO 63
  PIC(x, y) = COS(x / 30) * SIN(y / 30) * 4 + 24
  NEXT
NEXT

FOR n = 0 TO 99
Raylength(n) = (CameraHeight / (CameraHeight - n)) * CameraDistance
NEXT

FOR n& = 0 TO 199
lsy(n&) = n& * 320 + 4
NEXT

SCREEN 13
buffer(0) = 2560: buffer(1) = 200
DEF SEG = VARSEG(buffer(0))

PlayerX = 0
PlayerAngle = 1920 / 4
PlayerY = 0

DO
  PlayerX = PlayerX + 10 * Cosine(PlayerAngle)
  PlayerY = PlayerY + 10 * Sine(PlayerAngle)

  presum = lsy(100)
FOR y = 99 TO 0 STEP -1
  xang = PlayerAngle - 159
  IF xang < 0 THEN xang = xang + 1920

  FOR x = 0 TO 319
   vx = PlayerX + Raylength(y) * Cosine(xang)
   vy = PlayerY + Raylength(y) * Sine(xang)
   POKE presum + x, (PIC(ABS(vx) MOD 64, ABS(vy) MOD 64))
   xang = xang + 1
   IF xang > 1919 THEN xang = 0
  NEXT

  presum = presum + 320
NEXT

  presum = lsy(99)
FOR y = 99 TO 0 STEP -1
  xang = PlayerAngle - 159
  IF xang < 0 THEN xang = xang + 1920
  FOR x = 0 TO 319
   vx = PlayerX + Raylength(y) * Cosine(xang)
   vy = PlayerY + Raylength(y) * Sine(xang)
   POKE presum + x, (PIC(ABS(vx) AND 63, ABS(vy) AND 63))
   xang = xang + 1
   IF xang > 1919 THEN xang = 0
  NEXT
  presum = presum - 320
NEXT

frames& = frames& + 1

PUT (0, 0), buffer, PSET

LOOP UNTIL INKEY$ = CHR$(27)


COLOR 63: PRINT frames& / (TIMER - t#)
DO: LOOP UNTIL INKEY$ = CHR$(27)
SYSTEM
1920/4 = 480. I think this line is definitely slow ;-)

My .0002 pence...
the graphics I handle take at least 30 minutes per view, the longuest times being the Buddhabot views that take several days for a 400x400 image...

Check the Kofman's final QB project thread : I really wonder about ASM vs explicit languages and that speed issue.
Quote:1920/4 = 480. I think this line is definitely slow ;-)

My .0002 pence...

Um, that's just to make the view line up down the middle and is only run once upon initialization.
... the entirety of the "slowness" of this program lies in the loops, not in the commands. if you take out all the commands, and just leave in the loops, it hardly makes it run any faster. I'm sure you prolly knew that already, but if it helps, cool.

*peace*

Meg.
Code:
PlayerX = PlayerX + 10 * Cosine(PlayerAngle)
PlayerY = PlayerY + 10 * Sine(PlayerAngle)

You could take out the two multiplications inside the loop by creating arrays outside of the loop, Cosine10() and Sine10()

*peace*

Meg.
Thanks, it just sped it up a little though :/
I've been playing around a bit with your code, trying to speed it up. I've managed to just about double the speed. I'm sure there's got to be a way to make it go even faster, but I don't know anything about trig or using the POKE command. So, without changing those things, this is the best I could do:

Code:
'$DYNAMIC
DEFINT A-Z
DIM PIC(63, 63)
DIM buffer(32001) AS INTEGER
DIM Sine(1920) AS SINGLE, Cosine(1920) AS SINGLE
DIM Raylength(99), lsy(199) AS LONG, presum AS LONG

T# = TIMER
CameraHeight = 100
CameraDistance = 128

FOR i# = 0 TO 6.28165 STEP 6.28165 / 1920
     Sine(a) = SIN(i#)
     Cosine(a) = COS(i#)
     a = a + 1
NEXT

FOR y = 0 TO 63
FOR x = 0 TO 63
  PIC(x, y) = COS(x / 30) * SIN(y / 30) * 4 + 24
  NEXT
NEXT

FOR y = 0 TO 99
     Raylength(y) = (CameraHeight / (CameraHeight - y)) * CameraDistance
NEXT

FOR n& = 0 TO 199
lsy(n&) = n& * 320 + 4
NEXT

SCREEN 13
buffer(0) = 2560: buffer(1) = 200
DEF SEG = VARSEG(buffer(0))

PlayerX = 0
PlayerAngle = 480
PlayerY = 0

S10# = 10 * Sine(PlayerAngle)
C10# = 10 * Cosine(PlayerAngle)

DO
  PlayerX = PlayerX + C10#
  PlayerY = PlayerY + S10#
  presum = lsy(100)
  presum2 = lsy(99)

  FOR y = 99 TO 0 STEP -1
    
     xang = PlayerAngle - 159
    
     FOR x = 0 TO 160
          vx = ABS(PlayerX + Raylength(y) * Cosine(xang))
          vy = ABS(PlayerY + Raylength(y) * Sine(xang))

          POKE presum + x, (PIC(vx MOD 64, vy MOD 64))
          POKE presum + (319 - x), (PIC(vx MOD 64, vy MOD 64))
          POKE presum2 + x, (PIC(vx AND 63, vy AND 63))
          POKE presum2 + (319 - x), (PIC(vx AND 63, vy AND 63))
          xang = xang + 1
          IF xang > 1919 THEN xang = 0
     NEXT x

     presum = presum + 320
     presum2 = presum2 - 320
  NEXT y

  frames& = frames& + 1

  PUT (0, 0), buffer, PSET

LOOP UNTIL INKEY$ = CHR$(27)

COLOR 63: PRINT frames& / (TIMER - T#)
DO: LOOP UNTIL INKEY$ = CHR$(27)
SYSTEM

Hope that helps!

*peace*

Meg.
I think i might have removed a line underneath

Code:
xang = PlayerAngle - 159

that you'd want to put back in.

By the way, if you could figure out some way of making these lines

Code:
vx = ABS(PlayerX + Raylength(y) * Cosine(xang))
vy = ABS(PlayerY + Raylength(y) * Sine(xang))

run faster, you'd have your problem solved. Those operations are what's making it run so slowly.

*peace*

Meg.
You can replace any "x MOD 64" for "x AND 63".
Pages: 1 2 3 4 5