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.
//
// 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.
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.