Author Topic: [C++] Converting FreeBASIC Pointer Types into a Class  (Read 43430 times)

0 Members and 1 Guest are viewing this topic.

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #20 on: August 16, 2009 »
Move this line
gfx_buffer *screen_buffer=create_gfx_buffer( 640, 480 );
inside main(), before set_graphics().
We can talk about static initialisers later.  Nothing 'before' main gets run.  It's not like FB where it starts at the top, it starts by running main().

Please change to 'Debug' configuration while we work out the problems.

Jim

Challenge Trophies Won:

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #21 on: August 17, 2009 »
Cheers! :)

how do I use the load_image function dude? Ive tried &, @ and * allready before the array names.

gfx_buffer *my_image=load_image( cool_raw(0), cool_pal(0), 480, 92 );
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #22 on: August 17, 2009 »
gfx_buffer *my_image=load_image( cool_raw(0), cool_pal(0), 480, 92 );

In C, arrays use [] brackets, where in FB it was ().
So, cool_raw[0] would be the first byte in in the raw data.
But, you want to pass the address of the first byte, and in C that is &, where in FB it was @.
So that would be
&cool_raw[0]
which will work OK.
But even more simply, arrays are already the address of the first element, so just
cool_raw
will work.
Plus you have the arguments round the wrong way :P
So either
Code: [Select]
gfx_buffer *my_image=load_image( &cool_pal[0], &cool_raw[0], 480, 92 );
or
gfx_buffer *my_image=load_image( cool_pal, cool_raw, 480, 92 );

Jim
Challenge Trophies Won:

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #23 on: August 17, 2009 »
Ah Doh! All fixed up now thanks dude.

A few questions on what I've been shown and learnt so far.

1) what does extern (external) actually do? Couldn't I use #include "raw_image.cpp" ?

2) I've tried using #include <string.h> but I can't use the string scope.

3) I notice there isnt a MOD command, how is the calc for rounding width in the load function work?

4) I can't find much on using IF, i've found else, what Im looking for is using and ( logical And && ) instead of this long process of elimination:

Code: [Select]
// basic lingo example: if (x>0) and (x<wwidth-1) then

if (x>0)
if (x<width)
if (y>0)
if (y<height)
insert_clever_code_here();

Thanks a million for helping a CPP / Visual Studio newb out!
Cheers Clyde.
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #24 on: August 17, 2009 »
Quote
what does extern (external) actually do? Couldn't I use #include "raw_image.cpp" ?
extern is just an external reference which tells the compiler everything is OK and the linker will fix it up later.  You *could* rename raw_image.cpp to raw_image.h and #include it, but the problem with that is it will get build every single time you compile.  If you leave it as a separate file it only gets rebuilt if it changes.  Using extern is way better.

Quote
I've tried using #include <string.h> but I can't use the string scope.
After all your #includes add the line
Code: [Select]
using namespace std;

Quote
I notice there isnt a MOD command, how is the calc for rounding width in the load function work?
The MOD command for integer types is %.  So 10%7=3.
& is bitwise AND.   &3 is the same as doing MOD 4.
If you think about it, all numbers that are divisible by 4 in binary don't have the lower two bits set (the 1 bit and the 2 bit).  So what I want to do is remove them and round up if there were any.  So

so if we look at the numbers, if it ends in 00b then I want to leave width alone, since it's already divisible by 4, 01b then I want to add 3, 10b add 2, 11b add 1.

00&3=0 (want to add 0)
01&3=1 (want to add 3)
10&3=2 (want to add 2)
11&3=3 (want to add 1)

4-(00&3)=4 (wrong)  4 is 100b
4-(01&3)=3 (right)    3 is 011b
4-(10&3)=2 (right)    2 is 010b
4-(11&3)=1 (right)    1 is 001b

100&3=0 (right)
011&3=3 (right)
010&3=2 (right)
001&3=1 (right)

So, ((4-(width&3)&3)
gives me the number I want to add.  Magic eh?

Quote
I can't find much on using IF, i've found else
You should be able to find these on any good C++ website.
&& (logical and)
|| (logical or)
<
>
== (equals - You MUST use a double ==)
<=
>=
!= (not equals, same as < > in FB)

The format is something like
Code: [Select]
if (a>b)
{
//something
}
else if (b>c)
{
//something else
}
else
{
//otherwise
}


Jim
« Last Edit: August 17, 2009 by Jim »
Challenge Trophies Won:

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #25 on: August 18, 2009 »
Cheers for the explanations dude! Magic :)

One other Class and pointer help, this time using a pointer pointer, called anim_buffer, basically this is a way or recording what frame_number links with a particular image frame as a gfx_buffer pointer pointer. I dont want to use a system of arrays of types sort of thang, as each tiled image will have different sizes depending on what it's of, i'd like it to follow more or less the way i've been upto things in FreeBASIC and pointers.

An example of how it's drawn: anim_buffer_1->frame[ 6 ] ( frame being told to draw frame 6 which is a gfx_buffer pointer.

here's the freeBASIC type.

Code: [Select]
type anim_image
    total_frames as integer
    frame_Width As Integer
    frame_Height As Integer
    frame as gfx_buffer pointer pointer
end type


function create_anim_images(byval srce As gfx_buffer Pointer,_
                            byval wwidth        As Integer,_
                            byval height        As Integer) As anim_image pointer

    dim as integer framesw=srce_buffer->wwidth\wwidth
    dim as integer framesh=srce_buffer->height\height

    dim as anim_image pointer image=callocate(len(anim_image))
    image->frame        =callocate(len(gfx_buffer pointer)*framesw*framesh)
   
    dim as integer frame_number,x,y
    for y=0 to (framesh-1)*height step height
        for x=0 to (framesw-1)*wwidth step wwidth
           
            image->frame[frame_number]=create_gfx_buffer(wwidth,height)
            draw_image(image->frame[frame_number],srce,-x,-y)
           
            frame_number+=1
           
        next
    next
   
    //;delete_gfx_buffer(srce)
   
    image->frame_wwidth=wwidth
    image->frame_height=height
    image->total_frames=framesw*framesh
   
    return image

End function

I've made a start on the class setup in c++, but am a little baffled and would love a hand sorting out the rest of the puzzle.

CPP class.
Code: [Select]
class anim_buffer
{
public:
int total_frames;
int frame_wwidth, frame_height;
gfx_buffer **frame;
};

Thankyou so much,
Clyde.
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #26 on: August 18, 2009 »
We should think this whole thing out again for C++.  The FB code is terrible and isn't worth porting unless there's a really good reason.  What's the spec?  Where is the data coming from, what is the intended use?  What kind of interface (what functions) would you like to be able to use?

How's it going, by the way?  Have you managed to plot a sprite yet?  Or (gasp!) a pixel with this new framework?

Jim
« Last Edit: August 18, 2009 by Jim »
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #27 on: August 18, 2009 »
gfx_buffer **frame;
To allocate this, first you need to allocate space for the pointers:
Code: [Select]
frame = new gfx_buffer *[num_frames];
then you need to allocate the frames
Code: [Select]
for (int i=0; i<num_frames; i++)
  frame[i] = new gfx_buffer(...);

If I were doing this, my anim_buffer class would inherit from and extend my gfx_buffer class.

Jim
Challenge Trophies Won:

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #28 on: August 19, 2009 »
Yeah I can draw images which is wicked ;)
Im running into problems in how to use sin / cos, as in the <math.h> there's 3 types of overloaded functions.

if i use sin( formula ) i then get told to use one of the three available, in this example im after the float sin one, but if i put float sin in, im then told float unexpected.


With regards to the bitmap font splitter / animation frames.

1 ) a gfx buffer is loaded which is the full size image that contains all the letters.

2 ) through the create_anim_buffer, frame[ frame_number ] corresponds to the individual list of individual images, to make them they are drawn to a newly created gfx_buffer, as in my examples above.

3) then in the draw_anim_image() routine, it would go someting like this:
void draw_anim_image( gfx_buffer *dest, anim_image *srce, int x, int y, int frame );
...
draw_gfx_buffer( screen_buffer, srce->frame[ frame ], pos_x, pos_y );

using bitmap fonts is going to be a big bonus.

Many thanks,
Clyde.
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #29 on: August 19, 2009 »
Try sinf() instead of sin() for float.  All the math.h functions use double, normally.

Jim
Challenge Trophies Won:

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #30 on: August 19, 2009 »
Before going onto the bitmap font routine, i want to sort out the sin problems im having.
You may remember my neighbour Trantor using this in a code help topic for FB.

When I run this, all i get is one pixel doing a sinus motion up and down.

I get warnings of possible loss of data and some other bits, which I'll post under the c++ code. Hopefully you wont need the raw and palette image files.

Code: [Select]
//
// includes.
//
#include <windows.h>
#include <tinyptc_ext.h>
#include <math.h>

extern unsigned char gb_pal[];
extern unsigned char gb_raw[];

extern unsigned char sca_pal[];
extern unsigned char sca_raw[];


#define PI 3.141593f
#define DEGREES (PI/180.00f)


//
// classes.
//
class gfx_buffer
{
public:
int wwidth, height;
int wwidth2, height2;
unsigned int *pixels;

};

//
// function declarations.
//
int set_graphics( char *title, int wwidth, int height );

gfx_buffer *create_gfx_buffer( int wwidth, int height);
gfx_buffer *load_gfx_buffer( unsigned char *pal, unsigned char *raw, int wwidth, int height);

//
// sub routines.
//
void draw_buffer_rect( gfx_buffer *dest, gfx_buffer *srce, int pos_x, int pos_y, int rect_x, int rect_y, int rect_wwidth, int rect_height );
void draw_gfx_buffer( gfx_buffer *dest, gfx_buffer *srce, int pos_x, int pos_y );

int main()
{
//
// initializing.
//
gfx_buffer *screen_buffer=create_gfx_buffer( 640, 480 );
gfx_buffer *gravity_image=load_gfx_buffer( gb_raw, gb_pal, 300, 300 );

set_graphics( ".:wIgGlE jIgGlE:.", 640, 480 );

int x=0,y=0;
int sin_y=0;
int cos_x=0;
int sin_height=24;
int angle1=0;

//
// main program loop.
//
while(1)
{
//
// clear screen_buffer.
//
for( int index=0; index<(screen_buffer->wwidth*screen_buffer->height); index++)
screen_buffer->pixels[ index ]=0x000000;

//
// wiggle it.
//
for ( x=0; x<gravity_image->wwidth; x++)
{
sin_y=sin_height * sin( (angle1+x)*(DEGREES));

draw_buffer_rect( screen_buffer, gravity_image, x, sin_y, x, 0, 1, gravity_image->height );
}   
 
angle1+=1;

//
// render to the screen_buffer.
//
ptc_update( &screen_buffer->pixels[0] );

}
}


int set_graphics( char *title, int wwidth, int height )
{
ptc_allowclose(1);
ptc_setflip(1);

ptc_setdialog(1,"Would You Prefer Full Screen Dude?",1,0);

if (!ptc_open( title,wwidth,height))
return 1;
else
return 0;

}


gfx_buffer *create_gfx_buffer( int wwidth, int height )
{
gfx_buffer *buffer = new gfx_buffer;

buffer->pixels = new unsigned int [wwidth*height];

buffer->wwidth = wwidth;
buffer->height = height;

buffer->wwidth2=wwidth/2;
buffer->height2=height/2;

return buffer;
}


void draw_gfx_buffer( gfx_buffer *dest, gfx_buffer *srce, int pos_x, int pos_y )
{
for (int y=0; y<srce->height; y++)
for (int x=0; x<srce->wwidth; x++)
dest->pixels[ (x+pos_x)+(y+pos_y) * dest->wwidth ]=srce->pixels[ x+y*srce->wwidth ];
}


void draw_buffer_rect( gfx_buffer *dest, gfx_buffer *srce, int pos_x, int pos_y, int rect_x, int rect_y, int rect_wwidth, int rect_height )
{                   

    unsigned int col;
    int x,y;

    for ( y=0; y<rect_height; y++)
        for ( x=0; x<rect_wwidth; x++)
           
            if (x+rect_x>0) 
if (x+rect_x<srce->wwidth-1)
if (y+rect_y>0)
if (y+rect_y<srce->height-1)
col=srce->pixels[ (x+rect_x) + (y+rect_y) * srce->wwidth ];
            end if
           
            if (x+pos_x>0)
if (x+pos_x<dest->wwidth-1)
if(y+pos_y>0)
if(y+pos_y<dest->height-1)
//if(col>0)
dest->pixels[ (x+pos_x) + (y+pos_y) * dest->wwidth ]=col;
}


gfx_buffer *load_gfx_buffer(unsigned char *raw, unsigned char *pal, int wwidth, int height)
{
//
// round width up to next multiple of 4.
//
wwidth += ( 4-( wwidth&3 )) & 3;

//
// create a new image.
//
gfx_buffer *buffer = create_gfx_buffer( wwidth, height );
   
//
// convert the palette to 32 bit ( requires alpha channel set )
//
unsigned int palette[256];
int index;

for ( index=0; index < 256; index++ )
palette[ index ] = 0xff000000 | ( pal[ index*3 ] << 16) | ( pal[ index*3+1 ] << 8) | pal[ index*3+2 ];

//
// convert the pixels.
//
for ( index=0; index<(wwidth*height); index++)
buffer->pixels[ index ] = palette[ *raw++ ];

return buffer;
}

Compiler Warnings:
Compiling...
wiggle it 1-1.cpp
.\wiggle it 1-1.cpp(81) : warning C4244: '=' : conversion from 'double' to 'int', possible loss of data
Linking...
Generating code
Finished generating code
MSVCRT.lib(cpu_disp.obj) : warning LNK4210: .CRT section exists; there may be unhandled static initializers or terminators
Embedding manifest...

Semi Colon Adventures 1 - 0 error(s), 2 warning(s)
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========


Cheers and all the very best,
Clyde.

Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #31 on: August 19, 2009 »
In draw_buffer_rect() you have two for loops.  The middle for loop is supposed to contain an 'if' that gets the colour AND and 'if' that sets the colour.  You need to tell the compiler that:
Code: [Select]
for (y...)
  for (x...)
  {//need this bracket
     if ()
      ...
     if ()
      ...
  }//and this bracket
The curly braces group expressions together.  Otherwise only the first expression after the control expression is used.  I often use {} even when I don't need to to make the grouping more clear. eg. in the code above, I'd have {} belonging to the (for y) going round the whole thing, just for clarity.

You also have a stray 'end if' in there.

Your other 'loss of data' problem:
One MAJOR difference between C++ and FB or C is that C++ is a strongly typed language.  When you say something is an 'int' it MEANS IT!  When you say something is 'double' it MEANS IT!
If you 'accidentally' assign something of one type to an object of another type then in FB or C it would just do it.  In C++ you need to tell the compiler that you know what you are doing.
The 'loss of data' warning is because sin() return a double, but you are assigning it to an int.  The compiler is telling you there's something wrong.
eg.
Code: [Select]
double a=0.5;
int b=a;
will give you the same warning.  You have 'lost' data because b==0 now.
If you intend to do this, you need to tell the compiler you mean it:
Code: [Select]
double a=0.5;
int b=(int)a;
The 'type cast' operator turns one object into another in a meaningful way.

Sometimes not having the type cast is an error, not just a warning and you must put one it to make it compile.  This is GOOD in my opinion, and is one of the major benefits of strongly-typed languages over BASIC and C.

Absurdly, you will get the 'loss of data' even if you do this
Code: [Select]
int a=5;
float b=a;
Even though a float can hold much bigger numbers than an int, it's not possible to exactly represent every int as a float.
eg. try this
Code: [Select]
int a=2147483647;
float b=a;
a=b;
and display the value of a. (hint: it's NOT 2147483647)

This code won't give a warning though:
Code: [Select]
int a=5;
double b=a;
a double can hold all integer values.

Jim
« Last Edit: August 19, 2009 by Jim »
Challenge Trophies Won:

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #32 on: August 20, 2009 »
Huge thanks Jim :)

I have one other question before bed.
how would one do the equivalent of for a=0 to 320 step 32 ?
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #33 on: August 20, 2009 »
Code: [Select]
for (int a=0; a < 320; a+=32)

a+=32
is C/C++ shorthand for
a=a+32

You can put any expression in there, including one that doesn't include a.
You can even do stuff like
Code: [Select]
int a,b;
for (a=0,b=0; a < 320; a+=32, b+=1)

Jim
Challenge Trophies Won:

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #34 on: August 20, 2009 »
Ok here's my font assembling routine which deals with variable width fonts, which I'd love if you could correct if for me; as i've been trying allsorts over the past few days and going in circles.

Presently im getting wierd results, every image frame, comes out as a green rectangle, which in itself is odd as there isnt any green in the bitmap font data what so ever.

Code: [Select]
//
// includes.
//
#include <windows.h>
#include <tinyptc_ext.h>

extern unsigned char font64_pal[];
extern unsigned char font64_raw[];


#define PI 3.141593
#define DEGREES (PI/180.00f)


//
// classes.
//
class gfx_buffer
{
public:
int wwidth, height;
int wwidth2, height2;
unsigned int *pixels;

};

class anim_image
{
public:
int frame_wwidth, frame_height;
int total_frames;
gfx_buffer **images;
};

//
// function declarations.
//
int set_graphics( char *title, int wwidth, int height );

gfx_buffer *create_gfx_buffer( int wwidth, int height);
gfx_buffer *load_gfx_buffer( unsigned char *pal, unsigned char *raw, int wwidth, int height);

anim_image *create_anim_images( gfx_buffer *srce, int wwidth, int height, int blank_wwidth, int min_wwidth, int spacing );

//
// sub routines.
//
void draw_gfx_buffer( gfx_buffer *dest, gfx_buffer *srce, int pos_x, int pos_y );

int main()
{
//
// initializing.
//
gfx_buffer *screen_buffer=create_gfx_buffer( 640, 480 );

gfx_buffer *font_image=load_gfx_buffer( font64_raw, font64_pal, 512, 512 );
anim_image *font_one=create_anim_images( font_image, 64, 64, 32, 32, 1 );

set_graphics( "gRaPhIcS aNtIcS", 640, 480 );



// main program loop.
while(1)
{
// clear screen.
for( int index=0; index<(screen_buffer->wwidth*screen_buffer->height); index++)
screen_buffer->pixels[index]=0x000000;
// next index

draw_gfx_buffer( screen_buffer, font_one->images[19], 0, 0 );
//draw_gfx_buffer( screen_buffer, font_image,0,0);


// render to the screen buffer.
ptc_update( &screen_buffer->pixels[0] );

} // wend.

} // end function main()



int set_graphics( char *title, int wwidth, int height )
{
ptc_allowclose(1);
ptc_setflip(1);

ptc_setdialog(1,"Would You Prefer Full Screen Dude?",1,0);

if (!ptc_open( title,wwidth,height))
return 1;
else
return 0;
// end if.

}


gfx_buffer *create_gfx_buffer( int wwidth, int height )
{
gfx_buffer *buffer = new gfx_buffer;

buffer->pixels = new unsigned int [wwidth*height];

buffer->wwidth = wwidth;
buffer->height = height;

buffer->wwidth2=wwidth/2;
buffer->height2=height/2;

return buffer;

}


void draw_gfx_buffer( gfx_buffer *dest, gfx_buffer *srce, int pos_x, int pos_y )
{
for (int y=0; y<srce->height; y++)
for (int x=0; x<srce->wwidth; x++)

if (x+pos_x>0)
if (x+pos_x<dest->wwidth-1)
if (y+pos_y>0)
if (y+pos_y<dest->height-1)

dest->pixels[ (x+pos_x)+(y+pos_y) * dest->wwidth ]=srce->pixels[ x+y*srce->wwidth ];
// next x.
//next y
}




gfx_buffer *load_gfx_buffer(unsigned char *raw, unsigned char *pal, int wwidth, int height)
{
//
// round width up to next multiple of 4.
//
wwidth += ( 4-( wwidth&3 )) & 3;

//
// create a new image.
//
gfx_buffer *buffer = create_gfx_buffer( wwidth, height );
   
//
// convert the palette to 32 bit.
//
unsigned int palette[256];
int index;

for ( index=0; index < 256; index++ )
palette[ index ] = 0xff000000 | ( pal[ index*3 ] << 16) | ( pal[ index*3+1 ] << 8) | pal[ index*3+2 ];
// next index

//convert the pixels
for ( index=0; index<(wwidth*height); index++)
buffer->pixels[ index ] = palette[ *raw++ ];
// next index

return buffer;
}

anim_image *create_anim_images( gfx_buffer *srce, int wwidth, int height, int blank_wwidth, int min_wwidth, int spacing )
{
int frame_w= srce->wwidth / wwidth;
int frame_h= srce->height / height;
int total_frames= frame_w * frame_h;

anim_image *anim_buffer = new anim_image;

anim_buffer->images=new gfx_buffer *[ total_frames ];

if (blank_wwidth==0)
blank_wwidth=wwidth;
   
if (min_wwidth>wwidth)
min_wwidth=wwidth;

int frame_number=0, x=0, y=0, test_l=0, test_r=0, x_test=0, y_test=0;

for (y=0; y<(frame_h-1)*height; y+=height )
{
for (x=0; x<(frame_w-1)*wwidth; x+=wwidth )
{
//
// test x.
//
test_r=x;
           
for ( x_test=x; x_test<(x+wwidth-1); x_test+=1 )
{
for ( y_test=y; y_test<(y+height-1); y_test+=1 )
{
if (srce->pixels[ (x_test)+(y_test) * srce->wwidth]!=0xff000000)
test_r=x_test;
} // next y_test.
} //next x_test.


//
// test l.
//
test_l=x+wwidth-1;
           
for ( x_test=x+wwidth-1; x_test<x; x_test-=1 )
{
                for ( y_test=y; y_test<(y+height-1); y_test=+1)
{
if (srce->pixels[ (x_test)+(y_test)*srce->wwidth]!=0xff000000)
test_l=x_test;
}
// next y_test.
} // next x_test.


//
// bob the builder time! :)
//
if (test_r>=test_l)
{   
test_l-=spacing >> 1;
                test_r+=spacing-(spacing >> 1);
               
if ((test_r-test_l)<min_wwidth)
{
x_test=min_wwidth-(test_r-test_l);
                    test_r+=x_test >> 1 ;
                    test_l-=x_test-(x_test >> 1);
} //end if
               
if (test_r>x+wwidth-1)
test_r=x+wwidth-1;


if (test_l<x)
{
test_l=x;
anim_buffer->images[frame_number]=create_gfx_buffer(test_r-test_l+1,height);
draw_gfx_buffer( anim_buffer->images[frame_number],srce,-test_l,-y);
}
}
else
{
anim_buffer->images[frame_number]=create_gfx_buffer(blank_wwidth,height);
} // end if

frame_number+=1;

} // next x
}// next y

anim_buffer->frame_wwidth = frame_w;
anim_buffer->frame_height = frame_h;
anim_buffer->total_frames = total_frames;

return anim_buffer;
}

freebasic equivalent function and types.
Code: [Select]
type gfx_buffer
    wwidth as integer
    height as integer
    pixels as uinteger pointer
end type

type anim_image
    total_frames as integer
    FrameWWidth As Integer
    FrameHeight As Integer
    frame as gfx_buffer pointer pointer
end type

function create_anim_images(byval source_buffer As gfx_buffer Pointer,_
                    byval wwidth        As Integer,_
                    byval height        As Integer,_
                    byval blank_wwidth as integer=0,_
                    byval min_wwidth as integer=0,_
                    byval spacing as integer=1) As anim_image pointer

    dim as integer framesw=source_buffer->wwidth\wwidth
    dim as integer framesh=source_buffer->height\height
   
    if blank_wwidth=0 then blank_wwidth=wwidth
    if min_wwidth>wwidth then min_wwidth=wwidth
   
    dim as anim_image pointer image=callocate(len(anim_image))
    image->frame=callocate(len(gfx_buffer pointer)*framesw*framesh)

   
    dim as integer frame_number,x,y,test_l,test_r,x_test,y_test
    for y=0 to (framesh-1)*height step height
        for x=0 to (framesw-1)*wwidth step wwidth
           
            test_r=x
            for x_test=x to x+wwidth-1
                for y_test=y to y+height-1
                    if source_buffer->pixels[x_test+y_test*source_buffer->wwidth]<>0 then test_r=x_test
                next
            next
           
            test_l=x+wwidth-1
            for x_test=x+wwidth-1 to x step-1
                for y_test=y to y+height-1
                    if source_buffer->pixels[x_test+y_test*source_buffer->wwidth]<>0 then test_l=x_test
                next
            next
           
            if test_r>=test_l then
                test_l-=spacing shr 1
                test_r+=spacing-(spacing shr 1)
                if (test_r-test_l)<min_wwidth then
                    x_test=min_wwidth-(test_r-test_l)
                    test_r+=x_test shr 1
                    test_l-=x_test-(x_test shr 1)
                end if
                if test_r>x+wwidth-1 then test_r=x+wwidth-1
                if test_l<x then test_l=x
                image->frame[frame_number]=create_gfx_buffer(test_r-test_l+1,height)
                draw_image(image->frame[frame_number],source_buffer,-test_l,-y)
            else
                image->frame[frame_number]=create_gfx_buffer(blank_wwidth,height)
            end if

            frame_number+=1
           
        next
    next
   
    delete_gfx_buffer(source_buffer)
   
    image->FrameWWidth=WWidth
    image->FrameHeight=Height
    image->total_frames=framesw*framesh
   
    return image

End function

Thanks so much in advance,
Clyde.
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #35 on: August 20, 2009 »
This won't work
Code: [Select]
for ( x_test=x+wwidth-1; x_test<x; x_test-=1 )
You write the equivalent of
Code: [Select]
For x=10 To 0 Step -1
as
Code: [Select]
for (x = 10; x >=0; x-=1)
Mostly you just need to change the < to a >= when you are counting downwards.

Looks like you've made a mistake here:
Code: [Select]
if (test_l<x)
{
test_l=x;
anim_buffer->images[frame_number]=create_gfx_buffer(test_r-test_l+1,height);
draw_gfx_buffer( anim_buffer->images[frame_number],srce,-test_l,-y);
}
should be
Code: [Select]
if (test_l<x)
test_l=x;
anim_buffer->images[frame_number]=create_gfx_buffer(test_r-test_l+1,height);
draw_gfx_buffer( anim_buffer->images[frame_number],srce,-test_l,-y);

Jim

« Last Edit: August 20, 2009 by Jim »
Challenge Trophies Won:

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #36 on: August 20, 2009 »
so those braces weren't needed.

for the step -1 bit?
Code: [Select]
for ( x_test=x+wwidth-1; x_test>=x; x_test-=1 )

For some reason now, it builds but the program doesnt run. before hand I had the dialog box for fullscreen... [yes] [no]
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #37 on: August 21, 2009 »
I think (but you can correct me if I'm wrong) you put braces in the wrong place.  I think with braces, it should have been:
Code: [Select]
if (test_l<x)
{
test_l=x;
}
anim_buffer->images[frame_number]=create_gfx_buffer(test_r-test_l+1,height);
draw_gfx_buffer( anim_buffer->images[frame_number],srce,-test_l,-y);

For loop?  Yes, that looks OK.

Dialog box missing? It must be stuck in an infinite loop creating the font, so it never gets there.

Jim

Challenge Trophies Won:

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #38 on: August 22, 2009 »
Im puzzled, it's not going to plan as in the Freebasic comparison version.
So I'll have to come up with a completely different way.
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #39 on: August 22, 2009 »
Don't be silly.  There's just some simple bug that needs fixing.  Can you post the *actual* code you're building and the test file and I will try to fix it up for you.

Jim
Challenge Trophies Won: