Qbasicnews.com
August 05, 2020, 10:07:23 PM
 Pages: [1]
 Author Topic: Optimize this, analyze that...  (Read 1415 times)
Ninkazu
Been there, done that

Posts: 1169

 « on: May 13, 2003, 10:35:52 PM »

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\$)

'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\$)
'''
'
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
END IF
'
IF xRIGHT > 319 THEN
sum = xRIGHT - 319
IF sum > TW THEN EXIT SUB
xRIGHT = 319
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
NEXT

t = ToffsBYT + CLIPoffsL + CLIPoffsT
'
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)
t = t + 1
j = j + 1
NEXT
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
NEXT

END SELECT
'
END IF
'''
END SUB
 Logged

am an asshole. Get used to it.
Agamemnus
x/ \z

Posts: 3491

 « Reply #1 on: May 13, 2003, 11:07:36 PM »

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.
 Logged

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.
Ninkazu
Been there, done that

Posts: 1169

 « Reply #2 on: May 13, 2003, 11:48:08 PM »

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.
 Logged

am an asshole. Get used to it.
relsoft
*/-\*

Posts: 3927

 « Reply #3 on: May 14, 2003, 12:51:28 AM »

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.
 Logged

y smiley is 24 bit.

Genso's Junkyard:
http://rel.betterwebber.com/
Antoni Gual
Na_th_an

Posts: 1434

 « Reply #4 on: May 14, 2003, 10:00:19 AM »

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
 Logged

Antoni
 Pages: [1]