Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Optimize this, analyze that...
#1
I was helping a dude out with a pure QB blitting routine, and I was wondering if there is a faster way to optimize this.

Code:
DEFINT A-Z
REM $DYNAMIC
DECLARE SUB QSPRITE (SPRITE(), xx, yy, frame, mode$)

DIM SHARED buffer(32001) AS INTEGER
buffer(0) = 2560: buffer(1) = 200


DIM SHARED lutsegy(199) AS LONG
FOR n& = 0 TO 199
lutsegy(n&) = n& * 320 + 4'if this doesn't work, try a +4 at the end.. I can't remember if this is right.
NEXT

SCREEN 13
DIM image(16 * 16 - 1)
FOR g = 0 TO 15
FOR h = 0 TO 15
  PSET (g, h), RND * 15 + 16
NEXT
NEXT
GET (0, 0)-(15, 15), image

xinc = 1: yinc = 1
DO
  QSPRITE image(), x, y, 1, "SOLID"
  PUT (0, 0), buffer, PSET
  x = x + xinc
  IF x > 318 - 15 OR x < 1 THEN xinc = -xinc
  y = y + yinc
  IF y > 198 - 15 OR y < 1 THEN yinc = -yinc

  REDIM buffer(32001) AS INTEGER
  buffer(0) = 2560: buffer(1) = 200

LOOP UNTIL LEN(INKEY$)

'SPRITE() is your image array
'XX is the x position
'YY is the y position
'frame is the specific image number (just use one)
'mode$ is either "SOLID" or "TRANSPARENT" depending on your blit type. SOLID is faster, but includes black.
SUB QSPRITE (SPRITE(), xx, yy, frame, mode$)
DIM segADD AS LONG
'''
'
IF frame THEN
'
TILEwidth = SPRITE(0) \ 8
TILEheight = SPRITE(1)
TP = TILEwidth * TILEheight
TH = TILEheight - 1
TW = TILEwidth - 1
TF = frame - 1
'
IF TP AND &H1 THEN
ToffsBYT = ((4 * frame) + TF) + (TP * TF)
ELSE
ToffsBYT = (4 * frame) + (TP * TF)
END IF
'
xLEFT = xx
xRIGHT = xx + TW
yTOP = yy
yBOTTOM = yy + TH
'
IF xLEFT < 0 THEN
sum = 0 - xLEFT
IF sum < 0 THEN sum = -sum
IF sum > TW THEN EXIT SUB
xLEFT = 0
CLIPoffsL = sum
CLIPadd = sum
END IF
'
IF xRIGHT > 319 THEN
sum = xRIGHT - 319
IF sum > TW THEN EXIT SUB
xRIGHT = 319
CLIPadd = sum
END IF
'
IF yTOP < 0 THEN
sum = 0 - yTOP
IF sum < 0 THEN sum = -sum
IF sum > TH THEN EXIT SUB
yTOP = 0
CLIPoffsT = sum * TILEwidth
END IF
'
IF yBOTTOM > 199 THEN
sum = yBOTTOM - 199
IF sum > TH THEN EXIT SUB
yBOTTOM = 199
END IF
'
t = ToffsBYT + CLIPoffsL + CLIPoffsT
'

'Get all color numbers to take down DEF SEG count
DIM cols(TP) AS INTEGER
DEF SEG = VARSEG(SPRITE(0))

j = 0
FOR y = yTOP TO yBOTTOM
  FOR x = xLEFT TO xRIGHT
   cols(j) = PEEK(t)
   t = t + 1
   j = j + 1
  NEXT
  t = t + CLIPadd
NEXT

t = ToffsBYT + CLIPoffsL + CLIPoffsT
'
segADD = lutsegy(yTOP)
DEF SEG = VARSEG(buffer(0))
'
'''
SELECT CASE mode$
CASE "SOLID"
'
j = 0
FOR y = yTOP TO yBOTTOM
FOR x = xLEFT TO xRIGHT
  c = cols(j)
  POKE segADD + x, c
  t = t + 1
  j = j + 1
NEXT
t = t + CLIPadd
segADD = segADD + 320
NEXT

'
CASE "TRANSPARENT"
j = 0
FOR y = yTOP TO yBOTTOM
  FOR x = xLEFT TO xRIGHT
    c = cols(j)
    IF c THEN POKE segADD + x, c
    t = t + 1
    j = j + 1
  NEXT
  t = t + CLIPadd
  segADD = segADD + 320
NEXT

END SELECT
'
END IF
'''
END SUB
am an asshole. Get used to it.
Reply
#2
IF x > 318 - 15 OR x < 1 THEN xinc = -xinc
y = y + yinc
IF y > 198 - 15 OR y < 1 THEN yinc = -yinc

make that 313 and 183.
Also look at the rest of your code; the QBSprite sub has a hell of a lot of addition/subtraction that you could put somewhere else; like in a global.

But we don't like globals, so we'll just pass it 1000 times or so.
Peace cannot be obtained without war. Why? If there is already peace, it is unnecessary for war. If there is no peace, there is already war."

Visit www.neobasic.net to see rubbish in all its finest.
Reply
#3
I know the main loop code isn't optimized, but that wasn't the main point of the program. I was just wondering about the QSprite.

Which additions could I have in a global? I don't understand.
am an asshole. Get used to it.
Reply
#4
RelGFX.

Qbrpgs.com---utilities.

BTW, I've tried copying to an intermediate 2d array also (like you) but found out after some experiments that multiple Def Segs is faster. Trust me.

PS. Run the RPG demo in RelGFX to see the speed.

The source is in Rel.Sprite and it has clipping.
y smiley is 24 bit.
[Image: anya2.jpg]

Genso's Junkyard:
http://rel.betterwebber.com/
Reply
#5
Don't use strings as commands, they are slow to compare in the SELECT CASE. If you want meaningful names, use constants

CONST TRANSPARENT=1
CONST SOLID =2

then you can pass an integer command to the function.

DECLARE SUB QSPRITE (SPRITE(),XX%,YY%,FRAME%,MODE%)

The SELECT CASE would be

SELECT CASE MODE%

CASE TRANSPARENT
...

CASE SOLID

As you see the code is still self - documented but you get rid of the slow string comparisons
Antoni
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)