Qbasicnews.com
January 20, 2020, 03:11:18 AM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: Back to Qbasicnews.com | QB Online Help | FAQ | Chat | All Basic Code | QB Knowledge Base
 
   Home   Help Search Login Register  
Pages: [1]
  Print  
Author Topic: Optimize this, analyze that...  (Read 1352 times)
Ninkazu
Been there, done that
*****
Posts: 1169



WWW
« 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$)

'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
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



WWW
« 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



WWW
« 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



WWW
« 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]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!