• Print

Author Topic: Will QB64-GL fix this issue???  (Read 555 times)

DSMan195276

  • Hero Member
  • *****
  • Posts: 1978
  • Yes
    • Email
Re: Will QB64-GL fix this issue???
« Reply #15 on: March 21, 2013, 07:49:43 AM »
I modified it to get some more speed and got the code down to here:

Code: [Select]
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' View Portal Demo.bas '
''''''''''''''''''''''''
'
' Written by Justin Richards (2013)
'
'
' This program was designed to be used as a template for creating a program
' that utilises view port scrolling (ie a 2d platform game, or top down map
' style game, etc).
'
' ...



' START '

' Declare Subs and Variables '

DEFLNG A-Z



DIM scrn_mem AS _MEM



' Set Screen Resolution and Colour Mode

DIM SHARED ResolutionX, ResolutionY, ResolutionScale, ColourMode

ResolutionX = 320
ResolutionY = 240
ResolutionScale = ResolutionX / ResolutionY
ColourMode = 32



Restart:



SCREEN _NEWIMAGE(ResolutionX, ResolutionY, ColourMode)

_FULLSCREEN

'Added this V
_DONTBLEND


' View Port Variables...

DIM SHARED ViewX1, ViewY1, ViewX2, ViewY2



' Background Tile Variables

DIM SHARED TileX1(10)
DIM SHARED TileY1(10)
DIM SHARED TileX2(10)
DIM SHARED TileY2(10)
DIM SHARED TileColourRed(10)
DIM SHARED TileColourGreen(10)
DIM SHARED TileColourBlue(10)



' Character Variables

DIM SHARED CharacterX, CharacterY, CharacterXInc, CharacterYInc

DIM SHARED CharacterMovedUp
DIM SHARED CharacterMovedDown
DIM SHARED CharacterMovedLeft
DIM SHARED CharacterMovedRight



' Set Screen Limits (this example is an area 1200 pixels x 600 pixels)

ViewX1Limit = 0
ViewY1Limit = 0
ViewX2Limit = 1200
ViewY2Limit = 600




' Set starting co-ordinates for our Character

CharacterX = 120: CharacterY = 120
CharacterXInc = 2: CharacterYInc = 2



' Set the Veiw Portal to centre on the Character's co-ordinates to start with

ViewX1 = CharacterX - (ResolutionX / 2): ViewY1 = CharacterY - (ResolutionY / 2): ViewX2 = CharacterX + (ResolutionX / 2) - 1: ViewY2 = CharacterY + (ResolutionY / 2) - 1



' Test to see whether the Character is close to the edge of the portal area and
' adjust the view portal position if necessary...


' X co-ordinates

IF ViewX1 < ViewX1Limit THEN

  ViewX1 = ViewX1Limit

  ViewX2 = ViewX1 + ResolutionX - 1

ELSEIF ViewX2 < ViewX2Limit - 1 THEN

  ViewX1 = ViewX1Limit + (ResolutionX / 2) - CharacterX
  ViewX2 = ViewX1 + ResolutionX - 1

ELSEIF ViewX2 > ViewX2Limit - 1 THEN

  ViewX1 = ViewX2Limit - ResolutionX

  ViewX1 = -ViewX1

  ViewX2 = ViewX1 + ResolutionX - 1

END IF


' Y co-ordinates

IF ViewY1 < ViewY1Limit THEN

  ViewY1 = ViewY1Limit

  ViewY2 = ViewY1 + ResolutionY - 1

ELSEIF ViewY2 < ViewY2Limit - 1 THEN

  ViewY1 = ViewY1Limit + (ResolutionY / 2) - CharacterY
  ViewY2 = ViewY1 + ResolutionY - 1

ELSEIF ViewY2 > ViewY2Limit - 1 THEN

  ViewY1 = ViewY2Limit - ResolutionY

  ViewY1 = -ViewY1

  ViewY2 = ViewY1 + ResolutionY - 1

END IF



' If the Character is not near the edge than change his co-ordinates based on the
' new screen position...

IF CharacterX > ViewX1Limit + (ResolutionX / 2) AND CharacterX < ViewX2Limit - (ResolutionX / 2) THEN CharacterX = -ViewX1 + (ResolutionX / 2)
IF CharacterY > ViewY1Limit + (ResolutionY / 2) AND CharacterY < ViewY2Limit - (ResolutionY / 2) THEN CharacterY = -ViewY1 + (ResolutionY / 2)




' These tiles form the brown rectangles (walls) in the background

FOR ResetTiles = 0 TO 9

  TileColourRed(ResetTiles) = 223
  TileColourGreen(ResetTiles) = 95
  TileColourBlue(ResetTiles) = 0

NEXT ResetTiles

TileX1(0) = 0: TileY1(0) = 0: TileX2(0) = 39: TileY2(0) = 599
TileX1(1) = 40: TileY1(1) = 0: TileX2(1) = 559: TileY2(1) = 39
TileX1(2) = 1160: TileY1(2) = 0: TileX2(2) = 1199: TileY2(2) = 599
TileX1(3) = 40: TileY1(3) = 560: TileX2(3) = 559: TileY2(3) = 599
TileX1(4) = 160: TileY1(4) = 160: TileX2(4) = 239: TileY2(4) = 199
TileX1(5) = 220: TileY1(5) = 40: TileX2(5) = 239: TileY2(5) = 159
TileX1(6) = 40: TileY1(6) = 270: TileX2(6) = 199: TileY2(6) = 299
TileX1(7) = 440: TileY1(7) = 270: TileX2(7) = 899: TileY2(7) = 499: TileColourRed(7) = 63: TileColourGreen(7) = 63: TileColourBlue(7) = 63


' Set Keyboard Constants

CONST Key_Up& = 18432
CONST Key_Down& = 20480
CONST Key_Left& = 19200
CONST Key_Right& = 19712


' Set delay/speed variables

TimeSet = 1

GameSpeed = 0


'Grab our screen

scrn_mem = _MEMIMAGE(0)
Bytes_Per_Pixel = 4
Scrn_Width = _WIDTH(0)

' Main Game Loop

DO


  '  ' Reset the Tick Clock
  '
  '  DEF SEG = 0
  '
  '  POKE 1132, 0


  ' Only process the loop if the desired delay has passed

  '  IF GameSpeed = TimeSet THEN


  ' Exit code

'Also why did you need the loop here? All it did was cause you to check INKEY$ 32 times a loop!
  'FOR KbdLoop = 0 TO 32

    'Kbd$ = ""
'You should really get rid of INKEY$ and check by other means
'Such as _KEYHIT
'INKEY$ is really slow
    Kbd = _KEYHIT

    IF Kbd = 27 THEN 'Esc


      IF ResolutionX = 1024 THEN

        CLS

        _DISPLAY

        SLEEP 1

        _FULLSCREEN _OFF

        SYSTEM

      END IF

      IF ResolutionX = 800 THEN

        ResolutionX = 1024
        ResolutionY = 768

      END IF

      IF ResolutionX = 640 THEN

        ResolutionX = 800
        ResolutionY = 600

      END IF

      IF ResolutionX = 320 THEN

        ResolutionX = 640
        ResolutionY = 480

      END IF

_MEMFREE scrn_mem 'Prevent a memory leak
      GOTO Restart

    END IF


  'NEXT KbdLoop


  ' Draw the Background

  DrawImages



  ' Test for collisions


'Don't use POINT
'Use _MEMGET instead to grab a LONG value. Ex:

'You have to calculate the starting byte in memory of your location
'This is dependent on the BPP of your screen image. If you have a 32-bit image, then it's 32 BPP
'256 colors is 8 BPP, 16 colors is 4 BPP
'You divide the BPP by 8 to get how many bytes each pixel is in size
'For a 32-bit image, that gives you 4 bytes per pixel (The same size as a LONG you'll note)

'From there, calculate the OFFSET via doing some addition and multiplying.
'Using Scrn_Width as the width, you can calculate the byte offset of a pixel like this:

'PicX is the X cord, PicY is the Y cord
' = (PicY * scrn_Width + PicX) * BPP

'Example _MEMGET's (You should note, the amount of Bytes you get is dependent on your variable type):

_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY - 21 + ViewY1) * scrn_Width + CharacterX - 20 + ViewX1) * Bytes_Per_Pixel, PCharacterUpTopLeft
_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY - 21 + ViewY1) * scrn_Width + CharacterX + ViewX1) * Bytes_Per_Pixel, PCharacterUpTopMiddle
_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY - 21 + ViewY1) * scrn_Width + CharacterX + 19 + ViewX1) * Bytes_Per_Pixel, PCharacterUpTopRight

  'PCharacterUpTopLeft = POINT(CharacterX - 20 + ViewX1, CharacterY - 21 + ViewY1)
  'PCharacterUpTopMiddle = POINT(CharacterX + ViewX1, CharacterY - 21 + ViewY1)
  'PCharacterUpTopRight = POINT(CharacterX + 19 + ViewX1, CharacterY - 21 + ViewY1)

_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY + 20 + ViewY1) * scrn_Width + CharacterX - 20 + ViewX1) * Bytes_Per_Pixel, PCharacterDownBottomLeft
_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY + 20 + ViewY1) * scrn_Width + CharacterX + ViewX1) * Bytes_Per_Pixel, PCharacterDownBottomMiddle
_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY + 20 + ViewY1) * scrn_Width + CharacterX + 19 + ViewX1) * Bytes_Per_Pixel, PCharacterDownBottomRight

  'PCharacterDownBottomLeft = POINT(CharacterX - 20 + ViewX1, CharacterY + 20 + ViewY1)
  'PCharacterDownBottomMiddle = POINT(CharacterX + ViewX1, CharacterY + 20 + ViewY1)
  'PCharacterDownBottomRight = POINT(CharacterX + 19 + ViewX1, CharacterY + 20 + ViewY1)

_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY - 20 + ViewY1) * scrn_Width + CharacterX - 21 + ViewX1) * Bytes_Per_Pixel, PCharacterLeftTopLeft
_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY + ViewY1) * scrn_Width + CharacterX - 21 + ViewX1) * Bytes_Per_Pixel, PCharacterLeftMiddleLeft
_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY + 19 + ViewY1) * scrn_Width + CharacterX - 21 + ViewX1) * Bytes_Per_Pixel, PCharacterLeftBottomLeft

  'PCharacterLeftTopLeft = POINT(CharacterX - 21 + ViewX1, CharacterY - 20 + ViewY1)
  'PCharacterLeftMiddleLeft = POINT(CharacterX - 21 + ViewX1, CharacterY + ViewY1)
  'PCharacterLeftBottomLeft = POINT(CharacterX - 21 + ViewX1, CharacterY + 19 + ViewY1)

_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY - 20 + ViewY1) * scrn_Width + CharacterX + 20 + ViewX1) * Bytes_Per_Pixel, PCharacterRightTopRight
_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY + ViewY1) * scrn_Width + CharacterX + 20 + ViewX1) * Bytes_Per_Pixel, PCharacterRightMiddleRight
_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY + 19 + ViewY1) * scrn_Width + CharacterX + 20 + ViewX1) * Bytes_Per_Pixel, PCharacterRightBottomRight

  'PCharacterRightTopRight = POINT(CharacterX + 20 + ViewX1, CharacterY - 20 + ViewY1)
  'PCharacterRightMiddleRight = POINT(CharacterX + 20 + ViewX1, CharacterY + ViewY1)
  'PCharacterRightBottomRight = POINT(CharacterX + 20 + ViewX1, CharacterY + 19 + ViewY1)

_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY + ViewY1) * scrn_Width + CharacterX + ViewX1) * Bytes_Per_Pixel, PCharacterCentre
  'PCharacterCentre = POINT(CharacterX + ViewX1, CharacterY + ViewY1)


  ' Test for keypresses

  UpOn = _KEYDOWN(Key_Up&)
  DownOn = _KEYDOWN(Key_Down&)
  LeftOn = _KEYDOWN(Key_Left&)
  RightOn = _KEYDOWN(Key_Right&)


  ' Move Character based on user input


  CharacterMovedUp = 0
  CharacterMovedDown = 0
  CharacterMovedLeft = 0
  CharacterMovedRight = 0


  IF UpOn = -1 AND DownOn = 0 AND PCharacterUpTopLeft = _RGB(0, 0, 0) AND PCharacterUpTopMiddle = _RGB(0, 0, 0) AND PCharacterUpTopRight = _RGB(0, 0, 0) THEN

    IF CharacterY > ViewY1Limit + (ResolutionY / 2) AND CharacterY < ViewY2Limit - (ResolutionY / 2) + CharacterYInc THEN ViewY1 = ViewY1 + CharacterYInc: ViewY2 = ViewY2 + CharacterYInc

    CharacterY = CharacterY - CharacterYInc

    CharacterMovedUp = -1

  END IF

  IF DownOn = -1 AND UpOn = 0 AND PCharacterDownBottomLeft = _RGB(0, 0, 0) AND PCharacterDownBottomMiddle = _RGB(0, 0, 0) AND PCharacterDownBottomRight = _RGB(0, 0, 0) THEN

    IF CharacterY > ViewY1Limit + (ResolutionY / 2) - CharacterYInc AND CharacterY < ViewY2Limit - (ResolutionY / 2) THEN ViewY1 = ViewY1 - CharacterYInc: ViewY2 = ViewY2 - CharacterYInc

    CharacterY = CharacterY + CharacterYInc

    CharacterMovedDown = -1

  END IF

  IF LeftOn = -1 AND RightOn = 0 AND PCharacterLeftTopLeft = _RGB(0, 0, 0) AND PCharacterLeftMiddleLeft = _RGB(0, 0, 0) AND PCharacterLeftBottomLeft = _RGB(0, 0, 0) THEN

    IF CharacterX > ViewX1Limit + (ResolutionX / 2) AND CharacterX < ViewX2Limit - (ResolutionX / 2) + CharacterXInc THEN ViewX1 = ViewX1 + CharacterXInc: ViewX2 = ViewX2 + CharacterXInc

    CharacterX = CharacterX - CharacterXInc

    CharacterMovedLeft = -1

  END IF

  IF RightOn = -1 AND LeftOn = 0 AND PCharacterRightTopRight = _RGB(0, 0, 0) AND PCharacterRightMiddleRight = _RGB(0, 0, 0) AND PCharacterRightBottomRight = _RGB(0, 0, 0) THEN

    IF CharacterX > ViewX1Limit + (ResolutionX / 2) - CharacterXInc AND CharacterX < ViewX2Limit - (ResolutionX / 2) THEN ViewX1 = ViewX1 - CharacterXInc: ViewX2 = ViewX2 - CharacterXInc

    CharacterX = CharacterX + CharacterXInc

    CharacterMovedRight = -1

  END IF


  ' reset timer and display graphics

  GameSpeed = 0


  _DISPLAY

  '  END IF


  ' Loop here until an even amount of time has passed

  '  DO
  '
  'LOOP UNTIL PEEK(1132) >= 1
  '
  '  DEF SEG
  '
  '
  '  ' Increment the timer
  '
  '  GameSpeed = GameSpeed + 1
  '



LOOP


END



SUB DrawImages


' Clear the screen and draw each tile one at a time

LINE (0, 0)-(ResolutionX - 1, ResolutionY - 1), _RGB(0, 0, 0), BF

FOR DrawTile = 0 TO 9

  IF NOT (TileX1(DrawTile) + ViewX1 > ResolutionX OR TileX2(DrawTile) + ViewX2 < ResolutionX OR TileY1(DrawTile) + ViewY1 > ResolutionY OR TileY2(DrawTile) + ViewY2 < ResolutionY) THEN

    LINE (TileX1(DrawTile) + ViewX1, TileY1(DrawTile) + ViewY1)-(TileX2(DrawTile) + ViewX1, TileY2(DrawTile) + ViewY1), _RGBA(TileColourRed(DrawTile), TileColourGreen(DrawTile), TileColourBlue(DrawTile), 127), BF

  END IF

NEXT DrawTile


' Draw the Character (Ball in this case)

CIRCLE (CharacterX + ViewX1, CharacterY + ViewY1), 19, _RGB(63, 255, 63)
CIRCLE (CharacterX - 1 + ViewX1, CharacterY - 1 + ViewY1), 19, _RGB(63, 255, 63)
'PAINT (CharacterX + ViewX1, CharacterY + ViewY1), _RGB(63, 255, 63), _RGB(63, 255, 63)


'Central
IF NOT CharacterMovedUp AND NOT CharacterMovedDown AND NOT CharacterMovedLeft AND NOT CharacterMovedRight THEN
  CIRCLE (CharacterX + ViewX1, CharacterY + ViewY1), 3, 2
  CIRCLE (CharacterX - 1 + ViewX1, CharacterY - 1 + ViewY1), 3, 2
  'PAINT (CharacterX + ViewX1, CharacterY + ViewY1), 2, 2
END IF

'Up
IF CharacterMovedUp AND NOT CharacterMovedLeft AND NOT CharacterMovedRight THEN
  CIRCLE (CharacterX + ViewX1, CharacterY - 15 + ViewY1), 3, 2
  CIRCLE (CharacterX - 1 + ViewX1, CharacterY - 16 + ViewY1), 3, 2
  'PAINT (CharacterX + ViewX1, CharacterY - 15 + ViewY1), 2, 2
END IF

'Down
IF CharacterMovedDown AND NOT CharacterMovedLeft AND NOT CharacterMovedRight THEN
  CIRCLE (CharacterX + ViewX1, CharacterY + 15 + ViewY1), 3, 2
  CIRCLE (CharacterX - 1 + ViewX1, CharacterY + 16 + ViewY1), 3, 2
  'PAINT (CharacterX + ViewX1, CharacterY + 15 + ViewY1), 2, 2
END IF

'Left
IF CharacterMovedLeft AND NOT CharacterMovedUp AND NOT CharacterMovedDown THEN
  CIRCLE (CharacterX - 15 + ViewX1, CharacterY + ViewY1), 3, 2
  CIRCLE (CharacterX - 16 + ViewX1, CharacterY - 1 + ViewY1), 3, 2
  'PAINT (CharacterX - 15 + ViewX1, CharacterY + ViewY1), 2, 2
END IF

'Right
IF CharacterMovedRight AND NOT CharacterMovedUp AND NOT CharacterMovedDown THEN
  CIRCLE (CharacterX + 15 + ViewX1, CharacterY + ViewY1), 3, 2
  CIRCLE (CharacterX + 16 + ViewX1, CharacterY - 1 + ViewY1), 3, 2
  'PAINT (CharacterX + 15 + ViewX1, CharacterY + ViewY1), 2, 2
END IF



'Up and Left
IF CharacterMovedUp AND CharacterMovedLeft THEN
  CIRCLE (CharacterX - 10 + ViewX1, CharacterY - 10 + ViewY1), 3, 2
  CIRCLE (CharacterX - 11 + ViewX1, CharacterY - 11 + ViewY1), 3, 2
  'PAINT (CharacterX - 10 + ViewX1, CharacterY - 10 + ViewY1), 2, 2
END IF

'Up and Right
IF CharacterMovedUp AND CharacterMovedRight THEN
  CIRCLE (CharacterX + 10 + ViewX1, CharacterY - 10 + ViewY1), 3, 2
  CIRCLE (CharacterX + 11 + ViewX1, CharacterY - 11 + ViewY1), 3, 2
  'PAINT (CharacterX + 10 + ViewX1, CharacterY - 10 + ViewY1), 2, 2
END IF

'Down and Left
IF CharacterMovedDown AND CharacterMovedLeft THEN
  CIRCLE (CharacterX - 10 + ViewX1, CharacterY + 10 + ViewY1), 3, 2
  CIRCLE (CharacterX - 11 + ViewX1, CharacterY + 11 + ViewY1), 3, 2
  'PAINT (CharacterX - 10 + ViewX1, CharacterY + 10 + ViewY1), 2, 2
END IF

'Down and Right
IF CharacterMovedDown AND CharacterMovedRight THEN
  CIRCLE (CharacterX + 11 + ViewX1, CharacterY + 11 + ViewY1), 3, 2
  CIRCLE (CharacterX + 11 + ViewX1, CharacterY + 11 + ViewY1), 3, 2
  'PAINT (CharacterX + 10 + ViewX1, CharacterY + 10 + ViewY1), 2, 2
END IF



END SUB


I commented the code, but a quick list of things I did:

Put DEFLNG A-Z at the beginning of the code (Fairly noticeable speed boost)
Used _MEMIMAGE() and _MEMGET instead of POINT.
Use _KEYHIT() to check for the Esc key instead of INKEY$
Got rid of the loop around INKEY$ (Why were you calling INKEY$ 32 times every loop? That was sure to slow things down)
Got rid of the PAINT statements.

To go from here, I would recommend drawing out the images at the beginning of the program, and save a separate image for each state of the player. Then, when you need to draw out the player instead of having to use PAINT and CIRCLE every-time, you can just use one _PUTIMAGE which is sure to be faster.

Matt
"Cast your cares on the Lord and he will sustain you; he will never let the righteous be shaken" -- Psalm 55:22
QB64 Linux Installer

Galleon

  • Administrator
  • Hero Member
  • *****
  • Posts: 4664
  • QB Forever
    • Email
Re: Will QB64-GL fix this issue???
« Reply #16 on: March 21, 2013, 08:09:13 AM »
Quote
do you think QB64GL will fix this issue?
QB64-GL will support hardware surface 2D operations in the future for many (but not all) QBASIC commands. For instance, PAINT has no hardware equivalent so it would either have to give an error or temporarily read back the hardware surface, modify it in software then update hardware surface (a very nasty performance hit that would be). As "nice" as the read-back then update method sounds for situations like PAINT it may not even be feasible even with the performance hit because of how QB64 is structured which will effectively be a pipeline as follows:
software 2D operations(done at time of call)->creation of any new hardware surfaces from software surfaces(buffered then done during GL render)->hardware 2D operations(buffered then done during GL render)
As you can see, hardware PAINT just doesn't fit well in this pipeline.
Something old... Something new... Something borrowed... Something blue...

JustinRichardsMusic

  • Sr. Member
  • ****
  • Posts: 335
  • Character names can be found in metal from the 90s
    • Email
Re: Will QB64-GL fix this issue???
« Reply #17 on: March 21, 2013, 08:09:51 AM »
Quote from: OlDosLover on March 21, 2013, 07:44:53 AM
Hi all,
   
