Author Topic: [C++] Bitmap Scroller: Strings And Things.  (Read 19706 times)

0 Members and 1 Guest are viewing this topic.

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
[C++] Bitmap Scroller: Strings And Things.
« on: September 07, 2009 »
Whilst the site was offline, I had a brief one to one via email with Jim'll Fix it, about converting over a bitmap scroller routine, the one I picked is the one that Shockwave showed me and uses. This coincides with my questions on classes and pointer types.

Here's what was discussed during the emails.

Quote from: Clyde
Hi Jim,

This is a conversion from a Blitz / Freebasic routine that Shockwave uses, and it uses mid$ which i've attempted in C++.
 
I am having problems with the message settings / setup found in gfx_text, when I look at the locals the message isnt correct and has weird characters at the end.
 
I've attached all the seperate sources if you need to compile them as a project.
 
Cheers and all the very best to you,
Clyde.

Quote from: Jim
Hi Clyde,

This might work for you:
Code: [Select]
char *mid_string(char *input, int start_pos, int stop_pos )
{
static char workspace[256];


int length = stop_pos - start_pos;
strncpy(workspace, input+start_pos, length);
workspace[length]='\0';


return workspace;
}

Problem with using 'new' is you waste memory for every single time you call the function.

Best way would be not to use mid_string() at all, instead find the start pos in the string and draw the next 20 characters, stopping if you hit a character with value 0.
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++] Bitmap Scroller: Strings And Things.
« Reply #1 on: September 07, 2009 »
I'd be interested to see how that method would be Jim dude, im a little fuzzy wuzzy as after each word there's a space / character 0.

Cheers for your help,
Clyde.

<edit by Jim>
Here are your questions, so now everyone knows what you said
Quote
Cheers Jim! :)
 
Sweet it's working! :D
 
I had to change strncpy to strncpy_s, as for some reason it warned me that it was unsafe.
and I needed to change length to equal start_pos + stop_pos.
I presume that workspace[length]='\0'; means to return a character of 0 or in this a space.
I've tried to make workspace a static outside of the function with the correct length of the scroller text, but I kept getting cant declare workspace with size 0, plus saying it needs to be constant.
 
I've declared scroller in the following fashion:
 
Code: [Select]
char scroller[] = ("                                            " // 48 spaces.
                       "HELLO THERE! IS THAT YOU?             GUESS WHAT CHUM? "
                       "I THINK IT'S WORKING THIS SCROLL OF MINE!!                  YIPPEEE!!!"
                       "                                             "); // 48 spaces);
Im keen on this idea of finding the characters upto 20, or in how i've got it 48. I'd really like to see how thats done, as i either have a slow pc, or the method with mid_string is slowing down the text output like you mentioned. I have found this the same in free basic too with using anything string related.
 
Cheers and all the very best,
Mike.
« Last Edit: September 07, 2009 by Jim »
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++] Bitmap Scroller: Strings And Things.
« Reply #2 on: September 07, 2009 »
Quote
I needed to change length to equal start_pos + stop_pos
That doesn't make any sense, so something else must be wrong.
Say you passed in start=5 and stop=15, then length should be 10, not 20.  And then when you get to start=200, stop=210 then you would be copying 410 chars instead of 10.  That would make it crash because there's only space for 250 in the workspace.

Quote
I had to change strncpy to strncpy_s, as for some reason it warned me that it was unsafe
Ah, yes, Microsoft supply an ISO extension to the C runtime library (called the Safer C Library) which makes all the string functions secure.  Mostly they're the same function names, but with _s on the end). Microsoft in their infinite wisdom have then gone and made the compiler warn every time you use the normal library routines which is a pain in the neck.
If you go to the Project Properties, and under the Compiler options there's a Preprocessor box.  In that box you can add _CRT_SECURE_NO_DEPRECATE to turn off the warnings.  Or you can ignore the warnings.  Or you can use the new functions, like you have already done so.

'\0' is the same as 0.  Strings in C are a series of characters followed by a 0.

As I said, there's no reason to use this midstring function.  Why not go
Code: [Select]
scroller[]="...";
start_pos=0;
...
xpos=0;
for (int x=0; x < number_of_chars_that_will_fill_screen; x++)
{
  if (scroller[start_pos+x]=='\0') break;
  print_char(xpos, ypos, scroller[start_pos+x]);
  xpos+=charwidth;
}
start_pos++;
There's no midstring in there, but it has the same result.
It also means you can do scrollers where the characters are not fixed width
Code: [Select]
int x=start_pos;
for(;;) //this means "forever", the 'breaks' will exit the loop
{
  if (scroller[x]=='\0') break;
  print_char(xpos, ypos, scroller[x]);
  xpos+=charwidth[x];
  if (xpos>SCREEN_WIDTH) break;
  x++;
}
That will stop when the rightmost character goes off the screen.

Quote
I've tried to make workspace a static outside of the function with the correct length of the scroller text, but I kept getting cant declare workspace with size 0, plus saying it needs to be constant.
I don't understand why you would want to do that, and I can't tell why you need to do that or really what you mean.

Jim
« Last Edit: September 07, 2009 by Jim »
Challenge Trophies Won:

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: [C++] Bitmap Scroller: Strings And Things.
« Reply #3 on: September 08, 2009 »
Thanks for the info etc dude! :)

I've tried the non mid_string bits, but it goes bananas with the speed, and then crashes out.
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++] Bitmap Scroller: Strings And Things.
« Reply #4 on: September 08, 2009 »
If you post code then it can be fixed.

I suspect you have 'start_pos' as a float so you can increment by much less than one character at a time - that deals with the speed.

I also suspect you never check that start_pos is past the end of the string (I didn't show that bit).
ie. this will wrap it back to the start
Code: [Select]
start_pos++;
if (start_pos > strlen(scroller)) start_pos = 0;

Jim
« Last Edit: September 08, 2009 by Jim »
Challenge Trophies Won:

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: [C++] Bitmap Scroller: Strings And Things.
« Reply #5 on: September 08, 2009 »
Ok, cool didnt spot your recent edit. I've attached a source listing, it also doesnt take into account the scroll_speed.

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++] Bitmap Scroller: Strings And Things.
« Reply #6 on: September 10, 2009 »
Any ideas on incorparating scroll_speed? As it goes like the clappers, and can't read it.

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++] Bitmap Scroller: Strings And Things.
« Reply #7 on: September 10, 2009 »
Why not make scroll_pos and scroll_speed floats?  Then, you'll probably need to use
(int)scroll_pos
in some places to round it down, when you want to use it as an array index.

Jim
Challenge Trophies Won:

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: [C++] Bitmap Scroller: Strings And Things.
« Reply #8 on: September 13, 2009 »
I need to have a rethink on this, as soon as i have my new birthday PC almost configured.
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++] Bitmap Scroller: Strings And Things.
« Reply #9 on: September 16, 2009 »
@JIM: Do you mean make x a float, as I dont see any scroll_pos.

I've done this, but it's still way too quick.

Code: [Select]
void bitmap_scroller( gfx_buffer *dest, anim_image *font )
{
int character;

int pos_x=0;

for (int x=0; x < 48; x++)
{
if (scroller[ start_pos+x]=='\0') break;

character=( int ) scroller[ start_pos+x ] - 32;

draw_gfx_buffer( dest, font->frame[ character ], pos_x, 240 );
pos_x+=font->frame[ character ]->wwidth;
}


//delay++;
//if ( delay >=4 )
//{
start_pos++;
// delay=0;
//}

if ( start_pos >= (int)strlen(scroller)-32 ) start_pos = 0;

float x= start_pos;
//float xx=(float) x;

for(;;) //this means "forever", the 'breaks' will exit the loop
{
if (scroller[ (int) x]=='\0') break;

character=(int) scroller[ (int) x ] - 32;

draw_gfx_buffer( dest, font->frame[ character ], pos_x, 240 );

pos_x+=font->frame[ character ]->wwidth;

if (pos_x>dest->wwidth) break;

x+=1.25;
}

}

