Author Topic: TinyPTC image loader  (Read 10787 times)

0 Members and 1 Guest are viewing this topic.

Offline MrP

  • Atari ST
  • ***
  • Posts: 176
  • Karma: 18
    • View Profile
TinyPTC image loader
« 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.....

« Last Edit: August 18, 2006 by MrP »

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17412
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: TinyPTC image loader
« Reply #1 on: August 17, 2006 »
Something like this should work;

Code: [Select]
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 :)
Shockwave ^ Codigos
Challenge Trophies Won:

Offline MrP

  • Atari ST
  • ***
  • Posts: 176
  • Karma: 18
    • View Profile
Re: TinyPTC image loader
« Reply #2 on: August 17, 2006 »
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.......

Code: [Select]
'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....
« Last Edit: August 17, 2006 by MrP »

Offline Rbz

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 2757
  • Karma: 493
    • View Profile
    • https://www.rbraz.com/
Re: TinyPTC image loader
« Reply #3 on: August 17, 2006 »
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  :)


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

Offline MrP

  • Atari ST
  • ***
  • Posts: 176
  • Karma: 18
    • View Profile
Re: TinyPTC image loader
« Reply #4 on: August 18, 2006 »
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.....
« Last Edit: August 18, 2006 by MrP »

Offline Rbz

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 2757
  • Karma: 493
    • View Profile
    • https://www.rbraz.com/
Re: TinyPTC image loader
« Reply #5 on: August 18, 2006 »
I think that FB did the same thing like C++ (destroy)

Check this out


doesn't work:
Code: [Select]
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:
Code: [Select]
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
Challenge Trophies Won:

Offline MrP

  • Atari ST
  • ***
  • Posts: 176
  • Karma: 18
    • View Profile
Re: TinyPTC image loader
« Reply #6 on: August 18, 2006 »
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

Offline MrP

  • Atari ST
  • ***
  • Posts: 176
  • Karma: 18
    • View Profile
Re: TinyPTC image loader
« Reply #7 on: August 18, 2006 »
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).....

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

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: TinyPTC image loader
« Reply #8 on: August 18, 2006 »
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.

Code: [Select]

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.
« Last Edit: August 18, 2006 by Stonemonkey »

Offline MrP

  • Atari ST
  • ***
  • Posts: 176
  • Karma: 18
    • View Profile
Re: TinyPTC image loader
« Reply #9 on: August 18, 2006 »
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

Offline MrP

  • Atari ST
  • ***
  • Posts: 176
  • Karma: 18
    • View Profile
Re: TinyPTC image loader
« Reply #10 on: August 18, 2006 »
scrap that apparently that doesn't work either. Stonemonkey your right you can only do it with callocate...... Cheers Matey....

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: TinyPTC image loader
« Reply #11 on: August 18, 2006 »
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
Challenge Trophies Won:

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: TinyPTC image loader
« Reply #12 on: August 18, 2006 »
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.
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: TinyPTC image loader
« Reply #13 on: August 18, 2006 »
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.

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: TinyPTC image loader
« Reply #14 on: August 19, 2006 »
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
Challenge Trophies Won:

Offline MrP

  • Atari ST
  • ***
  • Posts: 176
  • Karma: 18
    • View Profile
Re: TinyPTC image loader
« Reply #15 on: August 21, 2006 »
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.......

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

« Last Edit: August 21, 2006 by MrP »

Offline DrewPee

  • I Toast Therefore I am
  • Pentium
  • *****
  • Posts: 563
  • Karma: 25
  • Eat Cheese - It's good for you!
    • View Profile
    • Retro Computer Museum
Re: TinyPTC image loader
« Reply #16 on: August 24, 2006 »
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 . . .
DrewPee
aka Falcon of The Lost Boyz (Amiga)
Ex-Amiga Coder and Graphic Designer
Administrator of > www.retrocomputermuseum.co.uk

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17412
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: TinyPTC image loader
« Reply #17 on: August 24, 2006 »
Mr. P that lib works perfectly, thanks very much for posting it and Drew, that was a cool example!
Shockwave ^ Codigos
Challenge Trophies Won:

Offline MrP

  • Atari ST
  • ***
  • Posts: 176
  • Karma: 18
    • View Profile
Re: TinyPTC image loader
« Reply #18 on: August 25, 2006 »
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
« Last Edit: August 25, 2006 by MrP »

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: TinyPTC image loader
« Reply #19 on: August 28, 2006 »
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. :)
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

Challenge Trophies Won: