0
\$\begingroup\$

Upon checking the docs of SDL (1.2) I saw that the SDL_Rect struct defines the x and y as Sint16. I'm making a bitmap font text scroller and I need those specifically to be unsigned ints because the text does need to go offscreen, yet still using the same struct because the SDLBlit method needs it. I tried creating my own and typecasting it as an SDL_Rect but that didn't work. Any ideas?

Also, to be more clear. The string of text scrolls to the left, therefore the first letter of my text does indeed go off screen but the rest doesn't. I assumed this was the problem.

for(int i=0;i<strlen(string);i++) {
  SDL_Blitsurface(bitmapsurface, rects[chars[i]], screen, destrect);
  destrect.x+=8;
}
\$\endgroup\$
1
\$\begingroup\$

Looking at the SDL_Rect documentation, it's defined as:

typedef struct {
  Sint16 x, y;
  Uint16 w, h;
} SDL_Rect;

This gives you a range of −32768 to 32767 for the x and y component, and a range of 0 to 65535 for the w and h component. It doesn't make sense to have negative widths and heights (thus w and h are unsigned), and x and y are already signed, meaning that it can represent off-screen positions (up to 32k pixels to the left of the screen and up to 32k pixels above the top of the screen).

Assuming your characters are 8 pixels wide (you do destrect.x+=8;), you can have 4000 charaters to the left of the screen and still be within the representable range of Sint16.

Only render what's on the screen, as the other poster suggested. In general, there are 3 cases:

  1. Character is completely off-screen, no need to render

  2. Character is partially off-screen, render parts of it

  3. Character is completely on-screen, render it fully

In case the blitting function handles clipping, case 2 and 3 can be combined.

Given that you have a fixed-width font, skipping off-screen characters is relatively easy and can be done up-front, with no conditionals inside the loop:

// The X position of where the text starts
int text_position_x = -90000;

// The text that you want to output
const char *chars = "Hello World";

// The fixed width of each character
int char_width = 8;

// Determine the first on-screen character
int first_character = 0;
int last_character = strlen(chars);

// If text starts off-screen, skip completely invisible characters
if (text_position_x < 0) {
    first_character = -text_position_x / char_width;
    text_position_x += char_width * first_character;
}

// text_position_x will be >= -char_width + 1
dstrect.x = text_position_x;
for (int i=first_character; i<last_character; i++) {
    SDL_Blitsurface(bitmapsurface, rects[chars[i]], screen, destrect);
    destrect.x+=8;
}

Some other remarks:

  • Call strlen() only once at the beginning and not in every iteration
  • You can do clipping on the top / right / bottom edge of the screen as well
  • You could cull some strings early once you know they are fully off-screen
\$\endgroup\$
0
\$\begingroup\$

You will have to check (where the text is, Inside or outside the screen) before you render, and correct it.

Example:

if( rec.x < 0 )
{
    // Here you will set something to render the other par of the text in x=0;
}
\$\endgroup\$
  • \$\begingroup\$ My routine goes through a for loop looking at each character and blits it to the screen; then increments the destinations rect.x accordingly. Shouldn't that mean that even though certain rects are off screen it should still render the ones that are? Think of it as each letter in a sentence being a rect with the x variable being decreased accordingly per frame. \$\endgroup\$ – user093837 Apr 15 '15 at 2:21
  • \$\begingroup\$ Try to render only the thing that are in the screen. The text is scrooling pixel per pixel or, character per character?? If you do, pixel per pixel, yo will need to render a character twice, one in x=0 and other in x=SCREEN_WIDTH \$\endgroup\$ – ReymonARG Apr 15 '15 at 2:33
  • \$\begingroup\$ Per pixel. Why one for x=screen width? I'm a bit confused here. Basically the function loops through a string grabs the char an outputs via a blit to the dest rect. Then I increment x accordingly (+8 because char width is 8) \$\endgroup\$ – user093837 Apr 15 '15 at 19:16
  • \$\begingroup\$ 8 pixel is the width of the Char? Ok. So if you scroll 8 pixel, you don't need to do. \$\endgroup\$ – ReymonARG Apr 15 '15 at 19:21
  • \$\begingroup\$ I'm not scrolling 8 pixels. 8 is just the width of the char an it's x position is incremented/decremented by one. \$\endgroup\$ – user093837 Apr 15 '15 at 21:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.