00001 #define G3_DOT 0 //coloured dot
00002 #define G3_LINE 1 //coloured line
00003 #define G3_TRI 2 //coloured triangle
00004 #define G3_TTRI 3 //texture triangle (not implemented yet!)
00005
00006 #define G3_MAX_TYPE 3
00007
00008 #define G3_MAX_ANGLE 4095 //maximum angle (4096 degrees)
00009
00010
00011
00012
00013 #define G3_MAX_INTENSITY 31 //32 shades of each colour palette
00014
00015
00016 #pragma pack(push,1)
00017
00018
00019 class G3Light;
00020 class G3Buffer;
00021 class G3ZBuffer;
00022 class G3Scene;
00023 class G3Object;
00024
00025 struct Point3D {
00026 int32 x, y, z;
00027 int32 f;
00028 Point3D() : f(0) {};
00029 };
00030
00031 struct G3_def {
00032 uint8 typ;
00033 uint32 clr;
00034 uint32 p1;
00035 uint32 p2;
00036 uint32 p3;
00037 uint32 pn;
00038 };
00039
00040 struct G3_defx {
00041 uint8 typ;
00042 union {
00043 struct {
00044 uint8 r, g, b, R;
00045 }
00046 clr_;
00047 uint32 clr;
00048 };
00049 Point3D p1;
00050 Point3D p2;
00051 Point3D p3;
00052 Point3D pn;
00053 };
00054
00055 #define G3_dot G3_def
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 #define G3_dotx G3_defx
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 #define G3_line G3_def
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 #define G3_linex G3_defx
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 #define G3_tri G3_def
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 #define G3_trix G3_defx
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 #pragma pack(pop)
00148
00149
00150 struct G3Light : virtual public SystemCode {
00151 union {
00152 struct {
00153 uint8 r, g, b, R;
00154 }
00155 clr_;
00156 uint32 clr;
00157 };
00158 uint32 x;
00159 uint32 y;
00160 uint32 z;
00161 uint32 xang;
00162 uint32 yang;
00163 uint32 zang;
00164 uint32 axang;
00165 uint32 ayang;
00166 uint32 azang;
00167 uint32 flgs;
00168 G3Light() {
00169 RaiseException(ERR_BADARGS);
00170 }
00171 G3Light(int _clr, int xa, int ya, int za) {
00172 clr = _clr;
00173 xang = xa;
00174 yang = ya;
00175 zang = za;
00176 flgs = 1;
00177 }
00178 void SetClr(int _clr) {clr = _clr;}
00179 void SetAngles(uint x, uint y, uint z) { xang = x; yang = y; zang = z; }
00180 void GetAngles(uint32 *x, uint32 *y, uint32 *z) { if (x) *x = xang; if (y) *y = yang; if (z) *z = zang; }
00181 void AddAngles(int x, int y, int z) {
00182 xang += x; yang += y; zang += z;
00183 xang &= G3_MAX_ANGLE;
00184 yang &= G3_MAX_ANGLE;
00185 zang &= G3_MAX_ANGLE;
00186 }
00187 void Show() {flgs |= 0x0001;}
00188 void Hide() {flgs &= 0xfffe;}
00189 };
00190
00191 class G3Buffer : public Bitmap {
00192 friend class G3Scene;
00193 friend class G3Object;
00194 _PROTECTED_:
00195 Window *gfx;
00196 int32 postxadd, postyadd;
00197 public:
00198 G3Buffer();
00199 void Init(Window *_gfx);
00200 void Put() {
00201 gfx->Put(img, 0, 0, x_1, y_1);
00202 }
00203 void Uninit() {}
00204
00205 void Reset() {
00206 memset24(img, 0, xy);
00207 }
00208 };
00209
00210 class G3ZBuffer : public Bitmap {
00211 friend class G3Scene;
00212 friend class G3Object;
00213 _PROTECTED_:
00214 int16 *zbuf;
00215 Window *gfx;
00216 int32 postxadd, postyadd;
00217 public:
00218 G3ZBuffer();
00219 void Init(Window *_gfx);
00220 void Put() {
00221 gfx->Put(img, 0, 0, x_1, y_1);
00222 }
00223 void Uninit() {
00224 if (zbuf) {MemFree((PTR)zbuf);zbuf = (int16*)NULL;}
00225 }
00226 ~G3ZBuffer() { Uninit(); }
00227 void Reset() {
00228 if (!img) return;
00229 memset24(img, 0, xy);
00230 memset32(zbuf, 0x7fff7fff, xy / 2);
00231 }
00232 };
00233
00234 class G3Scene : virtual public SystemCode {
00235 _PROTECTED_:
00236 void rotate_lights();
00237 void rotate_objects();
00238 public:
00239 List<G3Object*> ol;
00240 List<G3Light*> ll;
00241 void AddObject(G3Object *o) {
00242 ol.Seek(0, SEEK_END);
00243 ol.Seek(1, SEEK_CUR);
00244 ol.Insert(o);
00245 }
00246 BOOL DelObject(G3Object *o) {
00247 int offset = ol.Find(o);
00248 if (offset == -1) return FALSE;
00249 ol.Seek(offset, SEEK_SET);
00250 ol.Delete();
00251 return TRUE;
00252 }
00253 void AddLight(G3Light *o) {
00254 ll.Seek(0, SEEK_END);
00255 ll.Seek(1, SEEK_CUR);
00256 ll.Insert(o);
00257 }
00258 BOOL DelLight(G3Light *o) {
00259 int offset = ll.Find(o);
00260 if (offset == -1) return FALSE;
00261 ll.Seek(offset, SEEK_SET);
00262 ll.Delete();
00263 return TRUE;
00264 }
00265 void Draw(G3Buffer *_buf);
00266 void DrawZ(G3ZBuffer *_zbuf);
00267 BOOL Load3DS(char *fn);
00268 BOOL Load3DS(char *fn, uint32 clr);
00269 };
00270
00271 class G3Object : virtual public SystemCode {
00272
00273 friend class G3Scene;
00274 _PROTECTED_:
00275 static PTR edgeptr;
00276 uint32 nov;
00277 Point3D *vl;
00278 Point3D *tvl;
00279 uint32 noe;
00280 uint32 elsiz;
00281 uint32 telsiz;
00282 PTR el;
00283 PTR tel;
00284 int32 prexadd;
00285 int32 preyadd;
00286 int32 prezadd;
00287 void rotate_vertices(int, int);
00288 void rotate_elements();
00289 void _Draw(G3Buffer *_buf, List<G3Light*> *ll);
00290 void _DrawZ(G3ZBuffer *_zbuf, List<G3Light*> *ll);
00291 void fillpoly(G3_trix *o, List<G3Light*> *ll, G3Buffer *_buf);
00292 void fillpoly(G3_trix *o, List<G3Light*> *ll, G3ZBuffer *_zbuf);
00293 void calc_normal(G3_def *,int32 &,int32 &,int32 &);
00294 uint32 xang;
00295 uint32 yang;
00296 uint32 zang;
00297 public:
00298 uint32 flgs;
00299 int32 axang;
00300 int32 ayang;
00301 int32 azang;
00302 static BOOL use9;
00303 static BOOL sides;
00304 G3Object() {
00305
00306 flgs = 1;
00307 prexadd = preyadd = prezadd = 0;
00308 xang = yang = zang = 0;
00309 nov = 0;noe = 0;elsiz = 0;telsiz = 0;
00310 vl = (Point3D*)NULL;
00311 tvl = (Point3D*)NULL;
00312 el = NULL;
00313 tel = NULL;
00314 axang = ayang = azang = 0;
00315 }
00316 ~G3Object() {
00317 if (vl) MemFree((PTR)vl);
00318 if (tvl) MemFree((PTR)tvl);
00319 if (el) MemFree((PTR)el);
00320 if (tel) MemFree((PTR)tel);
00321 }
00322 int AddVertex(int, int, int, BOOL normal = FALSE);
00323 void AddElement(int typ, int clr, int p1, int p2 = 0, int p3 = 0);
00324 void SetAngles(int x, int y, int z) {
00325 xang = x; yang = y; zang = z;
00326 xang &= G3_MAX_ANGLE;
00327 yang &= G3_MAX_ANGLE;
00328 zang &= G3_MAX_ANGLE;
00329 }
00330 void AddAngles(int x, int y, int z) {
00331 xang += x; yang += y; zang += z;
00332 xang &= G3_MAX_ANGLE;
00333 yang &= G3_MAX_ANGLE;
00334 zang &= G3_MAX_ANGLE;
00335 }
00336 void GetAngles(uint32 *x, uint32 *y, uint32 *z) { if (x) *x = xang; if (y) *y = yang; if (z) *z = zang; }
00337 void SetPos(int x, int y, int z) { prexadd = x; preyadd = y; prezadd = z; }
00338 void AddPos(int x, int y, int z) { prexadd += x; preyadd += y; prezadd += z; }
00339 void GetPos(int *x, int *y, int *z) { if (x) *x = prexadd; if (y) *x = preyadd; if (z) *z = prezadd; }
00340 void UpdateNormals(int idx = -1);
00341 void MoveVertex(int, int, int, int, BOOL = TRUE);
00342 void Show() {flgs |= 0x0001;}
00343 void Hide() {flgs &= 0xfffe;}
00344 };
00345