Dark Bit Factory & Gravity

PROGRAMMING => Freebasic => Topic started by: Merick on May 28, 2007

Title: lua!!!!
Post 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.
Title: Re: lua?
Post by: Shockwave on May 28, 2007
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.
Title: Re: lua?
Post by: Merick on May 28, 2007
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.
Title: Re: lua?
Post by: ninogenio on May 28, 2007
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.
Title: Re: lua?
Post by: Merick on May 28, 2007
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:
Code: [Select]
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:

Code: [Select]
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
Title: Re: lua?
Post by: ninogenio on May 28, 2007
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.
Title: Re: lua?
Post by: Merick on May 28, 2007
I think I got part of it. If I put this in:

Code: [Select]
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
Title: Re: lua?
Post by: Shockwave on May 28, 2007
It will be sorted when the libs guys get on here later if you don't fix it first :)
Title: Re: lua?
Post by: Merick on May 28, 2007
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:

Code: [Select]
#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?
Title: Re: lua?
Post by: Shockwave on May 28, 2007
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.
Title: Re: lua?
Post by: Jim on May 28, 2007
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
Title: Re: lua?
Post by: Merick on May 29, 2007
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.
Title: Re: lua?
Post by: Merick on May 29, 2007
Here's what I have so far:

Code: [Select]
#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)
Title: Re: lua?
Post by: Merick on May 30, 2007
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
Title: Re: lua?
Post by: ninogenio on May 30, 2007
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.
Title: Re: lua?
Post by: Merick on May 30, 2007
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
Title: Re: lua?
Post by: ninogenio on May 30, 2007
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
Title: Re: lua?
Post by: Merick on May 30, 2007
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:

Code: [Select]
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

Code: [Select]
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
Title: Re: lua?
Post by: ninogenio on May 30, 2007
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.
Code: [Select]
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
Title: Re: lua?
Post by: Merick on May 30, 2007
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?
Title: Re: lua?
Post by: Merick on May 31, 2007
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)
Title: Re: lua?
Post by: ninogenio on May 31, 2007
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.

 
Title: Re: lua?
Post by: Merick on May 31, 2007
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)

Code: [Select]
'' 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
Title: Re: lua?
Post by: Merick on June 01, 2007
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.

Code: [Select]
'' 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:

Code: [Select]
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
Title: Re: lua?
Post by: ninogenio on June 01, 2007
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.
Title: Re: lua?
Post by: Merick on June 01, 2007
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
Title: Re: lua?
Post by: ninogenio on June 01, 2007
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.
Title: Re: lua?
Post by: Merick on June 01, 2007
actually, I had already realized that about using shared but the value still remains at zero
Title: Re: lua?
Post by: ninogenio on June 01, 2007
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.

Title: Re: lua?
Post by: Merick on June 01, 2007
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.
Title: Re: lua?
Post by: ninogenio on June 01, 2007
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.
Title: Re: lua?
Post by: Merick on June 01, 2007
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
Title: Re: lua?
Post by: ninogenio on June 01, 2007
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?
Title: Re: lua?
Post by: Merick on June 01, 2007
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
Title: Re: lua?
Post by: ninogenio on June 01, 2007
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.
Title: Re: lua?
Post by: Merick on June 02, 2007
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.

Title: Re: lua?
Post by: ninogenio on June 02, 2007
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.
Title: Re: lua?
Post by: Merick on June 02, 2007
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.
Title: Re: lua?
Post by: Jim on June 02, 2007
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
Title: Re: lua?
Post by: Merick on June 02, 2007
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.

Title: Re: lua?
Post by: Shockwave on June 02, 2007
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
Title: Re: lua?
Post by: Merick on June 02, 2007
Is tinyptc better than using the standard graphics commands?
Title: Re: lua?
Post by: Shockwave on June 02, 2007
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. :)



Title: Re: lua?
Post by: Merick on June 02, 2007
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)
Title: Re: lua?
Post by: ninogenio on June 02, 2007
if your intrested in ptc merick, if you look further back i posted an example of setting ptc up wih lua for you.
Title: Re: lua?
Post by: Merick on June 02, 2007
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?
Title: Re: lua?
Post by: ninogenio on June 02, 2007
the correct type for image create is (any ptr) but im not quite shure what you mean.
Title: Re: lua?
Post by: Merick on June 02, 2007
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
Title: Re: lua?
Post by: ninogenio on June 02, 2007
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.
Title: Re: lua?
Post by: Merick on June 02, 2007
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
Title: Re: lua?
Post by: ninogenio on June 02, 2007
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?
Title: Re: lua?
Post by: Merick on June 02, 2007
no prob, thanks for your help, I want to get this sorted out so I can implement the "target" option for the graphics commands
Title: Re: lua?
Post by: Merick on June 02, 2007
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:

Code: [Select]
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:

Code: [Select]
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)
Title: Re: lua?
Post by: Merick on June 03, 2007
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. 

Title: Re: lua?
Post by: ninogenio on June 03, 2007
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.
Title: Re: lua?
Post by: Merick on June 03, 2007
I found that tool: swig

I posted about this on the FreeBasic board, the guys there are helping me out with it
Title: Re: lua?
Post by: ninogenio on June 05, 2007
Right i had a spare half hour there so here is a bmp image loader for you.

ImageLoader.Bi
Code: [Select]
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
Code: [Select]
#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
Code: [Select]
--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:
Title: Re: lua?
Post by: Merick on June 05, 2007
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.
Title: Re: lua?
Post by: ninogenio on June 05, 2007
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.
Title: Re: lua?
Post by: Merick on June 05, 2007
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
Title: Re: lua?
Post by: ninogenio on June 05, 2007
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.
Title: Re: lua?
Post by: Merick on June 05, 2007
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
Title: Re: lua?
Post by: ninogenio on June 06, 2007
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 :-\
Title: Re: lua?
Post by: Merick on June 06, 2007
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
Title: Re: lua?
Post by: ninogenio on June 06, 2007
lol yeah im currently busy trying to get broken sword 2 to run on my psp.

oh well have fun!
Title: Re: lua?
Post by: Merick on June 07, 2007
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?
Title: Re: lua?
Post by: Jim on June 07, 2007
Some of the flags for the graphics mode stuff got changed around in 0.17.  I don't know if that affects you.

Jim
Title: Re: lua?
Post by: Merick on June 07, 2007
got the error reporting thing worked out, need to put this after the pcall function: print *lua_tostring(L, 1)
Title: Re: lua?
Post by: ninogenio on June 07, 2007
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?
Title: Re: lua?
Post by: Merick on June 07, 2007
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:

Code: [Select]
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)

Title: Re: lua?
Post by: Merick on June 10, 2007
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)
Title: Re: lua?
Post by: Merick on June 11, 2007
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
Title: Re: lua?
Post by: Merick on June 14, 2007
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
Title: Re: lua?
Post by: Merick on June 24, 2007
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
Title: Re: lua!!!!
Post by: ninogenio on June 24, 2007
thats come a long way merick congrats!

i can see how the new stuff works and it looks much better!
Title: Re: lua!!!!
Post by: Merick on June 24, 2007
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.
Title: Re: lua!!!!
Post by: Merick on June 30, 2007
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...
Title: Re: lua!!!!
Post by: Merick on July 05, 2007
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.
Title: Re: lua!!!!
Post by: Merick on July 22, 2007
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.