|
[quad3d] Crash! |
ngiacomelli
Member #5,114
October 2004
|
I noticed that my game was crashing with a call to quad3d. This happens randomly, so I initially suspected overflow, or something similarly nasty and subversive! Basically, on my menu screen, the player can rotate a cube to select what he or she wants to do (New Game, Exit, etc). I logged some of the values that my game was passing to quad3d: Here's the call: Here's the type of numbers you see when the program doesn't crash: vtx1: 8642240 6481680 11927552 vtx2: 8642240 9246960 11927552 vtx3: 12329280 9246960 11927552 vtx4: 12329280 6481680 11927552 Here's some from when it does: vtx1: 320 120 2097169 vtx2: 320 15728520 2097169 vtx3: 20971360 15728520 2097169 vtx4: 20971360 120 2097169 The entire 3d navigation code is relatively self-contained. It's also part of a game started during a hack, so it's pretty messy: Header:
Here's the code that renders and translates the cube:
Here's how I set everything up:
Any suggestions?
|
kdevil
Member #1,075
March 2001
|
v1 = face->vtxlist + face->v1; The only suggestion I have is to add some logging before those statements and make sure you're getting what you expect for face->vtxlist. ----- |
Arthur Kalliokoski
Second in Command
February 2005
|
The crashing numbers include 320 and 120. Do those particular values occur somewhere else? Just a guess... a wild pointer is stuffing them everywhere They all watch too much MSNBC... they get ideas. |
ngiacomelli
Member #5,114
October 2004
|
EDIT: Looks like the navigation code is fine. If I skip its execution entirely, the game will still crash at random points. Looks like it's a rogue pointer, or something equally horrible! EDIT 2: Scratch that. Actually, with the navigation code entirely commented out, I have no crash problems. It's in there, somewhere. Full header: 1#ifndef nav3d
2#define nav3d
3
4#define NUM_VERTICES 8
5#define NUM_FACES 6
6
7typedef struct VTX
8{
9 fixed x, y, z;
10} VTX;
11
12typedef struct QUAD
13{
14 VTX *vtxlist;
15 int id;
16 int v1, v2, v3, v4;
17} QUAD;
18
19typedef struct SHAPE
20{
21 fixed x, y, z;
22 fixed rx, ry, rz;
23 fixed dz;
24 fixed drx, dry, drz;
25} SHAPE;
26
27VTX points[] =
28{
29 { -32 << 16, -32 << 16, -32 << 16 },
30 { -32 << 16, 32 << 16, -32 << 16 },
31 { 32 << 16, 32 << 16, -32 << 16 },
32 { 32 << 16, -32 << 16, -32 << 16 },
33 { -32 << 16, -32 << 16, 32 << 16 },
34 { -32 << 16, 32 << 16, 32 << 16 },
35 { 32 << 16, 32 << 16, 32 << 16 },
36 { 32 << 16, -32 << 16, 32 << 16 },
37};
38
39QUAD faces[] =
40{
41 { points, 0, 0, 3, 2, 1 },
42 { points, 1, 4, 5, 6, 7 },
43 { points, 2, 0, 1, 5, 4 },
44 { points, 3, 2, 3, 7, 6 },
45 { points, 4, 0, 4, 7, 3 },
46 { points, 5, 1, 2, 6, 5 }
47};
48
49SHAPE nav_cube;
50VTX output_points[NUM_VERTICES];
51QUAD output_faces[NUM_FACES];
52
53int mov_count, mov_direction;
54
55BITMAP *nav_texture[6];
56BITMAP *plank;
57char keybuf[KEY_MAX];
58
59#endif
Full source: 1#include <allegro.h>
2#include "application.h"
3#include "canvas.h"
4#include "object.h"
5#include "nav3d.h"
6
7void draw_quad(BITMAP *b, VTX *v1, VTX *v2, VTX *v3, VTX *v4, int face);
8
9int setup_navigation()
10{
11
12 int i = 0, x = 0, y = 0, i_a = 0;
13
14 nav_cube.x = 0; nav_cube.y = 0; nav_cube.z = 150 << 16;
15 nav_cube.rx = 0; nav_cube.ry = 0; nav_cube.rz = 0;
16 nav_cube.dz = 0; nav_cube.drx = 0; nav_cube.dry = 0; nav_cube.drz = 0;
17
18 mov_count = 0; mov_direction = 0;
19
20 set_projection_viewport(0, 0, 320, 240);
21
22 nav_texture[0] = load_bitmap("gfx/hud/tex0.bmp", NULL);
23 nav_texture[1] = load_bitmap("gfx/hud/tex1.bmp", NULL);
24 nav_texture[2] = load_bitmap("gfx/hud/tex2.bmp", NULL);
25 nav_texture[3] = load_bitmap("gfx/hud/tex3.bmp", NULL);
26 nav_texture[4] = load_bitmap("gfx/hud/tex4.bmp", NULL);
27 nav_texture[5] = load_bitmap("gfx/hud/tex5.bmp", NULL);
28
29 plank = load_bitmap("gfx/hud/plank.bmp", NULL);
30
31 if( nav_texture[0] == NULL || nav_texture[1] == NULL || nav_texture[2] == NULL || nav_texture[3] == NULL ||
32 nav_texture[5] == NULL || plank == NULL ) return 1;
33
34 return 0;
35
36}
37
38void update_navigation(void)
39{
40
41 nav_cube.z += nav_cube.dz;
42
43 if ((nav_cube.z > itofix(1024)) || (nav_cube.z < itofix(192))) nav_cube.dz = -nav_cube.dz;
44
45 nav_cube.rx += nav_cube.drx;
46 nav_cube.ry += nav_cube.dry;
47 nav_cube.rz += nav_cube.drz;
48
49}
50
51void translate_shapes(void)
52{
53
54 int c, d;
55 MATRIX matrix;
56 VTX *outpoint = output_points;
57 QUAD *outface = output_faces;
58
59 get_transformation_matrix(&matrix, itofix(1), nav_cube.rx, nav_cube.ry, nav_cube.rz, nav_cube.x, nav_cube.y, nav_cube.z);
60
61 for (d = 0; d < NUM_VERTICES; d++) {
62 apply_matrix(&matrix, points[d].x, points[d].y, points[d].z,
63 &outpoint[d].x, &outpoint[d].y, &outpoint[d].z);
64 persp_project(outpoint[d].x, outpoint[d].y, outpoint[d].z,
65 &outpoint[d].x, &outpoint[d].y);
66 }
67
68 for (d=0; d<NUM_FACES; d++) {
69 outface[d] = faces[d];
70 outface[d].vtxlist = outpoint;
71 }
72
73 outpoint += NUM_VERTICES;
74 outface += NUM_FACES;
75
76}
77
78void draw_quad(BITMAP *b, VTX *v1, VTX *v2, VTX *v3, VTX *v4, int face)
79{
80
81 V3D vtx1 = { 0, 0, 0, 0, 0, 0 };
82 V3D vtx2 = { 0, 0, 0, 32<<16, 0, 0 };
83 V3D vtx3 = { 0, 0, 0, 32<<16, 32<<16, 0 };
84 V3D vtx4 = { 0, 0, 0, 0, 32<<16, 0 };
85
86 vtx1.x = v1->x; vtx1.y = v1->y; vtx1.z = v1->z;
87 vtx2.x = v2->x; vtx2.y = v2->y; vtx2.z = v2->z;
88 vtx3.x = v3->x; vtx3.y = v3->y; vtx3.z = v3->z;
89 vtx4.x = v4->x; vtx4.y = v4->y; vtx4.z = v4->z;
90
91 log_write(" vtx1: %i %i %i", vtx1.x, vtx1.y, vtx1.z );
92 log_write(" vtx2: %i %i %i", vtx2.x, vtx2.y, vtx2.z );
93 log_write(" vtx3: %i %i %i", vtx3.x, vtx3.y, vtx3.z );
94 log_write(" vtx4: %i %i %i", vtx4.x, vtx4.y, vtx4.z );
95
96 quad3d(b, POLYTYPE_PTEX, nav_texture[face], &vtx1, &vtx2, &vtx3, &vtx4); // Crashes here!
97
98}
99
100int quad_cmp(const void *e1, const void *e2)
101{
102
103 QUAD *q1 = (QUAD *)e1;
104 QUAD *q2 = (QUAD *)e2;
105
106 fixed d1 = q1->vtxlist[q1->v1].z + q1->vtxlist[q1->v2].z +
107 q1->vtxlist[q1->v3].z + q1->vtxlist[q1->v4].z;
108
109 fixed d2 = q2->vtxlist[q2->v1].z + q2->vtxlist[q2->v2].z +
110 q2->vtxlist[q2->v3].z + q2->vtxlist[q2->v4].z;
111
112 return d2 - d1;
113
114}
115
116void draw_shapes(BITMAP *b)
117{
118
119 int c;
120 QUAD *face = output_faces;
121 VTX *v1, *v2, *v3, *v4;
122 qsort(output_faces, NUM_FACES, sizeof(QUAD), quad_cmp);
123
124 for (c=0; c < NUM_FACES; c++) {
125
126 v1 = face->vtxlist + face->v1;
127 v2 = face->vtxlist + face->v2;
128 v3 = face->vtxlist + face->v3;
129 v4 = face->vtxlist + face->v4;
130
131 draw_quad(b, v1, v2, v3, v4, face->id);
132
133 face++;
134
135 }
136
137}
138
139int get_look_face()
140{
141
142 int c;
143
144 QUAD *face = output_faces;
145
146 qsort(output_faces, NUM_FACES, sizeof(QUAD), quad_cmp);
147
148 for( c = 0; c < NUM_FACES; c++ ) {
149
150 if( c == (NUM_FACES-1) ) return face->id;
151 face++;
152
153 }
154
155 return -1;
156
157}
158
159void menu_logic() {
160
161 update_navigation();
162 translate_shapes();
163
164 if( mov_count > 0 ) {
165
166 mov_count += 2;
167
168 switch( mov_direction ) {
169
170 case 0:
171 nav_cube.rx += itofix(2);
172 break;
173 case 1:
174 nav_cube.rx -= itofix(2);
175 break;
176 case 2:
177 nav_cube.ry -= itofix(2);
178 break;
179 case 3:
180 nav_cube.ry += itofix(2);
181 break;
182
183 }
184
185 if( mov_count > 64 ) {
186 mov_count = 0;
187 }
188
189 }
190
191}
192
193void menu_input() {
194
195 if( key[KEY_D] && !keybuf[KEY_D] && mov_count <= 0 ) {
196
197 mov_count = 1; mov_direction = 3;
198
199 }
200
201 if( key[KEY_A] && !keybuf[KEY_A] && mov_count <= 0 ) {
202
203 mov_count = 1; mov_direction = 2;
204
205 }
206
207 if( key[KEY_S] && !keybuf[KEY_S] && mov_count <= 0 ) {
208
209 mov_count = 1; mov_direction = 0;
210
211 }
212
213 if( key[KEY_W] && !keybuf[KEY_W] && mov_count <= 0 ) {
214
215 mov_count = 1; mov_direction = 1;
216
217 }
218
219 if( key[KEY_SPACE] && !keybuf[KEY_SPACE] && mov_count <= 0 ) {
220
221 switch( get_look_face() ) {
222
223 case 0:
224 application_set_state(APP_GAME);
225 break;
226 case 1:
227 application_set_state(APP_TERMINATING);
228 break;
229
230 }
231
232 }
233
234 memcpy((void*)keybuf,(void*)key,sizeof(keybuf));
235
236}
237
238void render_menu()
239{
240
241 int x = 0, y = 0;
242
243 clear_to_color( buffer, makecol( 0, 0, 0 ) );
244
245 draw_shapes( buffer );
246 draw_sprite( buffer, plank, 110, 168 );
247
248 if( mov_count <= 0 ) {
249
250 switch( get_look_face() ) {
251
252 case 0:
253 textprintf_centre_ex(buffer, small_n, 160, 181, makecol(0, 0, 0), -1, "NEW GAME");
254 textprintf_centre_ex(buffer, small_n, 160, 180, makecol(255, 255, 255), -1, "NEW GAME");
255 break;
256 case 1:
257 textprintf_centre_ex(buffer, small_n, 160, 181, makecol(0, 0, 0), -1, "EXIT");
258 textprintf_centre_ex(buffer, small_n, 160, 180, makecol(255, 255, 255), -1, "EXIT");
259 break;
260 case 2:
261 textprintf_centre_ex(buffer, small_n, 160, 181, makecol(0, 0, 0), -1, "CREDITS");
262 textprintf_centre_ex(buffer, small_n, 160, 180, makecol(255, 255, 255), -1, "CREDITS");
263 break;
264 case 3:
265 textprintf_centre_ex(buffer, small_n, 160, 181, makecol(0, 0, 0), -1, "OPTIONS");
266 textprintf_centre_ex(buffer, small_n, 160, 180, makecol(255, 255, 255), -1, "OPTIONS");
267 break;
268 case 4:
269 textprintf_centre_ex(buffer, small_n, 160, 181, makecol(0, 0, 0), -1, "LOAD GAME");
270 textprintf_centre_ex(buffer, small_n, 160, 180, makecol(255, 255, 255), -1, "LOAD GAME");
271 break;
272 case 5:
273 textprintf_centre_ex(buffer, small_n, 160, 181, makecol(0, 0, 0), -1, "SAVE GAME");
274 textprintf_centre_ex(buffer, small_n, 160, 180, makecol(255, 255, 255), -1, "SAVE GAME");
275 break;
276
277 }
278
279 }
280
281 stretch_blit(buffer, screen, 0, 0, 320, 240, 0, 0, 640, 480);
282
283}
|
kazzmir
Member #1,786
December 2001
|
Would you mind attaching the source to the entire project? Im willing to debug it but I dont want to hack together the source from your code pastes. |
|