rest() + save_bitmap() clashes?
Dark Nation

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

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

Dark Nation

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

This may be completely irrelevant, but

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

What is this supposed to do?

Dark Nation

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.

Thread #586658. Printed from Allegro.cc