Dark Bit Factory & Gravity
PROGRAMMING => Freebasic => Topic started by: MrP on August 16, 2006
-
First off Hello Everyone...... (download the file at the bottom to see what this thing actually does)
Been away for quite some time and its nice to come back and see so many familiar names. Used to do a little over at the dbf board and its nice to see that you've all got a new home. And very nice it is to I might add....
Well now i'm back for a while i've downloaded this freebasic thingy and to be honest I'm quite impressed with what it can do, and as such its prompted me to get back to coding again. (for how long I'm not sure!!!!!!)
Anyways after playing for a couple of weeks and getting familiar with the tinyptc api you begin to realise that you're going to have to do it all manually, and to be honest thats fine by me, so my first real project was to get some images loaded and get them whizzing about as only they can in a gfx demo.
As it stands this will load any uncompressed 32 bit tga image and display it correctly using the embedded per pixel alpha channel information (useful for nice anti-aliased edges and stuff - download the file to see it in action). eventually I will add other blending methods but first off I need some help and this is where I'm hoping somebody can help.......
I'm having trouble returning a pointer to an array defined in a funtion eg:-
declare function image_load("image.name")
my_img = image_load("image.name")
function image_load("image.name")
'load image and get width and height - this bit works
dim img_array(image_width, image_height) - this bit also works
'put image data into array - this bit also works
return img_array(0) - this bit im stuck with, also tried function = img_array(0)
end function
this is a very simplified version of whats really happening if you want the code i've got i'd be happy to post it but if anyone can just tell me how to return a pointer to an array and then use that pointer back in the main loop, well I'll be a happy bunny. I know it has to do with pointers and stuff, but since I've never used them before I'm a bit of a noob at it. Of course I will continue to bash at it but if anybody can give me a point (excuse the pun) in the right direction I would be most grateful. This will be released as code when I get it how I want it......
Many thanks in advance.... MrP.....
-
Something like this should work;
Dim P as Integer Ptr
P = @IMG_ARRAY(0)
And welcome back :)
By the way, I couldn't connect to the link. As long as the files are zipped you can even directly upload them to this board by clicking on additional options and attaching the file :)
-
Sorry about that Shockwave put the pc to sleep when I went to bed DER!!!!!!! anyways attached the file now.
OK heres some simple code to get what I'm after. Please tell me its easy to do, this is driving me nuts.......
'ok heres what im stuck with.....
screenres 640, 480
declare function create_array() 'declare our function
my_array = create_array() 'i want a pointer to the array created in function create_array()
'to be held in value my_array
print my_array, "this is outside" 'my_array does have the right number
'print *my_array 'this is how you would go about getting info from the pointer
'address but seeing that my_array has not been defined as a pointer
'I cant get at the stuff I need. Hope this is a clearer picture.....
'it errors when you uncomment this line
sleep
end
function create_array()
dim array(10) 'create our array
value = 2 'fill it with some stuff
for i = 0 to 9 '
array(i) = value '
value += 2 '
next i '
print @array(0), "this is inside the function"
function = @array(0) 'return the pointer to the array
end function
'I assume this is easy to do but I don't know enough about pointers yet.....
'Still I'll keep bashing away at it....
-
Hello MrP, welcome back :)
Well, about those FB pointers, i'm not good either, but I know one way to do that, hope it help you :)
screenres 640, 480
declare sub create_array(byval array as integer ptr)
dim shared my_array(10) as integer
dim i as integer
create_array(@my_array(0))
for i = 0 to 9
print my_array(i), "this is outside"
next
sleep
end
Sub create_array(byval array as integer ptr)
dim value as integer
dim i as integer
value = 2 'fill it with some stuff
for i = 0 to 9 '
array[i] = value '
value += 2 '
next i '
for i = 0 to 9
print array[i], "this is inside the function"
next
print
end sub
-
Thanks for the reply Rbraz that does work very well but when i call the function to create the array its going to load an image into it and hence i dont know how big the array needs to be, i know you can create a dynamic array before hand (thrawn does exactly what i want with his pload library), but you have to create the array before you call the function. Just as you do in your code, jeez I cant tell you how many times i have banged my head against the keyboard trying to sort this. imagine in blitz if you write:-
myimage = loadimage("image.name")
you can then draw that image with
drawimage myimage, x, y
I know using tinyptc you haven't got a drawimage, i have coded the routine to draw the image, but I need it to read the information from an array created inside my load_image function, this is why i need to pass the address in memory where the array was created back to the line that created it ie the myimage = load_image("image.name") so I can reference the myimage as the beginning of the array, i'm beginning to think this isn't doable with my train of thought. Did some c++ a long time ago and I seem to remember that anything that was created inside a function was local to it and when that function ended anything that was created in it got destroyed, maybe wrong on that, but if that is what happens in freebasic I cant do what i want to do.
I just want to make the process of loading an image into an array as simple as it was in blitz it would make for a very good library considering what i have got the drawimage side of things to do, not only can this draw the image with per pixel alpa information, i've also added additive blending, and the ability to add an alpha value to the whole of the image (for fading and the like).....
If i have to create the array before hand like you do then so be it but I would rather not do.....
-
I think that FB did the same thing like C++ (destroy)
Check this out
doesn't work:
screenres 640, 480
declare function create_array() as integer ptr
'dim shared array(10) as integer
dim shared my_array as integer ptr
dim i as integer
my_array = create_array()
            Â
