GLBasic forum

Codesnippets => Code Snippets => Topic started by: spacefractal on 2014-Jun-04

Title: Little autoscaling system with a virtual Image (suitable for Android).
Post by: spacefractal on 2014-Jun-04
Rater to write a story about this one, you can instead read about it in this thread, who started it (there is a project in that link, so im did not add this here again):
http://www.glbasic.com/forum/index.php?topic=9834.msg85756#msg85756

Here is code which would do scaling a virtual image to any resolution and uses either side letterbox or top/bottom. If the scaling is close to a perfect scaling, its would been pefectly that and might crop few pixels.

This code using a 428x240 virtual image, but could been use any virtual resolution. Also when you have scaling value, you could eventuelly expand this code to could uses the whole image, if you game supports that (examping a scrolling game). Im have not do that, but its give you a idea.

The main idea here is using PaintImage() which perfecm all scaling calcuations for you, before checking mousestate and for drawing the virtual screen. Hence its a function.

Code (glbasic) Select

// ----------------------------------------------------------------------------- CONFIG VARIABLES
GLOBAL VW = 428                                 // The virtual Width screen
GLOBAL VH = 240                                 // The virtual Height screen

// ----------------------------------------------------------------------------- DECLARE VARIABLES
GLOBAL FramesPerSecond                          // Helmos fps Routine
GLOBAL sx,sy                                    // Android Get Screen Size (pixels)
GLOBAL PX#, PY#, PW#, PH#                       // The calculate rectangle
GLOBAL sx, sy                                   // The screen resolution
GLOBAL scaling                                  // perform scaling value

// ----------------------------------------------------------------------------- SETUP SCREEN
SETSCREEN 960, 640, 0                           // a test resolution (this skips on Android, but nice for testing on Windows
SYSTEMPOINTER TRUE                              // Show mouse
LIMITFPS 60                                     // Vertical sync limit fps
AUTOPAUSE TRUE                                  // Set pause when lost focus

// ----------------------------------------------------------------------------- LOAD VISUAL ASSETS
LOADSPRITE "Media/TEST.bmp",1                   // Background image test

// ----------------------------------------------------------------------------- SET OUTPUT SCREEN / TOUCH
//      --- ANDROID SETS
CREATESCREEN 1,200,VW,VH                       // Create virtual screen
GETSCREENSIZE sx,sy                            // Get Screen Size of the current window
scaling=sx/VW                                  // set scaling for any resolution, letter boxed top/bottom
IF scaling*VH>sy THEN scaling=sy/VH            // set scaling for any resolution, letter boxed side

// round up to a perfect scaling, if its very close
LOCAL sc=INTEGER(FMOD(scaling, 1)*10)          // a integer reminder of a float.
IF sc<>0 THEN scaling=scaling+0.025            // make sure the image is used the whole screen and not lost one px.
IF sc=9 THEN scaling=INTEGER(scaling+0.1)      // if very close to a perfect scaling (like 1.9, 2.9 etc), perfect scaling it.
IF sc=4 THEN scaling=INTEGER(scaling)+0.5      // if very close to a half pixel perfect scaling (like 1.4, 2.4 etc).


// ----------------------------------------------------------------------------- MAIN GAME LOOP
WHILE TRUE
// ----------------------------------------------------------------------------- DISPLAY
// --- SET VIRTUAL SCREEN
ALPHATESTING 0.0                           // GLBv12 alpha on
SMOOTHSHADING FALSE                        // Hard pixels
USESCREEN 1                                // Set Virtual screen buffer

//  --- DRAW TEST IMAGE
CLEARSCREEN RGB(0, 0, 0)
DRAWSPRITE 1,0,0

//  --- CHECK MOUSESTATE BASED ON THE VIRTUAL SCREEN ---
PaintImage(200, 0, 0, 0, 0, scaling, 0, 0)  // calculate retangle of the virtual image placement (but its dont draw it)

LOCAL xpos#, ypos#, button1, button2        // Declare some local variables
MOUSESTATE xpos, ypos, button1, button2     // check mousestate
xpos#=(xpos-PX)/scaling                     // calculate mousestate based on virtual image instead of surface
ypos#=(ypos-PY)/scaling                     // calculate mousestate based on virtual image instead of surface

IF xpos<0 THEN xpos=0                       // check edges of the virtual image
IF ypos<0 THEN ypos=0
IF xpos>VW THEN xpos=VW
IF ypos>VH THEN ypos=VH

xpos=INTEGER(xpos)                          // final xpos mouse position
ypos=INTEGER(ypos)                          // final ypos mouse position


//      --- PRINT DEBUG INFO
FramesPerSecond=FPS()
PRINT "SCALING     : "+scaling,117,24
PRINT "GETSCREEN X : "+sx,117,34
PRINT "GETSCREEN Y : "+sy,117,44
PRINT "MOUSE X     : "+xpos,117,56
PRINT "MOUSE Y     : "+ypos,117,66
PRINT "FPS         : "+FramesPerSecond,117,78


// ----------------------------------------------------------------------------- DISPLAY [END]

// ----------------------------------------------------------------------------- OUTPUT AND SCALE
USESCREEN -1         // Set Backbuffer
SMOOTHSHADING FALSE  // Hard pixels

// Paint the image
PaintImage(200, 0, 0, 0, 0, scaling, 0, 1)   

    // this is a example how to check, if its have been a letter boxed viw.
// draw a line to the border, if its a side letter box
IF PX>0
DRAWRECT PX-scaling, 0, scaling+0.5, PH, RGB(255, 255, 255)
DRAWRECT PX+PW, 0, scaling+0.5, PH, RGB(255, 255, 255)
ENDIF

IF PY>0
// draw a line to the border, if its a top/bottom letter box
DRAWRECT 0, PY-scaling, PW, scaling+0.5, RGB(255, 255, 255)
DRAWRECT 0, PY+PH, PW, scaling+0.5, RGB(255, 255, 255)
ENDIF

// ----------------------------------------------------------------------------- OUTPUT AND SCALE [END]
SHOWSCREEN
WEND
// ----------------------------------------------------------------------------- MAIN GAME LOOP [END]

FUNCTION FPS:
        // Created by Hemlos (a long time ago), updated Aug.7,2014
        STATIC OSTimeCurrent$, OSTimePrevious$, FPSBuffer
        LOCAL FramesPerSecond
        OSTimePrevious$ = OSTimeCurrent$
        INC FPSBuffer, 1
        OSTimeCurrent$ = PLATFORMINFO$("TIME")
        IF OSTimePrevious$ <> OSTimeCurrent$
                FramesPerSecond = FPSBuffer
                FPSBuffer = 0
        ENDIF
        RETURN FramesPerSecond
ENDFUNCTION

// id     = id of the image
// x#     = x pos of the image
// y#     = y pos of the image
// xspot  = 0 = center, -1 = left, 1 = right hotspot
// yspot  = 0 = center, -1 = top, 1 = bottom hotspot
// zoom   = scaling
// mirror = should the image been mirrored?
// draw   = 1 draw the image after calculate the retangle
//          0 do NOT draw the image, but just calculate the retangle)
FUNCTION PaintImage: id, x#, y#, xspot, yspot, zoom#, mirror=0, draw=1
// get size of the incoming sprite
LOCAL h#, w#
GETSPRITESIZE id, w, h
IF w<1 OR h<1
RETURN 0
ENDIF

// calculate rectangle of the sprite positions
IF xspot=-1 THEN PX=x#+0.5
IF xspot=0 THEN PX=sx/2.0-(w#*zoom#/2.0)+x#+0.5
IF xspot=1 THEN PX=sx-w#*zoom#-x#+0.5
IF yspot=-1 THEN PY=y#
IF yspot=0 THEN PY=sy/2.0-(h*zoom#/2.0)+y#
IF yspot=1 THEN PY=sy-h#*zoom#-y#

// checks if the rectangle is on the screen
IF PY-PH>sy OR PX-PW>sx OR PY<-h*zoom*1.2 OR PX<-w*zoom*1.2 THEN RETURN 0

// perform scaling to the image.
PW=INTEGER(w*zoom#)
PH=INTEGER(h*zoom#)

// should the image draw or not? usable for rectangle calculate for ingame controls.
IF draw=0 THEN RETURN 0


// draw the image (using STRETCHSPRITE)
IF zoom<1 THEN SMOOTHSHADING TRUE
IF mirror=1
STRETCHSPRITE id, PX, PY, -ABS(PW), ABS(PH)
ELSE
STRETCHSPRITE id, PX, PY, ABS(PW), ABS(PH)
ENDIF
IF zoom<1 THEN SMOOTHSHADING FALSE
RETURN 1
ENDFUNCTION
Title: Re: Little autoscaling system with a virtual Image (suitable for Android).
Post by: erico on 2014-Aug-06
Good going!

Just a bump here so people keep this in mind. ;)
Title: Re: Little autoscaling system with a virtual Image (suitable for Android).
Post by: spacefractal on 2014-Aug-06
im have just update the code, so the virtual resolution can been set in a variable, start in the code (here of course testing with 428x240).

Mousepos will still correspons to the virtual image retangle, not the full screen. That why im used PaintImage() for calculate the mouse position. Its was to calculate the retangle, where the game would paint the virtual image on the screen.
Title: Re: Little autoscaling system with a virtual Image (suitable for Android).
Post by: erico on 2014-Aug-06
Great, this is much smaller, smarter and cleaner code then what I had before. :good:
Title: Re: Little autoscaling system with a virtual Image (suitable for Android).
Post by: Hemlos on 2014-Aug-08
heh i forgot about that FPS() function, i made several styles. Glad to see it does the trick on android.
IMO its a cheap trick, as it doesnt actually track time, but rather waits for the time on the OS to tick a second.
I like it though for several reasons;
For one thing, it uses the OS to keep track of time as opposed to the program doing it.
The math load on the cpu is minimal as opposed to tracking milliseconds, as its just an incrementing integer here.
And the update happens once per second.

I cleaned it up, optimized it for you..
I made the updater LOCAL, this is an optimization.
A compliation optimization too, got rid of the semicolons.


Code (glbasic) Select

FUNCTION FPS:
        // Created by Hemlos (a long time ago), updated Aug.7,2014
        STATIC OSTimeCurrent$, OSTimePrevious$, FPSBuffer
        LOCAL FramesPerSecond
        OSTimePrevious$ = OSTimeCurrent$
        INC FPSBuffer, 1
        OSTimeCurrent$ = PLATFORMINFO$("TIME")
        IF OSTimePrevious$ <> OSTimeCurrent$
                FramesPerSecond = FPSBuffer
                FPSBuffer = 0
        ENDIF
        RETURN FramesPerSecond
ENDFUNCTION
Title: Re: Little autoscaling system with a virtual Image (suitable for Android).
Post by: erico on 2014-Aug-08
Yep, I borrowed it from you from some older thread. ;/ ;)

I find it usefull while I understand nothing that goes on, but it works fine on all OSes.
I use it often on my snippets down the snippet section and the game I´m doing while in development.
I hope you don´t mind, it is really nice!
Title: Re: Little autoscaling system with a virtual Image (suitable for Android).
Post by: Hemlos on 2014-Aug-08
If you use it, use the one i updated above.
I dont mind at all, i am a firm believer in sharing code for especially for learning purposes.

There are other ways of doing it too...if your program  needs to syncronize across different libs per say, you should use one that tracks the milliseconds.

edit: For instance, my 3d particle engine requires a very precise tracker reporting from the end of the main loop before the showscreen.
Title: Re: Little autoscaling system with a virtual Image (suitable for Android).
Post by: erico on 2014-Aug-08
Thanks a lot for sharing Hemlos, I really like it and even better now optimized by its own owner! :good: :booze:
Super thanks!

Hey, why don´t you put it on its own thread? I´m sure this deserves it. ;)
Title: Re: Little autoscaling system with a virtual Image (suitable for Android).
Post by: Hemlos on 2014-Aug-08
im sure there are some threads with it...id have to dig around first before doing that.

aboout linux mint 17 test....itll run a terminal program, but not an opengl window.....bug?
In GLbasic, i did set the options and multiplatform to be linux...i attached it here
and here is a screenshot of it running in windows attached as well
Title: Re: Little autoscaling system with a virtual Image (suitable for Android).
Post by: erico on 2014-Aug-08
oh my...that is a lot different from what I had on osx...I´d need sometime to think...heck maybe I can get an old hd or linux-on-pendrive to help this front.
Can we take this discussion to a more specific thread? We could use your latest thread on linux or open a newer one, your call.
Title: Re: Little autoscaling system with a virtual Image (suitable for Android).
Post by: spacefractal on 2014-Aug-08
im have updatedd the post with the update to the fps function. im diddent touch this one really and was not a part of this snippet.
Title: Re: Little autoscaling system with a virtual Image (suitable for Android).
Post by: Hemlos on 2014-Aug-08
I dont know...let me know..It seems to be based on your other thread Erico
Merge?

what do you think SF?
Title: Re: Little autoscaling system with a virtual Image (suitable for Android).
Post by: erico on 2014-Aug-09
Oh no, I mean your lib is perfect.

What I take as bad, is the image you uploaded from the virtual screen apk test on another thread, that one is not using this code spacefractal upgraded here.
But is should work if you did the changes I mentioned a couple posts before and I´m pretty sure there should not be any red parts into it.

So I wonder now if virtual screens are working on linux. I have to figure this out myself.
I will create a post about it or invade your linux post ;/

Thanks for testing! And super thanks for the FPS lib!
Title: Re: Little autoscaling system with a virtual Image (suitable for Android).
Post by: spacefractal on 2014-Aug-09
im seperated my version of the virtual screen, so other easier could search and find it, which was based on the code Erico did for the Android Resolution test, but cleaned it up, so its can been used in any resolution rather than doing hardcoded one, used with his style in code.

So for Android, you should newer hardcode resolutions, which can go wrong. Its even better if its used with Android Extras (its not that hard to uses the basic features and the bug fixes im fixed).

The FPS code was really not a part of this code, but im just added it anyway for some reason, and updated my post to reflect that.

For the Resolution test code and pictures, Erico gave and asked us to test, should been posted in his thread, not mine. Its uses two differents of code.....
Title: Re: Little autoscaling system with a virtual Image (suitable for Android).
Post by: erico on 2014-Aug-09
It is fine Space!

It even got Hemlos to update his lib! :) :good:  :P

My concern is actually on the virtual screen on Linux here and how a GLB game goes on Linux.
Give me a while to set up a linux distro to try figure this out.

Mac/Linux/PC output of a tool or a game is really important imho. I gotta check what is going on
Title: Re: Little autoscaling system with a virtual Image (suitable for Android).
Post by: fuzzy70 on 2014-Aug-09
Linux can, quite frankly, be a nightmare to deal with or everything works without problems. While I am very familiar with using Linux including building/compiling/installing apps etc from source they vary a lot between distro's. I never really dug deeper into some aspects of it like sound or graphics but just simply followed the dependencies of whatever I was installing.

Gfx drivers where a cause of numerous headaches as the "Official" binaries from the likes of Nvidia or Ati/AMD where not guaranteed to work on all distro's resulting in having to use alternate ones which lacked features like hardware 3D acceleration or something else. Same went for sound in that you had OSS/ESS/Pulse Audio plus others & I never really got to the bottom of what the differences where other than some programs used one over the other. I have even come across distro's where the supplied games where silent even though the had sound options & had to install a different sound system to the default one to make audio work.

Drivers have pretty much always an issue with Linux due to manufacturers of hardware refusing to open source their ones & making binary only versions for whatever distro they see fit to support, which is no fault of Linux itself.

So many options has its plus points in that you can tailor the system to your needs, but the offshoot of that is not everything you want will work without some extras or tweaking.

Lee
Title: Re: Little autoscaling system with a virtual Image (suitable for Android).
Post by: erico on 2014-Aug-09
I see, but you have the likes of humble bundle, which needs pc mac linux support games the least.
They probably don´t have to bother the minimum details of each disto?

But somehow it has to work with at least one, or the more popular or easier ones.
So I was wondering, UBUNTU seems to be the more popular one, at least propaganda wise.
I have to set up something that makes sure at least a base of linux system works with the output of GLB.

Title: Re: Little autoscaling system with a virtual Image (suitable for Android).
Post by: fuzzy70 on 2014-Aug-09
I have purchased quite a few Humble Bundle games, some of which there are no Linux versions but they are in the main games or bundles that where Windows specific. I just had a look at my account & some require MOJO whatever that is, some are as DEB packages, some are .BIN & others are .tar.gz (whether they need to be compiled from source I'm not sure).

I have to be honest & say that games where not really my thing on Linux other than some of the Gnome desktop games like "Robots" or puzzle/card games. I did have issues with GLB programs I wrote in Linux, none of them using sound but just graphics in that they would just flash a window then close or output was not the same as it was in Windows. Again that was down to different distro's, worked fine on some & not on others even with installing any required libraries.

Unfortunately I have not had Linux installed for a year or 2 but when I last had it I tried Fedora, Open SUSE, & Xubuntu, I was never a fan of regular Ubuntu with Unity & the lightweight Xubuntu gave me the same software but without the extra bloat & resource hogging of the regular version. I think Fedora gave me the most issues with respect to getting a fully functional gfx driver installed as Nvidia didn't provide one for it at that time, Open SUSE had some issues that I do not recall at the moment & Xubuntu I was unable to use my wireless card without a lot of messing about when I installed it even though it worked perfectly if I ran it from the LiveCD.

All in all a lot of fun & games, whereas my previous pc I had very minor or no hassles at all so it is pretty much the luck of the draw. I will return to Linux at some point but it's not high on my list of to-do's  :D

Lee
Title: Re: Little autoscaling system with a virtual Image (suitable for Android).
Post by: erico on 2016-Apr-23
Hmmm...I´m trying to implement this function on the avocado game and am failing miserably...
It keeps blank, I made a few alterations with no success yet.


Title: Re: Little autoscaling system with a virtual Image (suitable for Android).
Post by: Ian Price on 2016-Apr-23
Here's a tip erico.

Create a virtual screen the size of the caanoo screen. Use that screen to draw everything to. Then use the normal screen and either use POLYVECTOR to scale or STRETCHSPRITE or ZOOMSPRITE to display the image.

Here's a simple demo to show how to scale (even 10 all round). To scale to rectangular screens you might need to use SCALE_X and SCALE_Y variables.

Code (glbasic) Select

SETSCREEN 640,640,0

CREATESCREEN 1,999,64,64

GLOBAL scale%=10 // Scales the virtual screen by factor of 10


WHILE TRUE

  // Use virtual screen to draw on
  USESCREEN 1

  // Draw rects randomly by pressing SPACE
  IF KEY(57)
   FOR n=0 TO 300
    DRAWRECT RND(64),RND(64),RND(16),RND(16),RGB(RND(255),RND(255),RND(255))
   NEXT
  ENDIF

  PRINT "PRESS",10,10
  PRINT "SPACE",10,20

  // Draw the scale virtual screen on the actual screen
  scale_screen()
 
  // Draw original screen sprite, so you can see the scaling
  DRAWSPRITE 999,0,0
 
  SHOWSCREEN
 
WEND



// Scale virtual screen scene
FUNCTION scale_screen:

USESCREEN -1

SMOOTHSHADING FALSE

// Render whole scene in scaled screen
STARTPOLY 999
  POLYVECTOR 64*scale,0,64,0
  POLYVECTOR 0,0,0,0
  POLYVECTOR 0,64*scale,0,64
  POLYVECTOR 64*scale,64*scale,64,64
ENDPOLY

ENDFUNCTION


Hope that helps make it a bit clearer.


[EDIT] Or you can use the PRESCALER function from the latest versions of GLB. Call it at the start of the code and then just draw everything as normal. Supposedly. I've not used it and I don't know what impact it has on gamespeed. USESCREEN can also affect FPS, so be forewarned.
Title: Re: Little autoscaling system with a virtual Image (suitable for Android).
Post by: erico on 2016-Apr-23
Thanks Ian, that is what I´m doing, but I have fixed android resolution detection, while this more advanced version SF did can handle infinite android resolutions+calculate the touch zone. I understand the concept as you said but not the math in SF´s code and so I can´t fix it. :S
I was wondering if this function was tested before and the errors are on my side only.

Title: Re: Little autoscaling system with a virtual Image (suitable for Android).
Post by: Ian Price on 2016-Apr-23
It's easy to set up autoscaling based on resolution and finding the touchscreen positions. Simply divide the actual resolution (x and y) by the required resolution eg - if the actual X resolution is 1020 and your screen is set up for 320: 1020/320=3.19 so every pixel the mouse moves to cover a 320 res screen should move 3.19 pixels on the larger res screen. Use something like this -

Code (glbasic) Select

LOCAL mx%, my%, b1%, b2%
LOCAL  cx#, cy#

MOUSESTATE mx, my, b1, b2

cx=mx*3.19


Obviously you can automate the actual value too

Code (glbasic) Select

GLOBAL w%, h%
GLOBAL screen_x=%320; screen_y%=240
GLOBAL res_x#, res_y#

GLOBAL mx%, my%, b1%, b2%, cx%,cy%

GETDESKTOPSIZE w,h

res_x=w/screen_x
res_y=h/screen_y


WHILE TRUE

MOUSESTATE mx, my, b1, b2

cx=mx*res_x
cy=my*res_y

SHOWSCREEN

WEND



Or something along those lines (BTW not tested in GLB).

This should give you a fairly accurate mouseposition on the screen.

Title: Re: Little autoscaling system with a virtual Image (suitable for Android).
Post by: erico on 2016-Apr-23
That is what SF´s function is supposed to do. Strange is that I just tested it alone and it works.
So it is probably that I screwed something while adding it to the game.

I will try again.

If I can´t make it happen, then I will have to write one and I will follow your tips
Title: Re: Little autoscaling system with a virtual Image (suitable for Android).
Post by: erico on 2016-Apr-23
Fixed.

It was a couple variables that got declared on the wrong order on my code, now it is all fine, works like a charm.
I´d just have to cut off the broken resolutions now.

Really great code.