Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Topics - Dark Schneider

#21
The problem is that in the XCode project the Debug config points to a Missing SDK if using some new XCode, surely because it points to 3.x version, while the Release config points to the Lastest one. It is easy to fix only changing by hand the config (Targets->iPhone->properties->Build, at the beginning). But if this could be fixed when GLBASIC generates the XCode project file, then better.
#22
I am sure this can be useful to many, it is typical in pro games to disable the iPhone autolock while you are playing, if not you are required to touch the screen, and it can affect how your app is used (forced touchs).

For use it, simply add the iOSAuxFunc.gbas to your GLBASIC project, and the iOSAuxFunc.m to your XCode project, for example to the Other Sources folder.

Included in the iOSAuxFunc is the EnableAutoLock() function, pass FALSE to disable it and TRUE to enable it again. There is no need to call EnableAutoLock(TRUE) on exit because the iOS devices do it by its own. The typical use is:

- Do not call at beginning.
- Call EnableAutoLock(FALSE) at start of GAMEPLAY.
- If paused, call EnableAutoLock(TRUE). When return to game call EnableAutoLock(FALSE).
- When gameplay ends (return to main menu, etc.), call EnableAutoLock(TRUE).

As summary, set AutoLock = OFF ( EnableAutoLock(FALSE) ) ONLY while playing, is the way iPhone games does it mainly.

[attachment deleted by admin]
#23
Sometimes using FOREACH with a TYPE generates this error, i.e. I have this code:
Code (glbasic) Select

FOREACH bonus_item IN stage.bonus_items[]
NEXT

This generates an error TYPE is not declared, but if I change it to:
Code (glbasic) Select

FOR i%=0 TO LEN(stage.bonus_items[])-1
NEXT

exactly in the same place of code, it works fine.

I think the problem is accessing other TYPEs members using FOREACH, but in GLBASIC v8 this worked fine. I mark the "others" because using within a type with something like:
Code (glbasic) Select

FOREACH bonus IN self.bonus_items[]
NEXT

works fine too.
#24
Math / Vector 2D
2011-Jan-18
Typical case of 2D-Vector, very usefull for sprites and other 2D things:

Code (glbasic) Select

// --------------------------------- //
// TYPE TVector2
// --------------------------------- //

CONSTANT TVector2VersionMajor%=1, TVector2VersionMinor%=1, TVector2VersionBuild%=0, TVector2VersionRevision%=2

//! TVector2
//!
//! Author: Dark Schneider
//!
//! Two-dimensional vector


//---------------------//
// --- DEFINITIONS --- //
//---------------------//


//---------------//
// --- TYPES --- //
//---------------//
//! TVector2 types

//! Type TVector2
//! Main type
TYPE TVector2

//---------------//
// - VARIABLES - //
//---------------//
x#=0
y#=0


//---------------//
// - FUNCTIONS - //
//---------------//
//! TVector2 functions

//! Set type data
//\param x# - coordinate X
//\param y# - coordinate Y
//\return Itself with new values
FUNCTION Set AS TVector2: x#=0, y#=0
self.x=x; self.y=y
RETURN self
ENDFUNCTION


//\return Length squared of vector
FUNCTION LengthSq:
RETURN self.x*self.x+self.y*self.y
ENDFUNCTION


//\return Length of vector
FUNCTION Length:
RETURN SQR(self.x*self.x+self.y*self.y)
ENDFUNCTION


//\param v - vector for dot product
//\return Dot product of itself with v
FUNCTION DotProduct: v AS TVector2
RETURN self.x*v.x+self.y*v.y
ENDFUNCTION


//\param scale# - scale factor
//\return Itself scaled
FUNCTION Scale AS TVector2: scale#
self.x=self.x*scale#
self.y=self.y*scale#
RETURN self
ENDFUNCTION


//\return Itself normalized
FUNCTION Normalize AS TVector2:
LOCAL l#=self.Length()
IF l < 0.0000001
self.Set(0,0)
ELSE
self.Scale(1.0/l)
ENDIF
RETURN self
ENDFUNCTION


//\return Itself with inverse values: x=-x; y=-y
FUNCTION Invert AS TVector2:
self.x=-self.x
self.y=-self.y
RETURN self
ENDFUNCTION


//\return New vector with inverse values: x=-x; y=-y
FUNCTION Inverse AS TVector2:
LOCAL l_result AS TVector2
l_result=self
l_result.Invert()
RETURN l_result
ENDFUNCTION


//\param v - vector to add
//\return Itself modified
FUNCTION Add AS TVector2: v AS TVector2
self.x=self.x+v.x
self.y=self.y+v.y
RETURN self
ENDFUNCTION


//\param v - vector to substract
//\return Itself modified
FUNCTION Substract AS TVector2: v AS TVector2
self.x=self.x-v.x
self.y=self.y-v.y
RETURN self
ENDFUNCTION


//! Compute angle between the vector and another one
//\param v - vector against to compute angle
//\return Angle from itself to v, values in the range [0-180[
FUNCTION AngleWith: v AS TVector2
LOCAL div#, dot#
div = self.Length() * v.Length()
IF div = 0 THEN RETURN 0
dot = self.DotProduct(v) / div
IF ABS(dot) > 1 THEN RETURN 0 // 1.5/1.49999
RETURN ACOS(dot)
ENDFUNCTION


//\return Angle of the vector using X axis as angle=0
FUNCTION ToAngle:
LOCAL l_result#=0
IF self.x<>0 AND self.y<>0
l_result=ATAN(self.y,self.x)
IF self.y<0 THEN l_result=360+l_result
ELSE
IF self.x=0
IF self.y>0
l_result=90
ELSEIF self.y<0
l_result=270
ENDIF
ELSEIF self.y=0 AND self.x<0
l_result=180
ENDIF
ENDIF
RETURN l_result
ENDFUNCTION


//! Modify the vector creating a normalized vector with direction defined by an angle
//\return Itself modified
FUNCTION FromAngle AS TVector2: angle#
self.x=COS(angle)
self.y=SIN(angle)
RETURN self
ENDFUNCTION

ENDTYPE



//-------------------//
// --- FUNCTIONS --- //
//-------------------//
//! Global functions

//! Create a new vector instance
//\param x# - coordinate X
//\param y# - coordinate Y
//\return The new vector instance
FUNCTION TVector2Create AS TVector2: x#=0, y#=0
LOCAL l_result AS TVector2
l_result.Set(x,y)
RETURN l_result
ENDFUNCTION


//! Add 2 vectors
//\param v1 - vector1
//\param v2 - vector2
//\return New vector v=v1+v2
FUNCTION TVector2Add AS TVector2: v1 AS TVector2, v2 AS TVector2
LOCAL l_result AS TVector2
l_result=v1
l_result.Add(v2)
RETURN l_result
ENDFUNCTION


//! Substract 2 vectors
//\param v1 - vector1
//\param v2 - vector2
//\return New vector v=v1-v2
FUNCTION TVector2Substract AS TVector2: v1 AS TVector2, v2 AS TVector2
LOCAL l_result AS TVector2
l_result=v1
l_result.Substract(v2)
RETURN l_result
ENDFUNCTION


//! Scale a vector
//\param v - vector to use as base for scale
//\scale# - scale factor
//\return New vector v*scale
FUNCTION TVector2Scale AS TVector2: v AS TVector2, scale#
LOCAL l_result AS TVector2
l_result=v
l_result.Scale(scale#)
RETURN l_result
ENDFUNCTION


//! Compute a normalized vector with direction defined by an angle
//\return New vector
FUNCTION TVector2FromAngle AS TVector2: angle#
LOCAL l_result AS TVector2
l_result.FromAngle(angle)
RETURN l_result
ENDFUNCTION


//! Computes the linear interpolation between 2 vectors
//\param v1 - vector1
//\param v2 - vector2
//\param interpolation# - interpolation value, [0.0-1.0]
//\return Vector with values of the interpolation
FUNCTION TVector2LinearInterpolation AS TVector2: v1 AS TVector2, v2 AS TVector2, interpolation#
LOCAL l_vresult AS TVector2
l_vresult.x=(1.0-interpolation)*v1.x+interpolation*v2.x
l_vresult.y=(1.0-interpolation)*v1.y+interpolation*v2.y
RETURN l_vresult
ENDFUNCTION
#25
If not set the %, is the FPU used in any way, affecting the performance or not?
example:
Code (glbasic) Select

FUNCTION MyFunc:
   LOCAL result%
   ...
   return result
endfunction


We return an integer but we have not set the % on the function, is the value changed to FP?.

What about if we return nothing?

On PC this is not noticeable, but this can be important on devices, where we have only a shared vector unit for FP computing and its power is very limited. Especially when we have function that are called many times per franme, like TYPES.Update()
#26
I have this error including if I compile a new empty project, it only fails when compiling for iPhone, many other targets (GP2X-WIZ, GP2X, Xbox-Linux) compiles with no error.

With an empty project, I have this:

Code (glbasic) Select

_______________________________________
*** Configuration: IPHONE ***
precompiling:
GPC - GLBasic Precompiler V.8.142 SN:74167187 - 3D, NET
Wordcount:0 commands
compiling:
arch:
/cygdrive/q/Compiler/platform/iPhone/bin/arm-apple-darwin9-libtool: object: gpc_tempg.o truncated or malformed object (offset field of section 2 in LC_SEGMENT command 0 extends past the end of the file)
*** FATAL ERROR - Please post this output in the forum
_______________________________________
*** Finished ***
Elapsed: 4.2 sec. Time: 13:16
Build: 0 succeeded.
*** 1 FAILED ***


I think my compiler is up to date, it doesn't detect any new version.

Any ideas?
#27
I think it is an interesting feature, but I don't know if there is currently a way to do this on GLBasic.
#28
Hello, I'd like to know about this, something like a fast tutorial. How it works exactly?.

In example, for a project in landscape mode, we set 1024x768, then at begin we do GETSCREENSIZE?. What coordinates report MOUSESTATE?, and for drawing, we need to set the appropiated (x,y) scaled values?, we need to load the correct media or we must use the method of "@2x"?.

Thanks.
#29
The original is here, with the example project:
http://gamecorner.110mb.com/index.php?page=bitmap-fonts-proportional

I have modified it for these reasons:
- To work with my Screen Manager (http://www.glbasic.com/forum/index.php?topic=5439.0).
- Added a param, it is the lastest one, 'kernoffset', I saw it interesting, giving it a negative value we can have the highly desirable effect of slight overlap. Try it in the example of the project using this modified version and giving negative values to 'kernoffset'.

The credits was untouched as this is work of PeeJays with slighty modifications. Justify text doesn't work properly but this is a mistake in the original too. Remember to add the Screen Manager to work.

[attachment deleted by admin]
#30
Hi, here is a centralized screen manager for GLBasic (those ones that uses CREATESCREEN and USESCREEN), so we only need to ask for a screen with CreateScreen, use it with RenderBegin, ask for its sprite associated with GetSprite, and release them with Destroy, with no worry about if the screen requested is in use or not (CreateScreen always will give us a free one if available). Remember to destroy not more needed ones.

Code (glbasic) Select

// --------------------------------- //
// TYPE ScreenManager
// --------------------------------- //

CONSTANT ScreenManagerVersionMajor%=1, ScreenManagerVersionMinor%=0, ScreenManagerVersionBuild%=0, ScreenManagerVersionRevision%=2

//! Screen Manager
//!
//! Author: Dark Schneider
//!
//! Management of SCREENS


//---------------------//
// --- DEFINITIONS --- //
//---------------------//


//-------------------//
// --- VARIABLES --- //
//-------------------//
GLOBAL ScreenManagerSprites%[], ScreenManagerSpritesCursor%=0


//-------------------//
// --- FUNCTIONS --- //
//-------------------//
//! FUNCTIONS

//! initializes the Screen Manager system, MUST be called ONLY ONCE before using it
FUNCTION ScreenManagerInit:
IF ScreenManagerIsInitialized() THEN ScreenManagerDispose()
DIM ScreenManagerSprites[32]
FOR i%=0 TO LEN(ScreenManagerSprites[])-1
ScreenManagerSprites[i]=-1
NEXT
ScreenManagerSpritesCursor=0
ENDFUNCTION


//! releases all the resources
FUNCTION ScreenManagerDispose:
ScreenManagerDestroyScreenAll()
DIM ScreenManagerSprites[0]
ENDFUNCTION


//! checks if the Screen Manager system has been initialized
// \return TRUE if the Screen Manager system has been initialized, FALSE if not
FUNCTION ScreenManagerIsInitialized:
IF LEN(ScreenManagerSprites[])>0 THEN RETURN TRUE
RETURN FALSE
ENDFUNCTION


//! screens iterator
// \return the next screen available, -1 if no available
@FUNCTION ScreenManagerNext:
LOCAL l_cursor%=ScreenManagerSpritesCursor
WHILE ScreenManagerSprites[ScreenManagerSpritesCursor]<>-1
INC ScreenManagerSpritesCursor
IF ScreenManagerSpritesCursor>=LEN(ScreenManagerSprites[]) THEN ScreenManagerSpritesCursor=0
IF ScreenManagerSpritesCursor=l_cursor THEN RETURN -1
WEND
RETURN ScreenManagerSpritesCursor
ENDFUNCTION


//! creates a new screen with parameters
// \param width% - width of the screen
// \param height% - height of the screen
// \return screen number, range 0-31, -1 if there is no screen available
FUNCTION ScreenManagerCreateScreenWithParams: width%, height%
LOCAL l_screen%=ScreenManagerNext()
IF l_screen=-1 THEN RETURN -1
ScreenManagerSprites[l_screen]=GENSPRITE(); CREATESCREEN l_screen, ScreenManagerSprites[l_screen], width, height
RETURN l_screen
ENDFUNCTION


//! creates a new screen with the screen resolution as size
// \return screen number, range 0-31, -1 if there is no screen available
FUNCTION ScreenManagerCreateScreen:
LOCAL scw%,sch%
GETSCREENSIZE scw,sch
RETURN ScreenManagerCreateScreenWithParams(scw,sch)
ENDFUNCTION


//! destroys a screen and releases the resources used
FUNCTION ScreenManagerDestroyScreen: screen_num%
IF ScreenManagerIsScreenInit(screen_num) THEN LOADSPRITE "xx", ScreenManagerSprites[screen_num]
ScreenManagerSprites[screen_num]=-1
ENDFUNCTION


//! destroys all the screens and releases the resources used
FUNCTION ScreenManagerDestroyScreenAll:
FOR i%=0 TO LEN(ScreenManagerSprites[])-1
ScreenManagerDestroyScreen(i)
NEXT
ENDFUNCTION


//! checks if an indicated screen has been created
// \param screen_num% - screen number to check
// \return TRUE if created, FALSE if not
FUNCTION ScreenManagerIsScreenInit: screen_num%
IF ScreenManagerSprites[screen_num]<>-1 THEN RETURN TRUE
RETURN FALSE
ENDFUNCTION


//! gets the sprite associated to a screen number
// \param screen_num% - screen number to check
// \return SPRITE ID associated to the screen, -1 if that screen has not been initialized
FUNCTION ScreenManagerGetSprite: screen_num%
RETURN ScreenManagerSprites[screen_num]
ENDFUNCTION


//! gets the size of the indicated screen
// \param screen_num% - screen number to check
// \param BYREF width% - return value of the screen width
// \param BYREF height% - return value of the screen height
FUNCTION ScreenManagerGetScreenSize: screen_num%, BYREF width%, BYREF height%
IF ScreenManagerIsScreenInit(screen_num)
GETSPRITESIZE ScreenManagerGetSprite(screen_num),width,height
RETURN TRUE
ELSE
width=-1; height=-1; RETURN FALSE
ENDIF
ENDFUNCTION


//! sets the indicated screen as render target
// \param screen_num% - screen number to check
// \return TRUE is success, FALSE if screen indicated has not been initialized
FUNCTION ScreenManagerRenderBegin: screen_num%
IF ScreenManagerIsScreenInit(screen_num)=FALSE THEN RETURN FALSE
USESCREEN screen_num
RETURN TRUE
ENDFUNCTION


//! sets the backbuffer as render target
FUNCTION ScreenManagerRenderEnd:
USESCREEN -1
ENDFUNCTION


#31
For those who like to have a centralized resources manager, use the Load, Unload, Get and Release functions of this ResourceManager so you will not have repeated resources or memory leaks (panic functions like Dispose or ReleasexxxAll  ;) ).

Be sure to use the correct one when loading an anim, because it really is a sprite, so you need to use the LoadAnim, but all later access are like a sprite.

Code (glbasic) Select

// --------------------------------- //
// TYPE ResourceManager
// --------------------------------- //
CONSTANT ResourceManagerVersionMajor%=1, ResourceManagerVersionMinor%=0, ResourceManagerVersionBuild%=0, ResourceManagerVersionRevision%=4

//! Resources Manager
//!
//! Author: Dark Schneider
//!
//! Centralized management of a resources pool

//-------------//
// --- API --- //
//-------------//
//
//! API summary
//! ---------------
//!
//! FUNCTION ResourceManagerDispose: -> clear all resources
//!
//! FUNCTION ResourceManagerLoadxxx: filename$ -> load an element, uses the complete filename$ as element.name$, including the path, important if using SETCURRENTDIR(); return its ID
//!
//! FUNCTION ResourceManagerUnloadxxxByxxx: -> decrement element counter, if 0 (not used by anything) then release it; return FALSE if element doesn't exists
//!
//! FUNCTION ResourceManagerReleasexxxByxxx: -> release the resource directly bypassing element counter; return FALSE if element doesn't exists
//!
//! FUNCTION ResourceManagerReleasexxxAll: -> release all the resources of that type (Sprites or Sounds)
//!
//! FUNCTION ResourceManagerGetxxxyyy: -> return element ID or name$, if doesn't exists it returns -1 or ""
//!
//! FUNCTION ResourceManagerGetxxxIDLoad: -> return element ID, if doesn't exists it loads it


//---------------------//
// --- DEFINITIONS --- //
//---------------------//


//---------------//
// --- TYPES --- //
//---------------//
TYPE TResourceManagerNode
name$
id%
count%=0
ENDTYPE


//-------------------//
// --- VARIABLES --- //
//-------------------//
GLOBAL ResourceManagerSprites[] AS TResourceManagerNode, ResourceManagerSounds[] AS TResourceManagerNode


//-------------------//
// --- FUNCTIONS --- //
//-------------------//
//! FUNCTIONS

//! Releases all the resources
FUNCTION ResourceManagerDispose:
ResourceManagerReleaseSpritesAll()
ResourceManagerReleaseSoundsAll()
ENDFUNCTION


//! Loads a SPRITE
// \param filename$ - file to load
// \return ID of the sprite
FUNCTION ResourceManagerLoadSprite: filename$
LOCAL l_var%=ResourceManagerSearchNodeByNameAux(filename$, ResourceManagerSprites[])
IF l_var<0
l_var=ResourceManagerLoadSpriteAux(filename$)
ELSE
INC ResourceManagerSprites[l_var].count
l_var=ResourceManagerSprites[l_var].id
ENDIF
RETURN l_var
ENDFUNCTION


//! Loads an ANIM, see LOADANIM for more details
// \param filename$ - file to load
// \param width% - width of each frame
// \param height% - height of each frame
// \return ID of the sprite
FUNCTION ResourceManagerLoadAnim: filename$, width%, height%
LOCAL l_var%=ResourceManagerSearchNodeByNameAux(filename$, ResourceManagerSprites[])
IF l_var<0
l_var=ResourceManagerLoadAnimAux(filename$, width, height)
ELSE
INC ResourceManagerSprites[l_var].count
l_var=ResourceManagerSprites[l_var].id
ENDIF
RETURN l_var
ENDFUNCTION


//! Loads a SOUND, see LOADSOUND for more details
// \param filename$ - file to load
// \param buffer% - number of buffers of the sound
// \return ID of the sound
FUNCTION ResourceManagerLoadSound: filename$, buffer%
LOCAL l_var%=ResourceManagerSearchNodeByNameAux(filename$, ResourceManagerSounds[])
IF l_var<0
l_var=ResourceManagerLoadSoundAux(filename$, buffer)
ELSE
INC ResourceManagerSounds[l_var].count
l_var=ResourceManagerSounds[l_var].id
ENDIF
RETURN l_var
ENDFUNCTION


//! Unloads ONE copy of the SPRITE, if the resource is not used by anything, it is released
// \param name$ - name of the element to unload
// \return true, or false if the element doesn't exists
FUNCTION ResourceManagerUnloadSpriteByName: name$
LOCAL l_var%=ResourceManagerSearchNodeByNameAux(name$, ResourceManagerSprites[])
IF l_var<0
RETURN FALSE
ELSE
DEC ResourceManagerSprites[l_var].count
IF ResourceManagerSprites[l_var].count<=0 THEN ResourceManagerReleaseSpriteAux(l_var)
ENDIF
RETURN TRUE
ENDFUNCTION


//! Unloads ONE copy of the SPRITE, if the resource is not used by anything, it is released
// \param id% - ID of the element to unload
// \return true, or false if the element doesn't exists
FUNCTION ResourceManagerUnloadSpriteByID: id%
LOCAL l_var%=ResourceManagerSearchNodeByIDAux(id, ResourceManagerSprites[])
IF l_var<0
RETURN FALSE
ELSE
DEC ResourceManagerSprites[l_var].count
IF ResourceManagerSprites[l_var].count<=0 THEN ResourceManagerReleaseSpriteAux(l_var)
ENDIF
RETURN TRUE
ENDFUNCTION


//! Unloads ONE copy of the SOUND, if the resource is not used by anything, it is released
// \param name$ - name of the element to unload
// \return true, or false if the element doesn't exists
FUNCTION ResourceManagerUnloadSoundByName: name$
LOCAL l_var%=ResourceManagerSearchNodeByNameAux(name$, ResourceManagerSounds[])
IF l_var<0
RETURN FALSE
ELSE
DEC ResourceManagerSounds[l_var].count
IF ResourceManagerSounds[l_var].count<=0 THEN ResourceManagerReleaseSoundAux(l_var)
ENDIF
RETURN TRUE
ENDFUNCTION


//! Unloads ONE copy of the SOUND, if the resource is not used by anything, it is released
// \param id% - ID of the element to unload
// \return true, or false if the element doesn't exists
FUNCTION ResourceManagerUnloadSoundByID: id%
LOCAL l_var%=ResourceManagerSearchNodeByIDAux(id, ResourceManagerSounds[])
IF l_var<0
RETURN FALSE
ELSE
DEC ResourceManagerSounds[l_var].count
IF ResourceManagerSounds[l_var].count<=0 THEN ResourceManagerReleaseSoundAux(l_var)
ENDIF
RETURN TRUE
ENDFUNCTION


//! Releases the SPRITE
// \param name$ - name of the element to unload
// \return true, or false if the element doesn't exists
FUNCTION ResourceManagerReleaseSpriteByName: name$
LOCAL l_var%=ResourceManagerSearchNodeByNameAux(name$, ResourceManagerSprites[])
IF l_var<0
RETURN FALSE
ELSE
ResourceManagerReleaseSpriteAux(l_var)
ENDIF
RETURN TRUE
ENDFUNCTION


//! Releases the SPRITE
// \param id% - ID of the element to unload
// \return true, or false if the element doesn't exists
FUNCTION ResourceManagerReleaseSpriteByID: id%
LOCAL l_var%=ResourceManagerSearchNodeByIDAux(id, ResourceManagerSprites[])
IF l_var<0
RETURN FALSE
ELSE
ResourceManagerReleaseSpriteAux(l_var)
ENDIF
RETURN TRUE
ENDFUNCTION


//! Releases the SOUND
// \param name$ - name of the element to unload
// \return true, or false if the element doesn't exists
FUNCTION ResourceManagerReleaseSoundByName: name$
LOCAL l_var%=ResourceManagerSearchNodeByNameAux(name$, ResourceManagerSounds[])
IF l_var<0
RETURN FALSE
ELSE
ResourceManagerReleaseSoundAux(l_var)
ENDIF
RETURN TRUE
ENDFUNCTION


//! Releases the SOUND
// \param id% - ID of the element to unload
// \return true, or false if the element doesn't exists
FUNCTION ResourceManagerReleaseSoundByID: id%
LOCAL l_var%=ResourceManagerSearchNodeByIDAux(id, ResourceManagerSounds[])
IF l_var<0
RETURN FALSE
ELSE
ResourceManagerReleaseSoundAux(l_var)
ENDIF
RETURN TRUE
ENDFUNCTION


//! Releases ALL the SPRITES
FUNCTION ResourceManagerReleaseSpritesAll:
FOREACH sprite IN ResourceManagerSprites[]
LOADSPRITE "xx", sprite.id
NEXT
DIM ResourceManagerSprites[0]
ENDFUNCTION


//! Releases ALL the SOUNDS
FUNCTION ResourceManagerReleaseSoundsAll:
FOREACH sound IN ResourceManagerSounds[]
LOADSOUND "xx", sound.id, 1
NEXT
DIM ResourceManagerSounds[0]
ENDFUNCTION


//! Gets SPRITE ID
// \param name$ - name of the element
// \return ID of the element, -1 if it doesn't exists
FUNCTION ResourceManagerGetSpriteID: name$
LOCAL l_var%=ResourceManagerSearchNodeByNameAux(name$, ResourceManagerSprites[])
IF l_var<0
RETURN -1
ENDIF
RETURN ResourceManagerSprites[l_var].id
ENDFUNCTION


//! Gets SPRITE ID, if it doesn't exists, loads it
// \param name$ - name of the element
// \return ID of the element
FUNCTION ResourceManagerGetSpriteIDLoad: name$
LOCAL l_var%=ResourceManagerSearchNodeByNameAux(name$, ResourceManagerSprites[])
IF l_var<0
l_var=ResourceManagerLoadSpriteAux(name$)
ELSE
l_var=ResourceManagerSprites[l_var].id
ENDIF
RETURN l_var
ENDFUNCTION


//! Gets ANIM ID, if it doesn't exists, loads it
// \param name$ - name of the element
// \param width% - width of each frame
// \param height% - height of each frame
// \return ID of the element
FUNCTION ResourceManagerGetAnimIDLoad: name$, width%, height%
LOCAL l_var%=ResourceManagerSearchNodeByNameAux(name$, ResourceManagerSprites[])
IF l_var<0
l_var=ResourceManagerLoadAnimAux(name$, width, height)
ELSE
l_var=ResourceManagerSprites[l_var].id
ENDIF
RETURN l_var
ENDFUNCTION


//! Gets SPRITE name
// \param id% - ID of the element
// \return name of the element, "" if it doesn't exists
FUNCTION ResourceManagerGetSpriteName$: id%
LOCAL l_var%=ResourceManagerSearchNodeByIDAux(id, ResourceManagerSprites[])
IF l_var<0
RETURN ""
ENDIF
RETURN ResourceManagerSprites[l_var].name$
ENDFUNCTION


//! Gets SOUND ID
// \param name$ - name of the element
// \return ID of the element, -1 if it doesn't exists
FUNCTION ResourceManagerGetSoundID: name$
LOCAL l_var%=ResourceManagerSearchNodeByNameAux(name$, ResourceManagerSounds[])
IF l_var<0
RETURN -1
ENDIF
RETURN ResourceManagerSounds[l_var].id
ENDFUNCTION


//! Gets SOUND ID, if it doesn't exists, loads it
// \param name$ - name of the element
// \param buffer% - number of buffers of the sound
// \return ID of the element
FUNCTION ResourceManagerGetSoundIDLoad: name$, buffer%
LOCAL l_var%=ResourceManagerSearchNodeByNameAux(name$, ResourceManagerSounds[])
IF l_var<0
l_var=ResourceManagerLoadSoundAux(name$, buffer)
ELSE
l_var=ResourceManagerSounds[l_var].id
ENDIF
RETURN l_var
ENDFUNCTION


//! Gets SOUND name
// \param id% - ID of the element
// \return name of the element, "" if it doesn't exists
FUNCTION ResourceManagerGetSoundName$: id%
LOCAL l_var%=ResourceManagerSearchNodeByIDAux(id, ResourceManagerSounds[])
IF l_var<0
RETURN ""
ENDIF
RETURN ResourceManagerSounds[l_var].name$
ENDFUNCTION





//----------------------------//
// --- AUXILIAR FUNCTIONS --- //
// ---     DO NOT USE     --- //
//----------------------------//
//! Loads a SPRITE and adds it to resources pool
// \param filename$ - file to load
// \return ID of the sprite
@FUNCTION ResourceManagerLoadSpriteAux: filename$
LOCAL l_node AS TResourceManagerNode
IF DOESFILEEXIST(filename$)=FALSE THEN RETURN -1
l_node.name$=filename$
l_node.id=GENSPRITE(); LOADSPRITE filename$, l_node.id
INC l_node.count
DIMPUSH ResourceManagerSprites[], l_node
RETURN l_node.id
ENDFUNCTION


//! Loads an ANIM and adds it to resources pool
// \param filename$ - file to load
// \param width% - width of each frame
// \param height% - height of each frame
// \return ID of the sprite
@FUNCTION ResourceManagerLoadAnimAux: filename$, width%, height%
LOCAL l_node AS TResourceManagerNode
IF DOESFILEEXIST(filename$)=FALSE THEN RETURN -1
l_node.name$=filename$
l_node.id=GENSPRITE(); LOADANIM filename$, l_node.id, width, height
INC l_node.count
DIMPUSH ResourceManagerSprites[], l_node
RETURN l_node.id
ENDFUNCTION


//! Loads a SOUND and adds it to resources pool
// \param filename$ - file to load
// \param buffer% - number of buffers of the sound
// \return ID of the sound
@FUNCTION ResourceManagerLoadSoundAux: filename$, buffer%
LOCAL l_node AS TResourceManagerNode
IF DOESFILEEXIST(filename$)=FALSE THEN RETURN -1
l_node.name$=filename$
l_node.id=GENSOUND(); LOADSOUND filename$, l_node.id, buffer
INC l_node.count
DIMPUSH ResourceManagerSounds[], l_node
RETURN l_node.id
ENDFUNCTION


//! Releases a SPRITE and remove it from resources pool
// \param index% - element index in the resources pool
@FUNCTION ResourceManagerReleaseSpriteAux: index%
LOADSPRITE "xx", ResourceManagerSprites[index].id
DIMDEL ResourceManagerSprites[], index
ENDFUNCTION


//! Releases a SOUND and remove it from resources pool
// \param index% - element index in the resources pool
@FUNCTION ResourceManagerReleaseSoundAux: index%
LOADSOUND "xx", ResourceManagerSounds[index].id, 1
DIMDEL ResourceManagerSounds[], index
ENDFUNCTION


//! Search a node in the resources pool
// \param name$ - name of the resource
// \param nodes[] AS TResourceManagerNode - array to do search
// \return position of the node, -1 if not found
@FUNCTION ResourceManagerSearchNodeByNameAux: name$, nodes[] AS TResourceManagerNode
LOCAL l_result%=0
FOREACH node IN nodes[]
IF node.name$=name$ THEN RETURN l_result
INC l_result
NEXT
RETURN -1
ENDFUNCTION


//! Search a node in the resources pool
// \param id% - ID of the resource
// \param nodes[] AS TResourceManagerNode - array to do search
// \return position of the node, -1 if not found
@FUNCTION ResourceManagerSearchNodeByIDAux: id%, nodes[] AS TResourceManagerNode
LOCAL l_result%=0
FOREACH node IN nodes[]
IF node.id=id THEN RETURN l_result
INC l_result
NEXT
RETURN -1
ENDFUNCTION

#32
For dynamic arrays we use:

Code (glbasic) Select

LOCAL MyArray[]
DIM MyArray[0]
...
DIMPUSH MyArray[], data


All we know the cost of allocate memory in runtime, maybe there is the only way (until you want to make your own List) but, could something like this helps?:

Code (glbasic) Select

LOCAL MyArray[]
DIM MyArray[1024]
REDIM MyArray[0]
...
DIMPUSH MyArray[], data


I mean, some languages have the option to create collections with a base size (maybe C#, I don't remember well  :zzz: ) and then when you overpass that size it begins with the dynamic growing.
#33
Hi, my question is if we need to free memory of anything other than resources (sprites, sounds), i.e. if we have:

Code (glbasic) Select

TYPE TMyType
   array[]

FUNCTION Init:
   DIM self.array[x]
ENDFUNCTION
ENDTYPE

FUNCTION MyFunc:
LOCAL myvar[] as TMyType
DIM myvar[x]
FOREACH item IN myvar[]
   item.Init() // this does the DIM array[x] in the TYPE
NEXT

// SOME CODE HERE...

//There is need to do this, or we can forget about all memory management?
FOREACH item IN myvar[]
   DIM item.array[0]
NEXT
DIM myvar[0]
ENDFUNCTION


In other words, we need to worry about arrays?
#34
We have a SORTARRAY function, but we have not a SEARCHARRAY function, it would be good one like the SORTARRAY one, accepting TYPEs with the same syntax, using the first member variable as compare for equal, or allowing to use a custom function with the syntax something like:

Code (glbasic) Select
FUNCTION compare: BYREF a, value%#$
   IF a.member%#$=value%#$ then return TRUE
   return FALSE
ENDFUNCTION


I think a basic function like a SEARCH should be available in GLBasic API.
#35
For games does not use the touch screen, this is needed, I don't know if GLBasic includes a way to do this, if not, it would be good to add it. Here is the way to do it (in the "The Automatic Sleep Timer" section):

http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/RuntimeEnvironment/RuntimeEnvironment.html

and for OS 3 or later, there is need to do:

http://stackoverflow.com/questions/1058717/idletimerdisabled-not-working-since-iphone-3-0

that is the sequence =NO and then =YES.

An example using it in code:
http://www.torquepowered.com/community/blogs/view/17211

I'd like to insert by myself but I don't know how to do it, as it must be called inside the app because the shared UIApplication.

This functions can be expanded to all systems with energy saving, like Windows or Linux, so if you play with a PAD don't allow to screen saver to popup.
#36
2D / Drawing with DEPTH
2010-Jun-28
Yes, depth for 2D drawing, the idea is for save fill-rate. Enable the depth buffer for 2D so we can draw 1-bit alpha graphics in front-to-back order and save much fill-rate.

2D functions could have a new 'depth%' param (0 used if not indicated) with 256 levels (0-255 values), 0 is total front and 255 is total back. Or use instead the same depth configured with a previous X_MAKE3D.

Using a default value of 0 like with vertex color in POLYVECTORs RGB(255,255,255) with no need to pass a value there is no need to re-write old codes.
#37
I started a post in features request http://www.glbasic.com/forum/index.php?topic=4598.0 "Don't stop the user music on devices under demmand", but I don't know if this is possible currently by some way. It is possible?

If not, don't you think it should be in this way by default?, when I start an application made with standard SDK it doesn't stop the music playing.
#38
I am doing tests on iPhone for 3D, I have noticed that 3D on this device runs not fast, I have tested to draw few objects (including only 1 object) but at about 3000 triangles it runs some slow, if I want to have about 30FPS I am limited to 1200 triangles.

I have turned off all the lights and the autonormals, and used a texture powerof2 (128x128).

I know devices are not much powerfull, but it is supposed iPhone is hardware accelerated. So it is a device problem or GLBaisc problem with OpenGL ES devices?.

There is a way to have really fast 3D on iPhone, it is 1500 triangles/frame the limit to have 30FPS?

Any suggestion is appreciated.
#39
There should be a way to say GLBasic not to stop the user music when launch the application.

Some games are preferable to have no music, and allow users to use their own in their music library, but currently GLBasic always stops the playing music when start the application.

Then, I think it could be good add something, probably the best location is in project properties, and mark and option for "Allow user custom music".

The main target I can think for this is of course the iPhone, but it can be used too on others devices, and in the future on iPad too.
#40
If we don't specify a type (a% or a#) what exactly happens?. An example: I want to create a TYPE rectangle, if I do the followirng:

Code (glbasic) Select

TYPE TRectangle
   left
   right
   width
   height
ENDTYPE


How it works?, it is dynamically converted?, it is used as template and then the compiler creates the % and/or the # version when needed/used?.

Because sometimes it is preferable to force the use of the IPU (Integer Processing Unit) instead the FPU, specially on devices. Then, with the prior example, should I do:

1) At use: assign by 'rect.left%=value', this is, referencing always with the % for specify type.

2) Create 2 rectangles:

Code (glbasic) Select

TYPE TRectangle
   left%
   right%
   width%
   height%
ENDTYPE


and

Code (glbasic) Select

TYPE TRectangleF
   left#
   right#
   width#
   height#
ENDTYPE


I'd like to know how GLBasic works internally with this to handle it correctly.