for i = 0 to 9
  print my_array[i], "this is outside"Â
next
sleep
end
function create_array() as integer ptr
  dim array(10) as integer
  dim value as integer
  dim i as integer
 Â
  value = 2        'fill it with some stuff
 Â
  for i = 0 to 9     '
    array(i) = value  '
    value += 2     '
  next i         '
 Â
  for i = 0 to 9
    print array(i), "this is inside the function"
  next
 Â
  print
 Â
  return @array(0)
 Â
end function
work's fine:
screenres 640, 480
declare function create_array() as integer ptr
dim shared array(10) as integer
dim shared my_array as integer ptr
dim i as integer
my_array = create_array()
            Â
for i = 0 to 9
  print my_array[i], "this is outside"Â
next
sleep
end
function create_array() as integer ptr
  'dim array(10) as integer
  dim value as integer
  dim i as integer
 Â
  value = 2        'fill it with some stuff
 Â
  for i = 0 to 9     '
    array(i) = value  '
    value += 2     '
  next i         '
 Â
  for i = 0 to 9
    print array(i), "this is inside the function"
  next
 Â
  print
 Â
  return @array(0)
 Â
end function
-
Thanks for confirming what I feared. It looks like im going to have create the array before calling the function. ah well thanks once again for the very quick reply... Lets see what I can do with it......
Cheers Rbraz
-
Well just got a reply over at the freebasic forums and it seems you can do it!!!!!
You dont have to create the array before hand but you do have to dim my_array as an integer pointer.......
Thank christ for that... now I can get to work putting this thing together properly....
Thanks Shockwave and Rbraz for the replies will put the finished lib up by weekend (hopefully).....
Declare Function create_array() As Integer Ptr
Dim my_array As Integer Ptr
my_array = create_array()
Print *my_array
Sleep
Function create_array() As Integer Ptr
Dim array(0 To 9) As Integer
array(0) = 20
Function = @array(0)
End Function
-
Yep, anything dimmed inside a function is local but you can use allocate/callocate to allocate memory inside a function that isn't destroyed on the function return.
There are a few different ways you can do it depending on your needs.
function my_function(byval num_ints)as integer pointer
'allocate some memory
 dim my_data as integer pointer=callocate(len(integer)*num_ints)
'write in some data
 dim i as integer
 for i=0 to num_ints-1
  *(my_data+i)=i*10
 next
'return pointer
 function=my_data
end function
'print one value from allocated memory
sub print_my_data(byval my_data as integer pointer,byval i as integer)
  print *(my_data+i)
end sub
 Â
sub main
 Â
'call function to allocate 10 ints and write some values in
  dim any_data as integer pointer=my_function(10)
 Â
'loop to print out all the data
  dim i as integer
  for i=0 to 9
    print_my_data(any_data,i)
  next
 Â
  print
  print"anykey to end"
  sleep
 Â
'clean up
  deallocate any_data
 Â
end sub
main
EDIT:
just read your last post there, I didn't realise you could do that.
EDIT AGAIN:
I'm not totally sure if you can, it might appear to work initially but I think there will be problems.
-
Just got another reply from the Freebasic forums, what you said is right Stonemonkey... This will cause issues, apparently if you want to go down the array route you use redim instead of dim.... Christ I think I've opened a can of worms here.... However just been looking through your code and that might just be a bit more appealing. Back to the drawing board for the minute then. Thanks for the reply Stonemonkey
-
scrap that apparently that doesn't work either. Stonemonkey your right you can only do it with callocate...... Cheers Matey....
-
Hello MrP.
The problem you're looking at isn't specific to freebasic, pretty much every language works like that...when you go in to a function anything you create there, like a dim/array or another variable, is allocated in temporary space only available while you're inside that function. It's called the 'stack'. When you exit the function, anything you created on the stack is lost, so if you return a reference to it back to the rest of the code (@array(0)) whatever it was pointing at is gone. You need to allocate some permanent space for it. This goes in a thing called the 'heap'. Stonemonkey has shown you what to do. The only important thing to remember about things you put on the heap is that you are responsible to tidying up your own mess. Anything you specifically create, you must destroy too.
Jim
-
I've heard that apparently you can also make Static variables inside subroutines, which keep the information outside of a sub / function. Have yet to try it myself.
-
Static variables are not destroyed and retain their value after the sub or function is returned but can only be accessed inside the sub or function they're declared in.
I'm not sure about returning a pointer of a static variable but I don't think I'd recommend doing that.
-
I don't recommend it either, it's a bad programming practice, but you are definitely allowed to do it. It doesn't help MrP though, since even though you call the function many times, there's only one instance of the static variable.
Jim
-
Thanks to you all for the pointers, that was a big help, was losing my mind for a minute there. Got it working using callocate now and everything is sweet. OK here is the code to load and display a 32bit Uncompressed tga file with per pixel alpha information..... Also please note it doesn't check if something is drawn off the edges of the screen so dont do it as that will be an issue.
Other than that if its of any use to you please free to use it. And of course any comments / critique are welcome....
I've also included the source and an image to use in a zip file at the end.......
'TGA image file loader (Supports Alpha)
#include once "tinyptc.bi"
screenres 640, 480, 32
if(ptc_open("TGA Test", 640, 480)) = 0 then end
dim shared as integer scr_buffer(640 * 480)
declare function load_image(f_name as string)
declare function draw_image(src_buffer as integer ptr, x_pos, y_pos)
declare function clear_screen()
dim my_img as integer ptr
my_img = load_image("test.tga")
dim angle as single
dim offset as single
angle = 250
while inkey$ = ""
clear_screen()
offset = 0
for i = 0 to 14
sprite_x = (320 - 32) + sin((angle - offset) / 1.7) * 200
sprite_y = (240 - 32) + cos(angle - offset) * 160
draw_image(my_img, sprite_x, sprite_y)
offset -= .3
next i
angle += .03
screensync
ptc_update @scr_buffer(0)
wend
deallocate(my_img)
ptc_close()
end
function clear_screen()
counter = 0
for i = 0 to 640 * 480 - 1
scr_buffer(i) = rgb(0, 0, 200)
next i
end function
function draw_image(src_buffer as integer ptr, x_pos, y_pos)
i = 2
for y = src_buffer[0] to 0 step -1
for x = 0 to src_buffer[1]
buffer_pos = (x_pos + x) + (y_pos + y) * 640
sr = scr_buffer(buffer_pos) shr 16 and &hff
sg = scr_buffer(buffer_pos) shr 8 and &hff
sb = scr_buffer(buffer_pos) and &hff
ir = src_buffer[i] shr 24 and &hff
ig = src_buffer[i] shr 16 and &hff
ib = src_buffer[i] shr 8 and &hff
ia = src_buffer[i + 1] and &hff
dr = (ia * (ir - sr)) shr 8 + sr and &hff
dg = (ia * (ig - sg)) shr 8 + sg and &hff
db = (ia * (ib - sb)) shr 8 + sb and &hff
scr_buffer(buffer_pos) = rgb(dr, dg, db)
i += 1
next x
next y
end function
function load_image(f_name as string)
dim img_width_lo_byte as byte
dim img_width_hi_byte as byte
dim img_height_lo_byte as byte
dim img_height_hi_byte as byte
dim img_width as short
dim img_height as short
dim img_bit as integer
#f = freefile
open f_name for binary as #f
get #f, 12, img_width_hi_byte 'and &hff
get #f, 13, img_width_lo_byte 'and &hff
get #f, 14, img_height_hi_byte' and &hff
get #f, 15, img_height_lo_byte 'and &hff
img_width = img_width_hi_byte shl 1 or img_width_lo_byte
img_height = img_height_hi_byte shl 1 or img_height_lo_byte
dim img_array as integer ptr
img_array = callocate(len(integer) * (img_width * img_height) + 3)
img_array[0] = img_width - 1
img_array[1] = img_height - 1
for i = 0 to img_width * img_height
get #f, 18 + i shl 2, img_array[i + 2]
next i
close #f
return img_array
end function
-
Wow that is so amazing - ive just been messing with the code and created an additional 'sprite' with alpha transparency and it works a treat - one image overlapping the other at different times causes a fantastic effect! Also got 32 'sprites' x 2 now (two images so two lots of 16).
Thanks for sharing MrP.
Ive attached what ive done - just for info . . .
-
Mr. P that lib works perfectly, thanks very much for posting it and Drew, that was a cool example!
-
I'm currently converting the drawing portion into mmx instructions using the inline asm feature of Freebasic. To be honest my brain has been bleeding for a couple of days or so now, but I have it working. Not bad considering that three days ago i hadn't done any asm on the pc at all.... I'm hoping to get a 2-3 times overall speed increase because using mmx you can calculate the alpha information on two pixels simultaneously. Like I said haven't done anyhting like this before so my hopeful speed increase might be a pipe dream. I'll post back when i have it working properly.....
@Shockwave - Not a problem at all. I'll post the other blending functions when i get them in properly
@DrewPee - Glad you liked it, and even more glad you had a bit of fun with it to. Kinda makes it all worth while
-
For some reason in the latest Freebasic / FBIDE the loader doesn't want to compile without giving me errors.
But it looks very cool, nice one Mr P / DrewPee. :)
-
That's the problem I have with updating. I know I should do it but I'm afraid that stuff like this will stop working if I do.
Btw, Clyde I'm sure that Drew's attachment contains an Exe, I seem to remember running it.
-
I always update if there's one available, thing that throws me sometimes is finding which includes to update from the CVS.
The error I get with the ImageLoader is "Function result wasn't explicitly set"
DrewPee, thats a pretty cool bob display you've got there.
-
All credit must go to MrP though - its his code with a bit added in by me . . . :)
But thanks anyway!
DrewPee
-
Function result wasn't explicitly set
That's because Functions are supposed to return a value. You should use Sub instead if you're not planning to return a value.
As a workaround, just add 'Return 0' to the end of the functions that complain.
Jim
-
Guess thats my bad it wont compile on the newer version. I know that functions should return something and subs dont, and hence only the loadimage should be a function cos thats the only thing that returns anything. Sorry about that peeps. My bad, guess I just had a function thing going that day....
-
No biggie. FB normally just emits a warning and adds return 0 to the end anyway.
Jim