Dark Bit Factory & Gravity
PROGRAMMING => Freebasic => Topic started by: Merick on May 28, 2007
-
I'm relatively new to programming, and for the past couple of months I've been scripting with lua (mostly with the PSP Lua Player) Can anyone tell me how to use lua with FB? Basically, I'd like to know if it would be possible to use pure lua code for the main part of a program, and revert to FB code only for things like graphics.
-
Very good question Merick, Freebasic is very good at being made to work with other libs etc.
I've never come across Lua before, however there are several people here who are interested in Console Homebrew.
Your question seems to be the other way around though, it would seem that you are interested in developing for the PC with the Lua scripting language as opposed to using FB stuff on your Psp.
In any case, I think you've come to the right place, my guess is that Jim or Relsoft or Nino will be able to point you in the right direction. Console homebrew is not my own strength, I know nothing of it, Graphics in FB is something I know about and if you have any specific questions on that I will be happy to help.
-
It's been a long time, and I didn't really have the patience to really sit down and work out how everything worked but at one time I did mess around with QB a little bit. It might take a bit to refresh my memory, but the stuff in FB that's based on the original QB codes should come pretty easy. However, back then I only used the standard QB code and never got into using libraries or anything like that.
The main reason I want to use lua with FB is because of the way lua uses variables and tables, and possibly the io functions. As I said it's been a while, but from what I can remember of QB, the lua functions for reading from a file (or text files at least) are a lot easier to use.
-
i never sat down and learned lua on the psp but i did have a wee play.
do you have a small lua example you could post?
im sure we could show you how to get it up and running in fb, it is possible im sure.
-
Here's something I was working on for the Lua Player. Since the lua player currently only has 3 functions for 2d graphics - points, lines, and rectangles (you can do more with the 3d gu, but that takes a bit more work to figure out), I decided to make a small graphics library for drawing polygons. These functions take some arguments and use them to calculate the coordinates for the various points on a polygon, then use the lua player's drawline function to draw them out. polylib.lua is the library itself, polytest.lua is a small test program I made to show off each of the functions in the lib. I know I'll have to change the graphics and input functions over to something compatible with FB, but that shouldn't be a problem as long as I can somehow get FB to use lua's tables and metatables.
function list:
draw_poly(x, y, radius, rotation, sides, sides_to_draw, closed, color)
draws a regular polygon (i.e. all sides are the same length)
x,y - the center point of the poly
radius - distance from the center point to each corner of the poly
rotation - angle in degrees in which to rotate the poly around it's center
sides - number of sides the poly has
sides_to_draw - number of sides that will actually be drawn
closed - if true and sides_to_draw is less than sides then it will draw a line connecting the end points
color - color to draw the poly
function draw_tri(x, y, side1, side2, angle, rotation, color)
draws a triangle rotated around the start point with two sides of the specified length at the given angle
draw_para(x,y, side1, side2, angle, rotation, color)
draws a parallelogram rotated around the start point, side1 and side2 are the lengths of each pair of sides, angle is the angle of the two sides that meet at the start point
draw_free(x, y, ptable, scale, color)
this one lets you draw free-form polys
ptable is basically a table with a list of coordinates relative to x,y. This example table has the coords to draw an outline of an x:
polytable = {
{x = 1, y = 0},
{x = 0, y = 1},
{x = 1, y = 2},
{x = 0, y = 3},
{x = 1, y = 4},
{x = 2, y = 3},
{x = 3, y = 4},
{x = 4, y = 3},
{x = 3, y = 2},
{x = 4, y = 1},
{x = 3, y = 0},
{x = 2, y = 1},
{x = 1, y = 0},
}
"scale" will let you change the size the poly is drawn at, set it to 1 for no change
-- advanced functions
polymorph.new(poly_table, frames, delay)
creates a new polymorph object
poly_table is a table that contains 2 of the same type of tables used for draw_free. Although the 2 poly tables don't have to be the exact same size, the smaller table must have at least half the number of points as the larger table.
frames is the number of animation frames you want it to take to morph one poly into the other,
delay is the delay between frames.
polymorph:start()
starts the animation timer
polymorph:set_auto(auto_type, wait)
sets up the automatic switching, auto_type is a string value:
"reverse" -sets it to auto-reverse the animation
"reset" -sets it to auto-reset to the first frame of the animation
"stop" -stops the animation timer
wait is a number value, it sets how long to wait before starting the next animation loop. If left out it will continue to use the previous wait value (default is 0)
polymorph:draw(x, y, scale, color)
draws the polymorph animation
draw_adv(x, y, ptable, scale, color)
this is an advanced version of the draw_free function, by adding a few things to the poly table you can change the way it gets drawn:
poly1 = {
{color = green, x = 1, y = 0},
{x = 0, y = 1},
{x = 1, y = 2},
{x = 2, y = 1},
{x = 1, y = 0},
{command = "break"},
{color = red, x = 1, y = 3},
{x = 0, y = 4},
{x = 1, y = 5},
{x = 2, y = 4},
{x = 1, y = 3},
{command = "break"},
{color = blue, x = 4, y = 0},
{x = 3, y = 1},
{x = 4, y = 2},
{x = 5, y = 1},
{x = 4, y = 0},
{command = "break"},
{color = white, x = 4, y = 3},
{x = 3, y = 4},
{x = 4, y = 5},
{x = 5, y = 4},
{x = 4, y = 3},
}
putting color = newcolor in any index will change the current drawing color. Although you can still put in a color when calling the function, it will be over-ridden by any color codes in the poly table
putting in command = "break" will stop the function from drawing a line between the points before and after the command
-
ill have a look into running lua stuff in fb for you but im sure someone else here will come with an answer for you as i dont really know lua that well.
-
I think I got part of it. If I put this in:
option explicit
#include once "Lua/lua.bi"
#include once "Lua/luauxlib.bi"
#include once "Lua/lualib.bi"
dim L as lua_State ptr
L = lua_open( ) 'create a lua state
luaopen_base(L) 'opens the basic library
luaopen_table(L) 'opens the table library
luaopen_io(L) 'opens the I/O library
luaopen_string(L) 'opens the string lib.
luaopen_math(L) 'opens the math lib.
then I can use lua_dofile(L, "script.lua") to run lua code from a file. Of course, in order to use graphics I'll have to make some wrapper functions in the main .bas file to let me call the FB graphics functions from the lua script
-
It will be sorted when the libs guys get on here later if you don't fix it first :)
-
Heh, with help from the lua example that comes with FB, I think I've got it figured out how to make the function wrappers. It's only a start, but this example will let you use the screen function to set the screen mode from inside a lua dofile:
#include once "Lua/lua.bi"
#include once "Lua/luauxlib.bi"
#include once "Lua/lualib.bi"
function scr cdecl (byval L as lua_State ptr) as integer
' get the number of parameters passed on the virtual stack
' by the calling lua code
dim pars(1 to 5) as integer
numpar = lua_gettop( L )
for i = 1 to numpar
' peek the specified vs element
pars(i) = lua_tonumber( L, i )
next i
if numpar = 1 then
screen pars(1)
elseif numpar = 2 then
screen pars(1),pars(2)
elseif numpar = 3 then
screen pars(1),pars(2),pars(3)
elseif numpar = 4 then
screen pars(1),pars(2),pars(3),pars(4)
elseif numpar = 5 then
screen pars(1),pars(2),pars(3),pars(4),pars(5)
end if
end function
dim L as lua_State ptr
L = lua_open( ) 'create a lua state
luaopen_base(L) 'opens the basic library
luaopen_table(L) 'opens the table library
luaopen_io(L) 'opens the I/O library
luaopen_string(L) 'opens the string lib.
luaopen_math(L) 'opens the math lib.
lua_register( L, "screen", @scr )
' execute the lua script from a file
lua_dofile( L, "test.lua" )
lua_close( L )
print "finished! press any key"
Sleep
End
one question though, in FB, which is more efficient - the if/then/elseif statments I'm useing now, or the select case statements?
-
Select case is generally better programming practice and allows you to use case else to have a default value too.
I use both, generally I use select case when there are several choices that would be difficult to read if I used a load of if thens..
I don't think it makes much difference in terms of overhead.
-
Good work in getting it going. Lua's a really powerful script language which is used in lots of applications and games to control things like movie playback or AI. I've always thought we should be using it at work to replace some of the C code we write now. Lots of advantages - like you don't have to compile it, it's easy to understand, you can extend it in lots of ways...
It'll be nice to see some examples of this in action, since I've never had time to research it properly. K+ Merick!
Jim
-
Well, with what I've done so far you can run a script in pure lua, but pure lua doesn't really have anything for getting user input, and (except for the file io functions) the only output is through the print statement, which I've found will only print to the console window and not a graphics window. Although I've made a start on some wrappers for some of the more simple functions, I don't really know enough yet to do some of the more complex stuff, like freetype or ogl.
-
Here's what I have so far:
#include once "Lua/lua.bi"
#include once "Lua/luauxlib.bi"
#include once "Lua/lualib.bi"
function scr (byval L as lua_State ptr) as integer
numpar = lua_gettop( L )
select case as const numpar
case 1
screen lua_tonumber(L, 1)
case 2
screen lua_tonumber(L, 1),lua_tonumber(L, 2),
case 3
screen lua_tonumber(L, 1),lua_tonumber(L, 2),lua_tonumber(L, 3),
case 4
screen lua_tonumber(L, 1),lua_tonumber(L, 2),lua_tonumber(L, 3),lua_tonumber(L, 4),
case 5
screen lua_tonumber(L, 1),lua_tonumber(L, 2),lua_tonumber(L, 3),lua_tonumber(L, 4),lua_tonumber(L, 5)
end select
end function
function sres (byval L as lua_State ptr) as integer
numpar = lua_gettop(L)
select case as const numpar
case 2
screenres lua_tonumber(L, 1),lua_tonumber(L, 2),
case 3
screenres lua_tonumber(L, 1),lua_tonumber(L, 2),lua_tonumber(L, 3),
case 4
screenres lua_tonumber(L, 1),lua_tonumber(L, 2),lua_tonumber(L, 3),lua_tonumber(L, 4),
case 5
screenres lua_tonumber(L, 1),lua_tonumber(L, 2),lua_tonumber(L, 3),lua_tonumber(L, 4),lua_tonumber(L, 5)
case 6
screenres lua_tonumber(L, 1),lua_tonumber(L, 2),lua_tonumber(L, 3),lua_tonumber(L, 4),lua_tonumber(L, 5),lua_tonumber(L, 6)
end select
end function
function scopy (byval L as lua_State ptr) as integer
numpar = lua_gettop( L )
select case as const numpar
case 0
screencopy
case 1
screencopy lua_tonumber(L, 1)
case 2
screencopy lua_tonumber(L, 1),lua_tonumber(L, 2)
end select
end function
function sset (byval L as lua_State ptr) as integer
numpar = lua_gettop(L)
select case as const numpar
case 0
screenset
case 1
screenset lua_tonumber(L, 1)
case 2
screenset lua_tonumber(L, 1),lua_tonumber(L, 2)
end select
end function
function vsync
screensync
end function
function ikey (byval L as lua_State ptr) as integer
lua_pushstring( L, inkey$)
ikey = 1
end function
function newcolor (byval L as lua_State ptr) as integer
numpar = lua_gettop(L)
select case as const numpar
case 3
lua_pushvalue(L, rgb(lua_tonumber(L, 1),lua_tonumber(L, 2),lua_tonumber(L, 3)))
case 4
lua_pushvalue(L, rgba(lua_tonumber(L, 1),lua_tonumber(L, 2),lua_tonumber(L, 3),lua_tonumber(L, 4)))
end select
newcolor = 1
end function
function sl (byval L as lua_State ptr) as integer
numpar = lua_gettop(L)
select case as const numpar
case 0
sleep
case 1
sleep lua_tonumber(L,1)
end select
end function
dim L as lua_State ptr
L = lua_open( ) 'create a lua state
luaopen_base(L) 'opens the basic library
luaopen_table(L) 'opens the table library
luaopen_io(L) 'opens the I/O library
luaopen_string(L) 'opens the string lib.
luaopen_math(L) 'opens the math lib.
' register wrapper functions for access from a lua script
lua_register( L, "Screen", @scr)
lua_register( L, "SRes", @sres)
lua_register( L, "SCopy", @scopy)
lua_register( L, "Sset", @sset)
lua_register( L, "Vsync", @vsync)
lua_register( L, "InKey", @ikey)
lua_register( L, "Sleep", @sl)
lua_register( L, "NewColor", @newcolor)
' execute the lua script from a file
lua_dofile( L, "test.lua" )
lua_close( L )
print "finished! press any key"
Sleep
End
most of these functions work ok, but when I try to use the newcolor function from the lua script the program crashes, can anyone tell me why?
here's how I'm calling it from the test.lua script:
Screen(13,32)
a= NewColor(100,100,100,100)
print(a)
-
Thanks to Tigra on the official FB forums I've been able to fix the problems I was having with the NewColor and sPrint functions.
Here's a new version of the interpreter, it includes a small lua script that uses the NewColor function and the dLine function, which is an incomplete but working wrapper for the standard line drawing function
*edit* link removed because I just uploaded a new version
-
thanks Merick, i for one am keeping a close eye on this as im very intrested. i think its really great what your doing as not a lot of people know this stuff!
so keep it going and ill be happy for anything else you can show us, great stuff mate k+
heh just had a play around with it there and i see how it works! can i maybe add a triangle function and a rectangle to it just to see if i can ill post up whatever i do.
-
Actually, I've already added the rectangle function. Just put "B" or "BF" as the last argument for dLine:
dLine(10,10, 100, 100, color) -- will draw a line
dLine(10,10, 100, 100, color, "B") --will draw a rectangle
dLine(10,10, 100, 100, color, "BF") --will draw a filled rectangle
Also, with what I've done so far, I've been able to convert most of my psp Lua Player polylib (which already has a function for triangles), the only thing that doesn't work yet is the polymorph function
http://www.mediafire.com/?2yq0jz5lmbh (http://www.mediafire.com/?2yq0jz5lmbh)
oh, in case you don't already know, in a lua script you use -- instead of ' for comments
-
cool cheers mate!
are types and arrays supported in lua?
-edit i see from the new file you posted that arrays are supported and also embeded functions this is really powerfull a lot more so than i first thought
-
In lua, you have tables. Tables are basically types and arrays rolled into one construct. With regular variables, you don't need to declare them before you use them, and you don't need to assign them as a specific type (integer, string, etc..) because lua has automatic typing. Tables are a little different, before you can use one you do need to declare it, like this:
a = {}
this creates an empty table, but you can also put in some values when you declare it:
a = {1, 10}
this puts the number 1 at position 1, and the number 10 at position 2. To access each element, you would use it like this: a[1] or a[2] etc.. There is no limit to the number of elements you can put in a table. If you want each position to have more than one value, then you can do it like this:
a = {
{1, 10},
{3,"hello"},
}
this is the same as
a = {}
a[1] = {1, 10}
a[2] = {3,"hello"}
in this example, a[1][2] = 10, and a[2][2] = "hello"
That's right, you can mix types in the same table.
one more example before I have to leave for work
a = {
{x = 10, y = 20},
{x = 13, y = 17}
}
In this example, if you were using this as a list of screen coordinates you would access the elements like this:
dLine(a[1].x, a[1].y, a[2].x, a[2].y, color)
The ability to use tables like this is one of the reasons I love working with lua
Here's a link to a page with some tutorials on lua:
http://lua-users.org/wiki/TutorialDirectory
-
cheers mate, here is a mess around by me its now using tinyptc_ext for drawing its very buggy and ive managed to break draw_poly somehow but its very smooth for animation and it has vsync built in it also lets you switch between full screen and a window.
this stuff really is cool its kept me ocupied for a few hours so far and i fully intent to keep going.
<edit oops i had forgot boundary checking in the draw line function>
if the genioline function is replaced with this.
Sub GenioLine( byval x1 as double ,byval y1 as double ,byval x2 as double ,byval y2 as double , byval Col As Integer )
dim i, deltax, deltay, numpixels as integer
dim d, dinc1, dinc2 as integer
dim x, xinc1, xinc2 as integer
dim y, yinc1, yinc2 as integer
'calculate deltaX and deltaY
deltax = abs(int(x2) - int(x1))
deltay = abs(int(y2) - int(y1))
'initialize
if(deltax >= deltay) then
'If x is independent variable
numpixels = deltax + 1
d = (2 * deltay) - deltax
dinc1 = deltay shl 1
dinc2 = (deltay - deltax) shl 1
xinc1 = 1
xinc2 = 1
yinc1 = 0
yinc2 = 1
else
'if y is independent variable
numpixels = deltay + 1
d = ( 2 * deltax ) - deltay
dinc1 = deltax shl 1
dinc2 = ( deltax - deltay ) shl 1
xinc1 = 0
xinc2 = 1
yinc1 = 1
yinc2 = 1
endif
'move the right direction
if ( int(x1) > int(x2) ) then
xinc1 = -xinc1
xinc2 = -xinc2
endif
if ( int(y1) > int(y2) ) then
yinc1 = -yinc1
yinc2 = -yinc2
endif
x = int(x1)
y = int(y1)
'draw the pixels
for i = 1 to numpixels
if y<640 and y>0 then
if x<480 and x>0 then
Buffer( y*ScrWidth+x ) = Col
endif
endif
if ( d < 0 ) then
d = d + dinc1
x = x + xinc1
y = y + yinc1
else
d = d + dinc2
x = x + xinc2
y = y + yinc2
endif
next
End Sub
then draw_poly works fine
-
Is tinyptc better than using the standard FB drawing routines? And since I don't know anything about it, Would you be willing be willing to make a header file with wrappers for all of it's functions?
-
Here's a new version. In this one, I've split the graphic and input/system functions into two separate header files, and I've also renamed most (but not all) of them so that the lua versions are spelled the same as the original Fb version. In addition, I've also created a system.lua file. This script will be run before the main.lua and it will contain some useful functions written mostly in lua code. I just started on it, so right now it only has an advanced timer function that uses the lua metatable system. To see how this works, check the comments in the file itself. I did this function first because with it I was able to get the polymorph function in polylib working.
(of course, if you don't want to use the functions in the system.lua file you could always replace it with one that has your own functions, or even remove the lua_dofile("system.lua") from the main .bas before compiling)
http://www.mediafire.com/?4qxxtzyvfzh (http://www.mediafire.com/?4qxxtzyvfzh)
-
its really taking shape!! i will maybe try a little something with it soon.
oh one thing mate that you probably already know but if you cdecl your fb wrapper functions it will get rid of a lot of warnings when registering them.
-
actually, I didn't know about that
**
Using one of the examples included with FB as a base, I've started working on a header for using the FreeType libs. I was able to get the font loader working (or at least, there were no errors when I tried using it), but when I tried adding the font printing function from the example the compiler gave me an error about a pointer and I'm not sure exactly what's wrong as I've never tried using the freetype library before
put this in a file named "lua freetype.bi" and put an include for it in "interpreter.bas"(make sure you put it after the lua open commands)
'' Lua Freetype header, modified from
'' FreeType2 library test, by jofers (spam[at]betterwebber.com)
''
#include "freetype2/freetype.bi"
' Alpha blending
#define FT_MASK_RB_32 &h00FF00FF
#define FT_MASK_G_32 &h0000FF00
' DataStructure to make it easy
Type FT_Var
ErrorMsg As FT_Error
Library As FT_Library
PixelSize As Integer
End Type
Dim Shared FT_Var As FT_Var
Declare sub DrawGlyph(ByVal FontFT As FT_Face, ByVal x As Integer, ByVal y As Integer, ByVal Clr As UInteger)
' Initialize FreeType
' -------------------
FT_Var.ErrorMsg = FT_Init_FreeType(@FT_Var.Library)
If FT_Var.ErrorMsg Then
Print "Could not load library"
End
End If
' Load a font
' -----------
Function loadfont cdecl (byval L as lua_State ptr) As Integer
args = lua_gettop(L)
select case as const args
case 0
return luaL_error(L, "you must enter a font file")
case 1
if lua_isstring( L, 1) then
Dim Face As FT_Face
Dim ErrorMsg As FT_Error
ErrorMsg = FT_New_Face(FT_Var.Library, *lua_tostring(L,1), 0, @Face )
If ErrorMsg Then return luaL_error(L, "can't find font file")
lua_pushnumber(L, CInt(Face))
end if
case else
return luaL_error(L, "LoadFont takes only one argument")
end select
GetFont = 1
End Function
lua_register( L, "LoadFont", @loadfont)
' Print Text
' ----------
Function PrintFT cdecl (byval L as lua_State ptr) As Integer
args = lua_gettop(L)
select case as const args
case 6
x = lua_tonumber(L,1)
y = lua_tonumber(L,2)
Font = lua_tonumber(L,3)
Size = lua_tonumber(L,4)
Clr = lua_tonumber(L,5)
Text = *lua_tostring(L,6)
Dim ErrorMsg As FT_Error
Dim FontFT As FT_Face
Dim GlyphIndex As FT_UInt
Dim Slot As FT_GlyphSlot
Dim PenX As Integer
Dim PenY As Integer
Dim i As Integer
' Get rid of any alpha channel in AlphaClr
Clr = Clr Shl 8 Shr 8
' Convert font handle
FontFT = Cast(FT_Face, Font)
' Set font size
ErrorMsg = FT_Set_Pixel_Sizes(FontFT, Size, Size)
FT_Var.PixelSize = Size
If ErrorMsg Then Return 0
' Draw each character
Slot = FontFT->Glyph
PenX = x
PenY = y
For i = 0 To Len(Text) - 1
' Load character index
GlyphIndex = FT_Get_Char_Index(FontFT, Text[i])
' Load character glyph
ErrorMsg = FT_Load_Glyph(FontFT, GlyphIndex, FT_LOAD_DEFAULT)
If ErrorMsg Then Return 0
' Render glyph
ErrorMsg = FT_Render_Glyph(FontFT->Glyph, FT_RENDER_MODE_NORMAL)
If ErrorMsg Then Return 0
' Check clipping
If (PenX + FontFT->Glyph->Bitmap_Left + FontFT->Glyph->Bitmap.Width) > 320 Then Exit For
If (PenY - FontFT->Glyph->Bitmap_Top + FontFT->Glyph->Bitmap.Rows) > 240 Then Exit For
If (PenX + FontFT->Glyph->Bitmap_Left) < 0 Then Exit For
If (PenY - FontFT->Glyph->Bitmap_Top) < 0 Then Exit For
' Set pixels
DrawGlyph FontFT, PenX + FontFT->Glyph->Bitmap_Left, PenY - FontFT->Glyph->Bitmap_Top, Clr
PenX += Slot->Advance.x Shr 6
Next i
case else
return luaL_error(L, "wrong number of arguments")
end select
End Function
lua_register( L, "FontPrint", @PrintFT)
sub DrawGlyph(ByVal FontFT As FT_Face, ByVal x As Integer, ByVal y As Integer, ByVal Clr As UInteger)
Dim BitmapFT As FT_Bitmap
Dim BitmapPtr As UByte Ptr
Dim DestPtr As UInteger Ptr
Dim BitmapHgt As Integer
Dim BitmapWid As Integer
Dim BitmapPitch As Integer
Dim Src_RB As UInteger
Dim Src_G As UInteger
Dim Dst_RB As UInteger
Dim Dst_G As UInteger
Dim Dst_Color As UInteger
Dim Alpha As Integer
BitmapFT = FontFT->Glyph->Bitmap
BitmapPtr = BitmapFT.Buffer
BitmapWid = BitmapFT.Width
BitmapHgt = BitmapFT.Rows
BitmapPitch = 320 - BitmapFT.Width
DestPtr = Cast(UInteger Ptr, ScreenPtr) + (y * 320) + x
Do While BitmapHgt
Do While BitmapWid
' Thanks, GfxLib
Src_RB = Clr And FT_MASK_RB_32
Src_G = Clr And FT_MASK_G_32
Dst_Color = *DestPtr
Alpha = *BitmapPtr
Dst_RB = Dst_Color And FT_MASK_RB_32
Dst_G = Dst_Color And FT_MASK_G_32
Src_RB = ((Src_RB - Dst_RB) * Alpha) Shr 8
Src_G = ((Src_G - Dst_G) * Alpha) Shr 8
*DestPtr = ((Dst_RB + Src_RB) And FT_MASK_RB_32) Or ((Dst_G + Src_G) And FT_MASK_G_32)
DestPtr += 1
BitmapPtr += 1
BitmapWid -= 1
Loop
BitmapWid = BitmapFT.Width
BitmapHgt -= 1
DestPtr += BitmapPitch
Loop
End sub
to load a font in lua, use something like this:
name = LoadFont("path/filename.ttf")
name can be any variable name, the path/filename can be either a quoted string, or a string variable with the filename in it. If the font is in the same folder as the executable you can leave out the path part
to print with a font, use this:
FontPrint(x, y, font, size, color, text)
where font is the variable name that you used with the LoadFont function, and color is a color made with the NewColor function
-
hmm, I think the error is because the font loader isn't working right and so the wrong data type is getting passed to the font print function
*edit*
Got it paritally working. The FontPrint function will now print the text, however if you set the screen resolution to an odd size it comes out as garbage. Also, I've found that using some fonts won't print the letters, just boxes.
'' Lua Freetype header, modified from
'' FreeType2 library test, by jofers (spam[at]betterwebber.com)
''
#include "freetype2/freetype.bi"
' Alpha blending
#define FT_MASK_RB_32 &h00FF00FF
#define FT_MASK_G_32 &h0000FF00
' DataStructure to make it easy
Type FT_Var
ErrorMsg As FT_Error
Library As FT_Library
PixelSize As Integer
End Type
Dim Shared FT_Var As FT_Var
Declare sub DrawGlyph(ByVal FontFT As FT_Face, ByVal x As Integer, ByVal y As Integer, ByVal Clr As UInteger)
Declare Function PrintFT(ByVal x As Integer, ByVal y As Integer, ByVal Text As String, ByVal Font As Integer, ByVal Size As Integer = 14, ByVal Clr As UInteger = Rgb(255, 255, 255))
' Initialize FreeType
' -------------------
FT_Var.ErrorMsg = FT_Init_FreeType(@FT_Var.Library)
If FT_Var.ErrorMsg Then
Print "Could not load library"
End
End If
' Load a font
' -----------
Function loadfont cdecl (byval L as lua_State ptr) As Integer
args = lua_gettop(L)
select case as const args
case 0
return luaL_error(L, "you must enter a font file")
case 1
if lua_isstring( L, 1) then
Dim Face As FT_Face
Dim ErrorMsg As FT_Error
ErrorMsg = FT_New_Face(FT_Var.Library, *lua_tostring(L,1), 0, @Face )
If ErrorMsg Then return luaL_error(L, "can't find font file")
lua_pushnumber(L, CInt(Face))
end if
case else
return luaL_error(L, "LoadFont takes only one argument")
end select
loadfont = 1
End Function
lua_register( L, "LoadFont", @loadfont)
function FontPrint cdecl (byval L as lua_State ptr) As Integer
args = lua_gettop(L)
select case as const args
case 6
if lua_isnumber(L,1) and lua_isnumber(L,2) and lua_isnumber(L,3) and lua_isnumber(L,4) and lua_isnumber(L,5) and lua_isstring(L,6) then
PrintFT lua_tonumber(L,1), lua_tonumber(L,2), *lua_tostring(L,6), lua_tonumber(L,3), lua_tonumber(L,4), lua_tonumber(L,5)
else
return luaL_error(L, "an argument was incorrect")
end if
case else
return luaL_error(L, "wrong number of arguments")
end select
'PrintFT Rnd * 200, Rnd * 180 + 20, "Hello World!", ArialFont, Rnd * 22 + 10, Rgb(Rnd * 255, Rnd * 255, Rnd * 255)
end function
lua_register( L, "FontPrint", @FontPrint)
Function PrintFT(ByVal x As Integer, ByVal y As Integer, ByVal Text As String, ByVal Font As Integer, ByVal Size As Integer = 14, ByVal Clr As UInteger = Rgb(255, 255, 255))
Dim ErrorMsg As FT_Error
Dim FontFT As FT_Face
Dim GlyphIndex As FT_UInt
Dim Slot As FT_GlyphSlot
Dim PenX As Integer
Dim PenY As Integer
Dim i As Integer
' Get rid of any alpha channel in AlphaClr
Clr = Clr Shl 8 Shr 8
' Convert font handle
FontFT = Cast(FT_Face, Font)
' Set font size
ErrorMsg = FT_Set_Pixel_Sizes(FontFT, Size, Size)
FT_Var.PixelSize = Size
If ErrorMsg Then Return 0
' Draw each character
Slot = FontFT->Glyph
PenX = x
PenY = y
For i = 0 To Len(Text) - 1
' Load character index
GlyphIndex = FT_Get_Char_Index(FontFT, Text[i])
' Load character glyph
ErrorMsg = FT_Load_Glyph(FontFT, GlyphIndex, FT_LOAD_DEFAULT)
If ErrorMsg Then Return 0
' Render glyph
ErrorMsg = FT_Render_Glyph(FontFT->Glyph, FT_RENDER_MODE_NORMAL)
If ErrorMsg Then Return 0
' Check clipping
If (PenX + FontFT->Glyph->Bitmap_Left + FontFT->Glyph->Bitmap.Width) > 320 Then Exit For
If (PenY - FontFT->Glyph->Bitmap_Top + FontFT->Glyph->Bitmap.Rows) > 240 Then Exit For
If (PenX + FontFT->Glyph->Bitmap_Left) < 0 Then Exit For
If (PenY - FontFT->Glyph->Bitmap_Top) < 0 Then Exit For
' Set pixels
DrawGlyph FontFT, PenX + FontFT->Glyph->Bitmap_Left, PenY - FontFT->Glyph->Bitmap_Top, Clr
PenX += Slot->Advance.x Shr 6
Next i
End Function
sub DrawGlyph(ByVal FontFT As FT_Face, ByVal x As Integer, ByVal y As Integer, ByVal Clr As UInteger)
Dim BitmapFT As FT_Bitmap
Dim BitmapPtr As UByte Ptr
Dim DestPtr As UInteger Ptr
Dim BitmapHgt As Integer
Dim BitmapWid As Integer
Dim BitmapPitch As Integer
Dim Src_RB As UInteger
Dim Src_G As UInteger
Dim Dst_RB As UInteger
Dim Dst_G As UInteger
Dim Dst_Color As UInteger
Dim Alpha As Integer
BitmapFT = FontFT->Glyph->Bitmap
BitmapPtr = BitmapFT.Buffer
BitmapWid = BitmapFT.Width
BitmapHgt = BitmapFT.Rows
BitmapPitch = 320 - BitmapFT.Width
DestPtr = Cast(UInteger Ptr, ScreenPtr) + (y * 320) + x
Do While BitmapHgt
Do While BitmapWid
' Thanks, GfxLib
Src_RB = Clr And FT_MASK_RB_32
Src_G = Clr And FT_MASK_G_32
Dst_Color = *DestPtr
Alpha = *BitmapPtr
Dst_RB = Dst_Color And FT_MASK_RB_32
Dst_G = Dst_Color And FT_MASK_G_32
Src_RB = ((Src_RB - Dst_RB) * Alpha) Shr 8
Src_G = ((Src_G - Dst_G) * Alpha) Shr 8
*DestPtr = ((Dst_RB + Src_RB) And FT_MASK_RB_32) Or ((Dst_G + Src_G) And FT_MASK_G_32)
DestPtr += 1
BitmapPtr += 1
BitmapWid -= 1
Loop
BitmapWid = BitmapFT.Width
BitmapHgt -= 1
DestPtr += BitmapPitch
Loop
End sub
the lua script I'm using with this:
screenres(320, 240, 32 )
math.randomseed(os.time())
font = LoadFont("fonts/arial.ttf")
for X = 1, 20 do
color = NewColor(math.random() * 255, math.random() * 255, math.random() * 255)
size = math.random() * 22 + 10
FontPrint(math.random() * 200, math.random() * 180 + 20, font, size, color, "Hello World!")
end
-
one thing i can see that might scramble the letters when you change the screenres is this line
DestPtr = Cast(UInteger Ptr, ScreenPtr) + (y * 320) + x
where 320 is it needs to be the scr width of your window, to make that possible you might have to have a global scrwidth in the graphics.bas file then fill in its size in the screenres function.
thats just a quick guess though, could you upload what you have so far? so i can see if i can guess whats up.
-
Here it is, I tried adding a screen_width global as you suggested but that didn't work
http://www.mediafire.com/?6yzfgy0lffm (http://www.mediafire.com/?6yzfgy0lffm)
*edit* i made an error in the graphics.bi that I just posted
screen_width = lua_tonumber(L, 2)
should be
screen_width = lua_tonumber(L, 1)
however, even correcting that doesn't fix it
**
just did a test, the probelm is that the value set to screen_width isn't lasting outside the function
-
right im messing around with it now but heres a couple of bits spotted right away.
now in fb to make a variable global so functions can acssess it you have to use the shared keyword so.
dim screen_width as integer.
becomes
dim shared screen_width as integer.
what fb would have been doing was creating a local screen_width function with a value of 0.
also.
BitmapPitch = 320 - BitmapFT.Width
should be
BitmapPitch = screen_width - BitmapFT.Width
right im going to download the freetype dll so i can try this out.
-
actually, I had already realized that about using shared but the value still remains at zero
-
where can i get my hands on the freetype dll you are yousing.
it should be fairly easy to get this going.
-edit got it
here is the code working i only had to modify a couple of bits.
i aslo cleaned out the warnings for you a couple of notes when you have a function in fb you have to return a value if there is no specific value to return just return(0) and it stops the compiler grumbling.
also with the wrapper functions even if you dont need to push values through still write them as.
function screen_clear cdecl (byval L as lua_State ptr)
and it will stop the compiler moaning.
now here is the working code all you have todo is add the fonts folder and the freetype dll also i think you will have to modify the freetype clipping planes to your window width/height.
-
Hey thanks.
As for the freetype dll I didn't install anything extra, I'm just using FBIde with Freebasic 0.16b installed over the version that was packaged with the ide, a couple of the files in the examples folder give me errors when I try to compile them, but the ones for freetype work fine.
-
No probs what errors do you get? i think we are yousing the same version of the compiler.
so you dont need the freetype dll? cause when i tryed to run your example it gave me an error saying freetype dll wasnt there unless you maybe have freetype installed in your system32 folder.
-
well, since I replaced my files with the edited ones that you posted, the compiler give me no errors at all.
I've got several programs installed on my pc that use the GTK (including Gimp itself), the GTK installs freetype as part of it's package.
Of course, it could also be that it's using the libfreetype.dll.a file in c:\freebasic\lib\win32
-
ahh right im guessing one of the packages youve installed has put the freetype dll in your system folder.
so what are your plans for this now are you planning on any games?
-
Well, eventually I might try doing a game, but for right now I want to get the interpreter to be able to use most of the standard FreeBasic graphics functions, after that I'd like to try to get it so you can load jpg, gif, and png images, and then maybe some basic 3d stuff with OGL
-
cool well keep us updated,
i might look into some stuff and whatever i find ill share.
the basic ogl stuff shouldnt be that hard.
-
Well, it could take me a while. Until now I've been writing scripts for the PSP Lua Player which already has all of that compiled into it. The source for that is available but it's all in C++ which I know nothing about, and instead of OGL it uses psp-specific libraries for it's limited 3d stuff so that can't really help me here.
-
Would you like me to take care of the ogl stuff? it could take me a little while as ive got other stuff im working on but i could chip away at it in my spare time for you.
-
that would be great, the more help I can get with this the better
In fact, I've been wondering if maybe we shouldn't make this a community project, maybe ask the admins to set up a section of the board just for Lua stuff.
***
hmm.... I did a small test to add the circle function, using only the x,y, radius, and color arguments, it works but if you use it in a non-standard resolution the circle gets squashed into an ellipse.
-
Maybe we can think about a separate section later when we see where this is going? Primarily DBF is a demo coding site so it'll be interesting to see how it works out. :)
What is the benefit of being able to call the FB graphics functions from Lua? Why not write in FB?
Jim
-
I only just started working with FB so I don't really know all it can do yet, but Lua is a very powerful scripting language. It's as easy, if not easier to learn than basic. I haven't really done much with it yet, just a few things for the psp lua player, but I've been able to pick it up a lot faster than any other programming language I've tried.
-
These days Merick, modern languages seem to be getting more and more similar and I'm sure that you could probably pick up fb's gfx commands easily enough.
Personally I work with FB, however I know bugger all about FB's graphics commands!! I just use tinyptc and it's all putting numbers into memory banks. Can be broken down to the pixel level.. I could help you with that I am sure..
For now though you seem to be having a lot of fun with what you're doing and it seems a gentle way of learning FB to me so if it makes you happy... :D
-
Is tinyptc better than using the standard graphics commands?
-
You have more control over everything as you have to write all the graphics commands yourself!
Not too daunting though, I actually made a library of commands that anyone is free to use for stuff like drawing simple text, triangles, circles, lines etc, most of it uses inline assembler so it's fast too.
The main reason I use it is for size reasons... Also an excellent and revised version of tinyptc has been developed on this forum called PTC_EXT
This was made by Rbraz and it's what I use. It's identical to Tinyptc, however it has perfectly synced refresh and support for MMX.
These intros are all created with it;
http://www.defacto2.net/cracktros.cfm?mode=author&value=Shockwave&recordsAtOnce=10 (http://www.defacto2.net/cracktros.cfm?mode=author&value=Shockwave&recordsAtOnce=10)
You should really follow steps 1,2 and 3 of these tutorials;
http://dbfinteractive.com/index.php?PHPSESSID=d15c6d471fa5d137ee8a0558b2a05319&cat=127 (http://dbfinteractive.com/index.php?PHPSESSID=d15c6d471fa5d137ee8a0558b2a05319&cat=127)
Which will guide you through your first steps of using tinyptc including installation of ptc_ext if you are interested. :)
-
Thanks, I'll look into it.
Here's another update, this time I've added a readme with a list of all the commands that I've made wrappers for:
http://www.mediafire.com/?7vbyw21x1fg (http://www.mediafire.com/?7vbyw21x1fg)
-
if your intrested in ptc merick, if you look further back i posted an example of setting ptc up wih lua for you.
-
I did check it out actually, I just haven't done anything with it yet because I wanted to get the standard FB graphics functions working first. I want to have a number of different headers so that people can use whatever graphics library they want by including a different set of files when compiling LuaFB.
One thing I can use some help with. I tried adding the imagecreate function, but I don't think it's working because I'm not sure which data type to push into the lua stack, any ideas?
-
the correct type for image create is (any ptr) but im not quite shure what you mean.
-
In order to send anything from FB to the lua state, or from the lua state to FB, you need to pass it through the lua stack, that's what this is for in the function: (byval L as lua_State ptr)
On the lua side, if you use a function like this:
sPrint(x,y, text ,color)
each argument is put into the stack, and can be accessed from the FB side by pointing to the position in the stack. For instance:
lua_tonumber(L, 2) -- gets the y position
On the FB side, to return some data to the lua side, you need to push it onto the stack:
function ikey cdecl (byval L as lua_State ptr)
lua_pushstring( L, inkey$) -- pushes the result of inkey$ onto the stack
ikey = 1 -- tells lua that one item was pushed into the stack
end function
In order to be able to use an image made with imagecreate, I need to figure out how to send the image pointer through the stack
** I just looked in lua.bi, ther is a function to get a pointer - lua_topointer, but not one to push it
-
Yeah i know all that but i dont think that lua script can handle pointers can it? what you need todo is have your image loading function in fb and pass it the filename.bmp/jpg/png then in fb there will be a global array that holds the image info then from lua you could call a function like draw image and in fb it will blit the image array it has to the screen.
well thats how i would do it anywho.
-
I'm not too familiar with FB arrays, in lua tables will automatically expand if you try to add new data to the end of it, do FB arrays work the same, or would I have to redim the array to make it bigger? Something like this would be needed to accomodate a variable number of images. I suppose I could make a function to set the size of the image array, but I'd prefer to be able to set it up to do that automatically.
As for pointers, well if I use lua_pushlightuserdata on the result of imagecreate, then print it with lua's print command this is what is printed out:
userdata: 0093F0A8
however, if I try to use lua_topointer or touserdata to reverse it, I get dozens of errors, none of which are from any of my files
-
fb arrays need to be redim`d but theres another way this can be done give me a few days as im not going to be at the pc very much for the next couple of days and ill bash something up for you is that cool?
-
no prob, thanks for your help, I want to get this sorted out so I can implement the "target" option for the graphics commands
-
I just figured out how to run a script without having to load an external file.
For instance, take my timer from the system.lua file:
Timer = {}
function Timer.new()
T = setmetatable(
{
start_time = 0,
running = false,
stopped_time = 0,
},
{
__index = Timer
}
)
return T
end
function Timer:start()
self.start_time = timer()
self.running = true
end
function Timer:time()
if self.running then
return (timer()-self.start_time)
else
return self.stopped_time
end
end
function Timer:reset()
self.start_time = timer()
self.stopped_time = 0
end
function Timer:stop()
self.stopped_time = (timer()-self.start_time)
self.running = false
end
If you remove the line breaks to create a single line and then load it into a string, you can run the it with lua_dostring from you're main .bas file:
dim code as string
code = "Timer = {} function Timer.new() T = setmetatable({start_time = 0, running = false, stopped_time = 0, }, {__index = Timer}) return T end function Timer:start() self.start_time = timer() self.running = true end function Timer:time() if self.running then return (timer()-self.start_time) else return self.stopped_time end end function Timer:reset() self.start_time = timer() self.stopped_time = 0 end function Timer:stop() self.stopped_time = (timer()-self.start_time) self.running = false end"
lua_dostring(L, code)
-
Anyone know how to convert header files from C/C++ .h to Freebasic .bi? There's already a set of bindings for using OpenGL in lua, but it's all in C.
-
theres a tool for converting somewhere but you might have some difficulties running gdi based gl in freebasic based on the screen function also with gl you will have to use standard screen reses.
-
I found that tool: swig
I posted about this on the FreeBasic board, the guys there are helping me out with it
-
Right i had a spare half hour there so here is a bmp image loader for you.
ImageLoader.Bi
const BITMAP_ID = &H4D42
Dim Shared NoImagesBmpStack As Integer
Type BITMAPINFOHEADER Field = 1
BiSize as integer
BiWidth as integer
BiHeight as integer
BiPlanes as short
BiBitCount as short
BiCompression as integer
BiSizeImage as integer
BiXPelsPerMeter as integer
BiYPelsPerMeter as integer
BiClrUsed as integer
BiClrImportant as integer
End Type
Type PALETTEENTRY Field = 1
peRed As Byte
peGreen As Byte
peBlue As Byte
peFlags As Byte
End Type
Type BITMAPFILEHEADER Field = 1
BfType As Short
BfSize As Integer
BfReserved1 As Short
BfReserved2 As Short
BfOffBits As Integer
End Type
'This is a replacement for AUX_RGBImageRec because GLAUX lib is not part of
'the freebasic install (perhaps not worth having for only one useful function).
'------------------------------------------------------------------------------
'Added by nino changed this so now we have a Byte And An Integer Buffer
Type BITMAP_RGBImageRec Field = 1
SizeX as integer
SizeY as integer
ByteBuffer as Ubyte Ptr
IntegerBuffer as Integer Ptr
End Type
Type BmpsImageStack
Image As BITMAP_RGBImageRec Ptr
End Type
Declare Function LoadBmp( Filename as string ) as BITMAP_RGBImageRec ptr
Dim Shared BmpImageStack As BmpsImageStack Ptr
Function LuaBmpSlots cdecl ( ByVal L As Lua_State Ptr ) As Integer
NoImagesBmpStack = Lua_ToNumber(L,1)
BmpImageStack = CAllocate( NoImagesBmpStack * SizeOf( BmpsImageStack ) )
Return(0)
End Function
lua_register( L, "LuaBmpSlots", @LuaBmpSlots )
Declare Function DeAllocateBmpStack()
Function DeAllocateBmpStack()
For X = 0 To NoImagesBmpStack
If ( BmpImageStack ) Then
If ( BmpImageStack[ X ]->Image ) Then
If ( BmpImageStack[ X ]->Image->IntegerBuffer ) Then
DeAllocate( BmpImageStack[ X ]->Image->IntegerBuffer )
End If
If ( BmpImageStack[ X ]->Image->ByteBuffer ) Then
DeAllocate( BmpImageStack[ X ]->Image->ByteBuffer )
End If
EndIf
DeAllocate( BmpImageStack[ X ]->Image )
End If
Next
If BmpImageStack Then
DeAllocate( BmpImageStack )
End If
Return(0)
End Function
Function LuaLoadBmp cdecl ( ByVal L As Lua_State Ptr ) As Integer
Dim BmpSlot As Integer = Lua_ToNumber( L , 1 )
Dim FileName As String = *Lua_ToString( L , 2 )
If BmpSlot > NoImagesBmpStack Then Return
BmpImageStack[ BmpSlot ]->Image = LoadBmp( FileName )
Return(0)
End Function
lua_register( L, "LuaLoadBmp", @LuaLoadBmp )
'' Loads A Bitmap Image. Only uncompressed 8 or 24 bit BITMAP immages supported
Function LoadBmp( Filename as string ) as BITMAP_RGBImageRec ptr
dim bitmapfileheader as BITMAPFILEHEADER '' this contains the bitmapfile header
dim bitmapinfoheader as BITMAPINFOHEADER '' this is all the info including the palette
dim bmpalette(256) as PALETTEENTRY '' we will store the palette here
dim index as integer
dim noofpixels as integer
dim p as ubyte ptr
dim r as ubyte, g as ubyte, b as ubyte
dim pbmpdata as BITMAP_RGBImageRec ptr
dim f as integer
f = freefile
If (open (Filename, for binary, as #f) = 0) then '' Does The File Exist?
Get #f, , bitmapfileheader
If bitmapfileheader.bfType <> BITMAP_ID then
Close #f
Return 0
End If
Get #f, , bitmapinfoheader
If bitmapinfoheader.biBitCount=8 or bitmapinfoheader.biBitCount=24 then
If bitmapinfoheader.biBitCount = 8 then
for index = 0 to 255
get #f, , bmpalette(index)
next
End If
noofpixels = bitmapinfoheader.biWidth*bitmapinfoheader.biHeight
'' allocate the memory for the image (24 bit memory image)
pbmpdata = allocate(len(BITMAP_RGBImageRec))
if pbmpdata = 0 then
'' close the file
close #f
return 0
end if
pbmpdata->sizeX = bitmapinfoheader.biWidth
pbmpdata->sizeY = bitmapinfoheader.biHeight
pbmpdata->ByteBuffer = Allocate( noofpixels * 3 )
pbmpdata->IntegerBuffer = Allocate( noofpixels * 4 )
If pbmpdata->ByteBuffer = 0 Then
'' close the file
close #f
deallocate (pbmpdata)
return 0
End If
'' now read it in
p = pbmpdata->ByteBuffer
if bitmapinfoheader.biBitCount=24 then
for index = 0 to noofpixels -1
'' Change from BGR to RGB format
get #f, , b
get #f, , g
get #f, , r
*p = r : p += 1
*p = g : p += 1
*p = b : p += 1
next
else
for index = 0 to noofpixels -1
'' Change from BGR to RGB format while converting to 24 bit
get #f, , b
*p = bmpalette(b).peBlue : p += 1
*p = bmpalette(b).peGreen : p += 1
*p = bmpalette(b).peRed : p += 1
next
end if
else
close #f
return 0
end if
'' Success!
close #f
'nino comment added this code here to format the rgb bytes and flip the image into
'the new integer_buffer
dim as integer y,x
dim as ubyte ptr my_pointer1
dim as integer ptr my_pointer2
dim as ubyte r,g,b
my_pointer1 = pbmpdata->ByteBuffer
for y= pbmpdata->sizey - 1 to 0 step - 1
for x=0 to pbmpdata->sizex - 1
r = *my_pointer1
my_pointer1 += 1
g = *my_pointer1
my_pointer1 += 1
b = *my_pointer1
my_pointer1 += 1
pbmpdata->IntegerBuffer[y*pbmpdata->sizex+x] = ((r shl 16) or (g shl 8) or b)
next
next
return pbmpdata
end if
return 0
end function
Function LuaDrawBmp cdecl ( ByVal L As Lua_State Ptr ) As Integer
' 1 = BmpStackNo 2 = x 3 = y
Dim X As Integer
Dim Y As Integer
Dim BmpStackNo As Integer = Lua_ToNumber( L , 1 )
Dim PosX As Integer = Lua_ToNumber( L , 2 )
Dim PosY As Integer = Lua_ToNumber( L , 3 )
Dim ImageWidth As Integer = BmpImageStack[ BmpStackNo ]->Image->SizeX
Dim ImageHeight As Integer = BmpImageStack[ BmpStackNo ]->Image->SizeY
Dim DestPtr As UInteger Ptr
DestPtr = Cast(UInteger Ptr, ScreenPtr) + ( PosY * screen_width ) + PosX
For Y = 0 To ImageHeight - 1
For X = 0 To ImageWidth - 1
*DestPtr = BmpImageStack[ BmpStackNo ]->Image->IntegerBuffer[ Y * ImageWidth + X ]
DestPtr += 1
Next
DestPtr += ( screen_width - ImageWidth )
Next
Return(0)
End Function
lua_register( L, "LuaDrawBmp", @LuaDrawBmp )
and here is how interpreter.bas should look with this
#include once "fbgfx.bi"
#include once "Lua/lua.bi"
#include once "Lua/luauxlib.bi"
#include once "Lua/lualib.bi"
dim L as lua_State ptr
L = lua_open( ) 'create a lua state
luaopen_base(L) 'opens the basic library
luaopen_table(L) 'opens the table library
luaopen_io(L) 'opens the I/O library
luaopen_string(L) 'opens the string lib.
luaopen_math(L) 'opens the math lib.
dim shared screen_width as integer 'needed for freetype
dim shared screen_height as integer 'needed for freetype
#include once "FBsystem.bi"
#include once "FBgraphics.bi"
#include once "lua freetype.bi"
#include once "ImageLoader.Bi"
' execute the lua script from a file
lua_dofile( L, "system.lua" )
lua_dofile( L, "main.lua" )
lua_close( L )
DeAllocateBmpStack()
Sleep
End
and heres how to use it in lua script
--These lines should go before main loop
TestImage = 1
LuaBmpSlots(1)
LuaLoadBmp( TestImage , "test.bmp" )
--and this line should go in the while loop
LuaDrawBmp( TestImage , 10 , 10 )
testimage refers to the slot in the bmpstack the bmp will be held in
luabmpslots allocates slots of memory on a bmp stack for images to be held set this to however many images you intend to load
lualoadbmp takes a refrence to the bmp image stack and the filename of the bmp
luadrawbmp takes a refrence to the bmp stack and the x and y positions to draw the image.
ohh and one more thing this loader only works properly with image widths divisable by eight ie 32/8 = an even 4
hop this helps :cheers:
-
Hey thanks, I'll try this out as soon as I can figure out how to get it to compile. I just upgraded FB to v0.17 and it seems the lua headers were completely re-written and I'm having some trouble figuring out what I need to change in order to make it work.
-
no problem i had some difficultes getting some of my stuff to build with 0.17 too so i just reverted back i guess if you switch also to a newer platform 0.16 users wont be able to build our code.
you could always install both versions though.
-
Ok I re-installed 0.16, but when I try this it crashes with the winXP generic "program had a problem" error
*edit*
Stupid me, I forgot to set a screen mode
-
i suspect youve possible mised one of the steps above
here is the project folder i have and exe that works on my system.
note you will have to add the fonts folder and the freetype dll.
-
Yeah, i just edited my previous post, I forgot to set a screen mode in the lua script.
Anyway, if I set the graphics with screenres it works just fine, but if I set it with screen it doesn't work right, it runs but all I get is a single row of pixels spread across the top of the window
-
hmm i dont know much about fb functions i used the same methode to blit the bmp as is used to blit the font via screenptr but im using integers so the only thing i can think of is that using screen isnt opening a 32 bit color window but im not sure :-\
-
hmm... well thanks again, this gives me something to play around with
but for now GameTap just finished downloading Tomb Raider Anniversary, so I'm gonna be busy for a while ;D
-
lol yeah im currently busy trying to get broken sword 2 to run on my psp.
oh well have fun!
-
Alright, thanks to some files posted by Tigra on the Freebasic board I've been able to get FBlua to compile with v0.17. Use the liblua.a in this archive to replace the liblua.a in the lib\win32 folder that gets installed by 0.17, and use the -lang deprecated option when you compile.
http://www.mediafire.com/?a40b2i4xtxj (http://www.mediafire.com/?a40b2i4xtxj)
This works, but I've noticed a few problems:
-- lua's error reporting function isn't printing the errors anymore -- probably because of the change in the liblua.a or the headers, I just need to figure out the new setup
-- my sPrint function isn't working correctly anymore, it looks like there was a change in the way that colors are used in the higher color depth screen modes
--You're image loading functions don't seem to work with 0.17, something about missing a pointer?
-
Some of the flags for the graphics mode stuff got changed around in 0.17. I don't know if that affects you.
Jim
-
got the error reporting thing worked out, need to put this after the pcall function: print *lua_tostring(L, 1)
-
hey merick its cool that your sorting this out!
i dont know why your getting an error about a missing pointer is the fb screenptr command still supported as thats the only fb reliant function in my loader. does the freetype fonts work in 0.17?
-
Freetype works, or at least as much as it did before, it still has some problems with the text not being drawn depending on the length of the text and where you're trying to print it in the window
as for screenptr, I just tried a test and it still works so I don't think that's it. Heres a copy of the error log when I try to compile with your image loader included:
Command executed:
"C:\FreeBasic\fbc.exe" "C:\FreeBasic\projects\FBLua\FBIDETEMP.bas" -lang deprecated
Compiler output:
C:/FreeBasic/projects/FBLua/FBgraphics.bi(212) warning 5(0): Implicit conversion
C:/FreeBasic/projects/FBLua/FBgraphics.bi(219) warning 5(0): Implicit conversion
C:/FreeBasic/projects/FBLua/ImageLoader.Bi(77) error 29: Expected pointer, before '->'
If ( BmpImageStack->Image ) Then
^
C:/FreeBasic/projects/FBLua/ImageLoader.Bi(78) error 29: Expected pointer, before '->'
If ( BmpImageStack->Image->IntegerBuffer ) Then
^
C:/FreeBasic/projects/FBLua/ImageLoader.Bi(79) error 29: Expected pointer, before '->'
DeAllocate( BmpImageStack->Image->IntegerBuffer )
^
C:/FreeBasic/projects/FBLua/ImageLoader.Bi(79) error 55: Type mismatch, at parameter 1 of DEALLOCATE()
DeAllocate( BmpImageStack->Image->IntegerBuffer )
^
C:/FreeBasic/projects/FBLua/ImageLoader.Bi(81) error 29: Expected pointer, before '->'
If ( BmpImageStack->Image->ByteBuffer ) Then
^
C:/FreeBasic/projects/FBLua/ImageLoader.Bi(82) error 29: Expected pointer, before '->'
DeAllocate( BmpImageStack->Image->ByteBuffer )
^
C:/FreeBasic/projects/FBLua/ImageLoader.Bi(85) error 29: Expected pointer, before '->'
DeAllocate( BmpImageStack->Image )
^
C:/FreeBasic/projects/FBLua/ImageLoader.Bi(103) error 9: Expected expression
If BmpSlot > NoImagesBmpStack Then Return
^
C:/FreeBasic/projects/FBLua/ImageLoader.Bi(104) error 29: Expected pointer, before '->'
BmpImageStack->Image = LoadBmp( FileName )
^
C:/FreeBasic/projects/FBLua/ImageLoader.Bi(238) error 29: Expected pointer, before '->'
Dim ImageWidth As Integer = BmpImageStack->Image->SizeX
^
C:/FreeBasic/projects/FBLua/ImageLoader.Bi(238) error 123: Too many errors, exiting
Results:
Compilation failed
System:
FBIde: 0.4.6
fbc: FreeBASIC Compiler - Version 0.17 (05-11-2007) for win32 (target:win32)
OS: Windows XP (build 2600, Service Pack 2)
-
New version (includes both the source and an exe): http://www.mediafire.com/?2xng1dvneyg (http://www.mediafire.com/?2xng1dvneyg)
In this version I've added most of the flags from fbgfx.bi to the lua state. However, the only functions on the lua side that can actually use them atm are Screen() and ScreenRes(). If you want to set multiple flags you have to set them with "+", you can't use "or" because the lua or works differently than the FB or:
ScreenRes(400,400,32,1,GFX_ALWAYS_ON_TOP+GFX_NO_FRAME+GFX_ALPHA_PRIMITIVES)
-
woot! I've got the image pointer thing worked out now, in a day or two I should be able to post an update that can use png images (using yetifoot's png loader) and possibly bmp's as well if I can adapt nino's bmp loader
-
gah, this is driving me crazy. I've got the image loading and unloading worked out, but I just can't figure out how to set up lua's __gc metamethod to link the image deallocation to lua's garbage collector
http://www.mediafire.com/?3hmnetngbmg
-
Update: test version 2007.6.23
http://www.mediafire.com/?6orj12rwjnh (http://www.mediafire.com/?6orj12rwjnh)
Thanks to Voodooattack at the FreeBasic forums, I've now got preliminary image loading for .bmp and .png, with the memory management being done automatically in the background. (everything will be freed on program exit, or else use image = nil to remove an image from memory while the program is still running) I've also renamed all of the screen functions, check the readme file for the new syntax.
(sorry nino, but Voodooattack wrote a different bmp loader)
*edit*
there was a bug in when trying to blit partial images, but Voodooattack just showed me what I did wrong, link updated to the fixed version
*end edit*
There's also a slight change in the way scripts are loaded. The file that's auto-run now is the "system.lua" in the main folder, atm I'm only having it load "main.lua" from the scripts folder
-
thats come a long way merick congrats!
i can see how the new stuff works and it looks much better!
-
Just discovered there's a bug with fullscreen modes, at least on my winXP machine. Although you can set fullscreen, when the program exits the desktop is all messed up.
-
now with sound: http://www.mediafire.com/?9wtcwz2mt1j (http://www.mediafire.com/?9wtcwz2mt1j)
check the readme for the new functions
forgot to add this to the readme - to use the fbgfx flags in FBlua, you need to put FB. in front of them, just like using the FB namespace in FreeBasic -FB.GFX_FULLSCREEN, FB.GFX_NO_SWITCH, etc...
-
update: version 2007.7.4
source: http://www.mediafire.com/?3mlzziparme
exe with test script: http://www.mediafire.com/?4iy1b5xglgj
Changes:
Added support for the MultiKey input function. Use like this:
If mKey(SC.ESCAPE) then
[code block]
end
see the readme for all the scancode (SC) flags
I've changed the way that GetMouse() works. Instead of using:
x,y,buttons = GetMouse()
you need only one variable:
mouse = GetMouse()
this will set "mouse" as a table with the following elements:
mouse.X = mouse x pos
mouse.Y = mouse y pos
mouse.C = true (1) if the mouse is being captured to the program window, false (nil) if not
mouse.L = left button - true if pressed
mouse.R = right button - true if pressed
mouse.M = middle button - true if pressed
SetMouse() has been changed to three different functions:
SetMouse.Visible(true/false) --set to false to hide the mouse cursor, true to show it again
SetMouse.Clip(true/false) --set to true to hold the mouse cursor inside the program window
SetMouse.Pos(x,y) - sets mouse cursor to an x,y pos inside the program window
added support for using joysticks, works similar to the new version of GetMouse(), see readme for details.
Also, I found a pdf reference file with the standard lua functions and have included it in the archives.
-
update: version 2007.7.22
http://www.mediafire.com/?9goouzmemzp
Changes:
Added more wrappers for the FBsound functions - see readme
Added the spPrint function. This is a test function based on a by-pixel font print function made by Joshy.
OpenGL ---
I've started adding function for OpenGL. These functions are not part of the main exe, instead I've put them into a .dll for use with the lua binary module system. To use the opengl functions you need to use require("OGlua") first.
For a demo of how to use it, the archive has a copy NeHe lesson 4 converted to lua. ATM, the functions used in this demo are the only ones implemented so far.