Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » rest() + save_bitmap() clashes?

This thread is locked; no one can reply to it. rss feed Print
rest() + save_bitmap() clashes?
Dark Nation
Member #1,642
November 2001
avatar

My game calls the rest command to reduce CPU usage. However, after calling save_bitmap (called by a specific keypress to take snapshots), trouble begins. About 10 seconds after making the call to save_bitmap, my palette goes all wonky. I haven't studied it very closely, but I think it may be reverting to the system palette. Any ideas why? If I don't call save_bitmap (just return from the snapshot code) or remove the call to rest, everything is fine.

Billybob
Member #3,136
January 2003

Sounds like memory problems. Accessing memory haven't allocated, broken pointers, dangling pointers, etc.

Dark Nation
Member #1,642
November 2001
avatar

I've whittled down the code to about 100 lines (including several blank lines) and am still getting the error. Can anyone take a look and see if they get the same problem?

1#include <allegro.h>
2 
3bool quit=false;
4int d_nbmenu_proc(int msg,DIALOG *d,int c);
5 
6 
7int onExit()
8{
9 exit(0);
10}
11 
12static MENU the_menu[] =
13{
14 { "&Exit", onExit, NULL },
15 { NULL }
16};
17 
18int onSnapshot()
19{
20 BITMAP *screen2 = create_bitmap_ex(8,320,240);
21 char buf[20];
22 int num=0;
23 do
24 {
25 sprintf(buf, "test%03d.bmp", ++num);
26 } while(num<999 && exists(buf));
27 
28 blit(screen,screen2,0,0,0,0,320,240);
29 PALETTE temppal;
30 get_palette(temppal);
31 save_bitmap(buf,screen2,temppal);
32 destroy_bitmap(screen2);
33 return D_O_K;
34}
35 
36static DIALOG dialogs[] =
37{
38 { d_nbmenu_proc, 0, 0, 0, 13, 0, 0, 0, D_USER, 0, 0, (void *) the_menu },
39 { d_keyboard_proc, 0, 0, 0, 0, 0, 0, 'z', 0, 0, 0, (void *) onSnapshot },
40 { d_keyboard_proc, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, (void *) onExit },//
41 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL }
42};
43 
44int main(int argc,char **argv)
45{
46 allegro_init();
47 
48 if(install_timer() < 0)
49 {
50 al_trace(allegro_error);
51 exit(1);
52 }
53 
54 if(install_keyboard() < 0)
55 {
56 al_trace(allegro_error);
57 exit(1);
58 }
59 
60 if(install_mouse() < 0)
61 {
62 al_trace(allegro_error);
63 exit(1);
64 }
65 
66 set_color_depth(8);
67 if(set_gfx_mode(GFX_AUTODETECT_FULLSCREEN,320,240,0,0)!=0)
68 {
69 al_trace(allegro_error);
70 exit(1);
71 }
72 else
73 {
74 al_trace("OK\n");
75 }
76 DIALOG_PLAYER *player=init_dialog(dialogs,-1);
77 show_mouse(screen);
78 quit=!update_dialog(player);
79 while(!quit)
80 {
81 quit = !update_dialog(player);
82 }
83 return 0;
84}
85 
86END_OF_MAIN()
87 
88int d_nbmenu_proc(int msg,DIALOG *d,int c)
89{
90 rest (1);
91 return d_menu_proc(msg,d,c);
92}
93 
94/* end */

I compiled it with:

g++ -o test.exe test.cpp -lalleg

When you run it, hit the Z key on the keyboard. After about 5 to 10 seconds, the mouse will change colors. I have a strange feeling that it's because I have a rest command inside of a dialog procedure. Is that the problem? Is there a way to make it work? I've even tried replacing the nbmenu_proc with rest_proc, which I defined as:

int d_rest_proc(int msg,DIALOG *d,int c)
{
  rest (1);
  return D_O_K;
}

This still gives me the same bug.

Kauhiz
Member #4,798
July 2004

This may be completely irrelevant, but

do
{
    sprintf(buf, "test%03d.bmp", ++num);
} while(num<999 && exists(buf));

What is this supposed to do?

---
It's Ridge Racer! RIIIIIDGE RAAAAACER!

Dark Nation
Member #1,642
November 2001
avatar

It finds the first unused testXXX.bmp filename.

I even tried taking that part out and just using a static filename. Same bug.

I even copied the update_dialog function into my code and whittled it down as much as possible while still keeping the bug. I even took out the keyboard_proc and replaced it with specific functions. After doing that and a little more whittling, here is the current incarnation:

1#include <allegro.h>
2 
3bool quit=false;
4int d_rest_proc(int msg,DIALOG *d,int c);
5 
6 
7int onExit()
8{
9 exit(0);
10}
11 
12int onSnapshot()
13{
14 PALETTE temppal;
15 get_palette(temppal);
16 save_bitmap("test.bmp",screen,temppal);
17 return D_O_K;
18}
19 
20int d_exit_proc(int msg, DIALOG *d, int c)
21{
22 if (msg==MSG_KEY) exit(0);
23 return D_O_K;
24}
25 
26int d_snapshot_proc(int msg, DIALOG *d, int c)
27{
28 if (msg==MSG_KEY)
29 {
30 PALETTE temppal;
31 get_palette(temppal);
32 save_bitmap("test.bmp",screen,temppal);
33 }
34 return D_O_K;
35}
36 
37static DIALOG dialogs[] =
38{
39 { d_rest_proc, 0, 0, 0, 13, 0, 0, 0, D_USER, 0, 0, NULL },
40 { d_snapshot_proc, 0, 0, 0, 0, 0, 0, 'z', 0, 0, 0, NULL },
41 { d_exit_proc, 0, 0, 0, 0, 0, 0, 'x', 0, 0, 0, NULL },
42 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL }
43};
44 
45int update_dialog2(DIALOG_PLAYER *player)
46{
47 int c, cascii, cscan, ccombo, r, ret;
48 
49 /* deal with keyboard input */
50 if (keypressed())
51 {
52 cascii = readkey()&0xFF;
53 
54 /* keyboard shortcut? */
55 for (c=0; player->dialog[c].proc; c++)
56 {
57 if (utolower(player->dialog[c].key) == utolower(cascii))
58 {
59 object_message(player->dialog+c, MSG_KEY, cascii);
60 goto getout;
61 }
62 }
63 }
64 
65 /* send idle messages */
66 player->res |= dialog_message(player->dialog, MSG_IDLE, 0, &player->obj);
67 
68 getout:
69 
70 return 1;
71}
72 
73 
74int main(int argc,char **argv)
75{
76 allegro_init();
77 
78 if(install_timer() < 0)
79 {
80 al_trace(allegro_error);
81 exit(1);
82 }
83 
84 if(install_keyboard() < 0)
85 {
86 al_trace(allegro_error);
87 exit(1);
88 }
89 
90 if(install_mouse() < 0)
91 {
92 al_trace(allegro_error);
93 exit(1);
94 }
95 
96 set_color_depth(8);
97 if(set_gfx_mode(GFX_AUTODETECT_FULLSCREEN,320,240,0,0)!=0)
98 {
99 al_trace(allegro_error);
100 exit(1);
101 }
102 else
103 {
104 al_trace("OK\n");
105 }
106 DIALOG_PLAYER *player=init_dialog(dialogs,-1);
107 show_mouse(screen);
108 quit=!update_dialog2(player);
109 while(!quit)
110 {
111 quit = !update_dialog2(player);
112 }
113 return 0;
114}
115 
116END_OF_MAIN()
117 
118int d_rest_proc(int msg,DIALOG *d,int c)
119{
120 rest (1);
121 return D_O_K;
122}
123 
124/* end */

Thoughts? The bug seems to have something to do with MSG_IDLE messages. When I take out this line from update_dialog2:

player->res |= dialog_message(player->dialog, MSG_IDLE, 0, &player->obj);

...the bug goes away.

Edit: I just ran my original code and put a graphical display of the current palette on the screen. All of the colors change to what seems to be the default palette. What's worse, when I do a set_palette from a master palette I set up, the last 10 palette entries won't change. Odder still is the fact that if I output (through al_trace) the palette entries before and after the odd palette change, the values are the same. But, for some reason, the wrong colors are being displayed on the screen.

Go to: