• Welcome to Dark Bit Factory & Gravity.
 

[C++] Converting FreeBASIC Pointer Types into a Class

Started by Clyde, August 14, 2009

Previous topic - Next topic

0 Members and 0 Guests are viewing this topic.

Clyde

Thanks to the dudes who've got me this far! ;)

As I'm learning how to use Pointers & Type in FreeBASIC with TinyPtc_ext, I'd like to also continue this with my semi colon adventures in the world of CPP.

And I wonder if you could spare some time and help me sort out my initial steps, im working with a class in replace of a type, I think I've got the method of casting a pointer variable for the class, im stuck on allocating the correct amount of space for the class & pointer.

Firstly here's the FreeBASIC source / method


type gfx_buffer
   wwidth as integer
   height as integer

   pixels as uinteger pointer

end type

dim as gfx_buffer ptr screen_buffer

screen_buffer=create_gfx_buffer( 640, 480 )


function create_gfx_buffer(byval wwidth as integer,_
                           byval height as integer )as gfx_buffer pointer
   
   dim as gfx_buffer pointer buffer
   
   buffer=callocate(len(gfx_buffer)+len(uinteger)*wwidth*height)
   

   buffer->wwidth=wwidth
   buffer->height=height
   
   buffer->pixels=cast(uinteger pointer,cast(byte pointer,buffer)+len(gfx_buffer))
 
   return buffer

end function


C++ Source:

#include <windows.h>

// remember ( ALT+F7) to add linker -> input -> dependencies 'libmmx.lib' & 'libtinyptc_ext.lib'
#include <tinyptc_ext.h>


const int XRES=640;
const int YRES=480;
const int ARES=XRES*YRES;

class gfx_buffer {
public:
int wwidth, height, wwidth2, height2;
unsigned int *pixels;
};

static gfx_buffer* screen_buffer;

// functions.
int set_graphics( int wwidth, int height );
gfx_buffer* create_gfx_buffer( int wwidth, int height );

screen_buffer=create_gfx_buffer( 640, 480 )

int main()
{
set_graphics( XRES, YRES );

while (1)
{
// clear screen.

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

gfx_buffer* create_gfx_buffer( int wwidth, int height )
{
gfx_buffer* buffer=callocate
}


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

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

   if (!ptc_open("mOnKeY bUiSnEsS 1",XRES,YRES)) return 1;

return 0;

}


It's the calallocate and length thats probably my main problem, providing the rest of the class and variables as pointer are correct.

Here's a link to the MSVC version of tinyptc_ext courtesy of rbz: http://www.dbfinteractive.com/forum/index.php?action=dlattach;topic=3981.0;attach=4574


Cheers and hugest of thanks,
Clyde
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.


Challenge Trophies Won:

Jim

The equivalent of callocate is malloc().  You need to #include <stdlib.h> to use it.
Since you're using a class, you can't pull the same trick that you do in FB of allocating the structure and the framebuffer at the same time.  To allocate classes you use the 'new' operator.
You could do something like:

gfx_buffer *screen_buffer = new gfx_buffer;
screen_buffer->pixels = new unsigned int [width * height];

Even better, your class should do this in its constructor:

class gfx_buffer
{
private:
int width, height;
unsigned int *pixels;

public:
//constructor
gfx_buffer(int w, int h)
{
 width = w;
 height = h;
 pixels = new unsigned int [w*h];
}

//destructor
~gfx_buffer()
{
 delete [] pixels;
}

// getters
int get_width() { return width; }
int get_height() { return height; }
unsigned int *get_pixels() { return pixels; }

//other methods, eg.

void setpixel(int x, int y, unsigned int colour)
{
if (x>=0 && x < width && y>=0 && y < height)
 pixels[x+y*width] = colour;
}

void plotsprite(int x, int y, gfx_buffer *sprite)
{
//draw sprite into this gfx_buffer at x,y
}

}


Then, in your main() function, you can create lots of images with no work:

gfx_buffer *screen = new gfx_buffer(640,480);
gfx_buffer *sprite = new gfx_buffer(64,64);
...
//and the code you're looking for
ptc_update(screen->get_pixels());



Then you can extend the methods in the gfx_buffer class.

Jim
Challenge Trophies Won:

Clyde

Bingo & Cool!!

For maloc, and the way I did similar in FB i'd need to do a struct-ure then dude?
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.


Challenge Trophies Won:

Jim

Yes, typedef/struct:

typedef struct
{
int x, y;
unsigned int *pixels;
} gfx_buffer;
...
gfx_buffer *screen = (gfx_buffer *)malloc(sizeof *screen + 640*480*sizeof(unsigned int));
screen->pixels = (unsigned int *)(((char *)screen)+sizeof *screen);

But this is NASTY!  The C++ in my previous post is WAY WAY WAY better coding style.

Jim
Challenge Trophies Won:

Clyde

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


Challenge Trophies Won:

Clyde

Whilst im still up, hows about a conversion of this routine in FB for loading an image from a file / binary.





#include "raw_data.bi"
#include "pal_data.bi"

dim as gfx_buffer ptr image1
image1=load_image_8bit(32,32,@raw_variable_name_ubyte(0),@pal_variable_name_ubyte(0))

function Load_Image_8bit( byval image as ubyte pointer,byval palet as ubyte pointer,byval wwidth as integer,byval height as integer )as gfx_buffer pointer
   
   while ((wwidth mod 4) <> 0)
       wwidth += 1
   wend
   
   dim as gfx_buffer pointer buffer=create_gfx_buffer(wwidth,height)
   dim as uinteger pal(0 to 255), col
   dim as integer a,x,y
   
   for a=0 to 255
       pal(a)=(palet[a*3] shl 16)or(palet[a*3+1] shl 8)or(palet[a*3+2]) 'or &HFF000000
   next    
   
   for y=0 to height-1
       for x=0 to wwidth-1
           buffer->pixels[ x+y*wwidth ]=pal(image[x+(y*wwidth)])
       next
   next
   
   return buffer

end function


I have yet to find a bmp2raw for C++, and also Binary2... ( i presume either a header or cpp file, or infact a .bi ) but it would be awesome for a conversion of the above. the weekend i will be doing my first ever intro in CPP.

Cheers and thanks again dudes,
Clyde.
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.


Challenge Trophies Won:

hellfire

Quotehows about this routine in FB for loading an image from a file / binary.
I'm not quite sure what your question is, or if there is any ;)

QuoteI have yet to find a bmp2raw for C++, and also Binary2...
The binary version would be something like this but you've got a resource-manager in Visual Studio, so you can include your images as jpeg or png and let Windows do the decoding for you.
There's no need to apply colour-reduction and the result is still much smaller.
Code can be found here.

Challenge Trophies Won:

Clyde

thanks for the links they'll sure come in handy.

I'd like to keep it if pos, with a similar approach to the above; where the raw data and colour data is in a file. as im more familiar with it, I have just modified  the post as i'd left some bits out. Once im more comfortable with CPP, I'll look into resources.

Cheers and hugest of thanks,
Clyde.
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.


Challenge Trophies Won:

Jim

You can keep using bmp2raw and bin2bas, just take the .bas files and replace '&H' with '0x', remove the '_' at the line ends, and replace the headers with

unsigned char picture_pal[] =
unsigned char picture_raw[] =


Then the loader looks a bit like:

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

 //create a new image
 gfx_buffer *gfx = new gfx_buffer(width, height);

 //convert the palette to 32bit
 unsigned int palette[256];
 for (int i=0; i < 256; i++)
    palette[i] = 0xff000000 | (pal[i*3]<<16) | (pal[i*3+1] << 8) | pal[i*3+2];

 //convert the pixels
 unsigned int *pix = gfx->get_pixels();
 for (int j=0; j<width*height; j++)
    *pix++ = palette[*raw++];

 return gfx;
}


If you are feeling brave, you could make this a second constructor for your gfx_buffer class.

Finally, rename the .bas files to .cpp and add them to your project in the solution browser in Visual Studio.
In your main cpp file, at the top after the includes, add

extern unsigned char picture_pal[];
extern unsigned char picture_raw[];

That will tell the main cpp file where to find the picture data - you'd need this for each picture.

Jim

Challenge Trophies Won:

Clyde

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


Challenge Trophies Won:

Jim

Challenge Trophies Won:


Shockwave

¿Dónde están los sanitarios?
(Where is the toilet?)
Shockwave ^ Codigos
Challenge Trophies Won:

Clyde

el baño es sólo para niñas

I've tried doing this with having the setup and creation functions out of the class; just so I can have a practise. but am running into a few probs.


#include <windows.h>
#include <tinyptc_ext.h> // remember ( ALT+F7) to add linker -> input -> dependencies 'libmmx.lib' & 'libtinyptc_ext.lib'


const int XRES=640;
const int YRES=480;
const int ARES=XRES*YRES;


class gfx_buffer
{
private:
int wwidth, height;
int wwidth2, height2;
unsigned int *pixels;

}


// funksters.
//void draw_gfx_buffer( gfx_buffer *dest, gfx_buffer *srce, int x, int y );

gfx_buffer* create_gfx_buffer( int wwidth, int height );

int set_graphics( int wwidth, int height );

gfx_buffer *screen_buffer=create_gfx_buffer( XRES, YRES );

//screen_buffer=create_gfx_buffer( 640, 480 );

int main()
{
set_graphics( XRES, YRES );

while (1)
{
// clear screen.

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

} // wend.
} // end function.


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 set_pixel()
//{

//}



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

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

    if (!ptc_open("mOnKeY bUiSnEsS 1",wwidth,height)) return 1;

return 0;

}


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


Challenge Trophies Won:

Jim

a) What problems?
b) Why not use the code I've given you so far?

<edit> hard to say, because the code is already becoming a jumble, but you might just need to change

ptc_update( screen_buffer->pixels[0] );
to
ptc_update( &screen_buffer->pixels[0] );


Jim
Challenge Trophies Won:

Shockwave

Shockwave ^ Codigos
Challenge Trophies Won:

Clyde

Sole reason Jim, I want to try it with the functions out side the class.
I have used the method you gave me btw. thanks :)

here's the compile output:


Compiling...
Main1-2.cpp
.\Main1-2.cpp(23) : error C2143: syntax error : missing ';' before '*'
.\Main1-2.cpp(23) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
.\Main1-2.cpp(27) : error C2143: syntax error : missing ';' before '*'
.\Main1-2.cpp(27) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
.\Main1-2.cpp(27) : error C2371: 'gfx_buffer' : redefinition; different basic types
        .\Main1-2.cpp(23) : see declaration of 'gfx_buffer'
.\Main1-2.cpp(27) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
.\Main1-2.cpp(40) : error C2227: left of '->pixels' must point to class/struct/union/generic type
        type is 'int *'
.\Main1-2.cpp(46) : error C2143: syntax error : missing ';' before '*'
.\Main1-2.cpp(46) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
.\Main1-2.cpp(46) : error C2371: 'gfx_buffer' : redefinition; different basic types
        .\Main1-2.cpp(23) : see declaration of 'gfx_buffer'
.\Main1-2.cpp(47) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
.\Main1-2.cpp(48) : error C2065: 'buffer' : undeclared identifier
.\Main1-2.cpp(48) : error C2061: syntax error : identifier 'gfx_buffer'
.\Main1-2.cpp(50) : error C2065: 'buffer' : undeclared identifier
.\Main1-2.cpp(50) : error C2227: left of '->pixels' must point to class/struct/union/generic type
        type is ''unknown-type''
.\Main1-2.cpp(52) : error C2065: 'buffer' : undeclared identifier
.\Main1-2.cpp(52) : error C2227: left of '->wwidth' must point to class/struct/union/generic type
        type is ''unknown-type''
.\Main1-2.cpp(53) : error C2065: 'buffer' : undeclared identifier
.\Main1-2.cpp(53) : error C2227: left of '->height' must point to class/struct/union/generic type
        type is ''unknown-type''
.\Main1-2.cpp(55) : error C2065: 'buffer' : undeclared identifier
.\Main1-2.cpp(55) : error C2227: left of '->wwidth2' must point to class/struct/union/generic type
        type is ''unknown-type''
.\Main1-2.cpp(56) : error C2065: 'buffer' : undeclared identifier
.\Main1-2.cpp(56) : error C2227: left of '->height2' must point to class/struct/union/generic type
        type is ''unknown-type''
.\Main1-2.cpp(58) : error C2065: 'buffer' : undeclared identifier
Semi Colon Adventures 1 - 24 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.


Challenge Trophies Won:

TinDragon

[edited] first response not really a good one.

Clyde the compiler is giving you hints at whats wrong
'gfx_buffer' : redefinition; different basic types .\Main1-2.cpp(23) : see declaration of 'gfx_buffer'
this line is giving you the biggest clue, if you have read anything about the c++ langauge you should know why this is failing, you have been doing something in freebasic with the DECLARE keyword that does what you are missing here ;)

Jim

There are 3 things causing all those errors:
1) There should be a ';' after the closing '}' on your class, on line 21
2) Because you're accessing all the properties of gfx_buffer outside of the class, you must change them to 'public' instead of 'private' (or use the code I gave you, whatever).
3) You need this fix
ptc_update( &screen_buffer->pixels[0] );
which you have ignored.

Jim
Challenge Trophies Won:

Clyde

Thanks mate.

I get in the build log ( F5 - release ):
CIL library( CIL module) : warning LNK4210: .CRT section exists; there may be unhandled static initializers or terminators

plus:

Unhandled exception at 0x0019103a in Semi Colon Adventures 1.exe: 0xC0000005: Access violation reading location 0x00000004.


//
// includes.
// remember ( ALT+F7) to add linker -> input -> dependencies 'libmmx.lib' & 'libtinyptc_ext.lib'
//
#include <windows.h>
#include <tinyptc_ext.h>

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

};

//
// functions.
//
int set_graphics( int wwidth, int height );


gfx_buffer *create_gfx_buffer( int width, int height);




//
// variables.
//
//unsigned int screen_buffer[ ARES ];
gfx_buffer *screen_buffer=create_gfx_buffer( 640, 480 );


int main()
{
// initializing.
set_graphics( XRES, YRES );


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

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

} // wend.

} // end function main()



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

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

   if (!ptc_open("sEmI cOl0n AdVeNtUrEs",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;

}


Muchos Gracias Amigas ;) ,
Senior Clyde.
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.


Challenge Trophies Won: