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

0 Members and 1 Guest are viewing this topic.

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #40 on: August 22, 2009 »
Sure thing dude, and that's really swell of you.

[ ed 209 ] i've included a zip archive of the individual files used including the tinyptc MSVC lib, and thanks for your time in this matter. [ / ed209 ]

Very cool and cheers,
Clyde.
« Last Edit: August 22, 2009 by Clyde »
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

Challenge Trophies Won:

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17394
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #41 on: August 22, 2009 »
Off topic:

Quote
Sure thing dude, and that's really swell of you.

Do you talk like that in real life?

On Topic:

Thanks for not giving with it Clyde and Jim, good luck.
Shockwave ^ Codigos
Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1292
  • Karma: 466
    • View Profile
    • my stuff
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #42 on: August 22, 2009 »
Clyde, you just have a typo in create_anim_images:
Code: [Select]
for ( y_test=y; y_test<(y+height-1); y_test=+1)should be:
Code: [Select]
for ( y_test=y; y_test<(y+height-1); y_test+=1)
It's easy to find such stuff by simply stepping through the code with the debugger.
Challenge Trophies Won:

Offline TinDragon

  • Pentium
  • *****
  • Posts: 644
  • Karma: 24
    • View Profile
    • J2K's blog
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #43 on: August 22, 2009 »
Also in your main loop you have one as well
Code: [Select]
draw_gfx_buffer( screen_buffer, font_one->images[19], 0, 0 );

Should be
Code: [Select]
draw_gfx_buffer( screen_buffer, font_one->frame[19], 0, 0 );
Since you dont have an "images" in that class, which should be an error when trying to compile. BTW displays a 5 on screen but has some white lines like its offcentre, probably your sizes are slightly out ;)

[edit]god i made typo's giving you the info  :D
« Last Edit: August 22, 2009 by TinDragon »

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #44 on: August 23, 2009 »
My guess is that part of the problem is in the display code
Code: [Select]
if (x+pos_x>0)
if (x+pos_x<dest->wwidth-1)
if (y+pos_y>0)
if (y+pos_y<dest->height-1)
and that we have a selection of 'off by one' errors here
Code: [Select]
if (x+pos_x>=0)
if (x+pos_x<dest->wwidth)
if (y+pos_y>=0)
if (y+pos_y<dest->height)
With those fixed you can now draw on the first and last scanlines and first and last pixels of every scanline.

I think there are similar problems in the code that's copying the characters out of the big sprite into the small ones, causing the offset.
Clyde, in C++ all arrays count from 0 and finish one index sooner than in FB. So,
int number[3];
has 3 ints in it.  number[0], number[1], number[2].  It's a bad error to use number[3].
Also, in FB the For loops go for one more iteration
For a=0 To 3
a=0, a=1, a=2, a=3
Where in C++
for (int a=0; a < 3; a++)
a=0, a=1, a=2

It looks like you've adjusted for this in most places, but I think there are still some problems.  Worth just doing a quick compare with the FB and C++ for all the If and For to check.

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 #45 on: August 23, 2009 »
Thanks all for the info, will have a gander in a mo, need to switch to the other OS that has VS C++ on it.

JC2K: I forgot I had changed that, when I was collecting the files for zipping, I missed one when spring cleaning it.
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

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 #46 on: August 23, 2009 »
Awesome!! with a capital A :)
I owe you all a pint of what ever takes your fancy! :)

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

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 #47 on: August 23, 2009 »
With this print_text function, it doesnt draw the correct letters, it always draws from the first ( 0 ) frame upto how ever long it is, but not the corresponding letter for example:

text="CLYDE"
output:
[space] ! " £ $ %

