Codesnippets > Code Snippets
Z Project - universal screen size scaling system
ampos:
Yes, it is (again) a UNIVERSAL SCREEN SIZE SCALING SYSTEM :S
I had the idea to port ALL gfx commands to use polyvectors and be resolution independents, so we can code to just 1 resolution and will work at all platforms, using the (almost) fastest polyvector system, targetting any target resolution with/without aspect ratio.
To start, I have made the initialization function and ported the very first function, DRAWSPRITE. If one of each us made 1 function, it could be done real soon. I will copy your functions to this first post to keep it updated. Please, post the function you are going to do before so no one else does the same.
HOW-TO USE
In your proyect, you only need to change the CONSTANTS x_orig and y_orig with the values of the screen size you are coding for (the size that will draw at size 1:1).
Call the "z_init" function at the start of your program. If you dont want it to keep the aspect ratio of your graphics, call it with value=0
That's all, just call the functions as if they were original GLBasic commands, same syntax. (Note that I added the "color" param to the function as optional; as it is going to be used by polyvector anyway, just put it!)
You call the functions with "absolute" values, as if they were for a fixed screen size. The commands themself will scale your graphics to the device resolution, leaving black borders for unused screen.
In many console games (I recall some Wii examples) they draw a background that fills the entire screen and the game is drawn really in a center 4:3 "window" in the center of the screen. An iPAD (1024x768) resolution game will look similar in a 800x480 android device. If you do not want the screen to be filled with black borders, just do this:
--- Code: (glbasic) ---CLEARSCREEN -1 //if the entire screen is going to be redrawn, do not clear it before!
...your game here
SC() //use this instead of showscreen
function SC: //this routine will fill your entire screen with a nice background
showscreen
stretchsprite background,0,0,x_res,y_res
endfunction
--- End code ---
Example:
x_orig=1024;z_drawsprite id,512,0 will be always drawn at the center of the screen, even at a 320x240 screen resolution.
--- Code: (glbasic) ---// --------------------------------- //
// Project: ProjectoZ
// Start: Tuesday, October 25, 2011
// IDE Version: 10.118
GLOBAL x_offset,y_offset //offset to add to X&Y to display correctly
GLOBAL x_res,y_res //X&Y real screen size
GLOBAL x_zoom,y_zoom //zoom to scale sprites and so
GLOBAL x_orig=768,y_orig=1024 //the screen size our app is designed for
GLOBAL single_sheet=0 //1 IF all sprites in a single sheet
FUNCTION initZ: keep_ratio=0
LOCAL z
GETSCREENSIZE x_res,y_res
x_zoom=x_res/x_orig
y_zoom=y_res/y_orig
IF keep_ratio<>0
z=MIN(x_zoom,y_zoom)
x_zoom=z
y_zoom=z
x_offset=(x_res-(x_orig*x_zoom))/2
y_offset=(y_res-(y_orig*y_zoom))/2
IF x_offset<1 THEN x_offset=0
IF y_offset<1 THEN y_offset=0
ENDIF
init_SC()
ENDFUNCTION
FUNCTION z_drawsprite: num%,x%,y%,color=0xFFFFFF
LOCAL sx,sy,x1,y1,x2,y2
GETSPRITESIZE num,sx,sy
x1=x_offset+(x*x_zoom)
x2=sx*x_zoom
y1=y_offset+(y*y_zoom)
y2=sy*y_zoom
// STRETCHSPRITE num,x1,y1,x2,y2
STARTPOLY num
POLYVECTOR x1,y1,0,0,color
POLYVECTOR x1,y1+y2,0,sy,color
POLYVECTOR x1+x2,y1+y2,sx,sy,color
POLYVECTOR x1+x2,y1,sx,0,color
ENDPOLY
ENDFUNCTION
FUNCTION z_drawanim: num%,frame%,x%,y%,w%,h%,color=0xFFFFFF
LOCAL sx,sy,x1,y1,x2,y2,ancho,alto,xa,ya
GETSPRITESIZE num,sx,sy
x1=x_offset+(x*x_zoom)
x2=w*x_zoom
y1=y_offset+(y*y_zoom)
y2=h*y_zoom
ancho=sx/w;alto=sy/h
ya=INTEGER(frame/ancho)*h
xa=MOD(frame,ancho)*w
// STRETCHANIM num,frame,x1,y1,x2,y2
IF single_sheet=0 THEN STARTPOLY num
POLYVECTOR x1,y1,xa,ya,color //TL
POLYVECTOR x1,y1+y2,xa,ya+h,color //BL
POLYVECTOR x1+x2,y1+y2,xa+w,ya+h,color //
POLYVECTOR x1+x2,y1,xa+w,ya,color
IF single_sheet=0
ENDPOLY
ELSE
POLYNEWSTRIP
ENDIF
ENDFUNCTION
FUNCTION z_rotozoomanim: num%,frame%,x%,y%,w%,h%,ang,size,color=0xFFFFFF
LOCAL sx,sy,x1,y1,x2,y2,ancho,alto,xa,ya,x3,x4,y3,y4,xcos,ysin,xs,ys,sw,sh
GETSPRITESIZE num,sx,sy
sw=w;sh=h
x=x_offset+(x*x_zoom)-(((w*size)-w)/2)
w=w*x_zoom*size
y=y_offset+(y*y_zoom)-(((h*size)-h)/2)
h=h*y_zoom*size
INC x2,x1;INC y2,y1
ancho=sx/sw;alto=sy/sh
ya=INTEGER(frame/ancho)*sh
xa=MOD(frame,ancho)*sw
h=h/2
w=w/2
INC x,w
INC y,h
x1 = x
y1 = y
x2 = x
y2 = (y + h)
x3 = (x + w)
y3 = y
x4 = (x + w)
y4 = (y + h)
xcos = tCOS(ang)
ysin = tSIN(ang)
x1 = x - (xcos * w) - (ysin * h)
y1 = y - (xcos * h) + (ysin * w)
x2 = x - (xcos * w) + (ysin * h)
y2 = y + (xcos * h) + (ysin * w)
x3 = x + (xcos * w) - (ysin * h)
y3 = y - (xcos * h) - (ysin * w)
x4 = x + (xcos * w) + (ysin * h)
y4 = y + (xcos * h) - (ysin * w)
SELECT single_sheet
CASE 0
STARTPOLY num
POLYVECTOR x1, y1, xa, ya,color //TL
POLYVECTOR x2, y2, xa, ya + sh,color //BL
POLYVECTOR x4, y4, xa + sw, ya + sh,color //BR
POLYVECTOR x3, y3, xa + sw, ya,color //TR
ENDPOLY
CASE 1
POLYVECTOR x2, y2, xa, ya + sh,color //BL
POLYVECTOR x1, y1, xa, ya,color //TL
POLYVECTOR x4, y4, xa + sw, ya + sh,color //BR
POLYVECTOR x3, y3, xa + sw, ya,color //TR
POLYNEWSTRIP
ENDSELECT
ENDFUNCTION
FUNCTION z_print: t$,x,y,font=100,centered=1,zoom=1,color=0xFFFFFF,underline=0,italic=0
LOCAL fx,fy,l,c$,tx,ty,dx,dy,fxz,fyz,t1,t2,t3,t4,tl
LOCAL line_width=2 //width of the underline line in pixels at zoom 1 (100%)
LOCAL outline=2 //width of the outline in underline in pixels at zoom 1 (100%)
LOCAL und_pos=.9 //vertical position of underline (in % of Font Y size)
LOCAL ital_ang=.5 //inclination of font (in % of font X size)
GETSPRITESIZE font,fx,fy
fx=fx/16;fy=fy/16 //change to fy/8 if you dont use full charset fonts
fxz=fx*zoom*x_zoom;fyz=fy*zoom*y_zoom
tl=LEN(t$,1)*zoom*x_zoom
x=x_offset+(x*x_zoom)
y=y_offset+(y*y_zoom)
DEC x,(LEN(t$,1)*zoom*centered*x_zoom)/2
IF underline=1
t1=line_width*(zoom*y_zoom);IF t1<1 THEN t1=1
t2=fxz/4
t3=fyz*und_pos
t4=outline*(zoom*x_zoom);IF t4<1 THEN t4=1
STARTPOLY //this can be changed with a call to z_drawline...
POLYVECTOR x-t2-t4,y+t3-t4,0,0,0
POLYVECTOR x-t2-t4,y+t3+t1+t4,0,0,0
POLYVECTOR x+t2+tl+t4,y+t3+t1+t4,0,0,0
POLYVECTOR x+t2+tl+t4,y+t3-t4,0,0,0
ENDPOLY
STARTPOLY
POLYVECTOR x-t2,y+t3,0,0,color
POLYVECTOR x-t2,y+t3+t1,0,0,color
POLYVECTOR x+t2+tl,y+t3+t1,0,0,color
POLYVECTOR x+t2+tl,y+t3,0,0,color
ENDPOLY
ENDIF
italic=italic*zoom*fx*ital_ang*x_zoom
STARTPOLY font,2
FOR n=0 TO LEN(t$)-1
c$=MID$(t$,n,1)
l=ASC(c$)
ty=ASR(l,4)
tx=INTEGER(MOD(l,ty*16))
dx=tx*fx
dy=ty*fy
POLYVECTOR x,y+fyz,dx,dy+fy,color //BL
POLYVECTOR x+italic,y,dx,dy+1,color //TL
POLYVECTOR x+fxz,y+fyz,dx+fx,dy+fy,color //BR
POLYVECTOR x+fxz+italic,y,dx+fx,dy+1,color //TR
POLYNEWSTRIP
INC x,LEN(c$,1)*zoom*x_zoom
NEXT
ENDPOLY
ENDFUNCTION
FUNCTION z_drawline: x1,y1,x2,y2,color=0xFFFFFF,width=1
LOCAL w=(x2-x1)*x_zoom
LOCAL h=(y2-y1)*y_zoom
x1=x_offset+(x1*x_zoom)
y1=y_offset+(y1*y_zoom)
x2=x_offset+(x2*x_zoom)
y2=y_offset+(y2*y_zoom)
width=width*x_zoom
glLineWidth (width)
DRAWLINE x1,y1,x2,y2,color
glLineWidth(1)
// STARTPOLY
// POLYVECTOR x1,y1,0,0,color
// POLYVECTOR x1+w,y1+h,0,0,color
// POLYVECTOR x1+w+1,y1+1+h,0,0,color
// POLYVECTOR x1+1,y1+1,0,0,color
// ENDPOLY
ENDFUNCTION
FUNCTION z_drawrect: x,y,w,h,color=0xFFFFFF
x=x_offset+(x*x_zoom)
y=y_offset+(y*y_zoom)
w=w*x_zoom
h=h*y_zoom
STARTPOLY
POLYVECTOR x,y,0,0,color
POLYVECTOR x,y+h,0,0,color
POLYVECTOR x+w,y+h,0,0,color
POLYVECTOR x+w,y,0,0,color
ENDPOLY
ENDFUNCTION
INLINE
#define OGL ::
typedef float GLfloat;
ENDINLINE
INLINE
} extern "C" { void __stdcall glLineWidth( GLfloat width );; }; namespace __GLBASIC__ {
ENDINLINE
FUNCTION glLineWidth: width
INLINE
OGL glLineWidth(width);
ENDINLINE
ENDFUNCTION
INLINE
} // + + + A T T E N T I O N + + +
// int __a__ needs to be a n^2 value.
// Higher values give better precision
// but larger lookup tables as well!
const unsigned int __a__ = 131072 ;
const DGInt __b__ = (360.0 / __a__) ;
const unsigned int __c__ = (__a__ - 1) ;
DGInt _sin_tbl_[__c__] ;
DGInt _cos_tbl_[__c__] ;
const DGInt __d__ = (1 / __b__);
namespace __GLBASIC__ {
ENDINLINE
FUNCTION init_SC:
INLINE
for(int i=0; i < __c__; ++i)
{
_sin_tbl_[i] = SIN( i * __b__ ) ;
_cos_tbl_[i] = COS( i * __b__ ) ;
}
ENDINLINE
ENDFUNCTION // INIT_SIN_COS_TABLES
// ------------------------------------------------------------- //
// --- TCOS ---
// ------------------------------------------------------------- //
FUNCTION tCOS: x // in degrees
INLINE
return _cos_tbl_[ (int)(x * __d__) & __c__ ] ;
ENDINLINE
ENDFUNCTION // TCOS
// ------------------------------------------------------------- //
// --- TSIN ---
// ------------------------------------------------------------- //
FUNCTION tSIN: x // in degrees
INLINE
return _sin_tbl_[ (int)(x * __d__) & __c__ ] ;
ENDINLINE
ENDFUNCTION // TSIN
--- End code ---
HOW TO MAKE FUNCTIONS
I think that the z_drawsprite function is easy enough to understand, but to clarify how to calculate target resolutions
Initial X & Y coordinates are calculated with
--- Code: (glbasic) --- x1=x_offset+(x*x_zoom)
y1=y_offset+(y*y_zoom)
--- End code ---
You have to use, mandatory, x_offset & y_offset, as the init function will set this values correctly if the user wants or not "aspect ratio lock"
The target sprite sizes are easily calculated too with
--- Code: (glbasic) --- x2=sx*x_zoom
y2=sy*y_zoom
--- End code ---
being sx and sy, current sprite size.
0.01 - Initial release
- DRAWSPRITE
0.02 - PRINT (with attributes)
0.03 - DRAWLINE
DRAWRECT
Added a "+1" on z_print text print part to fix gfx glitches
0.04 - DRAWANIM (it needs in the function the size of the anim frame)
ROTOZOOMANIM (it needs in the function the size of the anim frame
Uses tCOS and tSIN for faster SIN/COS
Updated PRINT to use POLYNEWSTRIP
The variable SINGLESHEET can be used to use POLYNEWSTRIP when drawing multiple sprites from a single sheet.
The DRAWLINE command has the option WIDTH, through OpenGL itself.
0.05- Minor update. Removed some old lines. Add more explanations for use.
0.06- RotoZoomAnim had a bug
Wampus:
Good stuff. Can be used as a basis for scalable control schemes too.
ampos:
Added Z_PRINT.
Nobody wants to contribute?
ampos:
I have added more things:
DRAWANIM, that needs also the size of the sprite animation frame.
ROTOZOOMANIM, also need the frame size. It uses also tCOS and tSIN functions for speed.
The DRAWLINE get a WIDTH option, that is set using OpenGL.
PRINT uses POLYNEWSTRIP, making it much more faster.
Some functions read the global variable SINGLESHEET. If =1, they will use POLYNEWSTRIP, making it MUCH faster if you are drawing multiple sprites from the same sprite sheet.
Example:
You have a sheet with multiple flowers pictrures. You normally will use this to draw:
--- Code: (glbasic) ---FOREACH f IN flowers()
Z_DRAWSPRITE f.id,f.x,f.y
NEXT
SHOWSCREEN
--- End code ---
That will be
--- Code: (glbasic) ---FOREACH f IN flowers()
Z_DRAWANIM f.id,f.frame,f.x,f.y
{STARTPOLY f.id
...blah...blah POLYVECTOR
ENDPOLY}
NEXT
SHOWSCREEN
--- End code ---
Ok, the SINGLESHEET has to be done this way:
--- Code: (glbasic) ---SINGLESHEET=1
STARTPOLY id,2
FOREACH f IN flowers()
Z_DRAWSPRITE f.id,f.x,f.y
NEXT
ENDPOLY
SHOWSCREEN
--- End code ---
Will translate into:
--- Code: (glbasic) ---SINGLESHEET=1
STARTPOLY id,2
FOREACH f IN flowers()
Z_DRAWSPRITE f.id,f.x,f.y
{blah, blah... POLYVECTOR
NEWPOLYSTRIP}
NEXT
ENDPOLY
SHOWSCREEN
--- End code ---
Probably I will not create DRAWANIM or ROTOSPRITE as it can be used easily in ROTOZOOMANIM with frame=0
bigsofty:
Congrats and thanks Ampos, great stuff! :good:
Navigation
[0] Message Index
[#] Next page
Go to full version