Image Map Image Map
Page 4 of 4 FirstFirst 1234
Results 31 to 34 of 34

Thread: Optimizing a QuickBasic game

  1. #31
    Join Date
    Jul 2015
    Location
    Vancouver Island
    Posts
    240

    Default

    Quote Originally Posted by mangis View Post
    In SCREEN 13 using a filled box (LINE (0,0)-(319,199),0,BF) is much faster than using CLS. Might be worth a try in SCREEN 9 as well.
    This is true in mode 9 too (see above), even if I clear the full screen, but the difference isn't as dramatic. Resizing the clear box dynamically definitely helps.

    Quote Originally Posted by mangis View Post
    I looked at GRIDFLIP.BAS

    The perspective calculations for the grid look extremely expensive. 4608 floating point operations (at a glance) per frame. [...]

    Since you only have 6x6 possible states for your projected coordinates, why not precalculate them to an integer lookup? The size should only be 20kb.
    The only problem with this approach is I left the geometry completely variable on purpose, so that users can adjust for their headset (or I can add support for extra headsets easily by creating a new geometry profile) and I don't want to sacrifice that. You can change all kinds of things in-game - the zoom level, eye spacing, stereo balance, even the grid position on-screen.

    Otherwise I could just use simple + & - ops for *all* X/Y movements essentially turning it into a 2D parallax scroll. I think I prefer it to be a real 3D engine conceptually though.

    Quote Originally Posted by mangis View Post
    But even that would be unnescessary, since you only need to calculate the first Z-row of points in your grid and the distance to the next point. Then you can just use integer addition to get the next points at that height.

    Something like this maybe:
    Code:
      
      halfHVW = (HVW / 2)
      halfHVWx3 =  halfHVW * 3
      
      FOR zb = 8 TO 1 STEP -1
        baseXL = (((Grid(zb, 1, 1).X - ReyeX) / (Grid(zb, 1, 1).Z - eyez)) * HVW) + halfHVW + RiftFudge
        baseXR = (((Grid(zb, 1, 1).X - LeyeX) / (Grid(zb, 1, 1).Z - eyez)) * HVW) + halfHVWx3 - RiftFudge
        baseY  = (((Grid(zb, 1, 1).Y - eyeH) / (Grid(zb, 1, 1).Z - eyez)) * VH) + HVH
        distance = ((((Grid(zb, 2, 1).X - ReyeX) / (Grid(zb, 2, 1).Z - eyez)) * HVW) + halfHVW + RiftFudge) - baseXL
        ydist = -distance + offsetY
        
        FOR B = 1 TO 6
          ydist = ydist + distance
          xdist = -distance + eyeoffset
          flatY = baseY  + ydist
          
        FOR A = 1 TO 6
            xdist = xdist + distance        
            flatXL = baseXL + xdist
            flatXR = baseXR + xdist
    
    ...
    Wow, thanks for looking into it so much! If I'm reading this right, you've essentially made a hybrid version that calculates the upper left and then bases everything else off that? That should work with my geometry adjustment controls too. I'm gonna give this a try & see how it does.

    I also think I can get away with mirroring the right eye from the left (just the projected grid positions, not the objects on the grid) and eliminate all the floating point calculations for flatXR. *** EDIT: that got me a bunch of speed, but of course doesn't work with the way the game board moves around to react to the player movements. And that's done as part of the 3D geometry calculation, so there's no good 2D way to do any mirroring. The board isn't symmetrical in X unless the player is in the exact middle, which can't happen. I should remember how my own game is written.

    Quote Originally Posted by mangis View Post
    Most of the objects are rendered with Qbasics unoptimized geometry primitives. Like CIRCLE (flatXR, flatY), 5, 15.
    It might be much faster to prerender them, store them with GET, and draw them with PUT in-game.
    I thought you couldn't use GET & PUT with double-buffering? I.e. you can't PUT things onto the offscreen buffer

    The original plan was for the player & enemy sprites to be 3D wireframe objects, but obviously that didn't materialize (I don't have a very easy way to "project" things off the grid, especially in Z.)
    Last edited by xjas; December 12th, 2017 at 01:24 PM.

  2. #32

    Default

    Quote Originally Posted by xjas View Post
    The only problem with this approach is I left the geometry completely variable on purpose, so that users can adjust for their headset (or I can add support for extra headsets easily by creating a new geometry profile) and I don't want to sacrifice that.
    The lookup could be recalculated when those variables would be adjusted. In case the single Z-row + integer addition works well enough, you would only need (2 x 6 x 6 x 3) == 216 integers stored per recalc. That should still be well under a second even on a slow machine.

    Although I can understand features regarding VR could easily grow beyond that.

    Quote Originally Posted by xjas View Post
    I thought you couldn't use GET & PUT with double-buffering? I.e. you can't PUT things onto the offscreen buffer
    Ah, I didn't know that.

  3. #33
    Join Date
    Jul 2015
    Location
    Vancouver Island
    Posts
    240

    Default

    Happy new year guys! Working on this again.

    Here's a new version if anyone wants to try it out. It's somewhat of a release candidate for 1.3.

    Binary (DOS only for now): https://www.dropbox.com/s/5w7gz517jk...D3D21.EXE?dl=0
    Source: https://www.dropbox.com/s/nckiq4klgk...D3D21.BAS?dl=0

    I've basically taken all your suggestions and worked them into this one, to varying degrees. The last HUGE improvement was using iterative addition-based geometry calculation based on Mangis's routine above (thanks TONS for that!) I'm still not pre-calculating anything, but this was a nice compromise in flexibility and ease of implementation for pretty big gains. I'm now seeing ~4.5 FPS on the 386DX, which is what the original game jam version ran at on a P3/1000 and far faster than the "theoretical" maximum I calculated with the old render routine. Also does an easy 40-60FPS on my Pentium MMX (with vsync disabled).

    Optional command line parameters:
    LOWRES, NOVSYNC (self-explanatory)

    I'm pretty proud of how far this has come. On slow systems you can use the LOWRES parameter and shrink the playfield (or use Oculus DK1 mode) for big speed gains. It scales well.

    Some maybe-useful debug keys:
    ~ - debug info drop-down
    ! - displays framerate when you quit with ESC (resets if you die)

    [ ] - change eye spacing
    ( ) - change stereo balance (essentially changes the distance between the eyes POST render)
    , . - zoom game board in/out
    7/8/9/0 - nudge game board around the screen

    There are some other secret debug keys that do silly things and a "secret" VR mode (WIP) that shouldn't be too hard to find.

    If you give this a try and note any bugs or things that look like bugs, I would LOVE to hear them!

    I particularly had trouble with the screen-clearing routine not clearing everything when messing with the geometry, and rounding pixel coordinates causing compound errors over time. I'm actually not doing rounding anymore beyond what PSET does when fed a decimal value, it wasn't necessary. Both those issues should be fixed (unless you zoom in so much it wraps around to negative zoom.)
    Last edited by xjas; January 3rd, 2018 at 02:38 AM.

  4. #34
    Join Date
    Jul 2015
    Location
    Vancouver Island
    Posts
    240

    Default

    If anyone has a CyberMaxx or Virtual-I/O iGlasses headset (or a VFX1 so I can confirm the geometry profile I made on mine is right for all of them) and wants to help me add support for these devices, I would love to hear from you.
    Last edited by xjas; January 3rd, 2018 at 12:26 AM.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •