This is a "system" I am using to support any screen size.
First we got iPhone 3G, that just had 320x480. When 4G comes, it was easy, 640x960, with auto upscale 2x by iOS himself for old 3G games; for us was easy too: retina display was just x2. Then it comes iPad, 768x1024. Damm. It even has not the same screen aspect ratio.
Later was the Pre2. Ok, it is also 320x480, same as 3G; nothing to do here. But we noticed other WebOS devices had different screen sizes. But hey!, they were not a huge market to worry!; also, the TouchPad had 768x1024, same as iOS (intelligents this guys at HP, eh?).
And then, Android did come. And it was a nightmare. Any resolution can be out there. And to make things even worse, Google Android do not talk in any place about the screen sizes in pixels! They call it small, large, extra large,... even pixel density (what the hell was this on a mobile?).
And not to talk about aspect ratios... 320x480, 800x480, 854x480, 1280x800. Are they doing this just to disturb us?
With so many different screen sizes and aspect ratios, relative screen coordinates (to screen sizes and aspect ratio) has to be used, with an overcomplicated programming (any X coordinate has to be done as (x*xzoomsize)+aspect ratio... or if you want to print on top right corner, you have to substract coordinates... a shame.
So I got a solution. Perhaps it is not the best, and don't know if the fastest, but it works, and great!
First, create a virtual screen 1024x640 pixels. It has 16:10 aspect ratio (as many PC monitors out there) and it has also the highest texture size for many devices.
Type this at the start of your programs.
createscreen 1,100,1024,640
usescreen 1
Write all your graphics to this screen, and instead calling showscreen, just call my function sc()
FUNCTION sc:
LOCAL x,y,xz,yz,zoom,xres,yres
VIEWPORT 0,0,0,0
USESCREEN -1
GETSCREENSIZE xres,yres
xz=xres/1024;yz=yres/640
zoom=MIN(xz,yz)
INC alfa,dalfa //alfa is the current alphamode for your screen
IF alfa>-0.01 //dalfa is the speed of fade in/out
alfa=-0.01;dalfa=0
ENDIF
IF alfa<-1
alfa=-1;dalfa=0
ENDIF
ALPHAMODE alfa
deltax=(xres-(1024*zoom))/2 //perhaps you want to make global deltax, deltay and zoom at the ini of your program...
deltay=(yres-(640*zoom))/2 //and/or xres, yres
// STRETCHSPRITE 100,deltax,deltay,1024*zoom,640*zoom //this is the same without polysprites
STARTPOLY 100,0
POLYVECTOR deltax,deltay,0,0,RGB(255,255,255)
POLYVECTOR deltax,deltay+(640*zoom),0,640,RGB(255,255,255)
POLYVECTOR deltax+(1024*zoom),deltay+(640*zoom),1024,640,RGB(255,255,255)
POLYVECTOR deltax+(1024*zoom),deltay,1024,0,RGB(255,255,255)
ENDPOLY
IF MOUSEAXIS(4)=1 THEN ShowZones() // press right to see zones, if you are using zones()
IF KEY(31) //press S to save a screenshot
SAVEBMP RND(9999)+".png"
MOUSEWAIT //to avoid saving multiple savings with just 1 keypress
ENDIF
SHOWSCREEN
VIEWPORT 0,0,0,0
ALPHAMODE -1
USESCREEN 1
SETTRANSPARENCY RGB(0,0,0)
DRAWRECT 0,0,1024,640,RGB(0,0,0) // will draw black colour _AND_ transparent alpha
SETTRANSPARENCY RGB(255,128,0)
VIEWPORT 0,0,0,0
ENDFUNCTION
The sc() functions read the device real screen size and scales and center your virtual screen.
It doesnt matter anymore the screen size, ratio or density (!) of target device. It fits like a suit.
(although it is created for landscape portraits, it can be easily adapted to portrait ones)
To see it in action, just download the demo here:
http://www.glbasic.com/forum/index.php?topic=6905.0 (http://www.glbasic.com/forum/index.php?topic=6905.0)
(the example code is the same as for the imput$() function)
I was doing this a while back by blitting everything to one screen and then re-blitting it as a polyvector stretched to the real screen resolution. Indeed it does work well. You still need to re-calculate mouse touch areas though :)
No, I don't. All my touch areas are defined using ZONES lib, and they are also scaled by the createzone() function himself.
:P
I do this all the time for my unfinished code rejects, erm, demos...
Draw everything to a virtual screen and then that screen stretched to main screen. Even on PC.
For example on PC, this gives you a nice option to scale/rotate game screen as you see fit. Or even to have multiple game screens at once!
¡Fantástico!, estás que te sales. Ya me explicarás eso de librerias de zona (traducción literal) para la pantalla táctil. :nw:
A question, is it possible to define a virtual screen with CREATESCREEN larger than resolution of the device?
Thank you
Technically yes, although the device itself may not allow it (due to memory restrictions for example).
Quote from: msx on 2011-Sep-29
A question, is it possible to define a virtual screen with CREATESCREEN larger than resolution of the device?
Thank you
Yes; in fact it is what I am doing, a 1024x640 screen for a 480x320 device.
Perhaps, as MrTAToad says, some devices could not like it. WebOS likes it, not yet tested on 3G. My cutre-tablet chinorro 800x480 like it also.
Thanks, I have a problem resizing the screen but I can only test it on Windows because I have only an iPhone 3GS and a Palm Pre 2 and both have the same screen resolution. The problem occurs for lower screen resolutions of 320x480 but not for higher resolutions.
Could anyone test it on a Palm Pixi?
I've got a Pixi, what exactly would you like testing? If it's the scaling code above (not tested, but experience tells), you're probably better off forgetting it. The Pixi is really quite/very slow and scaling takes a large hit on the CPU. If you want to target the Pixi, then you need to code for it specifically. You really shouldn't try to force high end stuff down to its level. It's a nice device, but it's not really geared up to anything with lots of drawing or real-time effects.
Hi Ian, the application that I want to try not consume many resources because it has no real-time effects and great graphics. what I want is not well functioning in Pixi, but it works in any screen resolution correctly. The code is mine and I can not prove in a different resolution of 320x480.
If I send you the apk file, could you install it on your Palm Pixi?.
Thank you.
This is a nice idea when you are scaling to screens with the same ratios 4:3 for example, but otherwise you end up with images that are distorted; this does not look good and is noticed by end users. I code for everything relativistically rather than with absolute coordinates as much as possible, but I use separate image sets for each separate device resolution
Quote from: msx on 2011-Sep-29
Hi Ian, the application that I want to try not consume many resources because it has no real-time effects and great graphics. what I want is not well functioning in Pixi, but it works in any screen resolution correctly. The code is mine and I can not prove in a different resolution of 320x480.
If I send you the apk file, could you install it on your Palm Pixi?.
Thank you.
Yep, no problems. Email it to mrijprice gmail com (with AT and DOT)
Quote from: bigtunacan on 2011-Sep-29
This is a nice idea when you are scaling to screens with the same ratios 4:3 for example, but otherwise you end up with images that are distorted; this does not look good and is noticed by end users. I code for everything relativistically rather than with absolute coordinates as much as possible, but I use separate image sets for each separate device resolution
My routine scales with aspect ratio, so they are not distorted. It will scale up/down to fit in the screen and centers it.
Of course, some proyects will fit this system and others will not.
My App "The Last Angel" was programmed with relative coordinates and screen orientation.
In fact, I did a function to convert any coordinate relative to any corner relative position (print "test",-10,0 will print with text finishing at screen xres-10) and taking into account the screen orientation (that was before screenrotate by Gernot), and so, just look in the code snippets section, and when GLB was only iOS, and it just worked for Android and WebOS resolutions without changes.
Also my very first app (non-finished) was programmed with aspect ratio and screen sizes in mind and worked fine in my android device resolution easily.
But if your app can use the "universal screen size" function, it is a hell easier to code.
screen size on Android can been very hell, but its really not more speciel programmering for the pc really.
Also offbuffer is not very effective as well and you would lost very much of bandwidth/fillrate, so its is not or might been useable for some devices, where you can notice the framerate can fall by two, which was happens on the Sony Experia Play. I did optimize the update() (the function I use for game logic), so its do run smooth on that device.
So for best performents, you should do the awfull way doing scaling directly, or you can call it to a more advanced DRAW function, that so can do all scaling before its draw.
This was that I was need to do in my game.... For some games offbuffer do can work of course. Its depend on the game.
Hello,
I'm newbie regarding coding for the mobile platform and I have a few doubts, so I hope someone can help me. I post here because resolutions and orientation between different hardware is my main doubt.
The scenario is a game coded for desktop with a resolution normal resolution. Let's say 800x600.
- What happen if I pick a resolution like 480 x 320 (iPhone landscape mode) and the game is executed in iPad?! Is it automatically centered and gets a black border? Or is stretched? And what about android (and the other supported platforms)?
- Is it a best practice to code with fixed minimum resolution and stretch the screen for higher resolutions (or center the game) or should we code relative x,y, so we can use the getdesktopsize and use it? What is your experience?
- Can we force a user to play the game in landscape mode in hardware that supports it?
Sorry for all the questions but as I don't have any mobile hardware is difficult to get the picture :)
Thanks in advance,
António
On iOS if you make your game 480x320 it will be scaled by the iOS himself (with black borders on iPad). I think it is the same on WebOS TouchPad.
On Android, the game will be drawn at coordinate 0,0 of the screen, so you get a (little) screen game in a corner of the device; I have no way to scaleup by the os as iOS do.
You can force to play in any orientation. The target device will open the orientation as you set in GLB projects settings.
About how to design your game... thats the matter.
Perhaps you want to do it in the lowest resolution, but on devices with larger screens your game will look pixelated.
Another solution is the one by ... where you have your graphics on the highest resolution and they are scaled by his function; so you end with all your graphics resized to your current device resolution.
And another one is to draw all the game into a virtual screen and resize it to fill your target. This solution is the easiest one, but also has the highest performance drop. If you want a high fps game perhaps this is not your solution.
You could also choice to use 2 set of texture:
One small and one double up texture (example one 1024x1024 and one 2048x2048 for the tile texture).
The game logic is the same, but all graphics might draw with x2, in that way the game would not look blocky on iPad (example).
Also remember to support both way for landscape mode (can been checked really easy), elsewise Apple reject it (as least for iPad).
and yes Ambos is the easist one, just been aware framerate can been dropped for extreme much graphics, but it depend of design of course.
Quote from: ampos on 2011-Sep-29
where you have your graphics on the highest resolution and they are scaled by his function; so you end with all your graphics resized to your current device resolution.
You mean if the resolution on iOS or Android is higher than the current desktop resolution the SO automatically resize the screen?
So, if I understand correctly, the logical approach is to get the current desktop size with GETSCREENSIZE and code all the positions relatively instead of absolute? Of course that for this solution we should use "separate images sets for each separate device resolution" :)
Thank you,
António
Android can also rescale automatic too, if you not doing high resoulution. But its might been blocky of course.
its depend the game of course.
My game is example a tiled based puzzle game, and its use tree different of tile textures: 1024x1024, 2048x2048 and 4096x4096. The game pick that one that is closes to the real resolution and downscale the last bit of it. Only onscreen button icons, fonts etc do I use one size texture, because its not need to rescale them, or upscaling here is not a problem really. So its some kind of balance, what is need for the game. This is what I do.
With the above trick in mind, you could also do 2 sizes of offbuffer screen (example do a either 480x320 or 960x640 offbuffer), but gameplay game logic still use one of them (the graphics can either downscaling or upscalering, but users dont detect the game logic internal only use one resoulution)....
There is no reason to use higher texture if it not need to that
Quote from: ampos on 2011-Sep-19
http://www.glbasic.com/forum/index.php?action=dlattach;topic=6905.0;attach=3860 (http://www.glbasic.com/forum/index.php?action=dlattach;topic=6905.0;attach=3860)
Where is your sc() function? And this link is broken
Look now at the first post...
Quote from: ampos on 2011-Sep-19
No, I don't. All my touch areas are defined using ZONES lib, and they are also scaled by the createzone() function himself.
Hi Ampos I've started using your Zones Lib and find it very handy, thank you :) One thing that I noticed was the zones rescale according to a proportional screen. If my screen scaling is proportional and I retain the aspect ratio the zones are perfect. However I wanted to include an option in my menu to have Aspect Ratio On/Off (ugly as it may look sometimes) but in the CreateZone function I can't fathom out how to get it correct.
FUNCTION GE_CreateZone: ZoneNum, Xcoord, Ycoord, Width, Height
LOCAL m,r,x1,x2,y1,y2,x,y,xz,yz,z,xd,yd
x1=MIN(Xcoord,Xcoord+Width)
x2=MAX(Xcoord,Xcoord+Width)
y1=MIN(Ycoord,Ycoord+Height)
y2=MAX(Ycoord,Ycoord+Height)
r=GE_ZoneProperty(ZoneNum,6)
IF r=-1
m=BOUNDS(zones[],0)
REDIM zones[m+1]
ELSE
m=r
ENDIF
xz = GE_TargetScrX%/vscreenx ; yz = GE_TargetScrY%/vscreeny
z = MIN(xz,yz)
IF xz > yz
xd = (GE_TargetScrX%-(vscreenx*z))/2
yd = 0
ELSE
xd = 0
yd = (GE_TargetScrY%-(vscreeny*z))/2
ENDIF
zones[m].x=(x1*z)+xd
zones[m].y=(y1*z)+yd
zones[m].w=(x2-x1)*z
zones[m].h=(y2-y1)*z
zones[m].n=ZoneNum
ENDFUNCTION
I've added the "IF xz > yz" part as changes only need to be made in one axis dependent on portrait or landscape but I can't get my head around how to correctly calculate the .x start and .w in my (portrait) game. How can I make the routine not be aspect ratio correct??
Thanks in advance :doubt:
Just an FYI to everyone, I *love* this technique and implemented it in my game, but for whatever reason even though it may work on many devices, it didn't work on my ASUS eeePad Transformer tablet running android honeycomb 3.2. Nothing drawn onto a virtual screen that used CREATESCREEN would later render, meaning using this technique you only get a black screen. So far I haven't decided on what other approach would work on that device.. (although apparently stretchsprite worked on that one device)
So yeah.. frustrating ;/
It should be something similar to this (pseudocode)
xz=targetscrx/vscreenx; yz=targetscry/vscreeny
zone.x=x1*xz
zone.y=y1*yz
zone.w=(x2-x1)*xz
zone.h=(y2-y1)*yz
If the screen does not maintain ratio, all x,y,w,h coordinates/sizes are just multiplied by the zoom, no "delta x" (xd as I call it) are used.
Quote from: ampos on 2011-Oct-17
If the screen does not maintain ratio, all x,y,w,h coordinates/sizes are just multiplied by the zoom, no "delta x" (xd as I call it) are used.
Cheers Ampos, will experiment later ;)