Im a tad lost. :(

Could you convert the bitmap scroller that I first posted that is Freebasic / Blitz based into ( quick alternatives ) in C++ please dude? I only ask as I've been pondering on this for quite some weeks now, and once I see it working it'll complete the puzzle for me ( sink into the grey matter ).

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 hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
Re: [C++] Bitmap Scroller: Strings And Things.
« Reply #10 on: September 16, 2009 »
You're still increasing "start_pos" by 1 every frame.
Try it this way:

Code: [Select]
float start_pos= 0.0f;

...

start_pos+-=0.1f;

...

int x= start_pos;

for(;;)
{
      if (scroller[x]=='\0') break;

...

This will draw your characters at an integer position which is nearest to "start_pos",
thus increasing the actual pixel position every tenth (due to 0.1) frame.

If your font has proper anti-aliasing one might even think about drawing bitmaps at subpixel precision.

« Last Edit: September 16, 2009 by hellfire »
Challenge Trophies Won:

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: [C++] Bitmap Scroller: Strings And Things.
« Reply #11 on: September 16, 2009 »
Cheers HellFire :)

Will try that out, and I haven't got around to adding aa to the font yet.

Still no joys, it's either far too jerky or far too quick. also just noticed it doesnt go off the left edge smoothly.
« Last Edit: September 16, 2009 by Clyde »
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
Re: [C++] Bitmap Scroller: Strings And Things.
« Reply #12 on: September 16, 2009 »
Can you attach the current source including project- and data-files ?
Challenge Trophies Won:

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: [C++] Bitmap Scroller: Strings And Things.
« Reply #13 on: September 16, 2009 »
Sure thing :)

Here are the sources.

Add libtinyptcmmx.lib and libtinyptc_ext to the linker.
Also add to the project directories in includes the lib - graphics 2d.h / tinyptc_ext.h
« Last Edit: September 16, 2009 by Clyde »
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
Re: [C++] Bitmap Scroller: Strings And Things.
« Reply #14 on: September 16, 2009 »
I fiddled around in your code a bit:
Code: [Select]
//
// includes.
//
#include <windows.h>
#include <string.h>
#include "tinyptc_ext.h"
#include "lib - graphics 2d 1-1.h"

extern unsigned char us64_pal[];
extern unsigned char us64_raw[];

//
// sub routines.
//
void bitmap_scroller( gfx_buffer *dest, anim_image *font );

//
// meet the globals.
//
static float start_pos=0.0f;
static int delay=0;

static int best_fit_wwidth=48;//640+128/64;

static char scroller[] = { "                     "
        "HELLO THERE! IS THAT YOU CLYDE?              GUESS WHAT CHUM?            "
          "I THINK IT'S WORKING THIS SCROLL OF MINE!!               YIPPEEE!!!"
  "                                                "};

static int scroller_length=strlen( scroller );

static gfx_buffer *screen_buffer, *temp, *font_image, *scroll_buffer;
static anim_image *font_one;


int main()
{
//
// initializing.
//
screen_buffer=create_gfx_buffer( 640, 480 );
scroll_buffer=create_gfx_buffer( 640+64, 64 );

font_image=load_gfx_buffer( us64_raw, us64_pal, 512, 512 );
font_one=create_anim_images( font_image, 64,64,32,8,8);

delete_gfx_buffer (font_image);

set_graphics( "bItMaP sCrOlLeR", 640, 480 );

//
// main program loop.
//
while (1)
{
//
// clear screen.
//
clear_gfx_buffer(screen_buffer, 0);
bitmap_scroller( screen_buffer, font_one );
//
// render to the screen buffer.
//
ptc_update( &screen_buffer->pixels[0] );

}
delete_anim_image( font_one );
delete_gfx_buffer( screen_buffer );
}


void bitmap_scroller( gfx_buffer *dest, anim_image *font )
{
   int curchar= 0;
   int x= start_pos;

   // find first character that's not outside the left border
   while (scroller[curchar] && x+font->frame[scroller[curchar] - 32]->wwidth<0)
   {
      x+=font->frame[scroller[curchar] - 32]->wwidth;
      curchar++;
   }

   // draw characters until right border reached
while (x<640 && scroller[curchar])
{
char c= scroller[curchar] - 32;

draw_gfx_buffer( dest, font->frame[c], x, 240 );
x+=font->frame[c]->wwidth;

      curchar++;
}

start_pos-=1.0f;
}
It now keeps track of the pixel-position of the first character of the scroll-text on the screen.
Characters outside the left border of the screen are skipped, then characters are drawn until the right border of the screen is reached.
This has some potential for optimization if you happen to have a few megabytes of text.
Still misses wrapping when end of the text is reached.
« Last Edit: September 17, 2009 by hellfire »
Challenge Trophies Won:

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: [C++] Bitmap Scroller: Strings And Things.
« Reply #15 on: September 16, 2009 »
I really appreciate the help with this guys.
However it's still a tad jerky, maybe this is because it's using an unproportional font.
I have found in blitz and freebasic with the mid$ approach it slows down stuff.

How'd i make the latest method wrap please dude?

Hugest of thanks for your time and patience,
Clyde.
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
Re: [C++] Bitmap Scroller: Strings And Things.
« Reply #16 on: September 17, 2009 »
Quote
it's still a tad jerky
It's running pretty smooth here.
Try if it works better in a smaller resolution.
Although the scroller is rather simple, you still have to send a 640x480-buffer every frame and your pc might not be making it.

Quote
How'd i make the latest method wrap please dude?
The first while-loop figures out which character is the first that needs to be drawn.
If that's the last character of your string you can reset "start_pos" to zero.
Challenge Trophies Won:

Offline TinDragon

  • Pentium
  • *****
  • Posts: 644
  • Karma: 24
    • View Profile
    • J2K's blog
Re: [C++] Bitmap Scroller: Strings And Things.
« Reply #17 on: September 17, 2009 »
Since Clyde has used this framebuffer lib in Freebasic before his pc should be ok with updating the full buffer at a decent rate. Perhaps it could be something else running on his system and fighting for cpu time, I assume that its jerky in both debug and release mode ?

Offline Clyde

  • A Little Fuzzy Wuzzy
  • DBF Aficionado
  • ******
  • Posts: 7271
  • Karma: 71
    • View Profile
Re: [C++] Bitmap Scroller: Strings And Things.
« Reply #18 on: September 21, 2009 »
I've used TinyPTC_Ext with Free Basic, but when using it in C++, im not sure if it will perform the same or less so; as ive only been working in C for just over a month. I only really use the release build, and that is what has the slight jerkyness in.

Perhaps I could get some speed when you use a pointer to be the destination, eg the screen. and the colour info from the srce, again as a pointer, but im a tad stuck in that department, as im getting green pixels whenever I attempt it.
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.

Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
Re: [C++] Bitmap Scroller: Strings And Things.
« Reply #19 on: September 23, 2009 »
When I was a little bored yesterday I modified your draw_gfx_buffer function to extract the visible subregion of your source-image so you don't need to check every single pixel for being off-screen.
Code: [Select]
void draw_gfx_buffer( gfx_buffer *dest, gfx_buffer *srce, int pos_x, int pos_y )
{
int x, y;
   int sx,sy; // top-left of visible source image
   int w, h;  // width and height of visible source image

   // completely off?
   if (pos_x >= dest->wwidth
    || pos_y >= dest->height
    || pos_x <= -srce->wwidth
    || pos_y <= -srce->height)
    return;

   // partially off?
   if (pos_x < 0) // left
   {
      sx= -pos_x;
      w= srce->wwidth - sx;
      pos_x= 0;
   }
   else
   {
      sx= 0;
      w= srce->wwidth;
   }

   if (pos_y < 0) // top
   {
      sy= -pos_y;
      h= srce->height - sy;
      pos_y= 0;
   }
   else
   {
      sy= 0;
      h= srce->height;
   }

   if (w+pos_x > dest->wwidth) // right
      w= dest->wwidth-pos_x;
   
   if (h+pos_y > dest->height) // bottom
      h= dest->height-pos_y;

   unsigned int *src= srce->pixels + sy*srce->wwidth + sx;
   unsigned int *dst= dest->pixels + pos_y*dest->wwidth + pos_x;
for ( y=0; y< h; y++)
{
for ( x=0; x< w; x++)
   dst[x]= src[x];

      dst+= dest->wwidth;
      src+= srce->wwidth;
}
}
Challenge Trophies Won: