SDL image keep flashing, why?

Anybody can help? How can I modify my code to not keeping the text and images flashing?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
// Screen surface
SDL_Surface *gScreen;
SDL_Surface* fontSurface;
SDL_Color fColor;
SDL_Rect fontRect;
TTF_Font* font;
int score=0;
char *rank="";
char buffer [50];
char *question[] = {"1. The Boston matrix is used to help a firm with its:","2. The Cash cow in the Boston matrix has:","3. Which of these is not a common objective of a startup?","4. Which source of finance is a new sole trader business likely to use?","5. Which of these types of businesses are in the public sector?","XXX","XXX"};
char *choiceA[]= {"A. Cash flow","A. High market share, high growth","A. Celebrity status","A. Friends and family","A. Private limited company",""};
char *choiceB[]= {"B. Product portfolio","B. Low market hare, high growth","B. Growth","B. Bank loan","B. Public limited company"," "};
char *choiceC[]= {"C. Share price","C. High market share, low growth","C. Survival","C. Retained profit","C. Sole trader"," "};
char *choiceD[]= {"D. Organizational structure","D. Low market share, low growth","D. Celebrity status","D. All of the above","D. Government organizations"," "};
int score_q[] = {0,110,150,130,200,200};

char *correct_ans[] = {"","B","C","A","A","D"};
int index=0;

//Initialize the font of all text in the game, set to green
void fontInit(){
        TTF_Init();
        font = TTF_OpenFont("arial.ttf", 18);
        fColor.r = 0;
        fColor.g = 255;
        fColor.b = 0;
}

//Function for loading bmp files and displaying on the screen. 
void ShowBMP(char *file, SDL_Surface *screen, int x, int y)
{
    SDL_Surface *image;
	SDL_Surface *optimized_image;
    SDL_Rect dest;

	
	
    /* Load the BMP file into a surface */

    //image = SDL_LoadBMP(file);
	image = IMG_Load(file);
	optimized_image = SDL_DisplayFormat(image);
	SDL_FreeSurface(image);
	
    if ( optimized_image == NULL ) {
        fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError());
        return;    
	}

    /*   onto the screen surface.
       The surfaces should not be locked at this point.
     */
    dest.x = x;
    dest.y = y;
    dest.w = image->w;
    dest.h = image->h ;
    
    SDL_SetColorKey(optimized_image, SDL_SRCCOLORKEY, SDL_MapRGB(optimized_image->format, 255, 255, 255));
	SDL_BlitSurface(optimized_image, NULL, screen, &dest);
    /* Update the changed portion of the screen */
    SDL_UpdateRects(screen, 1, &dest);
	
	//SDL_FreeSurface(optimized_image);
}


//Print the designated string at the specified coordinates
void printF(char *c, int x, int y){
        fontSurface = TTF_RenderText_Solid(font, c, fColor);
        fontRect.x = x;
        fontRect.y = y;
        SDL_BlitSurface(fontSurface, NULL, gScreen, &fontRect);
}

struct UIState
{
  int mousex;
  int mousey;
  int mousedown;

  int hotitem;
  int activeitem;
} 
uistate = {0,0,0,0,0};

// Simplified interface to SDL's fillrect call
void drawrect(int x, int y, int w, int h, int color)
{
  SDL_Rect r;
  r.x = x;
  r.y = y;
  r.w = w;
  r.h = h;
  SDL_FillRect(gScreen, &r, color);
}

// Check whether current mouse position is within a rectangle
int regionhit(int x, int y, int w, int h)
{
  if (uistate.mousex < x ||
    uistate.mousey < y ||
    uistate.mousex >= x + w ||
    uistate.mousey >= y + h)
    return 0;
  return 1;
}

// Create a button
int button(int id, int x, int y)
{
  // Check whether the button should be hot
  if (regionhit(x, y, 282, 48))
  {
    uistate.hotitem = id;
    if (uistate.activeitem == 0 && uistate.mousedown)
      uistate.activeitem = id;
  }

  // Render button 
  drawrect(x+8, y+8, 282, 48, 0);
  if (uistate.hotitem == id)
  {
    if (uistate.activeitem == id)
    {
      // Shadow for the button 
      drawrect(x+2, y+2, 282, 48, 0xffffff);
    }
    else
    {
      // Button is merely 'hot'
      drawrect(x, y, 282, 48, 0xffffff);
    }
  }
  else
  {
    // button is not hot, but it may be active    
    drawrect(x, y, 282, 48, 0xaaaaaa);
  }

  // If button is hot and active, but mouse button is not
  // down, the user must have clicked the button.
  if (uistate.mousedown == 0 && 
    uistate.hotitem == id && 
    uistate.activeitem == id)
    return 1;

  // Otherwise, no clicky.
  return 0;
}

// Prepare for IMGUI code
void imgui_prepare()
{
  uistate.hotitem = 0;
}

// Finish up after IMGUI code
void imgui_finish()
{
  if (uistate.mousedown == 0)
  {
    uistate.activeitem = 0;
  }
  else
  {
    if (uistate.activeitem == 0)
      uistate.activeitem = -1;
  }
}

// Rendering function
void render()
{ 
		  
  imgui_prepare();
      
  //printF(question[index], 100, 100);  
  //button(10,25,90);
  printF(question[index], 30, 100);
  
  
  //Button A
  if (button(1,30,170)) {
	  if (correct_ans[index] == "A") {
	     score =score + score_q[index];
      }
	  else { 
         score =score - score_q[index];		  
	  }
	  //return 0;
  }
  printF(choiceA[index], 35, 180);
  
  //Button B
  if (button(2,330,170)){
	  if (correct_ans[index] == "B") {
	     score =score + score_q[index];
	  }
	  else { 
         score =score - score_q[index];		  
	  }
  }
  printF(choiceB[index], 335, 180);
  
  //Button C
  if (button(3,30,250)){
	  if (correct_ans[index] == "C") {
	     score =score + score_q[index];
	  }
	  else {
         score =score - score_q[index];		  
	  }
  }
  printF(choiceC[index], 35, 260);
    
  //Button D
  if (button(4,330,250)){
	  if (correct_ans[index] == "D") {
	     score =score + score_q[index];
      }		 
	  else { 
         score =score - score_q[index];		  
	  }
  }
  printF(choiceD[index], 335, 260);
  
  //convert the score to char and use base 10 to display
  printF("Your score is", 50, 320);
  printF(itoa(score,buffer,10), 230, 320);
  
  printF("Your rank is",50, 350);
  printF(rank,230,350);
 

 //Load image depending on points
  if (score <= -50) {     
	 ShowBMP("desktop_01.bmp", gScreen, 400,360);  
	 //SDL_Delay(1000);
	 //SDL_Quit();
  }	 
  if (score > -50 && score <100) {
	 ShowBMP("Hobo_0.bmp", gScreen, 400,360);   
	 rank = "Hobo";
  }
  if (score >=100 && score < 250) {
	 ShowBMP("Normal_150.bmp", gScreen, 400,360);   
	 rank = "Normal";
  }	  
  if (score >=250 && score < 500) {
     ShowBMP("Businessman_250.bmp",	gScreen, 400,360);   
	 rank = "Businessman";
  }
  if (score >=500) {
     ShowBMP("Wealthy_500.bmp",	gScreen, 400,360);  
     rank = "Wealthy";	 
  }	
 
   imgui_finish();  
  // update the screen
  SDL_UpdateRect(gScreen, 0, 0, 640, 480);    
     
  // don't take all the cpu time
  SDL_Delay(10); 
  
}

// Entry point
int main(int argc, char *argv[])
{
  // Initialize SDL's subsystems - in this case, only video.
    if (SDL_Init(SDL_INIT_VIDEO) < 0) 
  {
        fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
        exit(1);
    }

  // Register SDL_Quit to be called at exit; makes sure things are
  // cleaned up when we quit.
    atexit(SDL_Quit);
    
  // Attempt to create a 640x480 window with 32bit pixels.
    gScreen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
  
  //Initialize fonts
    fontInit();

  // If we fail, return error.
    if (gScreen == NULL) 
  {
        fprintf(stderr, "Unable to set up video: %s\n", SDL_GetError());
        exit(1);
    }
	
  static int bgcolor = 0x77 ;

  // clear screen
  drawrect(0,0,640,480,bgcolor);
  
  ShowBMP("background_640x480.png",gScreen,0,0);
  
  // Main loop: loop forever.
	index=0;
    while (index < sizeof(*question)+1 )
    {
	
        ShowBMP("background_640x480.png",gScreen,0,0);

        // Render stuff
		render();
		
					
    // Poll for events, and handle the ones we care about.
        SDL_Event event;
        while (SDL_PollEvent(&event)) 
        {
            switch (event.type) 
            {
			  case SDL_MOUSEMOTION:
				// update mouse position
				uistate.mousex = event.motion.x;
				uistate.mousey = event.motion.y;
				break;
			  case SDL_MOUSEBUTTONDOWN:
				// update button down state if left-clicking
				if (event.button.button == 1) {
				  uistate.mousedown = 1;
					  index++;
}								
				break;
			  case SDL_MOUSEBUTTONUP:
				// update button down state if left-clicking
				if (event.button.button == 1)
				  uistate.mousedown = 0;
				break;
			  
			  case SDL_KEYUP:                  
				switch (event.key.keysym.sym)
				{
				case SDLK_ESCAPE:
				  // If escape is pressed, return (and thus, quit)
				  return 0;
				}
                break;
              case SDL_QUIT:
                return(0);
            }
	
			
        }
		
    }


    return 0;
}
You draw an image and then you make what you draw visible right away by calling SDL_UpdateRects, so between you draw the background and a button you will only see the background at that position and that is what causes the flashing.

It's much better to draw everything that you want to draw to the screen, and then, when you have drawn everything want to draw, you make it visible by calling SDL_UpdateRects, SDL_UpdateRect or SDL_Flip.
Topic archived. No new replies allowed.