Image Scrolling, Not Working

Snibril
Unregistered
 
Post: #1
I am trying to scroll a background image vertically... The Xcord and Ycord do not work properly, I know it must be something I did. Can anyone help me? Here's the code:


Code:
#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>
#include <SDL_image.h>



int SDL_bgscroll(SDL_Surface *screen, int screen_x, int screen_y, int x_inc, int y_inc, SDL_Surface *bg_image, int x_cur, int y_cur)

{

// Retrieve the current screen and width._If empty, fill with the defaults.



SDL_Rect pictureLocationy1, pictureLocationy2, pictureLocationx1,

pictureLocationx2, pictureLocation_mid;



if (screen_x == 0) { screen_x = 1024; }

if (screen_y == 0) { screen_y = 768; }



// Increase the current by the incrementer.

x_cur = x_cur + x_inc;

printf("%d :: X screen,\n%d :: Y screen\n\n",screen_x,screen_y);

printf("%d :: X cord_,\n%d :: Y cord_\n\n",x_cur,y_cur);

printf("%d :: X incre ,\n%d :: Y incre \n\n",x_inc,y_inc);

y_cur = y_cur + y_inc;



/* The way this works is if the Y_inc is equal to 0 and the y_cur is equal to 0, it will NOT draw side pictures._Same thing with the x locations._That leavesa maximum _5_ pictures being rendered at one time on screen, and a minimum of_1_ picture being rendered._*/



bool has_x, has_y;



// Render the picture(s).

// First, we check the X & Y axis'.

if ((x_cur != 0) || (x_inc != 0)) { has_x = 1; }

if ((y_cur != 0) || (y_inc != 0)) { has_y = 1; }



// If they are existant, render the side pictures and top pictures.

if (has_x == 1){

// Render side pictures.

pictureLocationy1.x = x_cur - screen_x; pictureLocationy1.y = 0;

SDL_BlitSurface(bg_image, NULL, screen, &pictureLocationy1);

pictureLocationy2.x = x_cur + screen_x; pictureLocationy2.y = 0;

SDL_BlitSurface(bg_image, NULL, screen, &pictureLocationy2);

}

if (has_y == 1){

// Render top pictures.

pictureLocationx1.x = 0; pictureLocationx1.y = y_cur - screen_y;

SDL_BlitSurface(bg_image, NULL, screen, &pictureLocationx1);

pictureLocationx2.x = 0; pictureLocationx2.y = y_cur + screen_y;

SDL_BlitSurface(bg_image, NULL, screen, &pictureLocationx2);

}



// Render the middle picture.

pictureLocation_mid.x = x_cur; pictureLocation_mid.y = y_cur;

SDL_BlitSurface(bg_image, NULL, screen, &pictureLocation_mid);

}



// SDL Screen un/locking functions.

void Slock(SDL_Surface *screen)

{

if ( SDL_MUSTLOCK(screen) )

{

if ( SDL_LockSurface(screen) < 0 )

{

return;

}

}

}



void Sulock(SDL_Surface *screen)

{

if ( SDL_MUSTLOCK(screen) )

{

SDL_UnlockSurface(screen);

}

}



int main(int argc, char *argv[])

{

int x_cur = 0, y_cur = 0;



// Initialize SDL Video and Audio.

if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0 )

{

printf("Unable to init SDL: %s\n", SDL_GetError());

exit(1);

}

atexit(SDL_Quit);



SDL_Surface *screen;

SDL_Surface *bg_image;



// Set the screen resolution to 1024x768x32 with

// Hardware, Double Buffer, and Fullscreen.

screen=SDL_SetVideoMode(1024,768,32,SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN);​

if ( screen == NULL )

{

printf("System is unable to set 1024x768x32 video: %s\n", SDL_GetError());

exit(1);

}

int done=0;



bg_image = IMG_Load("background.bmp");

if (bg_image == NULL) {

fprintf(stderr, "Couldn't load %s: %s\n", "background.bmp", SDL_GetError());

return 0;

}


while(done == 0){



SDL_Event event;

while ( SDL_PollEvent(&event) ){



if ( event.type == SDL_KEYDOWN ){

if ( event.key.keysym.sym == SDLK_ESCAPE ) { done = 1; }

}

}

// Reset the values if the currents are above the maximum.

SDL_bgscroll(screen, 1024, 768, 4, 4, bg_image, x_cur, y_cur);

Slock(screen);

Sulock(screen);

SDL_Flip(screen);

}

return 0;

}


Blink
Quote this message in a reply
Member
Posts: 233
Joined: 2003.05
Post: #2
I looked it over quickly, but I didn't see anything obvious.

I'd start by leaving the lock functions out of your main loop. You only need to lock surfaces if you are directly changing individual pixels in the pixel data of a surface.

If that doesn't work, do a couple sanity checks by sticking printf's for the applicable variables right before you blit to the screen surface. Smile

"Pay no attention to that man behind the curtain." - Wizard of Oz
Quote this message in a reply
Member
Posts: 233
Joined: 2003.05
Post: #3
Actually, it's just a simple oversight on your part.
Once you leave the bgscroll function x_cur and y_cur don't change. You didn't pass by reference...
You could alternately make x_cur and y_cur global, but I don't recommend that.

I changed your code up for you. Try it out. I'm rusty with straight C, but this works.

Just a suggestion, you probably don't want to use the SDL prefix on functions that don't belong to the library. I'd use a prefix specific to your own program so you can keep them seperate.

Here's the fix:

#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>

enum bool
{
false = 0,
true
};

int SDL_bgscroll(SDL_Surface *screen, int screen_x, int screen_y, int x_inc, int y_inc, SDL_Surface *bg_image, int * x_cur, int * y_cur)

{

// Retrieve the current screen and width._If empty, fill with the defaults.



SDL_Rect pictureLocationy1, pictureLocationy2, pictureLocationx1,

pictureLocationx2, pictureLocation_mid;



if (screen_x == 0) { screen_x = 1024; }

if (screen_y == 0) { screen_y = 768; }



// Increase the current by the incrementer.

x_cur = x_cur + x_inc;

printf("%d :: X screen,\n%d :: Y screen\n\n",screen_x,screen_y);

printf("%d :: X cord_,\n%d :: Y cord_\n\n",*x_cur,*y_cur);

printf("%d :: X incre ,\n%d :: Y incre \n\n",x_inc,y_inc);

*y_cur = *y_cur + y_inc;



/* The way this works is if the Y_inc is equal to 0 and the y_cur is equal to 0, it will NOT draw side pictures._Same thing with the x locations._That leavesa maximum _5_ pictures being rendered at one time on screen, and a minimum of_1_ picture being rendered._*/



int has_x, has_y;



// Render the picture(s).

// First, we check the X & Y axis'.

if ((x_cur != 0) || (x_inc != 0)) { has_x = 1; }

if ((y_cur != 0) || (y_inc != 0)) { has_y = 1; }



// If they are existant, render the side pictures and top pictures.

if (has_x == 1){

// Render side pictures.

pictureLocationy1.x = *x_cur - screen_x; pictureLocationy1.y = 0;

SDL_BlitSurface(bg_image, NULL, screen, &pictureLocationy1);

pictureLocationy2.x = *x_cur + screen_x; pictureLocationy2.y = 0;

SDL_BlitSurface(bg_image, NULL, screen, &pictureLocationy2);

}

if (has_y == 1){

// Render top pictures.

pictureLocationx1.x = 0; pictureLocationx1.y = *y_cur - screen_y;

SDL_BlitSurface(bg_image, NULL, screen, &pictureLocationx1);

pictureLocationx2.x = 0; pictureLocationx2.y = *y_cur + screen_y;

SDL_BlitSurface(bg_image, NULL, screen, &pictureLocationx2);

}



// Render the middle picture.

pictureLocation_mid.x = *x_cur; pictureLocation_mid.y = *y_cur;

SDL_BlitSurface(bg_image, NULL, screen, &pictureLocation_mid);

return true;
}



// SDL Screen un/locking functions.

void Slock(SDL_Surface *screen)

{

if ( SDL_MUSTLOCK(screen) )

{

if ( SDL_LockSurface(screen) < 0 )

{

return;

}

}

}



void Sulock(SDL_Surface *screen)

{

if ( SDL_MUSTLOCK(screen) )

{

SDL_UnlockSurface(screen);

}

}



int main(int argc, char *argv[])

{

int x_cur = 0, y_cur = 0;



// Initialize SDL Video and Audio.

if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0 )

{

printf("Unable to init SDL: %s\n", SDL_GetError());

exit(1);

}

atexit(SDL_Quit);



SDL_Surface *screen;

SDL_Surface *bg_image;



// Set the screen resolution to 1024x768x32 with

// Hardware, Double Buffer, and Fullscreen.

screen=SDL_SetVideoMode(1024,768,32,SDL_HWSURFACE|
SDL_DOUBLEBUF|SDL_FULLSCREEN);

if ( screen == NULL )

{

printf("System is unable to set 1024x768x32 video: %s\n", SDL_GetError());

exit(1);

}

int done=0;



bg_image = SDL_LoadBMP("contraruncolor.bmp");

if (bg_image == NULL) {

fprintf(stderr, "Couldn't load %s: %s\n", "background.bmp", SDL_GetError());

return 0;

}


while(done == 0){



SDL_Event event;

while ( SDL_PollEvent(&event) ){



if ( event.type == SDL_KEYDOWN ){

if ( event.key.keysym.sym == SDLK_ESCAPE ) { done = 1; }

}

}

// Reset the values if the currents are above the maximum.

SDL_bgscroll(screen, 1024, 768, 4, 4, bg_image, &x_cur, &y_cur);

//Slock(screen);

//Sulock(screen);

SDL_Flip(screen);

}

return 0;
}

"Pay no attention to that man behind the curtain." - Wizard of Oz
Quote this message in a reply
Snibril
Unregistered
 
Post: #4
Thank you, I will try this out. Also I achieved my desired affect with this snippet of code:

static int scrollPosition = 256;


/* picture.Location, defined */

SDL_Rect pictureLocation;
pictureLocation.x = 0;
pictureLocation.w = 1024;
pictureLocation.h = 768;

/* scrolling background */

SDL_BlitSurface ( background, &pictureLocation, screen, NULL );
scrollPosition--;

pictureLocation.y = scrollPosition;

if (scrollPosition <= 0)
scrollPosition = 0;



SDL_Flip( background );
Quote this message in a reply
Snibril
Unregistered
 
Post: #5
Quote:Originally posted by aaronsullivan
Actually, it's just a simple oversight on your part.
Once you leave the bgscroll function x_cur and y_cur don't change. You didn't pass by reference...
You could alternately make x_cur and y_cur global, but I don't recommend that.

I changed your code up for you. Try it out. I'm rusty with straight C, but this works.

Just a suggestion, you probably don't want to use the SDL prefix on functions that don't belong to the library. I'd use a prefix specific to your own program so you can keep them seperate.


I get these errors when I try to compile:

conflicting types for 'enum bool'

previous declaration as 'typedef bool bool'

parase error before 'false'
Quote this message in a reply
Member
Posts: 233
Joined: 2003.05
Post: #6
I was getting errors with using bool, so I made it an enumerated type.

Just remove:
enum bool
{
false = 0,
true
};


and it should work fine!

P.S. you could edit your message and take that giant quote out!

"Pay no attention to that man behind the curtain." - Wizard of Oz
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  alpha not working in SDL image NSDuo 7 4,140 Feb 9, 2008 11:28 PM
Last Post: NSDuo