1 /*
2 
3 Copyright (C) 2015-2018 Night Dive Studios, LLC.
4 
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 
18 */
19 /*
20  * $Source: r:/prj/lib/src/3d/RCS/3d.h $
21  * $Revision: 1.35 $
22  * $Author: jaemz $
23  * $Date: 1994/09/20 13:21:45 $
24  *
25  * Header file for LookingGlass 3D library
26  *
27  * $Log: 3d.h $
28 
29  *------------------------------------------------------*
30  * MAC VERSION NOTES
31  *
32  *  All of the #pragma aux statements have been removed, because they only
33  *  specify the register order parameters are passed into routines.  Since
34  *  all this stuff has to work on both 68K and PowerPC machines, we have
35  *  to use C calling conventions almost everwhere.
36  *
37  *------------------------------------------------------*
38 
39  * Revision 1.35  1994/09/20  13:21:45  jaemz
40  * Added lighting features, took out old call interpret_object
41  *
42  * Revision 1.33  1994/08/28  14:48:05  kevin
43  * Added linear mapping alternative for detail level stuff.
44  *
45  * Revision 1.32  1994/08/18  03:45:08  jaemz
46  * Added call for g3_object_scale
47  *
48  * Revision 1.31  1994/07/21  00:28:25  jaemz
49  * Added stereo declares
50  *
51  * Revision 1.29  1994/06/08  21:20:12  jaemz
52  * Commented transform matrix
53  *
54  * Revision 1.28  1994/06/01  15:57:22  jaemz
55  * Added a "*" to g3_compute_normal
56  *
57  * Revision 1.27  1994/05/31  16:38:36  jaemz
58  * Added documenting comment to .h file about matrices being
59  * column based
60  *
61  * Revision 1.26  1994/05/19  09:47:42  kevin
62  * g3_light(draw)_t(l,floor_,wall_)map now use watcom register passing
63  conventions.
64  *
65  * Revision 1.25  1994/05/02  23:39:01  kevin
66  * Added prototypes for wall and floor map procedures.
67  *
68  * Revision 1.24  1994/02/08  20:48:06  kaboom
69  * Added translucent polygon prototypes\pragmas.
70  *
71  * Revision 1.23  1993/12/15  01:52:17  dc
72  * alloc_list
73  *
74  * Revision 1.22  1993/12/14  22:58:04  kevin
75  * Added declarations for biasx,biasy, and perspective mapper context
76  manipulation routines.
77  *
78  * Revision 1.21  1993/12/11  04:03:12  kevin
79  * Added declarations for g3_rotate_grad and _norm.
80  *
81  * Revision 1.20  1993/12/06  15:51:25  unknown
82  * c:\app\star24\vmode 132x44 uv mappers to take a phandle *, as they do
83  *
84  * Revision 1.19  1993/12/04  17:00:02  kaboom
85  * Added declarations for bitmap lighters.
86  *
87  * Revision 1.18  1993/11/07  09:02:15  dc
88  * support for replace_add_delta along axis
89  *
90  * Revision 1.17  1993/10/22  09:37:11  kaboom
91  * Added new prototypes and pragmas for linear map routines.
92  *
93  * Revision 1.16  1993/10/02  11:01:36  kaboom
94  * Changed names of clip_{line,polygon} to g3_clip_{line,polygon} to avoid
95  * name collisions.
96  *
97  * Revision 1.15  1993/10/02  09:11:30  kaboom
98  * Added declarations for scrw,scrh.  Added prototypes&pragmas for new
99  * clipping routines and g3_{draw,light}_tmap.  New inline for g3_set_vcolor.
100  *
101  * Revision 1.14  1993/08/11  15:02:42  kaboom
102  * Added prototypes and pragmas for lighting texture mappers.
103  *
104  * Revision 1.13  1993/08/04  00:48:39  dc
105  * move interpreter zaniness to separate file
106  *
107  * Revision 1.12  1993/07/08  23:36:08  kaboom
108  * Added prototypes for g3_bitmap(), g3_anchor_bitmap(), and
109  * g3_set_bitmap_scale().
110  *
111  * Revision 1.11  1993/06/30  11:20:01  spaz
112  * Added prototypes for g3_draw_cline, g3_draw_sline
113  *
114  * Revision 1.10  1993/06/18  15:47:24  kaboom
115  * Updated prototype for g3_project_point to reflect return value.
116  *
117  * Revision 1.9  1993/06/09  04:23:46  kaboom
118  * Changed prototype and comment for g3_draw_tmap_tile to reflect new usage.
119  *
120  * Revision 1.8  1993/06/04  16:53:29  matt
121  * Added hacks to get around c++ non-support of anonymous structures in unions.
122  *
123  * Revision 1.7  1993/05/24  15:51:04  matt
124  * Added g3_get_slew_step(), removed g3_draw_smooth_horizon(), changed a few
125  * comments.
126  *
127  * Revision 1.6  1993/05/21  16:09:17  matt
128  * Added new way to specifiy axis orientation, which may be more intuitive
129  *
130  * Revision 1.5  1993/05/13  12:17:08  matt
131  * Added new function, g3_check_codes()
132  *
133  * Revision 1.4  1993/05/11  15:23:49  matt
134  * Changed comment for g3_draw_tmap_tile() to reflect new functionality
135  *
136  * Revision 1.3  1993/05/11  14:57:53  matt
137  * Changed g3_vec_scale() to takes seperate dest & src.
138  * Added g3_get_view_pyramid().
139  *
140  * Revision 1.2  1993/05/10  13:25:14  matt
141  * Added the ability to access the elements of a vector as an array. Fields
142  * x,y,z can be accessed as xyz[0..2].
143  *
144  * Revision 1.1  1993/05/04  17:39:56  matt
145  * Initial revision
146  */
147 
148 #ifndef __3D_H
149 #define __3D_H
150 
151 #include <stdbool.h>
152 
153 #include "2d.h"
154 #include "fix.h"
155 
156 #pragma pack(push,2)
157 
158 // MLA defines
159 #define SwapFix(x, y)   \
160     {                   \
161         fix temp = (x); \
162         (x) = (y);      \
163         (y) = temp;     \
164     }
165 #define vm1 view_matrix.m1
166 #define vm2 view_matrix.m2
167 #define vm3 view_matrix.m3
168 #define vm4 view_matrix.m4
169 #define vm5 view_matrix.m5
170 #define vm6 view_matrix.m6
171 #define vm7 view_matrix.m7
172 #define vm8 view_matrix.m8
173 #define vm9 view_matrix.m9
174 
175 #define uvm1 unscaled_matrix.m1
176 #define uvm2 unscaled_matrix.m2
177 #define uvm3 unscaled_matrix.m3
178 #define uvm4 unscaled_matrix.m4
179 #define uvm5 unscaled_matrix.m5
180 #define uvm6 unscaled_matrix.m6
181 #define uvm7 unscaled_matrix.m7
182 #define uvm8 unscaled_matrix.m8
183 #define uvm9 unscaled_matrix.m9
184 
185 // Defines for stuff strewn all about the world
186 // #define stereo_on 1
187 
188 #define f1_0 fix_make(1, 0)
189 #define f0_5 fix_make(0, 0x8000)
190 #define f0_25 fix_make(0, 0x4000)
191 
192 // gets the next available pnt in reg.
193 #define getpnt(res)               \
194     {                             \
195         g3s_point *scratch;       \
196         if ((res = first_free)) { \
197             scratch = res->next;  \
198             first_free = scratch; \
199         }                         \
200     }
201 
202 // frees the point in the specified register. uses ebx as scratch
203 #define freepnt(src)                     \
204     {                                    \
205         g3s_point *scratch = first_free; \
206         src->next = scratch;             \
207         first_free = src;                \
208     }
209 
210 // FIXME Move to FIX
211 // new types:
212 typedef short sfix;
213 
214 #define sfix_make(a, b) ((((short)(a)) << 8) | (b))
215 #define fix_from_sfix(a) (((fix)(a)) << 8)
216 
217 #define g3_set_i(pnt, ii)          \
218     do {                           \
219         pnt->i = sfix_make(ii, 0); \
220         pnt->p3_flags |= PF_I;     \
221     } while (0);
222 #define g3_set_rgb(pnt, r, g, b)         \
223     do {                                 \
224         pnt->rgb = gr_bind_rgb(r, g, b); \
225         pnt->p3_flags |= PF_RGB;         \
226     } while (0);
227 
228 // constants
229 
230 // these are for rotation order when generating a matrix from angles
231 // bit 2 means y before z if 0, 1 means x before z if 0, 0 means x before y if 0
232 
233 #define ORDER_XYZ 0 // 000
234 #define ORDER_YXZ 1 // 001
235 #define ORDER_YZX 3 // 011
236 #define ORDER_XZY 4 // 100
237 #define ORDER_ZXY 6 // 110
238 #define ORDER_ZYX 7 // 111
239 
240 // To specify user's coordinate system: use one of these for each user_x_axis,
241 // user_y_axis,& user_z_axis in g3_init to tell the 3d what your x,y,& z mean.
242 
243 #define AXIS_RIGHT 1
244 #define AXIS_UP 2
245 #define AXIS_IN 3
246 #define AXIS_LEFT -AXIS_RIGHT
247 #define AXIS_DOWN -AXIS_UP
248 #define AXIS_OUT -AXIS_IN
249 
250 // vectors, points, matrices
251 
252 // NIGHTMARE CODE!!!!!!  ANONYMOUS UNIONS ARE BAAAAAAAD THINGS MAN
253 // MLA - left in the #ifdef so the C++ compiler handles it, we just have to
254 // change references of g3s_vector.x to g3s_vector.xyz[0] (or .gX, .gY, etc.
255 // from the #defines)
256 typedef struct g3s_vector {
257 #if 0 // MLA #ifdef __cplusplus
258 	fix x,y,z;
259 #else
260     union {
261         struct {
262             fix x, y, z;
263         };
264         fix xyz[3];
265     };
266 #endif
267 } g3s_vector;
268 
269 #define gX xyz[0]
270 #define gY xyz[1]
271 #define gZ xyz[2]
272 
273 typedef struct g3s_angvec {
274     fixang tx, ty, tz;
275 } g3s_angvec;
276 
277 // This transformation matrix is row based, ie
278 //|m1 m2 m3|   |x|   |x'|
279 //|m4 m5 m6| * |y| = |y'|
280 //|m7 m8 m9|   |z|   |z'|
281 //
282 // but of course the incoming y coordinates
283 // are inverted, have a nice day
284 typedef struct g3s_matrix {
285     fix m1, m2, m3, m4, m5, m6, m7, m8, m9;
286 } g3s_matrix;
287 
288 // typedef short g3s_phandle;    //used to refer to points, equal to pntnum * 4
289 typedef struct g3s_point *g3s_phandle;
290 
291 typedef struct g3s_point {
292 #if 0 // #ifdef __cplusplus
293 	fix x,y,z;
294 #else
295     union { // rotated 3d coords, use as vector or elements
296         g3s_vector vec;
297         struct {
298             fix x, y, z;
299         };
300         fix xyz[3];
301         g3s_phandle next; // next in free list, when point is unused
302     };
303 #endif
304 
305     fix sx, sy;     // screen coords
306     ubyte codes;     // clip codes
307     ubyte p3_flags; // misc flags
308 #if 0               // #ifdef __cplusplus
309 	sfix u,v;
310 #else
311     union {
312         struct {
313             sfix u, v;
314         } uv;        // for texturing, etc.
315         grs_rgb rgb; // for RGB-space gouraud shading
316     };
317 #endif
318     sfix i; // gouraud shading & lighting
319 } g3s_point;
320 
321 // clip codes
322 #define CC_OFF_LEFT 1
323 #define CC_OFF_RIGHT 2
324 #define CC_OFF_BOT 4
325 #define CC_OFF_TOP 8
326 #define CC_BEHIND 128
327 #define CC_CLIP_OVERFLOW 16
328 
329 // flags for the point structure
330 #define PF_U 1         // is u value used?
331 #define PF_V 2         // is v value used?
332 #define PF_I 4         // is i value used?
333 #define PF_PROJECTED 8 // has this point been projected?
334 #define PF_RGB 16      // are the RBG values used?
335 #define PF_CLIPPNT 32  // this point created by clipper
336 #define PF_LIT 64      // has this point been lit by the lighter?
337 
338 // lighting codes
339 #define LT_NONE 0
340 #define LT_SOLID 1
341 #define LT_DIFF 2
342 #define LT_SPEC 4
343 #define LT_GOUR 128
344 
345 #define LT_NEAR_LIGHT 16 // TRUE if light is near and has to be evaluated
346 #define LT_NEAR_VIEW 8   // TRUE if viewing point is near, and has to be reevaled
347 #define LT_LOC_LIGHT 32  // TRUE if light is a local point, not a vector
348 #define LT_TABSIZE 24    // size of the shading table
349 #define LT_BASELIT 15    // table entry of normal intensity (before saturating)
350 
351 extern fix scrw, scrh;
352 extern fix biasx, biasy;
353 
354 extern ubyte g3d_light_type;
355 extern fix g3d_amb_light, g3d_diff_light, g3d_spec_light;
356 extern fix g3d_ldotv, g3d_sdotl, g3d_sdotv, g3d_flash;
357 extern ubyte *g3d_light_tab;
358 extern g3s_vector g3d_light_src, g3d_light_trans;
359 extern g3s_vector g3d_light_src, g3d_light_trans;
360 extern g3s_vector g3d_view_vec, g3d_light_vec;
361 
362 // DG: my compiler was not happy about the names "or" and "and", so I appended a
363 // _
364 typedef struct g3s_codes {
365     byte or_;
366     byte and_;
367 } g3s_codes;
368 
369 /*
370  *      We're going to want a bunch of general-purpose 3d vector math
371  *      routines. These are:
372  *
373  *      Question:  some of these take a destination, and some change the
374  *              vector passed to them. Should we adopt a consistent interface?
375  *
376  * There's sure to be more of these
377  *
378  */
379 void g3_vec_sub(g3s_vector *dest, g3s_vector *src1, g3s_vector *src2);
380 void g3_vec_add(g3s_vector *dest, g3s_vector *src1, g3s_vector *src2);
381 
382 fix g3_vec_mag(g3s_vector *v);
383 void g3_vec_scale(g3s_vector *dest, g3s_vector *src, fix s);
384 void g3_vec_normalize(g3s_vector *v);
385 
386 void g3_compute_normal(g3s_vector *norm, g3s_vector *v0, g3s_vector *v1, g3s_vector *v2);
387 
388 fix g3_vec_dotprod(g3s_vector *v0, g3s_vector *v1);
389 
390 void g3_vec_rotate(g3s_vector *dest, g3s_vector *src, g3s_matrix *m);
391 // src and dest can be the same
392 
393 void g3_transpose(g3s_matrix *m);                          // transpose in place
394 void g3_copy_transpose(g3s_matrix *dest, g3s_matrix *src); // copy and transpose
395 void g3_matrix_x_matrix(g3s_matrix *dest, g3s_matrix *src1, g3s_matrix *src2);
396 
397 int g3_clip_line(g3s_point *src[], g3s_point *dest[]);
398 // MLA #pragma aux g3_clip_line parm [esi] [edi] modify [eax ebx ecx edx esi
399 // edi];
400 int g3_clip_polygon(int n, g3s_point *src[], g3s_point *dest[]);
401 // MLA #pragma aux g3_clip_polygon parm [ecx] [esi] [edi] modify [eax ebx ecx
402 // edx esi edi];
403 
404 /*
405  *      Graphics-specific 3d routines
406  *
407  */
408 
409 // stereo functions
410 short g3_init_stereo(short max_points, int user_x_axis, int user_y_axis, int user_z_axis);
411 // sets up system for stereo by allocating twice as many
412 // points, setting g3d_stereo_base to the amount of memory
413 // the points take up
414 
415 void g3_start_stereo_frame(grs_canvas *rt);
416 // mark all points as being unused, sets g3d_stereo to true
417 // sets g3d_rt_canv to rt so you know where to render to
418 
419 void g3_set_eyesep(fix sep);
420 // sets g3d_eyesep_raw to sep
421 
422 // System inialization, etc.
423 
424 short g3_init(short max_points, int user_x_axis, int user_y_axis, int user_z_axis);
425 // the three axis vars describe your coordintate system.  Use the constants
426 //      X_AXIS,Y_AXIS,Z_AXIS, or negative of these, to describe what your
427 // coordinates mean. For each of width_,height_, and depth_axis, specify
428 //      which of your axes goes in that dimension. Depth is into the screen,
429 //      height is up, and width is to the right
430 // returns number actually allocated
431 
432 void g3_shutdown(void); // frees allocated points, and whatever else
433 int g3_count_free_points(void);
434 
435 // Point definition and manipulation
436 
437 g3s_phandle g3_alloc_point(void);
438 // returns a free point
439 
440 int g3_alloc_list(int n, g3s_phandle *p);
441 // allocates n points into p, returns 0 for none, or n for ok
442 
443 g3s_phandle g3_rotate_point(g3s_vector *v);
444 // translate, rotate, and code point in 3-space. returns point handle
445 
446 g3s_phandle g3_rotate_norm(g3s_vector *v);
447 // rotate normal in 3-space. returns point handle.
448 
449 // g3s_phandle g3_rotate_grad(g3s_vector *v);
450 // MLA - defined as same routine in POINT.C
451 #define g3_rotate_grad g3_rotate_norm
452 // rotate gradient in 3-space. returns point handle.
453 
454 g3s_phandle g3_rotate_light_norm(g3s_vector *v);
455 // rotate light norm from obj space into viewer space
456 
457 int g3_project_point(g3s_phandle p);
458 // project already-rotated point. returns true if z>0
459 
460 g3s_phandle g3_transform_point(g3s_vector *v);
461 // translate, rotate, code, and project point (rotate_point + project_point);
462 // returns point handle
463 
464 void g3_rotate_delta_v(g3s_vector *dest, g3s_vector *src);
465 // rotates a delta - takes vector input, fills in vector
466 
467 void g3_rotate_delta_x(g3s_vector *dest, fix dx);
468 void g3_rotate_delta_y(g3s_vector *dest, fix dy);
469 void g3_rotate_delta_z(g3s_vector *dest, fix dz);
470 void g3_rotate_delta_xz(g3s_vector *dest, fix dx, fix dz);
471 void g3_rotate_delta_yz(g3s_vector *dest, fix dy, fix dz);
472 void g3_rotate_delta_xy(g3s_vector *dest, fix dx, fix dy);
473 void g3_rotate_delta_xyz(g3s_vector *dest, fix dx, fix dy, fix dz);
474 // rotate a deltas - take just the spefified values
475 
476 void g3_add_delta_v(g3s_phandle p, g3s_vector *delta);
477 void g3_add_delta_x(g3s_phandle p, fix dx);
478 void g3_add_delta_y(g3s_phandle p, fix dy);
479 void g3_add_delta_z(g3s_phandle p, fix dz);
480 void g3_add_delta_xy(g3s_phandle p, fix dx, fix dy);
481 void g3_add_delta_xz(g3s_phandle p, fix dx, fix dz);
482 void g3_add_delta_yz(g3s_phandle p, fix dy, fix dz);
483 void g3_add_delta_xyz(g3s_phandle p, fix dx, fix dy, fix dz);
484 // adds a delta to a point
485 
486 g3s_phandle g3_copy_add_delta_v(g3s_phandle src, g3s_vector *delta);
487 g3s_phandle g3_copy_add_delta_x(g3s_phandle src, fix dx);
488 g3s_phandle g3_copy_add_delta_y(g3s_phandle src, fix dy);
489 g3s_phandle g3_copy_add_delta_z(g3s_phandle src, fix dz);
490 g3s_phandle g3_copy_add_delta_xy(g3s_phandle src, fix dx, fix dy);
491 g3s_phandle g3_copy_add_delta_xz(g3s_phandle src, fix dx, fix dz);
492 g3s_phandle g3_copy_add_delta_yz(g3s_phandle src, fix dy, fix dz);
493 g3s_phandle g3_copy_add_delta_xyz(g3s_phandle src, fix dx, fix dy, fix dz);
494 // adds a delta to a point, and stores in a new point
495 
496 g3s_phandle g3_replace_add_delta_x(g3s_phandle src, g3s_phandle dst, fix dx);
497 g3s_phandle g3_replace_add_delta_y(g3s_phandle src, g3s_phandle dst, fix dy);
498 g3s_phandle g3_replace_add_delta_z(g3s_phandle src, g3s_phandle dst, fix dz);
499 // adds a delta to src and stores to preallocated point dst
500 
501 g3s_phandle g3_dup_point(g3s_phandle p); // makes copy of a point
502 
503 void g3_copy_point(g3s_phandle dest, g3s_phandle src);
504 
505 // do a whole bunch of points. returns codes and & or
506 g3s_codes g3_rotate_list(short n, g3s_phandle *dest_list, g3s_vector *v);
507 g3s_codes g3_transform_list(short n, g3s_phandle *dest_list, g3s_vector *v);
508 g3s_codes g3_project_list(short n, g3s_phandle *point_list);
509 
510 void g3_free_point(g3s_phandle p);               // adds to free list
511 void g3_free_list(int n_points, g3s_phandle *p); // adds to free list
512 
513 // Frame setup commands
514 
515 void g3_start_frame(void); // mark all points as unused
516 void g3_set_view_matrix(g3s_vector *pos, g3s_matrix *m, fix zoom);
517 void g3_set_view_angles(g3s_vector *pos, g3s_angvec *angles, int rotation_order,
518                         fix zoom); // takes ptr to angles
519 
520 int g3_end_frame(void); // returns number of points lost. thus, 0==no error
521 
522 // Lighting commands
523 void g3_light_diff(g3s_phandle norm, g3s_phandle pos); // takes normal vector
524                                                        // transformed, dots with
525                                                        // the light vec, puts
526                                                        // light val in norm
527 // MLA #pragma aux g3_light_diff "*" parm [eax] [edx] modify [eax edx ebx ecx
528 // esi edi];
529 
530 void g3_light_spec(g3s_phandle norm,
531                    g3s_phandle pos); // takes norm and point position, lights point
532 // MLA #pragma aux g3_light_spec "*" parm [eax] [edx] modify [eax edx ebx ecx
533 // esi edi];
534 
535 void g3_light_dands(g3s_phandle norm, g3s_phandle pos); // lights with both both
536 // MLA #pragma aux g3_light_dands "*" parm [eax] [edx] modify [eax edx ebx ecx
537 // esi edi];
538 
539 // farms out a point based on flags
540 fix g3_light(g3s_phandle norm, g3s_phandle pos);
541 // MLA #pragma aux g3_light "*" parm [eax] [edx] modify [eax edx ebx ecx esi
542 // edi];
543 
544 // generic list gronker, farms these points out
545 void g3_light_list(int n, g3s_phandle *norm, g3s_phandle *pos);
546 
547 // sets a light vector in source space directly
548 // this light vector has to be in user space so we can dot it with
549 // other vector.  This is either a point source (LT_LOC_LIGHT == TRUE)
550 // or a vector.
551 void g3_set_light_src(g3s_vector *l);
552 // MLA #pragma aux g3_set_light_src "*" parm [eax] modify [esi edi];
553 
554 // note these need to be called *after* you've built a frame or object
555 // in which you transform points
556 // evaluates light vector, putting it into light_vec.  Do not call this
557 // after setting an object up.  Only call before object frames.  Only
558 // for vector evaluation.  Only call for non local lighting.
559 // When lighting "modes" get set up, this will be called automagically
560 // when necessary.
561 void g3_eval_vec_light(void);
562 // MLA #pragma aux g3_eval_vec_light "*" modify [eax edx ebx ecx esi edi];
563 
564 // transforms light point into viewer coords with all scaling intact
565 // this prepares it to be subtracted from loc light points in eval_loc
566 // _light.  Call this after start_frame and before an object.
567 void g3_trans_loc_light(void);
568 // MLA #pragma aux g3_trans_loc_light "*" modify [eax edx ebx ecx esi edi];
569 
570 // evaluates light point relative to another point, uses light point
571 // this is only for local lighting, inside an object.  If its not local
572 // lighting, you don't need to call this one.  This assumes you'll want
573 // to set NEAR_LIGHT to zero.
574 void g3_eval_loc_light(g3s_phandle pos);
575 // MLA #pragma aux g3_eval_loc_light "*" parm [eax] modify [eax edx ebx ecx esi
576 // edi];
577 
578 // Evaluates and sets light vectors as necessary at the start of
579 // an object.  Does view vec if SPEC is set.  Transforms light
580 // vector or point depending how LOC_LIGHT is set.  Use this if
581 // both light and view will be modelled as far.  In fact, make
582 // sure both are set as far, or you will be sorry.
583 // Evaluates at the object center.  If necessary, evaluates the
584 // ldotv for light and view
585 void g3_eval_light_obj_cen(void);
586 // MLA #pragma aux g3_eval_light_obj_cen "*" modify [eax edx ebx ecx esi edi];
587 
588 // evaluates the light vector straight ahead pointing in
589 // at you, then evaluates ldotv as well.  Use after light vec
590 // has been evaluated.  Only need for specular
591 void g3_eval_view_ahead(void);
592 // MLA #pragma aux g3_eval_view_ahead "*" modify [eax edx ebx ecx esi edi];
593 
594 // takes the dot product of view and light, for specular light
595 void g3_eval_ldotv(void);
596 // MLA #pragma aux g3_eval_ldotv "*" modify [eax edx ebx ecx esi edi];
597 
598 // evaluate the view vector relative to a point
599 void g3_eval_view(g3s_phandle pos);
600 // MLA #pragma aux g3_eval_view "*" parm [eax] modify [eax edx ebx ecx esi edi];
601 
602 // Horizon
603 
604 void g3_draw_horizon(int sky_color, int ground_color);
605 
606 // Misc commands
607 
608 g3s_codes g3_check_codes(int n_verts, g3s_phandle *p);
609 // returns codes_and & codes_or of points
610 
611 bool g3_check_normal_facing(g3s_vector *v, g3s_vector *normal);
612 // takes surface normal and unrotated point on poly. normal need not
613 // be normalized
614 
615 bool g3_check_poly_facing(g3s_phandle p0, g3s_phandle p1, g3s_phandle p2);
616 // takes 3 rotated points on poly
617 
618 void g3_get_FOV(fixang *x, fixang *y);
619 // fills in field of view across width and height of screen
620 
621 fix g3_get_zoom(char axis, fixang angle, int window_width, int window_height);
622 // returns zoom factor to achieve the desired view angle. axis is 'y' or 'x'
623 
624 void g3_get_view_pyramid(g3s_vector *corners);
625 // fills in 4 vectors, which unit vectors from the eye that describe the
626 // view pyramid.  first vector is upper right, then clockwise
627 
628 void g3_get_slew_step(fix step_size, g3s_vector *x_step, g3s_vector *y_step, g3s_vector *z_step);
629 // fills in three vectors, each of length step_size, in the specified
630 // direction in the viewer's frame of reference.  any (or all) of the
631 // vector pointers can be NULL to skip that axis.
632 
633 // Instancing. These all return true if everything ok
634 
635 uchar g3_start_object(g3s_vector *p); // position only (no orientation).
636 
637 uchar g3_start_object_matrix(g3s_vector *p, g3s_matrix *m); // position and orientation. these can nest
638 
639 uchar g3_start_object_angles_v(g3s_vector *p, g3s_angvec *o,
640                                int rotation_order); // position and orientation vector. these can nest
641 uchar g3_start_object_angles_xyz(g3s_vector *p, fixang tx, fixang ty, fixang tz, int rotation_order);
642 
643 uchar g3_start_object_angles_x(g3s_vector *p, fixang tx);
644 uchar g3_start_object_angles_y(g3s_vector *p, fixang ty);
645 uchar g3_start_object_angles_z(g3s_vector *p, fixang tz);
646 uchar g3_start_object_angles_xy(g3s_vector *p, fixang tx, fixang ty, int rotation_order);
647 uchar g3_start_object_angles_xz(g3s_vector *p, fixang tx, fixang tz, int rotation_order);
648 uchar g3_start_object_angles_yz(g3s_vector *p, fixang ty, fixang tz, int rotation_order);
649 
650 // you can use this to scale things like make small boxes and the like.  The
651 // effect is to shrink or expand the points in their SOURCE coordinate system.
652 // Only call this after calling one of the start_object routines.  You can do it
653 // within a frame as well, the effect will be to make surrounding space smaller
654 // or bigger.  This will make you shoot towards or away from the origin,
655 // probably not the effect you're looking for
656 void g3_scale_object(fix s);
657 
658 void g3_end_object(void);
659 
660 // Drawing commands.
661 // all return 2d clip codes. See 2d header for values
662 
663 // note that for the 2 gouraud line drawers, the 3d assumes that the calling
664 // function has not only set the rgb or i fields of the passed points, but has
665 // also set the p3_flags byte to indicate which is being used.  'tis a terrible
666 // hack indeed (Spaz, 6/29)
667 
668 int g3_draw_point(g3s_phandle p);
669 int g3_draw_line(g3s_phandle p0, g3s_phandle p1);
670 int g3_draw_cline(g3s_phandle p0, g3s_phandle p1); // rgb-space gouraud line
671 int g3_draw_sline(g3s_phandle p0, g3s_phandle p1); // 2d-intensity gouraud line
672 
673 int g3_draw_poly(long c, int n_verts, g3s_phandle *p);
674 // MLA #pragma aux g3_draw_poly "*" parm [eax] [ecx] [esi] value [eax] modify
675 // [eax ebx ecx edx esi edi];
676 int g3_draw_tluc_poly(long c, int n_verts, g3s_phandle *p);
677 // MLA #pragma aux g3_draw_tluc_poly "*" parm [eax] [ecx] [esi] value [eax]
678 // modify [eax ebx ecx edx esi edi];
679 int g3_draw_spoly(int n_verts, g3s_phandle *p); // smooth poly
680 // MLA #pragma aux g3_draw_spoly "*" parm [ecx] [esi] value [eax] modify [eax
681 // ebx ecx edx esi edi];
682 int g3_draw_tluc_spoly(int n_verts, g3s_phandle *p); // smooth poly
683 // MLA #pragma aux g3_draw_tluc_spoly "*" parm [ecx] [esi] value [eax] modify
684 // [eax ebx ecx edx esi edi];
685 int g3_draw_cpoly(int n_verts, g3s_phandle *p); // RBG-space smooth poly
686 // MLA #pragma aux g3_draw_cpoly "*" parm [ecx] [esi] value [eax] modify [eax
687 // ebx ecx edx esi edi];
688 
689 int g3_check_and_draw_poly(long c, int n_verts, g3s_phandle *p);
690 // MLA #pragma aux g3_check_and_draw_poly "*" parm [eax] [ecx] [esi] value [eax]
691 // modify [eax ebx ecx edx esi edi];
692 int g3_check_and_draw_tluc_poly(long c, int n_verts, g3s_phandle *p);
693 // MLA #pragma aux g3_check_and_draw_tluc_poly "*" parm [eax] [ecx] [esi] value
694 // [eax] modify [eax ebx ecx edx esi edi];
695 int g3_check_and_draw_spoly(int n_verts, g3s_phandle *p);
696 // MLA #pragma aux g3_check_and_draw_spoly "*" parm [ecx] [esi] value [eax]
697 // modify [eax ebx ecx edx esi edi];
698 int g3_check_and_draw_tluc_spoly(int n_verts, g3s_phandle *p);
699 // MLA #pragma aux g3_check_and_draw_tluc_spoly "*" parm [ecx] [esi] value [eax]
700 // modify [eax ebx ecx edx esi edi];
701 int g3_check_and_draw_cpoly(int n_verts, g3s_phandle *p);
702 // MLA #pragma aux g3_check_and_draw_cpoly "*" parm [ecx] [esi] value [eax]
703 // modify [eax ebx ecx edx esi edi];
704 
705 // versions of the poly routines which take the args on the stack
706 int g3_draw_poly_st(int n_verts, ...);
707 int g3_draw_cpoly_st(int n_verts, ...); // RBG-space smooth poly
708 int g3_draw_spoly_st(int n_verts, ...); // smooth poly
709 int g3_check_and_draw_poly_st(int n_verts, ...);
710 int g3_check_and_draw_cpoly_st(int n_verts, ...);
711 int g3_check_and_draw_spoly_st(int n_verts, ...);
712 
713 grs_vertex **g3_bitmap(grs_bitmap *bm, g3s_phandle p);
714 // MLA #pragma aux g3_bitmap "*" parm [esi] [edi] modify [eax ebx ecx edx];
715 grs_vertex **g3_anchor_bitmap(grs_bitmap *bm, g3s_phandle p, short u_anchor, short v_anchor);
716 // MLA #pragma aux g3_anchor_bitmap "*" parm [esi] [edi] [eax] [edx] modify [eax
717 // ebx ecx edx];
718 grs_vertex **g3_light_bitmap(grs_bitmap *bm, g3s_phandle p);
719 // MLA #pragma aux g3_light_bitmap "*" parm [esi] [edi] modify [eax ebx ecx
720 // edx];
721 grs_vertex **g3_light_anchor_bitmap(grs_bitmap *bm, g3s_phandle p, short u_anchor, short v_anchor);
722 // MLA #pragma aux g3_light_anchor_bitmap "*" parm [esi] [edi] [eax] [edx]
723 // modify [eax ebx ecx edx];
724 grs_vertex **g3_full_light_bitmap(grs_bitmap *bm, grs_vertex **p);
725 // MLA #pragma aux g3_full_light_bitmap "*" parm [esi] [edi] modify [eax ebx ecx
726 // edx];
727 grs_vertex **g3_full_light_anchor_bitmap(grs_bitmap *bm, grs_vertex **p, short u_anchor, short v_anchor);
728 // MLA #pragma aux g3_full_light_anchor_bitmap "*" parm [esi] [edi] [eax] [edx]
729 // modify [eax ebx ecx edx];
730 
731 void g3_set_bitmap_scale(fix u_scale, fix v_scale);
732 // MLA #pragma aux g3_set_bitmap_scale "*" parm [ebx] [ecx] modify [eax ebx ecx
733 // edx];
734 
735 int g3_draw_tmap(int n, g3s_phandle *vp, grs_bitmap *bm);
736 int g3_light_tmap(int n, g3s_phandle *vp, grs_bitmap *bm);
737 int g3_draw_floor_map(int n, g3s_phandle *vp, grs_bitmap *bm);
738 int g3_light_floor_map(int n, g3s_phandle *vp, grs_bitmap *bm);
739 int g3_draw_wall_map(int n, g3s_phandle *vp, grs_bitmap *bm);
740 int g3_light_wall_map(int n, g3s_phandle *vp, grs_bitmap *bm);
741 int g3_draw_lmap(int n, g3s_phandle *vp, grs_bitmap *bm);
742 int g3_light_lmap(int n, g3s_phandle *vp, grs_bitmap *bm);
743 
744 #define g3_draw_tmap_quad(vp, bm) g3_draw_tmap_quad_tile(vp, bm, 1, 1)
745 #define g3_check_and_draw_tmap_quad(vp, bm) g3_check_and_draw_tmap_quad_tile(vp, bm, 1, 1)
746 // these take four points, which match the four points of the texture map
747 // corners.  The points are clockwise, and the first point is the upper left.
748 
749 int g3_draw_tmap_quad_tile(g3s_phandle *vp, grs_bitmap *bm, int width_count, int height_count);
750 // MLA #pragma aux g3_draw_tmap_quad_tile "*" parm [esi] [edi] [eax] [ebx] value
751 // [eax] modify [eax ebx ecx edx esi edi];
752 int g3_check_and_draw_tmap_quad_tile(g3s_phandle *vp, grs_bitmap *bm, int width_count, int height_count);
753 // MLA #pragma aux g3_check_and_draw_tmap_quad_tile "*" parm [esi] [edi] [eax]
754 // [ebx] value [eax] modify [eax ebx ecx edx esi edi];
755 // these are like draw_tmap_quad(), but tile the specified number of times
756 // across and down.
757 int g3_light_tmap_quad_tile(g3s_phandle *vp, grs_bitmap *bm, int width_count, int height_count);
758 // MLA #pragma aux g3_light_tmap_quad_tile "*" parm [esi] [edi] [eax] [ebx]
759 // value [eax] modify [eax ebx ecx edx esi edi];
760 int g3_check_and_light_tmap_quad_tile(g3s_phandle *vp, grs_bitmap *bm, int width_count, int height_count);
761 // MLA #pragma aux g3_check_and_light_tmap_quad_tile "*" parm [esi] [edi] [eax]
762 // [ebx] value [eax] modify [eax ebx ecx edx esi edi];
763 
764 int g3_draw_lmap_quad_tile(g3s_phandle *vp, grs_bitmap *bm, int width_count, int height_count);
765 // MLA #pragma aux g3_draw_lmap_quad_tile "*" parm [esi] [edi] [eax] [ebx] value
766 // [eax] modify [eax ebx ecx edx esi edi];
767 int g3_check_and_draw_lmap_quad_tile(g3s_phandle *vp, grs_bitmap *bm, int width_count, int height_count);
768 // MLA #pragma aux g3_check_and_draw_lmap_quad_tile "*" parm [esi] [edi] [eax]
769 // [ebx] value [eax] modify [eax ebx ecx edx esi edi];
770 int g3_light_lmap_quad_tile(g3s_phandle *vp, grs_bitmap *bm, int width_count, int height_count);
771 // MLA #pragma aux g3_light_lmap_quad_tile "*" parm [esi] [edi] [eax] [ebx]
772 // value [eax] modify [eax ebx ecx edx esi edi];
773 int g3_check_and_light_lmap_quad_tile(g3s_phandle *vp, grs_bitmap *bm, int width_count, int height_count);
774 // MLA #pragma aux g3_check_and_light_lmap_quad_tile "*" parm [esi] [edi] [eax]
775 // [ebx] value [eax] modify [eax ebx ecx edx esi edi];
776 
777 int g3_draw_tmap_tile(g3s_phandle upperleft, g3s_vector *u_vec, g3s_vector *v_vec, int nverts, g3s_phandle *vp,
778                       grs_bitmap *bm);
779 // MLA #pragma aux g3_draw_tmap_tile "*" parm [eax] [ebx] [ecx] [edx] [esi]
780 // [edi] value [eax] modify [eax ebx ecx edx esi edi];
781 // this will tile a texture map over an arbitrary polygon. upperleft is the
782 // point in 3-space the matches the upper left corner of the texture map.
783 // u_vec and v_vec are the u and v basis vectors respectively.
784 // upperleft need not be in the polygon.  If upperleft is 0, the warp matrix
785 // from the last texture map that drew (i.e. was at least partly on screen)
786 // will be used.
787 int g3_light_tmap_tile(g3s_phandle upperleft, g3s_vector *u_vec, g3s_vector *v_vec, int nverts, g3s_phandle *vp,
788                        grs_bitmap *bm);
789 // MLA #pragma aux g3_light_tmap_tile "*" parm [eax] [ebx] [ecx] [edx] [esi]
790 // [edi] value [eax] modify [eax ebx ecx edx esi edi];
791 int g3_draw_lmap_tile(g3s_phandle upperleft, g3s_vector *u_vec, g3s_vector *v_vec, int nverts, g3s_phandle *vp,
792                       grs_bitmap *bm);
793 // MLA #pragma aux g3_draw_lmap_tile "*" parm [eax] [ebx] [ecx] [edx] [esi]
794 // [edi] value [eax] modify [eax ebx ecx edx esi edi];
795 int g3_light_lmap_tile(g3s_phandle upperleft, g3s_vector *u_vec, g3s_vector *v_vec, int nverts, g3s_phandle *vp,
796                        grs_bitmap *bm);
797 // MLA #pragma aux g3_light_lmap_tile "*" parm [eax] [ebx] [ecx] [edx] [esi]
798 // [edi] value [eax] modify [eax ebx ecx edx esi edi];
799 
800 void g3_interpret_object(ubyte *object_ptr, ...);
801 extern void g3_set_tmaps_linear(void);
802 extern void g3_reset_tmaps(void);
803 
804 // Pragmas for all these functions
805 
806 /* MLA
807 #pragma aux g3_init_stereo "*" parm [eax] [ebx] [ecx] [edx] value [ax];
808 #pragma aux g3_start_stereo_frame "*" parm [eax] modify [eax ebx ecx];
809 #pragma aux g3_set_eyesep "*" parm [eax];
810 
811 #pragma aux g3_vec_dotprod "*" parm [esi] [edi] modify exact [eax ebx ecx edx
812 esi] #pragma aux g3_vec_mag "*" parm [esi] modify [eax ebx ecx edx esi edi]
813 #pragma aux g3_vec_normalize "*" parm [esi] modify [eax ebx ecx edx edi];
814 #pragma aux g3_vec_add "*" parm [edi] [esi] [ebx] modify exact [eax];
815 #pragma aux g3_vec_sub "*" parm [edi] [esi] [ebx] modify exact [eax];
816 #pragma aux g3_vec_scale "*" parm [edi] [esi] [ebx] modify exact [eax edx];
817 #pragma aug g3_vec_rotate "*" parm [ebx] [esi] [edi] modify [eax ecx edx];
818 
819 #pragma aux g3_init "*" parm [eax] [ebx] [ecx] [edx] value [ax];
820 #pragma aux g3_shutdown "*";
821 #pragma aux g3_count_free_points "*" value [eax];
822 
823 #pragma aux g3_alloc_point "*" value [eax] modify exact [eax esi ebx];
824 #pragma aux g3_alloc_list  "*" value [eax] parm [ecx] [esi] modify exact [eax
825 ebx esi];
826 
827 #pragma aux g3_rotate_point "*" parm [esi] value [edi] modify [eax ebx ecx edx
828 esi edi]; #pragma aux g3_rotate_grad "*" parm [esi] value [edi] modify [eax ebx
829 ecx edx esi edi]; #pragma aux g3_rotate_norm "*" parm [esi] value [edi] modify
830 [eax ebx ecx edx esi edi]; #pragma aux g3_project_point "*" parm [edi] modify
831 exact [eax ecx edx]; #pragma aux g3_transform_point "*" parm [esi] value [edi]
832 modify [eax ebx ecx edx esi edi]; #pragma aux g3_rotate_light_norm "*" parm
833 [esi] value [edi] modify [eax ebx ecx edx esi edi];
834 
835 
836 #pragma aux g3_rotate_list "*" parm [ecx] [edi] [esi] value [ax] modify [eax ebx
837 ecx edx esi edi]; #pragma aux g3_project_list "*" parm [ecx] [esi] value [ax]
838 modify [eax ebx ecx edx esi edi]; #pragma aux g3_transform_list "*" parm [ecx]
839 [edi] [esi] value [ax] modify [eax ebx ecx edx esi edi];
840 
841 #pragma aux g3_rotate_delta_v "*" parm [edi] [esi] modify [eax ebx ecx edx esi];
842 
843 #pragma aux g3_add_delta_v "*" parm [edi] [esi] modify [eax ebx edx esi];
844 #pragma aux g3_add_delta_x "*" parm [edi] [eax] modify [eax ebx edx];
845 #pragma aux g3_add_delta_y "*" parm [edi] [eax] modify [eax ebx edx];
846 #pragma aux g3_add_delta_z "*" parm [edi] [eax] modify [eax ebx edx];
847 #pragma aux g3_add_delta_xy "*" parm [edi] [eax] [ebx] modify exact [eax ebx ecx
848 edx esi]; #pragma aux g3_add_delta_xz "*" parm [edi] [eax] [ebx] modify exact
849 [eax ebx ecx edx esi]; #pragma aux g3_add_delta_yz "*" parm [edi] [eax] [ebx]
850 modify exact [eax ebx ecx edx esi]; #pragma aux g3_add_delta_xyz "*" parm [edi]
851 [eax] [ebx] [ecx] modify exact [eax ebx ecx edx esi];
852 
853 
854 #pragma aux g3_copy_add_delta_v "*" parm [esi] [ebx] value [edi] modify [eax
855 ebx]; #pragma aux g3_copy_add_delta_x "*" parm [esi] [eax] value [edi] modify
856 exact [eax ebx edx esi]; #pragma aux g3_copy_add_delta_y "*" parm [esi] [eax]
857 value [edi] modify exact [eax ebx edx esi]; #pragma aux g3_copy_add_delta_z "*"
858 parm [esi] [eax] value [edi] modify exact [eax ebx edx esi]; #pragma aux
859 g3_copy_add_delta_xy "*" parm [esi] [eax] [ebx] value [edi] modify exact [eax
860 ebx ecx edx]; #pragma aux g3_copy_add_delta_xz "*" parm [esi] [eax] [ebx] value
861 [edi] modify exact [eax ebx ecx edx]; #pragma aux g3_copy_add_delta_yz "*" parm
862 [esi] [eax] [ebx] value [edi] modify exact [eax ebx ecx edx]; #pragma aux
863 g3_copy_add_delta_xyz "*" parm [esi] [eax] [ebx] [ecx] value [edi] modify exact
864 [eax ebx ecx edx esi];
865 
866 #pragma aux g3_replace_add_delta_x "*" parm [esi] [edi] [eax] value [edi] modify
867 exact [eax ebx edx esi]; #pragma aux g3_replace_add_delta_y "*" parm [esi] [edi]
868 [eax] value [edi] modify exact [eax ebx edx esi]; #pragma aux
869 g3_replace_add_delta_z "*" parm [esi] [edi] [eax] value [edi] modify exact [eax
870 ebx edx esi];
871 
872 #pragma aux g3_rotate_delta_x  "*" parm [edi] [eax] modify exact [eax ebx edx];
873 #pragma aux g3_rotate_delta_y  "*" parm [edi] [eax] modify exact [eax ebx edx];
874 #pragma aux g3_rotate_delta_z  "*" parm [edi] [eax] modify exact [eax ebx edx];
875 #pragma aux g3_rotate_delta_xz "*" parm [edi] [eax] [ebx] modify exact [eax ebx
876 ecx edx esi]; #pragma aux g3_rotate_delta_xy "*" parm [edi] [eax] [ebx] modify
877 exact [eax ebx ecx edx esi]; #pragma aux g3_rotate_delta_yz "*" parm [edi] [eax]
878 [ebx] modify exact [eax ebx ecx edx esi]; #pragma aux g3_rotate_delta_xyz "*"
879 parm [edi] [eax] [ebx] [ecx] modify exact [eax ebx ecx edx esi];
880 
881 #pragma aux g3_dup_point "*" parm [esi] value [edi] modify [ebx ecx esi];
882 #pragma aux g3_copy_point "*" parm [edi] [esi] modify exact [ecx esi];
883 
884 #pragma aux g3_free_point "*" parm [eax] modify exact [ebx esi];
885 #pragma aux g3_free_list "*" parm [ecx] [esi] modify exact [eax ebx ecx esi];
886 
887 #pragma aux g3_set_view_matrix "*" parm [esi] [ebx] [eax] modify [eax ebx ecx
888 edx esi edi]; #pragma aux g3_set_view_angles "*" parm [esi] [ebx] [ecx] [eax]
889 modify [eax ebx ecx edx esi edi];
890 
891 #pragma aux g3_start_frame "*" modify [eax ebx ecx];
892 #pragma aux g3_end_frame "*" value [eax];
893 
894 #pragma aux g3_draw_horizon "*" parm [eax] [edx] modify [eax ebx ecx edx esi
895 edi];
896 
897 #pragma aux g3_check_codes "*" parm [ecx] [esi] value [bx] modify exact [ebx ecx
898 edx esi];
899 
900 #pragma aux g3_check_normal_facing "*" parm [esi] [edi] value [al] modify exact
901 [eax ebx ecx edx]; #pragma aux g3_check_poly_facing "*" parm [eax] [edx] [ebx]
902 value [al] modify [eax ebx ecx edx esi edi];
903 
904 #pragma aux g3_start_object "*" parm [esi] value [al] modify exact [eax];
905 #pragma aux g3_start_object_matrix "*" parm [esi] [edi] value [al] modify [eax
906 ebx ecx edx esi edi]; #pragma aux g3_start_object_angles_v "*" parm [esi] [edi]
907 [ecx] value [al] modify [eax ebx ecx edx esi edi]; #pragma aux
908 g3_start_object_angles_xyz "*" parm [esi] [eax] [ebx] [edx] [ecx] value [al]
909 modify [eax ebx ecx edx esi edi]; #pragma aux g3_start_object_angles_x "*" parm
910 [esi] [ebx] value [al] modify [eax ebx ecx edx esi edi]; #pragma aux
911 g3_start_object_angles_y "*" parm [esi] [ebx] value [al] modify [eax ebx ecx edx
912 esi edi]; #pragma aux g3_start_object_angles_z "*" parm [esi] [ebx] value [al]
913 modify [eax ebx ecx edx esi edi]; #pragma aux g3_start_object_angles_xy "*" parm
914 [esi] [ebx] [edx] [ecx] value [al] modify [eax ebx ecx edx esi edi]; #pragma aux
915 g3_start_object_angles_xz "*" parm [esi] [ebx] [edx] [ecx] value [al] modify
916 [eax ebx ecx edx esi edi]; #pragma aux g3_start_object_angles_yz "*" parm [esi]
917 [ebx] [edx] [ecx] value [al] modify [eax ebx ecx edx esi edi]; #pragma aux
918 g3_end_object "*" modify [ecx esi edi]; #pragma aux g3_scale_object "*" parm
919 [eax] modify [ecx eax edx];
920 
921 #pragma aux g3_draw_line "*" parm [esi] [edi] value [eax] modify [eax ebx ecx
922 edx esi edi]; #pragma aux g3_draw_cline "*" parm [esi] [edi] value [eax] modify
923 [eax ebx ecx edx esi edi]; #pragma aux g3_draw_sline "*" parm [esi] [edi] value
924 [eax] modify [eax ebx ecx edx esi edi]; #pragma aux g3_draw_point "*" parm [esi]
925 value [eax] modify [eax ecx edx esi];
926 
927 #pragma aux g3_get_FOV parm [esi] [edi] modify exact [eax ebx ecx edx];
928 #pragma aux g3_get_zoom "*" parm [eax] [ebx] [ecx] [edx] value [eax] modify
929 exact [eax ebx ecx edx esi edi];
930 
931 #pragma aux g3_get_view_pyramid "*" parm [edi] modify exact [eax ebx ecx edx esi
932 edi];
933 
934 #pragma aux g3_get_slew_step "*" parm [eax] [ebx] [ecx] [edi] modify exact [eax
935 edx esi];
936 
937 #pragma aux g3_compute_normal "*" parm [edi] [eax] [edx] [ebx] modify exact [eax
938 ebx ecx edx esi edi];
939 
940 #pragma aux g3_transpose parm [esi] modify exact [eax];
941 #pragma aux g3_copy_transpose parm [edi] [esi] modify exact [eax];
942 
943 #pragma aux g3_matrix_x_matrix parm [ebx] [esi] [edi] modify exact [eax ebx ecx
944 edx];
945 
946 #pragma aux g3_interpret_object "*" parm caller modify [eax ebx ecx edx esi
947 edi];
948 */
949 
950 // inline code to handle stack args for polygon routines
951 
952 // Note that these are a lot uglier than they need to be, because C is so
953 // annoying.  For starters, I shouldn't even have to specifiy the number of
954 // parms, since C obviously knows this number.  Secondly,  if I have varargs,
955 // C forces me to put all the args on the stack, when I really want the
956 // count in register and the rest on the stack.  Lastly, since these are
957 // inline functions, C won't do the stack fixup, and since I don't have
958 // access, once again, to the parameter count, I have to use the variable
959 // to fixup the stack.  This is really ugly since a wrong count supplied to
960 // the function will mess up the stack.  Too bad C doesn't have a constant
961 // defined to be the parameter count for the current function.
962 
963 // awwwww, poor matt
964 
965 // MLA- took these out because we can't do inline asm in PowerPC (or 68K for
966 // that matter) and all routines need to be C callable
967 /*
968 #pragma aux g3_draw_poly_st = \
969         "mov ecx,[esp]"                 \
970         "lea esi,4[esp]"                        \
971         "call	g3_draw_poly"     \
972         "pop ecx"                               \
973         "lea esp,[esp+ecx*4]"   \
974         parm [ecx] [esi] value [eax] modify [eax ebx ecx edx esi edi];
975 
976 #pragma aux g3_draw_spoly_st = \
977         "mov ecx,[esp]"                 \
978         "lea esi,4[esp]"                        \
979         "call	g3_draw_spoly"    \
980         "pop ecx"                               \
981         "lea esp,[esp+ecx*4]"   \
982         parm [ecx] [esi] value [eax] modify [eax ebx ecx edx esi edi];
983 
984 #pragma aux g3_draw_cpoly_st = \
985         "mov ecx,[esp]"                 \
986         "lea esi,4[esp]"                        \
987         "call	g3_draw_cpoly"    \
988         "pop ecx"                               \
989         "lea esp,[esp+ecx*4]"   \
990         parm [ecx] [esi] value [eax] modify [eax ebx ecx edx esi edi];
991 
992 #pragma aux g3_check_and_draw_poly_st = \
993         "mov ecx,[esp]"                 \
994         "lea esi,4[esp]"                        \
995         "call	g3_check_and_draw_poly"   \
996         "pop ecx"                               \
997         "lea esp,[esp+ecx*4]"   \
998         parm [ecx] [esi] value [eax] modify [eax ebx ecx edx esi edi];
999 
1000 #pragma aux g3_check_and_draw_cpoly_st = \
1001         "mov ecx,[esp]"                 \
1002         "lea esi,4[esp]"                        \
1003         "call	g3_check_and_draw_cpoly"  \
1004         "pop ecx"                               \
1005         "lea esp,[esp+ecx*4]"   \
1006         parm [ecx] [esi] value [eax] modify [eax ebx ecx edx esi edi];
1007 
1008 #pragma aux g3_check_and_draw_spoly_st = \
1009         "mov ecx,[esp]"                 \
1010         "lea esi,4[esp]"                        \
1011         "call	g3_check_and_draw_spoly"  \
1012         "pop ecx"                               \
1013         "lea esp,[esp+ecx*4]"   \
1014         parm [ecx] [esi] value [eax] modify [eax ebx ecx edx esi edi];
1015 */
1016 
1017 #pragma pack(pop)
1018 
1019 #endif /* __3D_H */
1020