Quote
However, I timed how long it took to get from the far left wall to the grey wall in each screen mode and this is what I got:
320x240 = 3 secs
640x480 = 4 secs
800x600 = 5 secs
1024x768 = 8 secs
    I havent examined the code deeply but i assume you are moving a fixed amount horizontally. Is this fixed amount a set number of pixels or a percentage of the overall screen resolution? As 320 across is half of 640 you would expect to see more difference between those two size of resolutions.
    My advice is to place your character on a unblocked horizontal path  and have it move to the other side in a loop with code not a key press ,and time (with timer) . In theory you should reach a speed that does not get faster and can be expressed as pixels per cycle (cycle = your benchmark constant between all screen resolutions). If indeed ,in each screen resolution ,the pixels per cycle are the same regardless of screen resolution ,then to get movement across the screen the same at 320 verses 640 then you need to double the fixed amount of horizontal movement.
    If it took 320 seconds to move 320 graduations then to move 640 graduations either double your speed or double your step movement.
OlDosLover.

I understand what your saying here.

The purpose of the 'how many seconds' test was to give me a fixed length to travel in an allotted time.  In each screen mode I travelled the exact same distance, but it took longer as the resolution grew.

If there was no lag then then the time taken should have been 3 seconds in every screen res.

I don't expect it to be with no delay code what so ever. What is bothering me is the fact that in 32-bit screen modes, without hardware support, my screen res can't be more than 640x480 without lagging beyond usefulness. In this day and age, I would have expected higher res screens to be possible...
James Hetter's Revenge has been unleashed! Follow the games progress here:
http://www.qb64.net/forum/index.php?topic=6762.0

Download the latest version here:
https://www.dropbox.com/s/8p8gguliw1y6ink/Hetters%20Revenge.zip?m

JustinRichardsMusic

  • Sr. Member
  • ****
  • Posts: 335
  • Character names can be found in metal from the 90s
    • Email
Re: Will QB64-GL fix this issue???
« Reply #18 on: March 21, 2013, 08:14:06 AM »
Quote from: Galleon on March 21, 2013, 08:09:13 AM
Quote
do you think QB64GL will fix this issue?
QB64-GL will support hardware surface 2D operations in the future for many (but not all) QBASIC commands. For instance, PAINT has no hardware equivalent so it would either have to give an error or temporarily read back the hardware surface, modify it in software then update hardware surface (a very nasty performance hit that would be). As "nice" as the read-back then update method sounds for situations like PAINT it may not even be feasible even with the performance hit because of how QB64 is structured which will effectively be a pipeline as follows:
software 2D operations(done at time of call)->creation of any new hardware surfaces from software surfaces(buffered then done during GL render)->hardware 2D operations(buffered then done during GL render)
As you can see, hardware PAINT just doesn't fit well in this pipeline.

PAINT is not something I use very often.

Would the current version (5) of GL run this program? I'd like to test it.

Also, will GL still benefit computers without a video card? ie onboard video?
James Hetter's Revenge has been unleashed! Follow the games progress here:
http://www.qb64.net/forum/index.php?topic=6762.0

Download the latest version here:
https://www.dropbox.com/s/8p8gguliw1y6ink/Hetters%20Revenge.zip?m

OlDosLover

  • Hero Member
  • *****
  • Posts: 3859
  • OlDosLover
    • Email
Re: Will QB64-GL fix this issue???
« Reply #19 on: March 21, 2013, 08:34:08 AM »
Hi all,
    I agree.
Quote
If there was no lag then then the time taken should have been 3 seconds in every screen res.

I don't expect it to be with no delay code what so ever. What is bothering me is the fact that in 32-bit screen modes, without hardware support, my screen res can't be more than 640x480 without lagging beyond usefulness. In this day and age, I would have expected higher res screens to be possible...
    To prove the diff between screen resolutions get rid of all the "variables" like keypresses and have it do it with pure code. Then the issue is graphical as nothing else tweaked in code will make it run faster. Also once you achived this you can compare different ways of drawing your graphics.
    Thats a huge speed increase DSMan!
OlDosLover.
« Last Edit: March 21, 2013, 08:39:37 AM by OlDosLover »

DSMan195276

  • Hero Member
  • *****
  • Posts: 1978
  • Yes
    • Email
Re: Will QB64-GL fix this issue???
« Reply #20 on: March 21, 2013, 11:04:03 AM »
It slipped my mind, but you could also use $CHECKING:OFF to increase your speed. You should use it around the _MEMGET statements and probably use it in your screen drawing code to get a bit more speed. And again, storing the player states in images and then just using _PUTIMAGE instead of redrawing the player every time will increase the speed without sacraficing any of the graphics.

Matt
"Cast your cares on the Lord and he will sustain you; he will never let the righteous be shaken" -- Psalm 55:22
QB64 Linux Installer

OlDosLover

  • Hero Member
  • *****
  • Posts: 3859
  • OlDosLover
    • Email
Re: Will QB64-GL fix this issue???
« Reply #21 on: March 21, 2013, 02:16:11 PM »
Hi all,
   
Quote
And again, storing the player states in images and then just using _PUTIMAGE instead of redrawing the player every time will increase the speed without sacraficing any of the graphics.
    Totatally agree. Need help with this JustinRichardsMusic then just ask.
OlDosLover.


JustinRichardsMusic

  • Sr. Member
  • ****
  • Posts: 335
  • Character names can be found in metal from the 90s
    • Email
Re: Will QB64-GL fix this issue???
« Reply #22 on: March 21, 2013, 05:31:26 PM »
Ok,

I got rid of the POINT test variables - no change
I took out all the CIRCLE statements - no change
I used $CHECKING:OFF - small improvement

I think it all depends on the CPU speed and in particular VPU speed. In my case I'm only using on board video which uses software rendering and can't handle the increased load of the higher resolutions.

What I would like to do is get it to a speed where it runs faster than I need it to at high res so that I can add a small delay to control the speed of the game.

It runs ok at 640x480 but anything above that is unusable.

The only thing Ivan think of to speed it up is to only redraw the areas that have been changed. But this method is buggy and not an option for the game I have in mind...
James Hetter's Revenge has been unleashed! Follow the games progress here:
http://www.qb64.net/forum/index.php?topic=6762.0

Download the latest version here:
https://www.dropbox.com/s/8p8gguliw1y6ink/Hetters%20Revenge.zip?m

JustinRichardsMusic

  • Sr. Member
  • ****
  • Posts: 335
  • Character names can be found in metal from the 90s
    • Email
Re: Will QB64-GL fix this issue???
« Reply #23 on: March 21, 2013, 05:37:19 PM »
Quote from: DSMan195276 on March 21, 2013, 07:49:43 AM
I modified it to get some more speed and got the code down to here:

Code: [Select]
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' View Portal Demo.bas '
''''''''''''''''''''''''
'
' Written by Justin Richards (2013)
'
'
' This program was designed to be used as a template for creating a program
' that utilises view port scrolling (ie a 2d platform game, or top down map
' style game, etc).
'
' ...



' START '

' Declare Subs and Variables '

DEFLNG A-Z



DIM scrn_mem AS _MEM



' Set Screen Resolution and Colour Mode

DIM SHARED ResolutionX, ResolutionY, ResolutionScale, ColourMode

ResolutionX = 320
ResolutionY = 240
ResolutionScale = ResolutionX / ResolutionY
ColourMode = 32



Restart:



SCREEN _NEWIMAGE(ResolutionX, ResolutionY, ColourMode)

_FULLSCREEN

'Added this V
_DONTBLEND


' View Port Variables...

DIM SHARED ViewX1, ViewY1, ViewX2, ViewY2



' Background Tile Variables

DIM SHARED TileX1(10)
DIM SHARED TileY1(10)
DIM SHARED TileX2(10)
DIM SHARED TileY2(10)
DIM SHARED TileColourRed(10)
DIM SHARED TileColourGreen(10)
DIM SHARED TileColourBlue(10)



' Character Variables

DIM SHARED CharacterX, CharacterY, CharacterXInc, CharacterYInc

DIM SHARED CharacterMovedUp
DIM SHARED CharacterMovedDown
DIM SHARED CharacterMovedLeft
DIM SHARED CharacterMovedRight



' Set Screen Limits (this example is an area 1200 pixels x 600 pixels)

ViewX1Limit = 0
ViewY1Limit = 0
ViewX2Limit = 1200
ViewY2Limit = 600




' Set starting co-ordinates for our Character

CharacterX = 120: CharacterY = 120
CharacterXInc = 2: CharacterYInc = 2



' Set the Veiw Portal to centre on the Character's co-ordinates to start with

ViewX1 = CharacterX - (ResolutionX / 2): ViewY1 = CharacterY - (ResolutionY / 2): ViewX2 = CharacterX + (ResolutionX / 2) - 1: ViewY2 = CharacterY + (ResolutionY / 2) - 1



' Test to see whether the Character is close to the edge of the portal area and
' adjust the view portal position if necessary...


' X co-ordinates

IF ViewX1 < ViewX1Limit THEN

  ViewX1 = ViewX1Limit

  ViewX2 = ViewX1 + ResolutionX - 1

ELSEIF ViewX2 < ViewX2Limit - 1 THEN

  ViewX1 = ViewX1Limit + (ResolutionX / 2) - CharacterX
  ViewX2 = ViewX1 + ResolutionX - 1

ELSEIF ViewX2 > ViewX2Limit - 1 THEN

  ViewX1 = ViewX2Limit - ResolutionX

  ViewX1 = -ViewX1

  ViewX2 = ViewX1 + ResolutionX - 1

END IF


' Y co-ordinates

IF ViewY1 < ViewY1Limit THEN

  ViewY1 = ViewY1Limit

  ViewY2 = ViewY1 + ResolutionY - 1

ELSEIF ViewY2 < ViewY2Limit - 1 THEN

  ViewY1 = ViewY1Limit + (ResolutionY / 2) - CharacterY
  ViewY2 = ViewY1 + ResolutionY - 1

ELSEIF ViewY2 > ViewY2Limit - 1 THEN

  ViewY1 = ViewY2Limit - ResolutionY

  ViewY1 = -ViewY1

  ViewY2 = ViewY1 + ResolutionY - 1

END IF



' If the Character is not near the edge than change his co-ordinates based on the
' new screen position...

IF CharacterX > ViewX1Limit + (ResolutionX / 2) AND CharacterX < ViewX2Limit - (ResolutionX / 2) THEN CharacterX = -ViewX1 + (ResolutionX / 2)
IF CharacterY > ViewY1Limit + (ResolutionY / 2) AND CharacterY < ViewY2Limit - (ResolutionY / 2) THEN CharacterY = -ViewY1 + (ResolutionY / 2)




' These tiles form the brown rectangles (walls) in the background

FOR ResetTiles = 0 TO 9

  TileColourRed(ResetTiles) = 223
  TileColourGreen(ResetTiles) = 95
  TileColourBlue(ResetTiles) = 0

NEXT ResetTiles

TileX1(0) = 0: TileY1(0) = 0: TileX2(0) = 39: TileY2(0) = 599
TileX1(1) = 40: TileY1(1) = 0: TileX2(1) = 559: TileY2(1) = 39
TileX1(2) = 1160: TileY1(2) = 0: TileX2(2) = 1199: TileY2(2) = 599
TileX1(3) = 40: TileY1(3) = 560: TileX2(3) = 559: TileY2(3) = 599
TileX1(4) = 160: TileY1(4) = 160: TileX2(4) = 239: TileY2(4) = 199
TileX1(5) = 220: TileY1(5) = 40: TileX2(5) = 239: TileY2(5) = 159
TileX1(6) = 40: TileY1(6) = 270: TileX2(6) = 199: TileY2(6) = 299
TileX1(7) = 440: TileY1(7) = 270: TileX2(7) = 899: TileY2(7) = 499: TileColourRed(7) = 63: TileColourGreen(7) = 63: TileColourBlue(7) = 63


' Set Keyboard Constants

CONST Key_Up& = 18432
CONST Key_Down& = 20480
CONST Key_Left& = 19200
CONST Key_Right& = 19712


' Set delay/speed variables

TimeSet = 1

GameSpeed = 0


'Grab our screen

scrn_mem = _MEMIMAGE(0)
Bytes_Per_Pixel = 4
Scrn_Width = _WIDTH(0)

' Main Game Loop

DO


  '  ' Reset the Tick Clock
  '
  '  DEF SEG = 0
  '
  '  POKE 1132, 0


  ' Only process the loop if the desired delay has passed

  '  IF GameSpeed = TimeSet THEN


  ' Exit code

'Also why did you need the loop here? All it did was cause you to check INKEY$ 32 times a loop!
  'FOR KbdLoop = 0 TO 32

    'Kbd$ = ""
'You should really get rid of INKEY$ and check by other means
'Such as _KEYHIT
'INKEY$ is really slow
    Kbd = _KEYHIT

    IF Kbd = 27 THEN 'Esc


      IF ResolutionX = 1024 THEN

        CLS

        _DISPLAY

        SLEEP 1

        _FULLSCREEN _OFF

        SYSTEM

      END IF

      IF ResolutionX = 800 THEN

        ResolutionX = 1024
        ResolutionY = 768

      END IF

      IF ResolutionX = 640 THEN

        ResolutionX = 800
        ResolutionY = 600

      END IF

      IF ResolutionX = 320 THEN

        ResolutionX = 640
        ResolutionY = 480

      END IF

_MEMFREE scrn_mem 'Prevent a memory leak
      GOTO Restart

    END IF


  'NEXT KbdLoop


  ' Draw the Background

  DrawImages



  ' Test for collisions


'Don't use POINT
'Use _MEMGET instead to grab a LONG value. Ex:

'You have to calculate the starting byte in memory of your location
'This is dependent on the BPP of your screen image. If you have a 32-bit image, then it's 32 BPP
'256 colors is 8 BPP, 16 colors is 4 BPP
'You divide the BPP by 8 to get how many bytes each pixel is in size
'For a 32-bit image, that gives you 4 bytes per pixel (The same size as a LONG you'll note)

'From there, calculate the OFFSET via doing some addition and multiplying.
'Using Scrn_Width as the width, you can calculate the byte offset of a pixel like this:

'PicX is the X cord, PicY is the Y cord
' = (PicY * scrn_Width + PicX) * BPP

'Example _MEMGET's (You should note, the amount of Bytes you get is dependent on your variable type):

_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY - 21 + ViewY1) * scrn_Width + CharacterX - 20 + ViewX1) * Bytes_Per_Pixel, PCharacterUpTopLeft
_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY - 21 + ViewY1) * scrn_Width + CharacterX + ViewX1) * Bytes_Per_Pixel, PCharacterUpTopMiddle
_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY - 21 + ViewY1) * scrn_Width + CharacterX + 19 + ViewX1) * Bytes_Per_Pixel, PCharacterUpTopRight

  'PCharacterUpTopLeft = POINT(CharacterX - 20 + ViewX1, CharacterY - 21 + ViewY1)
  'PCharacterUpTopMiddle = POINT(CharacterX + ViewX1, CharacterY - 21 + ViewY1)
  'PCharacterUpTopRight = POINT(CharacterX + 19 + ViewX1, CharacterY - 21 + ViewY1)

_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY + 20 + ViewY1) * scrn_Width + CharacterX - 20 + ViewX1) * Bytes_Per_Pixel, PCharacterDownBottomLeft
_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY + 20 + ViewY1) * scrn_Width + CharacterX + ViewX1) * Bytes_Per_Pixel, PCharacterDownBottomMiddle
_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY + 20 + ViewY1) * scrn_Width + CharacterX + 19 + ViewX1) * Bytes_Per_Pixel, PCharacterDownBottomRight

  'PCharacterDownBottomLeft = POINT(CharacterX - 20 + ViewX1, CharacterY + 20 + ViewY1)
  'PCharacterDownBottomMiddle = POINT(CharacterX + ViewX1, CharacterY + 20 + ViewY1)
  'PCharacterDownBottomRight = POINT(CharacterX + 19 + ViewX1, CharacterY + 20 + ViewY1)

_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY - 20 + ViewY1) * scrn_Width + CharacterX - 21 + ViewX1) * Bytes_Per_Pixel, PCharacterLeftTopLeft
_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY + ViewY1) * scrn_Width + CharacterX - 21 + ViewX1) * Bytes_Per_Pixel, PCharacterLeftMiddleLeft
_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY + 19 + ViewY1) * scrn_Width + CharacterX - 21 + ViewX1) * Bytes_Per_Pixel, PCharacterLeftBottomLeft

  'PCharacterLeftTopLeft = POINT(CharacterX - 21 + ViewX1, CharacterY - 20 + ViewY1)
  'PCharacterLeftMiddleLeft = POINT(CharacterX - 21 + ViewX1, CharacterY + ViewY1)
  'PCharacterLeftBottomLeft = POINT(CharacterX - 21 + ViewX1, CharacterY + 19 + ViewY1)

_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY - 20 + ViewY1) * scrn_Width + CharacterX + 20 + ViewX1) * Bytes_Per_Pixel, PCharacterRightTopRight
_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY + ViewY1) * scrn_Width + CharacterX + 20 + ViewX1) * Bytes_Per_Pixel, PCharacterRightMiddleRight
_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY + 19 + ViewY1) * scrn_Width + CharacterX + 20 + ViewX1) * Bytes_Per_Pixel, PCharacterRightBottomRight

  'PCharacterRightTopRight = POINT(CharacterX + 20 + ViewX1, CharacterY - 20 + ViewY1)
  'PCharacterRightMiddleRight = POINT(CharacterX + 20 + ViewX1, CharacterY + ViewY1)
  'PCharacterRightBottomRight = POINT(CharacterX + 20 + ViewX1, CharacterY + 19 + ViewY1)

_MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY + ViewY1) * scrn_Width + CharacterX + ViewX1) * Bytes_Per_Pixel, PCharacterCentre
  'PCharacterCentre = POINT(CharacterX + ViewX1, CharacterY + ViewY1)


  ' Test for keypresses

  UpOn = _KEYDOWN(Key_Up&)
  DownOn = _KEYDOWN(Key_Down&)
  LeftOn = _KEYDOWN(Key_Left&)
  RightOn = _KEYDOWN(Key_Right&)


  ' Move Character based on user input


  CharacterMovedUp = 0
  CharacterMovedDown = 0
  CharacterMovedLeft = 0
  CharacterMovedRight = 0


  IF UpOn = -1 AND DownOn = 0 AND PCharacterUpTopLeft = _RGB(0, 0, 0) AND PCharacterUpTopMiddle = _RGB(0, 0, 0) AND PCharacterUpTopRight = _RGB(0, 0, 0) THEN

    IF CharacterY > ViewY1Limit + (ResolutionY / 2) AND CharacterY < ViewY2Limit - (ResolutionY / 2) + CharacterYInc THEN ViewY1 = ViewY1 + CharacterYInc: ViewY2 = ViewY2 + CharacterYInc

    CharacterY = CharacterY - CharacterYInc

    CharacterMovedUp = -1

  END IF

  IF DownOn = -1 AND UpOn = 0 AND PCharacterDownBottomLeft = _RGB(0, 0, 0) AND PCharacterDownBottomMiddle = _RGB(0, 0, 0) AND PCharacterDownBottomRight = _RGB(0, 0, 0) THEN

    IF CharacterY > ViewY1Limit + (ResolutionY / 2) - CharacterYInc AND CharacterY < ViewY2Limit - (ResolutionY / 2) THEN ViewY1 = ViewY1 - CharacterYInc: ViewY2 = ViewY2 - CharacterYInc

    CharacterY = CharacterY + CharacterYInc

    CharacterMovedDown = -1

  END IF

  IF LeftOn = -1 AND RightOn = 0 AND PCharacterLeftTopLeft = _RGB(0, 0, 0) AND PCharacterLeftMiddleLeft = _RGB(0, 0, 0) AND PCharacterLeftBottomLeft = _RGB(0, 0, 0) THEN

    IF CharacterX > ViewX1Limit + (ResolutionX / 2) AND CharacterX < ViewX2Limit - (ResolutionX / 2) + CharacterXInc THEN ViewX1 = ViewX1 + CharacterXInc: ViewX2 = ViewX2 + CharacterXInc

    CharacterX = CharacterX - CharacterXInc

    CharacterMovedLeft = -1

  END IF

  IF RightOn = -1 AND LeftOn = 0 AND PCharacterRightTopRight = _RGB(0, 0, 0) AND PCharacterRightMiddleRight = _RGB(0, 0, 0) AND PCharacterRightBottomRight = _RGB(0, 0, 0) THEN

    IF CharacterX > ViewX1Limit + (ResolutionX / 2) - CharacterXInc AND CharacterX < ViewX2Limit - (ResolutionX / 2) THEN ViewX1 = ViewX1 - CharacterXInc: ViewX2 = ViewX2 - CharacterXInc

    CharacterX = CharacterX + CharacterXInc

    CharacterMovedRight = -1

  END IF


  ' reset timer and display graphics

  GameSpeed = 0


  _DISPLAY

  '  END IF


  ' Loop here until an even amount of time has passed

  '  DO
  '
  'LOOP UNTIL PEEK(1132) >= 1
  '
  '  DEF SEG
  '
  '
  '  ' Increment the timer
  '
  '  GameSpeed = GameSpeed + 1
  '



LOOP


END



SUB DrawImages


' Clear the screen and draw each tile one at a time

LINE (0, 0)-(ResolutionX - 1, ResolutionY - 1), _RGB(0, 0, 0), BF

FOR DrawTile = 0 TO 9

  IF NOT (TileX1(DrawTile) + ViewX1 > ResolutionX OR TileX2(DrawTile) + ViewX2 < ResolutionX OR TileY1(DrawTile) + ViewY1 > ResolutionY OR TileY2(DrawTile) + ViewY2 < ResolutionY) THEN

    LINE (TileX1(DrawTile) + ViewX1, TileY1(DrawTile) + ViewY1)-(TileX2(DrawTile) + ViewX1, TileY2(DrawTile) + ViewY1), _RGBA(TileColourRed(DrawTile), TileColourGreen(DrawTile), TileColourBlue(DrawTile), 127), BF

  END IF

NEXT DrawTile


' Draw the Character (Ball in this case)

CIRCLE (CharacterX + ViewX1, CharacterY + ViewY1), 19, _RGB(63, 255, 63)
CIRCLE (CharacterX - 1 + ViewX1, CharacterY - 1 + ViewY1), 19, _RGB(63, 255, 63)
'PAINT (CharacterX + ViewX1, CharacterY + ViewY1), _RGB(63, 255, 63), _RGB(63, 255, 63)


'Central
IF NOT CharacterMovedUp AND NOT CharacterMovedDown AND NOT CharacterMovedLeft AND NOT CharacterMovedRight THEN
  CIRCLE (CharacterX + ViewX1, CharacterY + ViewY1), 3, 2
  CIRCLE (CharacterX - 1 + ViewX1, CharacterY - 1 + ViewY1), 3, 2
  'PAINT (CharacterX + ViewX1, CharacterY + ViewY1), 2, 2
END IF

'Up
IF CharacterMovedUp AND NOT CharacterMovedLeft AND NOT CharacterMovedRight THEN
  CIRCLE (CharacterX + ViewX1, CharacterY - 15 + ViewY1), 3, 2
  CIRCLE (CharacterX - 1 + ViewX1, CharacterY - 16 + ViewY1), 3, 2
  'PAINT (CharacterX + ViewX1, CharacterY - 15 + ViewY1), 2, 2
END IF

'Down
IF CharacterMovedDown AND NOT CharacterMovedLeft AND NOT CharacterMovedRight THEN
  CIRCLE (CharacterX + ViewX1, CharacterY + 15 + ViewY1), 3, 2
  CIRCLE (CharacterX - 1 + ViewX1, CharacterY + 16 + ViewY1), 3, 2
  'PAINT (CharacterX + ViewX1, CharacterY + 15 + ViewY1), 2, 2
END IF

'Left
IF CharacterMovedLeft AND NOT CharacterMovedUp AND NOT CharacterMovedDown THEN
  CIRCLE (CharacterX - 15 + ViewX1, CharacterY + ViewY1), 3, 2
  CIRCLE (CharacterX - 16 + ViewX1, CharacterY - 1 + ViewY1), 3, 2
  'PAINT (CharacterX - 15 + ViewX1, CharacterY + ViewY1), 2, 2
END IF

'Right
IF CharacterMovedRight AND NOT CharacterMovedUp AND NOT CharacterMovedDown THEN
  CIRCLE (CharacterX + 15 + ViewX1, CharacterY + ViewY1), 3, 2
  CIRCLE (CharacterX + 16 + ViewX1, CharacterY - 1 + ViewY1), 3, 2
  'PAINT (CharacterX + 15 + ViewX1, CharacterY + ViewY1), 2, 2
END IF



'Up and Left
IF CharacterMovedUp AND CharacterMovedLeft THEN
  CIRCLE (CharacterX - 10 + ViewX1, CharacterY - 10 + ViewY1), 3, 2
  CIRCLE (CharacterX - 11 + ViewX1, CharacterY - 11 + ViewY1), 3, 2
  'PAINT (CharacterX - 10 + ViewX1, CharacterY - 10 + ViewY1), 2, 2
END IF

'Up and Right
IF CharacterMovedUp AND CharacterMovedRight THEN
  CIRCLE (CharacterX + 10 + ViewX1, CharacterY - 10 + ViewY1), 3, 2
  CIRCLE (CharacterX + 11 + ViewX1, CharacterY - 11 + ViewY1), 3, 2
  'PAINT (CharacterX + 10 + ViewX1, CharacterY - 10 + ViewY1), 2, 2
END IF

'Down and Left
IF CharacterMovedDown AND CharacterMovedLeft THEN
  CIRCLE (CharacterX - 10 + ViewX1, CharacterY + 10 + ViewY1), 3, 2
  CIRCLE (CharacterX - 11 + ViewX1, CharacterY + 11 + ViewY1), 3, 2
  'PAINT (CharacterX - 10 + ViewX1, CharacterY + 10 + ViewY1), 2, 2
END IF

'Down and Right
IF CharacterMovedDown AND CharacterMovedRight THEN
  CIRCLE (CharacterX + 11 + ViewX1, CharacterY + 11 + ViewY1), 3, 2
  CIRCLE (CharacterX + 11 + ViewX1, CharacterY + 11 + ViewY1), 3, 2
  'PAINT (CharacterX + 10 + ViewX1, CharacterY + 10 + ViewY1), 2, 2
END IF



END SUB


I commented the code, but a quick list of things I did:

Put DEFLNG A-Z at the beginning of the code (Fairly noticeable speed boost)
Used _MEMIMAGE() and _MEMGET instead of POINT.
Use _KEYHIT() to check for the Esc key instead of INKEY$
Got rid of the loop around INKEY$ (Why were you calling INKEY$ 32 times every loop? That was sure to slow things down)
Got rid of the PAINT statements.

To go from here, I would recommend drawing out the images at the beginning of the program, and save a separate image for each state of the player. Then, when you need to draw out the player instead of having to use PAINT and CIRCLE every-time, you can just use one _PUTIMAGE which is sure to be faster.

Matt

WOW, don't know how I missed this post! I'm going to check this out now... Thanks
James Hetter's Revenge has been unleashed! Follow the games progress here:
http://www.qb64.net/forum/index.php?topic=6762.0

Download the latest version here:
https://www.dropbox.com/s/8p8gguliw1y6ink/Hetters%20Revenge.zip?m

JustinRichardsMusic

  • Sr. Member
  • ****
  • Posts: 335
  • Character names can be found in metal from the 90s
    • Email
Re: Will QB64-GL fix this issue???
« Reply #24 on: March 21, 2013, 05:46:13 PM »
Turns out I have version 0.953 which has no _MEM capabilities. Need to download version 0.954, I'll post back soon...
James Hetter's Revenge has been unleashed! Follow the games progress here:
http://www.qb64.net/forum/index.php?topic=6762.0

Download the latest version here:
https://www.dropbox.com/s/8p8gguliw1y6ink/Hetters%20Revenge.zip?m

JustinRichardsMusic

  • Sr. Member
  • ****
  • Posts: 335
  • Character names can be found in metal from the 90s
    • Email
Re: Will QB64-GL fix this issue???
« Reply #25 on: March 21, 2013, 06:07:23 PM »
MIND = BLOWN!!!

That is a massive speed increase DSMan - you are a deadset legend.

I've tested it on two machines.

1.6GB machine with 2GB ram - A small speed increase
2.2GB machine with 2GB ram - A massive speed increase

Which does kind of point out that proccessing power and the absence of a video card really does affect the performace of even basic software rendered games.

I'm going to sift through the code now and get my head around these _MEM statements.  I might even make a simple tutorial to put up on the forum aswell, because it is clear to me now that THIS method is definately the way to go with making games in QB64.  And if someone is looking for a start, they may as start with the best method possible...

Thanks again DSMAN!
James Hetter's Revenge has been unleashed! Follow the games progress here:
http://www.qb64.net/forum/index.php?topic=6762.0

Download the latest version here:
https://www.dropbox.com/s/8p8gguliw1y6ink/Hetters%20Revenge.zip?m

codeguy

  • Hero Member
  • *****
  • Posts: 3552
  • what the h3ll did i name that code?
    • stuff at dkm
    • Email
Re: Will QB64-GL fix this issue???
« Reply #26 on: March 22, 2013, 07:12:32 AM »
http://www.qb64.net/forum/index.php?topic=3837.msg38775#msg38775
link to ellipse/circle rendering algos used by unseenmachine and terry. they are wicked-fast ;D and developed by codeguy
these will provide a further increase in rendering circles and ellipses, outlined or filled.
« Last Edit: March 22, 2013, 07:50:52 AM by codeguy »
http://denteddisk.forums-free.com/make-an-appointment-with-the-resident-code-guru-f34.html

JustinRichardsMusic

  • Sr. Member
  • ****
  • Posts: 335
  • Character names can be found in metal from the 90s
    • Email
Re: Will QB64-GL fix this issue???
« Reply #27 on: March 26, 2013, 04:57:15 AM »
Quote

    'Use _MEMGET instead to grab a LONG value. Ex:

    'You have to calculate the starting byte in memory of your location
    'This is dependent on the BPP of your screen image. If you have a 32-bit image, then it's 32 BPP
    '256 colors is 8 BPP, 16 colors is 4 BPP
    'You divide the BPP by 8 to get how many bytes each pixel is in size
    'For a 32-bit image, that gives you 4 bytes per pixel (The same size as a LONG you'll note)

    'From there, calculate the OFFSET via doing some addition and multiplying.
    'Using Scrn_Width as the width, you can calculate the byte offset of a pixel like this:

    'PicX is the X cord, PicY is the Y cord
    ' = (PicY * scrn_Width + PicX) * BPP

    'Example _MEMGET's (You should note, the amount of Bytes you get is dependent on your variable type):

    _MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY - 21 + ViewY1) * Scrn_Width + CharacterX - 20 + ViewX1) * Bytes_Per_Pixel, PCharacterUpTopLeft
    _MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY - 21 + ViewY1) * Scrn_Width + CharacterX + ViewX1) * Bytes_Per_Pixel, PCharacterUpTopMiddle
    _MEMGET scrn_mem, scrn_mem.OFFSET + ((CharacterY - 21 + ViewY1) * Scrn_Width + CharacterX + 19 + ViewX1) * Bytes_Per_Pixel, PCharacterUpTopRight

    'PCharacterUpTopLeft = POINT(CharacterX - 20 + ViewX1, CharacterY - 21 + ViewY1)
    'PCharacterUpTopMiddle = POINT(CharacterX + ViewX1, CharacterY - 21 + ViewY1)
    'PCharacterUpTopRight = POINT(CharacterX + 19 + ViewX1, CharacterY - 21 + ViewY1)


Hey DSMAN, I was wondering if you could give me a little more insight into this formula for locating a pixel in a _MEM block.

The formula is (Y * image_width + X) * Bytes_Per_Pixel

Why this formula?  I know that it works, but it seems illogical to me!?


Also, I thought I should note that you added _DONTBLEND back into your example, and when I took it out again the speed didn't decrease at all which surprised me...

Thanks
Justin
James Hetter's Revenge has been unleashed! Follow the games progress here:
http://www.qb64.net/forum/index.php?topic=6762.0

Download the latest version here:
https://www.dropbox.com/s/8p8gguliw1y6ink/Hetters%20Revenge.zip?m

JustinRichardsMusic

  • Sr. Member
  • ****
  • Posts: 335
  • Character names can be found in metal from the 90s
    • Email
Re: Will QB64-GL fix this issue???
« Reply #28 on: March 26, 2013, 05:27:52 AM »
I also should note that I re-instated the paint commands (all of them) and saw no visible loss in performance either...


It seems to me that the _MEM method speeds up the process so much that the paint commands no longer cause a noticable delay.  I guess if there were a whole heap of them covering larger areas it would be a different story...

And as I said before I would never use paint normally, I only used it for this demo to simplify it, but thought it was worth a mention anyways...

Cheers
Justin
James Hetter's Revenge has been unleashed! Follow the games progress here:
http://www.qb64.net/forum/index.php?topic=6762.0

Download the latest version here:
https://www.dropbox.com/s/8p8gguliw1y6ink/Hetters%20Revenge.zip?m

DSMan195276

  • Hero Member
  • *****
  • Posts: 1978
  • Yes
    • Email
Re: Will QB64-GL fix this issue???
« Reply #29 on: March 26, 2013, 07:51:54 AM »
Quote
Hey DSMAN, I was wondering if you could give me a little more insight into this formula for locating a pixel in a _MEM block.

The formula is (Y * image_width + X) * Bytes_Per_Pixel

Why this formula?  I know that it works, but it seems illogical to me!?


Also, I thought I should note that you added _DONTBLEND back into your example, and when I took it out again the speed didn't decrease at all which surprised me...

Quote
I also should note that I re-instated the paint commands (all of them) and saw no visible loss in performance either...

It seems to me that the _MEM method speeds up the process so much that the paint commands no longer cause a noticable delay.  I guess if there were a whole heap of them covering larger areas it would be a different story...

And as I said before I would never use paint normally, I only used it for this demo to simplify it, but thought it was worth a mention anyways...

I think it's worth noting that the biggest speed increase probably came from getting rid of INKEY$ as well as the loop around INKEY$. The loop you had make your program check INKEY$ 32 times before the screen could be refreshed. That's way to much and very bad, if you do use INKEY$ only use it once per loop so that you don't kill you speed so much.

Second, with _MEM, you have to keep in mind how the image looks in memory. You can think of memory as a big 1-dimensional array. There is no 2D memory, so everything has to be represented in a way that is 1D. Even 2D arrays are represented in this 1D space, it's not as complicated as you may think though.

But, forget about the _MEM stuff and instead picture a rectangle made-up of a bunch of blocks. This rectangle has a width of six blocks and a height of eight blocks. We'll call the top left block (0, 0), and then going from there the block to it's right is (1, 0) and the block under it is (0, 1). Fairly standard coordinate system. Now, imagine that we took each row of blocks and put them right after the row above it, so when we're done we just have a single row of blocks all in a line. In this row, the first six blocks are the first row, the next six blocks are the next row, the six blocks after that are the 3rd row, etc. Until we get to the 8th row and then we're done.

Now, to deal with our now single row of blocks, the easiest thing to do is to just translate our 2D cords into 1D cords, and we can do this just by a bit of math. By looking at our 1D row of blocks, you can notice that every row is together, so we have blocks (0, 0) to (5, 0) and then right after that blocks (0, 1) to blocks (5, 1), and that pattern continues until you get to (0, 7) to (0, 7). And now to the math, we need to find a way of translating our original 2D cord system into this 1D system. First, we take the Y cord, which simply represents which row of blocks we want. We know that each row is located one right after another. So the first row is at block 0, the second row is at block 6, the third row is at block 12, etc. This pattern continues, because to get to each row, you have to first go past the rows behind it, and remember each row has a 'width' number of blocks in it (6 in our case, since our width was six). So to get to the offset of our row, we just do the width * Y. That's part of the math, all we have left is the X cord. You can notice the X cord doesn't actually change, they are still right after each-other. Since we already know where the row is located, width * Y, we can just add the X cord to this number to get what block we're at.

The image is in memory exactly the same way, every row is right after that last one. So we can use the same math, width * Y + X to get the location. The only other rick is that we were assuming each block is one 'unit', or one pixel. We're address the memory byte by byte, and our pixels aren't actually single bytes, so you have to multiply the 1D location by the number of bytes per pixel (4 in most cases).

_DONTBLEND only has an effect on the drawing commands and image commands, it has no effect on the _MEM command because we bypass all of that. That's probably most of the reason why it doesn't effect the speed much.

As for PAINT, it is possible it's a small enough area that it doesn't make a huge difference, I would still recommend drawing your character out before hand (In all it's positions) into seperate images. _PUTIMAGE will be tons faster then drawing the character each time.

Matt
"Cast your cares on the Lord and he will sustain you; he will never let the righteous be shaken" -- Psalm 55:22
QB64 Linux Installer

  • Print