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.


Topics - Albert

Pages: [1] 2
1
Inline / 3rd party / LUA 5.2 wrapper
« on: 2012-Jun-25 »
This is my attempt to embed LUA into glBasic in a cross-platform cross-compile way.

Tested in Windows and Android.
Added only some of the LUA commands, and a little set of GLBasic commands for testing purposes.
I hope that one of you interested in and have enough knowledge (more than me) to fix and extend this little sample.

Download with source: https://dl.dropbox.com/u/292449/glbasic/lua/lua1.zip
Install on Android: https://dl.dropbox.com/u/292449/glbasic/lua/lua1.apk


2
Bug Reports / Android PORTRAIT forced!!??
« on: 2012-Jun-12 »
I've got a TV-out cable for my Galaxy S.
I've tried some stuff on my old TV, and I liked it, the phone can handle well the portrait and landscape mode on the TV,
But it's not the case, when I try some of my landscape projects compiled with GLBasic: the screen on the TV remains portrait, and all the stuff on it rotated 90°
I found this line in the AndroidManifest.xml:
Code: (glbasic) [Select]
android:screenOrientation="portrait"
It would be nice if it could be landscape if screen width > screen height.

3
Code Snippets / Good looking GUI by code
« on: 2012-May-21 »
I dunno what happened my thread.
Here it is again:

So this is an attempt to make a good looking GUI with GLBasic. This is only some graphics and there isn't any real GUI logic in the background.

I realized that I have simply not enough time to clean my code :( So there is it as is. Maybe smbdy could find this useful.

Update: see http://www.glbasic.com/forum/index.php?topic=8139.msg69683#msg69683 for IMGUI code







[attachment deleted by admin]

4
Code Snippets / StateMachine
« on: 2012-May-21 »
Hi!

I've created this simple state machine for creating simple menus and game states during my LD48.

[attachment deleted by admin]

5
GLBasic - en / IndieDB
« on: 2011-Sep-28 »
Hi!
It would be nice if somebody would create an indieDB group: glBasicDevelopers and then an engine: glBasic (the order is important) on indieDB like one of my friend made it with SFML ( http://www.indiedb.com/engines/sfml/games )

I searched and I found 1 game on indieDB wich made in glBasic. Yesterday I registered our games too: http://www.indiedb.com/games/legendary-quest-of-sandor-rozsa

6
Code Snippets / Ray of lights
« on: 2011-Sep-21 »
Hi!

I'm experimenting with ray of lights. You can download the fully commented project from here or you can found in the attachment.
http://dl.dropbox.com/u/292449/lightrays.zip




[attachment deleted by admin]

7
Code Snippets / Blobmonster
« on: 2011-Feb-10 »
So Charlie has this tutorial and source code in BlitzMax: http://www.charliesgames.com/wordpress/?p=441
I ported it to glBasic, have fun!



Code: (glbasic) [Select]
// --------------------------------- //
// Project: blobmonster
// Start: Friday, February 04, 2011
// IDE Version: 8.200

SETCURRENTDIR("Media") // seperate media and binaries?

//ported to glBasic by Bence Dobos, 2011

//How to make an Irukandji style blob monster.
//By Charlie Knight, 2009/2010
//http://www.charliesgames.com
//
//This code is public domain. Feel free to use as you please.
//If you use the code as a basis for your own blob monsters, let me know! I'd love to
//see what you came up with!
//
//The code is written using the Blitzmax language, but it should be fairly easy to port
//to C++/Java/Whatever with a suitable graphics library.
//
//the image blob.png can be found at http://www.charliesgames.com/wpimages/blob.png
//
//Cheers
//Charlie

GLOBAL KEY_ESCAPE=1
GLOBAL blob=0
GLOBAL w, h

//load the image
LOADSPRITE "blob.png", blob
GETSPRITESIZE blob, w, h

//create a blobMonster object
LOCAL test AS blobMonster

test.Create(10, 10)
//main loop
WHILE KEY(KEY_ESCAPE)=0
//update and draw the blobmonster
CLEARSCREEN
test.Update()
test.Draw()

SHOWSCREEN
WEND
END
//Finished!

//simple class (type in glBasic) to hold a 2d coordinate
TYPE point
x#
y#
ENDTYPE

//here's the blob monster type
TYPE blobMonster

//x and y coords
x#
y#

//speed, try changing it
speed# = 1

//number of nodes along the body, try changing it to 100
segments# = 10

//array to hold the points along the body
tail[] AS point

time# = 0

//function that returns a new blob monster object. Blitzmax equivalent (kind of)
//of a constructor in C++/Java
FUNCTION Create AS blobMonster:inX#, inY#
DIM self.tail[self.segments]
//starting point of the blob monster
self.x = inX
self.y = inY
//give the tail some coordinates, just make them the same as the main x and y for now
FOR i = 0 TO self.segments - 1
self.tail[i].x# = inX
self.tail[i].y# = inY
NEXT

RETURN self
ENDFUNCTION

FUNCTION Update%:
//time is a bit misleading, it's used for all sorts of things
INC self.time#, self.speed#

//here the x and y coordinates are updated.
//this uses the following as a basic rule for moving things
//around a point in 2d space:
//x=radius*cos(angle)+xOrigin
//y=raduis*sin(angle)+yOrigin
//this basically is the basis for anything that moves in this example
//
//the 2 lines of code below make the monster move around, but
//you can change this to anything you like, try setting x and y to the mouse
//coordinates for example
self.y = (15 * COS(self.time * -6)) + (240 + (180 * SIN(self.time * 1.3)))
self.x = (15 * SIN(self.time * -6)) + (320 + (200 * COS(self.time / 1.5)))

//put the head of the tail at x,y coords
self.tail[0].x = self.x
self.tail[0].y = self.y

//update the tail
//basically, the points don//t move unless they//re further that 7 pixels
//from the previous point. this gives the kind of springy effect as the
//body stretches
FOR i = 1 TO self.segments - 1
    //calculate distance between the current point and the previous
    LOCAL distX# = (self.tail[i - 1].x - tail[i].x)
        LOCAL distY# = (self.tail[i - 1].y - tail[i].y)
LOCAL dist# = SQR(distX * distX + distY * distY)
      //move if too far away
          IF dist > 7
//the (distX*0.2) bit makes the point move
//just 20% of the distance. this makes the
//movement smoother, and the point decelerate
//as it gets closer to the target point.
//try changing it to 1 (i.e 100%) to see what happens
self.tail[i].x = self.tail[i].x + (distX * (0.3))
            self.tail[i].y = self.tail[i].y + (distY * (0.3))
          ENDIF

NEXT

RETURN FALSE
ENDFUNCTION

FUNCTION Draw:
//time to draw stuff!

//this sets the blend mode to LIGHTBLEND, or additive blending, which makes
//the images progressively more bright as they overlap
//ALPHAMODE LIGHTBLEND
LOCAL color=RGB( 0, 200, 150 )
LOCAL scale=1
//###########
//draw the main bit of the body
//begin looping through the segments of the body
FOR i = 0 TO self.segments - 1
//set the alpha transparency vaue to 0.15, pretty transparent
ALPHAMODE 0.15
//the  (0.5*sin(i*35)) bit basically bulges the size of the images being
//drawn as it gets closer to the center of the monsters body, and tapers off in size as it gets
//to the end. try changing the 0.5 to a higher number to see the effect.
scale = 1 + (0.5 * SIN(i * 35))
//draw the image
PolySprite(blob, self.tail[i].x, self.tail[i].y, scale, scale, color, 0.5, 0.5, 0, w, h)

//this next chunk just draws smaller dots in the center of each segment of the body
ALPHAMODE 0.8
scale = 0.1
PolySprite(blob, self.tail[i].x, self.tail[i].y, scale, scale, color, 0.5, 0.5, 0, w, h)
NEXT

//#########################
//draw little spikes on tail
color = RGB( 255, 255, 255 )
//note that the x and y scales are different
LOCAL scalex = 0.6
LOCAL scaley = 0.1
LOCAL rot=0
//move the image handle to halfway down the left edge, this'll make the image
//appear to the side of the coordinate it is drawn too, rather than the
//center as we had for the body sections

//rotate the 1st tail image. basically, we//re calculating the angle between
//the last 2 points of the tail, and then adding an extra wobble (the 10*sin(time*10) bit)
//to make the pincer type effect.
rot = 10 * SIN(self.time * 10) + calculateAngle(self.tail[self.segments - 1].x, self.tail[self.segments - 1].y, self.tail[self.segments - 5].x, self.tail[self.segments - 5].y) + 90
PolySprite(blob, self.tail[self.segments - 1].x, self.tail[self.segments - 1].y, scalex, scaley, color,0, 0.5, rot, w, h)

//second tail image uses negative time to make it move in the opposite direction
rot = 10 * SIN(-self.time * 10) + calculateAngle(self.tail[self.segments - 1].x, self.tail[self.segments - 1].y, self.tail[self.segments - 5].x, self.tail[self.segments - 5].y) + 90
PolySprite(blob, self.tail[self.segments - 1].x, self.tail[self.segments - 1].y, scalex, scaley, color,0, 0.5, rot, w, h)



//#####################
//draw little fins/arms
ALPHAMODE 1

//begin looping through the body sections again. Note that we don't want fins
//on the first and last section because we want other things at those coords.
FOR i = 1 TO self.segments - 2
//like the bulging body, we want the fins to grow larger in the center, and smaller
//at the end, so the same sort of thing is used here.
scalex = 0.1 + (0.6 * SIN(i * 30))
scaley = 0.05

//rotate the image. We want the fins to stick out sideways from the body (the calculateangle() bit)
//and also to move a little on their own. the 33 * Sin(time * 5 + i * 30) makes the
//fin rotate based in the i index variable, so that all the fins look like they//re moving
//one after the other.
rot = 33 * SIN(self.time * 5 + i * 30) + calculateAngle(self.tail[i].x, self.tail[i].y, self.tail[i - 1].x, self.tail[i - 1].y)
PolySprite( blob, self.tail[i].x, self.tail[i].y, scalex, scaley, color, 0, 0.5, rot, w, h)

//rotate the opposte fin, note that the signs have changes (-time and -i*30)
//to reflect the rotations of the other fin
rot = 33 * SIN(-self.time * 5 - i * 30) + calculateAngle(self.tail[i].x, self.tail[i].y, self.tail[i - 1].x, self.tail[i - 1].y) + 180
PolySprite( blob, self.tail[i].x, self.tail[i].y, scalex, scaley, color, 0, 0.5, rot, w, h)

NEXT

//###################
//Draw the eyes. These are just at 90 degrees to the head of the tail.
color = RGB( 255, 0, 0 )
scale = 0.6
ALPHAMODE 0.3
LOCAL ang# = calculateAngle(self.tail[0].x, self.tail[0].y, self.tail[1].x, self.tail[1].y)
PolySprite(blob, self.x + (7 * COS(ang + 50)), self.y + (7 * SIN(ang + 50)), scale, scale, color, 0.5, 0.5, 0.0, w, h)
PolySprite(blob, self.x + (7 * COS(ang + 140)), self.y + (7 * SIN(ang + 140)), scale, scale, color, 0.5, 0.5, 0.0, w, h)
color = RGB( 255, 255, 255 )
scale = 0.1
ALPHAMODE 0.5
PolySprite(blob, self.x + (7 * COS(ang + 50)), self.y + (7 * SIN(ang + 50)), scale, scale, color, 0.5, 0.5, 0.0, w, h)
PolySprite(blob, self.x + (7 * COS(ang + 140)), self.y + (7 * SIN(ang + 140)), scale, scale, color, 0.5, 0.5, 0.0, w, h)

//draw beaky thing
color = RGB( 0, 200, 155 )
scalex = 0.3
scaley = 0.1
ALPHAMODE 0.8
rot = ang + 95
PolySprite(blob, self.x, self.y, scalex, scaley, color, 0.0, 0.5, rot, w, h)

//yellow light
color = RGB( 255, 255, 0 )
ALPHAMODE 0.2
scale = 4
PolySprite(blob, self.x, self.y, scale, scale, color, 0.5, 0.5, 0, w, h)

//Finished!
ENDFUNCTION

ENDTYPE

//This function calculates and returns the angle between two 2d coordinates
FUNCTION calculateAngle#:x1#,y1#,x2#,y2#
LOCAL theX#=x1-x2
LOCAL theY#=y1-y2
LOCAL theAngle#=-ATAN(theX,theY)
RETURN theAngle
ENDFUNCTION

//Draw and colorize a sprite. You can set the handle point, rotation, scale and color of the sprite
//Written by Bence Dobos
//spr - the ID of the sprite
//scalex, scaley - the ratio of the sprite scale [0.0-inf]
//color - 0xffffff is the normal color
//xc,yc - the ratio of the handle point of the sprite [0.0-1.0], this point is used to draw the sprite, rotate and scale. 0,0 is the top-left point, 0.5,0.5 is the center point
//rot - rotation of the sprite [0-360]
//w,h - width, height of the sprite in pixel, if not specified it's determined automatically
FUNCTION PolySprite: spr, x, y, scalex, scaley, color=0xffffff, xc=0.0, yc=0.0, rot=0, w=-1, h=-1
IF w=-1
GETSPRITESIZE spr, w, h
ENDIF
LOCAL w2=w*scalex
LOCAL h2=h*scaley
LOCAL xcenter=x+xc*w2
LOCAL ycenter=y+yc*h2
LOCAL xr1=-xc*w2
LOCAL yr1=-yc*h2
LOCAL xr2=(1.0-xc)*w2
LOCAL yr2=-yc*h2
LOCAL xr3=(1.0-xc)*w2
LOCAL yr3=(1.0-yc)*h2
LOCAL xr4=-xc*w2
LOCAL yr4=(1.0-yc)*h2

LOCAL x1, y1, x2, y2
LOCAL x3, y3, x4, y4
IF rot<>0
LOCAL sp = SIN(rot)
LOCAL cp = COS(rot)
x1 = xr1*cp-yr1*sp+x
y1 = xr1*sp+yr1*cp+y
x2 = xr2*cp-yr2*sp+x
y2 = xr2*sp+yr2*cp+y
x3 = xr3*cp-yr3*sp+x
y3 = xr3*sp+yr3*cp+y
x4 = xr4*cp-yr4*sp+x
y4 = xr4*sp+yr4*cp+y
ELSE
x1=xr1+x
y1=yr1+y
x2=xr2+x
y2=yr2+y
x3=xr3+x
y3=yr3+y
x4=xr4+x
y4=yr4+y
ENDIF

STARTPOLY spr
  POLYVECTOR   x1, y1,  0,  0, color
  POLYVECTOR   x2, y2,  0,  h, color
  POLYVECTOR   x3, y3,  w,  h, color
  POLYVECTOR   x4, y4,  w,  0, color
ENDPOLY
ENDFUNCTION

Edit: Missing beaky thing, fixed.

[attachment deleted by admin]

8
Bug Reports / UTF-8 .ini (hacked highscore)
« on: 2011-Jan-26 »
Hi! Some funny coder hacked the highscore system. (maybe they reverse engineering the secret code, and made a custom script to submit scores)
And they sumbitted some kanji or whatever as name. Some player reported the game now freezes when trying to open the highscore.ini
I tested it, and for big surprise NETWEBGET() created an UTF-8 ini, containing the kanji:
...
n9=ありがとう
s9=6104
...
(I googled it and wiki says it's an ancient Japanese word, meaning: hard to be, special, rare)
So it's UTF-8, great! NETWEBGET() made a good job, but INIOPEN freezes...

I1m trying to find a workaround for this, but i'm open for ideas.

9
Bug Reports / Problem with POW
« on: 2011-Jan-26 »
Hi!
I'm experimenting with 3D and I'm trying to learn from the samples comes with glBasic. Unfortunetly that samples are rather old (just as the Help  :'( ) so before I could try any of that 3D sample program I have to fix that.
So I found a bug around POW and float/int types while I fixed the ObjectCreation.gbas:

Code: (glbasic) [Select]
cubeSize=5
DIM ObjectTypes[POW(cubeSize, 3)]
DEBUG BOUNDS(ObjectTypes[], 0) //124

So the POW(cubeSize,3) returns 124 to the DIM

I've made a little test to figure out what is going here.

Code: (glbasic) [Select]
LOCAL res%, res2#
res=POW(5,3)
res2=POW(5,3)
LOCAL obj[], obj2[]
DIM obj[res]
DIM obj2[POW(5,3)]

WHILE TRUE
PRINT res, 0,0 //124
PRINT res2, 0,20 //125
PRINT BOUNDS(obj[],0),0,40 //124
PRINT BOUNDS(obj2[],0),0,60 //124
SHOWSCREEN
WEND

res% gets 124, res# 125. The big problem is that if you want to use directly the resolt of POW(5,3) then your fv gets 124 (DIM obj2[POW(5,3)]) :(



10
Legendary Quest of Sandor Rozsa - X-Mas Special is a small challenge teaser for an upcoming 2D sidescroller game by Puli Games, an independent gamedevelopers' alliance. In this challenge you control Sandor the rascal at Christmas time. The constables gathered all the adornments for themselves, your task is to take them back and put it on the tree. As an extra, you can rebuild the snowman by finding the snowman's parts.



You can download from the showroom http://www.glbasic.com/showroom.php?site=games&game=legendaryquestofsandorrozsaxmasspecial&lang=en or from Puli Games' forum: http://puligames.com/index.php?topic=54

More info at: www.puligames.com

11
Code Snippets / Immediate Mode GUI
« on: 2010-Dec-14 »
Update: For the updated IMGUI system jump to: http://www.glbasic.com/forum/index.php?topic=5431.msg69686#msg69686

I followed Sol's tutorial about Immediate Mode GUI http://sol.gfxile.net/imgui/ and expanded it a bit (only the top widget will be highlighted; added a dragable Window widget)

Quote
The magic here is that the call to button will perform everything the widget would be expected to do at any single time, including the rendering of the visible widget. There's a bit of global data that's shared by all of the widgets that enables them to work.

There's no setup phase, but if a widget needs some data to show it's state (say, a scroll bar, text edit field, etc), the state data is owned by the host application and not the widget. This is surprisingly handy and performance-friendly, as there's no querying and message-sending involved.

There's also no cleanup required, except for the data that you have allocated yourself. The widgets only exist when they're called, so you'll need to ask for them each frame you want to use them.

Nothing is ever simply positive, and IMGUI does have its problems. The most obvious one is that it's just about as anti-OOP as you can get, so it may feel wrong for you. Other problems are related to the fact that the widgets don't really exist except when they are queried, and as such things like automatic layouts or keyboard focus get somewhat more difficult.



Here is the code:
Code: (glbasic) [Select]
// --------------------------------- //
// Project: imgui
// Start: Thursday, December 09, 2010
// IDE Version: 8.174

// Made by Bence Dobos. Based on this great tutorial http://sol.gfxile.net/imgui/
// Widget IDs must be unique!

SETCURRENTDIR("Media") // seperate media and binaries?
SYSTEMPOINTER TRUE
LOADFONT "smalfont.png", 0

//GUI object
GLOBAL gui AS UIState

//variables (what the widgets will be using and changing)
GLOBAL backgroundcolor = RGB(100,100,255)
GLOBAL text$ = "teszt"
GLOBAL showwin=FALSE
GLOBAL winX=300
GLOBAL winY=50
GLOBAL win2X=70
GLOBAL win2Y=250
GLOBAL menustr1$[]
DIMDATA menustr1$[], "File", "Open", "Save", "Save As", "---", "New project", "Open project", "Close project", "---", "Exit"
GLOBAL showmenu1=FALSE
GLOBAL menustr2$[]
DIMDATA menustr2$[], "View", "Output", "Status", "---", "Skins", "Colors", "Look and feel",  "---", "Whitespace", "Wordwrap"
GLOBAL showmenu2=FALSE
GLOBAL toastmsg$="Welcome"
GLOBAL toasttimer=50

//start endless loop
WHILE TRUE
CLEARSCREEN backgroundcolor
//prepare the gui
gui.prepare()

ALPHAMODE 0
PRINT "(SHIFT+)TAB to switch widget, ENTER, UP, DOWN to use widget",5,25,TRUE
//ALPHAMODE -0.5

//buttons (doing nothing)
IF button(1,10,50,60,25,RGB(100,0,200),"Button") THEN settoast("button", 50)
IF button(2,120,50,100,25,RGB(100,0,200),"Button long") THEN settoast("button long", 100)

//button (change background color)
IF button(3,10,100,60,25,RGB(255,0,200),"Color") THEN backgroundcolor = RND(0xffffff)

//button (show/hide window)
IF button(4,120,100,150,25,RGB(100,0,200),"Show/hide Window") THEN showwin = NOT showwin

//button (show popupmenu)
IF button(5,10,0,40,25,RGB(200,200,200),"File") THEN showmenu1=TRUE
//button (show popupmenu)
IF button(6,50,0,50,25,RGB(200,200,200),"View") THEN showmenu2=TRUE

//slider (change background color)
sliderV(7, 550, 20, 430, 0xffffff, backgroundcolor)
textfield(7, 10,200, 20, text$)
sliderH(8, 50, 410, 430, 0xffffff, backgroundcolor)

//window (about window, transparent)
ALPHAMODE -0.7
window( 20, win2X, win2Y, 200, 150, RGB(100,200,70), "About")
ALPHAMODE 0
PRINT "Immediate Mode GUI", win2X+5, win2Y+20, TRUE
PRINT "Written by Bence Dobos", win2X+5, win2Y+50, TRUE
PRINT "Based on Jari Komppa's", win2X+5, win2Y+80, TRUE
PRINT "great tutorial at", win2X+5, win2Y+100, TRUE
PRINT "sol.gfxile.net/imgui/", win2X+5, win2Y+120, TRUE

//window (showing gui variables)
IF showwin
window( 10, winX, winY, 200, 300, RGB(200,200,200), "GUI states")
PRINT "tab: " + gui.tab ,winX+5, winY+20, TRUE
PRINT "shift: " + gui.shift ,winX+100, winY+20, TRUE
PRINT "ctrl: " + gui.ctrl ,winX+5, winY+40, TRUE
PRINT "alt: " + gui.alt ,winX+100, winY+40, TRUE
PRINT "up: " + gui.up ,winX+5, winY+60, TRUE
PRINT "down: " + gui.down ,winX+100, winY+60, TRUE
PRINT "left: " + gui.left ,winX+5, winY+80, TRUE
PRINT "right: " + gui.right ,winX+100, winY+80, TRUE
PRINT "mousex:" + gui.mousex ,winX+5, winY+100, TRUE
PRINT "mousex:" + gui.mousey ,winX+100, winY+100, TRUE
PRINT "lclick: " + gui.mouselclick ,winX+5, winY+120, TRUE
PRINT "rclick: " + gui.mouserclick ,winX+100, winY+120, TRUE
PRINT "mclick: " + gui.mousemclick ,winX+5, winY+140, TRUE
PRINT "scroll: " + gui.mousescroll ,winX+100, winY+140, TRUE
PRINT "prehot: " + gui.prehotitem ,winX+5, winY+160, TRUE
PRINT "hotitem: " + gui.hotitem ,winX+100, winY+160, TRUE
PRINT "active: " + gui.activeitem ,winX+5, winY+180, TRUE
PRINT "kbditem: " + gui.kbditem ,winX+100, winY+180, TRUE
PRINT "key$: " + gui.keyentered$ ,winX+5, winY+200, TRUE
PRINT "keychar: " + gui.keychar ,winX+100, winY+200, TRUE
PRINT "lastwidget: " + gui.lastwidget ,winX+5, winY+220, TRUE
//a red close button bottom of the window
IF button(11,winX+5,winY+270,190,25,RGB(255,100,100),"Close this window") THEN showwin = NOT showwin
//a red close button top-right of the window
IF button(12,winX+200-16,winY,16,16,RGB(255,100,100),"X") THEN showwin = NOT showwin
ENDIF

IF showmenu1
LOCAL item = popupmenu(30, 10, 0, RGB(200,200,200), menustr1$[])
IF item = -1 THEN showmenu1=FALSE
IF item>0
settoast(menustr1$[item] + " MeniItem selected", 50)
showmenu1=FALSE
ENDIF
ENDIF
IF showmenu2
LOCAL item = popupmenu(30, 50, 0, RGB(200,200,200), menustr2$[])
IF item = -1 THEN showmenu2=FALSE
IF item>0
settoast(menustr2$[item] + " MeniItem selected", 50)
showmenu2=FALSE
ENDIF
ENDIF
IF toasttimer>0
toast(99, 320-LEN(toastmsg$, TRUE)/2, 440, RGB(60, 60, 60), toastmsg$, toasttimer)
DEC toasttimer
ENDIF

//finish the gui
gui.finish()
SHOWSCREEN
WEND

FUNCTION settoast:text$, timer
toastmsg$=text$
toasttimer=timer
ENDFUNCTION

// --------------------------------- //
// Immediate Mode GUI code start here
// Widget IDs must be unique!

FUNCTION getkey: k, BYREF dst
IF KEY(k)
IF dst<>-1
dst = 1
ENDIF
ELSE
dst = 0
ENDIF
ENDFUNCTION

TYPE UIState
//mouse
mousex
mousey
mouselclick
mouserclick
mousemclick
mousescroll

//keyboard
kbditem
keyentered$
keychar
tab
shift
ctrl
alt
up
down
left
right

//widget
prehotitem
hotitem
activeitem
lastwidget

//checking if mouse position is in specified region
FUNCTION inregion: x, y, w, h
IF (self.mousex<x OR self.mousey<y OR self.mousex>=x+w OR self.mousey>=y+h) THEN RETURN FALSE
RETURN TRUE
ENDFUNCTION

//prepare the IMGUI. Must call at the start of your gameloop
FUNCTION prepare:
//widget
self.hotitem = self.prehotitem
self.prehotitem = 0
//mouse
MOUSESTATE self.mousex, self.mousey, self.mouselclick, self.mouserclick
self.mousemclick = MOUSEAXIS(5)
self.mousescroll = MOUSEAXIS(2)
//keyboard
self.keyentered$ = INKEY$()
self.keychar = ASC(self.keyentered$)
getkey(15, self.tab)
getkey(42, self.shift)
getkey(29, self.ctrl)
getkey(56, self.alt)
getkey(200, self.up)
getkey(205, self.right)
getkey(208, self.down)
getkey(203, self.left)
//PRINT "key "+self.keyentered$+" "+ASC(self.keyentered$),360,5,TRUE
ENDFUNCTION

//finish the IMGUI. Must call at the end of your gameloop
FUNCTION finish:
//mouse
IF self.mouselclick = FALSE
self.activeitem = 0
ELSE
IF self.activeitem = 0 THEN self.activeitem = -1
ENDIF
//keyboard
IF gui.tab = 1
self.kbditem = 0
ENDIF
self.keyentered$ = ""
self.keychar = 0
ENDFUNCTION
ENDTYPE //TYPE IMGUI

//Button widget (clickable)
FUNCTION button: id, x, y, width, height, color, text$
LOCAL fw, fh
GETFONTSIZE fw, fh

IF gui.hotitem = id
IF (gui.activeitem = 0 AND gui.mouselclick)
gui.activeitem = id
ENDIF
ENDIF
IF gui.inregion(x,y,width,height)
gui.prehotitem = id
ENDIF
IF gui.kbditem = 0
gui.kbditem = id
ENDIF

IF gui.kbditem = id
DRAWRECT x-1, y-1, width+4, height+4, RGB(255, 0, 0)
ENDIF

DRAWRECT x+1, y+1, width, height, RGB(0, 0, 0)
IF gui.hotitem = id
IF gui.activeitem = id
DRAWRECT x+2, y+2, width, height, RGB(255, 255, 255)
ELSE
DRAWRECT x, y, width, height, RGB(255, 255, 255)
ENDIF
ELSE
DRAWRECT x, y, width, height, color
ENDIF

PRINT text$, x+5, y+(height-fh)/2, TRUE

//KBDITEM stb...
IF gui.kbditem = id
IF gui.tab = 1
gui.kbditem = 0
IF gui.shift THEN gui.kbditem = gui.lastwidget
gui.tab = -1
ENDIF
IF gui.keyentered$="\n" //ENTER
RETURN 1
ENDIF
ENDIF

gui.lastwidget = id

IF gui.mouselclick = 0 AND gui.hotitem = id AND gui.activeitem = id THEN RETURN 1

RETURN 0
ENDFUNCTION

//slider widget (vertical)
FUNCTION sliderV: id, x, y, height, maximum, BYREF value
STATIC marginH = 4
STATIC marginW = 4
LOCAL ypos = ((height-16) * value) / maximum

IF gui.hotitem = id
IF (gui.activeitem = 0 AND gui.mouselclick)
gui.activeitem = id
ENDIF
ENDIF
IF (gui.inregion(x+marginW,y+marginH, 16, height))
gui.prehotitem = id
ENDIF
IF gui.kbditem = 0
gui.kbditem = id
ENDIF

IF gui.kbditem = id
DRAWRECT x-1, y-1, 16+2, height+marginH*2+2, RGB(255, 0, 0)
ENDIF

DRAWRECT x, y, 16, height + marginH*2, RGB(50, 50, 50)

IF (gui.activeitem = id OR gui.hotitem = id)
DRAWRECT x+marginW, y+marginH + ypos, 16-marginW*2, 16, RGB(255,255,255)
ELSE
DRAWRECT x+marginW, y+marginH + ypos, 16-marginW*2, 16, RGB(200,200,200)
ENDIF

IF gui.kbditem = id
IF gui.tab = 1
gui.kbditem = 0
IF gui.shift THEN gui.kbditem = gui.lastwidget
gui.tab = -1
ENDIF
IF gui.up = 1
IF (value>0)
DEC value
RETURN 1
ENDIF
ENDIF
IF gui.down = 1
IF (value<maximum)
INC value
RETURN 1
ENDIF
ENDIF
ENDIF

gui.lastwidget = id

IF gui.activeitem = id
LOCAL mousepos = gui.mousey - (y+marginH)
IF (mousepos < 0) THEN mousepos = 0
IF (mousepos > height) THEN mousepos = height
LOCAL v = (mousepos*maximum) / height
IF (v <> value)
value = v
RETURN 1
ENDIF
ENDIF

RETURN 0
ENDFUNCTION

//slider widget (vertical)
FUNCTION sliderH: id, x, y, width, maximum, BYREF value
STATIC marginH = 4
STATIC marginW = 4
LOCAL xpos = ((width-16) * value) / maximum

IF gui.hotitem = id
IF (gui.activeitem = 0 AND gui.mouselclick)
gui.activeitem = id
ENDIF
ENDIF
IF (gui.inregion(x+marginH,y+marginW, width, 16))
gui.prehotitem = id
ENDIF
IF gui.kbditem = 0
gui.kbditem = id
ENDIF

IF gui.kbditem = id
DRAWRECT x-1, y-1, width+marginH*2+2, 16+2, RGB(255, 0, 0)
ENDIF

DRAWRECT x, y, width + marginH*2, 16, RGB(50, 50, 50)

IF (gui.activeitem = id OR gui.hotitem = id)
DRAWRECT x+marginW + xpos, y+marginH, 16, 16-marginW*2, RGB(255,255,255)
ELSE
DRAWRECT x+marginW + xpos, y+marginH, 16, 16-marginW*2, RGB(200,200,200)
ENDIF

IF gui.kbditem = id
IF gui.tab = 1
gui.kbditem = 0
IF gui.shift THEN gui.kbditem = gui.lastwidget
gui.tab = -1
ENDIF
IF gui.left = 1
IF (value>0)
DEC value
RETURN 1
ENDIF
ENDIF
IF gui.right = 1
IF (value<maximum)
INC value
RETURN 1
ENDIF
ENDIF
ENDIF

gui.lastwidget = id

IF gui.activeitem = id
LOCAL mousepos = gui.mousex - (x+marginH)
IF (mousepos < 0) THEN mousepos = 0
IF (mousepos > width) THEN mousepos = width
LOCAL v = (mousepos*maximum) / width
IF (v <> value)
value = v
RETURN 1
ENDIF
ENDIF

RETURN 0
ENDFUNCTION


//textfield widget (could type text in it)
FUNCTION textfield: id, x, y, width, BYREF buffer$

LOCAL length = LEN(buffer$)
LOCAL changed = 0
LOCAL fw, fh
GETFONTSIZE fw, fh

IF gui.hotitem = id
IF (gui.activeitem = 0 AND gui.mouselclick)
gui.activeitem = id
ENDIF
ENDIF
IF (gui.inregion(x-4,y-4, width*fw+8, fh+8))
gui.prehotitem = id
ENDIF
IF gui.kbditem = 0
gui.kbditem = id
ENDIF

IF gui.kbditem = id
DRAWRECT x-6, y-6, width*fw+12, fh+12, RGB(255,0,0)
ENDIF

IF (gui.activeitem = id OR gui.hotitem = id)
DRAWRECT x-4, y-4, width*fw+8, fh+8, RGB(200,200,200)
ELSE
DRAWRECT x-4, y-4, width*fw+8, fh+8, RGB(100,100,100)
ENDIF

IF gui.kbditem = id AND MOD(GETTIMERALL(),1000) < 500
PRINT buffer$+"_", x, y
ELSE
PRINT buffer$, x, y
ENDIF

IF gui.kbditem = id
IF gui.tab = 1
gui.kbditem = 0
IF gui.shift THEN gui.kbditem = gui.lastwidget
gui.tab = -1
ENDIF
IF ASC(gui.keyentered$) = 8 AND length > 0
buffer$ = MID$(buffer$, 0, length-1)
changed = 1
ENDIF
ENDIF
IF (ASC(gui.keyentered$)>=32 AND ASC(gui.keyentered$)<=127 AND length<width)
buffer$ = buffer$ + gui.keyentered$
changed = 1
ENDIF

IF (gui.mouselclick=FALSE AND gui.hotitem = id AND gui.activeitem = id)
gui.kbditem = id
ENDIF

gui.lastwidget = id

RETURN changed

ENDFUNCTION

//window widget (only a rectangle, with draggable header)
FUNCTION window: id, BYREF x, BYREF y, width, height, color, name$
STATIC headerH = 16
LOCAL changed = 0
LOCAL fw, fh
GETFONTSIZE fw, fh

IF gui.hotitem = id
IF (gui.activeitem = 0 AND gui.mouselclick)
gui.activeitem = id
ENDIF
ENDIF

IF (gui.inregion(x, y, width, height))
gui.prehotitem = -2 //window area
ENDIF
IF (gui.inregion(x, y, width, headerH))
gui.prehotitem = id //header
ENDIF

//move window
IF gui.mouselclick = 1 AND gui.activeitem = id
x = gui.mousex-width/2
y = gui.mousey-headerH/2
changed = 1
ENDIF

IF (gui.activeitem = id OR gui.hotitem = id)
DRAWRECT x, y, width, headerH, RGB(255, 255, 255)
ELSE
DRAWRECT x, y, width, headerH, color
ENDIF

PRINT name$, x+5, y+(headerH-fh)/2, TRUE

LOCAL namelen = LEN(name$, TRUE)
FOR i=1 TO 4
DRAWLINE x + 10 + namelen, y+headerH*i/4.0, x + width - 5, y+headerH*i/4.0, RGB(255, 255, 255)
NEXT

IF (gui.activeitem = id OR gui.hotitem = id)
DRAWRECT x, y+headerH, width, height-headerH, color //RGB(255,255,255)
ELSE
DRAWRECT x, y+headerH, width, height-headerH, color
ENDIF

RETURN changed
ENDFUNCTION

//popupmenu widget (only active while hot, return -1 if )
FUNCTION popupmenu: id, x, y, color, menuitems$[]
LOCAL fw, fh
GETFONTSIZE fw, fh
LOCAL width=0
LOCAL height=0
LOCAL numitems=0
LOCAL item=0
FOREACH mi$ IN menuitems$[]
width = MAX(width, LEN(mi$, TRUE))
IF mi$<>"---" THEN INC numitems
NEXT
height = numitems*fh
INC width, 10

IF (gui.inregion(x, y+fh, width, height-fh) OR gui.inregion(x, y, LEN(menuitems$[0],TRUE)+10, fh))
gui.prehotitem = id
gui.hotitem = id
IF (gui.activeitem = 0)
gui.activeitem = id
ENDIF
ENDIF
IF gui.hotitem<>id AND gui.mouselclick
RETURN -1
ENDIF

DRAWRECT x, y, LEN(menuitems$[0],TRUE)+10, fh, 0xffffff-color
DRAWRECT x, y+fh, width, height-fh, color
IF (gui.hotitem = id)
item = INTEGER((gui.mousey - y) / fh)
IF item>0
DRAWRECT x, y+item*fh, width, fh, RGB(255, 255, 255)
ENDIF
ENDIF

LOCAL ypos=0
FOREACH mi$ IN menuitems$[]
IF mi$<>"---"
PRINT mi$, x+5, y+ypos, TRUE
INC ypos, fh
ELSE
DRAWLINE x, y+ypos, x+width, y+ypos, 0
ENDIF
NEXT

IF (item>0 AND gui.activeitem = id AND gui.mouselclick)
numitems=0
LOCAL i=0
FOREACH mi$ IN menuitems$[]
IF mi$<>"---"
IF item=numitems THEN RETURN i
INC numitems
ENDIF
INC i
NEXT
ENDIF
RETURN 0
ENDFUNCTION

//toads widget (show a message and fade away after a period)
FUNCTION toast: id, x, y, color, text$, BYREF timer
LOCAL fw, fh
GETFONTSIZE fw, fh
LOCAL alpha=timer/10.0
IF alpha<0.1 THEN RETURN -1
IF alpha>1.0 THEN alpha = 0.8
LOCAL width = LEN(text$, TRUE)

IF gui.hotitem = id
IF (gui.activeitem = 0 AND gui.mouselclick)
gui.activeitem = id
timer = 0
ENDIF
ENDIF

IF (gui.inregion(x-4, y-4, width+8, fh+8))
gui.prehotitem = id
ENDIF

ALPHAMODE -alpha
DRAWRECT x-4, y-4, width+8, fh+8, color
PRINT text$, x,y, TRUE
ALPHAMODE 0
ENDFUNCTION

Also you can download the whole project.

EDIT:
- added SliderH (horizontal slider)
- added PopupMenu
- added Toaster (fade away message)

[attachment deleted by admin]

12
2D-snippets / Mirroring a Sprite
« on: 2008-Mar-22 »
Hi!
I have a number of sprites, loaded by LOADANIM
how can I draw a mirrored sprite?
I tried STRETCHANIM with -1, 1 but it seems that stretch values less than 0 -> no sprite visible :(

Please, I need very fast ansver! Or I have to draw all the mirrored sprites :)

13
FAQ / changing variable's value via FUNCTION
« on: 2008-Mar-07 »
Code: (glbasic) [Select]
value=1

PRINT value,10,10

foo(value)

PRINT value,10,40

SHOWSCREEN
MOUSEWAIT

FUNCTION foo: val
  val=2
ENDFUNCTION
result:
1
1

How can I change a variable's value which i got as a parameter?

14
Bug Reports / '\' and '/' in the filenames
« on: 2008-Mar-04 »
glBasic can't find the file if I use 'gfx\img.bmp' only if i use '/' like 'gfx/img.bmp'
This is only in my machine? I'm using Win XP pro

15
Bug Reports / Defining DIM outside from main
« on: 2008-Mar-04 »
if you defining DIM outside from MAIN (I mean from an include gpas file or after some function) then you get strange compiler messages like '{' not expected in ...cpp and a message to please copy these errorcodes to the glBasic forums.
The preprocessor sould be fixed to prevent .cpp making if DIM defined in the wrong place

Pages: [1] 2