Help Please. SDL_TTF TypeWriter Effect

I have been using the C programming language. SDL, and SDL_ttf to try and
make a TypeWriter effect. Still haven’t been able to figure it out. I have
asked on the forums at gamedev. Didn’t get much help from them. Except a
response I don’t understand which said:

  1. Declare an Uint32 typewriter_starttime and initialize it with the return
    value of SDL_GetTicks() when the text is supposed to begin appearing.
  2. Each frame, calculate Uint32 typewriter_time = SDL_GetTicks() -
    typewriter_starttime as the time that passed since the text is supposed to
    appear. Then calculate the number of characters to display based on that
    time interval (note that the number is in milliseconds) and display the
    appropriate std::string::substr using SDL_ttf.

Maby someone on this mailing list would be kind enofe to help me with this.
Thanks.

Here is a code I set up for it, but don’t know how to program in the type
writer effect. The effect you see in many Visual Novel games, and RPGS.
Where the text is printed one letter at a time.

#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_ttf.h>
#include <stdio.h>

SDL_Surface screen; / global for convenience */

message(char *text)
{
if(TTF_Init()==-1) {
printf(“TTF_Init: %s\n”, TTF_GetError());
exit(2);
}

TTF_Font *font;
font=TTF_OpenFont(“msgothic.ttc”, 16);
if(!font) {
printf(“TTF_OpenFont: %s\n”, TTF_GetError());
// handle error
}

// Render some UTF8 text in solid black to a new surface
// then blit to the upper left of the screen
// then free the text surface
//SDL_Surface *screen;

SDL_Color color={0,0,0};
SDL_Surface *text_surface;
if(!(text_surface=TTF_RenderUTF8_Solid(font,text,color))) {
//handle error here, perhaps print TTF_GetError at least
} else {
SDL_BlitSurface(text_surface,NULL,screen,NULL);
//perhaps we can reuse it, but I assume not for simplicity.
SDL_FreeSurface(text_surface);
}

}

static void example()
{
Uint8 *keystate;
int quit = 0;
while (quit == 0) {
SDL_PumpEvents();
keystate = SDL_GetKeyState(NULL);
if (keystate[SDLK_q] || keystate[SDLK_ESCAPE]) quit = 1;

message(“This is a test string.”);
}

}

int main(int argc, char *argv[])
{
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
printf(“Unable to initialize SDL: %s\n”, SDL_GetError());
return 1;
}

if (SDL_Init(SDL_INIT_TIMER) < 0) {
printf("Unable to initialize SDL Timer: %s\n", SDL_GetError());
return 1;
}

atexit(SDL_Quit);

screen = SDL_SetVideoMode(800,600,16,0);
if (screen == NULL) {
printf("Unable to set video mode: %s\n", SDL_GetError());
return 1;
}

SDL_WM_SetCaption("Example", "Example");
screen = SDL_GetVideoSurface();
example();

}–
View this message in context: http://www.nabble.com/Help-Please.-SDL_TTF-TypeWriter-Effect.-tp25084538p25084538.html
Sent from the SDL mailing list archive at Nabble.com.

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Fujitaka wrote:

I have been using the C programming language. SDL, and SDL_ttf to try and
make a TypeWriter effect. Still haven’t been able to figure it out. I have
asked on the forums at gamedev. Didn’t get much help from them. Except a
response I don’t understand which said:

  1. Declare an Uint32 typewriter_starttime and initialize it with the return
    value of SDL_GetTicks() when the text is supposed to begin appearing.
  2. Each frame, calculate Uint32 typewriter_time = SDL_GetTicks() -
    typewriter_starttime as the time that passed since the text is supposed to
    appear. Then calculate the number of characters to display based on that
    time interval (note that the number is in milliseconds) and display the
    appropriate std::string::substr using SDL_ttf.

Hello Fujitaka,

Let’s summarize. You want to accumulate a certain number of characters on the
screen after a certain amount of time. The time between new characters
appearing on the screen is constant. For example, print one additional
character every second:

0 1 2 3 4 5 6 7 8 9 10 seconds


| | | | | | | | | | |
H----e----l----l----o----W----o----r----l----d----! text

Pseudocode algorithm:

string <- "HelloWorld!"
n <- 0
N <- length string

while n < N:
print string[ n ]
wait 1sec.
n <- n + 1

If you start with this, you can make it more elaborate. Instead of printing a
character to the screen one-by-one, you keep an SDL_Surface where you
accumulate the text and then blit the surface onto the screen (assuming that
the area’s shape on the screen where the text will be displayed won’t change):

Pseudocode algorithm:

string <- "HelloWorld!"
n <- 0
N <- length string

c <- new surface
screen <- VideoSurface

while n < N:
blit from string[ n ] to c with offset n
blit from c to screen
wait 1sec.
n <- n + 1

That’s the basic footwork. Now I assume that SDL_ttf has a routing to blit a
string to screen:

Pseudocode algorithm:

string <- "HelloWorld!"
n <- 0
N <- length string

screen <- VideoSurface

while n < N:
ttfblit substring(string, 0, n) to screen
wait 1sec.
n <- n + 1

If your program has one thread doing everything, then your typewriter routine
will block everything else and your program will apparently slow down. So you
need to approach the drawing of characters differently.

You could instantiate a periodic timer that will print a character every so
often (variation: push an user event in your timer and let one of several
threads handle the work); Signal your drawing module every n milliseconds to
see if there’s unfinished work in the work queue; Instantiate a thread that
will blit the characters onto the screen.

If you want to vary the time between new characters showing up, there’s also a
whole slew of ways of doing that: You can keep a two-dimensional 26x26 array
of integers representing the delay between two characters (variation: add a
small, random delay to this value to make it look more human); Do some
research with regards to typing speeds; Model a human writer.

In the end, how you solve it depends on your needs and goals. I hope this
served as a useful steppingstone for you.

Best regards,
Chris

P.S.: What the above recommendation from gamedev asked you to do was to
calculate the number of characters to draw based on the modulus of the current
time (in ms.) minus the start time (in ms.):

total number of character to blit
= (current time - start time) % period


  • -- Christopher C. Eineke -- Email: chris at chriseineke.com -*-
    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.9 (GNU/Linux)

iEYEAREKAAYFAkqRixsACgkQPOmqd0kEEbvxLACdFUq6nZxeuQ4tFoZnoLvPdKNw
qJIAninUsimeYw+UIdxZKyaidIrep2j2
=A9hw
-----END PGP SIGNATURE-----