Code: [Select]
void print_text( gfx_buffer *dest, anim_image *font, int pos_x, int pos_y, char *message )
{
int len=strlen( message ); //length of the message text.

for ( int a=0; a<len; a++)
{
char frame=message[a]-32; //splits message into appropriate letter.

if (frame>=0 )
if ( frame<=font->total_frames-1 )
{
draw_gfx_buffer( dest, font->frame[a], pos_x, pos_y );
pos_x+=font->frame[a]->wwidth;
}

} // next a

} // end function
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1292
  • Karma: 466
    • View Profile
    • my stuff
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #48 on: August 23, 2009 »
Quote
Code: [Select]
draw_gfx_buffer( dest, font->frame[a], pos_x, pos_y );
You don't want to draw character "a" (which counts the letters in your string) but "frame".
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 #49 on: August 23, 2009 »
lol! Thanks for pointing that out dude! :)
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

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 #50 on: August 24, 2009 »
I thought all was ok, but it's not taking the correct widths per frame into account, they're all 64x64, when they should be ( width upto 64 + space )  * 64.
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 #51 on: August 24, 2009 »
Problem is here (in two places):
Code: [Select]
if (srce->pixels[ (x_test)+(y_test) * srce->wwidth]!=0)
should be
Code: [Select]
if (srce->pixels[ (x_test)+(y_test) * srce->wwidth]!=0xff000000)
That fixes most of the width-based stuff, though there's still something else wrong

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 #52 on: August 24, 2009 »
Tidied up some more off-by-ones in the for loops.  Here's the whole thing working:
Code: [Select]
//
// includes.
//
#include <windows.h>
#include "tinyptc_ext.h"

extern unsigned char us64_pal[]; // 64 distinguishes a variable font based around max width of 64, height == 64
extern unsigned char us64_raw[]; // i am unsure if this font is 8*8, or 8*16 ( including upper and lower case characters )

//
// 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 **frame;
};

//
// 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 );
anim_image *create_anim_images2( gfx_buffer *srce, int wwidth, int height );
//
// sub routines.
//
void draw_gfx_buffer( gfx_buffer *dest, gfx_buffer *srce, int pos_x, int pos_y );
void print_text( gfx_buffer *dest, anim_image *font, int pos_x, int pos_y, char *message );

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

gfx_buffer *font_image=load_gfx_buffer( us64_raw, us64_pal, 512, 512 );
anim_image *font_one=create_anim_images( font_image, 64, 64, 32, 2, 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

// remove remarks to test the image has been loaded successfully.
//draw_gfx_buffer( screen_buffer, font_one->frame[19], 0, 0 );
//draw_gfx_buffer( screen_buffer, font_image, 0, 0 );

print_text(screen_buffer, font_one, 10,10, "HELLO");

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

} // wend.

} // end function main()

void print_text( gfx_buffer *dest, anim_image *font, int pos_x, int pos_y, char *message )
{
int len=strlen( message ); //length of the message text.

for ( int a=0; a<len; a++)
{
char frame=message[a]-32; //splits message into appropriate letter.

if (frame>=0 )
if ( frame<=font->total_frames-1 )
{
draw_gfx_buffer( dest, font->frame[frame], pos_x, pos_y );
pos_x+=font->frame[frame]->wwidth;
}

} // next a

} // end function

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)
if (y+pos_y>=0)
if (y+pos_y<dest->height)

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->frame=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*height; y+=height )
{
for (x=0; x<frame_w*wwidth; x+=wwidth )
{
//
// test x.
//
test_r=x;

for ( x_test=x; x_test<(x+wwidth); x_test+=1 )
{
for ( y_test=y; y_test<(y+height); 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; 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) //then
test_r=x+wwidth-1;
// end if



if (test_l<x) // then
test_l=x;
// end if

anim_buffer->frame[frame_number]=create_gfx_buffer(test_r-test_l+1,height);
draw_gfx_buffer( anim_buffer->frame[frame_number],srce,-test_l,-y);




}
else
{
anim_buffer->frame[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;
}

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 #53 on: August 25, 2009 »
Thats just perfect, a great pressie! :D
So you need to be exact with your value checking!

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

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 #54 on: August 25, 2009 »
you may of noticed me using this slow method of clearing the screen, any ideas on how to improve upon it?

Code: [Select]
for( int index=0; index<(screen_buffer->wwidth*screen_buffer->height); index++)
screen_buffer->pixels[index]=0x000000;

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 #55 on: August 26, 2009 »
Make sure you have
Code: [Select]
#include <string.h>
at the top, then replace the for loop with
Code: [Select]
memset(screen_buffer->pixels, 0, screen_buffer->wwidth*screen_buffer->height * sizeof(unsigned int));

Jim
« Last Edit: August 26, 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 #56 on: August 26, 2009 »
Cheers Jim! :)

I get the following when ever I use sin / cos. Im wondering if this is telling me to add MSVCRT.lib or something else to the linker?

MSVCRT.lib(cpu_disp.obj) : warning LNK4210: .CRT section exists; there may be unhandled static initializers or terminators

how i use sin to avoid conversion warnings / loss of data errors:

mockup example:
Code: [Select]
float sinx;
int sinxx;

sinx=(float) sin( [i]insert_formula[/i] );
sinxx=(int) sinx;
draw( sinxx, 200, 0xFFFF0000 ); // ( usage - posx as int, posy as int, colour as unsigned int )
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 #57 on: August 26, 2009 »
To use sin() etc. you should
Code: [Select]
#include <math.h>
You can ignore the warnings.  I have already explained to you in this thread about the loss of precision warnings.

The .CRT warning is some problem in your project settings.  It's just a warning.  I don't know what's triggering it.  Can you post a zip of all your files again?

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

Offline TinDragon

  • Pentium
  • *****
  • Posts: 644
  • Karma: 24
    • View Profile
    • J2K's blog
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #58 on: August 26, 2009 »
Code: [Select]
sinx=(float) sin( [i]insert_formula[/i] );
I would think that should be "float sin(float whatever);" which is only available in C++ if the compiler help is correct. TBH if your using float values then use sinf() which expects a float in and gives a float out, which Jim mentioned earlier in this very thread, sin() works with doubles so will likely give the warning double to float conversion or something similiar, which you can ignore but it is better to fix imho.




Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1292
  • Karma: 466
    • View Profile
    • my stuff
Re: [C++] Converting FreeBASIC Pointer Types into a Class
« Reply #59 on: August 26, 2009 »
Generally VC++ is a bit picky with double/float conversions by default which results in a store and reload of every intermediary result.
To get around this you can set the fpu-precision to "fast" in the C++ settings.
But keep in mind that "missing" rounding leads to different results.

A simple example:
Code: [Select]
  float sum= 0.0f;
   for (float x=0.0f;x<10.0f;x+=0.1f)
   {
      float y= sin(x);
      sum+=y;
   }
   printf("result: %f \n", sum);
disassembly with fpu-precision "fast"
Code: [Select]
00401006  fldz            
00401008  fld         st(0)
0040100A  fld         dword ptr [402100h]
00401010  fld         dword ptr [4020FCh]
00401016  jmp         main+1Ah (40101Ah)
00401018  fxch        st(3)
0040101A  fld         st(3)
0040101C  fsin            
0040101E  faddp       st(3),st
00401020  fxch        st(3)
00401022  fadd        st,st(1)
00401024  fcom        st(3)
00401026  fnstsw      ax  
00401028  test        ah,5
0040102B  jnp         401018h
result: 18.647397
...and "precise"
Code: [Select]
00401009  fldz            
0040100B  fst         dword ptr [esp+38h]
0040100F  fstp        dword ptr [esp+34h]
00401013  fld         dword ptr [esp+34h]
00401017  call        _CIsin (401870h)
0040101C  fstp        dword ptr [esp+3Ch]
00401020  fld         dword ptr [esp+3Ch]
00401024  fadd        dword ptr [esp+38h]
00401028  fstp        dword ptr [esp+38h]
0040102C  fld         dword ptr [esp+34h]
00401030  fadd        qword ptr [402100h]
00401036  fstp        dword ptr [esp+34h]
0040103A  fld         dword ptr [4020FCh]
00401040  fld         dword ptr [esp+34h]
00401044  fcom        st(1)
00401046  fnstsw      ax  
00401048  fstp        st(1)
0040104A  test        ah,5
0040104D  jnp         main+17h (401017h)
result: 18.647362

« Last Edit: August 26, 2009 by hellfire »
Challenge Trophies Won: