summaryrefslogtreecommitdiffhomepage
path: root/Magic2
diff options
context:
space:
mode:
authormilo24x7@gmail.com <milo24x7@gmail.com@076cb2c4-205e-83fd-5cf3-1be9aa105544>2013-07-07 21:51:48 +0000
committermilo24x7@gmail.com <milo24x7@gmail.com@076cb2c4-205e-83fd-5cf3-1be9aa105544>2013-07-07 21:51:48 +0000
commit1de4b2bdbb019be6f1b7262c3eba5568d7682edd (patch)
tree3f8a1fc086daa93b24929886e1bf15b918ea9b94 /Magic2
parent073ef05b192338247ea304f2a72615633947b446 (diff)
downloadstarshatter-1de4b2bdbb019be6f1b7262c3eba5568d7682edd.zip
starshatter-1de4b2bdbb019be6f1b7262c3eba5568d7682edd.tar.gz
starshatter-1de4b2bdbb019be6f1b7262c3eba5568d7682edd.tar.bz2
Updated open source license declaration and fixed some formatting issues.
Diffstat (limited to 'Magic2')
-rw-r--r--Magic2/AlphaInverse.cpp8233
-rw-r--r--Magic2/AlphaPalette.cpp553
-rw-r--r--Magic2/Command.cpp128
-rw-r--r--Magic2/Command.h134
-rw-r--r--Magic2/ContentBundle.cpp298
-rw-r--r--Magic2/ContentBundle.h120
-rw-r--r--Magic2/Editor.cpp848
-rw-r--r--Magic2/Editor.h192
-rw-r--r--Magic2/Grid.cpp716
-rw-r--r--Magic2/Grid.h186
-rw-r--r--Magic2/GridProps.cpp276
-rw-r--r--Magic2/GridProps.h162
-rw-r--r--Magic2/Locale_ss.cpp498
-rw-r--r--Magic2/Locale_ss.h130
-rw-r--r--Magic2/M3DS.cpp550
-rw-r--r--Magic2/M3DS.h680
-rw-r--r--Magic2/Magic.cpp428
-rw-r--r--Magic2/Magic.h150
-rw-r--r--Magic2/MagicDoc.cpp1254
-rw-r--r--Magic2/MagicDoc.h264
-rw-r--r--Magic2/MagicView.cpp2898
-rw-r--r--Magic2/MagicView.h426
-rw-r--r--Magic2/MainFrm.cpp330
-rw-r--r--Magic2/MainFrm.h149
-rw-r--r--Magic2/MaterialDialog.cpp1410
-rw-r--r--Magic2/MaterialDialog.h258
-rw-r--r--Magic2/ModelFile3DS.cpp590
-rw-r--r--Magic2/ModelFile3DS.h98
-rw-r--r--Magic2/ModelFileMAG.cpp1674
-rw-r--r--Magic2/ModelFileMAG.h102
-rw-r--r--Magic2/ModelFileOBJ.cpp1604
-rw-r--r--Magic2/ModelFileOBJ.h98
-rw-r--r--Magic2/ModelView.cpp858
-rw-r--r--Magic2/ModelView.h152
-rw-r--r--Magic2/Primitives.cpp128
-rw-r--r--Magic2/Primitives.h134
-rw-r--r--Magic2/Selection.cpp406
-rw-r--r--Magic2/Selection.h172
-rw-r--r--Magic2/Selector.cpp804
-rw-r--r--Magic2/Selector.h176
-rw-r--r--Magic2/StdAfx.cpp16
-rw-r--r--Magic2/StdAfx.h92
-rw-r--r--Magic2/SurfacePropertiesDialog.cpp212
-rw-r--r--Magic2/SurfacePropertiesDialog.h170
-rw-r--r--Magic2/TexCubeDX9.cpp264
-rw-r--r--Magic2/TexCubeDX9.h122
-rw-r--r--Magic2/TextureMapDialog.cpp394
-rw-r--r--Magic2/TextureMapDialog.h194
-rw-r--r--Magic2/Thumbnail.cpp138
-rw-r--r--Magic2/Thumbnail.h86
-rw-r--r--Magic2/UVMapView.cpp924
-rw-r--r--Magic2/UVMapView.h188
-rw-r--r--Magic2/VideoDX9.cpp7258
-rw-r--r--Magic2/VideoDX9.h414
-rw-r--r--Magic2/l3ds.cpp3584
-rw-r--r--Magic2/l3ds.h912
-rw-r--r--Magic2/resource.h466
57 files changed, 22486 insertions, 21215 deletions
diff --git a/Magic2/AlphaInverse.cpp b/Magic2/AlphaInverse.cpp
index 464bfda..03ea403 100644
--- a/Magic2/AlphaInverse.cpp
+++ b/Magic2/AlphaInverse.cpp
@@ -1,4100 +1,4133 @@
-#include "stdafx.h"
-
-BYTE inverse_palette[32768] = {
- 0, 47, 63, 63, 62, 62, 61, 61,
- 61, 60, 60, 59, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4,
- 252, 252, 252, 252, 252, 252, 252, 252,
- 47, 47, 63, 63, 62, 62, 61, 61,
- 61, 60, 60, 59, 59, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4,
- 55, 252, 252, 252, 252, 252, 252, 252,
- 47, 46, 63, 63, 62, 62, 61, 61,
- 60, 60, 60, 59, 59, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 55,
- 55, 252, 252, 252, 252, 252, 252, 252,
- 46, 46, 46, 62, 62, 62, 61, 61,
- 60, 60, 59, 59, 59, 58, 4, 4,
- 4, 4, 4, 4, 4, 4, 55, 55,
- 55, 54, 252, 252, 252, 252, 252, 252,
- 46, 46, 45, 111, 111, 79, 79, 61,
- 60, 60, 59, 59, 59, 58, 58, 57,
- 4, 4, 4, 4, 56, 55, 55, 55,
- 54, 54, 54, 252, 252, 252, 252, 252,
- 111, 111, 111, 111, 111, 111, 79, 79,
- 60, 60, 59, 59, 58, 58, 58, 57,
- 57, 56, 56, 56, 56, 55, 55, 55,
- 54, 54, 54, 252, 252, 252, 252, 252,
- 111, 111, 111, 111, 111, 111, 111, 78,
- 78, 78, 59, 59, 58, 58, 57, 57,
- 57, 56, 56, 56, 55, 55, 55, 55,
- 54, 54, 54, 54, 252, 252, 252, 252,
- 111, 111, 111, 111, 111, 111, 110, 78,
- 78, 77, 77, 77, 58, 58, 57, 57,
- 57, 56, 56, 56, 55, 55, 55, 55,
- 54, 54, 54, 54, 54, 252, 252, 252,
- 111, 111, 111, 111, 110, 110, 110, 110,
- 78, 77, 213, 213, 213, 213, 213, 213,
- 56, 56, 56, 56, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 252, 252, 252,
- 111, 110, 110, 110, 110, 110, 110, 109,
- 109, 213, 213, 213, 213, 213, 213, 213,
- 213, 213, 56, 56, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 54, 252, 252,
- 110, 110, 110, 110, 110, 109, 109, 109,
- 109, 213, 213, 213, 213, 213, 213, 213,
- 213, 213, 212, 6, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 54, 53, 252,
- 2, 110, 110, 110, 109, 109, 109, 109,
- 213, 213, 213, 213, 213, 213, 213, 213,
- 213, 212, 6, 6, 6, 6, 6, 54,
- 54, 54, 54, 54, 54, 53, 53, 53,
- 2, 2, 2, 109, 109, 109, 109, 108,
- 213, 213, 213, 213, 213, 213, 213, 213,
- 212, 6, 6, 6, 6, 6, 6, 6,
- 54, 54, 54, 54, 53, 53, 53, 53,
- 2, 2, 2, 2, 108, 108, 108, 108,
- 213, 213, 213, 213, 213, 213, 213, 212,
- 6, 6, 6, 6, 6, 6, 6, 211,
- 211, 211, 70, 53, 53, 53, 53, 53,
- 2, 2, 2, 2, 2, 108, 108, 108,
- 213, 213, 213, 213, 213, 213, 212, 6,
- 6, 6, 6, 6, 6, 6, 211, 211,
- 211, 211, 211, 70, 70, 70, 53, 53,
- 2, 2, 2, 2, 2, 2, 107, 107,
- 107, 213, 213, 213, 213, 212, 6, 6,
- 6, 6, 6, 6, 6, 211, 211, 211,
- 211, 211, 211, 210, 210, 70, 70, 70,
- 2, 2, 2, 2, 2, 2, 107, 107,
- 107, 213, 213, 213, 212, 6, 6, 6,
- 6, 6, 6, 6, 211, 211, 211, 211,
- 211, 211, 210, 210, 210, 210, 210, 210,
- 2, 2, 2, 2, 2, 2, 107, 107,
- 106, 106, 213, 212, 6, 6, 6, 6,
- 6, 6, 6, 211, 211, 211, 211, 211,
- 211, 210, 210, 210, 210, 210, 210, 209,
- 2, 2, 2, 2, 2, 2, 106, 106,
- 106, 106, 106, 6, 6, 6, 6, 6,
- 6, 6, 211, 211, 211, 211, 211, 211,
- 210, 210, 210, 210, 210, 210, 209, 209,
- 2, 2, 2, 2, 2, 2, 105, 105,
- 105, 105, 105, 6, 6, 6, 6, 6,
- 6, 211, 211, 211, 211, 211, 211, 210,
- 210, 210, 210, 210, 210, 209, 209, 209,
- 2, 2, 2, 2, 2, 2, 105, 105,
- 105, 105, 105, 6, 6, 6, 6, 6,
- 211, 211, 211, 211, 211, 211, 210, 210,
- 210, 210, 210, 210, 209, 209, 209, 209,
- 2, 2, 2, 2, 2, 2, 105, 105,
- 104, 104, 104, 6, 6, 6, 6, 211,
- 211, 211, 211, 211, 211, 210, 210, 210,
- 210, 210, 210, 209, 209, 209, 209, 209,
- 2, 2, 2, 2, 2, 104, 104, 104,
- 104, 104, 104, 103, 6, 6, 211, 211,
- 211, 211, 211, 211, 210, 210, 210, 210,
- 210, 210, 209, 209, 209, 209, 209, 209,
- 2, 2, 2, 2, 2, 104, 104, 104,
- 104, 104, 103, 103, 103, 211, 211, 211,
- 211, 211, 211, 210, 210, 210, 210, 210,
- 210, 209, 209, 209, 209, 209, 209, 209,
- 250, 250, 250, 250, 250, 104, 104, 104,
- 103, 103, 103, 103, 103, 211, 211, 211,
- 211, 211, 210, 210, 210, 210, 210, 210,
- 209, 209, 209, 209, 209, 209, 209, 208,
- 250, 250, 250, 250, 250, 250, 102, 102,
- 103, 103, 103, 103, 103, 103, 211, 211,
- 211, 210, 210, 210, 210, 210, 210, 209,
- 209, 209, 209, 209, 209, 209, 208, 208,
- 250, 250, 250, 250, 250, 250, 250, 102,
- 102, 102, 103, 103, 103, 103, 211, 211,
- 210, 210, 210, 210, 210, 210, 209, 209,
- 209, 209, 209, 209, 209, 208, 208, 208,
- 250, 250, 250, 250, 250, 250, 250, 250,
- 102, 102, 102, 103, 103, 103, 211, 210,
- 210, 210, 210, 210, 210, 209, 209, 209,
- 209, 209, 209, 209, 208, 208, 208, 254,
- 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 102, 102, 102, 103, 103, 103, 210,
- 210, 210, 210, 210, 209, 209, 209, 209,
- 209, 209, 209, 208, 208, 208, 254, 254,
- 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 102, 102, 102, 103, 103, 210,
- 210, 210, 210, 209, 209, 209, 209, 209,
- 209, 209, 208, 208, 208, 254, 254, 254,
- 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 250, 102, 102, 102, 102, 210,
- 210, 210, 209, 209, 209, 209, 209, 209,
- 209, 208, 208, 208, 254, 254, 254, 254,
- 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 250, 250, 102, 102, 102, 210,
- 210, 209, 209, 209, 209, 209, 209, 209,
- 208, 208, 208, 254, 254, 254, 254, 254,
- 47, 47, 63, 63, 62, 62, 61, 61,
- 61, 60, 60, 59, 59, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4,
- 55, 252, 252, 252, 252, 252, 252, 252,
- 47, 46, 63, 63, 62, 62, 61, 61,
- 60, 60, 60, 59, 59, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 55,
- 55, 252, 252, 252, 252, 252, 252, 252,
- 46, 46, 46, 62, 62, 62, 61, 61,
- 60, 60, 59, 59, 59, 58, 4, 4,
- 4, 4, 4, 4, 4, 4, 55, 55,
- 55, 54, 252, 252, 252, 252, 252, 252,
- 46, 46, 45, 45, 62, 79, 61, 61,
- 60, 60, 59, 59, 59, 58, 58, 57,
- 4, 4, 4, 4, 56, 55, 55, 55,
- 54, 54, 54, 252, 252, 252, 252, 252,
- 46, 45, 45, 45, 79, 79, 79, 79,
- 60, 60, 59, 59, 58, 58, 58, 57,
- 57, 56, 56, 56, 56, 55, 55, 55,
- 54, 54, 54, 252, 252, 252, 252, 252,
- 111, 111, 111, 111, 111, 79, 79, 79,
- 78, 60, 59, 59, 58, 58, 57, 57,
- 57, 56, 56, 56, 55, 55, 55, 55,
- 54, 54, 54, 54, 252, 252, 252, 252,
- 111, 111, 111, 111, 111, 111, 79, 78,
- 78, 78, 77, 59, 58, 58, 57, 57,
- 57, 56, 56, 56, 55, 55, 55, 55,
- 54, 54, 54, 54, 54, 252, 252, 252,
- 111, 111, 111, 111, 111, 110, 110, 78,
- 78, 77, 77, 77, 58, 58, 57, 57,
- 56, 56, 56, 56, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 252, 252, 252,
- 111, 111, 111, 110, 110, 110, 110, 110,
- 77, 77, 77, 213, 213, 213, 213, 213,
- 56, 56, 56, 56, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 54, 252, 252,
- 110, 110, 110, 110, 110, 110, 109, 109,
- 109, 213, 213, 213, 213, 213, 213, 213,
- 213, 56, 56, 55, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 54, 53, 252,
- 110, 110, 110, 110, 110, 109, 109, 109,
- 109, 213, 213, 213, 213, 213, 213, 213,
- 213, 213, 212, 73, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 53, 53, 53,
- 2, 110, 110, 109, 109, 109, 109, 109,
- 108, 213, 213, 213, 213, 213, 213, 213,
- 213, 212, 212, 212, 6, 55, 55, 54,
- 54, 54, 54, 54, 53, 53, 53, 53,
- 2, 2, 2, 109, 109, 109, 108, 108,
- 108, 213, 213, 213, 213, 213, 213, 213,
- 212, 212, 212, 6, 6, 6, 6, 54,
- 54, 54, 54, 53, 53, 53, 53, 53,
- 2, 2, 2, 2, 108, 108, 108, 108,
- 108, 213, 213, 213, 213, 213, 213, 212,
- 212, 212, 6, 6, 6, 6, 211, 211,
- 211, 70, 70, 53, 53, 53, 53, 53,
- 2, 2, 2, 2, 108, 108, 108, 107,
- 107, 213, 213, 213, 213, 213, 212, 212,
- 212, 6, 6, 6, 6, 211, 211, 211,
- 211, 211, 70, 70, 70, 70, 53, 53,
- 2, 2, 2, 2, 2, 107, 107, 107,
- 107, 107, 213, 213, 213, 212, 212, 212,
- 6, 6, 6, 6, 211, 211, 211, 211,
- 211, 211, 70, 70, 70, 70, 70, 70,
- 2, 2, 2, 2, 2, 107, 107, 107,
- 107, 106, 213, 213, 212, 212, 212, 6,
- 6, 6, 6, 211, 211, 211, 211, 211,
- 211, 211, 210, 210, 210, 210, 70, 70,
- 2, 2, 2, 2, 2, 107, 107, 106,
- 106, 106, 106, 212, 212, 212, 6, 6,
- 6, 6, 211, 211, 211, 211, 211, 211,
- 211, 210, 210, 210, 210, 210, 210, 209,
- 2, 2, 2, 2, 2, 2, 106, 106,
- 106, 106, 106, 212, 212, 6, 6, 6,
- 6, 211, 211, 211, 211, 211, 211, 211,
- 210, 210, 210, 210, 210, 210, 209, 209,
- 2, 2, 2, 2, 2, 105, 105, 105,
- 105, 105, 105, 212, 6, 6, 6, 6,
- 211, 211, 211, 211, 211, 211, 211, 210,
- 210, 210, 210, 210, 210, 209, 209, 209,
- 2, 2, 2, 2, 2, 105, 105, 105,
- 105, 105, 105, 104, 6, 6, 6, 211,
- 211, 211, 211, 211, 211, 211, 210, 210,
- 210, 210, 210, 210, 209, 209, 209, 209,
- 2, 2, 2, 2, 2, 105, 105, 104,
- 104, 104, 104, 104, 6, 6, 211, 211,
- 211, 211, 211, 211, 211, 210, 210, 210,
- 210, 210, 210, 209, 209, 209, 209, 209,
- 2, 2, 2, 2, 2, 104, 104, 104,
- 104, 104, 104, 103, 103, 211, 211, 211,
- 211, 211, 211, 211, 210, 210, 210, 210,
- 210, 210, 209, 209, 209, 209, 209, 209,
- 2, 2, 2, 2, 104, 104, 104, 104,
- 104, 103, 103, 103, 103, 103, 211, 211,
- 211, 211, 211, 210, 210, 210, 210, 210,
- 210, 209, 209, 209, 209, 209, 209, 208,
- 250, 250, 250, 250, 102, 102, 102, 102,
- 103, 103, 103, 103, 103, 103, 211, 211,
- 211, 211, 210, 210, 210, 210, 210, 210,
- 209, 209, 209, 209, 209, 209, 208, 208,
- 250, 250, 250, 250, 250, 102, 102, 102,
- 102, 103, 103, 103, 103, 103, 211, 211,
- 211, 210, 210, 210, 210, 210, 210, 209,
- 209, 209, 209, 209, 209, 208, 208, 208,
- 250, 250, 250, 250, 250, 250, 102, 102,
- 102, 102, 103, 103, 103, 103, 103, 211,
- 210, 210, 210, 210, 210, 210, 209, 209,
- 209, 209, 209, 209, 208, 208, 208, 208,
- 250, 250, 250, 250, 250, 250, 250, 102,
- 102, 102, 102, 103, 103, 103, 103, 210,
- 210, 210, 210, 210, 210, 209, 209, 209,
- 209, 209, 209, 208, 208, 208, 208, 208,
- 250, 250, 250, 250, 250, 250, 250, 250,
- 102, 102, 102, 102, 102, 103, 103, 210,
- 210, 210, 210, 210, 209, 209, 209, 209,
- 209, 209, 208, 208, 208, 208, 208, 254,
- 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 102, 102, 102, 102, 102, 103, 210,
- 210, 210, 210, 209, 209, 209, 209, 209,
- 209, 208, 208, 208, 208, 208, 254, 254,
- 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 102, 102, 102, 102, 102, 210,
- 210, 210, 209, 209, 209, 209, 209, 209,
- 208, 208, 208, 208, 208, 254, 254, 254,
- 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 250, 102, 102, 102, 102, 210,
- 210, 209, 209, 209, 209, 209, 209, 208,
- 208, 208, 208, 208, 254, 254, 254, 254,
- 47, 46, 63, 63, 62, 62, 61, 61,
- 60, 60, 60, 59, 59, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 55,
- 55, 252, 252, 252, 252, 252, 252, 252,
- 46, 46, 46, 62, 62, 62, 61, 61,
- 60, 60, 59, 59, 59, 58, 4, 4,
- 4, 4, 4, 4, 4, 4, 55, 55,
- 55, 54, 252, 252, 252, 252, 252, 252,
- 46, 46, 45, 45, 62, 62, 61, 61,
- 60, 60, 59, 59, 59, 58, 58, 57,
- 4, 4, 4, 4, 56, 55, 55, 55,
- 54, 54, 54, 252, 252, 252, 252, 252,
- 46, 45, 45, 45, 45, 79, 79, 61,
- 60, 60, 59, 59, 58, 58, 58, 57,
- 57, 56, 56, 56, 56, 55, 55, 55,
- 54, 54, 54, 252, 252, 252, 252, 252,
- 45, 45, 45, 45, 79, 79, 79, 79,
- 60, 60, 59, 59, 58, 58, 57, 57,
- 57, 56, 56, 56, 55, 55, 55, 55,
- 54, 54, 54, 54, 252, 252, 252, 252,
- 111, 111, 111, 111, 111, 79, 79, 78,
- 78, 78, 59, 59, 58, 58, 57, 57,
- 57, 56, 56, 56, 55, 55, 55, 55,
- 54, 54, 54, 54, 54, 252, 252, 252,
- 111, 111, 111, 111, 111, 111, 78, 78,
- 78, 77, 77, 77, 58, 58, 57, 57,
- 56, 56, 56, 56, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 252, 252, 252,
- 111, 111, 111, 111, 111, 110, 110, 78,
- 78, 77, 77, 77, 76, 58, 57, 57,
- 56, 56, 56, 56, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 54, 252, 252,
- 111, 111, 110, 110, 110, 110, 110, 109,
- 77, 77, 77, 76, 76, 213, 75, 57,
- 56, 56, 56, 55, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 54, 53, 252,
- 110, 110, 110, 110, 110, 110, 109, 109,
- 109, 77, 213, 213, 213, 213, 213, 213,
- 75, 56, 56, 55, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 53, 53, 53,
- 110, 110, 110, 110, 109, 109, 109, 109,
- 109, 213, 213, 213, 213, 213, 213, 213,
- 213, 74, 73, 73, 55, 55, 55, 54,
- 54, 54, 54, 54, 53, 53, 53, 53,
- 110, 110, 110, 109, 109, 109, 109, 109,
- 108, 213, 213, 213, 213, 213, 213, 213,
- 212, 212, 212, 73, 73, 73, 54, 54,
- 54, 54, 54, 53, 53, 53, 53, 53,
- 2, 2, 109, 109, 109, 108, 108, 108,
- 108, 213, 213, 213, 213, 213, 213, 212,
- 212, 212, 212, 212, 73, 72, 72, 54,
- 54, 54, 53, 53, 53, 53, 53, 53,
- 2, 2, 2, 108, 108, 108, 108, 108,
- 108, 213, 213, 213, 213, 213, 212, 212,
- 212, 212, 212, 212, 212, 72, 72, 71,
- 70, 70, 70, 53, 53, 53, 53, 53,
- 2, 2, 2, 2, 108, 108, 107, 107,
- 107, 107, 213, 213, 213, 212, 212, 212,
- 212, 212, 212, 212, 6, 211, 211, 211,
- 70, 70, 70, 70, 70, 70, 53, 53,
- 2, 2, 2, 2, 107, 107, 107, 107,
- 107, 107, 213, 213, 212, 212, 212, 212,
- 212, 212, 212, 6, 211, 211, 211, 211,
- 211, 70, 70, 70, 70, 70, 70, 70,
- 2, 2, 2, 2, 107, 107, 107, 107,
- 106, 106, 106, 212, 212, 212, 212, 212,
- 212, 212, 6, 211, 211, 211, 211, 211,
- 211, 210, 70, 70, 70, 70, 70, 70,
- 2, 2, 2, 2, 2, 107, 106, 106,
- 106, 106, 106, 212, 212, 212, 212, 212,
- 212, 6, 211, 211, 211, 211, 211, 211,
- 210, 210, 210, 210, 210, 210, 70, 70,
- 2, 2, 2, 2, 2, 105, 106, 106,
- 106, 106, 106, 106, 212, 212, 212, 212,
- 6, 211, 211, 211, 211, 211, 211, 210,
- 210, 210, 210, 210, 210, 210, 209, 209,
- 2, 2, 2, 2, 2, 105, 105, 105,
- 105, 105, 105, 105, 212, 212, 212, 6,
- 211, 211, 211, 211, 211, 211, 210, 210,
- 210, 210, 210, 210, 210, 209, 209, 209,
- 2, 2, 2, 2, 105, 105, 105, 105,
- 105, 105, 104, 104, 212, 212, 6, 211,
- 211, 211, 211, 211, 211, 210, 210, 210,
- 210, 210, 210, 210, 209, 209, 209, 209,
- 2, 2, 2, 2, 105, 105, 104, 104,
- 104, 104, 104, 104, 103, 6, 211, 211,
- 211, 211, 211, 211, 210, 210, 210, 210,
- 210, 210, 210, 209, 209, 209, 209, 209,
- 2, 2, 2, 2, 104, 104, 104, 104,
- 104, 104, 103, 103, 103, 103, 211, 211,
- 211, 211, 211, 210, 210, 210, 210, 210,
- 210, 210, 209, 209, 209, 209, 209, 209,
- 2, 2, 2, 104, 104, 104, 104, 104,
- 104, 103, 103, 103, 103, 103, 211, 211,
- 211, 211, 210, 210, 210, 210, 210, 210,
- 210, 209, 209, 209, 209, 209, 209, 208,
- 250, 250, 250, 102, 102, 102, 102, 102,
- 103, 103, 103, 103, 103, 103, 211, 211,
- 211, 210, 210, 210, 210, 210, 210, 210,
- 209, 209, 209, 209, 209, 209, 208, 208,
- 250, 250, 250, 250, 102, 102, 102, 102,
- 102, 103, 103, 103, 103, 103, 103, 211,
- 210, 210, 210, 210, 210, 210, 210, 209,
- 209, 209, 209, 209, 209, 208, 208, 208,
- 250, 250, 250, 250, 250, 102, 102, 102,
- 102, 102, 102, 103, 103, 103, 103, 210,
- 210, 210, 210, 210, 210, 210, 209, 209,
- 209, 209, 209, 209, 208, 208, 208, 208,
- 250, 250, 250, 250, 250, 250, 102, 102,
- 102, 102, 102, 102, 103, 103, 103, 210,
- 210, 210, 210, 210, 210, 209, 209, 209,
- 209, 209, 209, 208, 208, 208, 208, 208,
- 250, 250, 250, 250, 250, 250, 250, 102,
- 102, 102, 102, 102, 102, 103, 103, 210,
- 210, 210, 210, 210, 209, 209, 209, 209,
- 209, 209, 208, 208, 208, 208, 208, 208,
- 250, 250, 250, 250, 250, 250, 250, 250,
- 102, 102, 102, 102, 102, 102, 103, 210,
- 210, 210, 210, 209, 209, 209, 209, 209,
- 209, 208, 208, 208, 208, 208, 208, 254,
- 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 102, 102, 102, 102, 102, 101, 210,
- 210, 210, 209, 209, 209, 209, 209, 209,
- 208, 208, 208, 208, 208, 208, 254, 254,
- 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 102, 102, 102, 102, 101, 101,
- 210, 209, 209, 209, 209, 209, 209, 208,
- 208, 208, 208, 208, 208, 254, 254, 254,
- 247, 46, 46, 62, 62, 62, 61, 61,
- 60, 60, 59, 59, 59, 58, 4, 4,
- 4, 4, 4, 4, 4, 4, 55, 55,
- 55, 54, 252, 252, 252, 252, 252, 252,
- 46, 46, 45, 45, 62, 62, 61, 61,
- 60, 60, 59, 59, 59, 58, 58, 57,
- 4, 4, 4, 4, 56, 55, 55, 55,
- 54, 54, 54, 252, 252, 252, 252, 252,
- 46, 45, 45, 45, 45, 61, 61, 61,
- 60, 60, 59, 59, 58, 58, 58, 57,
- 57, 56, 56, 56, 56, 55, 55, 55,
- 54, 54, 54, 252, 252, 252, 252, 252,
- 45, 45, 45, 45, 95, 79, 79, 60,
- 60, 60, 59, 59, 58, 58, 57, 57,
- 57, 56, 56, 56, 55, 55, 55, 55,
- 54, 54, 54, 54, 252, 252, 252, 252,
- 45, 45, 45, 127, 95, 79, 79, 78,
- 78, 59, 59, 59, 58, 58, 57, 57,
- 57, 56, 56, 56, 55, 55, 55, 55,
- 54, 54, 54, 54, 54, 252, 252, 252,
- 45, 127, 127, 127, 127, 79, 78, 78,
- 78, 78, 59, 59, 58, 58, 57, 57,
- 56, 56, 56, 56, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 252, 252, 252,
- 111, 111, 111, 111, 111, 111, 78, 78,
- 78, 77, 77, 77, 58, 58, 57, 57,
- 56, 56, 56, 56, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 54, 252, 252,
- 111, 111, 111, 111, 110, 110, 78, 78,
- 77, 77, 77, 77, 76, 76, 57, 57,
- 56, 56, 56, 55, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 54, 53, 252,
- 111, 110, 110, 110, 110, 110, 110, 109,
- 77, 77, 77, 76, 76, 75, 75, 75,
- 56, 56, 56, 55, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 53, 53, 53,
- 110, 110, 110, 110, 110, 109, 109, 109,
- 109, 77, 76, 76, 76, 75, 75, 75,
- 74, 74, 56, 55, 55, 55, 55, 54,
- 54, 54, 54, 54, 53, 53, 53, 53,
- 110, 110, 110, 110, 109, 109, 109, 109,
- 109, 76, 213, 213, 213, 213, 213, 74,
- 74, 73, 73, 73, 55, 55, 54, 54,
- 54, 54, 54, 53, 53, 53, 53, 53,
- 110, 110, 109, 109, 109, 109, 109, 108,
- 108, 108, 213, 213, 213, 213, 213, 213,
- 74, 73, 73, 73, 73, 73, 54, 54,
- 54, 54, 53, 53, 53, 53, 53, 53,
- 2, 109, 109, 109, 109, 108, 108, 108,
- 108, 108, 213, 213, 213, 213, 213, 212,
- 212, 212, 73, 73, 73, 72, 72, 72,
- 54, 53, 53, 53, 53, 53, 53, 53,
- 2, 2, 108, 108, 108, 108, 108, 108,
- 107, 107, 213, 213, 213, 213, 212, 212,
- 212, 212, 212, 73, 72, 72, 72, 71,
- 70, 70, 70, 53, 53, 53, 53, 53,
- 2, 2, 2, 108, 108, 108, 107, 107,
- 107, 107, 213, 213, 213, 212, 212, 212,
- 212, 212, 212, 212, 211, 72, 71, 70,
- 70, 70, 70, 70, 70, 70, 53, 53,
- 2, 2, 2, 2, 107, 107, 107, 107,
- 107, 106, 106, 213, 212, 212, 212, 212,
- 212, 212, 212, 211, 211, 211, 211, 211,
- 70, 70, 70, 70, 70, 70, 70, 70,
- 2, 2, 2, 2, 107, 107, 107, 106,
- 106, 106, 106, 106, 212, 212, 212, 212,
- 212, 212, 211, 211, 211, 211, 211, 211,
- 70, 70, 70, 70, 70, 70, 70, 70,
- 2, 2, 2, 2, 107, 106, 106, 106,
- 106, 106, 106, 106, 212, 212, 212, 212,
- 212, 211, 211, 211, 211, 211, 211, 211,
- 210, 210, 70, 70, 70, 70, 70, 70,
- 2, 2, 2, 2, 105, 105, 105, 105,
- 105, 105, 105, 106, 212, 212, 212, 212,
- 211, 211, 211, 211, 211, 211, 211, 210,
- 210, 210, 210, 210, 210, 210, 209, 209,
- 2, 2, 2, 2, 105, 105, 105, 105,
- 105, 105, 105, 105, 212, 212, 212, 211,
- 211, 211, 211, 211, 211, 211, 210, 210,
- 210, 210, 210, 210, 210, 209, 209, 209,
- 2, 2, 2, 2, 105, 105, 105, 105,
- 104, 104, 104, 104, 104, 212, 211, 211,
- 211, 211, 211, 211, 211, 210, 210, 210,
- 210, 210, 210, 210, 209, 209, 209, 209,
- 2, 2, 2, 105, 104, 104, 104, 104,
- 104, 104, 104, 103, 103, 103, 211, 211,
- 211, 211, 211, 211, 210, 210, 210, 210,
- 210, 210, 210, 209, 209, 209, 209, 209,
- 2, 2, 2, 104, 104, 104, 104, 104,
- 104, 104, 103, 103, 103, 103, 211, 211,
- 211, 211, 211, 210, 210, 210, 210, 210,
- 210, 210, 209, 209, 209, 209, 209, 209,
- 2, 2, 102, 102, 102, 104, 104, 104,
- 103, 103, 103, 103, 103, 103, 103, 211,
- 211, 211, 210, 210, 210, 210, 210, 210,
- 210, 209, 209, 209, 209, 209, 209, 208,
- 250, 250, 102, 102, 102, 102, 102, 102,
- 102, 103, 103, 103, 103, 103, 103, 211,
- 211, 210, 210, 210, 210, 210, 210, 210,
- 209, 209, 209, 209, 209, 209, 208, 208,
- 250, 250, 250, 102, 102, 102, 102, 102,
- 102, 102, 103, 103, 103, 103, 103, 211,
- 210, 210, 210, 210, 210, 210, 210, 209,
- 209, 209, 209, 209, 209, 208, 208, 208,
- 250, 250, 250, 250, 102, 102, 102, 102,
- 102, 102, 102, 103, 103, 103, 103, 103,
- 210, 210, 210, 210, 210, 210, 209, 209,
- 209, 209, 209, 209, 208, 208, 208, 208,
- 250, 250, 250, 250, 250, 102, 102, 102,
- 102, 102, 102, 102, 103, 103, 103, 103,
- 210, 210, 210, 210, 210, 209, 209, 209,
- 209, 209, 209, 208, 208, 208, 208, 208,
- 250, 250, 250, 250, 250, 250, 102, 102,
- 102, 102, 102, 102, 102, 103, 103, 103,
- 210, 210, 210, 210, 209, 209, 209, 209,
- 209, 209, 208, 208, 208, 208, 208, 208,
- 250, 250, 250, 250, 250, 250, 250, 102,
- 102, 102, 102, 102, 102, 102, 101, 101,
- 210, 210, 210, 209, 209, 209, 209, 209,
- 209, 208, 208, 208, 208, 208, 208, 208,
- 250, 250, 250, 250, 250, 250, 250, 250,
- 102, 102, 102, 102, 102, 101, 101, 101,
- 210, 210, 209, 209, 209, 209, 209, 209,
- 208, 208, 208, 208, 208, 208, 208, 254,
- 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 102, 102, 102, 102, 101, 101, 101,
- 210, 209, 209, 209, 209, 209, 209, 208,
- 208, 208, 208, 208, 208, 208, 254, 254,
- 247, 247, 247, 247, 62, 62, 61, 61,
- 60, 60, 59, 59, 59, 58, 58, 57,
- 4, 4, 4, 4, 56, 55, 55, 55,
- 54, 54, 54, 252, 252, 252, 252, 252,
- 247, 247, 247, 45, 45, 61, 61, 61,
- 60, 60, 59, 59, 58, 58, 58, 57,
- 57, 56, 56, 56, 56, 55, 55, 55,
- 54, 54, 54, 252, 252, 252, 252, 252,
- 247, 247, 45, 45, 44, 95, 61, 60,
- 60, 60, 59, 59, 58, 58, 57, 57,
- 57, 56, 56, 56, 55, 55, 55, 55,
- 54, 54, 54, 54, 252, 252, 252, 252,
- 247, 45, 45, 44, 44, 95, 79, 60,
- 60, 59, 59, 59, 58, 58, 57, 57,
- 57, 56, 56, 56, 55, 55, 55, 55,
- 54, 54, 54, 54, 54, 252, 252, 252,
- 45, 143, 143, 127, 44, 95, 79, 78,
- 78, 59, 59, 59, 58, 58, 57, 57,
- 56, 56, 56, 56, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 252, 252, 252,
- 159, 159, 159, 127, 127, 95, 94, 78,
- 78, 77, 77, 58, 58, 58, 57, 57,
- 56, 56, 56, 56, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 54, 252, 252,
- 159, 159, 159, 127, 126, 126, 94, 78,
- 77, 77, 77, 77, 58, 58, 57, 57,
- 56, 56, 56, 55, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 54, 53, 252,
- 111, 111, 111, 110, 126, 126, 94, 78,
- 77, 77, 77, 76, 76, 76, 75, 56,
- 56, 56, 56, 55, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 53, 53, 53,
- 110, 110, 110, 110, 110, 110, 109, 77,
- 77, 77, 76, 76, 76, 75, 75, 75,
- 56, 56, 56, 55, 55, 55, 55, 54,
- 54, 54, 54, 54, 53, 53, 53, 53,
- 110, 110, 110, 110, 110, 109, 109, 109,
- 77, 76, 76, 76, 75, 75, 75, 75,
- 74, 74, 73, 55, 55, 55, 54, 54,
- 54, 54, 54, 53, 53, 53, 53, 53,
- 110, 110, 110, 109, 109, 109, 109, 109,
- 108, 76, 76, 76, 75, 75, 75, 74,
- 74, 73, 73, 73, 73, 55, 54, 54,
- 54, 54, 53, 53, 53, 53, 53, 53,
- 110, 109, 109, 109, 109, 109, 108, 108,
- 108, 108, 213, 213, 213, 75, 74, 74,
- 74, 73, 73, 73, 73, 72, 72, 54,
- 54, 53, 53, 53, 53, 53, 53, 53,
- 2, 109, 109, 109, 108, 108, 108, 108,
- 108, 108, 213, 213, 213, 213, 74, 74,
- 73, 73, 73, 73, 72, 72, 72, 71,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 2, 2, 108, 108, 108, 108, 108, 107,
- 107, 107, 213, 213, 213, 213, 212, 212,
- 212, 73, 73, 73, 72, 72, 72, 71,
- 70, 70, 70, 53, 53, 53, 53, 53,
- 2, 2, 108, 108, 108, 107, 107, 107,
- 107, 107, 107, 213, 213, 212, 212, 212,
- 212, 212, 212, 72, 72, 72, 71, 70,
- 70, 70, 70, 70, 70, 70, 53, 53,
- 2, 2, 2, 107, 107, 107, 107, 107,
- 107, 106, 106, 106, 212, 212, 212, 212,
- 212, 212, 212, 211, 211, 71, 71, 70,
- 70, 70, 70, 70, 70, 70, 70, 70,
- 2, 2, 2, 107, 107, 107, 107, 106,
- 106, 106, 106, 106, 212, 212, 212, 212,
- 212, 212, 211, 211, 211, 211, 211, 70,
- 70, 70, 70, 70, 70, 70, 70, 70,
- 2, 2, 2, 107, 107, 106, 106, 106,
- 106, 106, 106, 106, 212, 212, 212, 212,
- 212, 211, 211, 211, 211, 211, 211, 70,
- 70, 70, 70, 70, 70, 70, 70, 70,
- 2, 2, 2, 105, 105, 105, 105, 105,
- 105, 105, 105, 105, 105, 212, 212, 212,
- 211, 211, 211, 211, 211, 211, 211, 210,
- 210, 210, 210, 70, 70, 70, 70, 70,
- 2, 2, 2, 105, 105, 105, 105, 105,
- 105, 105, 105, 104, 104, 212, 212, 211,
- 211, 211, 211, 211, 211, 211, 210, 210,
- 210, 210, 210, 210, 210, 209, 209, 209,
- 2, 2, 2, 105, 105, 105, 105, 104,
- 104, 104, 104, 104, 103, 103, 211, 211,
- 211, 211, 211, 211, 211, 210, 210, 210,
- 210, 210, 210, 210, 209, 209, 209, 209,
- 2, 2, 2, 104, 104, 104, 104, 104,
- 104, 104, 104, 103, 103, 103, 211, 211,
- 211, 211, 211, 211, 210, 210, 210, 210,
- 210, 210, 210, 209, 209, 209, 209, 209,
- 2, 2, 104, 104, 104, 104, 104, 104,
- 104, 103, 103, 103, 103, 103, 103, 211,
- 211, 211, 211, 210, 210, 210, 210, 210,
- 210, 210, 209, 209, 209, 209, 209, 209,
- 2, 102, 102, 102, 102, 102, 102, 102,
- 103, 103, 103, 103, 103, 103, 103, 211,
- 211, 211, 210, 210, 210, 210, 210, 210,
- 210, 209, 209, 209, 209, 209, 209, 208,
- 250, 102, 102, 102, 102, 102, 102, 102,
- 102, 103, 103, 103, 103, 103, 103, 211,
- 211, 210, 210, 210, 210, 210, 210, 210,
- 209, 209, 209, 209, 209, 209, 208, 208,
- 250, 250, 102, 102, 102, 102, 102, 102,
- 102, 102, 103, 103, 103, 103, 103, 103,
- 210, 210, 210, 210, 210, 210, 210, 209,
- 209, 209, 209, 209, 209, 208, 208, 208,
- 250, 250, 250, 102, 102, 102, 102, 102,
- 102, 102, 102, 103, 103, 103, 103, 103,
- 210, 210, 210, 210, 210, 210, 209, 209,
- 209, 209, 209, 209, 208, 208, 208, 208,
- 250, 250, 250, 250, 102, 102, 102, 102,
- 102, 102, 102, 102, 102, 103, 103, 103,
- 210, 210, 210, 210, 210, 209, 209, 209,
- 209, 209, 209, 208, 208, 208, 208, 208,
- 250, 250, 250, 250, 250, 102, 102, 102,
- 102, 102, 102, 102, 102, 101, 101, 101,
- 210, 210, 210, 210, 209, 209, 209, 209,
- 209, 209, 208, 208, 208, 208, 208, 207,
- 250, 250, 250, 250, 250, 250, 102, 102,
- 102, 102, 102, 102, 102, 101, 101, 101,
- 210, 210, 210, 209, 209, 209, 209, 209,
- 209, 208, 208, 208, 208, 208, 207, 207,
- 250, 250, 250, 250, 250, 250, 250, 102,
- 102, 102, 102, 102, 101, 101, 101, 101,
- 210, 210, 209, 209, 209, 209, 209, 209,
- 208, 208, 208, 208, 208, 207, 207, 207,
- 250, 250, 250, 250, 250, 250, 250, 250,
- 102, 102, 102, 102, 101, 101, 101, 101,
- 101, 209, 209, 209, 209, 209, 209, 208,
- 208, 208, 208, 208, 207, 207, 207, 207,
- 247, 247, 247, 247, 247, 223, 223, 223,
- 223, 223, 59, 59, 58, 58, 58, 57,
- 57, 56, 56, 56, 56, 55, 55, 55,
- 54, 54, 54, 252, 252, 252, 252, 252,
- 247, 247, 247, 247, 44, 223, 223, 223,
- 223, 223, 59, 59, 58, 58, 57, 57,
- 57, 56, 56, 56, 55, 55, 55, 55,
- 54, 54, 54, 54, 252, 252, 252, 252,
- 247, 247, 247, 143, 143, 44, 223, 223,
- 223, 59, 59, 59, 58, 58, 57, 57,
- 57, 56, 56, 56, 55, 55, 55, 55,
- 54, 54, 54, 54, 54, 252, 252, 252,
- 247, 247, 143, 143, 143, 95, 95, 78,
- 60, 59, 59, 59, 58, 58, 57, 57,
- 56, 56, 56, 56, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 252, 252, 252,
- 143, 143, 143, 143, 143, 43, 43, 94,
- 78, 77, 59, 58, 58, 58, 57, 57,
- 56, 56, 56, 56, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 54, 252, 252,
- 159, 159, 159, 159, 159, 43, 94, 94,
- 78, 77, 77, 77, 58, 58, 57, 57,
- 56, 56, 56, 55, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 54, 53, 252,
- 159, 159, 159, 159, 126, 126, 94, 93,
- 77, 77, 77, 76, 76, 57, 57, 56,
- 56, 56, 56, 55, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 53, 53, 53,
- 159, 159, 159, 126, 126, 126, 94, 93,
- 77, 77, 76, 76, 76, 75, 75, 56,
- 56, 56, 56, 55, 55, 55, 55, 54,
- 54, 54, 54, 54, 53, 53, 53, 53,
- 110, 110, 110, 126, 126, 125, 125, 93,
- 77, 77, 76, 76, 76, 75, 75, 75,
- 74, 56, 56, 55, 55, 55, 54, 54,
- 54, 54, 54, 53, 53, 53, 53, 53,
- 110, 110, 110, 110, 109, 109, 125, 125,
- 92, 76, 76, 76, 75, 75, 75, 74,
- 74, 74, 73, 55, 55, 55, 54, 54,
- 54, 54, 53, 53, 53, 53, 53, 53,
- 110, 110, 109, 109, 109, 109, 109, 109,
- 108, 76, 76, 76, 75, 75, 75, 74,
- 74, 73, 73, 73, 73, 55, 54, 54,
- 54, 53, 53, 53, 53, 53, 53, 53,
- 110, 109, 109, 109, 109, 108, 108, 108,
- 108, 108, 76, 75, 75, 75, 74, 74,
- 74, 73, 73, 73, 73, 72, 72, 54,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 109, 109, 109, 108, 108, 108, 108, 108,
- 108, 107, 107, 75, 75, 74, 74, 74,
- 73, 73, 73, 73, 72, 72, 72, 71,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 2, 108, 108, 108, 108, 108, 108, 107,
- 107, 107, 107, 213, 213, 74, 74, 74,
- 73, 73, 73, 72, 72, 72, 71, 71,
- 70, 70, 70, 53, 53, 53, 53, 53,
- 2, 2, 108, 108, 107, 107, 107, 107,
- 107, 107, 106, 106, 213, 212, 212, 212,
- 73, 73, 73, 72, 72, 72, 71, 70,
- 70, 70, 70, 70, 70, 70, 52, 52,
- 2, 2, 107, 107, 107, 107, 107, 107,
- 106, 106, 106, 106, 106, 212, 212, 212,
- 212, 212, 72, 72, 72, 71, 71, 70,
- 70, 70, 70, 70, 70, 70, 70, 52,
- 2, 2, 2, 107, 107, 107, 106, 106,
- 106, 106, 106, 106, 106, 212, 212, 212,
- 212, 212, 211, 211, 71, 71, 70, 70,
- 70, 70, 70, 70, 70, 70, 70, 70,
- 2, 2, 2, 107, 105, 105, 106, 106,
- 106, 106, 106, 106, 106, 212, 212, 212,
- 212, 211, 211, 211, 211, 211, 70, 70,
- 70, 70, 70, 70, 70, 70, 70, 70,
- 2, 2, 2, 105, 105, 105, 105, 105,
- 105, 105, 105, 105, 105, 212, 212, 212,
- 211, 211, 211, 211, 211, 211, 211, 70,
- 70, 70, 70, 70, 70, 70, 70, 70,
- 2, 2, 105, 105, 105, 105, 105, 105,
- 105, 105, 104, 104, 104, 103, 212, 211,
- 211, 211, 211, 211, 211, 211, 210, 210,
- 210, 210, 210, 70, 70, 70, 209, 209,
- 2, 2, 105, 105, 105, 105, 104, 104,
- 104, 104, 104, 104, 103, 103, 103, 211,
- 211, 211, 211, 211, 211, 210, 210, 210,
- 210, 210, 210, 210, 209, 209, 209, 209,
- 2, 2, 104, 104, 104, 104, 104, 104,
- 104, 104, 103, 103, 103, 103, 103, 211,
- 211, 211, 211, 211, 210, 210, 210, 210,
- 210, 210, 210, 209, 209, 209, 209, 209,
- 2, 102, 104, 104, 104, 104, 104, 104,
- 104, 103, 103, 103, 103, 103, 103, 211,
- 211, 211, 211, 210, 210, 210, 210, 210,
- 210, 210, 209, 209, 209, 209, 209, 209,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 103, 103, 103, 103, 103, 103, 103, 103,
- 211, 211, 210, 210, 210, 210, 210, 210,
- 210, 209, 209, 209, 209, 209, 209, 208,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 102, 103, 103, 103, 103, 103, 103, 103,
- 211, 210, 210, 210, 210, 210, 210, 210,
- 209, 209, 209, 209, 209, 209, 208, 208,
- 250, 102, 102, 102, 102, 102, 102, 102,
- 102, 102, 102, 103, 103, 103, 103, 103,
- 210, 210, 210, 210, 210, 210, 210, 209,
- 209, 209, 209, 209, 209, 208, 208, 208,
- 250, 250, 102, 102, 102, 102, 102, 102,
- 102, 102, 102, 102, 103, 103, 103, 103,
- 210, 210, 210, 210, 210, 210, 209, 209,
- 209, 209, 209, 209, 208, 208, 208, 207,
- 250, 250, 250, 102, 102, 102, 102, 102,
- 102, 102, 102, 102, 101, 101, 101, 101,
- 210, 210, 210, 210, 210, 209, 209, 209,
- 209, 209, 209, 208, 208, 208, 207, 207,
- 250, 250, 250, 250, 102, 102, 102, 102,
- 102, 102, 102, 102, 101, 101, 101, 101,
- 101, 210, 210, 210, 209, 209, 209, 209,
- 209, 209, 208, 208, 208, 207, 207, 207,
- 250, 250, 250, 250, 250, 102, 102, 102,
- 102, 102, 102, 102, 101, 101, 101, 101,
- 100, 210, 210, 209, 209, 209, 209, 209,
- 209, 208, 208, 208, 207, 207, 207, 207,
- 250, 250, 250, 250, 250, 250, 102, 102,
- 102, 102, 102, 101, 101, 101, 101, 101,
- 100, 210, 209, 209, 209, 209, 209, 209,
- 208, 208, 208, 207, 207, 207, 207, 207,
- 250, 250, 250, 250, 250, 250, 250, 102,
- 102, 102, 102, 101, 101, 101, 101, 101,
- 100, 209, 209, 209, 209, 209, 209, 208,
- 208, 208, 207, 207, 207, 207, 207, 207,
- 246, 246, 246, 246, 223, 223, 223, 223,
- 223, 223, 223, 222, 58, 58, 57, 57,
- 57, 56, 56, 56, 55, 55, 55, 55,
- 54, 54, 54, 54, 252, 252, 252, 252,
- 246, 246, 246, 246, 223, 223, 223, 223,
- 223, 223, 223, 222, 58, 58, 57, 57,
- 57, 56, 56, 56, 55, 55, 55, 55,
- 54, 54, 54, 54, 54, 252, 252, 252,
- 246, 246, 246, 143, 143, 223, 223, 223,
- 223, 223, 223, 59, 58, 58, 57, 57,
- 56, 56, 56, 56, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 252, 252, 252,
- 246, 246, 143, 143, 143, 143, 43, 223,
- 223, 223, 59, 58, 58, 58, 57, 57,
- 56, 56, 56, 56, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 54, 252, 252,
- 246, 143, 143, 143, 142, 43, 43, 94,
- 15, 15, 77, 58, 58, 58, 57, 57,
- 56, 56, 56, 55, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 54, 53, 252,
- 159, 159, 159, 142, 142, 43, 43, 15,
- 15, 77, 77, 76, 58, 57, 57, 56,
- 56, 56, 56, 55, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 53, 53, 53,
- 159, 159, 158, 158, 158, 158, 42, 93,
- 93, 77, 77, 76, 76, 76, 57, 56,
- 56, 56, 56, 55, 55, 55, 55, 54,
- 54, 54, 54, 54, 53, 53, 53, 53,
- 159, 158, 158, 158, 158, 125, 125, 93,
- 93, 77, 76, 76, 76, 75, 75, 75,
- 56, 56, 56, 55, 55, 55, 54, 54,
- 54, 54, 54, 53, 53, 53, 53, 53,
- 158, 158, 158, 158, 125, 125, 125, 125,
- 92, 92, 76, 76, 75, 75, 75, 75,
- 74, 74, 55, 55, 55, 55, 54, 54,
- 54, 54, 53, 53, 53, 53, 53, 53,
- 158, 158, 158, 125, 125, 125, 125, 124,
- 92, 92, 76, 76, 75, 75, 75, 74,
- 74, 74, 73, 73, 55, 55, 54, 54,
- 54, 53, 53, 53, 53, 53, 53, 53,
- 110, 110, 109, 109, 109, 125, 124, 124,
- 92, 92, 76, 75, 75, 75, 74, 74,
- 74, 73, 73, 73, 73, 72, 54, 54,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 109, 109, 109, 109, 109, 108, 108, 108,
- 124, 123, 91, 75, 75, 75, 74, 74,
- 74, 73, 73, 73, 72, 72, 72, 53,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 109, 109, 108, 108, 108, 108, 108, 108,
- 107, 107, 91, 75, 75, 74, 74, 74,
- 73, 73, 73, 72, 72, 72, 72, 71,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 191, 108, 108, 108, 108, 108, 107, 107,
- 107, 107, 107, 75, 74, 74, 74, 73,
- 73, 73, 73, 72, 72, 72, 71, 71,
- 70, 70, 70, 53, 53, 52, 52, 52,
- 2, 108, 108, 107, 107, 107, 107, 107,
- 107, 106, 106, 106, 74, 74, 74, 73,
- 73, 73, 72, 72, 72, 71, 71, 70,
- 70, 70, 70, 70, 70, 52, 52, 52,
- 2, 2, 107, 107, 107, 107, 107, 106,
- 106, 106, 106, 106, 106, 212, 212, 73,
- 73, 72, 72, 72, 71, 71, 71, 70,
- 70, 70, 70, 70, 70, 70, 70, 52,
- 2, 2, 107, 107, 107, 106, 106, 106,
- 106, 106, 106, 106, 106, 212, 212, 212,
- 212, 72, 72, 72, 71, 71, 70, 70,
- 70, 70, 70, 70, 70, 70, 70, 70,
- 2, 2, 105, 105, 105, 105, 105, 105,
- 105, 105, 105, 106, 106, 212, 212, 212,
- 212, 211, 211, 71, 71, 71, 70, 70,
- 70, 70, 70, 70, 70, 70, 70, 70,
- 2, 2, 105, 105, 105, 105, 105, 105,
- 105, 105, 105, 105, 105, 104, 212, 212,
- 211, 211, 211, 211, 211, 70, 70, 70,
- 70, 70, 70, 70, 70, 70, 70, 68,
- 2, 2, 105, 105, 105, 105, 105, 105,
- 105, 104, 104, 104, 104, 103, 103, 211,
- 211, 211, 211, 211, 211, 211, 210, 70,
- 70, 70, 70, 70, 70, 70, 68, 68,
- 2, 105, 105, 105, 105, 104, 104, 104,
- 104, 104, 104, 103, 103, 103, 103, 211,
- 211, 211, 211, 211, 211, 210, 210, 210,
- 210, 210, 210, 210, 209, 209, 209, 209,
- 2, 104, 104, 104, 104, 104, 104, 104,
- 104, 104, 103, 103, 103, 103, 103, 103,
- 211, 211, 211, 211, 210, 210, 210, 210,
- 210, 210, 210, 209, 209, 209, 209, 209,
- 102, 102, 102, 102, 102, 104, 104, 104,
- 103, 103, 103, 103, 103, 103, 103, 103,
- 211, 211, 211, 210, 210, 210, 210, 210,
- 210, 210, 209, 209, 209, 209, 209, 209,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 102, 103, 103, 103, 103, 103, 103, 103,
- 211, 211, 210, 210, 210, 210, 210, 210,
- 210, 209, 209, 209, 209, 209, 209, 208,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 102, 102, 103, 103, 103, 103, 103, 103,
- 103, 210, 210, 210, 210, 210, 210, 210,
- 209, 209, 209, 209, 209, 209, 208, 207,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 102, 102, 102, 103, 103, 103, 103, 103,
- 103, 210, 210, 210, 210, 210, 210, 209,
- 209, 209, 209, 209, 209, 208, 207, 207,
- 250, 102, 102, 102, 102, 102, 102, 102,
- 102, 102, 102, 102, 101, 101, 101, 101,
- 100, 210, 210, 210, 210, 210, 209, 209,
- 209, 209, 209, 209, 208, 207, 207, 207,
- 250, 250, 102, 102, 102, 102, 102, 102,
- 102, 102, 102, 101, 101, 101, 101, 101,
- 100, 210, 210, 210, 210, 209, 209, 209,
- 209, 209, 209, 208, 207, 207, 207, 207,
- 250, 250, 250, 102, 102, 102, 102, 102,
- 102, 102, 102, 101, 101, 101, 101, 101,
- 100, 100, 210, 210, 209, 209, 209, 209,
- 209, 209, 208, 207, 207, 207, 207, 207,
- 250, 250, 250, 250, 102, 102, 102, 102,
- 102, 102, 102, 101, 101, 101, 101, 100,
- 100, 100, 210, 209, 209, 209, 209, 209,
- 209, 208, 207, 207, 207, 207, 207, 207,
- 250, 250, 250, 250, 250, 102, 102, 102,
- 102, 102, 101, 101, 101, 101, 101, 100,
- 100, 100, 209, 209, 209, 209, 209, 209,
- 208, 207, 207, 207, 207, 207, 207, 207,
- 250, 250, 250, 250, 250, 250, 102, 102,
- 102, 102, 101, 101, 101, 101, 101, 100,
- 100, 100, 209, 209, 209, 209, 209, 208,
- 207, 207, 207, 207, 207, 207, 207, 207,
- 246, 246, 246, 246, 223, 223, 223, 223,
- 223, 223, 222, 222, 222, 222, 57, 57,
- 57, 56, 56, 56, 55, 55, 55, 55,
- 54, 54, 54, 54, 54, 252, 252, 252,
- 246, 246, 246, 246, 223, 223, 223, 223,
- 223, 223, 222, 222, 222, 58, 57, 57,
- 56, 56, 56, 56, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 252, 252, 252,
- 246, 246, 246, 246, 143, 223, 223, 223,
- 223, 223, 222, 222, 222, 58, 57, 57,
- 56, 56, 56, 56, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 54, 252, 252,
- 246, 246, 246, 143, 142, 142, 223, 223,
- 223, 222, 222, 222, 58, 58, 57, 57,
- 56, 56, 56, 55, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 54, 53, 252,
- 246, 143, 143, 142, 142, 142, 43, 15,
- 15, 15, 222, 222, 58, 57, 57, 56,
- 56, 56, 56, 55, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 53, 53, 53,
- 159, 159, 142, 142, 142, 142, 15, 15,
- 15, 15, 15, 76, 76, 57, 57, 56,
- 56, 56, 56, 55, 55, 55, 55, 54,
- 54, 54, 54, 54, 53, 53, 53, 53,
- 159, 158, 158, 158, 158, 158, 42, 15,
- 15, 15, 92, 76, 76, 75, 75, 56,
- 56, 56, 56, 55, 55, 55, 54, 54,
- 54, 54, 54, 53, 53, 53, 53, 53,
- 158, 158, 158, 158, 158, 141, 42, 42,
- 41, 92, 92, 76, 76, 75, 75, 75,
- 56, 56, 55, 55, 55, 55, 54, 54,
- 54, 54, 53, 53, 53, 53, 53, 53,
- 158, 158, 158, 158, 157, 125, 125, 41,
- 92, 92, 92, 76, 75, 75, 75, 74,
- 74, 74, 55, 55, 55, 55, 54, 54,
- 54, 53, 53, 53, 53, 53, 53, 53,
- 158, 158, 158, 157, 157, 125, 124, 124,
- 92, 92, 91, 91, 75, 75, 75, 74,
- 74, 74, 73, 73, 55, 55, 54, 54,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 191, 157, 157, 157, 124, 124, 124, 124,
- 124, 92, 91, 91, 75, 75, 74, 74,
- 74, 73, 73, 73, 72, 72, 54, 53,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 191, 191, 157, 124, 124, 124, 124, 124,
- 123, 123, 91, 91, 75, 74, 74, 74,
- 73, 73, 73, 73, 72, 72, 72, 53,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 191, 191, 108, 108, 108, 108, 108, 123,
- 123, 123, 123, 90, 90, 74, 74, 74,
- 73, 73, 73, 72, 72, 72, 71, 71,
- 53, 53, 53, 53, 53, 52, 52, 52,
- 191, 191, 108, 108, 108, 107, 107, 107,
- 107, 123, 122, 90, 90, 74, 74, 73,
- 73, 73, 72, 72, 72, 71, 71, 71,
- 70, 70, 70, 52, 52, 52, 52, 52,
- 191, 191, 107, 107, 107, 107, 107, 107,
- 106, 106, 106, 106, 90, 74, 74, 73,
- 73, 73, 72, 72, 72, 71, 71, 70,
- 70, 70, 70, 70, 52, 52, 52, 52,
- 191, 191, 107, 107, 107, 107, 106, 106,
- 106, 106, 106, 106, 106, 74, 73, 73,
- 73, 72, 72, 72, 71, 71, 71, 70,
- 70, 70, 70, 70, 70, 70, 52, 52,
- 191, 191, 107, 107, 106, 106, 106, 106,
- 106, 106, 106, 106, 106, 106, 73, 73,
- 72, 72, 72, 71, 71, 71, 70, 70,
- 70, 70, 70, 70, 70, 70, 70, 51,
- 2, 105, 105, 105, 105, 105, 105, 105,
- 105, 105, 105, 105, 105, 105, 212, 212,
- 72, 72, 72, 71, 71, 71, 70, 70,
- 70, 70, 70, 70, 70, 70, 70, 68,
- 2, 105, 105, 105, 105, 105, 105, 105,
- 105, 105, 105, 104, 104, 104, 212, 212,
- 211, 211, 71, 71, 71, 70, 70, 70,
- 70, 70, 70, 70, 70, 68, 68, 68,
- 2, 105, 105, 105, 105, 105, 105, 104,
- 104, 104, 104, 104, 103, 103, 103, 211,
- 211, 211, 211, 211, 211, 70, 70, 70,
- 70, 70, 70, 70, 68, 68, 68, 68,
- 2, 105, 105, 104, 104, 104, 104, 104,
- 104, 104, 104, 103, 103, 103, 103, 103,
- 211, 211, 211, 211, 210, 210, 210, 70,
- 70, 70, 69, 68, 68, 68, 68, 68,
- 104, 104, 104, 104, 104, 104, 104, 104,
- 104, 103, 103, 103, 103, 103, 103, 103,
- 211, 211, 211, 210, 210, 210, 210, 210,
- 210, 210, 210, 68, 68, 209, 209, 209,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 103, 103, 103, 103, 103, 103, 103, 103,
- 211, 211, 210, 210, 210, 210, 210, 210,
- 210, 210, 209, 209, 209, 209, 209, 206,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 102, 103, 103, 103, 103, 103, 103, 103,
- 103, 210, 210, 210, 210, 210, 210, 210,
- 210, 209, 209, 209, 209, 209, 206, 206,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 102, 102, 103, 103, 103, 103, 103, 103,
- 100, 210, 210, 210, 210, 210, 210, 210,
- 209, 209, 209, 209, 209, 206, 206, 207,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 102, 102, 102, 101, 101, 101, 101, 100,
- 100, 210, 210, 210, 210, 210, 210, 209,
- 209, 209, 209, 209, 206, 206, 207, 207,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 102, 102, 102, 101, 101, 101, 101, 100,
- 100, 100, 210, 210, 210, 210, 209, 209,
- 209, 209, 209, 206, 206, 207, 207, 207,
- 250, 102, 102, 102, 102, 102, 102, 102,
- 102, 102, 101, 101, 101, 101, 101, 100,
- 100, 100, 210, 210, 210, 209, 209, 209,
- 209, 209, 206, 206, 207, 207, 207, 207,
- 250, 250, 102, 102, 102, 102, 102, 102,
- 102, 102, 101, 101, 101, 101, 101, 100,
- 100, 100, 210, 210, 209, 209, 209, 209,
- 209, 206, 206, 207, 207, 207, 207, 207,
- 250, 250, 250, 102, 102, 102, 102, 102,
- 102, 102, 101, 101, 101, 101, 100, 100,
- 100, 100, 99, 209, 209, 209, 209, 209,
- 206, 206, 207, 207, 207, 207, 207, 207,
- 250, 250, 250, 250, 102, 102, 102, 102,
- 102, 101, 101, 101, 101, 101, 100, 100,
- 100, 100, 98, 209, 209, 209, 209, 206,
- 206, 207, 207, 207, 207, 207, 207, 207,
- 250, 250, 250, 250, 250, 102, 102, 102,
- 102, 101, 101, 101, 101, 101, 100, 100,
- 100, 98, 98, 209, 209, 209, 206, 206,
- 207, 207, 207, 207, 207, 207, 207, 207,
- 245, 245, 245, 245, 223, 223, 223, 223,
- 223, 222, 222, 222, 222, 222, 221, 221,
- 56, 56, 56, 56, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 252, 252, 252,
- 245, 245, 245, 245, 223, 223, 223, 223,
- 223, 222, 222, 222, 222, 222, 221, 221,
- 56, 56, 56, 56, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 54, 252, 252,
- 245, 245, 245, 245, 223, 223, 223, 223,
- 223, 222, 222, 222, 222, 221, 221, 57,
- 56, 56, 56, 55, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 54, 53, 252,
- 245, 245, 245, 142, 142, 142, 223, 223,
- 222, 222, 222, 222, 222, 221, 57, 56,
- 56, 56, 56, 55, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 53, 53, 53,
- 245, 245, 142, 142, 142, 142, 15, 15,
- 15, 222, 222, 222, 222, 57, 57, 56,
- 56, 56, 56, 55, 55, 55, 55, 54,
- 54, 54, 54, 54, 53, 53, 53, 53,
- 245, 142, 142, 142, 142, 141, 141, 15,
- 15, 15, 15, 76, 76, 57, 57, 56,
- 56, 56, 56, 55, 55, 55, 54, 54,
- 54, 54, 54, 53, 53, 53, 53, 53,
- 158, 158, 158, 158, 141, 141, 141, 15,
- 15, 41, 92, 92, 76, 75, 75, 56,
- 56, 56, 55, 55, 55, 55, 54, 54,
- 54, 54, 53, 53, 53, 53, 53, 53,
- 158, 158, 158, 158, 141, 141, 141, 41,
- 41, 92, 92, 91, 91, 75, 75, 75,
- 74, 56, 55, 55, 55, 55, 54, 54,
- 54, 53, 53, 53, 53, 53, 53, 53,
- 158, 158, 157, 157, 157, 157, 157, 41,
- 41, 92, 91, 91, 91, 75, 75, 74,
- 74, 74, 73, 55, 55, 55, 54, 54,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 158, 157, 157, 157, 157, 157, 124, 124,
- 40, 40, 91, 91, 91, 75, 74, 74,
- 74, 74, 73, 73, 55, 54, 54, 53,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 191, 191, 157, 157, 157, 124, 124, 124,
- 123, 123, 91, 91, 90, 90, 74, 74,
- 74, 73, 73, 73, 72, 72, 53, 53,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 191, 191, 191, 124, 124, 124, 124, 123,
- 123, 123, 91, 90, 90, 90, 74, 74,
- 73, 73, 73, 72, 72, 72, 72, 53,
- 53, 53, 53, 53, 53, 52, 52, 52,
- 191, 191, 191, 191, 124, 124, 123, 123,
- 123, 123, 122, 90, 90, 90, 74, 74,
- 73, 73, 73, 72, 72, 72, 71, 71,
- 53, 52, 52, 52, 52, 52, 52, 52,
- 191, 191, 191, 191, 107, 107, 123, 123,
- 122, 122, 122, 122, 90, 89, 74, 73,
- 73, 73, 72, 72, 72, 71, 71, 71,
- 70, 70, 52, 52, 52, 52, 52, 52,
- 191, 191, 191, 191, 107, 107, 107, 107,
- 122, 122, 122, 121, 89, 89, 89, 73,
- 73, 72, 72, 72, 71, 71, 71, 70,
- 70, 70, 70, 70, 52, 52, 52, 52,
- 191, 191, 191, 107, 107, 107, 106, 106,
- 106, 106, 121, 121, 121, 89, 89, 73,
- 73, 72, 72, 72, 71, 71, 71, 70,
- 70, 70, 70, 70, 70, 52, 51, 51,
- 191, 191, 191, 105, 105, 105, 106, 106,
- 106, 106, 106, 121, 121, 121, 88, 88,
- 72, 72, 72, 71, 71, 71, 70, 70,
- 70, 70, 70, 70, 70, 70, 51, 51,
- 191, 191, 105, 105, 105, 105, 105, 105,
- 105, 105, 105, 105, 105, 120, 88, 88,
- 72, 72, 71, 71, 71, 71, 70, 70,
- 70, 70, 70, 70, 70, 68, 68, 68,
- 191, 191, 105, 105, 105, 105, 105, 105,
- 105, 105, 104, 104, 104, 104, 120, 87,
- 72, 71, 71, 71, 71, 70, 70, 70,
- 70, 70, 70, 69, 68, 68, 68, 68,
- 191, 105, 105, 105, 105, 105, 104, 104,
- 104, 104, 104, 104, 103, 103, 103, 103,
- 211, 211, 71, 71, 70, 70, 70, 70,
- 70, 69, 69, 68, 68, 68, 68, 68,
- 105, 105, 104, 104, 104, 104, 104, 104,
- 104, 104, 103, 103, 103, 103, 103, 103,
- 211, 211, 211, 211, 70, 70, 70, 69,
- 69, 69, 68, 68, 68, 68, 68, 68,
- 102, 102, 104, 104, 104, 104, 104, 104,
- 104, 103, 103, 103, 103, 103, 103, 103,
- 103, 211, 211, 210, 210, 210, 210, 69,
- 69, 68, 68, 68, 68, 68, 68, 68,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 103, 103, 103, 103, 103, 103, 103, 103,
- 103, 211, 210, 210, 210, 210, 210, 210,
- 210, 68, 68, 68, 68, 68, 206, 206,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 102, 102, 103, 103, 103, 103, 103, 100,
- 100, 100, 210, 210, 210, 210, 210, 210,
- 210, 209, 209, 209, 206, 206, 206, 206,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 102, 102, 102, 101, 101, 101, 101, 100,
- 100, 100, 210, 210, 210, 210, 210, 210,
- 209, 209, 209, 206, 206, 206, 206, 206,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 102, 102, 101, 101, 101, 101, 100, 100,
- 100, 100, 210, 210, 210, 210, 210, 209,
- 209, 209, 206, 206, 206, 206, 206, 206,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 102, 102, 101, 101, 101, 101, 100, 100,
- 100, 100, 99, 210, 210, 210, 209, 209,
- 209, 206, 206, 206, 206, 206, 206, 206,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 102, 101, 101, 101, 101, 101, 100, 100,
- 100, 100, 99, 210, 210, 209, 209, 209,
- 206, 206, 206, 206, 206, 206, 206, 206,
- 250, 102, 102, 102, 102, 102, 102, 102,
- 102, 101, 101, 101, 101, 101, 100, 100,
- 100, 100, 99, 98, 209, 209, 209, 206,
- 206, 206, 206, 206, 206, 206, 206, 206,
- 250, 250, 102, 102, 102, 102, 102, 102,
- 102, 101, 101, 101, 101, 100, 100, 100,
- 100, 99, 98, 98, 209, 209, 206, 206,
- 206, 206, 206, 206, 206, 206, 206, 206,
- 250, 250, 250, 102, 102, 102, 102, 102,
- 101, 101, 101, 101, 101, 100, 100, 100,
- 100, 98, 98, 98, 209, 206, 206, 206,
- 206, 206, 206, 206, 206, 206, 206, 206,
- 250, 250, 250, 250, 102, 102, 102, 102,
- 101, 101, 101, 101, 101, 100, 100, 100,
- 98, 98, 98, 98, 206, 206, 206, 206,
- 206, 206, 206, 206, 206, 206, 206, 206,
- 245, 245, 245, 245, 245, 223, 223, 223,
- 222, 222, 222, 222, 222, 221, 221, 221,
- 221, 221, 56, 56, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 54, 252, 252,
- 245, 245, 245, 245, 245, 223, 223, 223,
- 222, 222, 222, 222, 222, 221, 221, 221,
- 221, 56, 56, 55, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 54, 53, 252,
- 245, 245, 245, 245, 245, 223, 223, 223,
- 222, 222, 222, 222, 221, 221, 221, 221,
- 221, 56, 56, 55, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 53, 53, 53,
- 245, 245, 245, 245, 142, 223, 223, 222,
- 222, 222, 222, 222, 221, 221, 221, 221,
- 56, 56, 56, 55, 55, 55, 55, 54,
- 54, 54, 54, 54, 53, 53, 53, 53,
- 245, 245, 245, 142, 142, 141, 141, 15,
- 222, 222, 222, 222, 221, 221, 221, 56,
- 56, 56, 56, 55, 55, 55, 54, 54,
- 54, 54, 54, 53, 53, 53, 53, 53,
- 245, 142, 142, 142, 141, 141, 141, 15,
- 15, 15, 222, 222, 221, 221, 221, 56,
- 56, 56, 55, 55, 55, 55, 54, 54,
- 54, 54, 53, 53, 53, 53, 53, 53,
- 158, 158, 158, 141, 141, 141, 141, 141,
- 41, 41, 40, 91, 91, 91, 75, 75,
- 56, 56, 55, 55, 55, 55, 54, 54,
- 54, 53, 53, 53, 53, 53, 53, 53,
- 158, 158, 141, 141, 141, 141, 141, 140,
- 41, 40, 40, 91, 91, 91, 75, 74,
- 74, 74, 55, 55, 55, 55, 54, 54,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 158, 157, 157, 157, 157, 157, 140, 140,
- 40, 40, 91, 91, 91, 90, 90, 74,
- 74, 74, 73, 55, 55, 54, 54, 53,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 191, 191, 157, 157, 157, 156, 156, 156,
- 40, 40, 91, 91, 90, 90, 90, 74,
- 74, 73, 73, 73, 72, 54, 53, 53,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 191, 191, 191, 156, 156, 156, 156, 123,
- 123, 39, 39, 90, 90, 90, 90, 74,
- 74, 73, 73, 72, 72, 72, 53, 53,
- 53, 53, 53, 53, 53, 52, 52, 52,
- 191, 191, 191, 191, 156, 156, 123, 123,
- 123, 123, 38, 90, 90, 90, 89, 74,
- 73, 73, 73, 72, 72, 72, 71, 53,
- 53, 52, 52, 52, 52, 52, 52, 52,
- 191, 191, 191, 191, 156, 123, 123, 123,
- 123, 122, 122, 90, 90, 89, 89, 89,
- 73, 73, 72, 72, 72, 71, 71, 71,
- 52, 52, 52, 52, 52, 52, 52, 52,
- 191, 191, 191, 191, 191, 123, 123, 122,
- 122, 122, 122, 122, 89, 89, 89, 88,
- 73, 72, 72, 72, 72, 71, 71, 71,
- 70, 52, 52, 52, 52, 52, 52, 52,
- 191, 191, 191, 191, 191, 122, 122, 122,
- 122, 122, 121, 121, 89, 89, 89, 88,
- 88, 72, 72, 72, 71, 71, 71, 70,
- 70, 70, 70, 52, 52, 52, 51, 51,
- 191, 191, 191, 191, 191, 106, 106, 121,
- 121, 121, 121, 121, 121, 89, 88, 88,
- 88, 72, 72, 71, 71, 71, 71, 70,
- 70, 70, 70, 70, 51, 51, 51, 51,
- 191, 191, 191, 191, 105, 105, 105, 105,
- 121, 121, 121, 121, 121, 120, 88, 88,
- 88, 72, 71, 71, 71, 71, 70, 70,
- 70, 70, 70, 69, 69, 51, 51, 51,
- 191, 191, 191, 105, 105, 105, 105, 105,
- 105, 105, 121, 120, 120, 120, 88, 88,
- 87, 72, 71, 71, 71, 71, 70, 70,
- 70, 69, 69, 69, 68, 68, 68, 68,
- 191, 190, 190, 105, 105, 105, 105, 105,
- 105, 104, 104, 104, 120, 120, 120, 87,
- 87, 87, 71, 71, 71, 70, 70, 69,
- 69, 69, 69, 68, 68, 68, 68, 68,
- 190, 190, 105, 105, 105, 104, 104, 104,
- 104, 104, 104, 103, 103, 103, 103, 87,
- 87, 87, 71, 71, 70, 69, 69, 69,
- 69, 69, 68, 68, 68, 68, 68, 68,
- 190, 104, 104, 104, 104, 104, 104, 104,
- 104, 104, 103, 103, 103, 103, 103, 103,
- 87, 86, 71, 71, 69, 69, 69, 69,
- 69, 68, 68, 68, 68, 68, 68, 68,
- 102, 102, 102, 102, 102, 102, 104, 104,
- 103, 103, 103, 103, 103, 103, 103, 103,
- 100, 211, 211, 69, 69, 69, 69, 69,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 102, 103, 103, 103, 103, 103, 103, 100,
- 100, 100, 210, 210, 210, 69, 69, 68,
- 68, 68, 68, 68, 68, 68, 68, 206,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 102, 102, 101, 101, 101, 101, 100, 100,
- 100, 100, 99, 210, 210, 210, 210, 68,
- 68, 68, 68, 206, 206, 206, 206, 206,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 102, 102, 101, 101, 101, 101, 100, 100,
- 100, 100, 99, 210, 210, 210, 210, 210,
- 209, 206, 206, 206, 206, 206, 206, 206,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 102, 101, 101, 101, 101, 100, 100, 100,
- 100, 100, 99, 99, 210, 210, 210, 209,
- 206, 206, 206, 206, 206, 206, 206, 206,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 102, 101, 101, 101, 101, 100, 100, 100,
- 100, 99, 99, 99, 210, 210, 209, 206,
- 206, 206, 206, 206, 206, 206, 206, 206,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 101, 101, 101, 101, 101, 100, 100, 100,
- 100, 99, 99, 99, 98, 209, 206, 206,
- 206, 206, 206, 206, 206, 206, 206, 206,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 101, 101, 101, 101, 101, 100, 100, 100,
- 100, 99, 98, 98, 98, 206, 206, 206,
- 206, 206, 206, 206, 206, 206, 206, 206,
- 250, 102, 102, 102, 102, 102, 102, 102,
- 101, 101, 101, 101, 100, 100, 100, 100,
- 99, 98, 98, 98, 98, 206, 206, 206,
- 206, 206, 206, 206, 206, 206, 206, 206,
- 250, 250, 102, 102, 102, 102, 102, 101,
- 101, 101, 101, 101, 100, 100, 100, 100,
- 98, 98, 98, 98, 98, 206, 206, 206,
- 206, 206, 206, 206, 206, 206, 206, 205,
- 250, 250, 250, 102, 102, 102, 102, 101,
- 101, 101, 101, 101, 100, 100, 100, 98,
- 98, 98, 98, 98, 98, 206, 206, 206,
- 206, 206, 206, 206, 206, 206, 205, 205,
- 244, 244, 244, 244, 244, 223, 223, 222,
- 222, 222, 222, 222, 221, 221, 221, 221,
- 221, 220, 220, 5, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 54, 53, 252,
- 244, 244, 244, 244, 244, 223, 223, 222,
- 222, 222, 222, 222, 221, 221, 221, 221,
- 220, 220, 220, 220, 55, 55, 55, 54,
- 54, 54, 54, 54, 54, 53, 53, 53,
- 244, 244, 244, 244, 244, 223, 223, 222,
- 222, 222, 222, 221, 221, 221, 221, 221,
- 220, 220, 220, 55, 55, 55, 55, 54,
- 54, 54, 54, 54, 53, 53, 53, 53,
- 244, 244, 244, 244, 244, 141, 222, 222,
- 222, 222, 222, 221, 221, 221, 221, 221,
- 220, 220, 220, 55, 55, 55, 54, 54,
- 54, 54, 54, 53, 53, 53, 53, 53,
- 244, 244, 244, 141, 141, 141, 141, 222,
- 222, 222, 222, 221, 221, 221, 221, 221,
- 220, 220, 55, 55, 55, 55, 54, 54,
- 54, 54, 53, 53, 53, 53, 53, 53,
- 244, 244, 141, 141, 141, 141, 141, 141,
- 15, 222, 222, 221, 221, 221, 221, 221,
- 220, 56, 55, 55, 55, 55, 54, 54,
- 54, 53, 53, 53, 53, 53, 53, 53,
- 244, 141, 141, 141, 141, 141, 140, 140,
- 140, 40, 40, 91, 91, 91, 90, 90,
- 56, 56, 55, 55, 55, 55, 54, 54,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 158, 141, 141, 141, 141, 140, 140, 140,
- 140, 40, 40, 91, 91, 90, 90, 90,
- 74, 74, 55, 55, 55, 54, 54, 53,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 191, 191, 157, 157, 140, 140, 140, 140,
- 40, 40, 39, 39, 90, 90, 90, 90,
- 74, 74, 73, 55, 55, 54, 53, 53,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 191, 191, 191, 156, 156, 156, 156, 156,
- 139, 39, 39, 38, 90, 90, 90, 90,
- 74, 73, 73, 73, 72, 53, 53, 53,
- 53, 53, 53, 53, 53, 52, 52, 52,
- 191, 191, 191, 156, 156, 156, 156, 155,
- 123, 39, 38, 38, 90, 90, 90, 89,
- 88, 73, 73, 72, 72, 72, 53, 53,
- 53, 52, 52, 52, 52, 52, 52, 52,
- 191, 191, 191, 191, 156, 156, 155, 155,
- 123, 122, 38, 90, 90, 89, 89, 89,
- 88, 73, 72, 72, 72, 72, 71, 52,
- 52, 52, 52, 52, 52, 52, 52, 52,
- 191, 191, 191, 191, 191, 155, 155, 155,
- 122, 122, 122, 37, 89, 89, 89, 88,
- 88, 88, 72, 72, 72, 71, 71, 52,
- 52, 52, 52, 52, 52, 52, 52, 52,
- 191, 191, 191, 191, 191, 155, 155, 122,
- 122, 122, 122, 121, 89, 89, 89, 88,
- 88, 88, 72, 72, 71, 71, 71, 71,
- 52, 52, 52, 52, 52, 52, 51, 51,
- 191, 191, 191, 191, 191, 155, 122, 122,
- 122, 121, 121, 121, 121, 89, 88, 88,
- 88, 88, 72, 72, 71, 71, 71, 70,
- 70, 70, 52, 51, 51, 51, 51, 51,
- 191, 191, 191, 191, 191, 122, 121, 121,
- 121, 121, 121, 121, 121, 89, 88, 88,
- 88, 87, 72, 71, 71, 71, 71, 70,
- 70, 70, 69, 51, 51, 51, 51, 51,
- 191, 191, 191, 191, 191, 105, 121, 121,
- 121, 121, 121, 120, 120, 120, 88, 88,
- 87, 87, 87, 71, 71, 71, 70, 70,
- 69, 69, 69, 69, 68, 51, 51, 50,
- 191, 190, 190, 190, 105, 105, 105, 105,
- 121, 121, 120, 120, 120, 120, 120, 87,
- 87, 87, 87, 71, 71, 70, 69, 69,
- 69, 69, 69, 68, 68, 68, 68, 50,
- 190, 190, 190, 190, 105, 105, 105, 105,
- 104, 104, 120, 120, 120, 120, 119, 87,
- 87, 87, 86, 71, 71, 69, 69, 69,
- 69, 69, 68, 68, 68, 68, 68, 68,
- 190, 190, 190, 105, 104, 104, 104, 104,
- 104, 104, 104, 103, 120, 119, 119, 119,
- 87, 86, 86, 71, 69, 69, 69, 69,
- 69, 68, 68, 68, 68, 68, 68, 68,
- 3, 190, 190, 104, 104, 104, 104, 104,
- 104, 103, 103, 103, 103, 103, 118, 118,
- 118, 86, 86, 69, 69, 69, 69, 69,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 3, 102, 102, 102, 102, 102, 102, 102,
- 103, 103, 103, 103, 103, 103, 100, 100,
- 118, 86, 86, 69, 69, 69, 69, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 102, 101, 101, 101, 101, 100, 100, 100,
- 100, 100, 99, 69, 69, 69, 68, 68,
- 68, 68, 68, 68, 68, 68, 67, 67,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 102, 101, 101, 101, 101, 100, 100, 100,
- 100, 99, 99, 99, 69, 68, 68, 68,
- 68, 68, 68, 68, 67, 206, 206, 206,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 102, 101, 101, 101, 101, 100, 100, 100,
- 100, 99, 99, 99, 210, 210, 68, 68,
- 68, 206, 206, 206, 206, 206, 206, 206,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 101, 101, 101, 101, 100, 100, 100, 100,
- 100, 99, 99, 99, 99, 210, 206, 206,
- 206, 206, 206, 206, 206, 206, 206, 206,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 101, 101, 101, 101, 100, 100, 100, 100,
- 99, 99, 99, 99, 99, 206, 206, 206,
- 206, 206, 206, 206, 206, 206, 206, 205,
- 102, 102, 102, 102, 102, 102, 102, 101,
- 101, 101, 101, 101, 100, 100, 100, 100,
- 99, 99, 99, 98, 98, 206, 206, 206,
- 206, 206, 206, 206, 206, 206, 205, 205,
- 102, 102, 102, 102, 102, 102, 102, 101,
- 101, 101, 101, 101, 100, 100, 100, 100,
- 99, 98, 98, 98, 98, 206, 206, 206,
- 206, 206, 206, 206, 206, 205, 205, 205,
- 102, 102, 102, 102, 102, 102, 102, 101,
- 101, 101, 101, 100, 100, 100, 100, 99,
- 98, 98, 98, 98, 98, 206, 206, 206,
- 206, 206, 206, 206, 205, 205, 205, 205,
- 250, 102, 102, 102, 102, 102, 101, 101,
- 101, 101, 101, 100, 100, 100, 100, 98,
- 98, 98, 98, 98, 98, 206, 206, 206,
- 206, 206, 206, 205, 205, 205, 205, 205,
- 250, 250, 102, 102, 102, 102, 101, 101,
- 101, 101, 101, 100, 100, 100, 98, 98,
- 98, 98, 98, 98, 98, 206, 206, 206,
- 206, 206, 205, 205, 205, 205, 205, 205,
- 243, 243, 243, 244, 244, 244, 222, 222,
- 222, 222, 222, 221, 221, 221, 221, 221,
- 220, 220, 5, 5, 5, 5, 5, 54,
- 54, 54, 54, 54, 54, 53, 53, 53,
- 243, 243, 244, 244, 244, 223, 222, 222,
- 222, 222, 222, 221, 221, 221, 221, 220,
- 220, 220, 220, 5, 5, 55, 55, 54,
- 54, 54, 54, 54, 53, 53, 53, 53,
- 243, 244, 244, 244, 244, 223, 222, 222,
- 222, 222, 221, 221, 221, 221, 221, 220,
- 220, 220, 220, 220, 219, 55, 54, 54,
- 54, 54, 54, 53, 53, 53, 53, 53,
- 244, 244, 244, 244, 244, 141, 222, 222,
- 222, 222, 221, 221, 221, 221, 221, 220,
- 220, 220, 220, 220, 55, 55, 54, 54,
- 54, 54, 53, 53, 53, 53, 53, 53,
- 244, 244, 244, 244, 141, 141, 141, 222,
- 222, 222, 221, 221, 221, 221, 221, 220,
- 220, 220, 220, 55, 55, 55, 54, 54,
- 54, 53, 53, 53, 53, 53, 53, 53,
- 244, 244, 244, 141, 141, 141, 140, 140,
- 140, 222, 221, 221, 221, 221, 221, 220,
- 220, 220, 220, 55, 55, 55, 54, 54,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 244, 141, 141, 141, 140, 140, 140, 140,
- 140, 40, 40, 39, 221, 221, 221, 220,
- 220, 220, 55, 55, 55, 54, 54, 53,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 191, 201, 201, 201, 140, 140, 140, 140,
- 139, 139, 39, 39, 38, 90, 14, 14,
- 14, 14, 55, 55, 55, 54, 53, 53,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 191, 191, 201, 201, 140, 140, 140, 139,
- 139, 139, 39, 38, 38, 90, 14, 14,
- 14, 14, 73, 73, 55, 53, 53, 53,
- 53, 53, 53, 53, 53, 52, 52, 52,
- 191, 191, 191, 201, 156, 156, 139, 139,
- 139, 39, 38, 38, 90, 14, 14, 14,
- 14, 88, 88, 72, 72, 53, 53, 53,
- 53, 52, 52, 52, 52, 52, 52, 52,
- 191, 191, 191, 191, 156, 156, 155, 155,
- 155, 38, 38, 38, 90, 14, 14, 14,
- 88, 88, 88, 72, 72, 72, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52,
- 191, 191, 191, 191, 155, 155, 155, 155,
- 155, 122, 38, 37, 37, 89, 89, 88,
- 88, 88, 88, 72, 72, 71, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52,
- 191, 191, 191, 191, 191, 155, 155, 155,
- 122, 122, 122, 37, 37, 89, 89, 88,
- 88, 88, 88, 72, 72, 71, 71, 52,
- 52, 52, 52, 52, 52, 52, 51, 51,
- 191, 191, 191, 191, 191, 155, 155, 122,
- 122, 122, 121, 121, 89, 89, 88, 88,
- 88, 88, 87, 72, 71, 71, 71, 71,
- 52, 52, 52, 51, 51, 51, 51, 51,
- 191, 191, 191, 191, 191, 155, 154, 122,
- 121, 121, 121, 121, 121, 89, 88, 88,
- 88, 87, 87, 71, 71, 71, 71, 70,
- 70, 51, 51, 51, 51, 51, 51, 51,
- 191, 191, 191, 191, 191, 191, 121, 121,
- 121, 121, 121, 121, 120, 120, 88, 88,
- 87, 87, 87, 87, 71, 71, 71, 69,
- 69, 69, 51, 51, 51, 51, 51, 50,
- 191, 190, 190, 190, 190, 190, 121, 121,
- 121, 121, 120, 120, 120, 120, 88, 87,
- 87, 87, 87, 86, 71, 71, 69, 69,
- 69, 69, 69, 68, 51, 50, 50, 50,
- 190, 190, 190, 190, 190, 190, 121, 121,
- 121, 120, 120, 120, 120, 120, 119, 87,
- 87, 87, 86, 86, 71, 69, 69, 69,
- 69, 69, 68, 68, 68, 68, 50, 50,
- 190, 190, 190, 190, 190, 105, 104, 120,
- 120, 120, 120, 120, 120, 119, 119, 87,
- 87, 86, 86, 86, 69, 69, 69, 69,
- 69, 68, 68, 68, 68, 68, 68, 50,
- 3, 190, 190, 190, 104, 104, 104, 104,
- 104, 120, 120, 119, 119, 119, 119, 118,
- 87, 86, 86, 86, 69, 69, 69, 69,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 3, 3, 190, 190, 104, 104, 104, 104,
- 104, 103, 103, 119, 119, 118, 118, 118,
- 118, 86, 86, 86, 69, 69, 69, 68,
- 68, 68, 68, 68, 68, 68, 68, 67,
- 3, 3, 189, 102, 102, 102, 102, 102,
- 102, 101, 101, 101, 101, 100, 118, 118,
- 118, 117, 86, 85, 69, 69, 68, 68,
- 68, 68, 68, 68, 68, 67, 67, 67,
- 3, 189, 102, 102, 102, 102, 102, 102,
- 101, 101, 101, 101, 100, 100, 100, 100,
- 100, 99, 99, 85, 69, 68, 68, 68,
- 68, 68, 68, 67, 67, 67, 67, 67,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 101, 101, 101, 101, 100, 100, 100, 100,
- 99, 99, 99, 99, 68, 68, 68, 68,
- 68, 67, 67, 67, 67, 67, 67, 205,
- 102, 102, 102, 102, 102, 102, 102, 102,
- 101, 101, 101, 101, 100, 100, 100, 100,
- 99, 99, 99, 99, 99, 68, 68, 67,
- 67, 67, 67, 206, 206, 206, 205, 205,
- 102, 102, 102, 102, 102, 102, 102, 101,
- 101, 101, 101, 100, 100, 100, 100, 100,
- 99, 99, 99, 99, 99, 98, 67, 67,
- 206, 206, 206, 206, 206, 205, 205, 205,
- 102, 102, 102, 102, 102, 102, 102, 101,
- 101, 101, 101, 100, 100, 100, 100, 99,
- 99, 99, 99, 99, 98, 98, 206, 206,
- 206, 206, 206, 206, 205, 205, 205, 205,
- 102, 102, 102, 102, 102, 102, 101, 101,
- 101, 101, 101, 100, 100, 100, 100, 99,
- 99, 99, 98, 98, 98, 98, 206, 206,
- 206, 206, 206, 205, 205, 205, 205, 205,
- 102, 102, 102, 102, 102, 102, 101, 101,
- 101, 101, 101, 100, 100, 100, 100, 99,
- 98, 98, 98, 98, 98, 98, 206, 206,
- 206, 206, 205, 205, 205, 205, 205, 205,
- 102, 102, 102, 102, 102, 102, 101, 101,
- 101, 101, 100, 100, 100, 100, 99, 98,
- 98, 98, 98, 98, 98, 97, 206, 206,
- 206, 205, 205, 205, 205, 205, 205, 205,
- 102, 102, 102, 102, 102, 101, 101, 101,
- 101, 101, 100, 100, 100, 100, 98, 98,
- 98, 98, 98, 98, 98, 97, 206, 206,
- 205, 205, 205, 205, 205, 205, 205, 205,
- 250, 102, 102, 102, 102, 101, 101, 101,
- 101, 101, 100, 100, 100, 98, 98, 98,
- 98, 98, 98, 98, 98, 97, 206, 205,
- 205, 205, 205, 205, 205, 205, 205, 205,
- 243, 243, 243, 243, 243, 243, 222, 222,
- 222, 222, 221, 221, 221, 221, 221, 220,
- 220, 5, 5, 5, 5, 5, 5, 5,
- 54, 54, 54, 54, 53, 53, 53, 53,
- 243, 243, 243, 243, 243, 243, 222, 222,
- 222, 222, 221, 221, 221, 221, 220, 220,
- 220, 220, 5, 5, 5, 5, 219, 54,
- 54, 54, 54, 53, 53, 53, 53, 53,
- 243, 243, 243, 243, 243, 243, 222, 222,
- 222, 221, 221, 221, 221, 221, 220, 220,
- 220, 220, 220, 219, 219, 219, 219, 54,
- 54, 54, 53, 53, 53, 53, 53, 53,
- 243, 243, 243, 243, 175, 175, 222, 222,
- 222, 221, 221, 221, 221, 221, 220, 220,
- 220, 220, 220, 219, 219, 219, 54, 54,
- 54, 53, 53, 53, 53, 53, 53, 53,
- 243, 243, 243, 175, 175, 201, 140, 222,
- 222, 221, 221, 221, 221, 221, 220, 220,
- 220, 220, 220, 219, 219, 55, 54, 54,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 243, 243, 175, 175, 201, 201, 201, 140,
- 140, 221, 221, 221, 221, 221, 220, 220,
- 220, 220, 220, 219, 219, 54, 54, 53,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 175, 175, 201, 201, 201, 201, 201, 140,
- 139, 139, 139, 221, 221, 221, 220, 220,
- 220, 220, 219, 219, 55, 54, 53, 53,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 191, 201, 201, 201, 201, 201, 201, 139,
- 139, 139, 139, 38, 14, 14, 14, 14,
- 14, 14, 14, 55, 55, 53, 53, 53,
- 53, 53, 53, 53, 53, 52, 52, 52,
- 191, 191, 201, 201, 201, 201, 201, 139,
- 139, 139, 38, 38, 14, 14, 14, 14,
- 14, 14, 14, 88, 53, 53, 53, 53,
- 53, 52, 52, 52, 52, 52, 52, 52,
- 191, 191, 191, 201, 201, 201, 201, 139,
- 139, 139, 38, 38, 14, 14, 14, 14,
- 14, 14, 88, 88, 72, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52,
- 191, 191, 191, 191, 201, 201, 155, 155,
- 155, 138, 38, 37, 14, 14, 14, 14,
- 14, 88, 88, 88, 72, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52,
- 191, 191, 191, 191, 201, 155, 155, 155,
- 138, 138, 37, 37, 37, 14, 14, 14,
- 88, 88, 88, 88, 72, 71, 52, 52,
- 52, 52, 52, 52, 52, 52, 51, 51,
- 191, 191, 191, 191, 191, 155, 155, 154,
- 154, 154, 37, 37, 36, 36, 89, 88,
- 88, 88, 87, 87, 71, 71, 52, 52,
- 52, 52, 52, 51, 51, 51, 51, 51,
- 191, 191, 191, 191, 191, 155, 154, 154,
- 154, 154, 121, 36, 36, 36, 88, 88,
- 88, 87, 87, 87, 71, 71, 71, 51,
- 51, 51, 51, 51, 51, 51, 51, 51,
- 191, 191, 191, 191, 191, 154, 154, 154,
- 121, 121, 121, 121, 36, 35, 88, 88,
- 87, 87, 87, 87, 86, 71, 71, 69,
- 51, 51, 51, 51, 51, 51, 51, 50,
- 191, 190, 190, 190, 190, 190, 154, 121,
- 121, 121, 120, 120, 120, 120, 88, 87,
- 87, 87, 87, 86, 86, 71, 69, 69,
- 69, 69, 51, 51, 51, 50, 50, 50,
- 190, 190, 190, 190, 190, 190, 121, 121,
- 121, 120, 120, 120, 120, 120, 119, 87,
- 87, 87, 86, 86, 86, 69, 69, 69,
- 69, 69, 68, 50, 50, 50, 50, 50,
- 190, 190, 190, 190, 190, 190, 121, 120,
- 120, 120, 120, 120, 120, 119, 119, 87,
- 87, 86, 86, 86, 86, 69, 69, 69,
- 69, 68, 68, 68, 68, 50, 50, 50,
- 3, 190, 190, 190, 190, 190, 120, 120,
- 120, 120, 120, 119, 119, 119, 119, 118,
- 87, 86, 86, 86, 86, 69, 69, 69,
- 68, 68, 68, 68, 68, 68, 50, 50,
- 3, 3, 190, 190, 190, 190, 104, 120,
- 120, 120, 119, 119, 119, 119, 118, 118,
- 118, 86, 86, 86, 85, 69, 69, 68,
- 68, 68, 68, 68, 68, 68, 67, 67,
- 3, 3, 189, 189, 189, 102, 104, 104,
- 103, 119, 119, 119, 118, 118, 118, 118,
- 118, 86, 86, 85, 85, 69, 68, 68,
- 68, 68, 68, 68, 67, 67, 67, 67,
- 3, 189, 189, 189, 102, 102, 102, 102,
- 101, 101, 101, 101, 118, 118, 118, 118,
- 117, 117, 85, 85, 85, 68, 68, 68,
- 68, 68, 67, 67, 67, 67, 67, 67,
- 3, 189, 189, 102, 102, 102, 102, 101,
- 101, 101, 101, 100, 100, 100, 100, 100,
- 99, 99, 117, 85, 85, 68, 68, 68,
- 67, 67, 67, 67, 67, 67, 67, 67,
- 189, 189, 102, 102, 102, 102, 102, 101,
- 101, 101, 101, 100, 100, 100, 100, 99,
- 99, 99, 99, 99, 84, 68, 67, 67,
- 67, 67, 67, 67, 67, 67, 66, 66,
- 189, 102, 102, 102, 102, 102, 102, 101,
- 101, 101, 101, 100, 100, 100, 100, 99,
- 99, 99, 99, 99, 99, 67, 67, 67,
- 67, 67, 67, 67, 66, 205, 205, 205,
- 102, 102, 102, 102, 102, 102, 101, 101,
- 101, 101, 100, 100, 100, 100, 100, 99,
- 99, 99, 99, 99, 98, 97, 67, 67,
- 67, 67, 205, 205, 205, 205, 205, 205,
- 102, 102, 102, 102, 102, 102, 101, 101,
- 101, 101, 100, 100, 100, 100, 99, 99,
- 99, 99, 99, 98, 98, 97, 97, 206,
- 205, 205, 205, 205, 205, 205, 205, 205,
- 102, 102, 102, 102, 102, 101, 101, 101,
- 101, 101, 100, 100, 100, 100, 99, 99,
- 99, 98, 98, 98, 98, 97, 97, 205,
- 205, 205, 205, 205, 205, 205, 205, 205,
- 102, 102, 102, 102, 102, 101, 101, 101,
- 101, 101, 100, 100, 100, 100, 99, 98,
- 98, 98, 98, 98, 98, 97, 97, 205,
- 205, 205, 205, 205, 205, 205, 205, 204,
- 102, 102, 102, 102, 102, 101, 101, 101,
- 101, 100, 100, 100, 100, 99, 98, 98,
- 98, 98, 98, 98, 97, 97, 205, 205,
- 205, 205, 205, 205, 205, 205, 204, 204,
- 102, 102, 102, 102, 101, 101, 101, 101,
- 101, 100, 100, 100, 100, 98, 98, 98,
- 98, 98, 98, 98, 97, 97, 205, 205,
- 205, 205, 205, 205, 205, 204, 204, 204,
- 102, 102, 102, 102, 101, 101, 101, 101,
- 101, 100, 100, 100, 98, 98, 98, 98,
- 98, 98, 98, 98, 97, 97, 205, 205,
- 205, 205, 205, 205, 204, 204, 204, 204,
- 242, 242, 242, 242, 242, 242, 222, 222,
- 222, 221, 221, 221, 221, 221, 220, 220,
- 5, 5, 5, 5, 5, 5, 5, 218,
- 218, 218, 218, 53, 53, 53, 53, 53,
- 242, 242, 242, 242, 242, 175, 222, 222,
- 222, 221, 221, 221, 221, 220, 220, 220,
- 220, 5, 5, 5, 5, 219, 219, 218,
- 218, 218, 53, 53, 53, 53, 53, 53,
- 242, 242, 242, 242, 175, 175, 175, 222,
- 221, 221, 221, 221, 221, 220, 220, 220,
- 220, 220, 219, 219, 219, 219, 219, 218,
- 218, 53, 53, 53, 53, 53, 53, 53,
- 242, 242, 242, 175, 175, 175, 175, 222,
- 221, 221, 221, 221, 221, 220, 220, 220,
- 220, 220, 219, 219, 219, 219, 218, 218,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 242, 175, 175, 175, 175, 175, 201, 201,
- 221, 221, 221, 221, 221, 220, 220, 220,
- 220, 220, 219, 219, 219, 219, 218, 53,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 175, 175, 175, 175, 175, 201, 201, 201,
- 201, 221, 221, 221, 221, 220, 220, 220,
- 220, 220, 219, 219, 219, 219, 53, 53,
- 53, 53, 53, 53, 53, 53, 53, 53,
- 175, 175, 175, 201, 201, 201, 201, 201,
- 201, 139, 139, 221, 221, 220, 220, 220,
- 220, 219, 219, 219, 219, 219, 53, 53,
- 53, 53, 53, 53, 53, 52, 52, 52,
- 175, 201, 201, 201, 201, 201, 201, 201,
- 139, 139, 139, 38, 14, 14, 14, 14,
- 14, 14, 219, 219, 219, 53, 53, 53,
- 53, 52, 52, 52, 52, 52, 52, 52,
- 191, 191, 201, 201, 201, 201, 201, 201,
- 139, 138, 138, 14, 14, 14, 14, 14,
- 14, 14, 14, 13, 53, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52,
- 191, 191, 191, 201, 201, 201, 201, 201,
- 138, 138, 138, 14, 14, 14, 14, 14,
- 14, 14, 88, 13, 13, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52,
- 191, 191, 191, 201, 201, 201, 201, 138,
- 138, 138, 138, 37, 14, 14, 14, 14,
- 14, 88, 88, 13, 13, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 51, 51,
- 191, 191, 191, 191, 201, 201, 155, 138,
- 138, 138, 138, 37, 14, 14, 14, 14,
- 88, 88, 13, 87, 87, 52, 52, 52,
- 52, 52, 52, 51, 51, 51, 51, 51,
- 191, 191, 191, 191, 191, 155, 154, 154,
- 154, 154, 137, 36, 36, 36, 35, 88,
- 88, 88, 87, 87, 87, 86, 52, 51,
- 51, 51, 51, 51, 51, 51, 51, 51,
- 191, 191, 191, 191, 191, 154, 154, 154,
- 154, 154, 153, 36, 36, 35, 35, 88,
- 88, 87, 87, 87, 86, 86, 51, 51,
- 51, 51, 51, 51, 51, 51, 51, 50,
- 191, 190, 190, 190, 190, 154, 154, 154,
- 154, 153, 153, 120, 35, 35, 35, 34,
- 87, 87, 87, 86, 86, 86, 69, 51,
- 51, 51, 51, 51, 51, 50, 50, 50,
- 190, 190, 190, 190, 190, 190, 154, 153,
- 153, 120, 120, 120, 120, 35, 34, 87,
- 87, 87, 86, 86, 86, 86, 69, 69,
- 69, 51, 51, 50, 50, 50, 50, 50,
- 190, 190, 190, 190, 190, 190, 153, 153,
- 120, 120, 120, 120, 120, 119, 34, 87,
- 87, 86, 86, 86, 86, 85, 69, 69,
- 69, 68, 50, 50, 50, 50, 50, 50,
- 3, 190, 190, 190, 190, 190, 120, 120,
- 120, 120, 120, 119, 119, 119, 119, 87,
- 87, 86, 86, 86, 85, 85, 69, 69,
- 68, 68, 68, 68, 50, 50, 50, 50,
- 3, 3, 190, 190, 190, 190, 120, 120,
- 120, 120, 119, 119, 119, 119, 118, 118,
- 86, 86, 86, 85, 85, 85, 69, 68,
- 68, 68, 68, 68, 68, 67, 49, 49,
- 3, 3, 189, 189, 189, 189, 120, 120,
- 120, 119, 119, 119, 119, 118, 118, 118,
- 118, 86, 85, 85, 85, 85, 68, 68,
- 68, 68, 68, 67, 67, 67, 67, 49,
- 3, 189, 189, 189, 189, 189, 102, 120,
- 119, 119, 119, 119, 118, 118, 118, 118,
- 117, 117, 85, 85, 85, 85, 68, 68,
- 68, 67, 67, 67, 67, 67, 67, 67,
- 3, 189, 189, 189, 189, 102, 102, 101,
- 101, 101, 118, 118, 118, 118, 118, 118,
- 117, 117, 85, 85, 85, 84, 68, 67,
- 67, 67, 67, 67, 67, 67, 67, 66,
- 189, 189, 189, 189, 102, 102, 101, 101,
- 101, 101, 100, 100, 100, 100, 100, 117,
- 117, 117, 116, 84, 84, 84, 67, 67,
- 67, 67, 67, 67, 67, 66, 66, 66,
- 189, 189, 189, 102, 102, 102, 101, 101,
- 101, 101, 100, 100, 100, 100, 99, 99,
- 99, 99, 99, 116, 84, 67, 67, 67,
- 67, 67, 67, 67, 66, 66, 66, 66,
- 188, 188, 102, 102, 102, 102, 101, 101,
- 101, 101, 100, 100, 100, 100, 99, 99,
- 99, 99, 99, 99, 99, 67, 67, 67,
- 67, 67, 66, 66, 66, 66, 66, 204,
- 188, 188, 102, 102, 102, 101, 101, 101,
- 101, 100, 100, 100, 100, 100, 99, 99,
- 99, 99, 99, 98, 97, 97, 67, 67,
- 66, 66, 66, 204, 204, 204, 204, 204,
- 188, 102, 102, 102, 102, 101, 101, 101,
- 101, 100, 100, 100, 100, 99, 99, 99,
- 99, 99, 98, 98, 97, 97, 97, 66,
- 204, 204, 204, 204, 204, 204, 204, 204,
- 102, 102, 102, 102, 101, 101, 101, 101,
- 101, 100, 100, 100, 100, 99, 99, 99,
- 98, 98, 98, 98, 97, 97, 97, 204,
- 204, 204, 204, 204, 204, 204, 204, 204,
- 102, 102, 102, 102, 101, 101, 101, 101,
- 101, 100, 100, 100, 100, 99, 98, 98,
- 98, 98, 98, 98, 97, 97, 97, 204,
- 204, 204, 204, 204, 204, 204, 204, 204,
- 102, 102, 102, 102, 101, 101, 101, 101,
- 100, 100, 100, 100, 99, 98, 98, 98,
- 98, 98, 98, 97, 97, 97, 97, 204,
- 204, 204, 204, 204, 204, 204, 204, 204,
- 102, 102, 102, 101, 101, 101, 101, 101,
- 100, 100, 100, 100, 98, 98, 98, 98,
- 98, 98, 98, 97, 97, 97, 97, 204,
- 204, 204, 204, 204, 204, 204, 204, 204,
- 102, 102, 102, 101, 101, 101, 101, 101,
- 100, 100, 100, 98, 98, 98, 98, 98,
- 98, 98, 98, 97, 97, 97, 97, 204,
- 204, 204, 204, 204, 204, 204, 204, 204,
- 242, 242, 241, 241, 241, 241, 175, 222,
- 221, 221, 221, 221, 221, 220, 220, 5,
- 5, 5, 5, 5, 5, 5, 218, 218,
- 218, 218, 217, 217, 217, 53, 53, 53,
- 242, 241, 241, 241, 175, 175, 175, 222,
- 221, 221, 221, 221, 220, 220, 220, 220,
- 5, 5, 5, 5, 219, 219, 218, 218,
- 218, 218, 217, 217, 53, 53, 53, 53,
- 241, 241, 241, 175, 175, 175, 175, 175,
- 221, 221, 221, 221, 220, 220, 220, 220,
- 220, 219, 219, 219, 219, 219, 218, 218,
- 218, 218, 53, 53, 53, 53, 53, 53,
- 241, 241, 175, 175, 175, 175, 175, 175,
- 221, 221, 221, 221, 220, 220, 220, 220,
- 220, 219, 219, 219, 219, 218, 218, 218,
- 218, 53, 53, 53, 53, 53, 53, 53,
- 175, 175, 175, 175, 175, 175, 175, 201,
- 221, 221, 221, 221, 220, 220, 220, 220,
- 220, 219, 219, 219, 219, 218, 218, 218,
- 218, 53, 53, 53, 53, 53, 53, 53,
- 175, 175, 175, 175, 175, 175, 201, 201,
- 201, 221, 221, 221, 220, 220, 220, 220,
- 220, 219, 219, 219, 219, 218, 218, 218,
- 53, 53, 53, 53, 53, 52, 52, 52,
- 175, 175, 175, 175, 201, 201, 201, 201,
- 201, 201, 139, 221, 220, 220, 220, 220,
- 219, 219, 219, 219, 219, 218, 218, 53,
- 53, 52, 52, 52, 52, 52, 52, 52,
- 175, 175, 201, 201, 201, 201, 201, 201,
- 201, 138, 138, 14, 14, 14, 14, 14,
- 14, 219, 219, 219, 219, 218, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52,
- 191, 191, 201, 201, 201, 201, 201, 201,
- 201, 138, 138, 14, 14, 14, 14, 14,
- 14, 14, 13, 13, 13, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52,
- 191, 191, 201, 201, 201, 201, 201, 201,
- 138, 138, 138, 14, 14, 14, 14, 14,
- 14, 14, 13, 13, 13, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 51, 51,
- 191, 191, 191, 201, 201, 201, 201, 138,
- 138, 138, 138, 137, 14, 14, 14, 14,
- 14, 13, 13, 13, 13, 52, 52, 52,
- 52, 52, 52, 51, 51, 51, 51, 51,
- 191, 191, 191, 191, 201, 200, 200, 138,
- 138, 137, 137, 137, 14, 14, 14, 14,
- 13, 13, 13, 13, 13, 13, 52, 51,
- 51, 51, 51, 51, 51, 51, 51, 51,
- 191, 191, 191, 191, 191, 200, 154, 154,
- 154, 137, 137, 137, 36, 35, 35, 13,
- 13, 13, 13, 13, 86, 86, 51, 51,
- 51, 51, 51, 51, 51, 51, 51, 50,
- 191, 190, 190, 190, 190, 200, 154, 154,
- 153, 153, 153, 153, 35, 35, 35, 34,
- 13, 13, 13, 86, 86, 86, 51, 51,
- 51, 51, 51, 51, 51, 50, 50, 50,
- 190, 190, 190, 190, 190, 190, 154, 153,
- 153, 153, 153, 153, 35, 35, 34, 34,
- 13, 87, 86, 86, 86, 86, 85, 51,
- 51, 51, 51, 50, 50, 50, 50, 50,
- 190, 190, 190, 190, 190, 190, 153, 153,
- 153, 153, 153, 120, 120, 34, 34, 33,
- 87, 86, 86, 86, 86, 85, 85, 69,
- 51, 51, 50, 50, 50, 50, 50, 50,
- 3, 190, 190, 190, 190, 190, 153, 153,
- 153, 120, 120, 119, 119, 119, 33, 33,
- 33, 86, 86, 86, 85, 85, 85, 69,
- 68, 50, 50, 50, 50, 50, 50, 50,
- 3, 3, 190, 190, 190, 190, 153, 153,
- 120, 120, 119, 119, 119, 119, 119, 33,
- 86, 86, 86, 85, 85, 85, 85, 68,
- 68, 68, 68, 50, 50, 50, 49, 49,
- 3, 3, 189, 189, 189, 189, 189, 120,
- 120, 119, 119, 119, 119, 118, 118, 118,
- 86, 86, 85, 85, 85, 85, 85, 68,
- 68, 67, 67, 67, 67, 49, 49, 49,
- 3, 189, 189, 189, 189, 189, 189, 120,
- 119, 119, 119, 119, 118, 118, 118, 118,
- 117, 85, 85, 85, 85, 85, 84, 67,
- 67, 67, 67, 67, 67, 67, 49, 49,
- 3, 189, 189, 189, 189, 189, 189, 119,
- 119, 119, 119, 118, 118, 118, 118, 117,
- 117, 117, 85, 85, 85, 84, 84, 67,
- 67, 67, 67, 67, 67, 67, 66, 66,
- 189, 189, 189, 189, 189, 189, 189, 101,
- 101, 118, 118, 118, 118, 118, 118, 117,
- 117, 117, 116, 84, 84, 84, 67, 67,
- 67, 67, 67, 67, 67, 66, 66, 66,
- 189, 189, 189, 189, 189, 189, 101, 101,
- 101, 100, 100, 100, 100, 118, 117, 117,
- 117, 116, 116, 116, 84, 84, 67, 67,
- 67, 67, 67, 66, 66, 66, 66, 66,
- 188, 188, 188, 188, 188, 101, 101, 101,
- 101, 100, 100, 100, 100, 99, 99, 99,
- 99, 116, 116, 116, 84, 84, 67, 67,
- 67, 66, 66, 66, 66, 66, 66, 66,
- 188, 188, 188, 188, 102, 101, 101, 101,
- 101, 100, 100, 100, 100, 99, 99, 99,
- 99, 99, 99, 99, 115, 83, 67, 66,
- 66, 66, 66, 66, 66, 66, 66, 66,
- 188, 188, 188, 188, 101, 101, 101, 101,
- 100, 100, 100, 100, 100, 99, 99, 99,
- 99, 99, 98, 97, 97, 97, 66, 66,
- 66, 66, 66, 66, 66, 204, 204, 204,
- 188, 188, 188, 102, 101, 101, 101, 101,
- 100, 100, 100, 100, 99, 99, 99, 99,
- 99, 98, 98, 97, 97, 97, 97, 66,
- 66, 204, 204, 204, 204, 204, 204, 204,
- 188, 188, 102, 101, 101, 101, 101, 101,
- 100, 100, 100, 100, 99, 99, 99, 98,
- 98, 98, 98, 97, 97, 97, 97, 96,
- 204, 204, 204, 204, 204, 204, 204, 204,
- 187, 187, 102, 101, 101, 101, 101, 101,
- 100, 100, 100, 100, 99, 98, 98, 98,
- 98, 98, 98, 97, 97, 97, 97, 204,
- 204, 204, 204, 204, 204, 204, 204, 204,
- 187, 102, 102, 101, 101, 101, 101, 100,
- 100, 100, 100, 99, 98, 98, 98, 98,
- 98, 98, 97, 97, 97, 97, 97, 204,
- 204, 204, 204, 204, 204, 204, 204, 204,
- 187, 102, 101, 101, 101, 101, 101, 100,
- 100, 100, 100, 98, 98, 98, 98, 98,
- 98, 98, 97, 97, 97, 97, 96, 204,
- 204, 204, 204, 204, 204, 204, 204, 204,
- 187, 102, 101, 101, 101, 101, 101, 100,
- 100, 100, 98, 98, 98, 98, 98, 98,
- 98, 98, 97, 97, 97, 97, 96, 204,
- 204, 204, 204, 204, 204, 204, 204, 203,
- 241, 241, 241, 241, 241, 175, 175, 175,
- 221, 221, 221, 221, 220, 220, 5, 5,
- 5, 5, 5, 5, 5, 218, 218, 218,
- 218, 217, 217, 217, 217, 217, 216, 216,
- 241, 241, 241, 241, 175, 175, 175, 175,
- 221, 221, 221, 220, 220, 220, 220, 5,
- 5, 5, 5, 219, 219, 218, 218, 218,
- 218, 217, 217, 217, 217, 217, 53, 53,
- 241, 241, 175, 175, 175, 175, 175, 175,
- 221, 221, 221, 220, 220, 220, 220, 220,
- 219, 219, 219, 219, 219, 218, 218, 218,
- 218, 217, 217, 217, 217, 53, 53, 53,
- 241, 175, 175, 175, 175, 175, 175, 175,
- 221, 221, 221, 220, 220, 220, 220, 220,
- 219, 219, 219, 219, 218, 218, 218, 218,
- 218, 217, 217, 217, 53, 53, 53, 53,
- 175, 175, 175, 175, 175, 175, 175, 175,
- 201, 221, 221, 220, 220, 220, 220, 220,
- 219, 219, 219, 219, 218, 218, 218, 218,
- 218, 217, 53, 53, 53, 52, 52, 52,
- 175, 175, 175, 175, 175, 175, 175, 201,
- 201, 201, 221, 220, 220, 220, 220, 220,
- 219, 219, 219, 219, 218, 218, 218, 218,
- 218, 52, 52, 52, 52, 52, 52, 52,
- 175, 175, 175, 175, 175, 201, 201, 201,
- 201, 201, 138, 220, 220, 220, 220, 219,
- 219, 219, 219, 219, 218, 218, 218, 218,
- 52, 52, 52, 52, 52, 52, 52, 52,
- 175, 175, 175, 201, 201, 201, 201, 201,
- 201, 201, 138, 138, 14, 14, 14, 14,
- 219, 219, 219, 219, 218, 218, 218, 52,
- 52, 52, 52, 52, 52, 52, 52, 52,
- 191, 201, 201, 201, 201, 201, 201, 201,
- 200, 138, 138, 138, 14, 14, 14, 14,
- 14, 13, 13, 13, 218, 218, 52, 52,
- 52, 52, 52, 52, 52, 52, 51, 51,
- 191, 191, 201, 201, 201, 201, 200, 200,
- 200, 138, 137, 137, 14, 14, 14, 14,
- 14, 13, 13, 13, 13, 13, 52, 52,
- 52, 52, 52, 51, 51, 51, 51, 51,
- 191, 191, 191, 201, 201, 200, 200, 200,
- 200, 137, 137, 137, 14, 14, 14, 14,
- 13, 13, 13, 13, 13, 13, 52, 51,
- 51, 51, 51, 51, 51, 51, 51, 51,
- 191, 191, 191, 191, 200, 200, 200, 200,
- 137, 137, 137, 137, 14, 14, 14, 13,
- 13, 13, 13, 13, 13, 13, 51, 51,
- 51, 51, 51, 51, 51, 51, 51, 50,
- 191, 190, 190, 190, 200, 200, 200, 200,
- 137, 137, 137, 137, 136, 35, 13, 13,
- 13, 13, 13, 13, 13, 86, 51, 51,
- 51, 51, 51, 51, 51, 50, 50, 50,
- 190, 190, 190, 190, 190, 200, 200, 153,
- 153, 153, 153, 136, 136, 35, 34, 13,
- 13, 13, 13, 13, 86, 86, 85, 51,
- 51, 51, 51, 50, 50, 50, 50, 50,
- 190, 190, 190, 190, 190, 190, 153, 153,
- 153, 153, 153, 136, 136, 34, 34, 13,
- 13, 13, 86, 86, 86, 85, 85, 51,
- 51, 51, 50, 50, 50, 50, 50, 50,
- 3, 190, 190, 190, 190, 190, 153, 153,
- 153, 153, 152, 152, 152, 34, 33, 33,
- 33, 86, 86, 86, 85, 85, 85, 85,
- 50, 50, 50, 50, 50, 50, 50, 50,
- 3, 3, 190, 190, 190, 190, 153, 153,
- 152, 152, 152, 152, 119, 119, 33, 33,
- 32, 86, 86, 85, 85, 85, 85, 85,
- 50, 50, 50, 50, 50, 50, 49, 49,
- 3, 3, 189, 189, 189, 189, 189, 152,
- 152, 152, 119, 119, 119, 119, 118, 32,
- 32, 86, 85, 85, 85, 85, 85, 84,
- 67, 67, 49, 49, 49, 49, 49, 49,
- 3, 189, 189, 189, 189, 189, 189, 152,
- 152, 119, 119, 119, 118, 118, 118, 118,
- 32, 31, 85, 85, 85, 85, 84, 84,
- 67, 67, 67, 67, 49, 49, 49, 49,
- 3, 189, 189, 189, 189, 189, 189, 152,
- 119, 119, 119, 118, 118, 118, 118, 117,
- 117, 117, 85, 85, 85, 84, 84, 67,
- 67, 67, 67, 67, 67, 49, 49, 49,
- 189, 189, 189, 189, 189, 189, 189, 119,
- 119, 119, 118, 118, 118, 118, 117, 117,
- 117, 117, 85, 84, 84, 84, 84, 67,
- 67, 67, 67, 67, 66, 66, 66, 48,
- 189, 189, 189, 189, 189, 189, 189, 119,
- 118, 118, 118, 118, 118, 118, 117, 117,
- 117, 116, 116, 84, 84, 84, 84, 67,
- 67, 67, 66, 66, 66, 66, 66, 66,
- 188, 188, 188, 188, 188, 188, 188, 101,
- 100, 100, 100, 118, 118, 117, 117, 117,
- 116, 116, 116, 116, 84, 84, 83, 67,
- 66, 66, 66, 66, 66, 66, 66, 66,
- 188, 188, 188, 188, 188, 188, 101, 101,
- 100, 100, 100, 100, 99, 99, 99, 99,
- 116, 116, 116, 116, 115, 83, 83, 66,
- 66, 66, 66, 66, 66, 66, 66, 65,
- 188, 188, 188, 188, 188, 101, 101, 101,
- 100, 100, 100, 100, 99, 99, 99, 99,
- 99, 99, 116, 115, 115, 83, 83, 66,
- 66, 66, 66, 66, 66, 65, 65, 65,
- 188, 188, 188, 188, 188, 101, 101, 100,
- 100, 100, 100, 100, 99, 99, 99, 99,
- 99, 98, 97, 97, 97, 97, 83, 66,
- 66, 66, 66, 65, 65, 65, 65, 203,
- 188, 188, 188, 188, 101, 101, 101, 100,
- 100, 100, 100, 99, 99, 99, 99, 99,
- 98, 98, 97, 97, 97, 97, 96, 66,
- 65, 65, 65, 204, 204, 204, 203, 203,
- 187, 187, 187, 187, 101, 101, 101, 100,
- 100, 100, 100, 99, 99, 99, 98, 98,
- 98, 98, 97, 97, 97, 97, 96, 96,
- 204, 204, 204, 204, 204, 203, 203, 203,
- 187, 187, 187, 101, 101, 101, 101, 100,
- 100, 100, 100, 99, 98, 98, 98, 98,
- 98, 98, 97, 97, 97, 97, 96, 96,
- 204, 204, 204, 204, 203, 203, 203, 203,
- 187, 187, 187, 101, 101, 101, 100, 100,
- 100, 100, 99, 98, 98, 98, 98, 98,
- 98, 97, 97, 97, 97, 97, 96, 96,
- 204, 204, 204, 203, 203, 203, 203, 203,
- 187, 187, 187, 101, 101, 101, 100, 100,
- 100, 100, 98, 98, 98, 98, 98, 98,
- 98, 97, 97, 97, 97, 96, 96, 96,
- 204, 204, 203, 203, 203, 203, 203, 203,
- 187, 187, 101, 101, 101, 101, 100, 100,
- 100, 98, 98, 98, 98, 98, 98, 98,
- 98, 97, 97, 97, 97, 96, 96, 96,
- 204, 203, 203, 203, 203, 203, 203, 203,
- 1, 240, 240, 240, 240, 175, 175, 175,
- 221, 221, 221, 220, 220, 5, 5, 5,
- 5, 5, 5, 5, 218, 218, 218, 218,
- 217, 217, 217, 217, 217, 216, 216, 216,
- 240, 240, 240, 175, 175, 175, 175, 175,
- 221, 221, 220, 220, 220, 220, 5, 5,
- 5, 5, 219, 219, 218, 218, 218, 218,
- 217, 217, 217, 217, 217, 216, 216, 216,
- 240, 240, 175, 175, 175, 175, 175, 175,
- 175, 221, 220, 220, 220, 220, 220, 219,
- 219, 219, 219, 219, 218, 218, 218, 218,
- 217, 217, 217, 217, 217, 216, 216, 216,
- 240, 175, 175, 175, 175, 175, 175, 175,
- 175, 221, 220, 220, 220, 220, 220, 219,
- 219, 219, 219, 218, 218, 218, 218, 218,
- 217, 217, 217, 217, 217, 216, 216, 52,
- 175, 175, 175, 175, 175, 175, 175, 175,
- 175, 221, 220, 220, 220, 220, 220, 219,
- 219, 219, 219, 218, 218, 218, 218, 218,
- 217, 217, 217, 217, 217, 52, 52, 52,
- 175, 175, 175, 175, 175, 175, 175, 174,
- 201, 201, 220, 220, 220, 220, 220, 219,
- 219, 219, 219, 218, 218, 218, 218, 218,
- 217, 217, 217, 52, 52, 52, 52, 52,
- 175, 175, 175, 174, 174, 174, 201, 201,
- 201, 200, 200, 220, 220, 220, 219, 219,
- 219, 219, 219, 218, 218, 218, 218, 218,
- 217, 217, 52, 52, 52, 52, 52, 52,
- 174, 174, 174, 174, 174, 201, 201, 200,
- 200, 200, 200, 138, 14, 14, 14, 219,
- 219, 219, 219, 218, 218, 218, 218, 218,
- 52, 52, 52, 52, 52, 52, 51, 51,
- 174, 174, 174, 201, 201, 200, 200, 200,
- 200, 200, 200, 137, 14, 14, 14, 14,
- 13, 13, 13, 218, 218, 218, 218, 52,
- 52, 52, 52, 51, 51, 51, 51, 51,
- 191, 191, 201, 201, 200, 200, 200, 200,
- 200, 200, 137, 137, 14, 14, 14, 14,
- 13, 13, 13, 13, 13, 13, 52, 51,
- 51, 51, 51, 51, 51, 51, 51, 51,
- 191, 191, 191, 200, 200, 200, 200, 200,
- 200, 200, 137, 137, 136, 14, 14, 13,
- 13, 13, 13, 13, 13, 13, 51, 51,
- 51, 51, 51, 51, 51, 51, 51, 50,
- 191, 190, 190, 200, 200, 200, 200, 200,
- 200, 137, 137, 136, 136, 136, 13, 13,
- 13, 13, 13, 13, 13, 13, 51, 51,
- 51, 51, 51, 51, 51, 50, 50, 50,
- 190, 190, 190, 190, 200, 200, 200, 200,
- 137, 137, 136, 136, 136, 136, 13, 13,
- 13, 13, 13, 13, 13, 12, 12, 51,
- 51, 51, 51, 50, 50, 50, 50, 50,
- 190, 190, 190, 190, 190, 200, 200, 200,
- 153, 136, 136, 136, 136, 34, 13, 13,
- 13, 13, 13, 13, 12, 12, 12, 51,
- 51, 51, 50, 50, 50, 50, 50, 50,
- 3, 190, 190, 190, 190, 190, 200, 153,
- 153, 152, 136, 136, 136, 34, 33, 13,
- 13, 13, 13, 12, 12, 12, 85, 51,
- 50, 50, 50, 50, 50, 50, 50, 50,
- 3, 3, 190, 190, 190, 190, 153, 152,
- 152, 152, 152, 152, 152, 33, 33, 33,
- 32, 32, 32, 12, 85, 85, 85, 85,
- 50, 50, 50, 50, 50, 50, 49, 49,
- 3, 3, 189, 189, 189, 189, 152, 152,
- 152, 152, 152, 152, 151, 33, 33, 32,
- 32, 32, 31, 85, 85, 85, 85, 84,
- 50, 50, 49, 49, 49, 49, 49, 49,
- 3, 189, 189, 189, 189, 189, 189, 152,
- 152, 152, 152, 151, 119, 118, 118, 32,
- 32, 31, 85, 85, 85, 85, 84, 84,
- 67, 49, 49, 49, 49, 49, 49, 49,
- 3, 189, 189, 189, 189, 189, 189, 152,
- 152, 152, 151, 119, 118, 118, 118, 117,
- 31, 31, 85, 85, 84, 84, 84, 84,
- 67, 67, 67, 49, 49, 49, 49, 49,
- 189, 189, 189, 189, 189, 189, 189, 152,
- 152, 151, 118, 118, 118, 118, 117, 117,
- 117, 117, 85, 84, 84, 84, 84, 84,
- 67, 67, 67, 66, 49, 49, 48, 48,
- 189, 189, 189, 189, 189, 189, 189, 152,
- 151, 118, 118, 118, 118, 118, 117, 117,
- 117, 116, 116, 84, 84, 84, 84, 83,
- 67, 66, 66, 66, 66, 66, 48, 48,
- 188, 188, 188, 188, 188, 188, 188, 188,
- 118, 118, 118, 118, 118, 117, 117, 117,
- 116, 116, 116, 84, 84, 84, 83, 83,
- 66, 66, 66, 66, 66, 66, 66, 48,
- 188, 188, 188, 188, 188, 188, 188, 188,
- 118, 118, 118, 118, 117, 117, 117, 116,
- 116, 116, 116, 115, 83, 83, 83, 83,
- 66, 66, 66, 66, 66, 66, 65, 65,
- 188, 188, 188, 188, 188, 188, 188, 100,
- 100, 100, 100, 99, 99, 99, 117, 116,
- 116, 116, 116, 115, 115, 83, 83, 66,
- 66, 66, 66, 66, 65, 65, 65, 65,
- 188, 188, 188, 188, 188, 188, 188, 100,
- 100, 100, 100, 99, 99, 99, 99, 99,
- 99, 116, 115, 115, 115, 83, 83, 66,
- 66, 66, 65, 65, 65, 65, 65, 65,
- 188, 188, 188, 188, 188, 188, 100, 100,
- 100, 100, 100, 99, 99, 99, 99, 99,
- 98, 97, 97, 97, 97, 97, 83, 66,
- 65, 65, 65, 65, 65, 65, 65, 65,
- 187, 187, 187, 187, 187, 187, 100, 100,
- 100, 100, 99, 99, 99, 99, 99, 98,
- 98, 97, 97, 97, 97, 96, 96, 96,
- 65, 65, 65, 65, 65, 203, 203, 203,
- 187, 187, 187, 187, 187, 101, 100, 100,
- 100, 100, 99, 99, 99, 98, 98, 98,
- 98, 97, 97, 97, 97, 96, 96, 96,
- 65, 65, 203, 203, 203, 203, 203, 203,
- 187, 187, 187, 187, 187, 101, 100, 100,
- 100, 100, 99, 98, 98, 98, 98, 98,
- 98, 97, 97, 97, 97, 96, 96, 96,
- 96, 203, 203, 203, 203, 203, 203, 203,
- 187, 187, 187, 187, 187, 100, 100, 100,
- 100, 99, 98, 98, 98, 98, 98, 98,
- 97, 97, 97, 97, 97, 96, 96, 96,
- 203, 203, 203, 203, 203, 203, 203, 203,
- 187, 187, 187, 187, 101, 100, 100, 100,
- 100, 98, 98, 98, 98, 98, 98, 98,
- 97, 97, 97, 97, 96, 96, 96, 96,
- 203, 203, 203, 203, 203, 203, 203, 203,
- 186, 186, 186, 186, 101, 100, 100, 100,
- 98, 98, 98, 98, 98, 98, 98, 98,
- 97, 97, 97, 97, 96, 96, 96, 96,
- 203, 203, 203, 203, 203, 203, 203, 203,
- 1, 240, 240, 240, 240, 175, 175, 175,
- 175, 221, 220, 220, 5, 5, 5, 5,
- 5, 5, 5, 218, 218, 218, 218, 217,
- 217, 217, 217, 217, 216, 216, 216, 216,
- 240, 240, 240, 240, 175, 175, 175, 175,
- 175, 220, 220, 220, 220, 5, 5, 5,
- 5, 219, 219, 218, 218, 218, 218, 217,
- 217, 217, 217, 217, 216, 216, 216, 216,
- 240, 240, 175, 175, 175, 175, 175, 175,
- 175, 220, 220, 220, 220, 220, 219, 219,
- 219, 219, 219, 218, 218, 218, 218, 217,
- 217, 217, 217, 217, 216, 216, 216, 216,
- 240, 175, 175, 175, 175, 175, 175, 175,
- 175, 220, 220, 220, 220, 220, 219, 219,
- 219, 219, 218, 218, 218, 218, 218, 217,
- 217, 217, 217, 217, 216, 216, 216, 216,
- 175, 175, 175, 175, 175, 174, 174, 174,
- 174, 220, 220, 220, 220, 220, 219, 219,
- 219, 219, 218, 218, 218, 218, 218, 217,
- 217, 217, 217, 217, 216, 216, 216, 216,
- 175, 174, 174, 174, 174, 174, 174, 174,
- 174, 200, 220, 220, 220, 220, 219, 219,
- 219, 219, 218, 218, 218, 218, 218, 217,
- 217, 217, 217, 216, 216, 216, 52, 52,
- 174, 174, 174, 174, 174, 174, 174, 174,
- 200, 200, 200, 220, 220, 219, 219, 219,
- 219, 219, 218, 218, 218, 218, 218, 217,
- 217, 217, 217, 216, 52, 52, 51, 51,
- 174, 174, 174, 174, 174, 174, 200, 200,
- 200, 200, 200, 200, 14, 219, 219, 219,
- 219, 219, 218, 218, 218, 218, 218, 217,
- 217, 217, 52, 51, 51, 51, 51, 51,
- 174, 174, 174, 174, 174, 200, 200, 200,
- 200, 200, 200, 137, 137, 14, 14, 13,
- 13, 13, 218, 218, 218, 218, 218, 217,
- 51, 51, 51, 51, 51, 51, 51, 51,
- 173, 173, 173, 200, 200, 200, 200, 200,
- 200, 200, 200, 137, 136, 14, 14, 13,
- 13, 13, 13, 13, 13, 218, 217, 51,
- 51, 51, 51, 51, 51, 51, 51, 50,
- 191, 173, 200, 200, 200, 200, 200, 200,
- 200, 200, 137, 136, 136, 136, 13, 13,
- 13, 13, 13, 13, 13, 13, 51, 51,
- 51, 51, 51, 51, 51, 50, 50, 50,
- 190, 190, 190, 200, 200, 200, 200, 200,
- 200, 199, 136, 136, 136, 136, 13, 13,
- 13, 13, 13, 13, 13, 12, 12, 51,
- 51, 51, 51, 50, 50, 50, 50, 50,
- 190, 190, 190, 190, 200, 200, 200, 200,
- 199, 136, 136, 136, 136, 136, 13, 13,
- 13, 13, 13, 13, 12, 12, 12, 51,
- 51, 51, 50, 50, 50, 50, 50, 50,
- 3, 190, 190, 190, 200, 200, 199, 199,
- 199, 136, 136, 136, 136, 136, 13, 13,
- 13, 13, 13, 12, 12, 12, 12, 12,
- 50, 50, 50, 50, 50, 50, 50, 50,
- 3, 3, 190, 190, 190, 199, 199, 199,
- 152, 152, 152, 136, 135, 135, 33, 13,
- 13, 13, 12, 12, 12, 12, 12, 12,
- 50, 50, 50, 50, 50, 50, 49, 49,
- 3, 3, 189, 189, 189, 189, 199, 152,
- 152, 152, 152, 152, 151, 151, 33, 32,
- 32, 32, 12, 12, 12, 12, 12, 84,
- 50, 50, 49, 49, 49, 49, 49, 49,
- 3, 189, 189, 189, 189, 189, 152, 152,
- 152, 152, 152, 151, 151, 151, 32, 32,
- 32, 31, 12, 12, 12, 12, 84, 84,
- 49, 49, 49, 49, 49, 49, 49, 49,
- 3, 189, 189, 189, 189, 189, 189, 152,
- 152, 152, 151, 151, 151, 151, 32, 32,
- 31, 31, 31, 12, 84, 84, 84, 84,
- 84, 49, 49, 49, 49, 49, 49, 49,
- 189, 189, 189, 189, 189, 189, 189, 152,
- 152, 151, 151, 151, 151, 118, 117, 117,
- 31, 31, 30, 30, 84, 84, 84, 84,
- 83, 49, 49, 49, 49, 49, 48, 48,
- 189, 189, 189, 189, 189, 189, 189, 151,
- 151, 151, 151, 151, 118, 117, 117, 117,
- 117, 30, 30, 84, 84, 84, 84, 83,
- 83, 66, 66, 66, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 188, 188, 188,
- 151, 151, 118, 118, 118, 117, 117, 117,
- 116, 116, 116, 84, 84, 84, 83, 83,
- 83, 66, 66, 66, 66, 48, 48, 48,
- 188, 188, 188, 188, 188, 188, 188, 188,
- 151, 150, 118, 118, 117, 117, 117, 116,
- 116, 116, 116, 115, 83, 83, 83, 83,
- 66, 66, 66, 66, 66, 65, 48, 48,
- 188, 188, 188, 188, 188, 188, 188, 188,
- 150, 118, 118, 117, 117, 117, 117, 116,
- 116, 116, 115, 115, 83, 83, 83, 83,
- 66, 66, 66, 65, 65, 65, 65, 65,
- 188, 188, 188, 188, 188, 188, 188, 188,
- 100, 100, 99, 99, 117, 117, 116, 116,
- 116, 116, 115, 115, 115, 83, 83, 82,
- 66, 65, 65, 65, 65, 65, 65, 65,
- 188, 188, 188, 188, 188, 188, 187, 100,
- 100, 100, 99, 99, 99, 99, 99, 116,
- 116, 115, 115, 115, 115, 114, 83, 82,
- 65, 65, 65, 65, 65, 65, 65, 9,
- 187, 187, 187, 187, 187, 187, 187, 100,
- 100, 100, 99, 99, 99, 99, 99, 98,
- 97, 97, 97, 97, 114, 114, 114, 82,
- 65, 65, 65, 65, 65, 65, 65, 9,
- 187, 187, 187, 187, 187, 187, 187, 100,
- 100, 99, 99, 99, 99, 99, 98, 98,
- 97, 97, 97, 97, 96, 96, 96, 96,
- 65, 65, 65, 65, 65, 64, 9, 9,
- 187, 187, 187, 187, 187, 187, 100, 100,
- 100, 99, 99, 99, 98, 98, 98, 98,
- 97, 97, 97, 97, 96, 96, 96, 96,
- 96, 65, 65, 203, 203, 203, 202, 202,
- 187, 187, 187, 187, 187, 187, 100, 100,
- 100, 99, 98, 98, 98, 98, 98, 98,
- 97, 97, 97, 97, 96, 96, 96, 96,
- 96, 203, 203, 203, 203, 202, 202, 202,
- 187, 187, 187, 187, 186, 186, 100, 100,
- 99, 98, 98, 98, 98, 98, 98, 97,
- 97, 97, 97, 97, 96, 96, 96, 96,
- 96, 203, 203, 203, 202, 202, 202, 202,
- 186, 186, 186, 186, 186, 186, 100, 100,
- 98, 98, 98, 98, 98, 98, 98, 97,
- 97, 97, 97, 96, 96, 96, 96, 96,
- 96, 203, 203, 202, 202, 202, 202, 202,
- 186, 186, 186, 186, 186, 186, 100, 98,
- 98, 98, 98, 98, 98, 98, 98, 97,
- 97, 97, 97, 96, 96, 96, 96, 96,
- 96, 203, 202, 202, 202, 202, 202, 202,
- 239, 239, 239, 239, 239, 239, 175, 175,
- 175, 220, 220, 5, 5, 5, 5, 5,
- 5, 5, 218, 218, 218, 218, 217, 217,
- 217, 217, 217, 216, 216, 216, 216, 216,
- 239, 239, 239, 239, 175, 175, 175, 175,
- 175, 220, 220, 220, 5, 5, 5, 5,
- 219, 219, 218, 218, 218, 218, 217, 217,
- 217, 217, 217, 216, 216, 216, 216, 216,
- 239, 239, 239, 175, 175, 175, 175, 174,
- 174, 220, 220, 220, 220, 219, 219, 219,
- 219, 219, 218, 218, 218, 218, 217, 217,
- 217, 217, 217, 216, 216, 216, 216, 216,
- 239, 239, 175, 174, 174, 174, 174, 174,
- 174, 174, 220, 220, 220, 219, 219, 219,
- 219, 218, 218, 218, 218, 218, 217, 217,
- 217, 217, 217, 216, 216, 216, 216, 215,
- 174, 174, 174, 174, 174, 174, 174, 174,
- 174, 174, 220, 220, 220, 219, 219, 219,
- 219, 218, 218, 218, 218, 218, 217, 217,
- 217, 217, 217, 216, 216, 216, 216, 215,
- 174, 174, 174, 174, 174, 174, 174, 174,
- 174, 174, 220, 220, 220, 219, 219, 219,
- 219, 218, 218, 218, 218, 218, 217, 217,
- 217, 217, 216, 216, 216, 216, 216, 215,
- 174, 174, 174, 174, 174, 174, 174, 174,
- 200, 200, 200, 220, 219, 219, 219, 219,
- 219, 218, 218, 218, 218, 218, 217, 217,
- 217, 217, 216, 216, 216, 216, 216, 51,
- 174, 174, 174, 174, 174, 174, 174, 200,
- 200, 200, 200, 200, 199, 219, 219, 219,
- 219, 218, 218, 218, 218, 218, 217, 217,
- 217, 217, 216, 216, 51, 51, 51, 51,
- 173, 173, 173, 173, 173, 200, 200, 200,
- 200, 200, 200, 199, 136, 136, 13, 13,
- 219, 218, 218, 218, 218, 218, 217, 217,
- 217, 217, 51, 51, 51, 51, 51, 50,
- 173, 173, 173, 173, 173, 200, 200, 200,
- 200, 199, 199, 199, 136, 136, 13, 13,
- 13, 13, 13, 13, 218, 217, 217, 217,
- 51, 51, 51, 51, 51, 50, 50, 50,
- 173, 173, 173, 173, 200, 200, 200, 200,
- 199, 199, 199, 136, 136, 136, 13, 13,
- 13, 13, 13, 13, 13, 12, 12, 51,
- 51, 51, 51, 50, 50, 50, 50, 50,
- 190, 190, 173, 200, 200, 200, 200, 199,
- 199, 199, 199, 136, 136, 136, 13, 13,
- 13, 13, 13, 13, 12, 12, 12, 51,
- 51, 51, 50, 50, 50, 50, 50, 50,
- 3, 190, 190, 200, 200, 199, 199, 199,
- 199, 199, 136, 136, 136, 136, 13, 13,
- 13, 13, 13, 12, 12, 12, 12, 12,
- 50, 50, 50, 50, 50, 50, 50, 50,
- 3, 3, 190, 190, 199, 199, 199, 199,
- 199, 199, 135, 135, 135, 135, 13, 13,
- 13, 13, 12, 12, 12, 12, 12, 12,
- 50, 50, 50, 50, 50, 50, 49, 49,
- 3, 3, 189, 189, 189, 199, 199, 199,
- 199, 135, 135, 135, 135, 135, 135, 13,
- 32, 12, 12, 12, 12, 12, 12, 12,
- 50, 50, 49, 49, 49, 49, 49, 49,
- 3, 189, 189, 189, 189, 189, 199, 199,
- 152, 135, 135, 135, 135, 151, 134, 32,
- 32, 12, 12, 12, 12, 12, 12, 12,
- 49, 49, 49, 49, 49, 49, 49, 49,
- 3, 189, 189, 189, 189, 189, 199, 152,
- 152, 151, 151, 151, 151, 151, 134, 32,
- 31, 31, 12, 12, 12, 12, 84, 84,
- 11, 49, 49, 49, 49, 49, 49, 49,
- 189, 189, 189, 189, 189, 189, 189, 152,
- 151, 151, 151, 151, 151, 151, 150, 31,
- 31, 31, 30, 12, 12, 84, 84, 84,
- 11, 49, 49, 49, 49, 49, 48, 48,
- 189, 189, 189, 189, 189, 189, 189, 151,
- 151, 151, 151, 151, 150, 150, 117, 117,
- 31, 30, 30, 29, 84, 84, 84, 83,
- 83, 49, 49, 49, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 188, 188, 151,
- 151, 151, 150, 150, 150, 150, 117, 117,
- 116, 30, 29, 29, 84, 84, 83, 83,
- 83, 66, 66, 48, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 188, 188, 188,
- 150, 150, 150, 150, 150, 117, 117, 116,
- 116, 116, 29, 29, 83, 83, 83, 83,
- 82, 66, 66, 66, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 188, 188, 188,
- 150, 150, 150, 150, 117, 117, 117, 116,
- 116, 116, 115, 115, 83, 83, 83, 83,
- 82, 66, 65, 65, 65, 65, 48, 48,
- 188, 188, 188, 188, 188, 188, 188, 188,
- 150, 150, 150, 117, 117, 117, 116, 116,
- 116, 116, 115, 115, 115, 83, 83, 82,
- 82, 65, 65, 65, 65, 65, 65, 65,
- 188, 188, 188, 188, 188, 188, 187, 187,
- 150, 150, 150, 117, 117, 116, 116, 116,
- 116, 115, 115, 115, 115, 83, 82, 82,
- 82, 65, 65, 65, 65, 65, 65, 9,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 100, 99, 99, 99, 99, 99, 116, 116,
- 116, 115, 115, 115, 114, 114, 82, 82,
- 65, 65, 65, 65, 65, 64, 64, 9,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 100, 99, 99, 99, 99, 99, 98, 97,
- 97, 97, 97, 114, 114, 114, 114, 81,
- 65, 65, 65, 64, 64, 64, 9, 9,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 99, 99, 99, 99, 99, 98, 98, 97,
- 97, 97, 97, 96, 96, 96, 96, 96,
- 65, 64, 64, 64, 64, 9, 9, 9,
- 187, 187, 187, 187, 187, 187, 187, 100,
- 99, 99, 99, 98, 98, 98, 98, 97,
- 97, 97, 97, 96, 96, 96, 96, 96,
- 96, 64, 64, 64, 202, 202, 202, 202,
- 187, 187, 187, 187, 186, 186, 186, 100,
- 99, 98, 98, 98, 98, 98, 98, 97,
- 97, 97, 97, 96, 96, 96, 96, 96,
- 96, 202, 202, 202, 202, 202, 202, 202,
- 186, 186, 186, 186, 186, 186, 186, 99,
- 98, 98, 98, 98, 98, 98, 97, 97,
- 97, 97, 97, 96, 96, 96, 96, 96,
- 96, 202, 202, 202, 202, 202, 202, 202,
- 186, 186, 186, 186, 186, 186, 186, 98,
- 98, 98, 98, 98, 98, 98, 97, 97,
- 97, 97, 96, 96, 96, 96, 96, 96,
- 96, 202, 202, 202, 202, 202, 202, 202,
- 186, 186, 186, 186, 186, 186, 186, 98,
- 98, 98, 98, 98, 98, 98, 97, 97,
- 97, 97, 96, 96, 96, 96, 96, 96,
- 96, 202, 202, 202, 202, 202, 202, 202,
- 238, 238, 238, 238, 238, 238, 238, 175,
- 175, 220, 5, 5, 5, 5, 5, 5,
- 5, 218, 218, 218, 218, 217, 217, 217,
- 217, 217, 216, 216, 216, 216, 216, 215,
- 238, 238, 238, 238, 238, 238, 174, 174,
- 174, 220, 220, 5, 5, 5, 5, 219,
- 219, 218, 218, 218, 218, 217, 217, 217,
- 217, 217, 216, 216, 216, 216, 216, 215,
- 238, 238, 238, 238, 174, 174, 174, 174,
- 174, 174, 220, 220, 219, 219, 219, 219,
- 219, 218, 218, 218, 218, 217, 217, 217,
- 217, 217, 216, 216, 216, 216, 216, 215,
- 238, 238, 174, 174, 174, 174, 174, 174,
- 174, 174, 220, 220, 219, 219, 219, 219,
- 218, 218, 218, 218, 218, 217, 217, 217,
- 217, 217, 216, 216, 216, 216, 215, 215,
- 174, 174, 174, 174, 174, 174, 174, 174,
- 174, 174, 220, 220, 219, 219, 219, 219,
- 218, 218, 218, 218, 218, 217, 217, 217,
- 217, 217, 216, 216, 216, 216, 215, 215,
- 174, 174, 174, 174, 174, 174, 174, 174,
- 174, 174, 200, 220, 219, 219, 219, 219,
- 218, 218, 218, 218, 218, 217, 217, 217,
- 217, 216, 216, 216, 216, 216, 215, 215,
- 174, 174, 174, 174, 174, 174, 174, 174,
- 174, 200, 200, 199, 219, 219, 219, 219,
- 218, 218, 218, 218, 218, 217, 217, 217,
- 217, 216, 216, 216, 216, 216, 215, 215,
- 173, 173, 173, 173, 173, 173, 173, 200,
- 200, 200, 199, 199, 199, 219, 219, 219,
- 218, 218, 218, 218, 218, 217, 217, 217,
- 217, 216, 216, 216, 216, 216, 215, 215,
- 173, 173, 173, 173, 173, 173, 173, 200,
- 199, 199, 199, 199, 199, 136, 219, 219,
- 218, 218, 218, 218, 218, 217, 217, 217,
- 217, 216, 216, 216, 216, 50, 50, 50,
- 173, 173, 173, 173, 173, 173, 200, 199,
- 199, 199, 199, 199, 199, 136, 13, 13,
- 13, 13, 13, 218, 217, 217, 217, 217,
- 216, 216, 51, 50, 50, 50, 50, 50,
- 173, 173, 173, 173, 173, 199, 199, 199,
- 199, 199, 199, 199, 136, 136, 13, 13,
- 13, 13, 13, 13, 12, 12, 12, 217,
- 51, 51, 50, 50, 50, 50, 50, 50,
- 173, 173, 173, 173, 199, 199, 199, 199,
- 199, 199, 199, 199, 135, 135, 13, 13,
- 13, 13, 13, 12, 12, 12, 12, 12,
- 50, 50, 50, 50, 50, 50, 50, 50,
- 3, 3, 173, 199, 199, 199, 199, 199,
- 199, 199, 199, 135, 135, 135, 135, 13,
- 13, 13, 12, 12, 12, 12, 12, 12,
- 50, 50, 50, 50, 50, 50, 49, 49,
- 3, 3, 189, 189, 199, 199, 199, 199,
- 199, 199, 135, 135, 135, 135, 135, 13,
- 13, 12, 12, 12, 12, 12, 12, 12,
- 50, 50, 49, 49, 49, 49, 49, 49,
- 3, 189, 189, 189, 199, 199, 199, 199,
- 199, 135, 135, 135, 135, 135, 134, 134,
- 12, 12, 12, 12, 12, 12, 12, 11,
- 11, 49, 49, 49, 49, 49, 49, 49,
- 3, 189, 189, 189, 189, 199, 199, 199,
- 135, 135, 135, 135, 134, 134, 134, 133,
- 12, 12, 12, 12, 12, 12, 12, 11,
- 11, 49, 49, 49, 49, 49, 49, 49,
- 189, 189, 189, 189, 189, 189, 199, 198,
- 135, 135, 151, 151, 134, 134, 134, 133,
- 31, 12, 12, 12, 12, 12, 11, 11,
- 11, 49, 49, 49, 49, 49, 48, 48,
- 189, 189, 189, 189, 189, 189, 189, 151,
- 151, 151, 151, 150, 150, 150, 133, 133,
- 31, 30, 30, 12, 12, 11, 11, 11,
- 11, 49, 49, 49, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 188, 188, 151,
- 151, 150, 150, 150, 150, 150, 133, 133,
- 30, 30, 29, 29, 29, 11, 11, 11,
- 11, 11, 48, 48, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 188, 188, 150,
- 150, 150, 150, 150, 150, 149, 149, 149,
- 116, 29, 29, 29, 28, 83, 83, 83,
- 82, 82, 48, 48, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 188, 188, 188,
- 150, 150, 150, 150, 150, 149, 149, 116,
- 116, 116, 29, 28, 28, 83, 83, 82,
- 82, 82, 65, 48, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 188, 188, 188,
- 150, 150, 150, 150, 149, 149, 116, 116,
- 116, 115, 115, 115, 28, 83, 82, 82,
- 82, 82, 65, 65, 65, 48, 48, 48,
- 188, 188, 188, 188, 188, 188, 187, 187,
- 150, 150, 150, 149, 149, 149, 116, 116,
- 116, 115, 115, 115, 114, 83, 82, 82,
- 82, 65, 65, 65, 65, 65, 64, 64,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 187, 150, 149, 149, 149, 116, 116, 116,
- 115, 115, 115, 115, 114, 114, 82, 82,
- 81, 65, 65, 65, 64, 64, 64, 9,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 187, 150, 149, 99, 116, 116, 116, 116,
- 115, 115, 115, 114, 114, 114, 82, 81,
- 81, 65, 64, 64, 64, 64, 9, 9,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 187, 99, 99, 99, 99, 98, 97, 97,
- 97, 115, 114, 114, 114, 114, 113, 81,
- 81, 64, 64, 64, 64, 64, 9, 9,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 99, 99, 99, 99, 98, 98, 97, 97,
- 97, 97, 96, 96, 96, 96, 113, 113,
- 81, 64, 64, 64, 64, 9, 9, 9,
- 187, 187, 187, 187, 186, 186, 186, 186,
- 99, 99, 98, 98, 98, 98, 97, 97,
- 97, 97, 96, 96, 96, 96, 96, 96,
- 112, 64, 64, 64, 9, 9, 9, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 98, 98, 98, 98, 98, 98, 97, 97,
- 97, 97, 96, 96, 96, 96, 96, 96,
- 96, 64, 202, 202, 202, 202, 202, 202,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 98, 98, 98, 98, 98, 97, 97, 97,
- 97, 97, 96, 96, 96, 96, 96, 96,
- 96, 202, 202, 202, 202, 202, 202, 202,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 98, 98, 98, 98, 98, 97, 97, 97,
- 97, 96, 96, 96, 96, 96, 96, 96,
- 96, 202, 202, 202, 202, 202, 202, 202,
- 186, 186, 186, 186, 186, 186, 186, 98,
- 98, 98, 98, 98, 98, 97, 97, 97,
- 97, 96, 96, 96, 96, 96, 96, 96,
- 96, 202, 202, 202, 202, 202, 202, 202,
- 238, 238, 238, 238, 238, 237, 237, 237,
- 174, 174, 5, 5, 5, 5, 5, 5,
- 218, 218, 218, 218, 217, 217, 217, 217,
- 217, 216, 216, 216, 216, 216, 215, 215,
- 238, 238, 238, 238, 237, 237, 174, 174,
- 174, 174, 5, 5, 5, 5, 219, 219,
- 218, 218, 218, 218, 217, 217, 217, 217,
- 217, 216, 216, 216, 216, 216, 215, 215,
- 238, 238, 238, 237, 174, 174, 174, 174,
- 174, 174, 220, 219, 219, 219, 219, 219,
- 218, 218, 218, 218, 217, 217, 217, 217,
- 217, 216, 216, 216, 216, 216, 215, 215,
- 238, 238, 174, 174, 174, 174, 174, 174,
- 174, 174, 220, 219, 219, 219, 219, 218,
- 218, 218, 218, 218, 217, 217, 217, 217,
- 217, 216, 216, 216, 216, 215, 215, 215,
- 238, 174, 174, 174, 174, 174, 174, 174,
- 174, 174, 174, 219, 219, 219, 219, 218,
- 218, 218, 218, 218, 217, 217, 217, 217,
- 217, 216, 216, 216, 216, 215, 215, 215,
- 174, 174, 174, 174, 174, 174, 174, 174,
- 174, 174, 174, 219, 219, 219, 219, 218,
- 218, 218, 218, 218, 217, 217, 217, 217,
- 216, 216, 216, 216, 216, 215, 215, 215,
- 173, 173, 173, 173, 173, 173, 173, 173,
- 174, 199, 199, 199, 219, 219, 219, 218,
- 218, 218, 218, 218, 217, 217, 217, 217,
- 216, 216, 216, 216, 216, 215, 215, 215,
- 173, 173, 173, 173, 173, 173, 173, 173,
- 199, 199, 199, 199, 199, 219, 219, 218,
- 218, 218, 218, 218, 217, 217, 217, 217,
- 216, 216, 216, 216, 216, 215, 215, 215,
- 173, 173, 173, 173, 173, 173, 173, 199,
- 199, 199, 199, 199, 199, 199, 219, 218,
- 218, 218, 218, 218, 217, 217, 217, 217,
- 216, 216, 216, 216, 216, 215, 215, 215,
- 173, 173, 173, 173, 173, 173, 173, 199,
- 199, 199, 199, 199, 199, 199, 135, 13,
- 13, 13, 218, 217, 217, 217, 217, 216,
- 216, 216, 216, 216, 50, 50, 50, 50,
- 173, 173, 173, 173, 173, 173, 199, 199,
- 199, 199, 199, 199, 199, 135, 135, 13,
- 13, 13, 13, 12, 12, 12, 217, 216,
- 216, 216, 50, 50, 50, 50, 50, 50,
- 173, 173, 173, 173, 173, 199, 199, 199,
- 199, 199, 199, 199, 135, 135, 135, 13,
- 13, 13, 12, 12, 12, 12, 12, 12,
- 50, 50, 50, 50, 50, 50, 49, 49,
- 173, 173, 173, 173, 199, 199, 199, 199,
- 199, 199, 199, 135, 135, 135, 135, 13,
- 13, 12, 12, 12, 12, 12, 12, 12,
- 11, 50, 49, 49, 49, 49, 49, 49,
- 3, 189, 189, 199, 199, 199, 199, 199,
- 199, 198, 198, 135, 135, 135, 134, 134,
- 12, 12, 12, 12, 12, 12, 12, 11,
- 11, 49, 49, 49, 49, 49, 49, 49,
- 3, 189, 189, 189, 199, 199, 199, 199,
- 198, 198, 135, 135, 134, 134, 134, 134,
- 12, 12, 12, 12, 12, 12, 11, 11,
- 11, 49, 49, 49, 49, 49, 49, 49,
- 189, 189, 189, 189, 189, 199, 198, 198,
- 198, 198, 135, 134, 134, 134, 134, 133,
- 133, 12, 12, 12, 12, 12, 11, 11,
- 11, 11, 49, 49, 49, 49, 48, 48,
- 189, 189, 189, 189, 189, 189, 198, 198,
- 198, 135, 134, 134, 134, 134, 133, 133,
- 133, 12, 12, 12, 12, 11, 11, 11,
- 11, 11, 49, 49, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 188, 198, 198,
- 198, 150, 150, 150, 150, 133, 133, 133,
- 133, 30, 29, 29, 11, 11, 11, 11,
- 11, 11, 48, 48, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 188, 188, 150,
- 150, 150, 150, 150, 150, 150, 133, 133,
- 132, 29, 29, 29, 11, 11, 11, 11,
- 11, 11, 48, 48, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 188, 188, 150,
- 150, 150, 150, 150, 150, 149, 149, 149,
- 132, 29, 29, 28, 28, 11, 11, 11,
- 82, 82, 48, 48, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 188, 188, 188,
- 150, 150, 150, 150, 149, 149, 149, 148,
- 148, 115, 28, 28, 28, 27, 82, 82,
- 82, 82, 82, 48, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 188, 187, 187,
- 150, 150, 150, 149, 149, 149, 149, 148,
- 148, 115, 115, 28, 27, 27, 82, 82,
- 82, 82, 65, 65, 65, 48, 48, 48,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 150, 150, 150, 149, 149, 149, 148, 148,
- 115, 115, 115, 114, 114, 27, 82, 82,
- 81, 81, 65, 64, 64, 64, 64, 9,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 187, 150, 149, 149, 149, 148, 148, 115,
- 115, 115, 114, 114, 114, 114, 82, 81,
- 81, 81, 64, 64, 64, 64, 64, 9,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 187, 149, 149, 149, 149, 148, 116, 115,
- 115, 115, 114, 114, 114, 114, 113, 81,
- 81, 81, 64, 64, 64, 64, 9, 9,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 187, 149, 99, 99, 98, 97, 97, 115,
- 115, 114, 114, 114, 114, 113, 113, 81,
- 81, 81, 64, 64, 64, 9, 9, 9,
- 187, 187, 187, 187, 186, 186, 186, 186,
- 186, 99, 99, 98, 98, 97, 97, 97,
- 97, 96, 96, 96, 113, 113, 113, 113,
- 81, 64, 64, 64, 64, 9, 9, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 98, 98, 98, 98, 97, 97, 97,
- 97, 96, 96, 96, 96, 96, 96, 112,
- 112, 8, 64, 64, 9, 9, 9, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 98, 98, 98, 98, 97, 97, 97,
- 97, 96, 96, 96, 96, 96, 96, 96,
- 8, 8, 8, 202, 202, 202, 202, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 98, 98, 98, 97, 97, 97, 97,
- 97, 96, 96, 96, 96, 96, 96, 96,
- 8, 8, 202, 202, 202, 202, 202, 202,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 98, 98, 98, 98, 97, 97, 97, 97,
- 96, 96, 96, 96, 96, 96, 96, 96,
- 8, 8, 202, 202, 202, 202, 202, 202,
- 186, 186, 186, 186, 186, 185, 185, 185,
- 98, 98, 98, 98, 97, 97, 97, 97,
- 96, 96, 96, 96, 96, 96, 96, 96,
- 8, 8, 202, 202, 202, 202, 202, 202,
- 237, 237, 237, 237, 237, 237, 237, 237,
- 237, 174, 5, 5, 5, 5, 5, 218,
- 218, 218, 218, 217, 217, 217, 217, 217,
- 216, 216, 216, 216, 216, 215, 215, 215,
- 237, 237, 237, 237, 237, 237, 237, 174,
- 174, 174, 5, 5, 5, 219, 219, 218,
- 218, 218, 218, 217, 217, 217, 217, 217,
- 216, 216, 216, 216, 216, 215, 215, 215,
- 237, 237, 237, 237, 237, 237, 174, 174,
- 174, 174, 219, 219, 219, 219, 219, 218,
- 218, 218, 218, 217, 217, 217, 217, 217,
- 216, 216, 216, 216, 216, 215, 215, 215,
- 237, 237, 237, 237, 174, 174, 174, 174,
- 174, 174, 174, 219, 219, 219, 218, 218,
- 218, 218, 218, 217, 217, 217, 217, 217,
- 216, 216, 216, 216, 215, 215, 215, 215,
- 237, 237, 174, 174, 174, 174, 174, 174,
- 174, 174, 174, 219, 219, 219, 218, 218,
- 218, 218, 218, 217, 217, 217, 217, 217,
- 216, 216, 216, 216, 215, 215, 215, 215,
- 173, 173, 173, 173, 173, 173, 173, 173,
- 173, 174, 174, 219, 219, 219, 218, 218,
- 218, 218, 218, 217, 217, 217, 217, 216,
- 216, 216, 216, 216, 215, 215, 215, 215,
- 173, 173, 173, 173, 173, 173, 173, 173,
- 173, 173, 199, 199, 219, 219, 218, 218,
- 218, 218, 218, 217, 217, 217, 217, 216,
- 216, 216, 216, 216, 215, 215, 215, 215,
- 173, 173, 173, 173, 173, 173, 173, 173,
- 173, 199, 199, 199, 199, 219, 218, 218,
- 218, 218, 218, 217, 217, 217, 217, 216,
- 216, 216, 216, 216, 215, 215, 215, 215,
- 173, 173, 173, 173, 173, 173, 173, 173,
- 199, 199, 199, 199, 199, 199, 218, 218,
- 218, 218, 218, 217, 217, 217, 217, 216,
- 216, 216, 216, 216, 215, 215, 215, 215,
- 173, 173, 173, 173, 173, 173, 173, 199,
- 199, 199, 199, 199, 199, 198, 135, 13,
- 13, 218, 217, 217, 217, 217, 216, 216,
- 216, 216, 216, 215, 215, 215, 215, 215,
- 173, 173, 173, 173, 173, 173, 199, 199,
- 199, 199, 199, 198, 198, 198, 135, 13,
- 13, 13, 12, 12, 12, 217, 216, 216,
- 216, 216, 216, 215, 50, 50, 49, 49,
- 172, 172, 172, 172, 172, 199, 199, 199,
- 199, 199, 198, 198, 198, 135, 135, 134,
- 13, 12, 12, 12, 12, 12, 12, 12,
- 11, 50, 49, 49, 49, 49, 49, 49,
- 172, 172, 172, 172, 172, 199, 199, 199,
- 198, 198, 198, 198, 198, 134, 134, 134,
- 12, 12, 12, 12, 12, 12, 12, 11,
- 11, 49, 49, 49, 49, 49, 49, 49,
- 172, 172, 172, 172, 199, 199, 198, 198,
- 198, 198, 198, 198, 134, 134, 134, 134,
- 133, 12, 12, 12, 12, 12, 11, 11,
- 11, 11, 49, 49, 49, 49, 49, 49,
- 189, 189, 189, 189, 199, 198, 198, 198,
- 198, 198, 198, 198, 134, 134, 134, 133,
- 133, 12, 12, 12, 12, 11, 11, 11,
- 11, 11, 49, 49, 49, 49, 48, 48,
- 189, 189, 189, 189, 198, 198, 198, 198,
- 198, 198, 198, 134, 134, 134, 133, 133,
- 133, 12, 12, 12, 12, 11, 11, 11,
- 11, 11, 49, 49, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 198, 198, 198,
- 198, 198, 134, 134, 134, 133, 133, 133,
- 133, 132, 12, 12, 11, 11, 11, 11,
- 11, 11, 48, 48, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 188, 198, 198,
- 198, 150, 150, 150, 150, 133, 133, 133,
- 132, 132, 29, 11, 11, 11, 11, 11,
- 11, 11, 48, 48, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 188, 188, 198,
- 150, 150, 150, 150, 150, 133, 133, 132,
- 132, 132, 29, 28, 11, 11, 11, 11,
- 11, 11, 48, 48, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 188, 188, 150,
- 150, 150, 150, 150, 149, 149, 149, 132,
- 132, 132, 28, 28, 28, 11, 11, 11,
- 11, 82, 48, 48, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 188, 187, 187,
- 150, 150, 150, 149, 149, 149, 149, 148,
- 148, 131, 131, 28, 27, 27, 27, 82,
- 82, 82, 81, 48, 48, 48, 48, 48,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 150, 150, 150, 149, 149, 149, 148, 148,
- 148, 147, 147, 27, 27, 27, 26, 82,
- 82, 81, 81, 64, 64, 64, 48, 48,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 187, 150, 149, 149, 149, 148, 148, 148,
- 147, 147, 114, 114, 114, 26, 26, 81,
- 81, 81, 81, 64, 64, 64, 64, 9,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 187, 149, 149, 149, 149, 148, 148, 148,
- 147, 114, 114, 114, 114, 113, 26, 81,
- 81, 81, 81, 64, 64, 64, 9, 9,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 187, 149, 149, 149, 148, 148, 148, 147,
- 147, 114, 114, 114, 114, 113, 113, 81,
- 81, 81, 64, 64, 64, 64, 9, 9,
- 187, 187, 187, 187, 186, 186, 186, 186,
- 186, 186, 149, 148, 148, 148, 147, 147,
- 114, 114, 114, 114, 113, 113, 113, 112,
- 81, 80, 64, 64, 64, 9, 9, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 186, 98, 98, 97, 97, 97, 97,
- 96, 96, 96, 113, 113, 113, 113, 112,
- 112, 80, 64, 64, 9, 9, 9, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 186, 98, 98, 97, 97, 97, 97,
- 96, 96, 96, 96, 96, 113, 112, 112,
- 8, 8, 8, 64, 9, 9, 9, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 186, 98, 98, 97, 97, 97, 97,
- 96, 96, 96, 96, 96, 96, 96, 8,
- 8, 8, 8, 9, 9, 9, 9, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 98, 98, 97, 97, 97, 97, 97,
- 96, 96, 96, 96, 96, 96, 96, 8,
- 8, 8, 8, 202, 202, 202, 202, 202,
- 186, 186, 186, 186, 186, 185, 185, 185,
- 182, 182, 98, 97, 97, 97, 97, 96,
- 96, 96, 96, 96, 96, 96, 96, 8,
- 8, 8, 8, 202, 202, 202, 202, 202,
- 185, 185, 185, 185, 185, 185, 185, 185,
- 182, 182, 98, 97, 97, 97, 97, 96,
- 96, 96, 96, 96, 96, 96, 96, 8,
- 8, 8, 8, 202, 202, 202, 202, 202,
- 236, 236, 236, 236, 236, 236, 236, 236,
- 236, 236, 5, 5, 5, 5, 218, 218,
- 218, 218, 217, 217, 217, 217, 217, 216,
- 216, 216, 216, 216, 215, 215, 215, 215,
- 236, 236, 236, 236, 236, 236, 236, 236,
- 236, 174, 5, 5, 219, 219, 218, 218,
- 218, 218, 217, 217, 217, 217, 217, 216,
- 216, 216, 216, 216, 215, 215, 215, 215,
- 236, 236, 236, 236, 236, 236, 236, 174,
- 174, 174, 174, 219, 219, 219, 218, 218,
- 218, 218, 217, 217, 217, 217, 217, 216,
- 216, 216, 216, 216, 215, 215, 215, 215,
- 236, 236, 236, 236, 236, 174, 174, 174,
- 174, 174, 174, 219, 219, 218, 218, 218,
- 218, 218, 217, 217, 217, 217, 217, 216,
- 216, 216, 216, 215, 215, 215, 215, 215,
- 236, 236, 236, 173, 173, 173, 173, 173,
- 173, 173, 174, 219, 219, 218, 218, 218,
- 218, 218, 217, 217, 217, 217, 217, 216,
- 216, 216, 216, 215, 215, 215, 215, 215,
- 173, 173, 173, 173, 173, 173, 173, 173,
- 173, 173, 173, 219, 219, 218, 218, 218,
- 218, 218, 217, 217, 217, 217, 216, 216,
- 216, 216, 216, 215, 215, 215, 215, 215,
- 173, 173, 173, 173, 173, 173, 173, 173,
- 173, 173, 199, 199, 199, 218, 218, 218,
- 218, 218, 217, 217, 217, 217, 216, 216,
- 216, 216, 216, 215, 215, 215, 215, 215,
- 173, 173, 173, 173, 173, 173, 173, 173,
- 173, 199, 199, 199, 199, 198, 218, 218,
- 218, 218, 217, 217, 217, 217, 216, 216,
- 216, 216, 216, 215, 215, 215, 215, 215,
- 173, 173, 173, 173, 173, 173, 173, 173,
- 199, 199, 199, 199, 198, 198, 198, 218,
- 218, 218, 217, 217, 217, 217, 216, 216,
- 216, 216, 216, 215, 215, 215, 215, 214,
- 172, 172, 172, 172, 173, 173, 173, 199,
- 199, 199, 198, 198, 198, 198, 198, 197,
- 218, 217, 217, 217, 217, 216, 216, 216,
- 216, 216, 215, 215, 215, 215, 215, 214,
- 172, 172, 172, 172, 172, 172, 172, 199,
- 198, 198, 198, 198, 198, 198, 197, 197,
- 197, 12, 12, 12, 217, 216, 216, 216,
- 216, 216, 215, 215, 215, 215, 215, 49,
- 172, 172, 172, 172, 172, 172, 199, 198,
- 198, 198, 198, 198, 198, 197, 197, 197,
- 197, 12, 12, 12, 12, 12, 12, 11,
- 216, 216, 215, 49, 49, 49, 49, 49,
- 172, 172, 172, 172, 172, 198, 198, 198,
- 198, 198, 198, 198, 198, 197, 197, 197,
- 133, 12, 12, 12, 12, 12, 11, 11,
- 11, 11, 49, 49, 49, 49, 49, 49,
- 172, 172, 172, 172, 172, 198, 198, 198,
- 198, 198, 198, 198, 197, 197, 197, 133,
- 133, 12, 12, 12, 12, 11, 11, 11,
- 11, 11, 49, 49, 49, 49, 48, 48,
- 172, 172, 172, 172, 198, 198, 198, 198,
- 198, 198, 198, 197, 197, 197, 133, 133,
- 133, 133, 12, 12, 11, 11, 11, 11,
- 11, 11, 11, 49, 48, 48, 48, 48,
- 188, 188, 188, 188, 198, 198, 198, 198,
- 198, 198, 197, 197, 197, 197, 133, 133,
- 133, 132, 12, 12, 11, 11, 11, 11,
- 11, 11, 11, 48, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 198, 198, 198,
- 198, 198, 197, 197, 197, 133, 133, 133,
- 132, 132, 132, 11, 11, 11, 11, 11,
- 11, 11, 11, 48, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 188, 198, 198,
- 198, 197, 197, 197, 133, 133, 133, 132,
- 132, 132, 131, 11, 11, 11, 11, 11,
- 11, 11, 11, 48, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 188, 188, 198,
- 197, 197, 150, 150, 133, 133, 132, 132,
- 132, 132, 131, 11, 11, 11, 11, 11,
- 11, 11, 10, 48, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 188, 187, 150,
- 150, 150, 150, 150, 149, 149, 149, 132,
- 132, 131, 131, 131, 11, 11, 11, 11,
- 11, 10, 10, 48, 48, 48, 48, 48,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 150, 150, 150, 149, 149, 149, 148, 148,
- 148, 131, 131, 131, 27, 27, 26, 10,
- 10, 10, 10, 10, 48, 48, 48, 48,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 150, 150, 149, 149, 149, 148, 148, 148,
- 147, 147, 147, 130, 27, 26, 26, 10,
- 10, 10, 10, 80, 64, 64, 64, 48,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 187, 149, 149, 149, 149, 148, 148, 148,
- 147, 147, 147, 114, 26, 26, 26, 25,
- 81, 81, 80, 80, 64, 64, 9, 9,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 187, 149, 149, 149, 148, 148, 148, 147,
- 147, 147, 114, 114, 113, 113, 25, 25,
- 81, 80, 80, 64, 64, 64, 9, 9,
- 187, 187, 187, 187, 186, 186, 186, 186,
- 186, 149, 149, 148, 148, 148, 147, 147,
- 147, 147, 114, 114, 113, 113, 113, 81,
- 80, 80, 80, 64, 64, 9, 9, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 186, 149, 148, 148, 148, 147, 147,
- 147, 114, 114, 113, 113, 113, 113, 112,
- 80, 80, 80, 64, 9, 9, 9, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 186, 148, 148, 148, 147, 147, 147,
- 114, 114, 113, 113, 113, 113, 112, 112,
- 112, 80, 80, 64, 9, 9, 9, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 186, 181, 97, 97, 97, 97, 96,
- 96, 96, 96, 96, 113, 112, 112, 112,
- 8, 8, 8, 8, 9, 9, 9, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 182, 181, 97, 97, 97, 97, 96,
- 96, 96, 96, 96, 96, 112, 112, 8,
- 8, 8, 8, 8, 9, 9, 9, 9,
- 186, 186, 186, 186, 186, 185, 185, 185,
- 182, 182, 181, 97, 97, 97, 97, 96,
- 96, 96, 96, 96, 96, 96, 8, 8,
- 8, 8, 8, 8, 9, 9, 9, 9,
- 185, 185, 185, 185, 185, 185, 185, 185,
- 182, 182, 181, 181, 97, 97, 96, 96,
- 96, 96, 96, 96, 96, 96, 8, 8,
- 8, 8, 8, 8, 202, 202, 202, 202,
- 185, 185, 185, 185, 185, 185, 185, 182,
- 182, 182, 181, 181, 97, 97, 96, 96,
- 96, 96, 96, 96, 96, 96, 8, 8,
- 8, 8, 8, 8, 202, 202, 202, 202,
- 236, 236, 236, 236, 236, 236, 236, 236,
- 236, 236, 236, 5, 5, 218, 218, 218,
- 218, 217, 217, 217, 217, 217, 216, 216,
- 216, 216, 216, 215, 215, 215, 215, 214,
- 236, 236, 236, 236, 236, 236, 236, 236,
- 236, 236, 236, 219, 219, 218, 218, 218,
- 218, 217, 217, 217, 217, 217, 216, 216,
- 216, 216, 216, 215, 215, 215, 215, 214,
- 236, 236, 236, 236, 236, 236, 236, 236,
- 236, 174, 174, 219, 219, 218, 218, 218,
- 218, 217, 217, 217, 217, 217, 216, 216,
- 216, 216, 216, 215, 215, 215, 215, 214,
- 236, 236, 236, 236, 236, 236, 236, 173,
- 173, 173, 173, 219, 218, 218, 218, 218,
- 218, 217, 217, 217, 217, 217, 216, 216,
- 216, 216, 215, 215, 215, 215, 215, 214,
- 236, 236, 236, 236, 173, 173, 173, 173,
- 173, 173, 173, 219, 218, 218, 218, 218,
- 218, 217, 217, 217, 217, 217, 216, 216,
- 216, 216, 215, 215, 215, 215, 215, 214,
- 236, 173, 173, 173, 173, 173, 173, 173,
- 173, 173, 173, 173, 218, 218, 218, 218,
- 218, 217, 217, 217, 217, 216, 216, 216,
- 216, 216, 215, 215, 215, 215, 215, 214,
- 173, 173, 173, 173, 173, 173, 173, 173,
- 173, 173, 173, 199, 198, 218, 218, 218,
- 218, 217, 217, 217, 217, 216, 216, 216,
- 216, 216, 215, 215, 215, 215, 215, 214,
- 172, 172, 173, 173, 173, 173, 173, 173,
- 173, 173, 198, 198, 198, 198, 218, 218,
- 218, 217, 217, 217, 217, 216, 216, 216,
- 216, 216, 215, 215, 215, 215, 215, 214,
- 172, 172, 172, 172, 172, 172, 172, 172,
- 172, 198, 198, 198, 198, 198, 198, 218,
- 218, 217, 217, 217, 217, 216, 216, 216,
- 216, 216, 215, 215, 215, 215, 214, 214,
- 172, 172, 172, 172, 172, 172, 172, 172,
- 198, 198, 198, 198, 198, 198, 197, 197,
- 197, 217, 217, 217, 216, 216, 216, 216,
- 216, 215, 215, 215, 215, 215, 214, 214,
- 172, 172, 172, 172, 172, 172, 172, 198,
- 198, 198, 198, 198, 198, 197, 197, 197,
- 197, 197, 217, 217, 216, 216, 216, 216,
- 216, 215, 215, 215, 215, 215, 214, 214,
- 172, 172, 172, 172, 172, 172, 172, 198,
- 198, 198, 198, 198, 198, 197, 197, 197,
- 197, 196, 12, 12, 12, 12, 11, 216,
- 216, 215, 215, 215, 215, 215, 49, 49,
- 172, 172, 172, 172, 172, 172, 198, 198,
- 198, 198, 198, 198, 197, 197, 197, 197,
- 196, 196, 12, 12, 12, 11, 11, 11,
- 11, 11, 11, 49, 49, 49, 48, 48,
- 171, 171, 172, 172, 172, 198, 198, 198,
- 198, 198, 198, 197, 197, 197, 197, 196,
- 196, 196, 12, 12, 11, 11, 11, 11,
- 11, 11, 11, 49, 48, 48, 48, 48,
- 171, 171, 171, 171, 171, 198, 198, 198,
- 198, 198, 198, 197, 197, 197, 197, 196,
- 196, 196, 132, 11, 11, 11, 11, 11,
- 11, 11, 11, 48, 48, 48, 48, 48,
- 171, 171, 171, 171, 198, 198, 198, 198,
- 198, 198, 197, 197, 197, 197, 196, 196,
- 196, 132, 132, 11, 11, 11, 11, 11,
- 11, 11, 11, 48, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 198, 198, 198,
- 198, 197, 197, 197, 197, 196, 196, 196,
- 132, 132, 132, 11, 11, 11, 11, 11,
- 11, 11, 11, 48, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 198, 198, 198,
- 197, 197, 197, 197, 196, 196, 196, 132,
- 132, 132, 131, 131, 11, 11, 11, 11,
- 11, 11, 10, 48, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 188, 198, 198,
- 197, 197, 197, 196, 196, 196, 132, 132,
- 132, 131, 131, 131, 11, 11, 11, 11,
- 11, 10, 10, 10, 48, 48, 48, 48,
- 187, 187, 187, 187, 187, 187, 187, 197,
- 197, 197, 197, 196, 196, 149, 132, 132,
- 131, 131, 131, 131, 11, 11, 11, 10,
- 10, 10, 10, 10, 48, 48, 48, 48,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 197, 150, 149, 149, 149, 148, 148, 148,
- 131, 131, 131, 130, 130, 26, 26, 10,
- 10, 10, 10, 10, 10, 48, 48, 48,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 150, 149, 149, 149, 149, 148, 148, 148,
- 147, 147, 147, 130, 130, 26, 26, 10,
- 10, 10, 10, 10, 80, 64, 64, 9,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 187, 149, 149, 149, 148, 148, 148, 147,
- 147, 147, 146, 146, 146, 26, 25, 10,
- 10, 10, 80, 80, 80, 64, 9, 9,
- 187, 187, 187, 187, 186, 186, 186, 186,
- 186, 149, 149, 148, 148, 148, 147, 147,
- 147, 147, 146, 146, 113, 25, 25, 24,
- 24, 80, 80, 80, 80, 9, 9, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 186, 149, 148, 148, 148, 147, 147,
- 147, 146, 146, 113, 113, 113, 112, 24,
- 24, 80, 80, 80, 64, 9, 9, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 186, 148, 148, 148, 147, 147, 147,
- 147, 146, 113, 113, 113, 113, 112, 112,
- 7, 80, 80, 80, 9, 9, 9, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 186, 181, 148, 147, 147, 147, 147,
- 146, 113, 113, 113, 113, 112, 112, 112,
- 112, 8, 22, 22, 9, 9, 9, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 182, 181, 181, 179, 147, 147, 96,
- 96, 96, 113, 113, 112, 112, 112, 8,
- 8, 8, 8, 8, 9, 9, 9, 9,
- 186, 186, 186, 186, 186, 185, 185, 185,
- 182, 182, 181, 181, 179, 97, 96, 96,
- 96, 96, 96, 96, 112, 112, 8, 8,
- 8, 8, 8, 8, 9, 9, 9, 9,
- 185, 185, 185, 185, 185, 185, 185, 185,
- 182, 182, 181, 181, 179, 179, 96, 96,
- 96, 96, 96, 96, 96, 8, 8, 8,
- 8, 8, 8, 8, 8, 9, 9, 9,
- 185, 185, 185, 185, 185, 185, 185, 182,
- 182, 182, 181, 181, 179, 179, 96, 96,
- 96, 96, 96, 96, 96, 8, 8, 8,
- 8, 8, 8, 8, 8, 202, 202, 202,
- 185, 185, 185, 185, 185, 185, 185, 182,
- 182, 182, 181, 181, 179, 179, 96, 96,
- 96, 96, 96, 96, 96, 8, 8, 8,
- 8, 8, 8, 8, 8, 202, 202, 202,
- 235, 235, 235, 235, 235, 235, 235, 234,
- 234, 234, 234, 5, 218, 218, 218, 218,
- 217, 217, 217, 217, 217, 216, 216, 216,
- 216, 216, 215, 215, 215, 215, 214, 214,
- 235, 235, 235, 235, 235, 235, 234, 234,
- 234, 234, 234, 219, 218, 218, 218, 218,
- 217, 217, 217, 217, 217, 216, 216, 216,
- 216, 216, 215, 215, 215, 215, 214, 214,
- 235, 235, 235, 235, 235, 234, 234, 234,
- 234, 234, 228, 219, 218, 218, 218, 218,
- 217, 217, 217, 217, 217, 216, 216, 216,
- 216, 216, 215, 215, 215, 215, 214, 214,
- 235, 235, 235, 235, 234, 234, 234, 234,
- 234, 228, 227, 227, 218, 218, 218, 218,
- 217, 217, 217, 217, 217, 216, 216, 216,
- 216, 215, 215, 215, 215, 215, 214, 214,
- 235, 235, 235, 234, 234, 234, 173, 173,
- 173, 173, 227, 227, 218, 218, 218, 218,
- 217, 217, 217, 217, 217, 216, 216, 216,
- 216, 215, 215, 215, 215, 215, 214, 214,
- 235, 235, 173, 173, 173, 173, 173, 173,
- 173, 173, 227, 226, 226, 218, 218, 218,
- 217, 217, 217, 217, 216, 216, 216, 216,
- 216, 215, 215, 215, 215, 215, 214, 214,
- 172, 172, 172, 172, 172, 172, 172, 172,
- 172, 172, 226, 226, 226, 218, 218, 218,
- 217, 217, 217, 217, 216, 216, 216, 216,
- 216, 215, 215, 215, 215, 215, 214, 214,
- 172, 172, 172, 172, 172, 172, 172, 172,
- 172, 172, 198, 198, 198, 225, 218, 218,
- 217, 217, 217, 217, 216, 216, 216, 216,
- 216, 215, 215, 215, 215, 215, 214, 214,
- 172, 172, 172, 172, 172, 172, 172, 172,
- 172, 198, 198, 198, 198, 198, 197, 197,
- 217, 217, 217, 217, 216, 216, 216, 216,
- 216, 215, 215, 215, 215, 214, 214, 214,
- 172, 172, 172, 172, 172, 172, 172, 172,
- 198, 198, 198, 198, 198, 198, 197, 197,
- 197, 217, 217, 216, 216, 216, 216, 216,
- 215, 215, 215, 215, 215, 214, 214, 214,
- 172, 172, 172, 172, 172, 172, 172, 172,
- 198, 198, 198, 198, 198, 197, 197, 197,
- 197, 196, 217, 216, 216, 216, 216, 216,
- 215, 215, 215, 215, 215, 214, 214, 214,
- 172, 172, 172, 172, 172, 172, 172, 198,
- 198, 198, 198, 198, 197, 197, 197, 197,
- 197, 196, 196, 12, 12, 216, 216, 216,
- 215, 215, 215, 215, 215, 214, 214, 214,
- 171, 171, 171, 171, 172, 172, 198, 198,
- 198, 198, 198, 197, 197, 197, 197, 197,
- 196, 196, 196, 12, 11, 11, 11, 11,
- 11, 11, 215, 215, 48, 48, 48, 48,
- 171, 171, 171, 171, 171, 171, 198, 198,
- 198, 198, 198, 197, 197, 197, 197, 196,
- 196, 196, 195, 11, 11, 11, 11, 11,
- 11, 11, 11, 48, 48, 48, 48, 48,
- 171, 171, 171, 171, 171, 198, 198, 198,
- 198, 198, 197, 197, 197, 197, 196, 196,
- 196, 196, 195, 11, 11, 11, 11, 11,
- 11, 11, 11, 48, 48, 48, 48, 48,
- 171, 171, 171, 171, 171, 198, 198, 198,
- 198, 197, 197, 197, 197, 196, 196, 196,
- 196, 195, 195, 11, 11, 11, 11, 11,
- 11, 11, 11, 48, 48, 48, 48, 48,
- 171, 171, 171, 171, 171, 198, 198, 198,
- 197, 197, 197, 197, 197, 196, 196, 196,
- 195, 195, 195, 131, 11, 11, 11, 11,
- 11, 11, 11, 48, 48, 48, 48, 48,
- 188, 188, 188, 188, 188, 198, 198, 198,
- 197, 197, 197, 197, 196, 196, 196, 195,
- 195, 195, 131, 131, 11, 11, 11, 11,
- 11, 10, 10, 10, 48, 48, 48, 48,
- 187, 187, 187, 187, 187, 187, 198, 197,
- 197, 197, 197, 196, 196, 196, 195, 195,
- 195, 131, 131, 131, 11, 11, 11, 11,
- 10, 10, 10, 10, 48, 48, 48, 48,
- 187, 187, 187, 187, 187, 187, 187, 197,
- 197, 197, 196, 196, 196, 196, 195, 195,
- 195, 131, 131, 130, 130, 11, 10, 10,
- 10, 10, 10, 10, 10, 48, 48, 48,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 197, 196, 196, 196, 196, 195, 195, 195,
- 131, 131, 130, 130, 130, 130, 10, 10,
- 10, 10, 10, 10, 10, 48, 48, 48,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 187, 196, 196, 196, 195, 148, 148, 147,
- 147, 147, 130, 130, 130, 129, 10, 10,
- 10, 10, 10, 10, 80, 80, 9, 9,
- 187, 187, 187, 187, 186, 186, 186, 186,
- 186, 149, 149, 148, 148, 148, 148, 147,
- 147, 147, 146, 146, 146, 129, 25, 10,
- 10, 10, 80, 80, 80, 80, 9, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 186, 149, 148, 148, 148, 147, 147,
- 147, 146, 146, 146, 145, 145, 24, 24,
- 24, 80, 80, 80, 80, 9, 9, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 186, 148, 148, 148, 147, 147, 147,
- 147, 146, 146, 145, 145, 145, 24, 24,
- 7, 23, 80, 80, 22, 9, 9, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 186, 181, 148, 147, 147, 147, 147,
- 146, 146, 145, 145, 145, 112, 112, 112,
- 23, 23, 22, 22, 22, 9, 9, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 182, 181, 181, 147, 147, 147, 147,
- 146, 145, 145, 145, 112, 112, 112, 112,
- 8, 22, 22, 22, 21, 9, 9, 9,
- 186, 186, 186, 186, 186, 185, 185, 185,
- 182, 182, 181, 181, 179, 179, 147, 145,
- 145, 145, 145, 112, 112, 112, 112, 8,
- 8, 8, 8, 21, 21, 21, 9, 9,
- 185, 185, 185, 185, 185, 185, 185, 185,
- 182, 182, 181, 181, 179, 179, 179, 96,
- 96, 96, 96, 112, 112, 112, 8, 8,
- 8, 8, 8, 21, 21, 20, 9, 9,
- 185, 185, 185, 185, 185, 185, 185, 182,
- 182, 182, 181, 181, 179, 179, 179, 177,
- 96, 96, 96, 96, 8, 8, 8, 8,
- 8, 8, 8, 8, 20, 20, 19, 9,
- 185, 185, 185, 185, 185, 185, 185, 182,
- 182, 182, 181, 181, 179, 179, 179, 177,
- 96, 96, 96, 96, 8, 8, 8, 8,
- 8, 8, 8, 8, 20, 19, 19, 19,
- 185, 185, 185, 185, 185, 185, 183, 182,
- 182, 182, 181, 181, 179, 179, 179, 177,
- 96, 96, 96, 96, 8, 8, 8, 8,
- 8, 8, 8, 8, 19, 19, 19, 18,
- 235, 234, 234, 234, 234, 234, 234, 234,
- 234, 234, 234, 228, 218, 218, 218, 217,
- 217, 217, 217, 217, 216, 216, 216, 216,
- 216, 215, 215, 215, 215, 214, 214, 214,
- 234, 234, 234, 234, 234, 234, 234, 234,
- 234, 234, 228, 228, 218, 218, 218, 217,
- 217, 217, 217, 217, 216, 216, 216, 216,
- 216, 215, 215, 215, 215, 214, 214, 214,
- 234, 234, 234, 234, 234, 234, 234, 234,
- 234, 228, 228, 227, 227, 218, 218, 217,
- 217, 217, 217, 217, 216, 216, 216, 216,
- 216, 215, 215, 215, 215, 214, 214, 214,
- 234, 234, 234, 234, 234, 234, 234, 234,
- 228, 228, 227, 227, 227, 218, 218, 217,
- 217, 217, 217, 217, 216, 216, 216, 216,
- 215, 215, 215, 215, 215, 214, 214, 214,
- 234, 234, 234, 234, 234, 234, 234, 228,
- 228, 227, 227, 227, 226, 218, 218, 217,
- 217, 217, 217, 217, 216, 216, 216, 216,
- 215, 215, 215, 215, 215, 214, 214, 214,
- 234, 234, 234, 172, 172, 172, 172, 172,
- 227, 227, 227, 226, 226, 226, 218, 217,
- 217, 217, 217, 216, 216, 216, 216, 216,
- 215, 215, 215, 215, 215, 214, 214, 214,
- 172, 172, 172, 172, 172, 172, 172, 172,
- 227, 227, 226, 226, 226, 225, 225, 217,
- 217, 217, 217, 216, 216, 216, 216, 216,
- 215, 215, 215, 215, 215, 214, 214, 214,
- 172, 172, 172, 172, 172, 172, 172, 172,
- 172, 226, 226, 226, 225, 225, 225, 217,
- 217, 217, 217, 216, 216, 216, 216, 216,
- 215, 215, 215, 215, 215, 214, 214, 214,
- 172, 172, 172, 172, 172, 172, 172, 172,
- 172, 226, 226, 225, 225, 225, 224, 224,
- 217, 217, 217, 216, 216, 216, 216, 216,
- 215, 215, 215, 215, 214, 214, 214, 214,
- 172, 172, 172, 172, 172, 172, 172, 172,
- 172, 198, 198, 198, 225, 224, 224, 224,
- 224, 217, 216, 216, 216, 216, 216, 215,
- 215, 215, 215, 215, 214, 214, 214, 214,
- 172, 172, 172, 172, 172, 172, 172, 172,
- 198, 198, 198, 198, 197, 197, 197, 197,
- 197, 196, 196, 216, 216, 216, 216, 215,
- 215, 215, 215, 215, 214, 214, 214, 214,
- 171, 171, 171, 171, 171, 172, 172, 198,
- 198, 198, 198, 197, 197, 197, 197, 197,
- 196, 196, 196, 196, 216, 216, 216, 215,
- 215, 215, 215, 215, 214, 214, 214, 214,
- 171, 171, 171, 171, 171, 171, 171, 198,
- 198, 198, 198, 197, 197, 197, 197, 196,
- 196, 196, 196, 195, 11, 11, 11, 11,
- 11, 215, 215, 215, 214, 214, 214, 214,
- 171, 171, 171, 171, 171, 171, 198, 198,
- 198, 198, 197, 197, 197, 197, 197, 196,
- 196, 196, 195, 195, 11, 11, 11, 11,
- 11, 11, 11, 11, 48, 48, 48, 48,
- 171, 171, 171, 171, 171, 171, 198, 198,
- 198, 197, 197, 197, 197, 197, 196, 196,
- 196, 195, 195, 195, 11, 11, 11, 11,
- 11, 11, 11, 11, 48, 48, 48, 48,
- 171, 171, 171, 171, 171, 171, 198, 198,
- 197, 197, 197, 197, 197, 196, 196, 196,
- 195, 195, 195, 194, 11, 11, 11, 11,
- 11, 11, 11, 10, 48, 48, 48, 48,
- 171, 171, 171, 171, 171, 198, 198, 198,
- 197, 197, 197, 197, 196, 196, 196, 196,
- 195, 195, 194, 194, 194, 11, 11, 11,
- 11, 11, 10, 10, 48, 48, 48, 48,
- 187, 187, 187, 171, 171, 198, 198, 197,
- 197, 197, 197, 196, 196, 196, 196, 195,
- 195, 195, 194, 194, 194, 11, 11, 11,
- 10, 10, 10, 10, 10, 48, 48, 48,
- 187, 187, 187, 187, 187, 187, 197, 197,
- 197, 197, 197, 196, 196, 196, 195, 195,
- 195, 194, 194, 194, 194, 11, 11, 10,
- 10, 10, 10, 10, 10, 48, 48, 48,
- 187, 187, 187, 187, 187, 187, 187, 197,
- 197, 197, 196, 196, 196, 195, 195, 195,
- 195, 194, 194, 194, 130, 130, 10, 10,
- 10, 10, 10, 10, 10, 10, 48, 48,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 197, 196, 196, 196, 195, 195, 195, 195,
- 194, 194, 194, 130, 130, 129, 10, 10,
- 10, 10, 10, 10, 10, 10, 48, 48,
- 187, 187, 187, 187, 186, 186, 186, 186,
- 196, 196, 196, 196, 195, 195, 195, 194,
- 194, 194, 130, 130, 129, 129, 10, 10,
- 10, 10, 10, 10, 80, 80, 9, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 196, 196, 195, 195, 195, 195, 147,
- 147, 146, 146, 129, 129, 129, 128, 10,
- 10, 10, 80, 80, 80, 80, 9, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 186, 195, 195, 195, 147, 147, 147,
- 147, 146, 146, 145, 145, 145, 128, 24,
- 7, 23, 23, 22, 22, 22, 9, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 186, 148, 148, 148, 147, 147, 147,
- 146, 146, 145, 145, 145, 128, 128, 7,
- 23, 23, 22, 22, 22, 21, 9, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 182, 181, 181, 147, 147, 147, 147,
- 146, 145, 145, 145, 145, 144, 144, 23,
- 23, 22, 22, 22, 21, 21, 21, 9,
- 186, 186, 186, 186, 186, 185, 185, 185,
- 182, 182, 181, 181, 179, 179, 147, 145,
- 145, 145, 145, 145, 144, 144, 112, 112,
- 22, 22, 22, 21, 21, 21, 20, 9,
- 185, 185, 185, 185, 185, 185, 185, 185,
- 182, 182, 181, 181, 179, 179, 179, 145,
- 145, 145, 145, 144, 144, 112, 8, 8,
- 8, 8, 21, 21, 21, 20, 20, 19,
- 185, 185, 185, 185, 185, 185, 185, 182,
- 182, 182, 181, 181, 179, 179, 179, 177,
- 177, 145, 145, 144, 112, 8, 8, 8,
- 8, 8, 21, 21, 20, 20, 19, 19,
- 185, 185, 185, 185, 185, 185, 185, 182,
- 182, 182, 181, 181, 179, 179, 179, 177,
- 177, 176, 176, 112, 8, 8, 8, 8,
- 8, 8, 8, 20, 20, 19, 19, 19,
- 185, 185, 185, 185, 185, 185, 183, 182,
- 182, 182, 181, 181, 179, 179, 179, 177,
- 177, 176, 176, 8, 8, 8, 8, 8,
- 8, 8, 8, 20, 19, 19, 19, 18,
- 185, 185, 185, 185, 185, 183, 183, 182,
- 182, 182, 181, 181, 179, 179, 179, 177,
- 177, 176, 176, 176, 8, 8, 8, 8,
- 8, 8, 8, 19, 19, 19, 18, 18,
- 234, 234, 234, 234, 234, 234, 234, 234,
- 234, 229, 229, 228, 228, 218, 217, 217,
- 217, 217, 217, 216, 216, 216, 216, 216,
- 215, 215, 215, 215, 214, 214, 214, 214,
- 234, 234, 234, 234, 234, 234, 234, 234,
- 229, 229, 228, 228, 227, 218, 217, 217,
- 217, 217, 217, 216, 216, 216, 216, 216,
- 215, 215, 215, 215, 214, 214, 214, 214,
- 234, 234, 234, 234, 234, 234, 234, 229,
- 229, 228, 228, 227, 227, 227, 217, 217,
- 217, 217, 217, 216, 216, 216, 216, 216,
- 215, 215, 215, 215, 214, 214, 214, 214,
- 234, 234, 234, 234, 234, 234, 229, 229,
- 228, 228, 227, 227, 227, 226, 217, 217,
- 217, 217, 217, 216, 216, 216, 216, 215,
- 215, 215, 215, 215, 214, 214, 214, 214,
- 234, 234, 234, 234, 234, 229, 229, 228,
- 228, 227, 227, 227, 226, 226, 226, 217,
- 217, 217, 217, 216, 216, 216, 216, 215,
- 215, 215, 215, 215, 214, 214, 214, 214,
- 234, 234, 234, 234, 172, 229, 228, 228,
- 227, 227, 227, 226, 226, 226, 225, 217,
- 217, 217, 216, 216, 216, 216, 216, 215,
- 215, 215, 215, 215, 214, 214, 214, 214,
- 172, 172, 172, 172, 172, 172, 228, 227,
- 227, 227, 226, 226, 226, 225, 225, 225,
- 217, 217, 216, 216, 216, 216, 216, 215,
- 215, 215, 215, 215, 214, 214, 214, 214,
- 172, 172, 172, 172, 172, 172, 172, 227,
- 227, 226, 226, 226, 225, 225, 225, 224,
- 224, 217, 216, 216, 216, 216, 216, 215,
- 215, 215, 215, 215, 214, 214, 214, 214,
- 172, 172, 172, 172, 172, 172, 172, 172,
- 226, 226, 226, 225, 225, 225, 224, 224,
- 224, 217, 216, 216, 216, 216, 216, 215,
- 215, 215, 215, 214, 214, 214, 214, 214,
- 172, 172, 172, 172, 172, 172, 172, 172,
- 226, 226, 225, 225, 225, 224, 224, 224,
- 224, 224, 216, 216, 216, 216, 215, 215,
- 215, 215, 215, 214, 214, 214, 214, 214,
- 171, 171, 171, 171, 171, 171, 171, 172,
- 226, 225, 225, 225, 224, 224, 224, 224,
- 224, 224, 224, 216, 216, 216, 215, 215,
- 215, 215, 215, 214, 214, 214, 214, 214,
- 171, 171, 171, 171, 171, 171, 171, 171,
- 198, 198, 225, 197, 197, 224, 224, 224,
- 196, 196, 196, 195, 216, 216, 215, 215,
- 215, 215, 215, 214, 214, 214, 214, 214,
- 171, 171, 171, 171, 171, 171, 171, 171,
- 198, 198, 197, 197, 197, 197, 197, 196,
- 196, 196, 196, 195, 194, 11, 11, 11,
- 215, 215, 215, 214, 214, 214, 214, 214,
- 171, 171, 171, 171, 171, 171, 171, 198,
- 198, 197, 197, 197, 197, 197, 196, 196,
- 196, 196, 195, 195, 194, 11, 11, 11,
- 11, 11, 11, 214, 214, 214, 48, 48,
- 171, 171, 171, 171, 171, 171, 171, 198,
- 197, 197, 197, 197, 197, 196, 196, 196,
- 196, 195, 195, 194, 194, 11, 11, 11,
- 11, 11, 11, 10, 48, 48, 48, 48,
- 171, 171, 171, 171, 171, 171, 171, 198,
- 197, 197, 197, 197, 197, 196, 196, 196,
- 195, 195, 195, 194, 194, 11, 11, 11,
- 11, 11, 10, 10, 10, 48, 48, 48,
- 170, 171, 171, 171, 171, 171, 198, 197,
- 197, 197, 197, 197, 196, 196, 196, 195,
- 195, 195, 194, 194, 194, 194, 11, 11,
- 10, 10, 10, 10, 10, 48, 48, 48,
- 170, 170, 170, 171, 171, 169, 197, 197,
- 197, 197, 197, 196, 196, 196, 195, 195,
- 195, 194, 194, 194, 194, 193, 11, 10,
- 10, 10, 10, 10, 10, 10, 48, 48,
- 187, 187, 187, 187, 169, 169, 169, 197,
- 197, 197, 196, 196, 196, 196, 195, 195,
- 195, 194, 194, 194, 193, 193, 193, 10,
- 10, 10, 10, 10, 10, 10, 48, 48,
- 187, 187, 187, 187, 187, 187, 169, 197,
- 197, 196, 196, 196, 196, 195, 195, 195,
- 194, 194, 194, 194, 193, 193, 193, 10,
- 10, 10, 10, 10, 10, 10, 10, 48,
- 187, 187, 187, 187, 186, 186, 186, 167,
- 197, 196, 196, 196, 195, 195, 195, 195,
- 194, 194, 194, 193, 193, 193, 192, 10,
- 10, 10, 10, 10, 10, 10, 80, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 167, 196, 196, 195, 195, 195, 195, 194,
- 194, 194, 193, 193, 193, 192, 192, 10,
- 10, 10, 10, 10, 22, 22, 22, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 196, 195, 195, 195, 195, 194, 194,
- 194, 193, 193, 193, 129, 192, 192, 128,
- 10, 23, 23, 22, 22, 22, 21, 9,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 166, 195, 195, 195, 195, 194, 194,
- 193, 193, 193, 145, 145, 192, 128, 128,
- 23, 23, 22, 22, 22, 21, 21, 21,
- 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 182, 181, 195, 195, 147, 147, 193,
- 193, 145, 145, 145, 145, 128, 128, 128,
- 23, 22, 22, 22, 21, 21, 21, 20,
- 186, 186, 186, 186, 186, 185, 185, 185,
- 182, 182, 181, 181, 179, 147, 147, 145,
- 145, 145, 145, 145, 144, 144, 144, 144,
- 22, 22, 22, 21, 21, 21, 20, 20,
- 185, 185, 185, 185, 185, 185, 185, 185,
- 182, 182, 181, 181, 179, 179, 179, 145,
- 145, 145, 145, 145, 144, 144, 144, 144,
- 22, 22, 21, 21, 21, 20, 20, 19,
- 185, 185, 185, 185, 185, 185, 185, 182,
- 182, 182, 181, 181, 179, 179, 179, 177,
- 145, 145, 145, 144, 144, 144, 144, 8,
- 8, 21, 21, 21, 20, 20, 19, 19,
- 185, 185, 185, 185, 185, 185, 185, 182,
- 182, 182, 181, 181, 179, 179, 179, 177,
- 177, 176, 144, 144, 144, 144, 8, 8,
- 8, 21, 21, 20, 20, 19, 19, 19,
- 185, 185, 185, 185, 185, 185, 183, 182,
- 182, 182, 181, 181, 179, 179, 179, 177,
- 177, 176, 176, 176, 8, 8, 8, 8,
- 8, 8, 20, 20, 19, 19, 19, 18,
- 185, 185, 185, 185, 185, 183, 183, 182,
- 182, 182, 181, 181, 179, 179, 179, 177,
- 177, 176, 176, 176, 8, 8, 8, 8,
- 8, 8, 20, 19, 19, 19, 18, 18,
- 184, 184, 184, 184, 183, 183, 183, 182,
- 182, 182, 181, 181, 179, 179, 179, 177,
- 177, 176, 176, 176, 176, 8, 8, 8,
- 8, 8, 19, 19, 19, 18, 18, 18,
- 233, 233, 233, 233, 233, 233, 233, 233,
- 229, 229, 228, 228, 228, 227, 217, 217,
- 217, 217, 216, 216, 216, 216, 216, 215,
- 215, 215, 215, 214, 214, 214, 214, 253,
- 233, 233, 233, 233, 233, 233, 233, 229,
- 229, 228, 228, 228, 227, 227, 217, 217,
- 217, 217, 216, 216, 216, 216, 216, 215,
- 215, 215, 215, 214, 214, 214, 214, 214,
- 233, 233, 233, 233, 233, 233, 229, 229,
- 228, 228, 228, 227, 227, 227, 217, 217,
- 217, 217, 216, 216, 216, 216, 216, 215,
- 215, 215, 215, 214, 214, 214, 214, 214,
- 233, 233, 233, 233, 233, 229, 229, 228,
- 228, 228, 227, 227, 227, 226, 226, 217,
- 217, 217, 216, 216, 216, 216, 215, 215,
- 215, 215, 215, 214, 214, 214, 214, 214,
- 233, 233, 233, 233, 229, 229, 228, 228,
- 228, 227, 227, 227, 226, 226, 226, 217,
- 217, 217, 216, 216, 216, 216, 215, 215,
- 215, 215, 215, 214, 214, 214, 214, 214,
- 233, 233, 233, 229, 229, 228, 228, 228,
- 227, 227, 227, 226, 226, 226, 225, 225,
- 217, 216, 216, 216, 216, 216, 215, 215,
- 215, 215, 215, 214, 214, 214, 214, 214,
- 233, 172, 172, 229, 228, 228, 228, 227,
- 227, 227, 226, 226, 226, 225, 225, 225,
- 224, 216, 216, 216, 216, 216, 215, 215,
- 215, 215, 215, 214, 214, 214, 214, 214,
- 172, 172, 172, 172, 172, 228, 227, 227,
- 227, 226, 226, 226, 225, 225, 225, 224,
- 224, 216, 216, 216, 216, 216, 215, 215,
- 215, 215, 215, 214, 214, 214, 214, 214,
- 171, 171, 172, 172, 172, 172, 227, 227,
- 226, 226, 226, 225, 225, 225, 224, 224,
- 224, 224, 216, 216, 216, 216, 215, 215,
- 215, 215, 214, 214, 214, 214, 214, 214,
- 171, 171, 171, 171, 171, 171, 171, 226,
- 226, 226, 225, 225, 225, 224, 224, 224,
- 224, 224, 224, 216, 216, 215, 215, 215,
- 215, 215, 214, 214, 214, 214, 214, 214,
- 171, 171, 171, 171, 171, 171, 171, 226,
- 226, 225, 225, 225, 224, 224, 224, 224,
- 224, 224, 224, 216, 216, 215, 215, 215,
- 215, 215, 214, 214, 214, 214, 214, 214,
- 171, 171, 171, 171, 171, 171, 171, 171,
- 225, 225, 225, 224, 224, 224, 224, 224,
- 224, 224, 224, 224, 216, 215, 215, 215,
- 215, 215, 214, 214, 214, 214, 214, 214,
- 171, 171, 171, 171, 171, 171, 171, 171,
- 225, 225, 224, 224, 224, 224, 224, 224,
- 224, 196, 195, 195, 194, 194, 11, 215,
- 215, 215, 214, 214, 214, 214, 214, 214,
- 171, 171, 171, 171, 171, 171, 171, 171,
- 198, 197, 197, 197, 197, 197, 196, 196,
- 196, 195, 195, 194, 194, 194, 11, 11,
- 11, 11, 214, 214, 214, 214, 214, 214,
- 171, 171, 171, 171, 171, 171, 171, 171,
- 197, 197, 197, 197, 197, 196, 196, 196,
- 196, 195, 195, 194, 194, 194, 11, 11,
- 11, 11, 10, 10, 10, 48, 48, 48,
- 170, 170, 171, 171, 171, 171, 171, 197,
- 197, 197, 197, 197, 196, 196, 196, 196,
- 195, 195, 194, 194, 194, 194, 11, 11,
- 11, 10, 10, 10, 10, 48, 48, 48,
- 170, 170, 170, 170, 171, 171, 169, 197,
- 197, 197, 197, 196, 196, 196, 196, 195,
- 195, 195, 194, 194, 194, 194, 193, 10,
- 10, 10, 10, 10, 10, 10, 48, 48,
- 170, 170, 170, 170, 169, 169, 169, 197,
- 197, 197, 197, 196, 196, 196, 195, 195,
- 195, 194, 194, 194, 194, 193, 193, 10,
- 10, 10, 10, 10, 10, 10, 48, 48,
- 170, 168, 168, 168, 169, 169, 169, 169,
- 197, 197, 196, 196, 196, 195, 195, 195,
- 194, 194, 194, 194, 193, 193, 193, 10,
- 10, 10, 10, 10, 10, 10, 10, 48,
- 168, 168, 168, 168, 169, 169, 169, 169,
- 197, 196, 196, 196, 195, 195, 195, 195,
- 194, 194, 194, 193, 193, 193, 193, 192,
- 10, 10, 10, 10, 10, 10, 10, 48,
- 186, 186, 186, 168, 168, 167, 167, 167,
- 167, 196, 196, 196, 195, 195, 195, 194,
- 194, 194, 193, 193, 193, 193, 192, 192,
- 10, 10, 10, 10, 10, 22, 22, 21,
- 186, 186, 186, 186, 186, 167, 167, 167,
- 167, 167, 196, 195, 195, 195, 195, 194,
- 194, 193, 193, 193, 193, 192, 192, 192,
- 192, 10, 10, 22, 22, 22, 21, 21,
- 186, 186, 186, 186, 186, 186, 167, 167,
- 167, 167, 195, 195, 195, 195, 194, 194,
- 194, 193, 193, 193, 192, 192, 192, 192,
- 192, 23, 22, 22, 22, 21, 21, 21,
- 186, 186, 186, 186, 186, 186, 186, 166,
- 166, 166, 166, 195, 195, 194, 194, 194,
- 193, 193, 193, 193, 192, 192, 192, 128,
- 128, 22, 22, 22, 21, 21, 21, 20,
- 186, 186, 186, 186, 186, 185, 185, 166,
- 166, 166, 181, 181, 195, 194, 194, 193,
- 193, 193, 145, 145, 192, 128, 128, 128,
- 22, 22, 22, 21, 21, 21, 20, 20,
- 185, 185, 185, 185, 185, 185, 185, 185,
- 182, 182, 181, 181, 179, 179, 163, 193,
- 145, 145, 145, 145, 144, 144, 144, 144,
- 22, 22, 21, 21, 21, 20, 20, 19,
- 185, 185, 185, 185, 185, 185, 185, 182,
- 182, 182, 181, 181, 179, 179, 163, 163,
- 145, 145, 145, 144, 144, 144, 144, 144,
- 22, 21, 21, 21, 20, 20, 19, 19,
- 185, 185, 185, 185, 185, 185, 185, 182,
- 182, 182, 181, 181, 179, 179, 179, 177,
- 177, 176, 144, 144, 144, 144, 144, 144,
- 21, 21, 21, 20, 20, 19, 19, 19,
- 185, 185, 185, 185, 185, 185, 183, 182,
- 182, 182, 181, 181, 179, 179, 179, 177,
- 177, 176, 176, 144, 144, 144, 144, 8,
- 21, 21, 20, 20, 19, 19, 19, 18,
- 185, 185, 185, 185, 185, 183, 183, 182,
- 182, 182, 181, 181, 179, 179, 179, 177,
- 177, 176, 176, 176, 176, 8, 8, 8,
- 8, 20, 20, 19, 19, 19, 18, 18,
- 184, 184, 184, 184, 183, 183, 183, 182,
- 182, 182, 181, 181, 179, 179, 179, 177,
- 177, 176, 176, 176, 176, 8, 8, 8,
- 8, 20, 19, 19, 19, 18, 18, 18,
- 184, 184, 184, 184, 183, 183, 183, 182,
- 182, 181, 181, 181, 179, 179, 177, 177,
- 177, 176, 176, 176, 176, 160, 160, 8,
- 8, 19, 19, 19, 18, 18, 18, 17,
- 233, 232, 232, 232, 232, 232, 232, 229,
- 229, 229, 228, 228, 228, 227, 217, 217,
- 217, 216, 216, 216, 216, 216, 215, 215,
- 215, 215, 214, 214, 214, 214, 253, 253,
- 232, 232, 232, 232, 232, 232, 229, 229,
- 229, 228, 228, 228, 227, 227, 227, 217,
- 217, 216, 216, 216, 216, 216, 215, 215,
- 215, 215, 214, 214, 214, 214, 214, 253,
- 232, 232, 232, 232, 232, 229, 229, 229,
- 228, 228, 228, 227, 227, 227, 226, 217,
- 217, 216, 216, 216, 216, 216, 215, 215,
- 215, 215, 214, 214, 214, 214, 214, 214,
- 232, 232, 232, 232, 229, 229, 229, 228,
- 228, 228, 227, 227, 227, 226, 226, 226,
- 217, 216, 216, 216, 216, 215, 215, 215,
- 215, 215, 214, 214, 214, 214, 214, 214,
- 232, 232, 232, 229, 229, 229, 228, 228,
- 228, 227, 227, 227, 226, 226, 226, 225,
- 217, 216, 216, 216, 216, 215, 215, 215,
- 215, 215, 214, 214, 214, 214, 214, 214,
- 232, 232, 229, 229, 229, 228, 228, 228,
- 227, 227, 227, 226, 226, 226, 225, 225,
- 225, 216, 216, 216, 216, 215, 215, 215,
- 215, 215, 214, 214, 214, 214, 214, 214,
- 232, 229, 229, 229, 228, 228, 228, 227,
- 227, 227, 226, 226, 226, 225, 225, 225,
- 224, 216, 216, 216, 216, 215, 215, 215,
- 215, 215, 214, 214, 214, 214, 214, 214,
- 171, 171, 229, 228, 228, 228, 227, 227,
- 227, 226, 226, 226, 225, 225, 225, 224,
- 224, 224, 216, 216, 216, 215, 215, 215,
- 215, 215, 214, 214, 214, 214, 214, 214,
- 171, 171, 171, 171, 171, 227, 227, 227,
- 226, 226, 226, 225, 225, 225, 224, 224,
- 224, 224, 224, 216, 216, 215, 215, 215,
- 215, 214, 214, 214, 214, 214, 214, 214,
- 171, 171, 171, 171, 171, 171, 227, 226,
- 226, 226, 225, 225, 225, 224, 224, 224,
- 224, 224, 224, 216, 215, 215, 215, 215,
- 215, 214, 214, 214, 214, 214, 214, 214,
- 171, 171, 171, 171, 171, 171, 171, 226,
- 226, 225, 225, 225, 224, 224, 224, 224,
- 224, 224, 224, 224, 215, 215, 215, 215,
- 215, 214, 214, 214, 214, 214, 214, 214,
- 171, 171, 171, 171, 171, 171, 171, 226,
- 225, 225, 225, 224, 224, 224, 224, 224,
- 224, 224, 224, 224, 224, 215, 215, 215,
- 215, 214, 214, 214, 214, 214, 214, 214,
- 171, 171, 171, 171, 171, 171, 171, 225,
- 225, 225, 224, 224, 224, 224, 224, 224,
- 224, 224, 224, 195, 194, 194, 215, 215,
- 215, 214, 214, 214, 214, 214, 214, 214,
- 170, 171, 171, 171, 171, 171, 171, 171,
- 225, 224, 224, 224, 224, 224, 224, 224,
- 224, 195, 195, 194, 194, 194, 194, 11,
- 11, 214, 214, 214, 214, 214, 214, 214,
- 170, 170, 170, 171, 171, 171, 171, 171,
- 224, 224, 224, 224, 224, 224, 224, 196,
- 195, 195, 194, 194, 194, 194, 194, 11,
- 11, 10, 10, 10, 10, 214, 214, 214,
- 170, 170, 170, 170, 170, 171, 171, 169,
- 197, 197, 197, 197, 196, 196, 196, 195,
- 195, 195, 194, 194, 194, 194, 193, 193,
- 10, 10, 10, 10, 10, 10, 48, 48,
- 170, 170, 170, 170, 170, 169, 169, 169,
- 197, 197, 197, 196, 196, 196, 196, 195,
- 195, 194, 194, 194, 194, 193, 193, 193,
- 10, 10, 10, 10, 10, 10, 10, 48,
- 170, 170, 170, 169, 169, 169, 169, 169,
- 169, 197, 196, 196, 196, 196, 195, 195,
- 195, 194, 194, 194, 193, 193, 193, 193,
- 10, 10, 10, 10, 10, 10, 10, 48,
- 168, 168, 168, 168, 169, 169, 169, 169,
- 169, 196, 196, 196, 196, 195, 195, 195,
- 194, 194, 194, 194, 193, 193, 193, 192,
- 192, 10, 10, 10, 10, 10, 10, 10,
- 168, 168, 168, 168, 169, 169, 169, 169,
- 167, 196, 196, 196, 195, 195, 195, 194,
- 194, 194, 194, 193, 193, 193, 192, 192,
- 192, 10, 10, 10, 10, 10, 22, 21,
- 168, 168, 168, 168, 168, 167, 167, 167,
- 167, 167, 196, 195, 195, 195, 195, 194,
- 194, 194, 193, 193, 193, 193, 192, 192,
- 192, 192, 10, 10, 22, 22, 21, 21,
- 168, 168, 168, 168, 167, 167, 167, 167,
- 167, 167, 167, 195, 195, 195, 194, 194,
- 194, 193, 193, 193, 193, 192, 192, 192,
- 192, 192, 22, 22, 22, 21, 21, 21,
- 186, 186, 186, 186, 167, 167, 167, 167,
- 167, 167, 167, 195, 195, 195, 194, 194,
- 193, 193, 193, 193, 192, 192, 192, 192,
- 192, 192, 22, 22, 21, 21, 21, 20,
- 186, 186, 186, 186, 166, 166, 166, 166,
- 166, 166, 166, 195, 195, 194, 194, 193,
- 193, 193, 193, 192, 192, 192, 192, 192,
- 128, 22, 22, 21, 21, 21, 20, 20,
- 185, 185, 185, 185, 185, 166, 166, 166,
- 166, 166, 166, 181, 163, 163, 193, 193,
- 193, 193, 193, 192, 192, 192, 192, 128,
- 128, 22, 21, 21, 21, 20, 20, 19,
- 185, 185, 185, 185, 185, 185, 185, 164,
- 182, 182, 181, 181, 179, 163, 163, 163,
- 193, 145, 145, 192, 144, 144, 144, 144,
- 22, 21, 21, 21, 20, 20, 19, 19,
- 185, 185, 185, 185, 185, 185, 185, 182,
- 182, 182, 181, 181, 179, 163, 163, 163,
- 163, 145, 145, 144, 144, 144, 144, 144,
- 21, 21, 21, 20, 20, 19, 19, 19,
- 185, 185, 185, 185, 185, 185, 183, 182,
- 182, 182, 181, 181, 179, 179, 163, 163,
- 177, 176, 176, 144, 144, 144, 144, 144,
- 21, 21, 20, 20, 19, 19, 19, 18,
- 185, 185, 185, 185, 185, 183, 183, 182,
- 182, 182, 181, 181, 179, 179, 179, 177,
- 177, 176, 176, 176, 144, 144, 144, 21,
- 21, 20, 20, 19, 19, 19, 18, 18,
- 184, 184, 184, 184, 183, 183, 183, 182,
- 182, 182, 181, 181, 179, 179, 179, 177,
- 177, 176, 176, 176, 176, 176, 8, 8,
- 20, 20, 19, 19, 19, 18, 18, 18,
- 184, 184, 184, 184, 183, 183, 183, 182,
- 182, 181, 181, 181, 179, 179, 177, 177,
- 177, 176, 176, 176, 176, 160, 160, 160,
- 20, 19, 19, 19, 18, 18, 18, 17,
- 184, 184, 184, 184, 183, 183, 183, 182,
- 182, 181, 181, 181, 179, 179, 177, 177,
- 177, 176, 176, 176, 176, 160, 160, 160,
- 160, 19, 19, 18, 18, 18, 17, 17,
- 232, 232, 232, 232, 232, 230, 230, 229,
- 229, 229, 228, 228, 228, 227, 227, 217,
- 216, 216, 216, 216, 216, 215, 215, 215,
- 215, 214, 214, 214, 214, 253, 253, 253,
- 232, 232, 232, 232, 230, 230, 229, 229,
- 229, 228, 228, 228, 227, 227, 227, 226,
- 216, 216, 216, 216, 216, 215, 215, 215,
- 215, 214, 214, 214, 214, 214, 253, 253,
- 232, 232, 232, 230, 230, 229, 229, 229,
- 228, 228, 228, 227, 227, 227, 226, 226,
- 216, 216, 216, 216, 216, 215, 215, 215,
- 215, 214, 214, 214, 214, 214, 214, 253,
- 232, 232, 230, 230, 229, 229, 229, 228,
- 228, 228, 227, 227, 227, 226, 226, 226,
- 216, 216, 216, 216, 215, 215, 215, 215,
- 215, 214, 214, 214, 214, 214, 214, 214,
- 232, 230, 230, 229, 229, 229, 228, 228,
- 228, 227, 227, 227, 226, 226, 226, 225,
- 225, 216, 216, 216, 215, 215, 215, 215,
- 215, 214, 214, 214, 214, 214, 214, 214,
- 230, 230, 229, 229, 229, 228, 228, 228,
- 227, 227, 227, 226, 226, 226, 225, 225,
- 225, 216, 216, 216, 215, 215, 215, 215,
- 215, 214, 214, 214, 214, 214, 214, 214,
- 230, 229, 229, 229, 228, 228, 228, 227,
- 227, 227, 226, 226, 226, 225, 225, 225,
- 224, 224, 216, 216, 215, 215, 215, 215,
- 215, 214, 214, 214, 214, 214, 214, 214,
- 229, 229, 229, 228, 228, 228, 227, 227,
- 227, 226, 226, 226, 225, 225, 225, 224,
- 224, 224, 224, 216, 215, 215, 215, 215,
- 215, 214, 214, 214, 214, 214, 214, 214,
- 171, 171, 171, 228, 228, 227, 227, 227,
- 226, 226, 226, 225, 225, 225, 224, 224,
- 224, 224, 224, 216, 215, 215, 215, 215,
- 214, 214, 214, 214, 214, 214, 214, 214,
- 171, 171, 171, 171, 171, 227, 227, 226,
- 226, 226, 225, 225, 225, 224, 224, 224,
- 224, 224, 224, 224, 215, 215, 215, 215,
- 214, 214, 214, 214, 214, 214, 214, 214,
- 171, 171, 171, 171, 171, 171, 226, 226,
- 226, 225, 225, 225, 224, 224, 224, 224,
- 224, 224, 224, 224, 224, 215, 215, 215,
- 214, 214, 214, 214, 214, 214, 214, 214,
- 171, 171, 171, 171, 171, 171, 226, 226,
- 225, 225, 225, 224, 224, 224, 224, 224,
- 224, 224, 224, 224, 224, 215, 215, 215,
- 214, 214, 214, 214, 214, 214, 214, 214,
- 170, 170, 171, 171, 171, 171, 171, 225,
- 225, 225, 224, 224, 224, 224, 224, 224,
- 224, 224, 224, 224, 194, 194, 215, 215,
- 214, 214, 214, 214, 214, 214, 214, 214,
- 170, 170, 170, 170, 171, 171, 171, 225,
- 225, 224, 224, 224, 224, 224, 224, 224,
- 224, 224, 224, 194, 194, 194, 194, 194,
- 214, 214, 214, 214, 214, 214, 214, 214,
- 170, 170, 170, 170, 170, 170, 170, 225,
- 224, 224, 224, 224, 224, 224, 224, 224,
- 224, 195, 194, 194, 194, 194, 194, 193,
- 193, 10, 10, 10, 214, 214, 214, 214,
- 170, 170, 170, 170, 170, 170, 169, 169,
- 224, 224, 224, 224, 224, 224, 224, 195,
- 195, 194, 194, 194, 194, 194, 193, 193,
- 193, 10, 10, 10, 10, 10, 10, 48,
- 170, 170, 170, 170, 169, 169, 169, 169,
- 169, 224, 224, 224, 196, 196, 195, 195,
- 195, 194, 194, 194, 194, 193, 193, 193,
- 192, 10, 10, 10, 10, 10, 10, 48,
- 170, 170, 168, 169, 169, 169, 169, 169,
- 169, 169, 196, 196, 196, 195, 195, 195,
- 194, 194, 194, 194, 193, 193, 193, 193,
- 192, 192, 10, 10, 10, 10, 10, 10,
- 168, 168, 168, 168, 169, 169, 169, 169,
- 169, 169, 196, 196, 196, 195, 195, 195,
- 194, 194, 194, 193, 193, 193, 193, 192,
- 192, 192, 10, 10, 10, 10, 10, 21,
- 168, 168, 168, 168, 169, 169, 169, 169,
- 167, 167, 196, 196, 195, 195, 195, 194,
- 194, 194, 193, 193, 193, 193, 192, 192,
- 192, 192, 192, 10, 10, 22, 21, 21,
- 168, 168, 168, 168, 168, 167, 167, 167,
- 167, 167, 167, 195, 195, 195, 194, 194,
- 194, 193, 193, 193, 193, 192, 192, 192,
- 192, 192, 192, 22, 22, 21, 21, 21,
- 168, 168, 168, 168, 167, 167, 167, 167,
- 167, 167, 167, 195, 195, 195, 194, 194,
- 194, 193, 193, 193, 193, 192, 192, 192,
- 192, 192, 22, 22, 21, 21, 21, 20,
- 165, 165, 165, 167, 167, 167, 167, 167,
- 167, 167, 167, 167, 195, 194, 194, 194,
- 193, 193, 193, 193, 192, 192, 192, 192,
- 192, 192, 22, 21, 21, 21, 20, 20,
- 165, 165, 165, 165, 166, 166, 166, 166,
- 166, 166, 166, 166, 163, 194, 194, 193,
- 193, 193, 193, 192, 192, 192, 192, 192,
- 192, 22, 21, 21, 21, 20, 20, 19,
- 165, 165, 165, 165, 165, 166, 166, 166,
- 166, 166, 166, 181, 163, 163, 163, 193,
- 193, 193, 192, 192, 192, 192, 192, 192,
- 128, 21, 21, 21, 20, 20, 19, 19,
- 185, 185, 185, 185, 165, 164, 164, 164,
- 164, 182, 181, 181, 163, 163, 163, 163,
- 163, 193, 192, 192, 192, 144, 144, 144,
- 144, 21, 21, 20, 20, 19, 19, 19,
- 185, 185, 185, 185, 185, 164, 164, 164,
- 182, 182, 181, 181, 179, 163, 163, 163,
- 163, 163, 176, 144, 144, 144, 144, 144,
- 21, 21, 20, 20, 19, 19, 19, 18,
- 185, 185, 185, 185, 185, 183, 183, 182,
- 182, 182, 181, 181, 179, 163, 163, 163,
- 163, 176, 176, 176, 144, 144, 144, 144,
- 21, 20, 20, 19, 19, 19, 18, 18,
- 184, 184, 184, 184, 183, 183, 183, 182,
- 182, 182, 181, 181, 179, 179, 163, 163,
- 177, 176, 176, 176, 176, 144, 144, 21,
- 20, 20, 19, 19, 19, 18, 18, 18,
- 184, 184, 184, 184, 183, 183, 183, 182,
- 182, 181, 181, 181, 179, 179, 177, 177,
- 177, 176, 176, 176, 176, 160, 160, 160,
- 20, 19, 19, 19, 18, 18, 18, 17,
- 184, 184, 184, 184, 183, 183, 183, 182,
- 182, 181, 181, 181, 179, 179, 177, 177,
- 177, 176, 176, 176, 176, 160, 160, 160,
- 160, 19, 19, 18, 18, 18, 17, 17,
- 184, 184, 184, 184, 183, 183, 183, 182,
- 182, 181, 181, 181, 179, 179, 177, 177,
- 177, 176, 176, 176, 176, 160, 160, 160,
- 160, 19, 18, 18, 18, 17, 17, 17,
- 249, 231, 231, 231, 230, 230, 230, 229,
- 229, 229, 228, 228, 228, 227, 227, 227,
- 216, 216, 216, 216, 215, 215, 215, 215,
- 214, 214, 214, 214, 253, 253, 253, 253,
- 231, 231, 231, 230, 230, 230, 229, 229,
- 229, 228, 228, 228, 227, 227, 227, 226,
- 216, 216, 216, 216, 215, 215, 215, 215,
- 214, 214, 214, 214, 214, 253, 253, 253,
- 231, 231, 230, 230, 230, 229, 229, 229,
- 228, 228, 228, 227, 227, 227, 226, 226,
- 226, 216, 216, 216, 215, 215, 215, 215,
- 214, 214, 214, 214, 214, 214, 253, 253,
- 231, 230, 230, 230, 229, 229, 229, 228,
- 228, 228, 227, 227, 227, 226, 226, 226,
- 225, 216, 216, 215, 215, 215, 215, 215,
- 214, 214, 214, 214, 214, 214, 214, 253,
- 230, 230, 230, 229, 229, 229, 228, 228,
- 228, 227, 227, 227, 226, 226, 226, 225,
- 225, 216, 216, 215, 215, 215, 215, 215,
- 214, 214, 214, 214, 214, 214, 214, 214,
- 230, 230, 229, 229, 229, 228, 228, 228,
- 227, 227, 227, 226, 226, 226, 225, 225,
- 225, 224, 216, 215, 215, 215, 215, 215,
- 214, 214, 214, 214, 214, 214, 214, 214,
- 230, 229, 229, 229, 228, 228, 228, 227,
- 227, 227, 226, 226, 226, 225, 225, 225,
- 224, 224, 224, 215, 215, 215, 215, 215,
- 214, 214, 214, 214, 214, 214, 214, 214,
- 229, 229, 229, 228, 228, 228, 227, 227,
- 227, 226, 226, 226, 225, 225, 225, 224,
- 224, 224, 224, 215, 215, 215, 215, 215,
- 214, 214, 214, 214, 214, 214, 214, 214,
- 171, 171, 228, 228, 228, 227, 227, 227,
- 226, 226, 226, 225, 225, 225, 224, 224,
- 224, 224, 224, 224, 215, 215, 215, 214,
- 214, 214, 214, 214, 214, 214, 214, 214,
- 171, 171, 171, 171, 227, 227, 227, 226,
- 226, 226, 225, 225, 225, 224, 224, 224,
- 224, 224, 224, 224, 215, 215, 215, 214,
- 214, 214, 214, 214, 214, 214, 214, 214,
- 170, 171, 171, 171, 171, 227, 226, 226,
- 226, 225, 225, 225, 224, 224, 224, 224,
- 224, 224, 224, 224, 224, 215, 215, 214,
- 214, 214, 214, 214, 214, 214, 214, 214,
- 170, 170, 170, 171, 171, 171, 226, 226,
- 225, 225, 225, 224, 224, 224, 224, 224,
- 224, 224, 224, 224, 224, 215, 215, 214,
- 214, 214, 214, 214, 214, 214, 214, 214,
- 170, 170, 170, 170, 170, 170, 226, 225,
- 225, 225, 224, 224, 224, 224, 224, 224,
- 224, 224, 224, 224, 224, 194, 215, 214,
- 214, 214, 214, 214, 214, 214, 214, 214,
- 170, 170, 170, 170, 170, 170, 170, 225,
- 225, 224, 224, 224, 224, 224, 224, 224,
- 224, 224, 224, 224, 194, 194, 194, 193,
- 214, 214, 214, 214, 214, 214, 214, 214,
- 170, 170, 170, 170, 170, 170, 170, 225,
- 224, 224, 224, 224, 224, 224, 224, 224,
- 224, 224, 194, 194, 194, 194, 193, 193,
- 193, 10, 10, 214, 214, 214, 214, 214,
- 170, 170, 170, 170, 170, 169, 169, 169,
- 224, 224, 224, 224, 224, 224, 224, 224,
- 224, 194, 194, 194, 194, 193, 193, 193,
- 193, 192, 10, 10, 10, 10, 10, 214,
- 170, 170, 170, 170, 169, 169, 169, 169,
- 169, 224, 224, 224, 224, 224, 224, 195,
- 194, 194, 194, 194, 194, 193, 193, 193,
- 192, 192, 10, 10, 10, 10, 10, 10,
- 170, 168, 168, 169, 169, 169, 169, 169,
- 169, 169, 224, 224, 224, 195, 195, 195,
- 194, 194, 194, 194, 193, 193, 193, 192,
- 192, 192, 192, 10, 10, 10, 10, 10,
- 168, 168, 168, 168, 169, 169, 169, 169,
- 169, 169, 169, 196, 195, 195, 195, 194,
- 194, 194, 194, 193, 193, 193, 193, 192,
- 192, 192, 192, 10, 10, 10, 21, 21,
- 168, 168, 168, 168, 169, 169, 169, 169,
- 167, 167, 167, 195, 195, 195, 195, 194,
- 194, 194, 193, 193, 193, 193, 192, 192,
- 192, 192, 192, 192, 22, 21, 21, 21,
- 168, 168, 168, 168, 168, 167, 167, 167,
- 167, 167, 167, 167, 195, 195, 194, 194,
- 194, 193, 193, 193, 193, 192, 192, 192,
- 192, 192, 192, 22, 21, 21, 21, 20,
- 168, 168, 168, 168, 167, 167, 167, 167,
- 167, 167, 167, 167, 195, 194, 194, 194,
- 193, 193, 193, 193, 192, 192, 192, 192,
- 192, 192, 192, 21, 21, 21, 20, 20,
- 165, 165, 165, 167, 167, 167, 167, 167,
- 167, 167, 167, 167, 167, 194, 194, 193,
- 193, 193, 193, 193, 192, 192, 192, 192,
- 192, 192, 21, 21, 21, 20, 20, 19,
- 165, 165, 165, 165, 166, 166, 166, 166,
- 166, 166, 166, 166, 163, 163, 163, 193,
- 193, 193, 193, 192, 192, 192, 192, 192,
- 192, 192, 21, 21, 20, 20, 19, 19,
- 165, 165, 165, 165, 165, 166, 166, 166,
- 166, 166, 166, 181, 163, 163, 163, 163,
- 193, 193, 192, 192, 192, 192, 192, 192,
- 192, 21, 21, 20, 20, 19, 19, 19,
- 165, 165, 165, 165, 165, 164, 164, 164,
- 164, 164, 181, 181, 163, 163, 163, 163,
- 163, 163, 192, 192, 192, 192, 192, 144,
- 21, 21, 20, 20, 19, 19, 19, 18,
- 165, 165, 165, 165, 164, 164, 164, 164,
- 164, 182, 181, 181, 163, 163, 163, 163,
- 163, 163, 176, 192, 144, 144, 144, 144,
- 21, 20, 20, 19, 19, 19, 18, 18,
- 184, 184, 184, 184, 164, 164, 164, 164,
- 182, 182, 181, 181, 179, 163, 163, 163,
- 163, 176, 176, 176, 176, 144, 144, 144,
- 20, 20, 19, 19, 19, 18, 18, 18,
- 184, 184, 184, 184, 183, 183, 183, 182,
- 182, 181, 181, 181, 179, 163, 163, 163,
- 163, 176, 176, 176, 176, 160, 160, 160,
- 20, 19, 19, 19, 18, 18, 18, 17,
- 184, 184, 184, 184, 183, 183, 183, 182,
- 182, 181, 181, 181, 179, 179, 163, 177,
- 177, 176, 176, 176, 176, 160, 160, 160,
- 160, 19, 19, 18, 18, 18, 17, 17,
- 184, 184, 184, 184, 183, 183, 183, 182,
- 182, 181, 181, 181, 179, 179, 177, 177,
- 177, 176, 176, 176, 176, 160, 160, 160,
- 160, 19, 18, 18, 18, 17, 17, 17,
- 251, 184, 184, 184, 183, 183, 183, 182,
- 180, 180, 181, 178, 178, 179, 177, 177,
- 177, 176, 176, 176, 160, 160, 160, 160,
- 160, 160, 18, 18, 17, 17, 17, 16,
- 249, 249, 231, 231, 230, 230, 230, 229,
- 229, 229, 228, 228, 228, 227, 227, 227,
- 216, 216, 216, 215, 215, 215, 215, 214,
- 214, 214, 214, 253, 253, 253, 253, 253,
- 249, 231, 231, 230, 230, 230, 229, 229,
- 229, 228, 228, 228, 227, 227, 227, 226,
- 226, 216, 216, 215, 215, 215, 215, 214,
- 214, 214, 214, 214, 253, 253, 253, 253,
- 231, 231, 230, 230, 230, 229, 229, 229,
- 228, 228, 228, 227, 227, 227, 226, 226,
- 226, 216, 216, 215, 215, 215, 215, 214,
- 214, 214, 214, 214, 214, 253, 253, 253,
- 231, 230, 230, 230, 229, 229, 229, 228,
- 228, 228, 227, 227, 227, 226, 226, 226,
- 225, 225, 215, 215, 215, 215, 215, 214,
- 214, 214, 214, 214, 214, 214, 253, 253,
- 230, 230, 230, 229, 229, 229, 228, 228,
- 228, 227, 227, 227, 226, 226, 226, 225,
- 225, 225, 215, 215, 215, 215, 215, 214,
- 214, 214, 214, 214, 214, 214, 214, 253,
- 230, 230, 229, 229, 229, 228, 228, 228,
- 227, 227, 227, 226, 226, 226, 225, 225,
- 225, 224, 224, 215, 215, 215, 215, 214,
- 214, 214, 214, 214, 214, 214, 214, 214,
- 230, 229, 229, 229, 228, 228, 228, 227,
- 227, 227, 226, 226, 226, 225, 225, 225,
- 224, 224, 224, 215, 215, 215, 215, 214,
- 214, 214, 214, 214, 214, 214, 214, 214,
- 229, 229, 229, 228, 228, 228, 227, 227,
- 227, 226, 226, 226, 225, 225, 225, 224,
- 224, 224, 224, 224, 215, 215, 215, 214,
- 214, 214, 214, 214, 214, 214, 214, 214,
- 229, 229, 228, 228, 228, 227, 227, 227,
- 226, 226, 226, 225, 225, 225, 224, 224,
- 224, 224, 224, 224, 215, 215, 214, 214,
- 214, 214, 214, 214, 214, 214, 214, 214,
- 170, 170, 171, 228, 227, 227, 227, 226,
- 226, 226, 225, 225, 225, 224, 224, 224,
- 224, 224, 224, 224, 224, 215, 214, 214,
- 214, 214, 214, 214, 214, 214, 214, 214,
- 170, 170, 170, 170, 227, 227, 226, 226,
- 226, 225, 225, 225, 224, 224, 224, 224,
- 224, 224, 224, 224, 224, 215, 214, 214,
- 214, 214, 214, 214, 214, 214, 214, 214,
- 170, 170, 170, 170, 170, 226, 226, 226,
- 225, 225, 225, 224, 224, 224, 224, 224,
- 224, 224, 224, 224, 224, 224, 214, 214,
- 214, 214, 214, 214, 214, 214, 214, 214,
- 170, 170, 170, 170, 170, 170, 226, 225,
- 225, 225, 224, 224, 224, 224, 224, 224,
- 224, 224, 224, 224, 224, 224, 214, 214,
- 214, 214, 214, 214, 214, 214, 214, 214,
- 170, 170, 170, 170, 170, 170, 170, 225,
- 225, 224, 224, 224, 224, 224, 224, 224,
- 224, 224, 224, 224, 224, 194, 194, 193,
- 214, 214, 214, 214, 214, 214, 214, 214,
- 170, 170, 170, 170, 170, 170, 169, 169,
- 224, 224, 224, 224, 224, 224, 224, 224,
- 224, 224, 224, 194, 194, 194, 193, 193,
- 193, 192, 214, 214, 214, 214, 214, 214,
- 170, 170, 170, 170, 170, 169, 169, 169,
- 224, 224, 224, 224, 224, 224, 224, 224,
- 224, 224, 194, 194, 194, 193, 193, 193,
- 193, 192, 192, 10, 10, 10, 214, 214,
- 170, 170, 170, 169, 169, 169, 169, 169,
- 169, 224, 224, 224, 224, 224, 224, 224,
- 194, 194, 194, 194, 193, 193, 193, 193,
- 192, 192, 192, 192, 10, 10, 10, 10,
- 168, 168, 168, 169, 169, 169, 169, 169,
- 169, 169, 224, 224, 224, 224, 224, 194,
- 194, 194, 194, 193, 193, 193, 193, 192,
- 192, 192, 192, 192, 10, 10, 10, 21,
- 168, 168, 168, 168, 169, 169, 169, 169,
- 169, 169, 169, 224, 224, 195, 195, 194,
- 194, 194, 193, 193, 193, 193, 192, 192,
- 192, 192, 192, 192, 192, 21, 21, 21,
- 168, 168, 168, 168, 169, 169, 169, 169,
- 167, 167, 167, 167, 195, 195, 194, 194,
- 194, 194, 193, 193, 193, 193, 192, 192,
- 192, 192, 192, 192, 21, 21, 21, 20,
- 168, 168, 168, 168, 168, 167, 167, 167,
- 167, 167, 167, 167, 167, 195, 194, 194,
- 194, 193, 193, 193, 193, 192, 192, 192,
- 192, 192, 192, 192, 21, 21, 20, 20,
- 168, 168, 168, 168, 167, 167, 167, 167,
- 167, 167, 167, 167, 167, 194, 194, 194,
- 193, 193, 193, 193, 192, 192, 192, 192,
- 192, 192, 192, 21, 21, 20, 20, 19,
- 165, 165, 165, 167, 167, 167, 167, 167,
- 167, 167, 167, 167, 167, 194, 194, 193,
- 193, 193, 193, 192, 192, 192, 192, 192,
- 192, 192, 21, 21, 20, 20, 19, 19,
- 165, 165, 165, 165, 166, 166, 166, 166,
- 166, 166, 166, 166, 163, 163, 163, 163,
- 193, 193, 193, 192, 192, 192, 192, 192,
- 192, 192, 21, 20, 20, 19, 19, 19,
- 165, 165, 165, 165, 165, 166, 166, 166,
- 166, 166, 166, 166, 163, 163, 163, 163,
- 163, 193, 192, 192, 192, 192, 192, 192,
- 192, 21, 20, 20, 19, 19, 19, 18,
- 165, 165, 165, 165, 165, 164, 164, 164,
- 164, 164, 164, 163, 163, 163, 163, 163,
- 163, 163, 192, 192, 192, 192, 192, 192,
- 21, 20, 20, 19, 19, 19, 18, 18,
- 165, 165, 165, 165, 164, 164, 164, 164,
- 164, 164, 181, 181, 163, 163, 163, 163,
- 163, 163, 176, 176, 192, 144, 144, 144,
- 20, 20, 19, 19, 19, 18, 18, 18,
- 165, 165, 165, 164, 164, 164, 164, 164,
- 164, 181, 181, 181, 163, 163, 163, 163,
- 163, 163, 176, 176, 176, 160, 160, 160,
- 20, 19, 19, 19, 18, 18, 18, 17,
- 184, 184, 184, 184, 164, 164, 164, 182,
- 182, 181, 181, 181, 179, 163, 163, 163,
- 163, 176, 176, 176, 176, 160, 160, 160,
- 160, 19, 19, 18, 18, 18, 17, 17,
- 184, 184, 184, 184, 183, 183, 183, 182,
- 182, 181, 181, 181, 179, 163, 163, 163,
- 177, 176, 176, 176, 176, 160, 160, 160,
- 160, 19, 18, 18, 18, 17, 17, 17,
- 251, 184, 184, 184, 183, 183, 183, 182,
- 180, 180, 181, 178, 178, 162, 163, 177,
- 177, 176, 176, 176, 160, 160, 160, 160,
- 160, 160, 18, 18, 17, 17, 17, 16,
- 251, 251, 184, 184, 183, 183, 183, 180,
- 180, 180, 180, 178, 178, 162, 162, 177,
- 161, 176, 176, 176, 160, 160, 160, 160,
- 160, 160, 18, 17, 17, 17, 16, 16,
-};
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: AlphaInverse.cpp
+ AUTHOR: John DiCamillo
+*/
+
+#include "stdafx.h"
+
+BYTE inverse_palette[32768] = {
+ 0, 47, 63, 63, 62, 62, 61, 61,
+ 61, 60, 60, 59, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 252, 252, 252, 252, 252, 252, 252, 252,
+ 47, 47, 63, 63, 62, 62, 61, 61,
+ 61, 60, 60, 59, 59, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 55, 252, 252, 252, 252, 252, 252, 252,
+ 47, 46, 63, 63, 62, 62, 61, 61,
+ 60, 60, 60, 59, 59, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 55,
+ 55, 252, 252, 252, 252, 252, 252, 252,
+ 46, 46, 46, 62, 62, 62, 61, 61,
+ 60, 60, 59, 59, 59, 58, 4, 4,
+ 4, 4, 4, 4, 4, 4, 55, 55,
+ 55, 54, 252, 252, 252, 252, 252, 252,
+ 46, 46, 45, 111, 111, 79, 79, 61,
+ 60, 60, 59, 59, 59, 58, 58, 57,
+ 4, 4, 4, 4, 56, 55, 55, 55,
+ 54, 54, 54, 252, 252, 252, 252, 252,
+ 111, 111, 111, 111, 111, 111, 79, 79,
+ 60, 60, 59, 59, 58, 58, 58, 57,
+ 57, 56, 56, 56, 56, 55, 55, 55,
+ 54, 54, 54, 252, 252, 252, 252, 252,
+ 111, 111, 111, 111, 111, 111, 111, 78,
+ 78, 78, 59, 59, 58, 58, 57, 57,
+ 57, 56, 56, 56, 55, 55, 55, 55,
+ 54, 54, 54, 54, 252, 252, 252, 252,
+ 111, 111, 111, 111, 111, 111, 110, 78,
+ 78, 77, 77, 77, 58, 58, 57, 57,
+ 57, 56, 56, 56, 55, 55, 55, 55,
+ 54, 54, 54, 54, 54, 252, 252, 252,
+ 111, 111, 111, 111, 110, 110, 110, 110,
+ 78, 77, 213, 213, 213, 213, 213, 213,
+ 56, 56, 56, 56, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 252, 252, 252,
+ 111, 110, 110, 110, 110, 110, 110, 109,
+ 109, 213, 213, 213, 213, 213, 213, 213,
+ 213, 213, 56, 56, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 54, 252, 252,
+ 110, 110, 110, 110, 110, 109, 109, 109,
+ 109, 213, 213, 213, 213, 213, 213, 213,
+ 213, 213, 212, 6, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 54, 53, 252,
+ 2, 110, 110, 110, 109, 109, 109, 109,
+ 213, 213, 213, 213, 213, 213, 213, 213,
+ 213, 212, 6, 6, 6, 6, 6, 54,
+ 54, 54, 54, 54, 54, 53, 53, 53,
+ 2, 2, 2, 109, 109, 109, 109, 108,
+ 213, 213, 213, 213, 213, 213, 213, 213,
+ 212, 6, 6, 6, 6, 6, 6, 6,
+ 54, 54, 54, 54, 53, 53, 53, 53,
+ 2, 2, 2, 2, 108, 108, 108, 108,
+ 213, 213, 213, 213, 213, 213, 213, 212,
+ 6, 6, 6, 6, 6, 6, 6, 211,
+ 211, 211, 70, 53, 53, 53, 53, 53,
+ 2, 2, 2, 2, 2, 108, 108, 108,
+ 213, 213, 213, 213, 213, 213, 212, 6,
+ 6, 6, 6, 6, 6, 6, 211, 211,
+ 211, 211, 211, 70, 70, 70, 53, 53,
+ 2, 2, 2, 2, 2, 2, 107, 107,
+ 107, 213, 213, 213, 213, 212, 6, 6,
+ 6, 6, 6, 6, 6, 211, 211, 211,
+ 211, 211, 211, 210, 210, 70, 70, 70,
+ 2, 2, 2, 2, 2, 2, 107, 107,
+ 107, 213, 213, 213, 212, 6, 6, 6,
+ 6, 6, 6, 6, 211, 211, 211, 211,
+ 211, 211, 210, 210, 210, 210, 210, 210,
+ 2, 2, 2, 2, 2, 2, 107, 107,
+ 106, 106, 213, 212, 6, 6, 6, 6,
+ 6, 6, 6, 211, 211, 211, 211, 211,
+ 211, 210, 210, 210, 210, 210, 210, 209,
+ 2, 2, 2, 2, 2, 2, 106, 106,
+ 106, 106, 106, 6, 6, 6, 6, 6,
+ 6, 6, 211, 211, 211, 211, 211, 211,
+ 210, 210, 210, 210, 210, 210, 209, 209,
+ 2, 2, 2, 2, 2, 2, 105, 105,
+ 105, 105, 105, 6, 6, 6, 6, 6,
+ 6, 211, 211, 211, 211, 211, 211, 210,
+ 210, 210, 210, 210, 210, 209, 209, 209,
+ 2, 2, 2, 2, 2, 2, 105, 105,
+ 105, 105, 105, 6, 6, 6, 6, 6,
+ 211, 211, 211, 211, 211, 211, 210, 210,
+ 210, 210, 210, 210, 209, 209, 209, 209,
+ 2, 2, 2, 2, 2, 2, 105, 105,
+ 104, 104, 104, 6, 6, 6, 6, 211,
+ 211, 211, 211, 211, 211, 210, 210, 210,
+ 210, 210, 210, 209, 209, 209, 209, 209,
+ 2, 2, 2, 2, 2, 104, 104, 104,
+ 104, 104, 104, 103, 6, 6, 211, 211,
+ 211, 211, 211, 211, 210, 210, 210, 210,
+ 210, 210, 209, 209, 209, 209, 209, 209,
+ 2, 2, 2, 2, 2, 104, 104, 104,
+ 104, 104, 103, 103, 103, 211, 211, 211,
+ 211, 211, 211, 210, 210, 210, 210, 210,
+ 210, 209, 209, 209, 209, 209, 209, 209,
+ 250, 250, 250, 250, 250, 104, 104, 104,
+ 103, 103, 103, 103, 103, 211, 211, 211,
+ 211, 211, 210, 210, 210, 210, 210, 210,
+ 209, 209, 209, 209, 209, 209, 209, 208,
+ 250, 250, 250, 250, 250, 250, 102, 102,
+ 103, 103, 103, 103, 103, 103, 211, 211,
+ 211, 210, 210, 210, 210, 210, 210, 209,
+ 209, 209, 209, 209, 209, 209, 208, 208,
+ 250, 250, 250, 250, 250, 250, 250, 102,
+ 102, 102, 103, 103, 103, 103, 211, 211,
+ 210, 210, 210, 210, 210, 210, 209, 209,
+ 209, 209, 209, 209, 209, 208, 208, 208,
+ 250, 250, 250, 250, 250, 250, 250, 250,
+ 102, 102, 102, 103, 103, 103, 211, 210,
+ 210, 210, 210, 210, 210, 209, 209, 209,
+ 209, 209, 209, 209, 208, 208, 208, 254,
+ 250, 250, 250, 250, 250, 250, 250, 250,
+ 250, 102, 102, 102, 103, 103, 103, 210,
+ 210, 210, 210, 210, 209, 209, 209, 209,
+ 209, 209, 209, 208, 208, 208, 254, 254,
+ 250, 250, 250, 250, 250, 250, 250, 250,
+ 250, 250, 102, 102, 102, 103, 103, 210,
+ 210, 210, 210, 209, 209, 209, 209, 209,
+ 209, 209, 208, 208, 208, 254, 254, 254,
+ 250, 250, 250, 250, 250, 250, 250, 250,
+ 250, 250, 250, 102, 102, 102, 102, 210,
+ 210, 210, 209, 209, 209, 209, 209, 209,
+ 209, 208, 208, 208, 254, 254, 254, 254,
+ 250, 250, 250, 250, 250, 250, 250, 250,
+ 250, 250, 250, 250, 102, 102, 102, 210,
+ 210, 209, 209, 209, 209, 209, 209, 209,
+ 208, 208, 208, 254, 254, 254, 254, 254,
+ 47, 47, 63, 63, 62, 62, 61, 61,
+ 61, 60, 60, 59, 59, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 55, 252, 252, 252, 252, 252, 252, 252,
+ 47, 46, 63, 63, 62, 62, 61, 61,
+ 60, 60, 60, 59, 59, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 55,
+ 55, 252, 252, 252, 252, 252, 252, 252,
+ 46, 46, 46, 62, 62, 62, 61, 61,
+ 60, 60, 59, 59, 59, 58, 4, 4,
+ 4, 4, 4, 4, 4, 4, 55, 55,
+ 55, 54, 252, 252, 252, 252, 252, 252,
+ 46, 46, 45, 45, 62, 79, 61, 61,
+ 60, 60, 59, 59, 59, 58, 58, 57,
+ 4, 4, 4, 4, 56, 55, 55, 55,
+ 54, 54, 54, 252, 252, 252, 252, 252,
+ 46, 45, 45, 45, 79, 79, 79, 79,
+ 60, 60, 59, 59, 58, 58, 58, 57,
+ 57, 56, 56, 56, 56, 55, 55, 55,
+ 54, 54, 54, 252, 252, 252, 252, 252,
+ 111, 111, 111, 111, 111, 79, 79, 79,
+ 78, 60, 59, 59, 58, 58, 57, 57,
+ 57, 56, 56, 56, 55, 55, 55, 55,
+ 54, 54, 54, 54, 252, 252, 252, 252,
+ 111, 111, 111, 111, 111, 111, 79, 78,
+ 78, 78, 77, 59, 58, 58, 57, 57,
+ 57, 56, 56, 56, 55, 55, 55, 55,
+ 54, 54, 54, 54, 54, 252, 252, 252,
+ 111, 111, 111, 111, 111, 110, 110, 78,
+ 78, 77, 77, 77, 58, 58, 57, 57,
+ 56, 56, 56, 56, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 252, 252, 252,
+ 111, 111, 111, 110, 110, 110, 110, 110,
+ 77, 77, 77, 213, 213, 213, 213, 213,
+ 56, 56, 56, 56, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 54, 252, 252,
+ 110, 110, 110, 110, 110, 110, 109, 109,
+ 109, 213, 213, 213, 213, 213, 213, 213,
+ 213, 56, 56, 55, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 54, 53, 252,
+ 110, 110, 110, 110, 110, 109, 109, 109,
+ 109, 213, 213, 213, 213, 213, 213, 213,
+ 213, 213, 212, 73, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 53, 53, 53,
+ 2, 110, 110, 109, 109, 109, 109, 109,
+ 108, 213, 213, 213, 213, 213, 213, 213,
+ 213, 212, 212, 212, 6, 55, 55, 54,
+ 54, 54, 54, 54, 53, 53, 53, 53,
+ 2, 2, 2, 109, 109, 109, 108, 108,
+ 108, 213, 213, 213, 213, 213, 213, 213,
+ 212, 212, 212, 6, 6, 6, 6, 54,
+ 54, 54, 54, 53, 53, 53, 53, 53,
+ 2, 2, 2, 2, 108, 108, 108, 108,
+ 108, 213, 213, 213, 213, 213, 213, 212,
+ 212, 212, 6, 6, 6, 6, 211, 211,
+ 211, 70, 70, 53, 53, 53, 53, 53,
+ 2, 2, 2, 2, 108, 108, 108, 107,
+ 107, 213, 213, 213, 213, 213, 212, 212,
+ 212, 6, 6, 6, 6, 211, 211, 211,
+ 211, 211, 70, 70, 70, 70, 53, 53,
+ 2, 2, 2, 2, 2, 107, 107, 107,
+ 107, 107, 213, 213, 213, 212, 212, 212,
+ 6, 6, 6, 6, 211, 211, 211, 211,
+ 211, 211, 70, 70, 70, 70, 70, 70,
+ 2, 2, 2, 2, 2, 107, 107, 107,
+ 107, 106, 213, 213, 212, 212, 212, 6,
+ 6, 6, 6, 211, 211, 211, 211, 211,
+ 211, 211, 210, 210, 210, 210, 70, 70,
+ 2, 2, 2, 2, 2, 107, 107, 106,
+ 106, 106, 106, 212, 212, 212, 6, 6,
+ 6, 6, 211, 211, 211, 211, 211, 211,
+ 211, 210, 210, 210, 210, 210, 210, 209,
+ 2, 2, 2, 2, 2, 2, 106, 106,
+ 106, 106, 106, 212, 212, 6, 6, 6,
+ 6, 211, 211, 211, 211, 211, 211, 211,
+ 210, 210, 210, 210, 210, 210, 209, 209,
+ 2, 2, 2, 2, 2, 105, 105, 105,
+ 105, 105, 105, 212, 6, 6, 6, 6,
+ 211, 211, 211, 211, 211, 211, 211, 210,
+ 210, 210, 210, 210, 210, 209, 209, 209,
+ 2, 2, 2, 2, 2, 105, 105, 105,
+ 105, 105, 105, 104, 6, 6, 6, 211,
+ 211, 211, 211, 211, 211, 211, 210, 210,
+ 210, 210, 210, 210, 209, 209, 209, 209,
+ 2, 2, 2, 2, 2, 105, 105, 104,
+ 104, 104, 104, 104, 6, 6, 211, 211,
+ 211, 211, 211, 211, 211, 210, 210, 210,
+ 210, 210, 210, 209, 209, 209, 209, 209,
+ 2, 2, 2, 2, 2, 104, 104, 104,
+ 104, 104, 104, 103, 103, 211, 211, 211,
+ 211, 211, 211, 211, 210, 210, 210, 210,
+ 210, 210, 209, 209, 209, 209, 209, 209,
+ 2, 2, 2, 2, 104, 104, 104, 104,
+ 104, 103, 103, 103, 103, 103, 211, 211,
+ 211, 211, 211, 210, 210, 210, 210, 210,
+ 210, 209, 209, 209, 209, 209, 209, 208,
+ 250, 250, 250, 250, 102, 102, 102, 102,
+ 103, 103, 103, 103, 103, 103, 211, 211,
+ 211, 211, 210, 210, 210, 210, 210, 210,
+ 209, 209, 209, 209, 209, 209, 208, 208,
+ 250, 250, 250, 250, 250, 102, 102, 102,
+ 102, 103, 103, 103, 103, 103, 211, 211,
+ 211, 210, 210, 210, 210, 210, 210, 209,
+ 209, 209, 209, 209, 209, 208, 208, 208,
+ 250, 250, 250, 250, 250, 250, 102, 102,
+ 102, 102, 103, 103, 103, 103, 103, 211,
+ 210, 210, 210, 210, 210, 210, 209, 209,
+ 209, 209, 209, 209, 208, 208, 208, 208,
+ 250, 250, 250, 250, 250, 250, 250, 102,
+ 102, 102, 102, 103, 103, 103, 103, 210,
+ 210, 210, 210, 210, 210, 209, 209, 209,
+ 209, 209, 209, 208, 208, 208, 208, 208,
+ 250, 250, 250, 250, 250, 250, 250, 250,
+ 102, 102, 102, 102, 102, 103, 103, 210,
+ 210, 210, 210, 210, 209, 209, 209, 209,
+ 209, 209, 208, 208, 208, 208, 208, 254,
+ 250, 250, 250, 250, 250, 250, 250, 250,
+ 250, 102, 102, 102, 102, 102, 103, 210,
+ 210, 210, 210, 209, 209, 209, 209, 209,
+ 209, 208, 208, 208, 208, 208, 254, 254,
+ 250, 250, 250, 250, 250, 250, 250, 250,
+ 250, 250, 102, 102, 102, 102, 102, 210,
+ 210, 210, 209, 209, 209, 209, 209, 209,
+ 208, 208, 208, 208, 208, 254, 254, 254,
+ 250, 250, 250, 250, 250, 250, 250, 250,
+ 250, 250, 250, 102, 102, 102, 102, 210,
+ 210, 209, 209, 209, 209, 209, 209, 208,
+ 208, 208, 208, 208, 254, 254, 254, 254,
+ 47, 46, 63, 63, 62, 62, 61, 61,
+ 60, 60, 60, 59, 59, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 55,
+ 55, 252, 252, 252, 252, 252, 252, 252,
+ 46, 46, 46, 62, 62, 62, 61, 61,
+ 60, 60, 59, 59, 59, 58, 4, 4,
+ 4, 4, 4, 4, 4, 4, 55, 55,
+ 55, 54, 252, 252, 252, 252, 252, 252,
+ 46, 46, 45, 45, 62, 62, 61, 61,
+ 60, 60, 59, 59, 59, 58, 58, 57,
+ 4, 4, 4, 4, 56, 55, 55, 55,
+ 54, 54, 54, 252, 252, 252, 252, 252,
+ 46, 45, 45, 45, 45, 79, 79, 61,
+ 60, 60, 59, 59, 58, 58, 58, 57,
+ 57, 56, 56, 56, 56, 55, 55, 55,
+ 54, 54, 54, 252, 252, 252, 252, 252,
+ 45, 45, 45, 45, 79, 79, 79, 79,
+ 60, 60, 59, 59, 58, 58, 57, 57,
+ 57, 56, 56, 56, 55, 55, 55, 55,
+ 54, 54, 54, 54, 252, 252, 252, 252,
+ 111, 111, 111, 111, 111, 79, 79, 78,
+ 78, 78, 59, 59, 58, 58, 57, 57,
+ 57, 56, 56, 56, 55, 55, 55, 55,
+ 54, 54, 54, 54, 54, 252, 252, 252,
+ 111, 111, 111, 111, 111, 111, 78, 78,
+ 78, 77, 77, 77, 58, 58, 57, 57,
+ 56, 56, 56, 56, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 252, 252, 252,
+ 111, 111, 111, 111, 111, 110, 110, 78,
+ 78, 77, 77, 77, 76, 58, 57, 57,
+ 56, 56, 56, 56, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 54, 252, 252,
+ 111, 111, 110, 110, 110, 110, 110, 109,
+ 77, 77, 77, 76, 76, 213, 75, 57,
+ 56, 56, 56, 55, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 54, 53, 252,
+ 110, 110, 110, 110, 110, 110, 109, 109,
+ 109, 77, 213, 213, 213, 213, 213, 213,
+ 75, 56, 56, 55, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 53, 53, 53,
+ 110, 110, 110, 110, 109, 109, 109, 109,
+ 109, 213, 213, 213, 213, 213, 213, 213,
+ 213, 74, 73, 73, 55, 55, 55, 54,
+ 54, 54, 54, 54, 53, 53, 53, 53,
+ 110, 110, 110, 109, 109, 109, 109, 109,
+ 108, 213, 213, 213, 213, 213, 213, 213,
+ 212, 212, 212, 73, 73, 73, 54, 54,
+ 54, 54, 54, 53, 53, 53, 53, 53,
+ 2, 2, 109, 109, 109, 108, 108, 108,
+ 108, 213, 213, 213, 213, 213, 213, 212,
+ 212, 212, 212, 212, 73, 72, 72, 54,
+ 54, 54, 53, 53, 53, 53, 53, 53,
+ 2, 2, 2, 108, 108, 108, 108, 108,
+ 108, 213, 213, 213, 213, 213, 212, 212,
+ 212, 212, 212, 212, 212, 72, 72, 71,
+ 70, 70, 70, 53, 53, 53, 53, 53,
+ 2, 2, 2, 2, 108, 108, 107, 107,
+ 107, 107, 213, 213, 213, 212, 212, 212,
+ 212, 212, 212, 212, 6, 211, 211, 211,
+ 70, 70, 70, 70, 70, 70, 53, 53,
+ 2, 2, 2, 2, 107, 107, 107, 107,
+ 107, 107, 213, 213, 212, 212, 212, 212,
+ 212, 212, 212, 6, 211, 211, 211, 211,
+ 211, 70, 70, 70, 70, 70, 70, 70,
+ 2, 2, 2, 2, 107, 107, 107, 107,
+ 106, 106, 106, 212, 212, 212, 212, 212,
+ 212, 212, 6, 211, 211, 211, 211, 211,
+ 211, 210, 70, 70, 70, 70, 70, 70,
+ 2, 2, 2, 2, 2, 107, 106, 106,
+ 106, 106, 106, 212, 212, 212, 212, 212,
+ 212, 6, 211, 211, 211, 211, 211, 211,
+ 210, 210, 210, 210, 210, 210, 70, 70,
+ 2, 2, 2, 2, 2, 105, 106, 106,
+ 106, 106, 106, 106, 212, 212, 212, 212,
+ 6, 211, 211, 211, 211, 211, 211, 210,
+ 210, 210, 210, 210, 210, 210, 209, 209,
+ 2, 2, 2, 2, 2, 105, 105, 105,
+ 105, 105, 105, 105, 212, 212, 212, 6,
+ 211, 211, 211, 211, 211, 211, 210, 210,
+ 210, 210, 210, 210, 210, 209, 209, 209,
+ 2, 2, 2, 2, 105, 105, 105, 105,
+ 105, 105, 104, 104, 212, 212, 6, 211,
+ 211, 211, 211, 211, 211, 210, 210, 210,
+ 210, 210, 210, 210, 209, 209, 209, 209,
+ 2, 2, 2, 2, 105, 105, 104, 104,
+ 104, 104, 104, 104, 103, 6, 211, 211,
+ 211, 211, 211, 211, 210, 210, 210, 210,
+ 210, 210, 210, 209, 209, 209, 209, 209,
+ 2, 2, 2, 2, 104, 104, 104, 104,
+ 104, 104, 103, 103, 103, 103, 211, 211,
+ 211, 211, 211, 210, 210, 210, 210, 210,
+ 210, 210, 209, 209, 209, 209, 209, 209,
+ 2, 2, 2, 104, 104, 104, 104, 104,
+ 104, 103, 103, 103, 103, 103, 211, 211,
+ 211, 211, 210, 210, 210, 210, 210, 210,
+ 210, 209, 209, 209, 209, 209, 209, 208,
+ 250, 250, 250, 102, 102, 102, 102, 102,
+ 103, 103, 103, 103, 103, 103, 211, 211,
+ 211, 210, 210, 210, 210, 210, 210, 210,
+ 209, 209, 209, 209, 209, 209, 208, 208,
+ 250, 250, 250, 250, 102, 102, 102, 102,
+ 102, 103, 103, 103, 103, 103, 103, 211,
+ 210, 210, 210, 210, 210, 210, 210, 209,
+ 209, 209, 209, 209, 209, 208, 208, 208,
+ 250, 250, 250, 250, 250, 102, 102, 102,
+ 102, 102, 102, 103, 103, 103, 103, 210,
+ 210, 210, 210, 210, 210, 210, 209, 209,
+ 209, 209, 209, 209, 208, 208, 208, 208,
+ 250, 250, 250, 250, 250, 250, 102, 102,
+ 102, 102, 102, 102, 103, 103, 103, 210,
+ 210, 210, 210, 210, 210, 209, 209, 209,
+ 209, 209, 209, 208, 208, 208, 208, 208,
+ 250, 250, 250, 250, 250, 250, 250, 102,
+ 102, 102, 102, 102, 102, 103, 103, 210,
+ 210, 210, 210, 210, 209, 209, 209, 209,
+ 209, 209, 208, 208, 208, 208, 208, 208,
+ 250, 250, 250, 250, 250, 250, 250, 250,
+ 102, 102, 102, 102, 102, 102, 103, 210,
+ 210, 210, 210, 209, 209, 209, 209, 209,
+ 209, 208, 208, 208, 208, 208, 208, 254,
+ 250, 250, 250, 250, 250, 250, 250, 250,
+ 250, 102, 102, 102, 102, 102, 101, 210,
+ 210, 210, 209, 209, 209, 209, 209, 209,
+ 208, 208, 208, 208, 208, 208, 254, 254,
+ 250, 250, 250, 250, 250, 250, 250, 250,
+ 250, 250, 102, 102, 102, 102, 101, 101,
+ 210, 209, 209, 209, 209, 209, 209, 208,
+ 208, 208, 208, 208, 208, 254, 254, 254,
+ 247, 46, 46, 62, 62, 62, 61, 61,
+ 60, 60, 59, 59, 59, 58, 4, 4,
+ 4, 4, 4, 4, 4, 4, 55, 55,
+ 55, 54, 252, 252, 252, 252, 252, 252,
+ 46, 46, 45, 45, 62, 62, 61, 61,
+ 60, 60, 59, 59, 59, 58, 58, 57,
+ 4, 4, 4, 4, 56, 55, 55, 55,
+ 54, 54, 54, 252, 252, 252, 252, 252,
+ 46, 45, 45, 45, 45, 61, 61, 61,
+ 60, 60, 59, 59, 58, 58, 58, 57,
+ 57, 56, 56, 56, 56, 55, 55, 55,
+ 54, 54, 54, 252, 252, 252, 252, 252,
+ 45, 45, 45, 45, 95, 79, 79, 60,
+ 60, 60, 59, 59, 58, 58, 57, 57,
+ 57, 56, 56, 56, 55, 55, 55, 55,
+ 54, 54, 54, 54, 252, 252, 252, 252,
+ 45, 45, 45, 127, 95, 79, 79, 78,
+ 78, 59, 59, 59, 58, 58, 57, 57,
+ 57, 56, 56, 56, 55, 55, 55, 55,
+ 54, 54, 54, 54, 54, 252, 252, 252,
+ 45, 127, 127, 127, 127, 79, 78, 78,
+ 78, 78, 59, 59, 58, 58, 57, 57,
+ 56, 56, 56, 56, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 252, 252, 252,
+ 111, 111, 111, 111, 111, 111, 78, 78,
+ 78, 77, 77, 77, 58, 58, 57, 57,
+ 56, 56, 56, 56, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 54, 252, 252,
+ 111, 111, 111, 111, 110, 110, 78, 78,
+ 77, 77, 77, 77, 76, 76, 57, 57,
+ 56, 56, 56, 55, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 54, 53, 252,
+ 111, 110, 110, 110, 110, 110, 110, 109,
+ 77, 77, 77, 76, 76, 75, 75, 75,
+ 56, 56, 56, 55, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 53, 53, 53,
+ 110, 110, 110, 110, 110, 109, 109, 109,
+ 109, 77, 76, 76, 76, 75, 75, 75,
+ 74, 74, 56, 55, 55, 55, 55, 54,
+ 54, 54, 54, 54, 53, 53, 53, 53,
+ 110, 110, 110, 110, 109, 109, 109, 109,
+ 109, 76, 213, 213, 213, 213, 213, 74,
+ 74, 73, 73, 73, 55, 55, 54, 54,
+ 54, 54, 54, 53, 53, 53, 53, 53,
+ 110, 110, 109, 109, 109, 109, 109, 108,
+ 108, 108, 213, 213, 213, 213, 213, 213,
+ 74, 73, 73, 73, 73, 73, 54, 54,
+ 54, 54, 53, 53, 53, 53, 53, 53,
+ 2, 109, 109, 109, 109, 108, 108, 108,
+ 108, 108, 213, 213, 213, 213, 213, 212,
+ 212, 212, 73, 73, 73, 72, 72, 72,
+ 54, 53, 53, 53, 53, 53, 53, 53,
+ 2, 2, 108, 108, 108, 108, 108, 108,
+ 107, 107, 213, 213, 213, 213, 212, 212,
+ 212, 212, 212, 73, 72, 72, 72, 71,
+ 70, 70, 70, 53, 53, 53, 53, 53,
+ 2, 2, 2, 108, 108, 108, 107, 107,
+ 107, 107, 213, 213, 213, 212, 212, 212,
+ 212, 212, 212, 212, 211, 72, 71, 70,
+ 70, 70, 70, 70, 70, 70, 53, 53,
+ 2, 2, 2, 2, 107, 107, 107, 107,
+ 107, 106, 106, 213, 212, 212, 212, 212,
+ 212, 212, 212, 211, 211, 211, 211, 211,
+ 70, 70, 70, 70, 70, 70, 70, 70,
+ 2, 2, 2, 2, 107, 107, 107, 106,
+ 106, 106, 106, 106, 212, 212, 212, 212,
+ 212, 212, 211, 211, 211, 211, 211, 211,
+ 70, 70, 70, 70, 70, 70, 70, 70,
+ 2, 2, 2, 2, 107, 106, 106, 106,
+ 106, 106, 106, 106, 212, 212, 212, 212,
+ 212, 211, 211, 211, 211, 211, 211, 211,
+ 210, 210, 70, 70, 70, 70, 70, 70,
+ 2, 2, 2, 2, 105, 105, 105, 105,
+ 105, 105, 105, 106, 212, 212, 212, 212,
+ 211, 211, 211, 211, 211, 211, 211, 210,
+ 210, 210, 210, 210, 210, 210, 209, 209,
+ 2, 2, 2, 2, 105, 105, 105, 105,
+ 105, 105, 105, 105, 212, 212, 212, 211,
+ 211, 211, 211, 211, 211, 211, 210, 210,
+ 210, 210, 210, 210, 210, 209, 209, 209,
+ 2, 2, 2, 2, 105, 105, 105, 105,
+ 104, 104, 104, 104, 104, 212, 211, 211,
+ 211, 211, 211, 211, 211, 210, 210, 210,
+ 210, 210, 210, 210, 209, 209, 209, 209,
+ 2, 2, 2, 105, 104, 104, 104, 104,
+ 104, 104, 104, 103, 103, 103, 211, 211,
+ 211, 211, 211, 211, 210, 210, 210, 210,
+ 210, 210, 210, 209, 209, 209, 209, 209,
+ 2, 2, 2, 104, 104, 104, 104, 104,
+ 104, 104, 103, 103, 103, 103, 211, 211,
+ 211, 211, 211, 210, 210, 210, 210, 210,
+ 210, 210, 209, 209, 209, 209, 209, 209,
+ 2, 2, 102, 102, 102, 104, 104, 104,
+ 103, 103, 103, 103, 103, 103, 103, 211,
+ 211, 211, 210, 210, 210, 210, 210, 210,
+ 210, 209, 209, 209, 209, 209, 209, 208,
+ 250, 250, 102, 102, 102, 102, 102, 102,
+ 102, 103, 103, 103, 103, 103, 103, 211,
+ 211, 210, 210, 210, 210, 210, 210, 210,
+ 209, 209, 209, 209, 209, 209, 208, 208,
+ 250, 250, 250, 102, 102, 102, 102, 102,
+ 102, 102, 103, 103, 103, 103, 103, 211,
+ 210, 210, 210, 210, 210, 210, 210, 209,
+ 209, 209, 209, 209, 209, 208, 208, 208,
+ 250, 250, 250, 250, 102, 102, 102, 102,
+ 102, 102, 102, 103, 103, 103, 103, 103,
+ 210, 210, 210, 210, 210, 210, 209, 209,
+ 209, 209, 209, 209, 208, 208, 208, 208,
+ 250, 250, 250, 250, 250, 102, 102, 102,
+ 102, 102, 102, 102, 103, 103, 103, 103,
+ 210, 210, 210, 210, 210, 209, 209, 209,
+ 209, 209, 209, 208, 208, 208, 208, 208,
+ 250, 250, 250, 250, 250, 250, 102, 102,
+ 102, 102, 102, 102, 102, 103, 103, 103,
+ 210, 210, 210, 210, 209, 209, 209, 209,
+ 209, 209, 208, 208, 208, 208, 208, 208,
+ 250, 250, 250, 250, 250, 250, 250, 102,
+ 102, 102, 102, 102, 102, 102, 101, 101,
+ 210, 210, 210, 209, 209, 209, 209, 209,
+ 209, 208, 208, 208, 208, 208, 208, 208,
+ 250, 250, 250, 250, 250, 250, 250, 250,
+ 102, 102, 102, 102, 102, 101, 101, 101,
+ 210, 210, 209, 209, 209, 209, 209, 209,
+ 208, 208, 208, 208, 208, 208, 208, 254,
+ 250, 250, 250, 250, 250, 250, 250, 250,
+ 250, 102, 102, 102, 102, 101, 101, 101,
+ 210, 209, 209, 209, 209, 209, 209, 208,
+ 208, 208, 208, 208, 208, 208, 254, 254,
+ 247, 247, 247, 247, 62, 62, 61, 61,
+ 60, 60, 59, 59, 59, 58, 58, 57,
+ 4, 4, 4, 4, 56, 55, 55, 55,
+ 54, 54, 54, 252, 252, 252, 252, 252,
+ 247, 247, 247, 45, 45, 61, 61, 61,
+ 60, 60, 59, 59, 58, 58, 58, 57,
+ 57, 56, 56, 56, 56, 55, 55, 55,
+ 54, 54, 54, 252, 252, 252, 252, 252,
+ 247, 247, 45, 45, 44, 95, 61, 60,
+ 60, 60, 59, 59, 58, 58, 57, 57,
+ 57, 56, 56, 56, 55, 55, 55, 55,
+ 54, 54, 54, 54, 252, 252, 252, 252,
+ 247, 45, 45, 44, 44, 95, 79, 60,
+ 60, 59, 59, 59, 58, 58, 57, 57,
+ 57, 56, 56, 56, 55, 55, 55, 55,
+ 54, 54, 54, 54, 54, 252, 252, 252,
+ 45, 143, 143, 127, 44, 95, 79, 78,
+ 78, 59, 59, 59, 58, 58, 57, 57,
+ 56, 56, 56, 56, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 252, 252, 252,
+ 159, 159, 159, 127, 127, 95, 94, 78,
+ 78, 77, 77, 58, 58, 58, 57, 57,
+ 56, 56, 56, 56, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 54, 252, 252,
+ 159, 159, 159, 127, 126, 126, 94, 78,
+ 77, 77, 77, 77, 58, 58, 57, 57,
+ 56, 56, 56, 55, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 54, 53, 252,
+ 111, 111, 111, 110, 126, 126, 94, 78,
+ 77, 77, 77, 76, 76, 76, 75, 56,
+ 56, 56, 56, 55, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 53, 53, 53,
+ 110, 110, 110, 110, 110, 110, 109, 77,
+ 77, 77, 76, 76, 76, 75, 75, 75,
+ 56, 56, 56, 55, 55, 55, 55, 54,
+ 54, 54, 54, 54, 53, 53, 53, 53,
+ 110, 110, 110, 110, 110, 109, 109, 109,
+ 77, 76, 76, 76, 75, 75, 75, 75,
+ 74, 74, 73, 55, 55, 55, 54, 54,
+ 54, 54, 54, 53, 53, 53, 53, 53,
+ 110, 110, 110, 109, 109, 109, 109, 109,
+ 108, 76, 76, 76, 75, 75, 75, 74,
+ 74, 73, 73, 73, 73, 55, 54, 54,
+ 54, 54, 53, 53, 53, 53, 53, 53,
+ 110, 109, 109, 109, 109, 109, 108, 108,
+ 108, 108, 213, 213, 213, 75, 74, 74,
+ 74, 73, 73, 73, 73, 72, 72, 54,
+ 54, 53, 53, 53, 53, 53, 53, 53,
+ 2, 109, 109, 109, 108, 108, 108, 108,
+ 108, 108, 213, 213, 213, 213, 74, 74,
+ 73, 73, 73, 73, 72, 72, 72, 71,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 2, 2, 108, 108, 108, 108, 108, 107,
+ 107, 107, 213, 213, 213, 213, 212, 212,
+ 212, 73, 73, 73, 72, 72, 72, 71,
+ 70, 70, 70, 53, 53, 53, 53, 53,
+ 2, 2, 108, 108, 108, 107, 107, 107,
+ 107, 107, 107, 213, 213, 212, 212, 212,
+ 212, 212, 212, 72, 72, 72, 71, 70,
+ 70, 70, 70, 70, 70, 70, 53, 53,
+ 2, 2, 2, 107, 107, 107, 107, 107,
+ 107, 106, 106, 106, 212, 212, 212, 212,
+ 212, 212, 212, 211, 211, 71, 71, 70,
+ 70, 70, 70, 70, 70, 70, 70, 70,
+ 2, 2, 2, 107, 107, 107, 107, 106,
+ 106, 106, 106, 106, 212, 212, 212, 212,
+ 212, 212, 211, 211, 211, 211, 211, 70,
+ 70, 70, 70, 70, 70, 70, 70, 70,
+ 2, 2, 2, 107, 107, 106, 106, 106,
+ 106, 106, 106, 106, 212, 212, 212, 212,
+ 212, 211, 211, 211, 211, 211, 211, 70,
+ 70, 70, 70, 70, 70, 70, 70, 70,
+ 2, 2, 2, 105, 105, 105, 105, 105,
+ 105, 105, 105, 105, 105, 212, 212, 212,
+ 211, 211, 211, 211, 211, 211, 211, 210,
+ 210, 210, 210, 70, 70, 70, 70, 70,
+ 2, 2, 2, 105, 105, 105, 105, 105,
+ 105, 105, 105, 104, 104, 212, 212, 211,
+ 211, 211, 211, 211, 211, 211, 210, 210,
+ 210, 210, 210, 210, 210, 209, 209, 209,
+ 2, 2, 2, 105, 105, 105, 105, 104,
+ 104, 104, 104, 104, 103, 103, 211, 211,
+ 211, 211, 211, 211, 211, 210, 210, 210,
+ 210, 210, 210, 210, 209, 209, 209, 209,
+ 2, 2, 2, 104, 104, 104, 104, 104,
+ 104, 104, 104, 103, 103, 103, 211, 211,
+ 211, 211, 211, 211, 210, 210, 210, 210,
+ 210, 210, 210, 209, 209, 209, 209, 209,
+ 2, 2, 104, 104, 104, 104, 104, 104,
+ 104, 103, 103, 103, 103, 103, 103, 211,
+ 211, 211, 211, 210, 210, 210, 210, 210,
+ 210, 210, 209, 209, 209, 209, 209, 209,
+ 2, 102, 102, 102, 102, 102, 102, 102,
+ 103, 103, 103, 103, 103, 103, 103, 211,
+ 211, 211, 210, 210, 210, 210, 210, 210,
+ 210, 209, 209, 209, 209, 209, 209, 208,
+ 250, 102, 102, 102, 102, 102, 102, 102,
+ 102, 103, 103, 103, 103, 103, 103, 211,
+ 211, 210, 210, 210, 210, 210, 210, 210,
+ 209, 209, 209, 209, 209, 209, 208, 208,
+ 250, 250, 102, 102, 102, 102, 102, 102,
+ 102, 102, 103, 103, 103, 103, 103, 103,
+ 210, 210, 210, 210, 210, 210, 210, 209,
+ 209, 209, 209, 209, 209, 208, 208, 208,
+ 250, 250, 250, 102, 102, 102, 102, 102,
+ 102, 102, 102, 103, 103, 103, 103, 103,
+ 210, 210, 210, 210, 210, 210, 209, 209,
+ 209, 209, 209, 209, 208, 208, 208, 208,
+ 250, 250, 250, 250, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 103, 103, 103,
+ 210, 210, 210, 210, 210, 209, 209, 209,
+ 209, 209, 209, 208, 208, 208, 208, 208,
+ 250, 250, 250, 250, 250, 102, 102, 102,
+ 102, 102, 102, 102, 102, 101, 101, 101,
+ 210, 210, 210, 210, 209, 209, 209, 209,
+ 209, 209, 208, 208, 208, 208, 208, 207,
+ 250, 250, 250, 250, 250, 250, 102, 102,
+ 102, 102, 102, 102, 102, 101, 101, 101,
+ 210, 210, 210, 209, 209, 209, 209, 209,
+ 209, 208, 208, 208, 208, 208, 207, 207,
+ 250, 250, 250, 250, 250, 250, 250, 102,
+ 102, 102, 102, 102, 101, 101, 101, 101,
+ 210, 210, 209, 209, 209, 209, 209, 209,
+ 208, 208, 208, 208, 208, 207, 207, 207,
+ 250, 250, 250, 250, 250, 250, 250, 250,
+ 102, 102, 102, 102, 101, 101, 101, 101,
+ 101, 209, 209, 209, 209, 209, 209, 208,
+ 208, 208, 208, 208, 207, 207, 207, 207,
+ 247, 247, 247, 247, 247, 223, 223, 223,
+ 223, 223, 59, 59, 58, 58, 58, 57,
+ 57, 56, 56, 56, 56, 55, 55, 55,
+ 54, 54, 54, 252, 252, 252, 252, 252,
+ 247, 247, 247, 247, 44, 223, 223, 223,
+ 223, 223, 59, 59, 58, 58, 57, 57,
+ 57, 56, 56, 56, 55, 55, 55, 55,
+ 54, 54, 54, 54, 252, 252, 252, 252,
+ 247, 247, 247, 143, 143, 44, 223, 223,
+ 223, 59, 59, 59, 58, 58, 57, 57,
+ 57, 56, 56, 56, 55, 55, 55, 55,
+ 54, 54, 54, 54, 54, 252, 252, 252,
+ 247, 247, 143, 143, 143, 95, 95, 78,
+ 60, 59, 59, 59, 58, 58, 57, 57,
+ 56, 56, 56, 56, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 252, 252, 252,
+ 143, 143, 143, 143, 143, 43, 43, 94,
+ 78, 77, 59, 58, 58, 58, 57, 57,
+ 56, 56, 56, 56, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 54, 252, 252,
+ 159, 159, 159, 159, 159, 43, 94, 94,
+ 78, 77, 77, 77, 58, 58, 57, 57,
+ 56, 56, 56, 55, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 54, 53, 252,
+ 159, 159, 159, 159, 126, 126, 94, 93,
+ 77, 77, 77, 76, 76, 57, 57, 56,
+ 56, 56, 56, 55, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 53, 53, 53,
+ 159, 159, 159, 126, 126, 126, 94, 93,
+ 77, 77, 76, 76, 76, 75, 75, 56,
+ 56, 56, 56, 55, 55, 55, 55, 54,
+ 54, 54, 54, 54, 53, 53, 53, 53,
+ 110, 110, 110, 126, 126, 125, 125, 93,
+ 77, 77, 76, 76, 76, 75, 75, 75,
+ 74, 56, 56, 55, 55, 55, 54, 54,
+ 54, 54, 54, 53, 53, 53, 53, 53,
+ 110, 110, 110, 110, 109, 109, 125, 125,
+ 92, 76, 76, 76, 75, 75, 75, 74,
+ 74, 74, 73, 55, 55, 55, 54, 54,
+ 54, 54, 53, 53, 53, 53, 53, 53,
+ 110, 110, 109, 109, 109, 109, 109, 109,
+ 108, 76, 76, 76, 75, 75, 75, 74,
+ 74, 73, 73, 73, 73, 55, 54, 54,
+ 54, 53, 53, 53, 53, 53, 53, 53,
+ 110, 109, 109, 109, 109, 108, 108, 108,
+ 108, 108, 76, 75, 75, 75, 74, 74,
+ 74, 73, 73, 73, 73, 72, 72, 54,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 109, 109, 109, 108, 108, 108, 108, 108,
+ 108, 107, 107, 75, 75, 74, 74, 74,
+ 73, 73, 73, 73, 72, 72, 72, 71,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 2, 108, 108, 108, 108, 108, 108, 107,
+ 107, 107, 107, 213, 213, 74, 74, 74,
+ 73, 73, 73, 72, 72, 72, 71, 71,
+ 70, 70, 70, 53, 53, 53, 53, 53,
+ 2, 2, 108, 108, 107, 107, 107, 107,
+ 107, 107, 106, 106, 213, 212, 212, 212,
+ 73, 73, 73, 72, 72, 72, 71, 70,
+ 70, 70, 70, 70, 70, 70, 52, 52,
+ 2, 2, 107, 107, 107, 107, 107, 107,
+ 106, 106, 106, 106, 106, 212, 212, 212,
+ 212, 212, 72, 72, 72, 71, 71, 70,
+ 70, 70, 70, 70, 70, 70, 70, 52,
+ 2, 2, 2, 107, 107, 107, 106, 106,
+ 106, 106, 106, 106, 106, 212, 212, 212,
+ 212, 212, 211, 211, 71, 71, 70, 70,
+ 70, 70, 70, 70, 70, 70, 70, 70,
+ 2, 2, 2, 107, 105, 105, 106, 106,
+ 106, 106, 106, 106, 106, 212, 212, 212,
+ 212, 211, 211, 211, 211, 211, 70, 70,
+ 70, 70, 70, 70, 70, 70, 70, 70,
+ 2, 2, 2, 105, 105, 105, 105, 105,
+ 105, 105, 105, 105, 105, 212, 212, 212,
+ 211, 211, 211, 211, 211, 211, 211, 70,
+ 70, 70, 70, 70, 70, 70, 70, 70,
+ 2, 2, 105, 105, 105, 105, 105, 105,
+ 105, 105, 104, 104, 104, 103, 212, 211,
+ 211, 211, 211, 211, 211, 211, 210, 210,
+ 210, 210, 210, 70, 70, 70, 209, 209,
+ 2, 2, 105, 105, 105, 105, 104, 104,
+ 104, 104, 104, 104, 103, 103, 103, 211,
+ 211, 211, 211, 211, 211, 210, 210, 210,
+ 210, 210, 210, 210, 209, 209, 209, 209,
+ 2, 2, 104, 104, 104, 104, 104, 104,
+ 104, 104, 103, 103, 103, 103, 103, 211,
+ 211, 211, 211, 211, 210, 210, 210, 210,
+ 210, 210, 210, 209, 209, 209, 209, 209,
+ 2, 102, 104, 104, 104, 104, 104, 104,
+ 104, 103, 103, 103, 103, 103, 103, 211,
+ 211, 211, 211, 210, 210, 210, 210, 210,
+ 210, 210, 209, 209, 209, 209, 209, 209,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 103, 103, 103, 103, 103, 103, 103, 103,
+ 211, 211, 210, 210, 210, 210, 210, 210,
+ 210, 209, 209, 209, 209, 209, 209, 208,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 103, 103, 103, 103, 103, 103, 103,
+ 211, 210, 210, 210, 210, 210, 210, 210,
+ 209, 209, 209, 209, 209, 209, 208, 208,
+ 250, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 103, 103, 103, 103, 103,
+ 210, 210, 210, 210, 210, 210, 210, 209,
+ 209, 209, 209, 209, 209, 208, 208, 208,
+ 250, 250, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 103, 103, 103, 103,
+ 210, 210, 210, 210, 210, 210, 209, 209,
+ 209, 209, 209, 209, 208, 208, 208, 207,
+ 250, 250, 250, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 101, 101, 101, 101,
+ 210, 210, 210, 210, 210, 209, 209, 209,
+ 209, 209, 209, 208, 208, 208, 207, 207,
+ 250, 250, 250, 250, 102, 102, 102, 102,
+ 102, 102, 102, 102, 101, 101, 101, 101,
+ 101, 210, 210, 210, 209, 209, 209, 209,
+ 209, 209, 208, 208, 208, 207, 207, 207,
+ 250, 250, 250, 250, 250, 102, 102, 102,
+ 102, 102, 102, 102, 101, 101, 101, 101,
+ 100, 210, 210, 209, 209, 209, 209, 209,
+ 209, 208, 208, 208, 207, 207, 207, 207,
+ 250, 250, 250, 250, 250, 250, 102, 102,
+ 102, 102, 102, 101, 101, 101, 101, 101,
+ 100, 210, 209, 209, 209, 209, 209, 209,
+ 208, 208, 208, 207, 207, 207, 207, 207,
+ 250, 250, 250, 250, 250, 250, 250, 102,
+ 102, 102, 102, 101, 101, 101, 101, 101,
+ 100, 209, 209, 209, 209, 209, 209, 208,
+ 208, 208, 207, 207, 207, 207, 207, 207,
+ 246, 246, 246, 246, 223, 223, 223, 223,
+ 223, 223, 223, 222, 58, 58, 57, 57,
+ 57, 56, 56, 56, 55, 55, 55, 55,
+ 54, 54, 54, 54, 252, 252, 252, 252,
+ 246, 246, 246, 246, 223, 223, 223, 223,
+ 223, 223, 223, 222, 58, 58, 57, 57,
+ 57, 56, 56, 56, 55, 55, 55, 55,
+ 54, 54, 54, 54, 54, 252, 252, 252,
+ 246, 246, 246, 143, 143, 223, 223, 223,
+ 223, 223, 223, 59, 58, 58, 57, 57,
+ 56, 56, 56, 56, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 252, 252, 252,
+ 246, 246, 143, 143, 143, 143, 43, 223,
+ 223, 223, 59, 58, 58, 58, 57, 57,
+ 56, 56, 56, 56, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 54, 252, 252,
+ 246, 143, 143, 143, 142, 43, 43, 94,
+ 15, 15, 77, 58, 58, 58, 57, 57,
+ 56, 56, 56, 55, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 54, 53, 252,
+ 159, 159, 159, 142, 142, 43, 43, 15,
+ 15, 77, 77, 76, 58, 57, 57, 56,
+ 56, 56, 56, 55, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 53, 53, 53,
+ 159, 159, 158, 158, 158, 158, 42, 93,
+ 93, 77, 77, 76, 76, 76, 57, 56,
+ 56, 56, 56, 55, 55, 55, 55, 54,
+ 54, 54, 54, 54, 53, 53, 53, 53,
+ 159, 158, 158, 158, 158, 125, 125, 93,
+ 93, 77, 76, 76, 76, 75, 75, 75,
+ 56, 56, 56, 55, 55, 55, 54, 54,
+ 54, 54, 54, 53, 53, 53, 53, 53,
+ 158, 158, 158, 158, 125, 125, 125, 125,
+ 92, 92, 76, 76, 75, 75, 75, 75,
+ 74, 74, 55, 55, 55, 55, 54, 54,
+ 54, 54, 53, 53, 53, 53, 53, 53,
+ 158, 158, 158, 125, 125, 125, 125, 124,
+ 92, 92, 76, 76, 75, 75, 75, 74,
+ 74, 74, 73, 73, 55, 55, 54, 54,
+ 54, 53, 53, 53, 53, 53, 53, 53,
+ 110, 110, 109, 109, 109, 125, 124, 124,
+ 92, 92, 76, 75, 75, 75, 74, 74,
+ 74, 73, 73, 73, 73, 72, 54, 54,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 109, 109, 109, 109, 109, 108, 108, 108,
+ 124, 123, 91, 75, 75, 75, 74, 74,
+ 74, 73, 73, 73, 72, 72, 72, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 109, 109, 108, 108, 108, 108, 108, 108,
+ 107, 107, 91, 75, 75, 74, 74, 74,
+ 73, 73, 73, 72, 72, 72, 72, 71,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 191, 108, 108, 108, 108, 108, 107, 107,
+ 107, 107, 107, 75, 74, 74, 74, 73,
+ 73, 73, 73, 72, 72, 72, 71, 71,
+ 70, 70, 70, 53, 53, 52, 52, 52,
+ 2, 108, 108, 107, 107, 107, 107, 107,
+ 107, 106, 106, 106, 74, 74, 74, 73,
+ 73, 73, 72, 72, 72, 71, 71, 70,
+ 70, 70, 70, 70, 70, 52, 52, 52,
+ 2, 2, 107, 107, 107, 107, 107, 106,
+ 106, 106, 106, 106, 106, 212, 212, 73,
+ 73, 72, 72, 72, 71, 71, 71, 70,
+ 70, 70, 70, 70, 70, 70, 70, 52,
+ 2, 2, 107, 107, 107, 106, 106, 106,
+ 106, 106, 106, 106, 106, 212, 212, 212,
+ 212, 72, 72, 72, 71, 71, 70, 70,
+ 70, 70, 70, 70, 70, 70, 70, 70,
+ 2, 2, 105, 105, 105, 105, 105, 105,
+ 105, 105, 105, 106, 106, 212, 212, 212,
+ 212, 211, 211, 71, 71, 71, 70, 70,
+ 70, 70, 70, 70, 70, 70, 70, 70,
+ 2, 2, 105, 105, 105, 105, 105, 105,
+ 105, 105, 105, 105, 105, 104, 212, 212,
+ 211, 211, 211, 211, 211, 70, 70, 70,
+ 70, 70, 70, 70, 70, 70, 70, 68,
+ 2, 2, 105, 105, 105, 105, 105, 105,
+ 105, 104, 104, 104, 104, 103, 103, 211,
+ 211, 211, 211, 211, 211, 211, 210, 70,
+ 70, 70, 70, 70, 70, 70, 68, 68,
+ 2, 105, 105, 105, 105, 104, 104, 104,
+ 104, 104, 104, 103, 103, 103, 103, 211,
+ 211, 211, 211, 211, 211, 210, 210, 210,
+ 210, 210, 210, 210, 209, 209, 209, 209,
+ 2, 104, 104, 104, 104, 104, 104, 104,
+ 104, 104, 103, 103, 103, 103, 103, 103,
+ 211, 211, 211, 211, 210, 210, 210, 210,
+ 210, 210, 210, 209, 209, 209, 209, 209,
+ 102, 102, 102, 102, 102, 104, 104, 104,
+ 103, 103, 103, 103, 103, 103, 103, 103,
+ 211, 211, 211, 210, 210, 210, 210, 210,
+ 210, 210, 209, 209, 209, 209, 209, 209,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 103, 103, 103, 103, 103, 103, 103,
+ 211, 211, 210, 210, 210, 210, 210, 210,
+ 210, 209, 209, 209, 209, 209, 209, 208,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 103, 103, 103, 103, 103, 103,
+ 103, 210, 210, 210, 210, 210, 210, 210,
+ 209, 209, 209, 209, 209, 209, 208, 207,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 103, 103, 103, 103, 103,
+ 103, 210, 210, 210, 210, 210, 210, 209,
+ 209, 209, 209, 209, 209, 208, 207, 207,
+ 250, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 101, 101, 101, 101,
+ 100, 210, 210, 210, 210, 210, 209, 209,
+ 209, 209, 209, 209, 208, 207, 207, 207,
+ 250, 250, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 101, 101, 101, 101, 101,
+ 100, 210, 210, 210, 210, 209, 209, 209,
+ 209, 209, 209, 208, 207, 207, 207, 207,
+ 250, 250, 250, 102, 102, 102, 102, 102,
+ 102, 102, 102, 101, 101, 101, 101, 101,
+ 100, 100, 210, 210, 209, 209, 209, 209,
+ 209, 209, 208, 207, 207, 207, 207, 207,
+ 250, 250, 250, 250, 102, 102, 102, 102,
+ 102, 102, 102, 101, 101, 101, 101, 100,
+ 100, 100, 210, 209, 209, 209, 209, 209,
+ 209, 208, 207, 207, 207, 207, 207, 207,
+ 250, 250, 250, 250, 250, 102, 102, 102,
+ 102, 102, 101, 101, 101, 101, 101, 100,
+ 100, 100, 209, 209, 209, 209, 209, 209,
+ 208, 207, 207, 207, 207, 207, 207, 207,
+ 250, 250, 250, 250, 250, 250, 102, 102,
+ 102, 102, 101, 101, 101, 101, 101, 100,
+ 100, 100, 209, 209, 209, 209, 209, 208,
+ 207, 207, 207, 207, 207, 207, 207, 207,
+ 246, 246, 246, 246, 223, 223, 223, 223,
+ 223, 223, 222, 222, 222, 222, 57, 57,
+ 57, 56, 56, 56, 55, 55, 55, 55,
+ 54, 54, 54, 54, 54, 252, 252, 252,
+ 246, 246, 246, 246, 223, 223, 223, 223,
+ 223, 223, 222, 222, 222, 58, 57, 57,
+ 56, 56, 56, 56, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 252, 252, 252,
+ 246, 246, 246, 246, 143, 223, 223, 223,
+ 223, 223, 222, 222, 222, 58, 57, 57,
+ 56, 56, 56, 56, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 54, 252, 252,
+ 246, 246, 246, 143, 142, 142, 223, 223,
+ 223, 222, 222, 222, 58, 58, 57, 57,
+ 56, 56, 56, 55, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 54, 53, 252,
+ 246, 143, 143, 142, 142, 142, 43, 15,
+ 15, 15, 222, 222, 58, 57, 57, 56,
+ 56, 56, 56, 55, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 53, 53, 53,
+ 159, 159, 142, 142, 142, 142, 15, 15,
+ 15, 15, 15, 76, 76, 57, 57, 56,
+ 56, 56, 56, 55, 55, 55, 55, 54,
+ 54, 54, 54, 54, 53, 53, 53, 53,
+ 159, 158, 158, 158, 158, 158, 42, 15,
+ 15, 15, 92, 76, 76, 75, 75, 56,
+ 56, 56, 56, 55, 55, 55, 54, 54,
+ 54, 54, 54, 53, 53, 53, 53, 53,
+ 158, 158, 158, 158, 158, 141, 42, 42,
+ 41, 92, 92, 76, 76, 75, 75, 75,
+ 56, 56, 55, 55, 55, 55, 54, 54,
+ 54, 54, 53, 53, 53, 53, 53, 53,
+ 158, 158, 158, 158, 157, 125, 125, 41,
+ 92, 92, 92, 76, 75, 75, 75, 74,
+ 74, 74, 55, 55, 55, 55, 54, 54,
+ 54, 53, 53, 53, 53, 53, 53, 53,
+ 158, 158, 158, 157, 157, 125, 124, 124,
+ 92, 92, 91, 91, 75, 75, 75, 74,
+ 74, 74, 73, 73, 55, 55, 54, 54,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 191, 157, 157, 157, 124, 124, 124, 124,
+ 124, 92, 91, 91, 75, 75, 74, 74,
+ 74, 73, 73, 73, 72, 72, 54, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 191, 191, 157, 124, 124, 124, 124, 124,
+ 123, 123, 91, 91, 75, 74, 74, 74,
+ 73, 73, 73, 73, 72, 72, 72, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 191, 191, 108, 108, 108, 108, 108, 123,
+ 123, 123, 123, 90, 90, 74, 74, 74,
+ 73, 73, 73, 72, 72, 72, 71, 71,
+ 53, 53, 53, 53, 53, 52, 52, 52,
+ 191, 191, 108, 108, 108, 107, 107, 107,
+ 107, 123, 122, 90, 90, 74, 74, 73,
+ 73, 73, 72, 72, 72, 71, 71, 71,
+ 70, 70, 70, 52, 52, 52, 52, 52,
+ 191, 191, 107, 107, 107, 107, 107, 107,
+ 106, 106, 106, 106, 90, 74, 74, 73,
+ 73, 73, 72, 72, 72, 71, 71, 70,
+ 70, 70, 70, 70, 52, 52, 52, 52,
+ 191, 191, 107, 107, 107, 107, 106, 106,
+ 106, 106, 106, 106, 106, 74, 73, 73,
+ 73, 72, 72, 72, 71, 71, 71, 70,
+ 70, 70, 70, 70, 70, 70, 52, 52,
+ 191, 191, 107, 107, 106, 106, 106, 106,
+ 106, 106, 106, 106, 106, 106, 73, 73,
+ 72, 72, 72, 71, 71, 71, 70, 70,
+ 70, 70, 70, 70, 70, 70, 70, 51,
+ 2, 105, 105, 105, 105, 105, 105, 105,
+ 105, 105, 105, 105, 105, 105, 212, 212,
+ 72, 72, 72, 71, 71, 71, 70, 70,
+ 70, 70, 70, 70, 70, 70, 70, 68,
+ 2, 105, 105, 105, 105, 105, 105, 105,
+ 105, 105, 105, 104, 104, 104, 212, 212,
+ 211, 211, 71, 71, 71, 70, 70, 70,
+ 70, 70, 70, 70, 70, 68, 68, 68,
+ 2, 105, 105, 105, 105, 105, 105, 104,
+ 104, 104, 104, 104, 103, 103, 103, 211,
+ 211, 211, 211, 211, 211, 70, 70, 70,
+ 70, 70, 70, 70, 68, 68, 68, 68,
+ 2, 105, 105, 104, 104, 104, 104, 104,
+ 104, 104, 104, 103, 103, 103, 103, 103,
+ 211, 211, 211, 211, 210, 210, 210, 70,
+ 70, 70, 69, 68, 68, 68, 68, 68,
+ 104, 104, 104, 104, 104, 104, 104, 104,
+ 104, 103, 103, 103, 103, 103, 103, 103,
+ 211, 211, 211, 210, 210, 210, 210, 210,
+ 210, 210, 210, 68, 68, 209, 209, 209,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 103, 103, 103, 103, 103, 103, 103, 103,
+ 211, 211, 210, 210, 210, 210, 210, 210,
+ 210, 210, 209, 209, 209, 209, 209, 206,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 103, 103, 103, 103, 103, 103, 103,
+ 103, 210, 210, 210, 210, 210, 210, 210,
+ 210, 209, 209, 209, 209, 209, 206, 206,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 103, 103, 103, 103, 103, 103,
+ 100, 210, 210, 210, 210, 210, 210, 210,
+ 209, 209, 209, 209, 209, 206, 206, 207,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 101, 101, 101, 101, 100,
+ 100, 210, 210, 210, 210, 210, 210, 209,
+ 209, 209, 209, 209, 206, 206, 207, 207,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 101, 101, 101, 101, 100,
+ 100, 100, 210, 210, 210, 210, 209, 209,
+ 209, 209, 209, 206, 206, 207, 207, 207,
+ 250, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 101, 101, 101, 101, 101, 100,
+ 100, 100, 210, 210, 210, 209, 209, 209,
+ 209, 209, 206, 206, 207, 207, 207, 207,
+ 250, 250, 102, 102, 102, 102, 102, 102,
+ 102, 102, 101, 101, 101, 101, 101, 100,
+ 100, 100, 210, 210, 209, 209, 209, 209,
+ 209, 206, 206, 207, 207, 207, 207, 207,
+ 250, 250, 250, 102, 102, 102, 102, 102,
+ 102, 102, 101, 101, 101, 101, 100, 100,
+ 100, 100, 99, 209, 209, 209, 209, 209,
+ 206, 206, 207, 207, 207, 207, 207, 207,
+ 250, 250, 250, 250, 102, 102, 102, 102,
+ 102, 101, 101, 101, 101, 101, 100, 100,
+ 100, 100, 98, 209, 209, 209, 209, 206,
+ 206, 207, 207, 207, 207, 207, 207, 207,
+ 250, 250, 250, 250, 250, 102, 102, 102,
+ 102, 101, 101, 101, 101, 101, 100, 100,
+ 100, 98, 98, 209, 209, 209, 206, 206,
+ 207, 207, 207, 207, 207, 207, 207, 207,
+ 245, 245, 245, 245, 223, 223, 223, 223,
+ 223, 222, 222, 222, 222, 222, 221, 221,
+ 56, 56, 56, 56, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 252, 252, 252,
+ 245, 245, 245, 245, 223, 223, 223, 223,
+ 223, 222, 222, 222, 222, 222, 221, 221,
+ 56, 56, 56, 56, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 54, 252, 252,
+ 245, 245, 245, 245, 223, 223, 223, 223,
+ 223, 222, 222, 222, 222, 221, 221, 57,
+ 56, 56, 56, 55, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 54, 53, 252,
+ 245, 245, 245, 142, 142, 142, 223, 223,
+ 222, 222, 222, 222, 222, 221, 57, 56,
+ 56, 56, 56, 55, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 53, 53, 53,
+ 245, 245, 142, 142, 142, 142, 15, 15,
+ 15, 222, 222, 222, 222, 57, 57, 56,
+ 56, 56, 56, 55, 55, 55, 55, 54,
+ 54, 54, 54, 54, 53, 53, 53, 53,
+ 245, 142, 142, 142, 142, 141, 141, 15,
+ 15, 15, 15, 76, 76, 57, 57, 56,
+ 56, 56, 56, 55, 55, 55, 54, 54,
+ 54, 54, 54, 53, 53, 53, 53, 53,
+ 158, 158, 158, 158, 141, 141, 141, 15,
+ 15, 41, 92, 92, 76, 75, 75, 56,
+ 56, 56, 55, 55, 55, 55, 54, 54,
+ 54, 54, 53, 53, 53, 53, 53, 53,
+ 158, 158, 158, 158, 141, 141, 141, 41,
+ 41, 92, 92, 91, 91, 75, 75, 75,
+ 74, 56, 55, 55, 55, 55, 54, 54,
+ 54, 53, 53, 53, 53, 53, 53, 53,
+ 158, 158, 157, 157, 157, 157, 157, 41,
+ 41, 92, 91, 91, 91, 75, 75, 74,
+ 74, 74, 73, 55, 55, 55, 54, 54,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 158, 157, 157, 157, 157, 157, 124, 124,
+ 40, 40, 91, 91, 91, 75, 74, 74,
+ 74, 74, 73, 73, 55, 54, 54, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 191, 191, 157, 157, 157, 124, 124, 124,
+ 123, 123, 91, 91, 90, 90, 74, 74,
+ 74, 73, 73, 73, 72, 72, 53, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 191, 191, 191, 124, 124, 124, 124, 123,
+ 123, 123, 91, 90, 90, 90, 74, 74,
+ 73, 73, 73, 72, 72, 72, 72, 53,
+ 53, 53, 53, 53, 53, 52, 52, 52,
+ 191, 191, 191, 191, 124, 124, 123, 123,
+ 123, 123, 122, 90, 90, 90, 74, 74,
+ 73, 73, 73, 72, 72, 72, 71, 71,
+ 53, 52, 52, 52, 52, 52, 52, 52,
+ 191, 191, 191, 191, 107, 107, 123, 123,
+ 122, 122, 122, 122, 90, 89, 74, 73,
+ 73, 73, 72, 72, 72, 71, 71, 71,
+ 70, 70, 52, 52, 52, 52, 52, 52,
+ 191, 191, 191, 191, 107, 107, 107, 107,
+ 122, 122, 122, 121, 89, 89, 89, 73,
+ 73, 72, 72, 72, 71, 71, 71, 70,
+ 70, 70, 70, 70, 52, 52, 52, 52,
+ 191, 191, 191, 107, 107, 107, 106, 106,
+ 106, 106, 121, 121, 121, 89, 89, 73,
+ 73, 72, 72, 72, 71, 71, 71, 70,
+ 70, 70, 70, 70, 70, 52, 51, 51,
+ 191, 191, 191, 105, 105, 105, 106, 106,
+ 106, 106, 106, 121, 121, 121, 88, 88,
+ 72, 72, 72, 71, 71, 71, 70, 70,
+ 70, 70, 70, 70, 70, 70, 51, 51,
+ 191, 191, 105, 105, 105, 105, 105, 105,
+ 105, 105, 105, 105, 105, 120, 88, 88,
+ 72, 72, 71, 71, 71, 71, 70, 70,
+ 70, 70, 70, 70, 70, 68, 68, 68,
+ 191, 191, 105, 105, 105, 105, 105, 105,
+ 105, 105, 104, 104, 104, 104, 120, 87,
+ 72, 71, 71, 71, 71, 70, 70, 70,
+ 70, 70, 70, 69, 68, 68, 68, 68,
+ 191, 105, 105, 105, 105, 105, 104, 104,
+ 104, 104, 104, 104, 103, 103, 103, 103,
+ 211, 211, 71, 71, 70, 70, 70, 70,
+ 70, 69, 69, 68, 68, 68, 68, 68,
+ 105, 105, 104, 104, 104, 104, 104, 104,
+ 104, 104, 103, 103, 103, 103, 103, 103,
+ 211, 211, 211, 211, 70, 70, 70, 69,
+ 69, 69, 68, 68, 68, 68, 68, 68,
+ 102, 102, 104, 104, 104, 104, 104, 104,
+ 104, 103, 103, 103, 103, 103, 103, 103,
+ 103, 211, 211, 210, 210, 210, 210, 69,
+ 69, 68, 68, 68, 68, 68, 68, 68,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 103, 103, 103, 103, 103, 103, 103, 103,
+ 103, 211, 210, 210, 210, 210, 210, 210,
+ 210, 68, 68, 68, 68, 68, 206, 206,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 103, 103, 103, 103, 103, 100,
+ 100, 100, 210, 210, 210, 210, 210, 210,
+ 210, 209, 209, 209, 206, 206, 206, 206,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 101, 101, 101, 101, 100,
+ 100, 100, 210, 210, 210, 210, 210, 210,
+ 209, 209, 209, 206, 206, 206, 206, 206,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 101, 101, 101, 101, 100, 100,
+ 100, 100, 210, 210, 210, 210, 210, 209,
+ 209, 209, 206, 206, 206, 206, 206, 206,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 101, 101, 101, 101, 100, 100,
+ 100, 100, 99, 210, 210, 210, 209, 209,
+ 209, 206, 206, 206, 206, 206, 206, 206,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 101, 101, 101, 101, 101, 100, 100,
+ 100, 100, 99, 210, 210, 209, 209, 209,
+ 206, 206, 206, 206, 206, 206, 206, 206,
+ 250, 102, 102, 102, 102, 102, 102, 102,
+ 102, 101, 101, 101, 101, 101, 100, 100,
+ 100, 100, 99, 98, 209, 209, 209, 206,
+ 206, 206, 206, 206, 206, 206, 206, 206,
+ 250, 250, 102, 102, 102, 102, 102, 102,
+ 102, 101, 101, 101, 101, 100, 100, 100,
+ 100, 99, 98, 98, 209, 209, 206, 206,
+ 206, 206, 206, 206, 206, 206, 206, 206,
+ 250, 250, 250, 102, 102, 102, 102, 102,
+ 101, 101, 101, 101, 101, 100, 100, 100,
+ 100, 98, 98, 98, 209, 206, 206, 206,
+ 206, 206, 206, 206, 206, 206, 206, 206,
+ 250, 250, 250, 250, 102, 102, 102, 102,
+ 101, 101, 101, 101, 101, 100, 100, 100,
+ 98, 98, 98, 98, 206, 206, 206, 206,
+ 206, 206, 206, 206, 206, 206, 206, 206,
+ 245, 245, 245, 245, 245, 223, 223, 223,
+ 222, 222, 222, 222, 222, 221, 221, 221,
+ 221, 221, 56, 56, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 54, 252, 252,
+ 245, 245, 245, 245, 245, 223, 223, 223,
+ 222, 222, 222, 222, 222, 221, 221, 221,
+ 221, 56, 56, 55, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 54, 53, 252,
+ 245, 245, 245, 245, 245, 223, 223, 223,
+ 222, 222, 222, 222, 221, 221, 221, 221,
+ 221, 56, 56, 55, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 53, 53, 53,
+ 245, 245, 245, 245, 142, 223, 223, 222,
+ 222, 222, 222, 222, 221, 221, 221, 221,
+ 56, 56, 56, 55, 55, 55, 55, 54,
+ 54, 54, 54, 54, 53, 53, 53, 53,
+ 245, 245, 245, 142, 142, 141, 141, 15,
+ 222, 222, 222, 222, 221, 221, 221, 56,
+ 56, 56, 56, 55, 55, 55, 54, 54,
+ 54, 54, 54, 53, 53, 53, 53, 53,
+ 245, 142, 142, 142, 141, 141, 141, 15,
+ 15, 15, 222, 222, 221, 221, 221, 56,
+ 56, 56, 55, 55, 55, 55, 54, 54,
+ 54, 54, 53, 53, 53, 53, 53, 53,
+ 158, 158, 158, 141, 141, 141, 141, 141,
+ 41, 41, 40, 91, 91, 91, 75, 75,
+ 56, 56, 55, 55, 55, 55, 54, 54,
+ 54, 53, 53, 53, 53, 53, 53, 53,
+ 158, 158, 141, 141, 141, 141, 141, 140,
+ 41, 40, 40, 91, 91, 91, 75, 74,
+ 74, 74, 55, 55, 55, 55, 54, 54,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 158, 157, 157, 157, 157, 157, 140, 140,
+ 40, 40, 91, 91, 91, 90, 90, 74,
+ 74, 74, 73, 55, 55, 54, 54, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 191, 191, 157, 157, 157, 156, 156, 156,
+ 40, 40, 91, 91, 90, 90, 90, 74,
+ 74, 73, 73, 73, 72, 54, 53, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 191, 191, 191, 156, 156, 156, 156, 123,
+ 123, 39, 39, 90, 90, 90, 90, 74,
+ 74, 73, 73, 72, 72, 72, 53, 53,
+ 53, 53, 53, 53, 53, 52, 52, 52,
+ 191, 191, 191, 191, 156, 156, 123, 123,
+ 123, 123, 38, 90, 90, 90, 89, 74,
+ 73, 73, 73, 72, 72, 72, 71, 53,
+ 53, 52, 52, 52, 52, 52, 52, 52,
+ 191, 191, 191, 191, 156, 123, 123, 123,
+ 123, 122, 122, 90, 90, 89, 89, 89,
+ 73, 73, 72, 72, 72, 71, 71, 71,
+ 52, 52, 52, 52, 52, 52, 52, 52,
+ 191, 191, 191, 191, 191, 123, 123, 122,
+ 122, 122, 122, 122, 89, 89, 89, 88,
+ 73, 72, 72, 72, 72, 71, 71, 71,
+ 70, 52, 52, 52, 52, 52, 52, 52,
+ 191, 191, 191, 191, 191, 122, 122, 122,
+ 122, 122, 121, 121, 89, 89, 89, 88,
+ 88, 72, 72, 72, 71, 71, 71, 70,
+ 70, 70, 70, 52, 52, 52, 51, 51,
+ 191, 191, 191, 191, 191, 106, 106, 121,
+ 121, 121, 121, 121, 121, 89, 88, 88,
+ 88, 72, 72, 71, 71, 71, 71, 70,
+ 70, 70, 70, 70, 51, 51, 51, 51,
+ 191, 191, 191, 191, 105, 105, 105, 105,
+ 121, 121, 121, 121, 121, 120, 88, 88,
+ 88, 72, 71, 71, 71, 71, 70, 70,
+ 70, 70, 70, 69, 69, 51, 51, 51,
+ 191, 191, 191, 105, 105, 105, 105, 105,
+ 105, 105, 121, 120, 120, 120, 88, 88,
+ 87, 72, 71, 71, 71, 71, 70, 70,
+ 70, 69, 69, 69, 68, 68, 68, 68,
+ 191, 190, 190, 105, 105, 105, 105, 105,
+ 105, 104, 104, 104, 120, 120, 120, 87,
+ 87, 87, 71, 71, 71, 70, 70, 69,
+ 69, 69, 69, 68, 68, 68, 68, 68,
+ 190, 190, 105, 105, 105, 104, 104, 104,
+ 104, 104, 104, 103, 103, 103, 103, 87,
+ 87, 87, 71, 71, 70, 69, 69, 69,
+ 69, 69, 68, 68, 68, 68, 68, 68,
+ 190, 104, 104, 104, 104, 104, 104, 104,
+ 104, 104, 103, 103, 103, 103, 103, 103,
+ 87, 86, 71, 71, 69, 69, 69, 69,
+ 69, 68, 68, 68, 68, 68, 68, 68,
+ 102, 102, 102, 102, 102, 102, 104, 104,
+ 103, 103, 103, 103, 103, 103, 103, 103,
+ 100, 211, 211, 69, 69, 69, 69, 69,
+ 68, 68, 68, 68, 68, 68, 68, 68,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 103, 103, 103, 103, 103, 103, 100,
+ 100, 100, 210, 210, 210, 69, 69, 68,
+ 68, 68, 68, 68, 68, 68, 68, 206,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 101, 101, 101, 101, 100, 100,
+ 100, 100, 99, 210, 210, 210, 210, 68,
+ 68, 68, 68, 206, 206, 206, 206, 206,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 101, 101, 101, 101, 100, 100,
+ 100, 100, 99, 210, 210, 210, 210, 210,
+ 209, 206, 206, 206, 206, 206, 206, 206,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 101, 101, 101, 101, 100, 100, 100,
+ 100, 100, 99, 99, 210, 210, 210, 209,
+ 206, 206, 206, 206, 206, 206, 206, 206,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 101, 101, 101, 101, 100, 100, 100,
+ 100, 99, 99, 99, 210, 210, 209, 206,
+ 206, 206, 206, 206, 206, 206, 206, 206,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 101, 101, 101, 101, 101, 100, 100, 100,
+ 100, 99, 99, 99, 98, 209, 206, 206,
+ 206, 206, 206, 206, 206, 206, 206, 206,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 101, 101, 101, 101, 101, 100, 100, 100,
+ 100, 99, 98, 98, 98, 206, 206, 206,
+ 206, 206, 206, 206, 206, 206, 206, 206,
+ 250, 102, 102, 102, 102, 102, 102, 102,
+ 101, 101, 101, 101, 100, 100, 100, 100,
+ 99, 98, 98, 98, 98, 206, 206, 206,
+ 206, 206, 206, 206, 206, 206, 206, 206,
+ 250, 250, 102, 102, 102, 102, 102, 101,
+ 101, 101, 101, 101, 100, 100, 100, 100,
+ 98, 98, 98, 98, 98, 206, 206, 206,
+ 206, 206, 206, 206, 206, 206, 206, 205,
+ 250, 250, 250, 102, 102, 102, 102, 101,
+ 101, 101, 101, 101, 100, 100, 100, 98,
+ 98, 98, 98, 98, 98, 206, 206, 206,
+ 206, 206, 206, 206, 206, 206, 205, 205,
+ 244, 244, 244, 244, 244, 223, 223, 222,
+ 222, 222, 222, 222, 221, 221, 221, 221,
+ 221, 220, 220, 5, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 54, 53, 252,
+ 244, 244, 244, 244, 244, 223, 223, 222,
+ 222, 222, 222, 222, 221, 221, 221, 221,
+ 220, 220, 220, 220, 55, 55, 55, 54,
+ 54, 54, 54, 54, 54, 53, 53, 53,
+ 244, 244, 244, 244, 244, 223, 223, 222,
+ 222, 222, 222, 221, 221, 221, 221, 221,
+ 220, 220, 220, 55, 55, 55, 55, 54,
+ 54, 54, 54, 54, 53, 53, 53, 53,
+ 244, 244, 244, 244, 244, 141, 222, 222,
+ 222, 222, 222, 221, 221, 221, 221, 221,
+ 220, 220, 220, 55, 55, 55, 54, 54,
+ 54, 54, 54, 53, 53, 53, 53, 53,
+ 244, 244, 244, 141, 141, 141, 141, 222,
+ 222, 222, 222, 221, 221, 221, 221, 221,
+ 220, 220, 55, 55, 55, 55, 54, 54,
+ 54, 54, 53, 53, 53, 53, 53, 53,
+ 244, 244, 141, 141, 141, 141, 141, 141,
+ 15, 222, 222, 221, 221, 221, 221, 221,
+ 220, 56, 55, 55, 55, 55, 54, 54,
+ 54, 53, 53, 53, 53, 53, 53, 53,
+ 244, 141, 141, 141, 141, 141, 140, 140,
+ 140, 40, 40, 91, 91, 91, 90, 90,
+ 56, 56, 55, 55, 55, 55, 54, 54,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 158, 141, 141, 141, 141, 140, 140, 140,
+ 140, 40, 40, 91, 91, 90, 90, 90,
+ 74, 74, 55, 55, 55, 54, 54, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 191, 191, 157, 157, 140, 140, 140, 140,
+ 40, 40, 39, 39, 90, 90, 90, 90,
+ 74, 74, 73, 55, 55, 54, 53, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 191, 191, 191, 156, 156, 156, 156, 156,
+ 139, 39, 39, 38, 90, 90, 90, 90,
+ 74, 73, 73, 73, 72, 53, 53, 53,
+ 53, 53, 53, 53, 53, 52, 52, 52,
+ 191, 191, 191, 156, 156, 156, 156, 155,
+ 123, 39, 38, 38, 90, 90, 90, 89,
+ 88, 73, 73, 72, 72, 72, 53, 53,
+ 53, 52, 52, 52, 52, 52, 52, 52,
+ 191, 191, 191, 191, 156, 156, 155, 155,
+ 123, 122, 38, 90, 90, 89, 89, 89,
+ 88, 73, 72, 72, 72, 72, 71, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52,
+ 191, 191, 191, 191, 191, 155, 155, 155,
+ 122, 122, 122, 37, 89, 89, 89, 88,
+ 88, 88, 72, 72, 72, 71, 71, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52,
+ 191, 191, 191, 191, 191, 155, 155, 122,
+ 122, 122, 122, 121, 89, 89, 89, 88,
+ 88, 88, 72, 72, 71, 71, 71, 71,
+ 52, 52, 52, 52, 52, 52, 51, 51,
+ 191, 191, 191, 191, 191, 155, 122, 122,
+ 122, 121, 121, 121, 121, 89, 88, 88,
+ 88, 88, 72, 72, 71, 71, 71, 70,
+ 70, 70, 52, 51, 51, 51, 51, 51,
+ 191, 191, 191, 191, 191, 122, 121, 121,
+ 121, 121, 121, 121, 121, 89, 88, 88,
+ 88, 87, 72, 71, 71, 71, 71, 70,
+ 70, 70, 69, 51, 51, 51, 51, 51,
+ 191, 191, 191, 191, 191, 105, 121, 121,
+ 121, 121, 121, 120, 120, 120, 88, 88,
+ 87, 87, 87, 71, 71, 71, 70, 70,
+ 69, 69, 69, 69, 68, 51, 51, 50,
+ 191, 190, 190, 190, 105, 105, 105, 105,
+ 121, 121, 120, 120, 120, 120, 120, 87,
+ 87, 87, 87, 71, 71, 70, 69, 69,
+ 69, 69, 69, 68, 68, 68, 68, 50,
+ 190, 190, 190, 190, 105, 105, 105, 105,
+ 104, 104, 120, 120, 120, 120, 119, 87,
+ 87, 87, 86, 71, 71, 69, 69, 69,
+ 69, 69, 68, 68, 68, 68, 68, 68,
+ 190, 190, 190, 105, 104, 104, 104, 104,
+ 104, 104, 104, 103, 120, 119, 119, 119,
+ 87, 86, 86, 71, 69, 69, 69, 69,
+ 69, 68, 68, 68, 68, 68, 68, 68,
+ 3, 190, 190, 104, 104, 104, 104, 104,
+ 104, 103, 103, 103, 103, 103, 118, 118,
+ 118, 86, 86, 69, 69, 69, 69, 69,
+ 68, 68, 68, 68, 68, 68, 68, 68,
+ 3, 102, 102, 102, 102, 102, 102, 102,
+ 103, 103, 103, 103, 103, 103, 100, 100,
+ 118, 86, 86, 69, 69, 69, 69, 68,
+ 68, 68, 68, 68, 68, 68, 68, 68,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 101, 101, 101, 101, 100, 100, 100,
+ 100, 100, 99, 69, 69, 69, 68, 68,
+ 68, 68, 68, 68, 68, 68, 67, 67,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 101, 101, 101, 101, 100, 100, 100,
+ 100, 99, 99, 99, 69, 68, 68, 68,
+ 68, 68, 68, 68, 67, 206, 206, 206,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 101, 101, 101, 101, 100, 100, 100,
+ 100, 99, 99, 99, 210, 210, 68, 68,
+ 68, 206, 206, 206, 206, 206, 206, 206,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 101, 101, 101, 101, 100, 100, 100, 100,
+ 100, 99, 99, 99, 99, 210, 206, 206,
+ 206, 206, 206, 206, 206, 206, 206, 206,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 101, 101, 101, 101, 100, 100, 100, 100,
+ 99, 99, 99, 99, 99, 206, 206, 206,
+ 206, 206, 206, 206, 206, 206, 206, 205,
+ 102, 102, 102, 102, 102, 102, 102, 101,
+ 101, 101, 101, 101, 100, 100, 100, 100,
+ 99, 99, 99, 98, 98, 206, 206, 206,
+ 206, 206, 206, 206, 206, 206, 205, 205,
+ 102, 102, 102, 102, 102, 102, 102, 101,
+ 101, 101, 101, 101, 100, 100, 100, 100,
+ 99, 98, 98, 98, 98, 206, 206, 206,
+ 206, 206, 206, 206, 206, 205, 205, 205,
+ 102, 102, 102, 102, 102, 102, 102, 101,
+ 101, 101, 101, 100, 100, 100, 100, 99,
+ 98, 98, 98, 98, 98, 206, 206, 206,
+ 206, 206, 206, 206, 205, 205, 205, 205,
+ 250, 102, 102, 102, 102, 102, 101, 101,
+ 101, 101, 101, 100, 100, 100, 100, 98,
+ 98, 98, 98, 98, 98, 206, 206, 206,
+ 206, 206, 206, 205, 205, 205, 205, 205,
+ 250, 250, 102, 102, 102, 102, 101, 101,
+ 101, 101, 101, 100, 100, 100, 98, 98,
+ 98, 98, 98, 98, 98, 206, 206, 206,
+ 206, 206, 205, 205, 205, 205, 205, 205,
+ 243, 243, 243, 244, 244, 244, 222, 222,
+ 222, 222, 222, 221, 221, 221, 221, 221,
+ 220, 220, 5, 5, 5, 5, 5, 54,
+ 54, 54, 54, 54, 54, 53, 53, 53,
+ 243, 243, 244, 244, 244, 223, 222, 222,
+ 222, 222, 222, 221, 221, 221, 221, 220,
+ 220, 220, 220, 5, 5, 55, 55, 54,
+ 54, 54, 54, 54, 53, 53, 53, 53,
+ 243, 244, 244, 244, 244, 223, 222, 222,
+ 222, 222, 221, 221, 221, 221, 221, 220,
+ 220, 220, 220, 220, 219, 55, 54, 54,
+ 54, 54, 54, 53, 53, 53, 53, 53,
+ 244, 244, 244, 244, 244, 141, 222, 222,
+ 222, 222, 221, 221, 221, 221, 221, 220,
+ 220, 220, 220, 220, 55, 55, 54, 54,
+ 54, 54, 53, 53, 53, 53, 53, 53,
+ 244, 244, 244, 244, 141, 141, 141, 222,
+ 222, 222, 221, 221, 221, 221, 221, 220,
+ 220, 220, 220, 55, 55, 55, 54, 54,
+ 54, 53, 53, 53, 53, 53, 53, 53,
+ 244, 244, 244, 141, 141, 141, 140, 140,
+ 140, 222, 221, 221, 221, 221, 221, 220,
+ 220, 220, 220, 55, 55, 55, 54, 54,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 244, 141, 141, 141, 140, 140, 140, 140,
+ 140, 40, 40, 39, 221, 221, 221, 220,
+ 220, 220, 55, 55, 55, 54, 54, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 191, 201, 201, 201, 140, 140, 140, 140,
+ 139, 139, 39, 39, 38, 90, 14, 14,
+ 14, 14, 55, 55, 55, 54, 53, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 191, 191, 201, 201, 140, 140, 140, 139,
+ 139, 139, 39, 38, 38, 90, 14, 14,
+ 14, 14, 73, 73, 55, 53, 53, 53,
+ 53, 53, 53, 53, 53, 52, 52, 52,
+ 191, 191, 191, 201, 156, 156, 139, 139,
+ 139, 39, 38, 38, 90, 14, 14, 14,
+ 14, 88, 88, 72, 72, 53, 53, 53,
+ 53, 52, 52, 52, 52, 52, 52, 52,
+ 191, 191, 191, 191, 156, 156, 155, 155,
+ 155, 38, 38, 38, 90, 14, 14, 14,
+ 88, 88, 88, 72, 72, 72, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52,
+ 191, 191, 191, 191, 155, 155, 155, 155,
+ 155, 122, 38, 37, 37, 89, 89, 88,
+ 88, 88, 88, 72, 72, 71, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52,
+ 191, 191, 191, 191, 191, 155, 155, 155,
+ 122, 122, 122, 37, 37, 89, 89, 88,
+ 88, 88, 88, 72, 72, 71, 71, 52,
+ 52, 52, 52, 52, 52, 52, 51, 51,
+ 191, 191, 191, 191, 191, 155, 155, 122,
+ 122, 122, 121, 121, 89, 89, 88, 88,
+ 88, 88, 87, 72, 71, 71, 71, 71,
+ 52, 52, 52, 51, 51, 51, 51, 51,
+ 191, 191, 191, 191, 191, 155, 154, 122,
+ 121, 121, 121, 121, 121, 89, 88, 88,
+ 88, 87, 87, 71, 71, 71, 71, 70,
+ 70, 51, 51, 51, 51, 51, 51, 51,
+ 191, 191, 191, 191, 191, 191, 121, 121,
+ 121, 121, 121, 121, 120, 120, 88, 88,
+ 87, 87, 87, 87, 71, 71, 71, 69,
+ 69, 69, 51, 51, 51, 51, 51, 50,
+ 191, 190, 190, 190, 190, 190, 121, 121,
+ 121, 121, 120, 120, 120, 120, 88, 87,
+ 87, 87, 87, 86, 71, 71, 69, 69,
+ 69, 69, 69, 68, 51, 50, 50, 50,
+ 190, 190, 190, 190, 190, 190, 121, 121,
+ 121, 120, 120, 120, 120, 120, 119, 87,
+ 87, 87, 86, 86, 71, 69, 69, 69,
+ 69, 69, 68, 68, 68, 68, 50, 50,
+ 190, 190, 190, 190, 190, 105, 104, 120,
+ 120, 120, 120, 120, 120, 119, 119, 87,
+ 87, 86, 86, 86, 69, 69, 69, 69,
+ 69, 68, 68, 68, 68, 68, 68, 50,
+ 3, 190, 190, 190, 104, 104, 104, 104,
+ 104, 120, 120, 119, 119, 119, 119, 118,
+ 87, 86, 86, 86, 69, 69, 69, 69,
+ 68, 68, 68, 68, 68, 68, 68, 68,
+ 3, 3, 190, 190, 104, 104, 104, 104,
+ 104, 103, 103, 119, 119, 118, 118, 118,
+ 118, 86, 86, 86, 69, 69, 69, 68,
+ 68, 68, 68, 68, 68, 68, 68, 67,
+ 3, 3, 189, 102, 102, 102, 102, 102,
+ 102, 101, 101, 101, 101, 100, 118, 118,
+ 118, 117, 86, 85, 69, 69, 68, 68,
+ 68, 68, 68, 68, 68, 67, 67, 67,
+ 3, 189, 102, 102, 102, 102, 102, 102,
+ 101, 101, 101, 101, 100, 100, 100, 100,
+ 100, 99, 99, 85, 69, 68, 68, 68,
+ 68, 68, 68, 67, 67, 67, 67, 67,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 101, 101, 101, 101, 100, 100, 100, 100,
+ 99, 99, 99, 99, 68, 68, 68, 68,
+ 68, 67, 67, 67, 67, 67, 67, 205,
+ 102, 102, 102, 102, 102, 102, 102, 102,
+ 101, 101, 101, 101, 100, 100, 100, 100,
+ 99, 99, 99, 99, 99, 68, 68, 67,
+ 67, 67, 67, 206, 206, 206, 205, 205,
+ 102, 102, 102, 102, 102, 102, 102, 101,
+ 101, 101, 101, 100, 100, 100, 100, 100,
+ 99, 99, 99, 99, 99, 98, 67, 67,
+ 206, 206, 206, 206, 206, 205, 205, 205,
+ 102, 102, 102, 102, 102, 102, 102, 101,
+ 101, 101, 101, 100, 100, 100, 100, 99,
+ 99, 99, 99, 99, 98, 98, 206, 206,
+ 206, 206, 206, 206, 205, 205, 205, 205,
+ 102, 102, 102, 102, 102, 102, 101, 101,
+ 101, 101, 101, 100, 100, 100, 100, 99,
+ 99, 99, 98, 98, 98, 98, 206, 206,
+ 206, 206, 206, 205, 205, 205, 205, 205,
+ 102, 102, 102, 102, 102, 102, 101, 101,
+ 101, 101, 101, 100, 100, 100, 100, 99,
+ 98, 98, 98, 98, 98, 98, 206, 206,
+ 206, 206, 205, 205, 205, 205, 205, 205,
+ 102, 102, 102, 102, 102, 102, 101, 101,
+ 101, 101, 100, 100, 100, 100, 99, 98,
+ 98, 98, 98, 98, 98, 97, 206, 206,
+ 206, 205, 205, 205, 205, 205, 205, 205,
+ 102, 102, 102, 102, 102, 101, 101, 101,
+ 101, 101, 100, 100, 100, 100, 98, 98,
+ 98, 98, 98, 98, 98, 97, 206, 206,
+ 205, 205, 205, 205, 205, 205, 205, 205,
+ 250, 102, 102, 102, 102, 101, 101, 101,
+ 101, 101, 100, 100, 100, 98, 98, 98,
+ 98, 98, 98, 98, 98, 97, 206, 205,
+ 205, 205, 205, 205, 205, 205, 205, 205,
+ 243, 243, 243, 243, 243, 243, 222, 222,
+ 222, 222, 221, 221, 221, 221, 221, 220,
+ 220, 5, 5, 5, 5, 5, 5, 5,
+ 54, 54, 54, 54, 53, 53, 53, 53,
+ 243, 243, 243, 243, 243, 243, 222, 222,
+ 222, 222, 221, 221, 221, 221, 220, 220,
+ 220, 220, 5, 5, 5, 5, 219, 54,
+ 54, 54, 54, 53, 53, 53, 53, 53,
+ 243, 243, 243, 243, 243, 243, 222, 222,
+ 222, 221, 221, 221, 221, 221, 220, 220,
+ 220, 220, 220, 219, 219, 219, 219, 54,
+ 54, 54, 53, 53, 53, 53, 53, 53,
+ 243, 243, 243, 243, 175, 175, 222, 222,
+ 222, 221, 221, 221, 221, 221, 220, 220,
+ 220, 220, 220, 219, 219, 219, 54, 54,
+ 54, 53, 53, 53, 53, 53, 53, 53,
+ 243, 243, 243, 175, 175, 201, 140, 222,
+ 222, 221, 221, 221, 221, 221, 220, 220,
+ 220, 220, 220, 219, 219, 55, 54, 54,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 243, 243, 175, 175, 201, 201, 201, 140,
+ 140, 221, 221, 221, 221, 221, 220, 220,
+ 220, 220, 220, 219, 219, 54, 54, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 175, 175, 201, 201, 201, 201, 201, 140,
+ 139, 139, 139, 221, 221, 221, 220, 220,
+ 220, 220, 219, 219, 55, 54, 53, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 191, 201, 201, 201, 201, 201, 201, 139,
+ 139, 139, 139, 38, 14, 14, 14, 14,
+ 14, 14, 14, 55, 55, 53, 53, 53,
+ 53, 53, 53, 53, 53, 52, 52, 52,
+ 191, 191, 201, 201, 201, 201, 201, 139,
+ 139, 139, 38, 38, 14, 14, 14, 14,
+ 14, 14, 14, 88, 53, 53, 53, 53,
+ 53, 52, 52, 52, 52, 52, 52, 52,
+ 191, 191, 191, 201, 201, 201, 201, 139,
+ 139, 139, 38, 38, 14, 14, 14, 14,
+ 14, 14, 88, 88, 72, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52,
+ 191, 191, 191, 191, 201, 201, 155, 155,
+ 155, 138, 38, 37, 14, 14, 14, 14,
+ 14, 88, 88, 88, 72, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52,
+ 191, 191, 191, 191, 201, 155, 155, 155,
+ 138, 138, 37, 37, 37, 14, 14, 14,
+ 88, 88, 88, 88, 72, 71, 52, 52,
+ 52, 52, 52, 52, 52, 52, 51, 51,
+ 191, 191, 191, 191, 191, 155, 155, 154,
+ 154, 154, 37, 37, 36, 36, 89, 88,
+ 88, 88, 87, 87, 71, 71, 52, 52,
+ 52, 52, 52, 51, 51, 51, 51, 51,
+ 191, 191, 191, 191, 191, 155, 154, 154,
+ 154, 154, 121, 36, 36, 36, 88, 88,
+ 88, 87, 87, 87, 71, 71, 71, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51,
+ 191, 191, 191, 191, 191, 154, 154, 154,
+ 121, 121, 121, 121, 36, 35, 88, 88,
+ 87, 87, 87, 87, 86, 71, 71, 69,
+ 51, 51, 51, 51, 51, 51, 51, 50,
+ 191, 190, 190, 190, 190, 190, 154, 121,
+ 121, 121, 120, 120, 120, 120, 88, 87,
+ 87, 87, 87, 86, 86, 71, 69, 69,
+ 69, 69, 51, 51, 51, 50, 50, 50,
+ 190, 190, 190, 190, 190, 190, 121, 121,
+ 121, 120, 120, 120, 120, 120, 119, 87,
+ 87, 87, 86, 86, 86, 69, 69, 69,
+ 69, 69, 68, 50, 50, 50, 50, 50,
+ 190, 190, 190, 190, 190, 190, 121, 120,
+ 120, 120, 120, 120, 120, 119, 119, 87,
+ 87, 86, 86, 86, 86, 69, 69, 69,
+ 69, 68, 68, 68, 68, 50, 50, 50,
+ 3, 190, 190, 190, 190, 190, 120, 120,
+ 120, 120, 120, 119, 119, 119, 119, 118,
+ 87, 86, 86, 86, 86, 69, 69, 69,
+ 68, 68, 68, 68, 68, 68, 50, 50,
+ 3, 3, 190, 190, 190, 190, 104, 120,
+ 120, 120, 119, 119, 119, 119, 118, 118,
+ 118, 86, 86, 86, 85, 69, 69, 68,
+ 68, 68, 68, 68, 68, 68, 67, 67,
+ 3, 3, 189, 189, 189, 102, 104, 104,
+ 103, 119, 119, 119, 118, 118, 118, 118,
+ 118, 86, 86, 85, 85, 69, 68, 68,
+ 68, 68, 68, 68, 67, 67, 67, 67,
+ 3, 189, 189, 189, 102, 102, 102, 102,
+ 101, 101, 101, 101, 118, 118, 118, 118,
+ 117, 117, 85, 85, 85, 68, 68, 68,
+ 68, 68, 67, 67, 67, 67, 67, 67,
+ 3, 189, 189, 102, 102, 102, 102, 101,
+ 101, 101, 101, 100, 100, 100, 100, 100,
+ 99, 99, 117, 85, 85, 68, 68, 68,
+ 67, 67, 67, 67, 67, 67, 67, 67,
+ 189, 189, 102, 102, 102, 102, 102, 101,
+ 101, 101, 101, 100, 100, 100, 100, 99,
+ 99, 99, 99, 99, 84, 68, 67, 67,
+ 67, 67, 67, 67, 67, 67, 66, 66,
+ 189, 102, 102, 102, 102, 102, 102, 101,
+ 101, 101, 101, 100, 100, 100, 100, 99,
+ 99, 99, 99, 99, 99, 67, 67, 67,
+ 67, 67, 67, 67, 66, 205, 205, 205,
+ 102, 102, 102, 102, 102, 102, 101, 101,
+ 101, 101, 100, 100, 100, 100, 100, 99,
+ 99, 99, 99, 99, 98, 97, 67, 67,
+ 67, 67, 205, 205, 205, 205, 205, 205,
+ 102, 102, 102, 102, 102, 102, 101, 101,
+ 101, 101, 100, 100, 100, 100, 99, 99,
+ 99, 99, 99, 98, 98, 97, 97, 206,
+ 205, 205, 205, 205, 205, 205, 205, 205,
+ 102, 102, 102, 102, 102, 101, 101, 101,
+ 101, 101, 100, 100, 100, 100, 99, 99,
+ 99, 98, 98, 98, 98, 97, 97, 205,
+ 205, 205, 205, 205, 205, 205, 205, 205,
+ 102, 102, 102, 102, 102, 101, 101, 101,
+ 101, 101, 100, 100, 100, 100, 99, 98,
+ 98, 98, 98, 98, 98, 97, 97, 205,
+ 205, 205, 205, 205, 205, 205, 205, 204,
+ 102, 102, 102, 102, 102, 101, 101, 101,
+ 101, 100, 100, 100, 100, 99, 98, 98,
+ 98, 98, 98, 98, 97, 97, 205, 205,
+ 205, 205, 205, 205, 205, 205, 204, 204,
+ 102, 102, 102, 102, 101, 101, 101, 101,
+ 101, 100, 100, 100, 100, 98, 98, 98,
+ 98, 98, 98, 98, 97, 97, 205, 205,
+ 205, 205, 205, 205, 205, 204, 204, 204,
+ 102, 102, 102, 102, 101, 101, 101, 101,
+ 101, 100, 100, 100, 98, 98, 98, 98,
+ 98, 98, 98, 98, 97, 97, 205, 205,
+ 205, 205, 205, 205, 204, 204, 204, 204,
+ 242, 242, 242, 242, 242, 242, 222, 222,
+ 222, 221, 221, 221, 221, 221, 220, 220,
+ 5, 5, 5, 5, 5, 5, 5, 218,
+ 218, 218, 218, 53, 53, 53, 53, 53,
+ 242, 242, 242, 242, 242, 175, 222, 222,
+ 222, 221, 221, 221, 221, 220, 220, 220,
+ 220, 5, 5, 5, 5, 219, 219, 218,
+ 218, 218, 53, 53, 53, 53, 53, 53,
+ 242, 242, 242, 242, 175, 175, 175, 222,
+ 221, 221, 221, 221, 221, 220, 220, 220,
+ 220, 220, 219, 219, 219, 219, 219, 218,
+ 218, 53, 53, 53, 53, 53, 53, 53,
+ 242, 242, 242, 175, 175, 175, 175, 222,
+ 221, 221, 221, 221, 221, 220, 220, 220,
+ 220, 220, 219, 219, 219, 219, 218, 218,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 242, 175, 175, 175, 175, 175, 201, 201,
+ 221, 221, 221, 221, 221, 220, 220, 220,
+ 220, 220, 219, 219, 219, 219, 218, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 175, 175, 175, 175, 175, 201, 201, 201,
+ 201, 221, 221, 221, 221, 220, 220, 220,
+ 220, 220, 219, 219, 219, 219, 53, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53,
+ 175, 175, 175, 201, 201, 201, 201, 201,
+ 201, 139, 139, 221, 221, 220, 220, 220,
+ 220, 219, 219, 219, 219, 219, 53, 53,
+ 53, 53, 53, 53, 53, 52, 52, 52,
+ 175, 201, 201, 201, 201, 201, 201, 201,
+ 139, 139, 139, 38, 14, 14, 14, 14,
+ 14, 14, 219, 219, 219, 53, 53, 53,
+ 53, 52, 52, 52, 52, 52, 52, 52,
+ 191, 191, 201, 201, 201, 201, 201, 201,
+ 139, 138, 138, 14, 14, 14, 14, 14,
+ 14, 14, 14, 13, 53, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52,
+ 191, 191, 191, 201, 201, 201, 201, 201,
+ 138, 138, 138, 14, 14, 14, 14, 14,
+ 14, 14, 88, 13, 13, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52,
+ 191, 191, 191, 201, 201, 201, 201, 138,
+ 138, 138, 138, 37, 14, 14, 14, 14,
+ 14, 88, 88, 13, 13, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 51, 51,
+ 191, 191, 191, 191, 201, 201, 155, 138,
+ 138, 138, 138, 37, 14, 14, 14, 14,
+ 88, 88, 13, 87, 87, 52, 52, 52,
+ 52, 52, 52, 51, 51, 51, 51, 51,
+ 191, 191, 191, 191, 191, 155, 154, 154,
+ 154, 154, 137, 36, 36, 36, 35, 88,
+ 88, 88, 87, 87, 87, 86, 52, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51,
+ 191, 191, 191, 191, 191, 154, 154, 154,
+ 154, 154, 153, 36, 36, 35, 35, 88,
+ 88, 87, 87, 87, 86, 86, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 50,
+ 191, 190, 190, 190, 190, 154, 154, 154,
+ 154, 153, 153, 120, 35, 35, 35, 34,
+ 87, 87, 87, 86, 86, 86, 69, 51,
+ 51, 51, 51, 51, 51, 50, 50, 50,
+ 190, 190, 190, 190, 190, 190, 154, 153,
+ 153, 120, 120, 120, 120, 35, 34, 87,
+ 87, 87, 86, 86, 86, 86, 69, 69,
+ 69, 51, 51, 50, 50, 50, 50, 50,
+ 190, 190, 190, 190, 190, 190, 153, 153,
+ 120, 120, 120, 120, 120, 119, 34, 87,
+ 87, 86, 86, 86, 86, 85, 69, 69,
+ 69, 68, 50, 50, 50, 50, 50, 50,
+ 3, 190, 190, 190, 190, 190, 120, 120,
+ 120, 120, 120, 119, 119, 119, 119, 87,
+ 87, 86, 86, 86, 85, 85, 69, 69,
+ 68, 68, 68, 68, 50, 50, 50, 50,
+ 3, 3, 190, 190, 190, 190, 120, 120,
+ 120, 120, 119, 119, 119, 119, 118, 118,
+ 86, 86, 86, 85, 85, 85, 69, 68,
+ 68, 68, 68, 68, 68, 67, 49, 49,
+ 3, 3, 189, 189, 189, 189, 120, 120,
+ 120, 119, 119, 119, 119, 118, 118, 118,
+ 118, 86, 85, 85, 85, 85, 68, 68,
+ 68, 68, 68, 67, 67, 67, 67, 49,
+ 3, 189, 189, 189, 189, 189, 102, 120,
+ 119, 119, 119, 119, 118, 118, 118, 118,
+ 117, 117, 85, 85, 85, 85, 68, 68,
+ 68, 67, 67, 67, 67, 67, 67, 67,
+ 3, 189, 189, 189, 189, 102, 102, 101,
+ 101, 101, 118, 118, 118, 118, 118, 118,
+ 117, 117, 85, 85, 85, 84, 68, 67,
+ 67, 67, 67, 67, 67, 67, 67, 66,
+ 189, 189, 189, 189, 102, 102, 101, 101,
+ 101, 101, 100, 100, 100, 100, 100, 117,
+ 117, 117, 116, 84, 84, 84, 67, 67,
+ 67, 67, 67, 67, 67, 66, 66, 66,
+ 189, 189, 189, 102, 102, 102, 101, 101,
+ 101, 101, 100, 100, 100, 100, 99, 99,
+ 99, 99, 99, 116, 84, 67, 67, 67,
+ 67, 67, 67, 67, 66, 66, 66, 66,
+ 188, 188, 102, 102, 102, 102, 101, 101,
+ 101, 101, 100, 100, 100, 100, 99, 99,
+ 99, 99, 99, 99, 99, 67, 67, 67,
+ 67, 67, 66, 66, 66, 66, 66, 204,
+ 188, 188, 102, 102, 102, 101, 101, 101,
+ 101, 100, 100, 100, 100, 100, 99, 99,
+ 99, 99, 99, 98, 97, 97, 67, 67,
+ 66, 66, 66, 204, 204, 204, 204, 204,
+ 188, 102, 102, 102, 102, 101, 101, 101,
+ 101, 100, 100, 100, 100, 99, 99, 99,
+ 99, 99, 98, 98, 97, 97, 97, 66,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 102, 102, 102, 102, 101, 101, 101, 101,
+ 101, 100, 100, 100, 100, 99, 99, 99,
+ 98, 98, 98, 98, 97, 97, 97, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 102, 102, 102, 102, 101, 101, 101, 101,
+ 101, 100, 100, 100, 100, 99, 98, 98,
+ 98, 98, 98, 98, 97, 97, 97, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 102, 102, 102, 102, 101, 101, 101, 101,
+ 100, 100, 100, 100, 99, 98, 98, 98,
+ 98, 98, 98, 97, 97, 97, 97, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 102, 102, 102, 101, 101, 101, 101, 101,
+ 100, 100, 100, 100, 98, 98, 98, 98,
+ 98, 98, 98, 97, 97, 97, 97, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 102, 102, 102, 101, 101, 101, 101, 101,
+ 100, 100, 100, 98, 98, 98, 98, 98,
+ 98, 98, 98, 97, 97, 97, 97, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 242, 242, 241, 241, 241, 241, 175, 222,
+ 221, 221, 221, 221, 221, 220, 220, 5,
+ 5, 5, 5, 5, 5, 5, 218, 218,
+ 218, 218, 217, 217, 217, 53, 53, 53,
+ 242, 241, 241, 241, 175, 175, 175, 222,
+ 221, 221, 221, 221, 220, 220, 220, 220,
+ 5, 5, 5, 5, 219, 219, 218, 218,
+ 218, 218, 217, 217, 53, 53, 53, 53,
+ 241, 241, 241, 175, 175, 175, 175, 175,
+ 221, 221, 221, 221, 220, 220, 220, 220,
+ 220, 219, 219, 219, 219, 219, 218, 218,
+ 218, 218, 53, 53, 53, 53, 53, 53,
+ 241, 241, 175, 175, 175, 175, 175, 175,
+ 221, 221, 221, 221, 220, 220, 220, 220,
+ 220, 219, 219, 219, 219, 218, 218, 218,
+ 218, 53, 53, 53, 53, 53, 53, 53,
+ 175, 175, 175, 175, 175, 175, 175, 201,
+ 221, 221, 221, 221, 220, 220, 220, 220,
+ 220, 219, 219, 219, 219, 218, 218, 218,
+ 218, 53, 53, 53, 53, 53, 53, 53,
+ 175, 175, 175, 175, 175, 175, 201, 201,
+ 201, 221, 221, 221, 220, 220, 220, 220,
+ 220, 219, 219, 219, 219, 218, 218, 218,
+ 53, 53, 53, 53, 53, 52, 52, 52,
+ 175, 175, 175, 175, 201, 201, 201, 201,
+ 201, 201, 139, 221, 220, 220, 220, 220,
+ 219, 219, 219, 219, 219, 218, 218, 53,
+ 53, 52, 52, 52, 52, 52, 52, 52,
+ 175, 175, 201, 201, 201, 201, 201, 201,
+ 201, 138, 138, 14, 14, 14, 14, 14,
+ 14, 219, 219, 219, 219, 218, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52,
+ 191, 191, 201, 201, 201, 201, 201, 201,
+ 201, 138, 138, 14, 14, 14, 14, 14,
+ 14, 14, 13, 13, 13, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52,
+ 191, 191, 201, 201, 201, 201, 201, 201,
+ 138, 138, 138, 14, 14, 14, 14, 14,
+ 14, 14, 13, 13, 13, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 51, 51,
+ 191, 191, 191, 201, 201, 201, 201, 138,
+ 138, 138, 138, 137, 14, 14, 14, 14,
+ 14, 13, 13, 13, 13, 52, 52, 52,
+ 52, 52, 52, 51, 51, 51, 51, 51,
+ 191, 191, 191, 191, 201, 200, 200, 138,
+ 138, 137, 137, 137, 14, 14, 14, 14,
+ 13, 13, 13, 13, 13, 13, 52, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51,
+ 191, 191, 191, 191, 191, 200, 154, 154,
+ 154, 137, 137, 137, 36, 35, 35, 13,
+ 13, 13, 13, 13, 86, 86, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 50,
+ 191, 190, 190, 190, 190, 200, 154, 154,
+ 153, 153, 153, 153, 35, 35, 35, 34,
+ 13, 13, 13, 86, 86, 86, 51, 51,
+ 51, 51, 51, 51, 51, 50, 50, 50,
+ 190, 190, 190, 190, 190, 190, 154, 153,
+ 153, 153, 153, 153, 35, 35, 34, 34,
+ 13, 87, 86, 86, 86, 86, 85, 51,
+ 51, 51, 51, 50, 50, 50, 50, 50,
+ 190, 190, 190, 190, 190, 190, 153, 153,
+ 153, 153, 153, 120, 120, 34, 34, 33,
+ 87, 86, 86, 86, 86, 85, 85, 69,
+ 51, 51, 50, 50, 50, 50, 50, 50,
+ 3, 190, 190, 190, 190, 190, 153, 153,
+ 153, 120, 120, 119, 119, 119, 33, 33,
+ 33, 86, 86, 86, 85, 85, 85, 69,
+ 68, 50, 50, 50, 50, 50, 50, 50,
+ 3, 3, 190, 190, 190, 190, 153, 153,
+ 120, 120, 119, 119, 119, 119, 119, 33,
+ 86, 86, 86, 85, 85, 85, 85, 68,
+ 68, 68, 68, 50, 50, 50, 49, 49,
+ 3, 3, 189, 189, 189, 189, 189, 120,
+ 120, 119, 119, 119, 119, 118, 118, 118,
+ 86, 86, 85, 85, 85, 85, 85, 68,
+ 68, 67, 67, 67, 67, 49, 49, 49,
+ 3, 189, 189, 189, 189, 189, 189, 120,
+ 119, 119, 119, 119, 118, 118, 118, 118,
+ 117, 85, 85, 85, 85, 85, 84, 67,
+ 67, 67, 67, 67, 67, 67, 49, 49,
+ 3, 189, 189, 189, 189, 189, 189, 119,
+ 119, 119, 119, 118, 118, 118, 118, 117,
+ 117, 117, 85, 85, 85, 84, 84, 67,
+ 67, 67, 67, 67, 67, 67, 66, 66,
+ 189, 189, 189, 189, 189, 189, 189, 101,
+ 101, 118, 118, 118, 118, 118, 118, 117,
+ 117, 117, 116, 84, 84, 84, 67, 67,
+ 67, 67, 67, 67, 67, 66, 66, 66,
+ 189, 189, 189, 189, 189, 189, 101, 101,
+ 101, 100, 100, 100, 100, 118, 117, 117,
+ 117, 116, 116, 116, 84, 84, 67, 67,
+ 67, 67, 67, 66, 66, 66, 66, 66,
+ 188, 188, 188, 188, 188, 101, 101, 101,
+ 101, 100, 100, 100, 100, 99, 99, 99,
+ 99, 116, 116, 116, 84, 84, 67, 67,
+ 67, 66, 66, 66, 66, 66, 66, 66,
+ 188, 188, 188, 188, 102, 101, 101, 101,
+ 101, 100, 100, 100, 100, 99, 99, 99,
+ 99, 99, 99, 99, 115, 83, 67, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 188, 188, 188, 188, 101, 101, 101, 101,
+ 100, 100, 100, 100, 100, 99, 99, 99,
+ 99, 99, 98, 97, 97, 97, 66, 66,
+ 66, 66, 66, 66, 66, 204, 204, 204,
+ 188, 188, 188, 102, 101, 101, 101, 101,
+ 100, 100, 100, 100, 99, 99, 99, 99,
+ 99, 98, 98, 97, 97, 97, 97, 66,
+ 66, 204, 204, 204, 204, 204, 204, 204,
+ 188, 188, 102, 101, 101, 101, 101, 101,
+ 100, 100, 100, 100, 99, 99, 99, 98,
+ 98, 98, 98, 97, 97, 97, 97, 96,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 187, 187, 102, 101, 101, 101, 101, 101,
+ 100, 100, 100, 100, 99, 98, 98, 98,
+ 98, 98, 98, 97, 97, 97, 97, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 187, 102, 102, 101, 101, 101, 101, 100,
+ 100, 100, 100, 99, 98, 98, 98, 98,
+ 98, 98, 97, 97, 97, 97, 97, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 187, 102, 101, 101, 101, 101, 101, 100,
+ 100, 100, 100, 98, 98, 98, 98, 98,
+ 98, 98, 97, 97, 97, 97, 96, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 187, 102, 101, 101, 101, 101, 101, 100,
+ 100, 100, 98, 98, 98, 98, 98, 98,
+ 98, 98, 97, 97, 97, 97, 96, 204,
+ 204, 204, 204, 204, 204, 204, 204, 203,
+ 241, 241, 241, 241, 241, 175, 175, 175,
+ 221, 221, 221, 221, 220, 220, 5, 5,
+ 5, 5, 5, 5, 5, 218, 218, 218,
+ 218, 217, 217, 217, 217, 217, 216, 216,
+ 241, 241, 241, 241, 175, 175, 175, 175,
+ 221, 221, 221, 220, 220, 220, 220, 5,
+ 5, 5, 5, 219, 219, 218, 218, 218,
+ 218, 217, 217, 217, 217, 217, 53, 53,
+ 241, 241, 175, 175, 175, 175, 175, 175,
+ 221, 221, 221, 220, 220, 220, 220, 220,
+ 219, 219, 219, 219, 219, 218, 218, 218,
+ 218, 217, 217, 217, 217, 53, 53, 53,
+ 241, 175, 175, 175, 175, 175, 175, 175,
+ 221, 221, 221, 220, 220, 220, 220, 220,
+ 219, 219, 219, 219, 218, 218, 218, 218,
+ 218, 217, 217, 217, 53, 53, 53, 53,
+ 175, 175, 175, 175, 175, 175, 175, 175,
+ 201, 221, 221, 220, 220, 220, 220, 220,
+ 219, 219, 219, 219, 218, 218, 218, 218,
+ 218, 217, 53, 53, 53, 52, 52, 52,
+ 175, 175, 175, 175, 175, 175, 175, 201,
+ 201, 201, 221, 220, 220, 220, 220, 220,
+ 219, 219, 219, 219, 218, 218, 218, 218,
+ 218, 52, 52, 52, 52, 52, 52, 52,
+ 175, 175, 175, 175, 175, 201, 201, 201,
+ 201, 201, 138, 220, 220, 220, 220, 219,
+ 219, 219, 219, 219, 218, 218, 218, 218,
+ 52, 52, 52, 52, 52, 52, 52, 52,
+ 175, 175, 175, 201, 201, 201, 201, 201,
+ 201, 201, 138, 138, 14, 14, 14, 14,
+ 219, 219, 219, 219, 218, 218, 218, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52,
+ 191, 201, 201, 201, 201, 201, 201, 201,
+ 200, 138, 138, 138, 14, 14, 14, 14,
+ 14, 13, 13, 13, 218, 218, 52, 52,
+ 52, 52, 52, 52, 52, 52, 51, 51,
+ 191, 191, 201, 201, 201, 201, 200, 200,
+ 200, 138, 137, 137, 14, 14, 14, 14,
+ 14, 13, 13, 13, 13, 13, 52, 52,
+ 52, 52, 52, 51, 51, 51, 51, 51,
+ 191, 191, 191, 201, 201, 200, 200, 200,
+ 200, 137, 137, 137, 14, 14, 14, 14,
+ 13, 13, 13, 13, 13, 13, 52, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51,
+ 191, 191, 191, 191, 200, 200, 200, 200,
+ 137, 137, 137, 137, 14, 14, 14, 13,
+ 13, 13, 13, 13, 13, 13, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 50,
+ 191, 190, 190, 190, 200, 200, 200, 200,
+ 137, 137, 137, 137, 136, 35, 13, 13,
+ 13, 13, 13, 13, 13, 86, 51, 51,
+ 51, 51, 51, 51, 51, 50, 50, 50,
+ 190, 190, 190, 190, 190, 200, 200, 153,
+ 153, 153, 153, 136, 136, 35, 34, 13,
+ 13, 13, 13, 13, 86, 86, 85, 51,
+ 51, 51, 51, 50, 50, 50, 50, 50,
+ 190, 190, 190, 190, 190, 190, 153, 153,
+ 153, 153, 153, 136, 136, 34, 34, 13,
+ 13, 13, 86, 86, 86, 85, 85, 51,
+ 51, 51, 50, 50, 50, 50, 50, 50,
+ 3, 190, 190, 190, 190, 190, 153, 153,
+ 153, 153, 152, 152, 152, 34, 33, 33,
+ 33, 86, 86, 86, 85, 85, 85, 85,
+ 50, 50, 50, 50, 50, 50, 50, 50,
+ 3, 3, 190, 190, 190, 190, 153, 153,
+ 152, 152, 152, 152, 119, 119, 33, 33,
+ 32, 86, 86, 85, 85, 85, 85, 85,
+ 50, 50, 50, 50, 50, 50, 49, 49,
+ 3, 3, 189, 189, 189, 189, 189, 152,
+ 152, 152, 119, 119, 119, 119, 118, 32,
+ 32, 86, 85, 85, 85, 85, 85, 84,
+ 67, 67, 49, 49, 49, 49, 49, 49,
+ 3, 189, 189, 189, 189, 189, 189, 152,
+ 152, 119, 119, 119, 118, 118, 118, 118,
+ 32, 31, 85, 85, 85, 85, 84, 84,
+ 67, 67, 67, 67, 49, 49, 49, 49,
+ 3, 189, 189, 189, 189, 189, 189, 152,
+ 119, 119, 119, 118, 118, 118, 118, 117,
+ 117, 117, 85, 85, 85, 84, 84, 67,
+ 67, 67, 67, 67, 67, 49, 49, 49,
+ 189, 189, 189, 189, 189, 189, 189, 119,
+ 119, 119, 118, 118, 118, 118, 117, 117,
+ 117, 117, 85, 84, 84, 84, 84, 67,
+ 67, 67, 67, 67, 66, 66, 66, 48,
+ 189, 189, 189, 189, 189, 189, 189, 119,
+ 118, 118, 118, 118, 118, 118, 117, 117,
+ 117, 116, 116, 84, 84, 84, 84, 67,
+ 67, 67, 66, 66, 66, 66, 66, 66,
+ 188, 188, 188, 188, 188, 188, 188, 101,
+ 100, 100, 100, 118, 118, 117, 117, 117,
+ 116, 116, 116, 116, 84, 84, 83, 67,
+ 66, 66, 66, 66, 66, 66, 66, 66,
+ 188, 188, 188, 188, 188, 188, 101, 101,
+ 100, 100, 100, 100, 99, 99, 99, 99,
+ 116, 116, 116, 116, 115, 83, 83, 66,
+ 66, 66, 66, 66, 66, 66, 66, 65,
+ 188, 188, 188, 188, 188, 101, 101, 101,
+ 100, 100, 100, 100, 99, 99, 99, 99,
+ 99, 99, 116, 115, 115, 83, 83, 66,
+ 66, 66, 66, 66, 66, 65, 65, 65,
+ 188, 188, 188, 188, 188, 101, 101, 100,
+ 100, 100, 100, 100, 99, 99, 99, 99,
+ 99, 98, 97, 97, 97, 97, 83, 66,
+ 66, 66, 66, 65, 65, 65, 65, 203,
+ 188, 188, 188, 188, 101, 101, 101, 100,
+ 100, 100, 100, 99, 99, 99, 99, 99,
+ 98, 98, 97, 97, 97, 97, 96, 66,
+ 65, 65, 65, 204, 204, 204, 203, 203,
+ 187, 187, 187, 187, 101, 101, 101, 100,
+ 100, 100, 100, 99, 99, 99, 98, 98,
+ 98, 98, 97, 97, 97, 97, 96, 96,
+ 204, 204, 204, 204, 204, 203, 203, 203,
+ 187, 187, 187, 101, 101, 101, 101, 100,
+ 100, 100, 100, 99, 98, 98, 98, 98,
+ 98, 98, 97, 97, 97, 97, 96, 96,
+ 204, 204, 204, 204, 203, 203, 203, 203,
+ 187, 187, 187, 101, 101, 101, 100, 100,
+ 100, 100, 99, 98, 98, 98, 98, 98,
+ 98, 97, 97, 97, 97, 97, 96, 96,
+ 204, 204, 204, 203, 203, 203, 203, 203,
+ 187, 187, 187, 101, 101, 101, 100, 100,
+ 100, 100, 98, 98, 98, 98, 98, 98,
+ 98, 97, 97, 97, 97, 96, 96, 96,
+ 204, 204, 203, 203, 203, 203, 203, 203,
+ 187, 187, 101, 101, 101, 101, 100, 100,
+ 100, 98, 98, 98, 98, 98, 98, 98,
+ 98, 97, 97, 97, 97, 96, 96, 96,
+ 204, 203, 203, 203, 203, 203, 203, 203,
+ 1, 240, 240, 240, 240, 175, 175, 175,
+ 221, 221, 221, 220, 220, 5, 5, 5,
+ 5, 5, 5, 5, 218, 218, 218, 218,
+ 217, 217, 217, 217, 217, 216, 216, 216,
+ 240, 240, 240, 175, 175, 175, 175, 175,
+ 221, 221, 220, 220, 220, 220, 5, 5,
+ 5, 5, 219, 219, 218, 218, 218, 218,
+ 217, 217, 217, 217, 217, 216, 216, 216,
+ 240, 240, 175, 175, 175, 175, 175, 175,
+ 175, 221, 220, 220, 220, 220, 220, 219,
+ 219, 219, 219, 219, 218, 218, 218, 218,
+ 217, 217, 217, 217, 217, 216, 216, 216,
+ 240, 175, 175, 175, 175, 175, 175, 175,
+ 175, 221, 220, 220, 220, 220, 220, 219,
+ 219, 219, 219, 218, 218, 218, 218, 218,
+ 217, 217, 217, 217, 217, 216, 216, 52,
+ 175, 175, 175, 175, 175, 175, 175, 175,
+ 175, 221, 220, 220, 220, 220, 220, 219,
+ 219, 219, 219, 218, 218, 218, 218, 218,
+ 217, 217, 217, 217, 217, 52, 52, 52,
+ 175, 175, 175, 175, 175, 175, 175, 174,
+ 201, 201, 220, 220, 220, 220, 220, 219,
+ 219, 219, 219, 218, 218, 218, 218, 218,
+ 217, 217, 217, 52, 52, 52, 52, 52,
+ 175, 175, 175, 174, 174, 174, 201, 201,
+ 201, 200, 200, 220, 220, 220, 219, 219,
+ 219, 219, 219, 218, 218, 218, 218, 218,
+ 217, 217, 52, 52, 52, 52, 52, 52,
+ 174, 174, 174, 174, 174, 201, 201, 200,
+ 200, 200, 200, 138, 14, 14, 14, 219,
+ 219, 219, 219, 218, 218, 218, 218, 218,
+ 52, 52, 52, 52, 52, 52, 51, 51,
+ 174, 174, 174, 201, 201, 200, 200, 200,
+ 200, 200, 200, 137, 14, 14, 14, 14,
+ 13, 13, 13, 218, 218, 218, 218, 52,
+ 52, 52, 52, 51, 51, 51, 51, 51,
+ 191, 191, 201, 201, 200, 200, 200, 200,
+ 200, 200, 137, 137, 14, 14, 14, 14,
+ 13, 13, 13, 13, 13, 13, 52, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51,
+ 191, 191, 191, 200, 200, 200, 200, 200,
+ 200, 200, 137, 137, 136, 14, 14, 13,
+ 13, 13, 13, 13, 13, 13, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 50,
+ 191, 190, 190, 200, 200, 200, 200, 200,
+ 200, 137, 137, 136, 136, 136, 13, 13,
+ 13, 13, 13, 13, 13, 13, 51, 51,
+ 51, 51, 51, 51, 51, 50, 50, 50,
+ 190, 190, 190, 190, 200, 200, 200, 200,
+ 137, 137, 136, 136, 136, 136, 13, 13,
+ 13, 13, 13, 13, 13, 12, 12, 51,
+ 51, 51, 51, 50, 50, 50, 50, 50,
+ 190, 190, 190, 190, 190, 200, 200, 200,
+ 153, 136, 136, 136, 136, 34, 13, 13,
+ 13, 13, 13, 13, 12, 12, 12, 51,
+ 51, 51, 50, 50, 50, 50, 50, 50,
+ 3, 190, 190, 190, 190, 190, 200, 153,
+ 153, 152, 136, 136, 136, 34, 33, 13,
+ 13, 13, 13, 12, 12, 12, 85, 51,
+ 50, 50, 50, 50, 50, 50, 50, 50,
+ 3, 3, 190, 190, 190, 190, 153, 152,
+ 152, 152, 152, 152, 152, 33, 33, 33,
+ 32, 32, 32, 12, 85, 85, 85, 85,
+ 50, 50, 50, 50, 50, 50, 49, 49,
+ 3, 3, 189, 189, 189, 189, 152, 152,
+ 152, 152, 152, 152, 151, 33, 33, 32,
+ 32, 32, 31, 85, 85, 85, 85, 84,
+ 50, 50, 49, 49, 49, 49, 49, 49,
+ 3, 189, 189, 189, 189, 189, 189, 152,
+ 152, 152, 152, 151, 119, 118, 118, 32,
+ 32, 31, 85, 85, 85, 85, 84, 84,
+ 67, 49, 49, 49, 49, 49, 49, 49,
+ 3, 189, 189, 189, 189, 189, 189, 152,
+ 152, 152, 151, 119, 118, 118, 118, 117,
+ 31, 31, 85, 85, 84, 84, 84, 84,
+ 67, 67, 67, 49, 49, 49, 49, 49,
+ 189, 189, 189, 189, 189, 189, 189, 152,
+ 152, 151, 118, 118, 118, 118, 117, 117,
+ 117, 117, 85, 84, 84, 84, 84, 84,
+ 67, 67, 67, 66, 49, 49, 48, 48,
+ 189, 189, 189, 189, 189, 189, 189, 152,
+ 151, 118, 118, 118, 118, 118, 117, 117,
+ 117, 116, 116, 84, 84, 84, 84, 83,
+ 67, 66, 66, 66, 66, 66, 48, 48,
+ 188, 188, 188, 188, 188, 188, 188, 188,
+ 118, 118, 118, 118, 118, 117, 117, 117,
+ 116, 116, 116, 84, 84, 84, 83, 83,
+ 66, 66, 66, 66, 66, 66, 66, 48,
+ 188, 188, 188, 188, 188, 188, 188, 188,
+ 118, 118, 118, 118, 117, 117, 117, 116,
+ 116, 116, 116, 115, 83, 83, 83, 83,
+ 66, 66, 66, 66, 66, 66, 65, 65,
+ 188, 188, 188, 188, 188, 188, 188, 100,
+ 100, 100, 100, 99, 99, 99, 117, 116,
+ 116, 116, 116, 115, 115, 83, 83, 66,
+ 66, 66, 66, 66, 65, 65, 65, 65,
+ 188, 188, 188, 188, 188, 188, 188, 100,
+ 100, 100, 100, 99, 99, 99, 99, 99,
+ 99, 116, 115, 115, 115, 83, 83, 66,
+ 66, 66, 65, 65, 65, 65, 65, 65,
+ 188, 188, 188, 188, 188, 188, 100, 100,
+ 100, 100, 100, 99, 99, 99, 99, 99,
+ 98, 97, 97, 97, 97, 97, 83, 66,
+ 65, 65, 65, 65, 65, 65, 65, 65,
+ 187, 187, 187, 187, 187, 187, 100, 100,
+ 100, 100, 99, 99, 99, 99, 99, 98,
+ 98, 97, 97, 97, 97, 96, 96, 96,
+ 65, 65, 65, 65, 65, 203, 203, 203,
+ 187, 187, 187, 187, 187, 101, 100, 100,
+ 100, 100, 99, 99, 99, 98, 98, 98,
+ 98, 97, 97, 97, 97, 96, 96, 96,
+ 65, 65, 203, 203, 203, 203, 203, 203,
+ 187, 187, 187, 187, 187, 101, 100, 100,
+ 100, 100, 99, 98, 98, 98, 98, 98,
+ 98, 97, 97, 97, 97, 96, 96, 96,
+ 96, 203, 203, 203, 203, 203, 203, 203,
+ 187, 187, 187, 187, 187, 100, 100, 100,
+ 100, 99, 98, 98, 98, 98, 98, 98,
+ 97, 97, 97, 97, 97, 96, 96, 96,
+ 203, 203, 203, 203, 203, 203, 203, 203,
+ 187, 187, 187, 187, 101, 100, 100, 100,
+ 100, 98, 98, 98, 98, 98, 98, 98,
+ 97, 97, 97, 97, 96, 96, 96, 96,
+ 203, 203, 203, 203, 203, 203, 203, 203,
+ 186, 186, 186, 186, 101, 100, 100, 100,
+ 98, 98, 98, 98, 98, 98, 98, 98,
+ 97, 97, 97, 97, 96, 96, 96, 96,
+ 203, 203, 203, 203, 203, 203, 203, 203,
+ 1, 240, 240, 240, 240, 175, 175, 175,
+ 175, 221, 220, 220, 5, 5, 5, 5,
+ 5, 5, 5, 218, 218, 218, 218, 217,
+ 217, 217, 217, 217, 216, 216, 216, 216,
+ 240, 240, 240, 240, 175, 175, 175, 175,
+ 175, 220, 220, 220, 220, 5, 5, 5,
+ 5, 219, 219, 218, 218, 218, 218, 217,
+ 217, 217, 217, 217, 216, 216, 216, 216,
+ 240, 240, 175, 175, 175, 175, 175, 175,
+ 175, 220, 220, 220, 220, 220, 219, 219,
+ 219, 219, 219, 218, 218, 218, 218, 217,
+ 217, 217, 217, 217, 216, 216, 216, 216,
+ 240, 175, 175, 175, 175, 175, 175, 175,
+ 175, 220, 220, 220, 220, 220, 219, 219,
+ 219, 219, 218, 218, 218, 218, 218, 217,
+ 217, 217, 217, 217, 216, 216, 216, 216,
+ 175, 175, 175, 175, 175, 174, 174, 174,
+ 174, 220, 220, 220, 220, 220, 219, 219,
+ 219, 219, 218, 218, 218, 218, 218, 217,
+ 217, 217, 217, 217, 216, 216, 216, 216,
+ 175, 174, 174, 174, 174, 174, 174, 174,
+ 174, 200, 220, 220, 220, 220, 219, 219,
+ 219, 219, 218, 218, 218, 218, 218, 217,
+ 217, 217, 217, 216, 216, 216, 52, 52,
+ 174, 174, 174, 174, 174, 174, 174, 174,
+ 200, 200, 200, 220, 220, 219, 219, 219,
+ 219, 219, 218, 218, 218, 218, 218, 217,
+ 217, 217, 217, 216, 52, 52, 51, 51,
+ 174, 174, 174, 174, 174, 174, 200, 200,
+ 200, 200, 200, 200, 14, 219, 219, 219,
+ 219, 219, 218, 218, 218, 218, 218, 217,
+ 217, 217, 52, 51, 51, 51, 51, 51,
+ 174, 174, 174, 174, 174, 200, 200, 200,
+ 200, 200, 200, 137, 137, 14, 14, 13,
+ 13, 13, 218, 218, 218, 218, 218, 217,
+ 51, 51, 51, 51, 51, 51, 51, 51,
+ 173, 173, 173, 200, 200, 200, 200, 200,
+ 200, 200, 200, 137, 136, 14, 14, 13,
+ 13, 13, 13, 13, 13, 218, 217, 51,
+ 51, 51, 51, 51, 51, 51, 51, 50,
+ 191, 173, 200, 200, 200, 200, 200, 200,
+ 200, 200, 137, 136, 136, 136, 13, 13,
+ 13, 13, 13, 13, 13, 13, 51, 51,
+ 51, 51, 51, 51, 51, 50, 50, 50,
+ 190, 190, 190, 200, 200, 200, 200, 200,
+ 200, 199, 136, 136, 136, 136, 13, 13,
+ 13, 13, 13, 13, 13, 12, 12, 51,
+ 51, 51, 51, 50, 50, 50, 50, 50,
+ 190, 190, 190, 190, 200, 200, 200, 200,
+ 199, 136, 136, 136, 136, 136, 13, 13,
+ 13, 13, 13, 13, 12, 12, 12, 51,
+ 51, 51, 50, 50, 50, 50, 50, 50,
+ 3, 190, 190, 190, 200, 200, 199, 199,
+ 199, 136, 136, 136, 136, 136, 13, 13,
+ 13, 13, 13, 12, 12, 12, 12, 12,
+ 50, 50, 50, 50, 50, 50, 50, 50,
+ 3, 3, 190, 190, 190, 199, 199, 199,
+ 152, 152, 152, 136, 135, 135, 33, 13,
+ 13, 13, 12, 12, 12, 12, 12, 12,
+ 50, 50, 50, 50, 50, 50, 49, 49,
+ 3, 3, 189, 189, 189, 189, 199, 152,
+ 152, 152, 152, 152, 151, 151, 33, 32,
+ 32, 32, 12, 12, 12, 12, 12, 84,
+ 50, 50, 49, 49, 49, 49, 49, 49,
+ 3, 189, 189, 189, 189, 189, 152, 152,
+ 152, 152, 152, 151, 151, 151, 32, 32,
+ 32, 31, 12, 12, 12, 12, 84, 84,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 3, 189, 189, 189, 189, 189, 189, 152,
+ 152, 152, 151, 151, 151, 151, 32, 32,
+ 31, 31, 31, 12, 84, 84, 84, 84,
+ 84, 49, 49, 49, 49, 49, 49, 49,
+ 189, 189, 189, 189, 189, 189, 189, 152,
+ 152, 151, 151, 151, 151, 118, 117, 117,
+ 31, 31, 30, 30, 84, 84, 84, 84,
+ 83, 49, 49, 49, 49, 49, 48, 48,
+ 189, 189, 189, 189, 189, 189, 189, 151,
+ 151, 151, 151, 151, 118, 117, 117, 117,
+ 117, 30, 30, 84, 84, 84, 84, 83,
+ 83, 66, 66, 66, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 188, 188, 188,
+ 151, 151, 118, 118, 118, 117, 117, 117,
+ 116, 116, 116, 84, 84, 84, 83, 83,
+ 83, 66, 66, 66, 66, 48, 48, 48,
+ 188, 188, 188, 188, 188, 188, 188, 188,
+ 151, 150, 118, 118, 117, 117, 117, 116,
+ 116, 116, 116, 115, 83, 83, 83, 83,
+ 66, 66, 66, 66, 66, 65, 48, 48,
+ 188, 188, 188, 188, 188, 188, 188, 188,
+ 150, 118, 118, 117, 117, 117, 117, 116,
+ 116, 116, 115, 115, 83, 83, 83, 83,
+ 66, 66, 66, 65, 65, 65, 65, 65,
+ 188, 188, 188, 188, 188, 188, 188, 188,
+ 100, 100, 99, 99, 117, 117, 116, 116,
+ 116, 116, 115, 115, 115, 83, 83, 82,
+ 66, 65, 65, 65, 65, 65, 65, 65,
+ 188, 188, 188, 188, 188, 188, 187, 100,
+ 100, 100, 99, 99, 99, 99, 99, 116,
+ 116, 115, 115, 115, 115, 114, 83, 82,
+ 65, 65, 65, 65, 65, 65, 65, 9,
+ 187, 187, 187, 187, 187, 187, 187, 100,
+ 100, 100, 99, 99, 99, 99, 99, 98,
+ 97, 97, 97, 97, 114, 114, 114, 82,
+ 65, 65, 65, 65, 65, 65, 65, 9,
+ 187, 187, 187, 187, 187, 187, 187, 100,
+ 100, 99, 99, 99, 99, 99, 98, 98,
+ 97, 97, 97, 97, 96, 96, 96, 96,
+ 65, 65, 65, 65, 65, 64, 9, 9,
+ 187, 187, 187, 187, 187, 187, 100, 100,
+ 100, 99, 99, 99, 98, 98, 98, 98,
+ 97, 97, 97, 97, 96, 96, 96, 96,
+ 96, 65, 65, 203, 203, 203, 202, 202,
+ 187, 187, 187, 187, 187, 187, 100, 100,
+ 100, 99, 98, 98, 98, 98, 98, 98,
+ 97, 97, 97, 97, 96, 96, 96, 96,
+ 96, 203, 203, 203, 203, 202, 202, 202,
+ 187, 187, 187, 187, 186, 186, 100, 100,
+ 99, 98, 98, 98, 98, 98, 98, 97,
+ 97, 97, 97, 97, 96, 96, 96, 96,
+ 96, 203, 203, 203, 202, 202, 202, 202,
+ 186, 186, 186, 186, 186, 186, 100, 100,
+ 98, 98, 98, 98, 98, 98, 98, 97,
+ 97, 97, 97, 96, 96, 96, 96, 96,
+ 96, 203, 203, 202, 202, 202, 202, 202,
+ 186, 186, 186, 186, 186, 186, 100, 98,
+ 98, 98, 98, 98, 98, 98, 98, 97,
+ 97, 97, 97, 96, 96, 96, 96, 96,
+ 96, 203, 202, 202, 202, 202, 202, 202,
+ 239, 239, 239, 239, 239, 239, 175, 175,
+ 175, 220, 220, 5, 5, 5, 5, 5,
+ 5, 5, 218, 218, 218, 218, 217, 217,
+ 217, 217, 217, 216, 216, 216, 216, 216,
+ 239, 239, 239, 239, 175, 175, 175, 175,
+ 175, 220, 220, 220, 5, 5, 5, 5,
+ 219, 219, 218, 218, 218, 218, 217, 217,
+ 217, 217, 217, 216, 216, 216, 216, 216,
+ 239, 239, 239, 175, 175, 175, 175, 174,
+ 174, 220, 220, 220, 220, 219, 219, 219,
+ 219, 219, 218, 218, 218, 218, 217, 217,
+ 217, 217, 217, 216, 216, 216, 216, 216,
+ 239, 239, 175, 174, 174, 174, 174, 174,
+ 174, 174, 220, 220, 220, 219, 219, 219,
+ 219, 218, 218, 218, 218, 218, 217, 217,
+ 217, 217, 217, 216, 216, 216, 216, 215,
+ 174, 174, 174, 174, 174, 174, 174, 174,
+ 174, 174, 220, 220, 220, 219, 219, 219,
+ 219, 218, 218, 218, 218, 218, 217, 217,
+ 217, 217, 217, 216, 216, 216, 216, 215,
+ 174, 174, 174, 174, 174, 174, 174, 174,
+ 174, 174, 220, 220, 220, 219, 219, 219,
+ 219, 218, 218, 218, 218, 218, 217, 217,
+ 217, 217, 216, 216, 216, 216, 216, 215,
+ 174, 174, 174, 174, 174, 174, 174, 174,
+ 200, 200, 200, 220, 219, 219, 219, 219,
+ 219, 218, 218, 218, 218, 218, 217, 217,
+ 217, 217, 216, 216, 216, 216, 216, 51,
+ 174, 174, 174, 174, 174, 174, 174, 200,
+ 200, 200, 200, 200, 199, 219, 219, 219,
+ 219, 218, 218, 218, 218, 218, 217, 217,
+ 217, 217, 216, 216, 51, 51, 51, 51,
+ 173, 173, 173, 173, 173, 200, 200, 200,
+ 200, 200, 200, 199, 136, 136, 13, 13,
+ 219, 218, 218, 218, 218, 218, 217, 217,
+ 217, 217, 51, 51, 51, 51, 51, 50,
+ 173, 173, 173, 173, 173, 200, 200, 200,
+ 200, 199, 199, 199, 136, 136, 13, 13,
+ 13, 13, 13, 13, 218, 217, 217, 217,
+ 51, 51, 51, 51, 51, 50, 50, 50,
+ 173, 173, 173, 173, 200, 200, 200, 200,
+ 199, 199, 199, 136, 136, 136, 13, 13,
+ 13, 13, 13, 13, 13, 12, 12, 51,
+ 51, 51, 51, 50, 50, 50, 50, 50,
+ 190, 190, 173, 200, 200, 200, 200, 199,
+ 199, 199, 199, 136, 136, 136, 13, 13,
+ 13, 13, 13, 13, 12, 12, 12, 51,
+ 51, 51, 50, 50, 50, 50, 50, 50,
+ 3, 190, 190, 200, 200, 199, 199, 199,
+ 199, 199, 136, 136, 136, 136, 13, 13,
+ 13, 13, 13, 12, 12, 12, 12, 12,
+ 50, 50, 50, 50, 50, 50, 50, 50,
+ 3, 3, 190, 190, 199, 199, 199, 199,
+ 199, 199, 135, 135, 135, 135, 13, 13,
+ 13, 13, 12, 12, 12, 12, 12, 12,
+ 50, 50, 50, 50, 50, 50, 49, 49,
+ 3, 3, 189, 189, 189, 199, 199, 199,
+ 199, 135, 135, 135, 135, 135, 135, 13,
+ 32, 12, 12, 12, 12, 12, 12, 12,
+ 50, 50, 49, 49, 49, 49, 49, 49,
+ 3, 189, 189, 189, 189, 189, 199, 199,
+ 152, 135, 135, 135, 135, 151, 134, 32,
+ 32, 12, 12, 12, 12, 12, 12, 12,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 3, 189, 189, 189, 189, 189, 199, 152,
+ 152, 151, 151, 151, 151, 151, 134, 32,
+ 31, 31, 12, 12, 12, 12, 84, 84,
+ 11, 49, 49, 49, 49, 49, 49, 49,
+ 189, 189, 189, 189, 189, 189, 189, 152,
+ 151, 151, 151, 151, 151, 151, 150, 31,
+ 31, 31, 30, 12, 12, 84, 84, 84,
+ 11, 49, 49, 49, 49, 49, 48, 48,
+ 189, 189, 189, 189, 189, 189, 189, 151,
+ 151, 151, 151, 151, 150, 150, 117, 117,
+ 31, 30, 30, 29, 84, 84, 84, 83,
+ 83, 49, 49, 49, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 188, 188, 151,
+ 151, 151, 150, 150, 150, 150, 117, 117,
+ 116, 30, 29, 29, 84, 84, 83, 83,
+ 83, 66, 66, 48, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 188, 188, 188,
+ 150, 150, 150, 150, 150, 117, 117, 116,
+ 116, 116, 29, 29, 83, 83, 83, 83,
+ 82, 66, 66, 66, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 188, 188, 188,
+ 150, 150, 150, 150, 117, 117, 117, 116,
+ 116, 116, 115, 115, 83, 83, 83, 83,
+ 82, 66, 65, 65, 65, 65, 48, 48,
+ 188, 188, 188, 188, 188, 188, 188, 188,
+ 150, 150, 150, 117, 117, 117, 116, 116,
+ 116, 116, 115, 115, 115, 83, 83, 82,
+ 82, 65, 65, 65, 65, 65, 65, 65,
+ 188, 188, 188, 188, 188, 188, 187, 187,
+ 150, 150, 150, 117, 117, 116, 116, 116,
+ 116, 115, 115, 115, 115, 83, 82, 82,
+ 82, 65, 65, 65, 65, 65, 65, 9,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 100, 99, 99, 99, 99, 99, 116, 116,
+ 116, 115, 115, 115, 114, 114, 82, 82,
+ 65, 65, 65, 65, 65, 64, 64, 9,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 100, 99, 99, 99, 99, 99, 98, 97,
+ 97, 97, 97, 114, 114, 114, 114, 81,
+ 65, 65, 65, 64, 64, 64, 9, 9,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 99, 99, 99, 99, 99, 98, 98, 97,
+ 97, 97, 97, 96, 96, 96, 96, 96,
+ 65, 64, 64, 64, 64, 9, 9, 9,
+ 187, 187, 187, 187, 187, 187, 187, 100,
+ 99, 99, 99, 98, 98, 98, 98, 97,
+ 97, 97, 97, 96, 96, 96, 96, 96,
+ 96, 64, 64, 64, 202, 202, 202, 202,
+ 187, 187, 187, 187, 186, 186, 186, 100,
+ 99, 98, 98, 98, 98, 98, 98, 97,
+ 97, 97, 97, 96, 96, 96, 96, 96,
+ 96, 202, 202, 202, 202, 202, 202, 202,
+ 186, 186, 186, 186, 186, 186, 186, 99,
+ 98, 98, 98, 98, 98, 98, 97, 97,
+ 97, 97, 97, 96, 96, 96, 96, 96,
+ 96, 202, 202, 202, 202, 202, 202, 202,
+ 186, 186, 186, 186, 186, 186, 186, 98,
+ 98, 98, 98, 98, 98, 98, 97, 97,
+ 97, 97, 96, 96, 96, 96, 96, 96,
+ 96, 202, 202, 202, 202, 202, 202, 202,
+ 186, 186, 186, 186, 186, 186, 186, 98,
+ 98, 98, 98, 98, 98, 98, 97, 97,
+ 97, 97, 96, 96, 96, 96, 96, 96,
+ 96, 202, 202, 202, 202, 202, 202, 202,
+ 238, 238, 238, 238, 238, 238, 238, 175,
+ 175, 220, 5, 5, 5, 5, 5, 5,
+ 5, 218, 218, 218, 218, 217, 217, 217,
+ 217, 217, 216, 216, 216, 216, 216, 215,
+ 238, 238, 238, 238, 238, 238, 174, 174,
+ 174, 220, 220, 5, 5, 5, 5, 219,
+ 219, 218, 218, 218, 218, 217, 217, 217,
+ 217, 217, 216, 216, 216, 216, 216, 215,
+ 238, 238, 238, 238, 174, 174, 174, 174,
+ 174, 174, 220, 220, 219, 219, 219, 219,
+ 219, 218, 218, 218, 218, 217, 217, 217,
+ 217, 217, 216, 216, 216, 216, 216, 215,
+ 238, 238, 174, 174, 174, 174, 174, 174,
+ 174, 174, 220, 220, 219, 219, 219, 219,
+ 218, 218, 218, 218, 218, 217, 217, 217,
+ 217, 217, 216, 216, 216, 216, 215, 215,
+ 174, 174, 174, 174, 174, 174, 174, 174,
+ 174, 174, 220, 220, 219, 219, 219, 219,
+ 218, 218, 218, 218, 218, 217, 217, 217,
+ 217, 217, 216, 216, 216, 216, 215, 215,
+ 174, 174, 174, 174, 174, 174, 174, 174,
+ 174, 174, 200, 220, 219, 219, 219, 219,
+ 218, 218, 218, 218, 218, 217, 217, 217,
+ 217, 216, 216, 216, 216, 216, 215, 215,
+ 174, 174, 174, 174, 174, 174, 174, 174,
+ 174, 200, 200, 199, 219, 219, 219, 219,
+ 218, 218, 218, 218, 218, 217, 217, 217,
+ 217, 216, 216, 216, 216, 216, 215, 215,
+ 173, 173, 173, 173, 173, 173, 173, 200,
+ 200, 200, 199, 199, 199, 219, 219, 219,
+ 218, 218, 218, 218, 218, 217, 217, 217,
+ 217, 216, 216, 216, 216, 216, 215, 215,
+ 173, 173, 173, 173, 173, 173, 173, 200,
+ 199, 199, 199, 199, 199, 136, 219, 219,
+ 218, 218, 218, 218, 218, 217, 217, 217,
+ 217, 216, 216, 216, 216, 50, 50, 50,
+ 173, 173, 173, 173, 173, 173, 200, 199,
+ 199, 199, 199, 199, 199, 136, 13, 13,
+ 13, 13, 13, 218, 217, 217, 217, 217,
+ 216, 216, 51, 50, 50, 50, 50, 50,
+ 173, 173, 173, 173, 173, 199, 199, 199,
+ 199, 199, 199, 199, 136, 136, 13, 13,
+ 13, 13, 13, 13, 12, 12, 12, 217,
+ 51, 51, 50, 50, 50, 50, 50, 50,
+ 173, 173, 173, 173, 199, 199, 199, 199,
+ 199, 199, 199, 199, 135, 135, 13, 13,
+ 13, 13, 13, 12, 12, 12, 12, 12,
+ 50, 50, 50, 50, 50, 50, 50, 50,
+ 3, 3, 173, 199, 199, 199, 199, 199,
+ 199, 199, 199, 135, 135, 135, 135, 13,
+ 13, 13, 12, 12, 12, 12, 12, 12,
+ 50, 50, 50, 50, 50, 50, 49, 49,
+ 3, 3, 189, 189, 199, 199, 199, 199,
+ 199, 199, 135, 135, 135, 135, 135, 13,
+ 13, 12, 12, 12, 12, 12, 12, 12,
+ 50, 50, 49, 49, 49, 49, 49, 49,
+ 3, 189, 189, 189, 199, 199, 199, 199,
+ 199, 135, 135, 135, 135, 135, 134, 134,
+ 12, 12, 12, 12, 12, 12, 12, 11,
+ 11, 49, 49, 49, 49, 49, 49, 49,
+ 3, 189, 189, 189, 189, 199, 199, 199,
+ 135, 135, 135, 135, 134, 134, 134, 133,
+ 12, 12, 12, 12, 12, 12, 12, 11,
+ 11, 49, 49, 49, 49, 49, 49, 49,
+ 189, 189, 189, 189, 189, 189, 199, 198,
+ 135, 135, 151, 151, 134, 134, 134, 133,
+ 31, 12, 12, 12, 12, 12, 11, 11,
+ 11, 49, 49, 49, 49, 49, 48, 48,
+ 189, 189, 189, 189, 189, 189, 189, 151,
+ 151, 151, 151, 150, 150, 150, 133, 133,
+ 31, 30, 30, 12, 12, 11, 11, 11,
+ 11, 49, 49, 49, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 188, 188, 151,
+ 151, 150, 150, 150, 150, 150, 133, 133,
+ 30, 30, 29, 29, 29, 11, 11, 11,
+ 11, 11, 48, 48, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 188, 188, 150,
+ 150, 150, 150, 150, 150, 149, 149, 149,
+ 116, 29, 29, 29, 28, 83, 83, 83,
+ 82, 82, 48, 48, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 188, 188, 188,
+ 150, 150, 150, 150, 150, 149, 149, 116,
+ 116, 116, 29, 28, 28, 83, 83, 82,
+ 82, 82, 65, 48, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 188, 188, 188,
+ 150, 150, 150, 150, 149, 149, 116, 116,
+ 116, 115, 115, 115, 28, 83, 82, 82,
+ 82, 82, 65, 65, 65, 48, 48, 48,
+ 188, 188, 188, 188, 188, 188, 187, 187,
+ 150, 150, 150, 149, 149, 149, 116, 116,
+ 116, 115, 115, 115, 114, 83, 82, 82,
+ 82, 65, 65, 65, 65, 65, 64, 64,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 187, 150, 149, 149, 149, 116, 116, 116,
+ 115, 115, 115, 115, 114, 114, 82, 82,
+ 81, 65, 65, 65, 64, 64, 64, 9,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 187, 150, 149, 99, 116, 116, 116, 116,
+ 115, 115, 115, 114, 114, 114, 82, 81,
+ 81, 65, 64, 64, 64, 64, 9, 9,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 187, 99, 99, 99, 99, 98, 97, 97,
+ 97, 115, 114, 114, 114, 114, 113, 81,
+ 81, 64, 64, 64, 64, 64, 9, 9,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 99, 99, 99, 99, 98, 98, 97, 97,
+ 97, 97, 96, 96, 96, 96, 113, 113,
+ 81, 64, 64, 64, 64, 9, 9, 9,
+ 187, 187, 187, 187, 186, 186, 186, 186,
+ 99, 99, 98, 98, 98, 98, 97, 97,
+ 97, 97, 96, 96, 96, 96, 96, 96,
+ 112, 64, 64, 64, 9, 9, 9, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 98, 98, 98, 98, 98, 98, 97, 97,
+ 97, 97, 96, 96, 96, 96, 96, 96,
+ 96, 64, 202, 202, 202, 202, 202, 202,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 98, 98, 98, 98, 98, 97, 97, 97,
+ 97, 97, 96, 96, 96, 96, 96, 96,
+ 96, 202, 202, 202, 202, 202, 202, 202,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 98, 98, 98, 98, 98, 97, 97, 97,
+ 97, 96, 96, 96, 96, 96, 96, 96,
+ 96, 202, 202, 202, 202, 202, 202, 202,
+ 186, 186, 186, 186, 186, 186, 186, 98,
+ 98, 98, 98, 98, 98, 97, 97, 97,
+ 97, 96, 96, 96, 96, 96, 96, 96,
+ 96, 202, 202, 202, 202, 202, 202, 202,
+ 238, 238, 238, 238, 238, 237, 237, 237,
+ 174, 174, 5, 5, 5, 5, 5, 5,
+ 218, 218, 218, 218, 217, 217, 217, 217,
+ 217, 216, 216, 216, 216, 216, 215, 215,
+ 238, 238, 238, 238, 237, 237, 174, 174,
+ 174, 174, 5, 5, 5, 5, 219, 219,
+ 218, 218, 218, 218, 217, 217, 217, 217,
+ 217, 216, 216, 216, 216, 216, 215, 215,
+ 238, 238, 238, 237, 174, 174, 174, 174,
+ 174, 174, 220, 219, 219, 219, 219, 219,
+ 218, 218, 218, 218, 217, 217, 217, 217,
+ 217, 216, 216, 216, 216, 216, 215, 215,
+ 238, 238, 174, 174, 174, 174, 174, 174,
+ 174, 174, 220, 219, 219, 219, 219, 218,
+ 218, 218, 218, 218, 217, 217, 217, 217,
+ 217, 216, 216, 216, 216, 215, 215, 215,
+ 238, 174, 174, 174, 174, 174, 174, 174,
+ 174, 174, 174, 219, 219, 219, 219, 218,
+ 218, 218, 218, 218, 217, 217, 217, 217,
+ 217, 216, 216, 216, 216, 215, 215, 215,
+ 174, 174, 174, 174, 174, 174, 174, 174,
+ 174, 174, 174, 219, 219, 219, 219, 218,
+ 218, 218, 218, 218, 217, 217, 217, 217,
+ 216, 216, 216, 216, 216, 215, 215, 215,
+ 173, 173, 173, 173, 173, 173, 173, 173,
+ 174, 199, 199, 199, 219, 219, 219, 218,
+ 218, 218, 218, 218, 217, 217, 217, 217,
+ 216, 216, 216, 216, 216, 215, 215, 215,
+ 173, 173, 173, 173, 173, 173, 173, 173,
+ 199, 199, 199, 199, 199, 219, 219, 218,
+ 218, 218, 218, 218, 217, 217, 217, 217,
+ 216, 216, 216, 216, 216, 215, 215, 215,
+ 173, 173, 173, 173, 173, 173, 173, 199,
+ 199, 199, 199, 199, 199, 199, 219, 218,
+ 218, 218, 218, 218, 217, 217, 217, 217,
+ 216, 216, 216, 216, 216, 215, 215, 215,
+ 173, 173, 173, 173, 173, 173, 173, 199,
+ 199, 199, 199, 199, 199, 199, 135, 13,
+ 13, 13, 218, 217, 217, 217, 217, 216,
+ 216, 216, 216, 216, 50, 50, 50, 50,
+ 173, 173, 173, 173, 173, 173, 199, 199,
+ 199, 199, 199, 199, 199, 135, 135, 13,
+ 13, 13, 13, 12, 12, 12, 217, 216,
+ 216, 216, 50, 50, 50, 50, 50, 50,
+ 173, 173, 173, 173, 173, 199, 199, 199,
+ 199, 199, 199, 199, 135, 135, 135, 13,
+ 13, 13, 12, 12, 12, 12, 12, 12,
+ 50, 50, 50, 50, 50, 50, 49, 49,
+ 173, 173, 173, 173, 199, 199, 199, 199,
+ 199, 199, 199, 135, 135, 135, 135, 13,
+ 13, 12, 12, 12, 12, 12, 12, 12,
+ 11, 50, 49, 49, 49, 49, 49, 49,
+ 3, 189, 189, 199, 199, 199, 199, 199,
+ 199, 198, 198, 135, 135, 135, 134, 134,
+ 12, 12, 12, 12, 12, 12, 12, 11,
+ 11, 49, 49, 49, 49, 49, 49, 49,
+ 3, 189, 189, 189, 199, 199, 199, 199,
+ 198, 198, 135, 135, 134, 134, 134, 134,
+ 12, 12, 12, 12, 12, 12, 11, 11,
+ 11, 49, 49, 49, 49, 49, 49, 49,
+ 189, 189, 189, 189, 189, 199, 198, 198,
+ 198, 198, 135, 134, 134, 134, 134, 133,
+ 133, 12, 12, 12, 12, 12, 11, 11,
+ 11, 11, 49, 49, 49, 49, 48, 48,
+ 189, 189, 189, 189, 189, 189, 198, 198,
+ 198, 135, 134, 134, 134, 134, 133, 133,
+ 133, 12, 12, 12, 12, 11, 11, 11,
+ 11, 11, 49, 49, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 188, 198, 198,
+ 198, 150, 150, 150, 150, 133, 133, 133,
+ 133, 30, 29, 29, 11, 11, 11, 11,
+ 11, 11, 48, 48, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 188, 188, 150,
+ 150, 150, 150, 150, 150, 150, 133, 133,
+ 132, 29, 29, 29, 11, 11, 11, 11,
+ 11, 11, 48, 48, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 188, 188, 150,
+ 150, 150, 150, 150, 150, 149, 149, 149,
+ 132, 29, 29, 28, 28, 11, 11, 11,
+ 82, 82, 48, 48, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 188, 188, 188,
+ 150, 150, 150, 150, 149, 149, 149, 148,
+ 148, 115, 28, 28, 28, 27, 82, 82,
+ 82, 82, 82, 48, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 188, 187, 187,
+ 150, 150, 150, 149, 149, 149, 149, 148,
+ 148, 115, 115, 28, 27, 27, 82, 82,
+ 82, 82, 65, 65, 65, 48, 48, 48,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 150, 150, 150, 149, 149, 149, 148, 148,
+ 115, 115, 115, 114, 114, 27, 82, 82,
+ 81, 81, 65, 64, 64, 64, 64, 9,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 187, 150, 149, 149, 149, 148, 148, 115,
+ 115, 115, 114, 114, 114, 114, 82, 81,
+ 81, 81, 64, 64, 64, 64, 64, 9,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 187, 149, 149, 149, 149, 148, 116, 115,
+ 115, 115, 114, 114, 114, 114, 113, 81,
+ 81, 81, 64, 64, 64, 64, 9, 9,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 187, 149, 99, 99, 98, 97, 97, 115,
+ 115, 114, 114, 114, 114, 113, 113, 81,
+ 81, 81, 64, 64, 64, 9, 9, 9,
+ 187, 187, 187, 187, 186, 186, 186, 186,
+ 186, 99, 99, 98, 98, 97, 97, 97,
+ 97, 96, 96, 96, 113, 113, 113, 113,
+ 81, 64, 64, 64, 64, 9, 9, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 98, 98, 98, 98, 97, 97, 97,
+ 97, 96, 96, 96, 96, 96, 96, 112,
+ 112, 8, 64, 64, 9, 9, 9, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 98, 98, 98, 98, 97, 97, 97,
+ 97, 96, 96, 96, 96, 96, 96, 96,
+ 8, 8, 8, 202, 202, 202, 202, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 98, 98, 98, 97, 97, 97, 97,
+ 97, 96, 96, 96, 96, 96, 96, 96,
+ 8, 8, 202, 202, 202, 202, 202, 202,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 98, 98, 98, 98, 97, 97, 97, 97,
+ 96, 96, 96, 96, 96, 96, 96, 96,
+ 8, 8, 202, 202, 202, 202, 202, 202,
+ 186, 186, 186, 186, 186, 185, 185, 185,
+ 98, 98, 98, 98, 97, 97, 97, 97,
+ 96, 96, 96, 96, 96, 96, 96, 96,
+ 8, 8, 202, 202, 202, 202, 202, 202,
+ 237, 237, 237, 237, 237, 237, 237, 237,
+ 237, 174, 5, 5, 5, 5, 5, 218,
+ 218, 218, 218, 217, 217, 217, 217, 217,
+ 216, 216, 216, 216, 216, 215, 215, 215,
+ 237, 237, 237, 237, 237, 237, 237, 174,
+ 174, 174, 5, 5, 5, 219, 219, 218,
+ 218, 218, 218, 217, 217, 217, 217, 217,
+ 216, 216, 216, 216, 216, 215, 215, 215,
+ 237, 237, 237, 237, 237, 237, 174, 174,
+ 174, 174, 219, 219, 219, 219, 219, 218,
+ 218, 218, 218, 217, 217, 217, 217, 217,
+ 216, 216, 216, 216, 216, 215, 215, 215,
+ 237, 237, 237, 237, 174, 174, 174, 174,
+ 174, 174, 174, 219, 219, 219, 218, 218,
+ 218, 218, 218, 217, 217, 217, 217, 217,
+ 216, 216, 216, 216, 215, 215, 215, 215,
+ 237, 237, 174, 174, 174, 174, 174, 174,
+ 174, 174, 174, 219, 219, 219, 218, 218,
+ 218, 218, 218, 217, 217, 217, 217, 217,
+ 216, 216, 216, 216, 215, 215, 215, 215,
+ 173, 173, 173, 173, 173, 173, 173, 173,
+ 173, 174, 174, 219, 219, 219, 218, 218,
+ 218, 218, 218, 217, 217, 217, 217, 216,
+ 216, 216, 216, 216, 215, 215, 215, 215,
+ 173, 173, 173, 173, 173, 173, 173, 173,
+ 173, 173, 199, 199, 219, 219, 218, 218,
+ 218, 218, 218, 217, 217, 217, 217, 216,
+ 216, 216, 216, 216, 215, 215, 215, 215,
+ 173, 173, 173, 173, 173, 173, 173, 173,
+ 173, 199, 199, 199, 199, 219, 218, 218,
+ 218, 218, 218, 217, 217, 217, 217, 216,
+ 216, 216, 216, 216, 215, 215, 215, 215,
+ 173, 173, 173, 173, 173, 173, 173, 173,
+ 199, 199, 199, 199, 199, 199, 218, 218,
+ 218, 218, 218, 217, 217, 217, 217, 216,
+ 216, 216, 216, 216, 215, 215, 215, 215,
+ 173, 173, 173, 173, 173, 173, 173, 199,
+ 199, 199, 199, 199, 199, 198, 135, 13,
+ 13, 218, 217, 217, 217, 217, 216, 216,
+ 216, 216, 216, 215, 215, 215, 215, 215,
+ 173, 173, 173, 173, 173, 173, 199, 199,
+ 199, 199, 199, 198, 198, 198, 135, 13,
+ 13, 13, 12, 12, 12, 217, 216, 216,
+ 216, 216, 216, 215, 50, 50, 49, 49,
+ 172, 172, 172, 172, 172, 199, 199, 199,
+ 199, 199, 198, 198, 198, 135, 135, 134,
+ 13, 12, 12, 12, 12, 12, 12, 12,
+ 11, 50, 49, 49, 49, 49, 49, 49,
+ 172, 172, 172, 172, 172, 199, 199, 199,
+ 198, 198, 198, 198, 198, 134, 134, 134,
+ 12, 12, 12, 12, 12, 12, 12, 11,
+ 11, 49, 49, 49, 49, 49, 49, 49,
+ 172, 172, 172, 172, 199, 199, 198, 198,
+ 198, 198, 198, 198, 134, 134, 134, 134,
+ 133, 12, 12, 12, 12, 12, 11, 11,
+ 11, 11, 49, 49, 49, 49, 49, 49,
+ 189, 189, 189, 189, 199, 198, 198, 198,
+ 198, 198, 198, 198, 134, 134, 134, 133,
+ 133, 12, 12, 12, 12, 11, 11, 11,
+ 11, 11, 49, 49, 49, 49, 48, 48,
+ 189, 189, 189, 189, 198, 198, 198, 198,
+ 198, 198, 198, 134, 134, 134, 133, 133,
+ 133, 12, 12, 12, 12, 11, 11, 11,
+ 11, 11, 49, 49, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 198, 198, 198,
+ 198, 198, 134, 134, 134, 133, 133, 133,
+ 133, 132, 12, 12, 11, 11, 11, 11,
+ 11, 11, 48, 48, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 188, 198, 198,
+ 198, 150, 150, 150, 150, 133, 133, 133,
+ 132, 132, 29, 11, 11, 11, 11, 11,
+ 11, 11, 48, 48, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 188, 188, 198,
+ 150, 150, 150, 150, 150, 133, 133, 132,
+ 132, 132, 29, 28, 11, 11, 11, 11,
+ 11, 11, 48, 48, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 188, 188, 150,
+ 150, 150, 150, 150, 149, 149, 149, 132,
+ 132, 132, 28, 28, 28, 11, 11, 11,
+ 11, 82, 48, 48, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 188, 187, 187,
+ 150, 150, 150, 149, 149, 149, 149, 148,
+ 148, 131, 131, 28, 27, 27, 27, 82,
+ 82, 82, 81, 48, 48, 48, 48, 48,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 150, 150, 150, 149, 149, 149, 148, 148,
+ 148, 147, 147, 27, 27, 27, 26, 82,
+ 82, 81, 81, 64, 64, 64, 48, 48,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 187, 150, 149, 149, 149, 148, 148, 148,
+ 147, 147, 114, 114, 114, 26, 26, 81,
+ 81, 81, 81, 64, 64, 64, 64, 9,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 187, 149, 149, 149, 149, 148, 148, 148,
+ 147, 114, 114, 114, 114, 113, 26, 81,
+ 81, 81, 81, 64, 64, 64, 9, 9,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 187, 149, 149, 149, 148, 148, 148, 147,
+ 147, 114, 114, 114, 114, 113, 113, 81,
+ 81, 81, 64, 64, 64, 64, 9, 9,
+ 187, 187, 187, 187, 186, 186, 186, 186,
+ 186, 186, 149, 148, 148, 148, 147, 147,
+ 114, 114, 114, 114, 113, 113, 113, 112,
+ 81, 80, 64, 64, 64, 9, 9, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 186, 98, 98, 97, 97, 97, 97,
+ 96, 96, 96, 113, 113, 113, 113, 112,
+ 112, 80, 64, 64, 9, 9, 9, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 186, 98, 98, 97, 97, 97, 97,
+ 96, 96, 96, 96, 96, 113, 112, 112,
+ 8, 8, 8, 64, 9, 9, 9, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 186, 98, 98, 97, 97, 97, 97,
+ 96, 96, 96, 96, 96, 96, 96, 8,
+ 8, 8, 8, 9, 9, 9, 9, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 98, 98, 97, 97, 97, 97, 97,
+ 96, 96, 96, 96, 96, 96, 96, 8,
+ 8, 8, 8, 202, 202, 202, 202, 202,
+ 186, 186, 186, 186, 186, 185, 185, 185,
+ 182, 182, 98, 97, 97, 97, 97, 96,
+ 96, 96, 96, 96, 96, 96, 96, 8,
+ 8, 8, 8, 202, 202, 202, 202, 202,
+ 185, 185, 185, 185, 185, 185, 185, 185,
+ 182, 182, 98, 97, 97, 97, 97, 96,
+ 96, 96, 96, 96, 96, 96, 96, 8,
+ 8, 8, 8, 202, 202, 202, 202, 202,
+ 236, 236, 236, 236, 236, 236, 236, 236,
+ 236, 236, 5, 5, 5, 5, 218, 218,
+ 218, 218, 217, 217, 217, 217, 217, 216,
+ 216, 216, 216, 216, 215, 215, 215, 215,
+ 236, 236, 236, 236, 236, 236, 236, 236,
+ 236, 174, 5, 5, 219, 219, 218, 218,
+ 218, 218, 217, 217, 217, 217, 217, 216,
+ 216, 216, 216, 216, 215, 215, 215, 215,
+ 236, 236, 236, 236, 236, 236, 236, 174,
+ 174, 174, 174, 219, 219, 219, 218, 218,
+ 218, 218, 217, 217, 217, 217, 217, 216,
+ 216, 216, 216, 216, 215, 215, 215, 215,
+ 236, 236, 236, 236, 236, 174, 174, 174,
+ 174, 174, 174, 219, 219, 218, 218, 218,
+ 218, 218, 217, 217, 217, 217, 217, 216,
+ 216, 216, 216, 215, 215, 215, 215, 215,
+ 236, 236, 236, 173, 173, 173, 173, 173,
+ 173, 173, 174, 219, 219, 218, 218, 218,
+ 218, 218, 217, 217, 217, 217, 217, 216,
+ 216, 216, 216, 215, 215, 215, 215, 215,
+ 173, 173, 173, 173, 173, 173, 173, 173,
+ 173, 173, 173, 219, 219, 218, 218, 218,
+ 218, 218, 217, 217, 217, 217, 216, 216,
+ 216, 216, 216, 215, 215, 215, 215, 215,
+ 173, 173, 173, 173, 173, 173, 173, 173,
+ 173, 173, 199, 199, 199, 218, 218, 218,
+ 218, 218, 217, 217, 217, 217, 216, 216,
+ 216, 216, 216, 215, 215, 215, 215, 215,
+ 173, 173, 173, 173, 173, 173, 173, 173,
+ 173, 199, 199, 199, 199, 198, 218, 218,
+ 218, 218, 217, 217, 217, 217, 216, 216,
+ 216, 216, 216, 215, 215, 215, 215, 215,
+ 173, 173, 173, 173, 173, 173, 173, 173,
+ 199, 199, 199, 199, 198, 198, 198, 218,
+ 218, 218, 217, 217, 217, 217, 216, 216,
+ 216, 216, 216, 215, 215, 215, 215, 214,
+ 172, 172, 172, 172, 173, 173, 173, 199,
+ 199, 199, 198, 198, 198, 198, 198, 197,
+ 218, 217, 217, 217, 217, 216, 216, 216,
+ 216, 216, 215, 215, 215, 215, 215, 214,
+ 172, 172, 172, 172, 172, 172, 172, 199,
+ 198, 198, 198, 198, 198, 198, 197, 197,
+ 197, 12, 12, 12, 217, 216, 216, 216,
+ 216, 216, 215, 215, 215, 215, 215, 49,
+ 172, 172, 172, 172, 172, 172, 199, 198,
+ 198, 198, 198, 198, 198, 197, 197, 197,
+ 197, 12, 12, 12, 12, 12, 12, 11,
+ 216, 216, 215, 49, 49, 49, 49, 49,
+ 172, 172, 172, 172, 172, 198, 198, 198,
+ 198, 198, 198, 198, 198, 197, 197, 197,
+ 133, 12, 12, 12, 12, 12, 11, 11,
+ 11, 11, 49, 49, 49, 49, 49, 49,
+ 172, 172, 172, 172, 172, 198, 198, 198,
+ 198, 198, 198, 198, 197, 197, 197, 133,
+ 133, 12, 12, 12, 12, 11, 11, 11,
+ 11, 11, 49, 49, 49, 49, 48, 48,
+ 172, 172, 172, 172, 198, 198, 198, 198,
+ 198, 198, 198, 197, 197, 197, 133, 133,
+ 133, 133, 12, 12, 11, 11, 11, 11,
+ 11, 11, 11, 49, 48, 48, 48, 48,
+ 188, 188, 188, 188, 198, 198, 198, 198,
+ 198, 198, 197, 197, 197, 197, 133, 133,
+ 133, 132, 12, 12, 11, 11, 11, 11,
+ 11, 11, 11, 48, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 198, 198, 198,
+ 198, 198, 197, 197, 197, 133, 133, 133,
+ 132, 132, 132, 11, 11, 11, 11, 11,
+ 11, 11, 11, 48, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 188, 198, 198,
+ 198, 197, 197, 197, 133, 133, 133, 132,
+ 132, 132, 131, 11, 11, 11, 11, 11,
+ 11, 11, 11, 48, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 188, 188, 198,
+ 197, 197, 150, 150, 133, 133, 132, 132,
+ 132, 132, 131, 11, 11, 11, 11, 11,
+ 11, 11, 10, 48, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 188, 187, 150,
+ 150, 150, 150, 150, 149, 149, 149, 132,
+ 132, 131, 131, 131, 11, 11, 11, 11,
+ 11, 10, 10, 48, 48, 48, 48, 48,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 150, 150, 150, 149, 149, 149, 148, 148,
+ 148, 131, 131, 131, 27, 27, 26, 10,
+ 10, 10, 10, 10, 48, 48, 48, 48,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 150, 150, 149, 149, 149, 148, 148, 148,
+ 147, 147, 147, 130, 27, 26, 26, 10,
+ 10, 10, 10, 80, 64, 64, 64, 48,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 187, 149, 149, 149, 149, 148, 148, 148,
+ 147, 147, 147, 114, 26, 26, 26, 25,
+ 81, 81, 80, 80, 64, 64, 9, 9,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 187, 149, 149, 149, 148, 148, 148, 147,
+ 147, 147, 114, 114, 113, 113, 25, 25,
+ 81, 80, 80, 64, 64, 64, 9, 9,
+ 187, 187, 187, 187, 186, 186, 186, 186,
+ 186, 149, 149, 148, 148, 148, 147, 147,
+ 147, 147, 114, 114, 113, 113, 113, 81,
+ 80, 80, 80, 64, 64, 9, 9, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 186, 149, 148, 148, 148, 147, 147,
+ 147, 114, 114, 113, 113, 113, 113, 112,
+ 80, 80, 80, 64, 9, 9, 9, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 186, 148, 148, 148, 147, 147, 147,
+ 114, 114, 113, 113, 113, 113, 112, 112,
+ 112, 80, 80, 64, 9, 9, 9, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 186, 181, 97, 97, 97, 97, 96,
+ 96, 96, 96, 96, 113, 112, 112, 112,
+ 8, 8, 8, 8, 9, 9, 9, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 182, 181, 97, 97, 97, 97, 96,
+ 96, 96, 96, 96, 96, 112, 112, 8,
+ 8, 8, 8, 8, 9, 9, 9, 9,
+ 186, 186, 186, 186, 186, 185, 185, 185,
+ 182, 182, 181, 97, 97, 97, 97, 96,
+ 96, 96, 96, 96, 96, 96, 8, 8,
+ 8, 8, 8, 8, 9, 9, 9, 9,
+ 185, 185, 185, 185, 185, 185, 185, 185,
+ 182, 182, 181, 181, 97, 97, 96, 96,
+ 96, 96, 96, 96, 96, 96, 8, 8,
+ 8, 8, 8, 8, 202, 202, 202, 202,
+ 185, 185, 185, 185, 185, 185, 185, 182,
+ 182, 182, 181, 181, 97, 97, 96, 96,
+ 96, 96, 96, 96, 96, 96, 8, 8,
+ 8, 8, 8, 8, 202, 202, 202, 202,
+ 236, 236, 236, 236, 236, 236, 236, 236,
+ 236, 236, 236, 5, 5, 218, 218, 218,
+ 218, 217, 217, 217, 217, 217, 216, 216,
+ 216, 216, 216, 215, 215, 215, 215, 214,
+ 236, 236, 236, 236, 236, 236, 236, 236,
+ 236, 236, 236, 219, 219, 218, 218, 218,
+ 218, 217, 217, 217, 217, 217, 216, 216,
+ 216, 216, 216, 215, 215, 215, 215, 214,
+ 236, 236, 236, 236, 236, 236, 236, 236,
+ 236, 174, 174, 219, 219, 218, 218, 218,
+ 218, 217, 217, 217, 217, 217, 216, 216,
+ 216, 216, 216, 215, 215, 215, 215, 214,
+ 236, 236, 236, 236, 236, 236, 236, 173,
+ 173, 173, 173, 219, 218, 218, 218, 218,
+ 218, 217, 217, 217, 217, 217, 216, 216,
+ 216, 216, 215, 215, 215, 215, 215, 214,
+ 236, 236, 236, 236, 173, 173, 173, 173,
+ 173, 173, 173, 219, 218, 218, 218, 218,
+ 218, 217, 217, 217, 217, 217, 216, 216,
+ 216, 216, 215, 215, 215, 215, 215, 214,
+ 236, 173, 173, 173, 173, 173, 173, 173,
+ 173, 173, 173, 173, 218, 218, 218, 218,
+ 218, 217, 217, 217, 217, 216, 216, 216,
+ 216, 216, 215, 215, 215, 215, 215, 214,
+ 173, 173, 173, 173, 173, 173, 173, 173,
+ 173, 173, 173, 199, 198, 218, 218, 218,
+ 218, 217, 217, 217, 217, 216, 216, 216,
+ 216, 216, 215, 215, 215, 215, 215, 214,
+ 172, 172, 173, 173, 173, 173, 173, 173,
+ 173, 173, 198, 198, 198, 198, 218, 218,
+ 218, 217, 217, 217, 217, 216, 216, 216,
+ 216, 216, 215, 215, 215, 215, 215, 214,
+ 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 198, 198, 198, 198, 198, 198, 218,
+ 218, 217, 217, 217, 217, 216, 216, 216,
+ 216, 216, 215, 215, 215, 215, 214, 214,
+ 172, 172, 172, 172, 172, 172, 172, 172,
+ 198, 198, 198, 198, 198, 198, 197, 197,
+ 197, 217, 217, 217, 216, 216, 216, 216,
+ 216, 215, 215, 215, 215, 215, 214, 214,
+ 172, 172, 172, 172, 172, 172, 172, 198,
+ 198, 198, 198, 198, 198, 197, 197, 197,
+ 197, 197, 217, 217, 216, 216, 216, 216,
+ 216, 215, 215, 215, 215, 215, 214, 214,
+ 172, 172, 172, 172, 172, 172, 172, 198,
+ 198, 198, 198, 198, 198, 197, 197, 197,
+ 197, 196, 12, 12, 12, 12, 11, 216,
+ 216, 215, 215, 215, 215, 215, 49, 49,
+ 172, 172, 172, 172, 172, 172, 198, 198,
+ 198, 198, 198, 198, 197, 197, 197, 197,
+ 196, 196, 12, 12, 12, 11, 11, 11,
+ 11, 11, 11, 49, 49, 49, 48, 48,
+ 171, 171, 172, 172, 172, 198, 198, 198,
+ 198, 198, 198, 197, 197, 197, 197, 196,
+ 196, 196, 12, 12, 11, 11, 11, 11,
+ 11, 11, 11, 49, 48, 48, 48, 48,
+ 171, 171, 171, 171, 171, 198, 198, 198,
+ 198, 198, 198, 197, 197, 197, 197, 196,
+ 196, 196, 132, 11, 11, 11, 11, 11,
+ 11, 11, 11, 48, 48, 48, 48, 48,
+ 171, 171, 171, 171, 198, 198, 198, 198,
+ 198, 198, 197, 197, 197, 197, 196, 196,
+ 196, 132, 132, 11, 11, 11, 11, 11,
+ 11, 11, 11, 48, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 198, 198, 198,
+ 198, 197, 197, 197, 197, 196, 196, 196,
+ 132, 132, 132, 11, 11, 11, 11, 11,
+ 11, 11, 11, 48, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 198, 198, 198,
+ 197, 197, 197, 197, 196, 196, 196, 132,
+ 132, 132, 131, 131, 11, 11, 11, 11,
+ 11, 11, 10, 48, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 188, 198, 198,
+ 197, 197, 197, 196, 196, 196, 132, 132,
+ 132, 131, 131, 131, 11, 11, 11, 11,
+ 11, 10, 10, 10, 48, 48, 48, 48,
+ 187, 187, 187, 187, 187, 187, 187, 197,
+ 197, 197, 197, 196, 196, 149, 132, 132,
+ 131, 131, 131, 131, 11, 11, 11, 10,
+ 10, 10, 10, 10, 48, 48, 48, 48,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 197, 150, 149, 149, 149, 148, 148, 148,
+ 131, 131, 131, 130, 130, 26, 26, 10,
+ 10, 10, 10, 10, 10, 48, 48, 48,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 150, 149, 149, 149, 149, 148, 148, 148,
+ 147, 147, 147, 130, 130, 26, 26, 10,
+ 10, 10, 10, 10, 80, 64, 64, 9,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 187, 149, 149, 149, 148, 148, 148, 147,
+ 147, 147, 146, 146, 146, 26, 25, 10,
+ 10, 10, 80, 80, 80, 64, 9, 9,
+ 187, 187, 187, 187, 186, 186, 186, 186,
+ 186, 149, 149, 148, 148, 148, 147, 147,
+ 147, 147, 146, 146, 113, 25, 25, 24,
+ 24, 80, 80, 80, 80, 9, 9, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 186, 149, 148, 148, 148, 147, 147,
+ 147, 146, 146, 113, 113, 113, 112, 24,
+ 24, 80, 80, 80, 64, 9, 9, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 186, 148, 148, 148, 147, 147, 147,
+ 147, 146, 113, 113, 113, 113, 112, 112,
+ 7, 80, 80, 80, 9, 9, 9, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 186, 181, 148, 147, 147, 147, 147,
+ 146, 113, 113, 113, 113, 112, 112, 112,
+ 112, 8, 22, 22, 9, 9, 9, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 182, 181, 181, 179, 147, 147, 96,
+ 96, 96, 113, 113, 112, 112, 112, 8,
+ 8, 8, 8, 8, 9, 9, 9, 9,
+ 186, 186, 186, 186, 186, 185, 185, 185,
+ 182, 182, 181, 181, 179, 97, 96, 96,
+ 96, 96, 96, 96, 112, 112, 8, 8,
+ 8, 8, 8, 8, 9, 9, 9, 9,
+ 185, 185, 185, 185, 185, 185, 185, 185,
+ 182, 182, 181, 181, 179, 179, 96, 96,
+ 96, 96, 96, 96, 96, 8, 8, 8,
+ 8, 8, 8, 8, 8, 9, 9, 9,
+ 185, 185, 185, 185, 185, 185, 185, 182,
+ 182, 182, 181, 181, 179, 179, 96, 96,
+ 96, 96, 96, 96, 96, 8, 8, 8,
+ 8, 8, 8, 8, 8, 202, 202, 202,
+ 185, 185, 185, 185, 185, 185, 185, 182,
+ 182, 182, 181, 181, 179, 179, 96, 96,
+ 96, 96, 96, 96, 96, 8, 8, 8,
+ 8, 8, 8, 8, 8, 202, 202, 202,
+ 235, 235, 235, 235, 235, 235, 235, 234,
+ 234, 234, 234, 5, 218, 218, 218, 218,
+ 217, 217, 217, 217, 217, 216, 216, 216,
+ 216, 216, 215, 215, 215, 215, 214, 214,
+ 235, 235, 235, 235, 235, 235, 234, 234,
+ 234, 234, 234, 219, 218, 218, 218, 218,
+ 217, 217, 217, 217, 217, 216, 216, 216,
+ 216, 216, 215, 215, 215, 215, 214, 214,
+ 235, 235, 235, 235, 235, 234, 234, 234,
+ 234, 234, 228, 219, 218, 218, 218, 218,
+ 217, 217, 217, 217, 217, 216, 216, 216,
+ 216, 216, 215, 215, 215, 215, 214, 214,
+ 235, 235, 235, 235, 234, 234, 234, 234,
+ 234, 228, 227, 227, 218, 218, 218, 218,
+ 217, 217, 217, 217, 217, 216, 216, 216,
+ 216, 215, 215, 215, 215, 215, 214, 214,
+ 235, 235, 235, 234, 234, 234, 173, 173,
+ 173, 173, 227, 227, 218, 218, 218, 218,
+ 217, 217, 217, 217, 217, 216, 216, 216,
+ 216, 215, 215, 215, 215, 215, 214, 214,
+ 235, 235, 173, 173, 173, 173, 173, 173,
+ 173, 173, 227, 226, 226, 218, 218, 218,
+ 217, 217, 217, 217, 216, 216, 216, 216,
+ 216, 215, 215, 215, 215, 215, 214, 214,
+ 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 172, 226, 226, 226, 218, 218, 218,
+ 217, 217, 217, 217, 216, 216, 216, 216,
+ 216, 215, 215, 215, 215, 215, 214, 214,
+ 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 172, 198, 198, 198, 225, 218, 218,
+ 217, 217, 217, 217, 216, 216, 216, 216,
+ 216, 215, 215, 215, 215, 215, 214, 214,
+ 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 198, 198, 198, 198, 198, 197, 197,
+ 217, 217, 217, 217, 216, 216, 216, 216,
+ 216, 215, 215, 215, 215, 214, 214, 214,
+ 172, 172, 172, 172, 172, 172, 172, 172,
+ 198, 198, 198, 198, 198, 198, 197, 197,
+ 197, 217, 217, 216, 216, 216, 216, 216,
+ 215, 215, 215, 215, 215, 214, 214, 214,
+ 172, 172, 172, 172, 172, 172, 172, 172,
+ 198, 198, 198, 198, 198, 197, 197, 197,
+ 197, 196, 217, 216, 216, 216, 216, 216,
+ 215, 215, 215, 215, 215, 214, 214, 214,
+ 172, 172, 172, 172, 172, 172, 172, 198,
+ 198, 198, 198, 198, 197, 197, 197, 197,
+ 197, 196, 196, 12, 12, 216, 216, 216,
+ 215, 215, 215, 215, 215, 214, 214, 214,
+ 171, 171, 171, 171, 172, 172, 198, 198,
+ 198, 198, 198, 197, 197, 197, 197, 197,
+ 196, 196, 196, 12, 11, 11, 11, 11,
+ 11, 11, 215, 215, 48, 48, 48, 48,
+ 171, 171, 171, 171, 171, 171, 198, 198,
+ 198, 198, 198, 197, 197, 197, 197, 196,
+ 196, 196, 195, 11, 11, 11, 11, 11,
+ 11, 11, 11, 48, 48, 48, 48, 48,
+ 171, 171, 171, 171, 171, 198, 198, 198,
+ 198, 198, 197, 197, 197, 197, 196, 196,
+ 196, 196, 195, 11, 11, 11, 11, 11,
+ 11, 11, 11, 48, 48, 48, 48, 48,
+ 171, 171, 171, 171, 171, 198, 198, 198,
+ 198, 197, 197, 197, 197, 196, 196, 196,
+ 196, 195, 195, 11, 11, 11, 11, 11,
+ 11, 11, 11, 48, 48, 48, 48, 48,
+ 171, 171, 171, 171, 171, 198, 198, 198,
+ 197, 197, 197, 197, 197, 196, 196, 196,
+ 195, 195, 195, 131, 11, 11, 11, 11,
+ 11, 11, 11, 48, 48, 48, 48, 48,
+ 188, 188, 188, 188, 188, 198, 198, 198,
+ 197, 197, 197, 197, 196, 196, 196, 195,
+ 195, 195, 131, 131, 11, 11, 11, 11,
+ 11, 10, 10, 10, 48, 48, 48, 48,
+ 187, 187, 187, 187, 187, 187, 198, 197,
+ 197, 197, 197, 196, 196, 196, 195, 195,
+ 195, 131, 131, 131, 11, 11, 11, 11,
+ 10, 10, 10, 10, 48, 48, 48, 48,
+ 187, 187, 187, 187, 187, 187, 187, 197,
+ 197, 197, 196, 196, 196, 196, 195, 195,
+ 195, 131, 131, 130, 130, 11, 10, 10,
+ 10, 10, 10, 10, 10, 48, 48, 48,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 197, 196, 196, 196, 196, 195, 195, 195,
+ 131, 131, 130, 130, 130, 130, 10, 10,
+ 10, 10, 10, 10, 10, 48, 48, 48,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 187, 196, 196, 196, 195, 148, 148, 147,
+ 147, 147, 130, 130, 130, 129, 10, 10,
+ 10, 10, 10, 10, 80, 80, 9, 9,
+ 187, 187, 187, 187, 186, 186, 186, 186,
+ 186, 149, 149, 148, 148, 148, 148, 147,
+ 147, 147, 146, 146, 146, 129, 25, 10,
+ 10, 10, 80, 80, 80, 80, 9, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 186, 149, 148, 148, 148, 147, 147,
+ 147, 146, 146, 146, 145, 145, 24, 24,
+ 24, 80, 80, 80, 80, 9, 9, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 186, 148, 148, 148, 147, 147, 147,
+ 147, 146, 146, 145, 145, 145, 24, 24,
+ 7, 23, 80, 80, 22, 9, 9, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 186, 181, 148, 147, 147, 147, 147,
+ 146, 146, 145, 145, 145, 112, 112, 112,
+ 23, 23, 22, 22, 22, 9, 9, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 182, 181, 181, 147, 147, 147, 147,
+ 146, 145, 145, 145, 112, 112, 112, 112,
+ 8, 22, 22, 22, 21, 9, 9, 9,
+ 186, 186, 186, 186, 186, 185, 185, 185,
+ 182, 182, 181, 181, 179, 179, 147, 145,
+ 145, 145, 145, 112, 112, 112, 112, 8,
+ 8, 8, 8, 21, 21, 21, 9, 9,
+ 185, 185, 185, 185, 185, 185, 185, 185,
+ 182, 182, 181, 181, 179, 179, 179, 96,
+ 96, 96, 96, 112, 112, 112, 8, 8,
+ 8, 8, 8, 21, 21, 20, 9, 9,
+ 185, 185, 185, 185, 185, 185, 185, 182,
+ 182, 182, 181, 181, 179, 179, 179, 177,
+ 96, 96, 96, 96, 8, 8, 8, 8,
+ 8, 8, 8, 8, 20, 20, 19, 9,
+ 185, 185, 185, 185, 185, 185, 185, 182,
+ 182, 182, 181, 181, 179, 179, 179, 177,
+ 96, 96, 96, 96, 8, 8, 8, 8,
+ 8, 8, 8, 8, 20, 19, 19, 19,
+ 185, 185, 185, 185, 185, 185, 183, 182,
+ 182, 182, 181, 181, 179, 179, 179, 177,
+ 96, 96, 96, 96, 8, 8, 8, 8,
+ 8, 8, 8, 8, 19, 19, 19, 18,
+ 235, 234, 234, 234, 234, 234, 234, 234,
+ 234, 234, 234, 228, 218, 218, 218, 217,
+ 217, 217, 217, 217, 216, 216, 216, 216,
+ 216, 215, 215, 215, 215, 214, 214, 214,
+ 234, 234, 234, 234, 234, 234, 234, 234,
+ 234, 234, 228, 228, 218, 218, 218, 217,
+ 217, 217, 217, 217, 216, 216, 216, 216,
+ 216, 215, 215, 215, 215, 214, 214, 214,
+ 234, 234, 234, 234, 234, 234, 234, 234,
+ 234, 228, 228, 227, 227, 218, 218, 217,
+ 217, 217, 217, 217, 216, 216, 216, 216,
+ 216, 215, 215, 215, 215, 214, 214, 214,
+ 234, 234, 234, 234, 234, 234, 234, 234,
+ 228, 228, 227, 227, 227, 218, 218, 217,
+ 217, 217, 217, 217, 216, 216, 216, 216,
+ 215, 215, 215, 215, 215, 214, 214, 214,
+ 234, 234, 234, 234, 234, 234, 234, 228,
+ 228, 227, 227, 227, 226, 218, 218, 217,
+ 217, 217, 217, 217, 216, 216, 216, 216,
+ 215, 215, 215, 215, 215, 214, 214, 214,
+ 234, 234, 234, 172, 172, 172, 172, 172,
+ 227, 227, 227, 226, 226, 226, 218, 217,
+ 217, 217, 217, 216, 216, 216, 216, 216,
+ 215, 215, 215, 215, 215, 214, 214, 214,
+ 172, 172, 172, 172, 172, 172, 172, 172,
+ 227, 227, 226, 226, 226, 225, 225, 217,
+ 217, 217, 217, 216, 216, 216, 216, 216,
+ 215, 215, 215, 215, 215, 214, 214, 214,
+ 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 226, 226, 226, 225, 225, 225, 217,
+ 217, 217, 217, 216, 216, 216, 216, 216,
+ 215, 215, 215, 215, 215, 214, 214, 214,
+ 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 226, 226, 225, 225, 225, 224, 224,
+ 217, 217, 217, 216, 216, 216, 216, 216,
+ 215, 215, 215, 215, 214, 214, 214, 214,
+ 172, 172, 172, 172, 172, 172, 172, 172,
+ 172, 198, 198, 198, 225, 224, 224, 224,
+ 224, 217, 216, 216, 216, 216, 216, 215,
+ 215, 215, 215, 215, 214, 214, 214, 214,
+ 172, 172, 172, 172, 172, 172, 172, 172,
+ 198, 198, 198, 198, 197, 197, 197, 197,
+ 197, 196, 196, 216, 216, 216, 216, 215,
+ 215, 215, 215, 215, 214, 214, 214, 214,
+ 171, 171, 171, 171, 171, 172, 172, 198,
+ 198, 198, 198, 197, 197, 197, 197, 197,
+ 196, 196, 196, 196, 216, 216, 216, 215,
+ 215, 215, 215, 215, 214, 214, 214, 214,
+ 171, 171, 171, 171, 171, 171, 171, 198,
+ 198, 198, 198, 197, 197, 197, 197, 196,
+ 196, 196, 196, 195, 11, 11, 11, 11,
+ 11, 215, 215, 215, 214, 214, 214, 214,
+ 171, 171, 171, 171, 171, 171, 198, 198,
+ 198, 198, 197, 197, 197, 197, 197, 196,
+ 196, 196, 195, 195, 11, 11, 11, 11,
+ 11, 11, 11, 11, 48, 48, 48, 48,
+ 171, 171, 171, 171, 171, 171, 198, 198,
+ 198, 197, 197, 197, 197, 197, 196, 196,
+ 196, 195, 195, 195, 11, 11, 11, 11,
+ 11, 11, 11, 11, 48, 48, 48, 48,
+ 171, 171, 171, 171, 171, 171, 198, 198,
+ 197, 197, 197, 197, 197, 196, 196, 196,
+ 195, 195, 195, 194, 11, 11, 11, 11,
+ 11, 11, 11, 10, 48, 48, 48, 48,
+ 171, 171, 171, 171, 171, 198, 198, 198,
+ 197, 197, 197, 197, 196, 196, 196, 196,
+ 195, 195, 194, 194, 194, 11, 11, 11,
+ 11, 11, 10, 10, 48, 48, 48, 48,
+ 187, 187, 187, 171, 171, 198, 198, 197,
+ 197, 197, 197, 196, 196, 196, 196, 195,
+ 195, 195, 194, 194, 194, 11, 11, 11,
+ 10, 10, 10, 10, 10, 48, 48, 48,
+ 187, 187, 187, 187, 187, 187, 197, 197,
+ 197, 197, 197, 196, 196, 196, 195, 195,
+ 195, 194, 194, 194, 194, 11, 11, 10,
+ 10, 10, 10, 10, 10, 48, 48, 48,
+ 187, 187, 187, 187, 187, 187, 187, 197,
+ 197, 197, 196, 196, 196, 195, 195, 195,
+ 195, 194, 194, 194, 130, 130, 10, 10,
+ 10, 10, 10, 10, 10, 10, 48, 48,
+ 187, 187, 187, 187, 187, 187, 187, 187,
+ 197, 196, 196, 196, 195, 195, 195, 195,
+ 194, 194, 194, 130, 130, 129, 10, 10,
+ 10, 10, 10, 10, 10, 10, 48, 48,
+ 187, 187, 187, 187, 186, 186, 186, 186,
+ 196, 196, 196, 196, 195, 195, 195, 194,
+ 194, 194, 130, 130, 129, 129, 10, 10,
+ 10, 10, 10, 10, 80, 80, 9, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 196, 196, 195, 195, 195, 195, 147,
+ 147, 146, 146, 129, 129, 129, 128, 10,
+ 10, 10, 80, 80, 80, 80, 9, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 186, 195, 195, 195, 147, 147, 147,
+ 147, 146, 146, 145, 145, 145, 128, 24,
+ 7, 23, 23, 22, 22, 22, 9, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 186, 148, 148, 148, 147, 147, 147,
+ 146, 146, 145, 145, 145, 128, 128, 7,
+ 23, 23, 22, 22, 22, 21, 9, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 182, 181, 181, 147, 147, 147, 147,
+ 146, 145, 145, 145, 145, 144, 144, 23,
+ 23, 22, 22, 22, 21, 21, 21, 9,
+ 186, 186, 186, 186, 186, 185, 185, 185,
+ 182, 182, 181, 181, 179, 179, 147, 145,
+ 145, 145, 145, 145, 144, 144, 112, 112,
+ 22, 22, 22, 21, 21, 21, 20, 9,
+ 185, 185, 185, 185, 185, 185, 185, 185,
+ 182, 182, 181, 181, 179, 179, 179, 145,
+ 145, 145, 145, 144, 144, 112, 8, 8,
+ 8, 8, 21, 21, 21, 20, 20, 19,
+ 185, 185, 185, 185, 185, 185, 185, 182,
+ 182, 182, 181, 181, 179, 179, 179, 177,
+ 177, 145, 145, 144, 112, 8, 8, 8,
+ 8, 8, 21, 21, 20, 20, 19, 19,
+ 185, 185, 185, 185, 185, 185, 185, 182,
+ 182, 182, 181, 181, 179, 179, 179, 177,
+ 177, 176, 176, 112, 8, 8, 8, 8,
+ 8, 8, 8, 20, 20, 19, 19, 19,
+ 185, 185, 185, 185, 185, 185, 183, 182,
+ 182, 182, 181, 181, 179, 179, 179, 177,
+ 177, 176, 176, 8, 8, 8, 8, 8,
+ 8, 8, 8, 20, 19, 19, 19, 18,
+ 185, 185, 185, 185, 185, 183, 183, 182,
+ 182, 182, 181, 181, 179, 179, 179, 177,
+ 177, 176, 176, 176, 8, 8, 8, 8,
+ 8, 8, 8, 19, 19, 19, 18, 18,
+ 234, 234, 234, 234, 234, 234, 234, 234,
+ 234, 229, 229, 228, 228, 218, 217, 217,
+ 217, 217, 217, 216, 216, 216, 216, 216,
+ 215, 215, 215, 215, 214, 214, 214, 214,
+ 234, 234, 234, 234, 234, 234, 234, 234,
+ 229, 229, 228, 228, 227, 218, 217, 217,
+ 217, 217, 217, 216, 216, 216, 216, 216,
+ 215, 215, 215, 215, 214, 214, 214, 214,
+ 234, 234, 234, 234, 234, 234, 234, 229,
+ 229, 228, 228, 227, 227, 227, 217, 217,
+ 217, 217, 217, 216, 216, 216, 216, 216,
+ 215, 215, 215, 215, 214, 214, 214, 214,
+ 234, 234, 234, 234, 234, 234, 229, 229,
+ 228, 228, 227, 227, 227, 226, 217, 217,
+ 217, 217, 217, 216, 216, 216, 216, 215,
+ 215, 215, 215, 215, 214, 214, 214, 214,
+ 234, 234, 234, 234, 234, 229, 229, 228,
+ 228, 227, 227, 227, 226, 226, 226, 217,
+ 217, 217, 217, 216, 216, 216, 216, 215,
+ 215, 215, 215, 215, 214, 214, 214, 214,
+ 234, 234, 234, 234, 172, 229, 228, 228,
+ 227, 227, 227, 226, 226, 226, 225, 217,
+ 217, 217, 216, 216, 216, 216, 216, 215,
+ 215, 215, 215, 215, 214, 214, 214, 214,
+ 172, 172, 172, 172, 172, 172, 228, 227,
+ 227, 227, 226, 226, 226, 225, 225, 225,
+ 217, 217, 216, 216, 216, 216, 216, 215,
+ 215, 215, 215, 215, 214, 214, 214, 214,
+ 172, 172, 172, 172, 172, 172, 172, 227,
+ 227, 226, 226, 226, 225, 225, 225, 224,
+ 224, 217, 216, 216, 216, 216, 216, 215,
+ 215, 215, 215, 215, 214, 214, 214, 214,
+ 172, 172, 172, 172, 172, 172, 172, 172,
+ 226, 226, 226, 225, 225, 225, 224, 224,
+ 224, 217, 216, 216, 216, 216, 216, 215,
+ 215, 215, 215, 214, 214, 214, 214, 214,
+ 172, 172, 172, 172, 172, 172, 172, 172,
+ 226, 226, 225, 225, 225, 224, 224, 224,
+ 224, 224, 216, 216, 216, 216, 215, 215,
+ 215, 215, 215, 214, 214, 214, 214, 214,
+ 171, 171, 171, 171, 171, 171, 171, 172,
+ 226, 225, 225, 225, 224, 224, 224, 224,
+ 224, 224, 224, 216, 216, 216, 215, 215,
+ 215, 215, 215, 214, 214, 214, 214, 214,
+ 171, 171, 171, 171, 171, 171, 171, 171,
+ 198, 198, 225, 197, 197, 224, 224, 224,
+ 196, 196, 196, 195, 216, 216, 215, 215,
+ 215, 215, 215, 214, 214, 214, 214, 214,
+ 171, 171, 171, 171, 171, 171, 171, 171,
+ 198, 198, 197, 197, 197, 197, 197, 196,
+ 196, 196, 196, 195, 194, 11, 11, 11,
+ 215, 215, 215, 214, 214, 214, 214, 214,
+ 171, 171, 171, 171, 171, 171, 171, 198,
+ 198, 197, 197, 197, 197, 197, 196, 196,
+ 196, 196, 195, 195, 194, 11, 11, 11,
+ 11, 11, 11, 214, 214, 214, 48, 48,
+ 171, 171, 171, 171, 171, 171, 171, 198,
+ 197, 197, 197, 197, 197, 196, 196, 196,
+ 196, 195, 195, 194, 194, 11, 11, 11,
+ 11, 11, 11, 10, 48, 48, 48, 48,
+ 171, 171, 171, 171, 171, 171, 171, 198,
+ 197, 197, 197, 197, 197, 196, 196, 196,
+ 195, 195, 195, 194, 194, 11, 11, 11,
+ 11, 11, 10, 10, 10, 48, 48, 48,
+ 170, 171, 171, 171, 171, 171, 198, 197,
+ 197, 197, 197, 197, 196, 196, 196, 195,
+ 195, 195, 194, 194, 194, 194, 11, 11,
+ 10, 10, 10, 10, 10, 48, 48, 48,
+ 170, 170, 170, 171, 171, 169, 197, 197,
+ 197, 197, 197, 196, 196, 196, 195, 195,
+ 195, 194, 194, 194, 194, 193, 11, 10,
+ 10, 10, 10, 10, 10, 10, 48, 48,
+ 187, 187, 187, 187, 169, 169, 169, 197,
+ 197, 197, 196, 196, 196, 196, 195, 195,
+ 195, 194, 194, 194, 193, 193, 193, 10,
+ 10, 10, 10, 10, 10, 10, 48, 48,
+ 187, 187, 187, 187, 187, 187, 169, 197,
+ 197, 196, 196, 196, 196, 195, 195, 195,
+ 194, 194, 194, 194, 193, 193, 193, 10,
+ 10, 10, 10, 10, 10, 10, 10, 48,
+ 187, 187, 187, 187, 186, 186, 186, 167,
+ 197, 196, 196, 196, 195, 195, 195, 195,
+ 194, 194, 194, 193, 193, 193, 192, 10,
+ 10, 10, 10, 10, 10, 10, 80, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 167, 196, 196, 195, 195, 195, 195, 194,
+ 194, 194, 193, 193, 193, 192, 192, 10,
+ 10, 10, 10, 10, 22, 22, 22, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 196, 195, 195, 195, 195, 194, 194,
+ 194, 193, 193, 193, 129, 192, 192, 128,
+ 10, 23, 23, 22, 22, 22, 21, 9,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 166, 195, 195, 195, 195, 194, 194,
+ 193, 193, 193, 145, 145, 192, 128, 128,
+ 23, 23, 22, 22, 22, 21, 21, 21,
+ 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 182, 181, 195, 195, 147, 147, 193,
+ 193, 145, 145, 145, 145, 128, 128, 128,
+ 23, 22, 22, 22, 21, 21, 21, 20,
+ 186, 186, 186, 186, 186, 185, 185, 185,
+ 182, 182, 181, 181, 179, 147, 147, 145,
+ 145, 145, 145, 145, 144, 144, 144, 144,
+ 22, 22, 22, 21, 21, 21, 20, 20,
+ 185, 185, 185, 185, 185, 185, 185, 185,
+ 182, 182, 181, 181, 179, 179, 179, 145,
+ 145, 145, 145, 145, 144, 144, 144, 144,
+ 22, 22, 21, 21, 21, 20, 20, 19,
+ 185, 185, 185, 185, 185, 185, 185, 182,
+ 182, 182, 181, 181, 179, 179, 179, 177,
+ 145, 145, 145, 144, 144, 144, 144, 8,
+ 8, 21, 21, 21, 20, 20, 19, 19,
+ 185, 185, 185, 185, 185, 185, 185, 182,
+ 182, 182, 181, 181, 179, 179, 179, 177,
+ 177, 176, 144, 144, 144, 144, 8, 8,
+ 8, 21, 21, 20, 20, 19, 19, 19,
+ 185, 185, 185, 185, 185, 185, 183, 182,
+ 182, 182, 181, 181, 179, 179, 179, 177,
+ 177, 176, 176, 176, 8, 8, 8, 8,
+ 8, 8, 20, 20, 19, 19, 19, 18,
+ 185, 185, 185, 185, 185, 183, 183, 182,
+ 182, 182, 181, 181, 179, 179, 179, 177,
+ 177, 176, 176, 176, 8, 8, 8, 8,
+ 8, 8, 20, 19, 19, 19, 18, 18,
+ 184, 184, 184, 184, 183, 183, 183, 182,
+ 182, 182, 181, 181, 179, 179, 179, 177,
+ 177, 176, 176, 176, 176, 8, 8, 8,
+ 8, 8, 19, 19, 19, 18, 18, 18,
+ 233, 233, 233, 233, 233, 233, 233, 233,
+ 229, 229, 228, 228, 228, 227, 217, 217,
+ 217, 217, 216, 216, 216, 216, 216, 215,
+ 215, 215, 215, 214, 214, 214, 214, 253,
+ 233, 233, 233, 233, 233, 233, 233, 229,
+ 229, 228, 228, 228, 227, 227, 217, 217,
+ 217, 217, 216, 216, 216, 216, 216, 215,
+ 215, 215, 215, 214, 214, 214, 214, 214,
+ 233, 233, 233, 233, 233, 233, 229, 229,
+ 228, 228, 228, 227, 227, 227, 217, 217,
+ 217, 217, 216, 216, 216, 216, 216, 215,
+ 215, 215, 215, 214, 214, 214, 214, 214,
+ 233, 233, 233, 233, 233, 229, 229, 228,
+ 228, 228, 227, 227, 227, 226, 226, 217,
+ 217, 217, 216, 216, 216, 216, 215, 215,
+ 215, 215, 215, 214, 214, 214, 214, 214,
+ 233, 233, 233, 233, 229, 229, 228, 228,
+ 228, 227, 227, 227, 226, 226, 226, 217,
+ 217, 217, 216, 216, 216, 216, 215, 215,
+ 215, 215, 215, 214, 214, 214, 214, 214,
+ 233, 233, 233, 229, 229, 228, 228, 228,
+ 227, 227, 227, 226, 226, 226, 225, 225,
+ 217, 216, 216, 216, 216, 216, 215, 215,
+ 215, 215, 215, 214, 214, 214, 214, 214,
+ 233, 172, 172, 229, 228, 228, 228, 227,
+ 227, 227, 226, 226, 226, 225, 225, 225,
+ 224, 216, 216, 216, 216, 216, 215, 215,
+ 215, 215, 215, 214, 214, 214, 214, 214,
+ 172, 172, 172, 172, 172, 228, 227, 227,
+ 227, 226, 226, 226, 225, 225, 225, 224,
+ 224, 216, 216, 216, 216, 216, 215, 215,
+ 215, 215, 215, 214, 214, 214, 214, 214,
+ 171, 171, 172, 172, 172, 172, 227, 227,
+ 226, 226, 226, 225, 225, 225, 224, 224,
+ 224, 224, 216, 216, 216, 216, 215, 215,
+ 215, 215, 214, 214, 214, 214, 214, 214,
+ 171, 171, 171, 171, 171, 171, 171, 226,
+ 226, 226, 225, 225, 225, 224, 224, 224,
+ 224, 224, 224, 216, 216, 215, 215, 215,
+ 215, 215, 214, 214, 214, 214, 214, 214,
+ 171, 171, 171, 171, 171, 171, 171, 226,
+ 226, 225, 225, 225, 224, 224, 224, 224,
+ 224, 224, 224, 216, 216, 215, 215, 215,
+ 215, 215, 214, 214, 214, 214, 214, 214,
+ 171, 171, 171, 171, 171, 171, 171, 171,
+ 225, 225, 225, 224, 224, 224, 224, 224,
+ 224, 224, 224, 224, 216, 215, 215, 215,
+ 215, 215, 214, 214, 214, 214, 214, 214,
+ 171, 171, 171, 171, 171, 171, 171, 171,
+ 225, 225, 224, 224, 224, 224, 224, 224,
+ 224, 196, 195, 195, 194, 194, 11, 215,
+ 215, 215, 214, 214, 214, 214, 214, 214,
+ 171, 171, 171, 171, 171, 171, 171, 171,
+ 198, 197, 197, 197, 197, 197, 196, 196,
+ 196, 195, 195, 194, 194, 194, 11, 11,
+ 11, 11, 214, 214, 214, 214, 214, 214,
+ 171, 171, 171, 171, 171, 171, 171, 171,
+ 197, 197, 197, 197, 197, 196, 196, 196,
+ 196, 195, 195, 194, 194, 194, 11, 11,
+ 11, 11, 10, 10, 10, 48, 48, 48,
+ 170, 170, 171, 171, 171, 171, 171, 197,
+ 197, 197, 197, 197, 196, 196, 196, 196,
+ 195, 195, 194, 194, 194, 194, 11, 11,
+ 11, 10, 10, 10, 10, 48, 48, 48,
+ 170, 170, 170, 170, 171, 171, 169, 197,
+ 197, 197, 197, 196, 196, 196, 196, 195,
+ 195, 195, 194, 194, 194, 194, 193, 10,
+ 10, 10, 10, 10, 10, 10, 48, 48,
+ 170, 170, 170, 170, 169, 169, 169, 197,
+ 197, 197, 197, 196, 196, 196, 195, 195,
+ 195, 194, 194, 194, 194, 193, 193, 10,
+ 10, 10, 10, 10, 10, 10, 48, 48,
+ 170, 168, 168, 168, 169, 169, 169, 169,
+ 197, 197, 196, 196, 196, 195, 195, 195,
+ 194, 194, 194, 194, 193, 193, 193, 10,
+ 10, 10, 10, 10, 10, 10, 10, 48,
+ 168, 168, 168, 168, 169, 169, 169, 169,
+ 197, 196, 196, 196, 195, 195, 195, 195,
+ 194, 194, 194, 193, 193, 193, 193, 192,
+ 10, 10, 10, 10, 10, 10, 10, 48,
+ 186, 186, 186, 168, 168, 167, 167, 167,
+ 167, 196, 196, 196, 195, 195, 195, 194,
+ 194, 194, 193, 193, 193, 193, 192, 192,
+ 10, 10, 10, 10, 10, 22, 22, 21,
+ 186, 186, 186, 186, 186, 167, 167, 167,
+ 167, 167, 196, 195, 195, 195, 195, 194,
+ 194, 193, 193, 193, 193, 192, 192, 192,
+ 192, 10, 10, 22, 22, 22, 21, 21,
+ 186, 186, 186, 186, 186, 186, 167, 167,
+ 167, 167, 195, 195, 195, 195, 194, 194,
+ 194, 193, 193, 193, 192, 192, 192, 192,
+ 192, 23, 22, 22, 22, 21, 21, 21,
+ 186, 186, 186, 186, 186, 186, 186, 166,
+ 166, 166, 166, 195, 195, 194, 194, 194,
+ 193, 193, 193, 193, 192, 192, 192, 128,
+ 128, 22, 22, 22, 21, 21, 21, 20,
+ 186, 186, 186, 186, 186, 185, 185, 166,
+ 166, 166, 181, 181, 195, 194, 194, 193,
+ 193, 193, 145, 145, 192, 128, 128, 128,
+ 22, 22, 22, 21, 21, 21, 20, 20,
+ 185, 185, 185, 185, 185, 185, 185, 185,
+ 182, 182, 181, 181, 179, 179, 163, 193,
+ 145, 145, 145, 145, 144, 144, 144, 144,
+ 22, 22, 21, 21, 21, 20, 20, 19,
+ 185, 185, 185, 185, 185, 185, 185, 182,
+ 182, 182, 181, 181, 179, 179, 163, 163,
+ 145, 145, 145, 144, 144, 144, 144, 144,
+ 22, 21, 21, 21, 20, 20, 19, 19,
+ 185, 185, 185, 185, 185, 185, 185, 182,
+ 182, 182, 181, 181, 179, 179, 179, 177,
+ 177, 176, 144, 144, 144, 144, 144, 144,
+ 21, 21, 21, 20, 20, 19, 19, 19,
+ 185, 185, 185, 185, 185, 185, 183, 182,
+ 182, 182, 181, 181, 179, 179, 179, 177,
+ 177, 176, 176, 144, 144, 144, 144, 8,
+ 21, 21, 20, 20, 19, 19, 19, 18,
+ 185, 185, 185, 185, 185, 183, 183, 182,
+ 182, 182, 181, 181, 179, 179, 179, 177,
+ 177, 176, 176, 176, 176, 8, 8, 8,
+ 8, 20, 20, 19, 19, 19, 18, 18,
+ 184, 184, 184, 184, 183, 183, 183, 182,
+ 182, 182, 181, 181, 179, 179, 179, 177,
+ 177, 176, 176, 176, 176, 8, 8, 8,
+ 8, 20, 19, 19, 19, 18, 18, 18,
+ 184, 184, 184, 184, 183, 183, 183, 182,
+ 182, 181, 181, 181, 179, 179, 177, 177,
+ 177, 176, 176, 176, 176, 160, 160, 8,
+ 8, 19, 19, 19, 18, 18, 18, 17,
+ 233, 232, 232, 232, 232, 232, 232, 229,
+ 229, 229, 228, 228, 228, 227, 217, 217,
+ 217, 216, 216, 216, 216, 216, 215, 215,
+ 215, 215, 214, 214, 214, 214, 253, 253,
+ 232, 232, 232, 232, 232, 232, 229, 229,
+ 229, 228, 228, 228, 227, 227, 227, 217,
+ 217, 216, 216, 216, 216, 216, 215, 215,
+ 215, 215, 214, 214, 214, 214, 214, 253,
+ 232, 232, 232, 232, 232, 229, 229, 229,
+ 228, 228, 228, 227, 227, 227, 226, 217,
+ 217, 216, 216, 216, 216, 216, 215, 215,
+ 215, 215, 214, 214, 214, 214, 214, 214,
+ 232, 232, 232, 232, 229, 229, 229, 228,
+ 228, 228, 227, 227, 227, 226, 226, 226,
+ 217, 216, 216, 216, 216, 215, 215, 215,
+ 215, 215, 214, 214, 214, 214, 214, 214,
+ 232, 232, 232, 229, 229, 229, 228, 228,
+ 228, 227, 227, 227, 226, 226, 226, 225,
+ 217, 216, 216, 216, 216, 215, 215, 215,
+ 215, 215, 214, 214, 214, 214, 214, 214,
+ 232, 232, 229, 229, 229, 228, 228, 228,
+ 227, 227, 227, 226, 226, 226, 225, 225,
+ 225, 216, 216, 216, 216, 215, 215, 215,
+ 215, 215, 214, 214, 214, 214, 214, 214,
+ 232, 229, 229, 229, 228, 228, 228, 227,
+ 227, 227, 226, 226, 226, 225, 225, 225,
+ 224, 216, 216, 216, 216, 215, 215, 215,
+ 215, 215, 214, 214, 214, 214, 214, 214,
+ 171, 171, 229, 228, 228, 228, 227, 227,
+ 227, 226, 226, 226, 225, 225, 225, 224,
+ 224, 224, 216, 216, 216, 215, 215, 215,
+ 215, 215, 214, 214, 214, 214, 214, 214,
+ 171, 171, 171, 171, 171, 227, 227, 227,
+ 226, 226, 226, 225, 225, 225, 224, 224,
+ 224, 224, 224, 216, 216, 215, 215, 215,
+ 215, 214, 214, 214, 214, 214, 214, 214,
+ 171, 171, 171, 171, 171, 171, 227, 226,
+ 226, 226, 225, 225, 225, 224, 224, 224,
+ 224, 224, 224, 216, 215, 215, 215, 215,
+ 215, 214, 214, 214, 214, 214, 214, 214,
+ 171, 171, 171, 171, 171, 171, 171, 226,
+ 226, 225, 225, 225, 224, 224, 224, 224,
+ 224, 224, 224, 224, 215, 215, 215, 215,
+ 215, 214, 214, 214, 214, 214, 214, 214,
+ 171, 171, 171, 171, 171, 171, 171, 226,
+ 225, 225, 225, 224, 224, 224, 224, 224,
+ 224, 224, 224, 224, 224, 215, 215, 215,
+ 215, 214, 214, 214, 214, 214, 214, 214,
+ 171, 171, 171, 171, 171, 171, 171, 225,
+ 225, 225, 224, 224, 224, 224, 224, 224,
+ 224, 224, 224, 195, 194, 194, 215, 215,
+ 215, 214, 214, 214, 214, 214, 214, 214,
+ 170, 171, 171, 171, 171, 171, 171, 171,
+ 225, 224, 224, 224, 224, 224, 224, 224,
+ 224, 195, 195, 194, 194, 194, 194, 11,
+ 11, 214, 214, 214, 214, 214, 214, 214,
+ 170, 170, 170, 171, 171, 171, 171, 171,
+ 224, 224, 224, 224, 224, 224, 224, 196,
+ 195, 195, 194, 194, 194, 194, 194, 11,
+ 11, 10, 10, 10, 10, 214, 214, 214,
+ 170, 170, 170, 170, 170, 171, 171, 169,
+ 197, 197, 197, 197, 196, 196, 196, 195,
+ 195, 195, 194, 194, 194, 194, 193, 193,
+ 10, 10, 10, 10, 10, 10, 48, 48,
+ 170, 170, 170, 170, 170, 169, 169, 169,
+ 197, 197, 197, 196, 196, 196, 196, 195,
+ 195, 194, 194, 194, 194, 193, 193, 193,
+ 10, 10, 10, 10, 10, 10, 10, 48,
+ 170, 170, 170, 169, 169, 169, 169, 169,
+ 169, 197, 196, 196, 196, 196, 195, 195,
+ 195, 194, 194, 194, 193, 193, 193, 193,
+ 10, 10, 10, 10, 10, 10, 10, 48,
+ 168, 168, 168, 168, 169, 169, 169, 169,
+ 169, 196, 196, 196, 196, 195, 195, 195,
+ 194, 194, 194, 194, 193, 193, 193, 192,
+ 192, 10, 10, 10, 10, 10, 10, 10,
+ 168, 168, 168, 168, 169, 169, 169, 169,
+ 167, 196, 196, 196, 195, 195, 195, 194,
+ 194, 194, 194, 193, 193, 193, 192, 192,
+ 192, 10, 10, 10, 10, 10, 22, 21,
+ 168, 168, 168, 168, 168, 167, 167, 167,
+ 167, 167, 196, 195, 195, 195, 195, 194,
+ 194, 194, 193, 193, 193, 193, 192, 192,
+ 192, 192, 10, 10, 22, 22, 21, 21,
+ 168, 168, 168, 168, 167, 167, 167, 167,
+ 167, 167, 167, 195, 195, 195, 194, 194,
+ 194, 193, 193, 193, 193, 192, 192, 192,
+ 192, 192, 22, 22, 22, 21, 21, 21,
+ 186, 186, 186, 186, 167, 167, 167, 167,
+ 167, 167, 167, 195, 195, 195, 194, 194,
+ 193, 193, 193, 193, 192, 192, 192, 192,
+ 192, 192, 22, 22, 21, 21, 21, 20,
+ 186, 186, 186, 186, 166, 166, 166, 166,
+ 166, 166, 166, 195, 195, 194, 194, 193,
+ 193, 193, 193, 192, 192, 192, 192, 192,
+ 128, 22, 22, 21, 21, 21, 20, 20,
+ 185, 185, 185, 185, 185, 166, 166, 166,
+ 166, 166, 166, 181, 163, 163, 193, 193,
+ 193, 193, 193, 192, 192, 192, 192, 128,
+ 128, 22, 21, 21, 21, 20, 20, 19,
+ 185, 185, 185, 185, 185, 185, 185, 164,
+ 182, 182, 181, 181, 179, 163, 163, 163,
+ 193, 145, 145, 192, 144, 144, 144, 144,
+ 22, 21, 21, 21, 20, 20, 19, 19,
+ 185, 185, 185, 185, 185, 185, 185, 182,
+ 182, 182, 181, 181, 179, 163, 163, 163,
+ 163, 145, 145, 144, 144, 144, 144, 144,
+ 21, 21, 21, 20, 20, 19, 19, 19,
+ 185, 185, 185, 185, 185, 185, 183, 182,
+ 182, 182, 181, 181, 179, 179, 163, 163,
+ 177, 176, 176, 144, 144, 144, 144, 144,
+ 21, 21, 20, 20, 19, 19, 19, 18,
+ 185, 185, 185, 185, 185, 183, 183, 182,
+ 182, 182, 181, 181, 179, 179, 179, 177,
+ 177, 176, 176, 176, 144, 144, 144, 21,
+ 21, 20, 20, 19, 19, 19, 18, 18,
+ 184, 184, 184, 184, 183, 183, 183, 182,
+ 182, 182, 181, 181, 179, 179, 179, 177,
+ 177, 176, 176, 176, 176, 176, 8, 8,
+ 20, 20, 19, 19, 19, 18, 18, 18,
+ 184, 184, 184, 184, 183, 183, 183, 182,
+ 182, 181, 181, 181, 179, 179, 177, 177,
+ 177, 176, 176, 176, 176, 160, 160, 160,
+ 20, 19, 19, 19, 18, 18, 18, 17,
+ 184, 184, 184, 184, 183, 183, 183, 182,
+ 182, 181, 181, 181, 179, 179, 177, 177,
+ 177, 176, 176, 176, 176, 160, 160, 160,
+ 160, 19, 19, 18, 18, 18, 17, 17,
+ 232, 232, 232, 232, 232, 230, 230, 229,
+ 229, 229, 228, 228, 228, 227, 227, 217,
+ 216, 216, 216, 216, 216, 215, 215, 215,
+ 215, 214, 214, 214, 214, 253, 253, 253,
+ 232, 232, 232, 232, 230, 230, 229, 229,
+ 229, 228, 228, 228, 227, 227, 227, 226,
+ 216, 216, 216, 216, 216, 215, 215, 215,
+ 215, 214, 214, 214, 214, 214, 253, 253,
+ 232, 232, 232, 230, 230, 229, 229, 229,
+ 228, 228, 228, 227, 227, 227, 226, 226,
+ 216, 216, 216, 216, 216, 215, 215, 215,
+ 215, 214, 214, 214, 214, 214, 214, 253,
+ 232, 232, 230, 230, 229, 229, 229, 228,
+ 228, 228, 227, 227, 227, 226, 226, 226,
+ 216, 216, 216, 216, 215, 215, 215, 215,
+ 215, 214, 214, 214, 214, 214, 214, 214,
+ 232, 230, 230, 229, 229, 229, 228, 228,
+ 228, 227, 227, 227, 226, 226, 226, 225,
+ 225, 216, 216, 216, 215, 215, 215, 215,
+ 215, 214, 214, 214, 214, 214, 214, 214,
+ 230, 230, 229, 229, 229, 228, 228, 228,
+ 227, 227, 227, 226, 226, 226, 225, 225,
+ 225, 216, 216, 216, 215, 215, 215, 215,
+ 215, 214, 214, 214, 214, 214, 214, 214,
+ 230, 229, 229, 229, 228, 228, 228, 227,
+ 227, 227, 226, 226, 226, 225, 225, 225,
+ 224, 224, 216, 216, 215, 215, 215, 215,
+ 215, 214, 214, 214, 214, 214, 214, 214,
+ 229, 229, 229, 228, 228, 228, 227, 227,
+ 227, 226, 226, 226, 225, 225, 225, 224,
+ 224, 224, 224, 216, 215, 215, 215, 215,
+ 215, 214, 214, 214, 214, 214, 214, 214,
+ 171, 171, 171, 228, 228, 227, 227, 227,
+ 226, 226, 226, 225, 225, 225, 224, 224,
+ 224, 224, 224, 216, 215, 215, 215, 215,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 171, 171, 171, 171, 171, 227, 227, 226,
+ 226, 226, 225, 225, 225, 224, 224, 224,
+ 224, 224, 224, 224, 215, 215, 215, 215,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 171, 171, 171, 171, 171, 171, 226, 226,
+ 226, 225, 225, 225, 224, 224, 224, 224,
+ 224, 224, 224, 224, 224, 215, 215, 215,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 171, 171, 171, 171, 171, 171, 226, 226,
+ 225, 225, 225, 224, 224, 224, 224, 224,
+ 224, 224, 224, 224, 224, 215, 215, 215,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 170, 170, 171, 171, 171, 171, 171, 225,
+ 225, 225, 224, 224, 224, 224, 224, 224,
+ 224, 224, 224, 224, 194, 194, 215, 215,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 170, 170, 170, 170, 171, 171, 171, 225,
+ 225, 224, 224, 224, 224, 224, 224, 224,
+ 224, 224, 224, 194, 194, 194, 194, 194,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 170, 170, 170, 170, 170, 170, 170, 225,
+ 224, 224, 224, 224, 224, 224, 224, 224,
+ 224, 195, 194, 194, 194, 194, 194, 193,
+ 193, 10, 10, 10, 214, 214, 214, 214,
+ 170, 170, 170, 170, 170, 170, 169, 169,
+ 224, 224, 224, 224, 224, 224, 224, 195,
+ 195, 194, 194, 194, 194, 194, 193, 193,
+ 193, 10, 10, 10, 10, 10, 10, 48,
+ 170, 170, 170, 170, 169, 169, 169, 169,
+ 169, 224, 224, 224, 196, 196, 195, 195,
+ 195, 194, 194, 194, 194, 193, 193, 193,
+ 192, 10, 10, 10, 10, 10, 10, 48,
+ 170, 170, 168, 169, 169, 169, 169, 169,
+ 169, 169, 196, 196, 196, 195, 195, 195,
+ 194, 194, 194, 194, 193, 193, 193, 193,
+ 192, 192, 10, 10, 10, 10, 10, 10,
+ 168, 168, 168, 168, 169, 169, 169, 169,
+ 169, 169, 196, 196, 196, 195, 195, 195,
+ 194, 194, 194, 193, 193, 193, 193, 192,
+ 192, 192, 10, 10, 10, 10, 10, 21,
+ 168, 168, 168, 168, 169, 169, 169, 169,
+ 167, 167, 196, 196, 195, 195, 195, 194,
+ 194, 194, 193, 193, 193, 193, 192, 192,
+ 192, 192, 192, 10, 10, 22, 21, 21,
+ 168, 168, 168, 168, 168, 167, 167, 167,
+ 167, 167, 167, 195, 195, 195, 194, 194,
+ 194, 193, 193, 193, 193, 192, 192, 192,
+ 192, 192, 192, 22, 22, 21, 21, 21,
+ 168, 168, 168, 168, 167, 167, 167, 167,
+ 167, 167, 167, 195, 195, 195, 194, 194,
+ 194, 193, 193, 193, 193, 192, 192, 192,
+ 192, 192, 22, 22, 21, 21, 21, 20,
+ 165, 165, 165, 167, 167, 167, 167, 167,
+ 167, 167, 167, 167, 195, 194, 194, 194,
+ 193, 193, 193, 193, 192, 192, 192, 192,
+ 192, 192, 22, 21, 21, 21, 20, 20,
+ 165, 165, 165, 165, 166, 166, 166, 166,
+ 166, 166, 166, 166, 163, 194, 194, 193,
+ 193, 193, 193, 192, 192, 192, 192, 192,
+ 192, 22, 21, 21, 21, 20, 20, 19,
+ 165, 165, 165, 165, 165, 166, 166, 166,
+ 166, 166, 166, 181, 163, 163, 163, 193,
+ 193, 193, 192, 192, 192, 192, 192, 192,
+ 128, 21, 21, 21, 20, 20, 19, 19,
+ 185, 185, 185, 185, 165, 164, 164, 164,
+ 164, 182, 181, 181, 163, 163, 163, 163,
+ 163, 193, 192, 192, 192, 144, 144, 144,
+ 144, 21, 21, 20, 20, 19, 19, 19,
+ 185, 185, 185, 185, 185, 164, 164, 164,
+ 182, 182, 181, 181, 179, 163, 163, 163,
+ 163, 163, 176, 144, 144, 144, 144, 144,
+ 21, 21, 20, 20, 19, 19, 19, 18,
+ 185, 185, 185, 185, 185, 183, 183, 182,
+ 182, 182, 181, 181, 179, 163, 163, 163,
+ 163, 176, 176, 176, 144, 144, 144, 144,
+ 21, 20, 20, 19, 19, 19, 18, 18,
+ 184, 184, 184, 184, 183, 183, 183, 182,
+ 182, 182, 181, 181, 179, 179, 163, 163,
+ 177, 176, 176, 176, 176, 144, 144, 21,
+ 20, 20, 19, 19, 19, 18, 18, 18,
+ 184, 184, 184, 184, 183, 183, 183, 182,
+ 182, 181, 181, 181, 179, 179, 177, 177,
+ 177, 176, 176, 176, 176, 160, 160, 160,
+ 20, 19, 19, 19, 18, 18, 18, 17,
+ 184, 184, 184, 184, 183, 183, 183, 182,
+ 182, 181, 181, 181, 179, 179, 177, 177,
+ 177, 176, 176, 176, 176, 160, 160, 160,
+ 160, 19, 19, 18, 18, 18, 17, 17,
+ 184, 184, 184, 184, 183, 183, 183, 182,
+ 182, 181, 181, 181, 179, 179, 177, 177,
+ 177, 176, 176, 176, 176, 160, 160, 160,
+ 160, 19, 18, 18, 18, 17, 17, 17,
+ 249, 231, 231, 231, 230, 230, 230, 229,
+ 229, 229, 228, 228, 228, 227, 227, 227,
+ 216, 216, 216, 216, 215, 215, 215, 215,
+ 214, 214, 214, 214, 253, 253, 253, 253,
+ 231, 231, 231, 230, 230, 230, 229, 229,
+ 229, 228, 228, 228, 227, 227, 227, 226,
+ 216, 216, 216, 216, 215, 215, 215, 215,
+ 214, 214, 214, 214, 214, 253, 253, 253,
+ 231, 231, 230, 230, 230, 229, 229, 229,
+ 228, 228, 228, 227, 227, 227, 226, 226,
+ 226, 216, 216, 216, 215, 215, 215, 215,
+ 214, 214, 214, 214, 214, 214, 253, 253,
+ 231, 230, 230, 230, 229, 229, 229, 228,
+ 228, 228, 227, 227, 227, 226, 226, 226,
+ 225, 216, 216, 215, 215, 215, 215, 215,
+ 214, 214, 214, 214, 214, 214, 214, 253,
+ 230, 230, 230, 229, 229, 229, 228, 228,
+ 228, 227, 227, 227, 226, 226, 226, 225,
+ 225, 216, 216, 215, 215, 215, 215, 215,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 230, 230, 229, 229, 229, 228, 228, 228,
+ 227, 227, 227, 226, 226, 226, 225, 225,
+ 225, 224, 216, 215, 215, 215, 215, 215,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 230, 229, 229, 229, 228, 228, 228, 227,
+ 227, 227, 226, 226, 226, 225, 225, 225,
+ 224, 224, 224, 215, 215, 215, 215, 215,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 229, 229, 229, 228, 228, 228, 227, 227,
+ 227, 226, 226, 226, 225, 225, 225, 224,
+ 224, 224, 224, 215, 215, 215, 215, 215,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 171, 171, 228, 228, 228, 227, 227, 227,
+ 226, 226, 226, 225, 225, 225, 224, 224,
+ 224, 224, 224, 224, 215, 215, 215, 214,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 171, 171, 171, 171, 227, 227, 227, 226,
+ 226, 226, 225, 225, 225, 224, 224, 224,
+ 224, 224, 224, 224, 215, 215, 215, 214,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 170, 171, 171, 171, 171, 227, 226, 226,
+ 226, 225, 225, 225, 224, 224, 224, 224,
+ 224, 224, 224, 224, 224, 215, 215, 214,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 170, 170, 170, 171, 171, 171, 226, 226,
+ 225, 225, 225, 224, 224, 224, 224, 224,
+ 224, 224, 224, 224, 224, 215, 215, 214,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 170, 170, 170, 170, 170, 170, 226, 225,
+ 225, 225, 224, 224, 224, 224, 224, 224,
+ 224, 224, 224, 224, 224, 194, 215, 214,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 170, 170, 170, 170, 170, 170, 170, 225,
+ 225, 224, 224, 224, 224, 224, 224, 224,
+ 224, 224, 224, 224, 194, 194, 194, 193,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 170, 170, 170, 170, 170, 170, 170, 225,
+ 224, 224, 224, 224, 224, 224, 224, 224,
+ 224, 224, 194, 194, 194, 194, 193, 193,
+ 193, 10, 10, 214, 214, 214, 214, 214,
+ 170, 170, 170, 170, 170, 169, 169, 169,
+ 224, 224, 224, 224, 224, 224, 224, 224,
+ 224, 194, 194, 194, 194, 193, 193, 193,
+ 193, 192, 10, 10, 10, 10, 10, 214,
+ 170, 170, 170, 170, 169, 169, 169, 169,
+ 169, 224, 224, 224, 224, 224, 224, 195,
+ 194, 194, 194, 194, 194, 193, 193, 193,
+ 192, 192, 10, 10, 10, 10, 10, 10,
+ 170, 168, 168, 169, 169, 169, 169, 169,
+ 169, 169, 224, 224, 224, 195, 195, 195,
+ 194, 194, 194, 194, 193, 193, 193, 192,
+ 192, 192, 192, 10, 10, 10, 10, 10,
+ 168, 168, 168, 168, 169, 169, 169, 169,
+ 169, 169, 169, 196, 195, 195, 195, 194,
+ 194, 194, 194, 193, 193, 193, 193, 192,
+ 192, 192, 192, 10, 10, 10, 21, 21,
+ 168, 168, 168, 168, 169, 169, 169, 169,
+ 167, 167, 167, 195, 195, 195, 195, 194,
+ 194, 194, 193, 193, 193, 193, 192, 192,
+ 192, 192, 192, 192, 22, 21, 21, 21,
+ 168, 168, 168, 168, 168, 167, 167, 167,
+ 167, 167, 167, 167, 195, 195, 194, 194,
+ 194, 193, 193, 193, 193, 192, 192, 192,
+ 192, 192, 192, 22, 21, 21, 21, 20,
+ 168, 168, 168, 168, 167, 167, 167, 167,
+ 167, 167, 167, 167, 195, 194, 194, 194,
+ 193, 193, 193, 193, 192, 192, 192, 192,
+ 192, 192, 192, 21, 21, 21, 20, 20,
+ 165, 165, 165, 167, 167, 167, 167, 167,
+ 167, 167, 167, 167, 167, 194, 194, 193,
+ 193, 193, 193, 193, 192, 192, 192, 192,
+ 192, 192, 21, 21, 21, 20, 20, 19,
+ 165, 165, 165, 165, 166, 166, 166, 166,
+ 166, 166, 166, 166, 163, 163, 163, 193,
+ 193, 193, 193, 192, 192, 192, 192, 192,
+ 192, 192, 21, 21, 20, 20, 19, 19,
+ 165, 165, 165, 165, 165, 166, 166, 166,
+ 166, 166, 166, 181, 163, 163, 163, 163,
+ 193, 193, 192, 192, 192, 192, 192, 192,
+ 192, 21, 21, 20, 20, 19, 19, 19,
+ 165, 165, 165, 165, 165, 164, 164, 164,
+ 164, 164, 181, 181, 163, 163, 163, 163,
+ 163, 163, 192, 192, 192, 192, 192, 144,
+ 21, 21, 20, 20, 19, 19, 19, 18,
+ 165, 165, 165, 165, 164, 164, 164, 164,
+ 164, 182, 181, 181, 163, 163, 163, 163,
+ 163, 163, 176, 192, 144, 144, 144, 144,
+ 21, 20, 20, 19, 19, 19, 18, 18,
+ 184, 184, 184, 184, 164, 164, 164, 164,
+ 182, 182, 181, 181, 179, 163, 163, 163,
+ 163, 176, 176, 176, 176, 144, 144, 144,
+ 20, 20, 19, 19, 19, 18, 18, 18,
+ 184, 184, 184, 184, 183, 183, 183, 182,
+ 182, 181, 181, 181, 179, 163, 163, 163,
+ 163, 176, 176, 176, 176, 160, 160, 160,
+ 20, 19, 19, 19, 18, 18, 18, 17,
+ 184, 184, 184, 184, 183, 183, 183, 182,
+ 182, 181, 181, 181, 179, 179, 163, 177,
+ 177, 176, 176, 176, 176, 160, 160, 160,
+ 160, 19, 19, 18, 18, 18, 17, 17,
+ 184, 184, 184, 184, 183, 183, 183, 182,
+ 182, 181, 181, 181, 179, 179, 177, 177,
+ 177, 176, 176, 176, 176, 160, 160, 160,
+ 160, 19, 18, 18, 18, 17, 17, 17,
+ 251, 184, 184, 184, 183, 183, 183, 182,
+ 180, 180, 181, 178, 178, 179, 177, 177,
+ 177, 176, 176, 176, 160, 160, 160, 160,
+ 160, 160, 18, 18, 17, 17, 17, 16,
+ 249, 249, 231, 231, 230, 230, 230, 229,
+ 229, 229, 228, 228, 228, 227, 227, 227,
+ 216, 216, 216, 215, 215, 215, 215, 214,
+ 214, 214, 214, 253, 253, 253, 253, 253,
+ 249, 231, 231, 230, 230, 230, 229, 229,
+ 229, 228, 228, 228, 227, 227, 227, 226,
+ 226, 216, 216, 215, 215, 215, 215, 214,
+ 214, 214, 214, 214, 253, 253, 253, 253,
+ 231, 231, 230, 230, 230, 229, 229, 229,
+ 228, 228, 228, 227, 227, 227, 226, 226,
+ 226, 216, 216, 215, 215, 215, 215, 214,
+ 214, 214, 214, 214, 214, 253, 253, 253,
+ 231, 230, 230, 230, 229, 229, 229, 228,
+ 228, 228, 227, 227, 227, 226, 226, 226,
+ 225, 225, 215, 215, 215, 215, 215, 214,
+ 214, 214, 214, 214, 214, 214, 253, 253,
+ 230, 230, 230, 229, 229, 229, 228, 228,
+ 228, 227, 227, 227, 226, 226, 226, 225,
+ 225, 225, 215, 215, 215, 215, 215, 214,
+ 214, 214, 214, 214, 214, 214, 214, 253,
+ 230, 230, 229, 229, 229, 228, 228, 228,
+ 227, 227, 227, 226, 226, 226, 225, 225,
+ 225, 224, 224, 215, 215, 215, 215, 214,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 230, 229, 229, 229, 228, 228, 228, 227,
+ 227, 227, 226, 226, 226, 225, 225, 225,
+ 224, 224, 224, 215, 215, 215, 215, 214,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 229, 229, 229, 228, 228, 228, 227, 227,
+ 227, 226, 226, 226, 225, 225, 225, 224,
+ 224, 224, 224, 224, 215, 215, 215, 214,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 229, 229, 228, 228, 228, 227, 227, 227,
+ 226, 226, 226, 225, 225, 225, 224, 224,
+ 224, 224, 224, 224, 215, 215, 214, 214,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 170, 170, 171, 228, 227, 227, 227, 226,
+ 226, 226, 225, 225, 225, 224, 224, 224,
+ 224, 224, 224, 224, 224, 215, 214, 214,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 170, 170, 170, 170, 227, 227, 226, 226,
+ 226, 225, 225, 225, 224, 224, 224, 224,
+ 224, 224, 224, 224, 224, 215, 214, 214,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 170, 170, 170, 170, 170, 226, 226, 226,
+ 225, 225, 225, 224, 224, 224, 224, 224,
+ 224, 224, 224, 224, 224, 224, 214, 214,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 170, 170, 170, 170, 170, 170, 226, 225,
+ 225, 225, 224, 224, 224, 224, 224, 224,
+ 224, 224, 224, 224, 224, 224, 214, 214,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 170, 170, 170, 170, 170, 170, 170, 225,
+ 225, 224, 224, 224, 224, 224, 224, 224,
+ 224, 224, 224, 224, 224, 194, 194, 193,
+ 214, 214, 214, 214, 214, 214, 214, 214,
+ 170, 170, 170, 170, 170, 170, 169, 169,
+ 224, 224, 224, 224, 224, 224, 224, 224,
+ 224, 224, 224, 194, 194, 194, 193, 193,
+ 193, 192, 214, 214, 214, 214, 214, 214,
+ 170, 170, 170, 170, 170, 169, 169, 169,
+ 224, 224, 224, 224, 224, 224, 224, 224,
+ 224, 224, 194, 194, 194, 193, 193, 193,
+ 193, 192, 192, 10, 10, 10, 214, 214,
+ 170, 170, 170, 169, 169, 169, 169, 169,
+ 169, 224, 224, 224, 224, 224, 224, 224,
+ 194, 194, 194, 194, 193, 193, 193, 193,
+ 192, 192, 192, 192, 10, 10, 10, 10,
+ 168, 168, 168, 169, 169, 169, 169, 169,
+ 169, 169, 224, 224, 224, 224, 224, 194,
+ 194, 194, 194, 193, 193, 193, 193, 192,
+ 192, 192, 192, 192, 10, 10, 10, 21,
+ 168, 168, 168, 168, 169, 169, 169, 169,
+ 169, 169, 169, 224, 224, 195, 195, 194,
+ 194, 194, 193, 193, 193, 193, 192, 192,
+ 192, 192, 192, 192, 192, 21, 21, 21,
+ 168, 168, 168, 168, 169, 169, 169, 169,
+ 167, 167, 167, 167, 195, 195, 194, 194,
+ 194, 194, 193, 193, 193, 193, 192, 192,
+ 192, 192, 192, 192, 21, 21, 21, 20,
+ 168, 168, 168, 168, 168, 167, 167, 167,
+ 167, 167, 167, 167, 167, 195, 194, 194,
+ 194, 193, 193, 193, 193, 192, 192, 192,
+ 192, 192, 192, 192, 21, 21, 20, 20,
+ 168, 168, 168, 168, 167, 167, 167, 167,
+ 167, 167, 167, 167, 167, 194, 194, 194,
+ 193, 193, 193, 193, 192, 192, 192, 192,
+ 192, 192, 192, 21, 21, 20, 20, 19,
+ 165, 165, 165, 167, 167, 167, 167, 167,
+ 167, 167, 167, 167, 167, 194, 194, 193,
+ 193, 193, 193, 192, 192, 192, 192, 192,
+ 192, 192, 21, 21, 20, 20, 19, 19,
+ 165, 165, 165, 165, 166, 166, 166, 166,
+ 166, 166, 166, 166, 163, 163, 163, 163,
+ 193, 193, 193, 192, 192, 192, 192, 192,
+ 192, 192, 21, 20, 20, 19, 19, 19,
+ 165, 165, 165, 165, 165, 166, 166, 166,
+ 166, 166, 166, 166, 163, 163, 163, 163,
+ 163, 193, 192, 192, 192, 192, 192, 192,
+ 192, 21, 20, 20, 19, 19, 19, 18,
+ 165, 165, 165, 165, 165, 164, 164, 164,
+ 164, 164, 164, 163, 163, 163, 163, 163,
+ 163, 163, 192, 192, 192, 192, 192, 192,
+ 21, 20, 20, 19, 19, 19, 18, 18,
+ 165, 165, 165, 165, 164, 164, 164, 164,
+ 164, 164, 181, 181, 163, 163, 163, 163,
+ 163, 163, 176, 176, 192, 144, 144, 144,
+ 20, 20, 19, 19, 19, 18, 18, 18,
+ 165, 165, 165, 164, 164, 164, 164, 164,
+ 164, 181, 181, 181, 163, 163, 163, 163,
+ 163, 163, 176, 176, 176, 160, 160, 160,
+ 20, 19, 19, 19, 18, 18, 18, 17,
+ 184, 184, 184, 184, 164, 164, 164, 182,
+ 182, 181, 181, 181, 179, 163, 163, 163,
+ 163, 176, 176, 176, 176, 160, 160, 160,
+ 160, 19, 19, 18, 18, 18, 17, 17,
+ 184, 184, 184, 184, 183, 183, 183, 182,
+ 182, 181, 181, 181, 179, 163, 163, 163,
+ 177, 176, 176, 176, 176, 160, 160, 160,
+ 160, 19, 18, 18, 18, 17, 17, 17,
+ 251, 184, 184, 184, 183, 183, 183, 182,
+ 180, 180, 181, 178, 178, 162, 163, 177,
+ 177, 176, 176, 176, 160, 160, 160, 160,
+ 160, 160, 18, 18, 17, 17, 17, 16,
+ 251, 251, 184, 184, 183, 183, 183, 180,
+ 180, 180, 180, 178, 178, 162, 162, 177,
+ 161, 176, 176, 176, 160, 160, 160, 160,
+ 160, 160, 18, 17, 17, 17, 16, 16,
+};
diff --git a/Magic2/AlphaPalette.cpp b/Magic2/AlphaPalette.cpp
index 7f7c2e1..7142de0 100644
--- a/Magic2/AlphaPalette.cpp
+++ b/Magic2/AlphaPalette.cpp
@@ -1,260 +1,293 @@
-#include "stdafx.h"
-
-PALETTEENTRY standard_palette[256] = {
- { 0, 0, 0, 0 },
- { 128, 0, 0, 0 },
- { 0, 128, 0, 0 },
- { 128, 128, 0, 0 },
- { 0, 0, 128, 0 },
- { 128, 0, 128, 0 },
- { 0, 128, 128, 0 },
- { 192, 192, 192, 0 },
- { 192, 220, 192, 0 },
- { 166, 202, 240, 0 },
- { 186, 172, 189, 0 },
- { 167, 147, 172, 0 },
- { 143, 129, 148, 0 },
- { 122, 107, 126, 0 },
- { 100, 87, 104, 0 },
- { 55, 49, 57, 0 },
- { 247, 247, 247, 0 },
- { 240, 240, 240, 0 },
- { 232, 232, 232, 0 },
- { 225, 225, 225, 0 },
- { 217, 217, 217, 0 },
- { 210, 210, 210, 0 },
- { 202, 202, 202, 0 },
- { 195, 195, 195, 0 },
- { 188, 188, 188, 0 },
- { 180, 180, 180, 0 },
- { 173, 173, 173, 0 },
- { 165, 165, 165, 0 },
- { 158, 158, 158, 0 },
- { 150, 150, 150, 0 },
- { 143, 143, 143, 0 },
- { 136, 136, 136, 0 },
- { 128, 128, 128, 0 },
- { 121, 121, 121, 0 },
- { 113, 113, 113, 0 },
- { 106, 106, 106, 0 },
- { 98, 98, 98, 0 },
- { 91, 91, 91, 0 },
- { 83, 83, 83, 0 },
- { 76, 76, 76, 0 },
- { 69, 69, 69, 0 },
- { 61, 61, 61, 0 },
- { 54, 54, 54, 0 },
- { 42, 42, 42, 0 },
- { 31, 31, 31, 0 },
- { 21, 21, 21, 0 },
- { 10, 10, 10, 0 },
- { 5, 5, 5, 0 },
- { 149, 149, 234, 0 },
- { 134, 134, 227, 0 },
- { 117, 117, 223, 0 },
- { 104, 104, 215, 0 },
- { 87, 87, 210, 0 },
- { 70, 70, 206, 0 },
- { 49, 49, 185, 0 },
- { 45, 45, 168, 0 },
- { 36, 36, 134, 0 },
- { 31, 31, 118, 0 },
- { 27, 27, 101, 0 },
- { 22, 22, 84, 0 },
- { 18, 18, 67, 0 },
- { 13, 13, 51, 0 },
- { 9, 9, 34, 0 },
- { 4, 4, 17, 0 },
- { 159, 191, 223, 0 },
- { 143, 181, 218, 0 },
- { 128, 170, 213, 0 },
- { 112, 159, 207, 0 },
- { 96, 149, 202, 0 },
- { 85, 138, 191, 0 },
- { 69, 128, 186, 0 },
- { 68, 117, 166, 0 },
- { 62, 106, 151, 0 },
- { 55, 96, 136, 0 },
- { 53, 85, 117, 0 },
- { 47, 74, 102, 0 },
- { 43, 64, 85, 0 },
- { 35, 53, 71, 0 },
- { 29, 43, 56, 0 },
- { 21, 32, 43, 0 },
- { 184, 190, 199, 0 },
- { 171, 182, 190, 0 },
- { 159, 169, 181, 0 },
- { 148, 162, 171, 0 },
- { 136, 150, 162, 0 },
- { 123, 138, 153, 0 },
- { 112, 128, 143, 0 },
- { 102, 118, 132, 0 },
- { 92, 105, 120, 0 },
- { 86, 97, 105, 0 },
- { 77, 85, 94, 0 },
- { 67, 74, 82, 0 },
- { 57, 66, 70, 0 },
- { 48, 53, 58, 0 },
- { 38, 44, 47, 0 },
- { 29, 32, 35, 0 },
- { 154, 228, 154, 0 },
- { 137, 224, 137, 0 },
- { 120, 220, 120, 0 },
- { 112, 207, 112, 0 },
- { 96, 202, 96, 0 },
- { 80, 197, 80, 0 },
- { 64, 191, 64, 0 },
- { 58, 175, 77, 0 },
- { 53, 159, 67, 0 },
- { 48, 143, 63, 0 },
- { 43, 128, 64, 0 },
- { 37, 112, 56, 0 },
- { 32, 96, 50, 0 },
- { 27, 80, 43, 0 },
- { 21, 64, 33, 0 },
- { 16, 48, 27, 0 },
- { 186, 204, 179, 0 },
- { 175, 194, 167, 0 },
- { 164, 184, 156, 0 },
- { 152, 174, 145, 0 },
- { 140, 167, 131, 0 },
- { 130, 157, 119, 0 },
- { 119, 148, 107, 0 },
- { 111, 136, 98, 0 },
- { 99, 124, 88, 0 },
- { 88, 112, 80, 0 },
- { 81, 97, 73, 0 },
- { 70, 84, 65, 0 },
- { 61, 73, 54, 0 },
- { 51, 61, 46, 0 },
- { 40, 48, 37, 0 },
- { 30, 36, 28, 0 },
- { 209, 191, 173, 0 },
- { 202, 181, 159, 0 },
- { 191, 170, 149, 0 },
- { 183, 159, 136, 0 },
- { 175, 149, 122, 0 },
- { 167, 138, 109, 0 },
- { 159, 128, 96, 0 },
- { 147, 117, 87, 0 },
- { 129, 106, 84, 0 },
- { 116, 96, 75, 0 },
- { 103, 85, 67, 0 },
- { 90, 73, 58, 0 },
- { 78, 64, 50, 0 },
- { 64, 53, 43, 0 },
- { 51, 43, 34, 0 },
- { 38, 32, 26, 0 },
- { 209, 196, 173, 0 },
- { 202, 186, 159, 0 },
- { 191, 175, 149, 0 },
- { 183, 169, 136, 0 },
- { 175, 159, 122, 0 },
- { 167, 150, 109, 0 },
- { 159, 140, 96, 0 },
- { 143, 128, 90, 0 },
- { 131, 119, 82, 0 },
- { 116, 106, 75, 0 },
- { 103, 95, 67, 0 },
- { 90, 83, 58, 0 },
- { 78, 70, 50, 0 },
- { 64, 60, 43, 0 },
- { 51, 48, 34, 0 },
- { 38, 36, 26, 0 },
- { 255, 255, 170, 0 },
- { 255, 255, 128, 0 },
- { 255, 244, 106, 0 },
- { 249, 232, 113, 0 },
- { 255, 213, 43, 0 },
- { 255, 197, 21, 0 },
- { 255, 186, 43, 0 },
- { 255, 175, 43, 0 },
- { 255, 150, 21, 0 },
- { 255, 143, 32, 0 },
- { 244, 111, 11, 0 },
- { 215, 92, 19, 0 },
- { 190, 72, 22, 0 },
- { 168, 60, 23, 0 },
- { 146, 39, 24, 0 },
- { 128, 27, 21, 0 },
- { 244, 244, 138, 0 },
- { 242, 242, 119, 0 },
- { 248, 248, 92, 0 },
- { 240, 240, 100, 0 },
- { 247, 247, 72, 0 },
- { 239, 239, 80, 0 },
- { 237, 237, 61, 0 },
- { 236, 236, 40, 0 },
- { 235, 235, 20, 0 },
- { 215, 215, 19, 0 },
- { 194, 194, 18, 0 },
- { 175, 175, 16, 0 },
- { 156, 156, 14, 0 },
- { 136, 136, 13, 0 },
- { 117, 117, 11, 0 },
- { 98, 98, 9, 0 },
- { 215, 183, 168, 0 },
- { 211, 170, 150, 0 },
- { 205, 157, 135, 0 },
- { 199, 148, 120, 0 },
- { 193, 135, 104, 0 },
- { 187, 123, 89, 0 },
- { 174, 109, 70, 0 },
- { 151, 96, 62, 0 },
- { 128, 83, 53, 0 },
- { 105, 68, 44, 0 },
- { 143, 239, 239, 0 },
- { 124, 237, 237, 0 },
- { 106, 234, 234, 0 },
- { 87, 232, 232, 0 },
- { 70, 227, 227, 0 },
- { 47, 230, 230, 0 },
- { 32, 223, 223, 0 },
- { 29, 205, 205, 0 },
- { 26, 176, 176, 0 },
- { 20, 150, 150, 0 },
- { 17, 121, 121, 0 },
- { 13, 94, 94, 0 },
- { 223, 32, 223, 0 },
- { 204, 30, 204, 0 },
- { 186, 27, 186, 0 },
- { 168, 23, 168, 0 },
- { 149, 21, 149, 0 },
- { 131, 18, 131, 0 },
- { 112, 16, 112, 0 },
- { 94, 13, 94, 0 },
- { 74, 11, 74, 0 },
- { 56, 7, 56, 0 },
- { 249, 91, 91, 0 },
- { 248, 80, 80, 0 },
- { 247, 68, 68, 0 },
- { 247, 55, 55, 0 },
- { 247, 43, 43, 0 },
- { 245, 31, 31, 0 },
- { 244, 19, 19, 0 },
- { 240, 11, 11, 0 },
- { 228, 10, 10, 0 },
- { 217, 9, 9, 0 },
- { 204, 9, 9, 0 },
- { 192, 7, 7, 0 },
- { 180, 7, 7, 0 },
- { 168, 6, 6, 0 },
- { 156, 5, 5, 0 },
- { 145, 4, 4, 0 },
- { 131, 5, 5, 0 },
- { 118, 5, 5, 0 },
- { 106, 4, 4, 0 },
- { 94, 4, 4, 0 },
- { 80, 5, 5, 0 },
- { 66, 6, 6, 0 },
- { 53, 6, 6, 0 },
- { 41, 5, 5, 0 },
- { 128, 128, 128, 0 },
- { 255, 0, 0, 0 },
- { 0, 255, 0, 0 },
- { 255, 255, 0, 0 },
- { 0, 0, 255, 0 },
- { 255, 0, 255, 0 },
- { 0, 255, 255, 0 },
- { 255, 255, 255, 0 },
-};
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: AlphaPalette.cpp
+ AUTHOR: John DiCamillo
+*/
+
+#include "stdafx.h"
+
+PALETTEENTRY standard_palette[256] = {
+ { 0, 0, 0, 0 },
+ { 128, 0, 0, 0 },
+ { 0, 128, 0, 0 },
+ { 128, 128, 0, 0 },
+ { 0, 0, 128, 0 },
+ { 128, 0, 128, 0 },
+ { 0, 128, 128, 0 },
+ { 192, 192, 192, 0 },
+ { 192, 220, 192, 0 },
+ { 166, 202, 240, 0 },
+ { 186, 172, 189, 0 },
+ { 167, 147, 172, 0 },
+ { 143, 129, 148, 0 },
+ { 122, 107, 126, 0 },
+ { 100, 87, 104, 0 },
+ { 55, 49, 57, 0 },
+ { 247, 247, 247, 0 },
+ { 240, 240, 240, 0 },
+ { 232, 232, 232, 0 },
+ { 225, 225, 225, 0 },
+ { 217, 217, 217, 0 },
+ { 210, 210, 210, 0 },
+ { 202, 202, 202, 0 },
+ { 195, 195, 195, 0 },
+ { 188, 188, 188, 0 },
+ { 180, 180, 180, 0 },
+ { 173, 173, 173, 0 },
+ { 165, 165, 165, 0 },
+ { 158, 158, 158, 0 },
+ { 150, 150, 150, 0 },
+ { 143, 143, 143, 0 },
+ { 136, 136, 136, 0 },
+ { 128, 128, 128, 0 },
+ { 121, 121, 121, 0 },
+ { 113, 113, 113, 0 },
+ { 106, 106, 106, 0 },
+ { 98, 98, 98, 0 },
+ { 91, 91, 91, 0 },
+ { 83, 83, 83, 0 },
+ { 76, 76, 76, 0 },
+ { 69, 69, 69, 0 },
+ { 61, 61, 61, 0 },
+ { 54, 54, 54, 0 },
+ { 42, 42, 42, 0 },
+ { 31, 31, 31, 0 },
+ { 21, 21, 21, 0 },
+ { 10, 10, 10, 0 },
+ { 5, 5, 5, 0 },
+ { 149, 149, 234, 0 },
+ { 134, 134, 227, 0 },
+ { 117, 117, 223, 0 },
+ { 104, 104, 215, 0 },
+ { 87, 87, 210, 0 },
+ { 70, 70, 206, 0 },
+ { 49, 49, 185, 0 },
+ { 45, 45, 168, 0 },
+ { 36, 36, 134, 0 },
+ { 31, 31, 118, 0 },
+ { 27, 27, 101, 0 },
+ { 22, 22, 84, 0 },
+ { 18, 18, 67, 0 },
+ { 13, 13, 51, 0 },
+ { 9, 9, 34, 0 },
+ { 4, 4, 17, 0 },
+ { 159, 191, 223, 0 },
+ { 143, 181, 218, 0 },
+ { 128, 170, 213, 0 },
+ { 112, 159, 207, 0 },
+ { 96, 149, 202, 0 },
+ { 85, 138, 191, 0 },
+ { 69, 128, 186, 0 },
+ { 68, 117, 166, 0 },
+ { 62, 106, 151, 0 },
+ { 55, 96, 136, 0 },
+ { 53, 85, 117, 0 },
+ { 47, 74, 102, 0 },
+ { 43, 64, 85, 0 },
+ { 35, 53, 71, 0 },
+ { 29, 43, 56, 0 },
+ { 21, 32, 43, 0 },
+ { 184, 190, 199, 0 },
+ { 171, 182, 190, 0 },
+ { 159, 169, 181, 0 },
+ { 148, 162, 171, 0 },
+ { 136, 150, 162, 0 },
+ { 123, 138, 153, 0 },
+ { 112, 128, 143, 0 },
+ { 102, 118, 132, 0 },
+ { 92, 105, 120, 0 },
+ { 86, 97, 105, 0 },
+ { 77, 85, 94, 0 },
+ { 67, 74, 82, 0 },
+ { 57, 66, 70, 0 },
+ { 48, 53, 58, 0 },
+ { 38, 44, 47, 0 },
+ { 29, 32, 35, 0 },
+ { 154, 228, 154, 0 },
+ { 137, 224, 137, 0 },
+ { 120, 220, 120, 0 },
+ { 112, 207, 112, 0 },
+ { 96, 202, 96, 0 },
+ { 80, 197, 80, 0 },
+ { 64, 191, 64, 0 },
+ { 58, 175, 77, 0 },
+ { 53, 159, 67, 0 },
+ { 48, 143, 63, 0 },
+ { 43, 128, 64, 0 },
+ { 37, 112, 56, 0 },
+ { 32, 96, 50, 0 },
+ { 27, 80, 43, 0 },
+ { 21, 64, 33, 0 },
+ { 16, 48, 27, 0 },
+ { 186, 204, 179, 0 },
+ { 175, 194, 167, 0 },
+ { 164, 184, 156, 0 },
+ { 152, 174, 145, 0 },
+ { 140, 167, 131, 0 },
+ { 130, 157, 119, 0 },
+ { 119, 148, 107, 0 },
+ { 111, 136, 98, 0 },
+ { 99, 124, 88, 0 },
+ { 88, 112, 80, 0 },
+ { 81, 97, 73, 0 },
+ { 70, 84, 65, 0 },
+ { 61, 73, 54, 0 },
+ { 51, 61, 46, 0 },
+ { 40, 48, 37, 0 },
+ { 30, 36, 28, 0 },
+ { 209, 191, 173, 0 },
+ { 202, 181, 159, 0 },
+ { 191, 170, 149, 0 },
+ { 183, 159, 136, 0 },
+ { 175, 149, 122, 0 },
+ { 167, 138, 109, 0 },
+ { 159, 128, 96, 0 },
+ { 147, 117, 87, 0 },
+ { 129, 106, 84, 0 },
+ { 116, 96, 75, 0 },
+ { 103, 85, 67, 0 },
+ { 90, 73, 58, 0 },
+ { 78, 64, 50, 0 },
+ { 64, 53, 43, 0 },
+ { 51, 43, 34, 0 },
+ { 38, 32, 26, 0 },
+ { 209, 196, 173, 0 },
+ { 202, 186, 159, 0 },
+ { 191, 175, 149, 0 },
+ { 183, 169, 136, 0 },
+ { 175, 159, 122, 0 },
+ { 167, 150, 109, 0 },
+ { 159, 140, 96, 0 },
+ { 143, 128, 90, 0 },
+ { 131, 119, 82, 0 },
+ { 116, 106, 75, 0 },
+ { 103, 95, 67, 0 },
+ { 90, 83, 58, 0 },
+ { 78, 70, 50, 0 },
+ { 64, 60, 43, 0 },
+ { 51, 48, 34, 0 },
+ { 38, 36, 26, 0 },
+ { 255, 255, 170, 0 },
+ { 255, 255, 128, 0 },
+ { 255, 244, 106, 0 },
+ { 249, 232, 113, 0 },
+ { 255, 213, 43, 0 },
+ { 255, 197, 21, 0 },
+ { 255, 186, 43, 0 },
+ { 255, 175, 43, 0 },
+ { 255, 150, 21, 0 },
+ { 255, 143, 32, 0 },
+ { 244, 111, 11, 0 },
+ { 215, 92, 19, 0 },
+ { 190, 72, 22, 0 },
+ { 168, 60, 23, 0 },
+ { 146, 39, 24, 0 },
+ { 128, 27, 21, 0 },
+ { 244, 244, 138, 0 },
+ { 242, 242, 119, 0 },
+ { 248, 248, 92, 0 },
+ { 240, 240, 100, 0 },
+ { 247, 247, 72, 0 },
+ { 239, 239, 80, 0 },
+ { 237, 237, 61, 0 },
+ { 236, 236, 40, 0 },
+ { 235, 235, 20, 0 },
+ { 215, 215, 19, 0 },
+ { 194, 194, 18, 0 },
+ { 175, 175, 16, 0 },
+ { 156, 156, 14, 0 },
+ { 136, 136, 13, 0 },
+ { 117, 117, 11, 0 },
+ { 98, 98, 9, 0 },
+ { 215, 183, 168, 0 },
+ { 211, 170, 150, 0 },
+ { 205, 157, 135, 0 },
+ { 199, 148, 120, 0 },
+ { 193, 135, 104, 0 },
+ { 187, 123, 89, 0 },
+ { 174, 109, 70, 0 },
+ { 151, 96, 62, 0 },
+ { 128, 83, 53, 0 },
+ { 105, 68, 44, 0 },
+ { 143, 239, 239, 0 },
+ { 124, 237, 237, 0 },
+ { 106, 234, 234, 0 },
+ { 87, 232, 232, 0 },
+ { 70, 227, 227, 0 },
+ { 47, 230, 230, 0 },
+ { 32, 223, 223, 0 },
+ { 29, 205, 205, 0 },
+ { 26, 176, 176, 0 },
+ { 20, 150, 150, 0 },
+ { 17, 121, 121, 0 },
+ { 13, 94, 94, 0 },
+ { 223, 32, 223, 0 },
+ { 204, 30, 204, 0 },
+ { 186, 27, 186, 0 },
+ { 168, 23, 168, 0 },
+ { 149, 21, 149, 0 },
+ { 131, 18, 131, 0 },
+ { 112, 16, 112, 0 },
+ { 94, 13, 94, 0 },
+ { 74, 11, 74, 0 },
+ { 56, 7, 56, 0 },
+ { 249, 91, 91, 0 },
+ { 248, 80, 80, 0 },
+ { 247, 68, 68, 0 },
+ { 247, 55, 55, 0 },
+ { 247, 43, 43, 0 },
+ { 245, 31, 31, 0 },
+ { 244, 19, 19, 0 },
+ { 240, 11, 11, 0 },
+ { 228, 10, 10, 0 },
+ { 217, 9, 9, 0 },
+ { 204, 9, 9, 0 },
+ { 192, 7, 7, 0 },
+ { 180, 7, 7, 0 },
+ { 168, 6, 6, 0 },
+ { 156, 5, 5, 0 },
+ { 145, 4, 4, 0 },
+ { 131, 5, 5, 0 },
+ { 118, 5, 5, 0 },
+ { 106, 4, 4, 0 },
+ { 94, 4, 4, 0 },
+ { 80, 5, 5, 0 },
+ { 66, 6, 6, 0 },
+ { 53, 6, 6, 0 },
+ { 41, 5, 5, 0 },
+ { 128, 128, 128, 0 },
+ { 255, 0, 0, 0 },
+ { 0, 255, 0, 0 },
+ { 255, 255, 0, 0 },
+ { 0, 0, 255, 0 },
+ { 255, 0, 255, 0 },
+ { 0, 255, 255, 0 },
+ { 255, 255, 255, 0 },
+};
diff --git a/Magic2/Command.cpp b/Magic2/Command.cpp
index 0b52082..ce199b6 100644
--- a/Magic2/Command.cpp
+++ b/Magic2/Command.cpp
@@ -1,52 +1,76 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2005. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: Command.cpp
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Base class (interface) for command pattern. A
- command encapsulates a single editing operation
- that may be performed on a document. Each command
- may be done or undone multiple times. The specialized
- implementations for each type of operation are re-
- sponsible for providing a means to return the model
- to the prior state.
-*/
-
-#include "stdafx.h"
-#include "Command.h"
-
-// +--------------------------------------------------------------------+
-
-void Print(const char* msg, ...);
-
-// +--------------------------------------------------------------------+
-
-Command::Command(const char* n, MagicDoc* d)
- : name(n), document(d)
-{
-}
-
-Command::~Command()
-{
- document = 0;
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Command::Do()
-{
- Print("WARNING: Command::Do() called for '%s'\n", name.data());
-}
-
-void
-Command::Undo()
-{
- Print("WARNING: Command::Undo() called for '%s'\n", name.data());
-}
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: Command.cpp
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Base class (interface) for command pattern. A
+ command encapsulates a single editing operation
+ that may be performed on a document. Each command
+ may be done or undone multiple times. The specialized
+ implementations for each type of operation are re-
+ sponsible for providing a means to return the model
+ to the prior state.
+*/
+
+#include "stdafx.h"
+#include "Command.h"
+
+// +--------------------------------------------------------------------+
+
+void Print(const char* msg, ...);
+
+// +--------------------------------------------------------------------+
+
+Command::Command(const char* n, MagicDoc* d)
+ : name(n), document(d)
+{
+}
+
+Command::~Command()
+{
+ document = 0;
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Command::Do()
+{
+ Print("WARNING: Command::Do() called for '%s'\n", name.data());
+}
+
+void
+Command::Undo()
+{
+ Print("WARNING: Command::Undo() called for '%s'\n", name.data());
+}
diff --git a/Magic2/Command.h b/Magic2/Command.h
index 30f568e..f35e237 100644
--- a/Magic2/Command.h
+++ b/Magic2/Command.h
@@ -1,55 +1,79 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2005. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: Command.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Base class (interface) for command pattern. A
- command encapsulates a single editing operation
- that may be performed on a document. Each command
- may be done or undone multiple times. The specialized
- implementations for each type of operation are re-
- sponsible for providing a means to return the model
- to the prior state.
-*/
-
-#ifndef Command_h
-#define Command_h
-
-#include "Text.h"
-
-// +--------------------------------------------------------------------+
-
-class MagicDoc;
-class Solid;
-class Model;
-
-// +--------------------------------------------------------------------+
-
-class Command
-{
-public:
- static const char* TYPENAME() { return "Command"; }
-
- Command(const char* name, MagicDoc* document);
- virtual ~Command();
-
- // operations
- virtual void Do();
- virtual void Undo();
-
- const char* Name() const { return name; }
-
-protected:
- Text name;
- MagicDoc* document;
-};
-
-// +--------------------------------------------------------------------+
-
-#endif Command_h
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: Command.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Base class (interface) for command pattern. A
+ command encapsulates a single editing operation
+ that may be performed on a document. Each command
+ may be done or undone multiple times. The specialized
+ implementations for each type of operation are re-
+ sponsible for providing a means to return the model
+ to the prior state.
+*/
+
+#ifndef Command_h
+#define Command_h
+
+#include "Text.h"
+
+// +--------------------------------------------------------------------+
+
+class MagicDoc;
+class Solid;
+class Model;
+
+// +--------------------------------------------------------------------+
+
+class Command
+{
+public:
+ static const char* TYPENAME() { return "Command"; }
+
+ Command(const char* name, MagicDoc* document);
+ virtual ~Command();
+
+ // operations
+ virtual void Do();
+ virtual void Undo();
+
+ const char* Name() const { return name; }
+
+protected:
+ Text name;
+ MagicDoc* document;
+};
+
+// +--------------------------------------------------------------------+
+
+#endif Command_h
diff --git a/Magic2/ContentBundle.cpp b/Magic2/ContentBundle.cpp
index b489cf8..7d0e250 100644
--- a/Magic2/ContentBundle.cpp
+++ b/Magic2/ContentBundle.cpp
@@ -1,137 +1,161 @@
-/* Project nGenEx
- Destroyer Studios LLC
- Copyright © 1997-2006. All Rights Reserved.
-
- SUBSYSTEM: nGenEx.lib
- FILE: ContentBundle.cpp
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Chained collection of localized strings
-*/
-
-#include "MemDebug.h"
-#include "ContentBundle.h"
-#include "DataLoader.h"
-
-void Print(const char* fmt, ...);
-
-// +--------------------------------------------------------------------+
-
-ContentBundle::ContentBundle(const char* bundle, Locale* locale)
-{
- Text file = FindFile(bundle, locale);
- if (file.length() > 0) {
- LoadBundle(file);
- }
-}
-
-// +--------------------------------------------------------------------+
-
-ContentBundle::~ContentBundle()
-{
-}
-
-// +--------------------------------------------------------------------+
-
-Text
-ContentBundle::GetText(const char* key) const
-{
- return values.find(key, Text(key));
-}
-
-// +--------------------------------------------------------------------+
-
-Text
-ContentBundle::FindFile(const char* bundle, Locale* locale)
-{
- Text result;
- Text basename = Text(bundle);
- DataLoader* loader = DataLoader::GetLoader();
-
- if (loader && bundle) {
- if (locale) {
- result = basename + locale->GetFullCode() + ".txt";
-
- if (loader->FindFile(result))
- return result;
-
- result = basename + "_" + locale->GetLanguage() + ".txt";
-
- if (loader->FindFile(result))
- return result;
- }
-
- result = basename + ".txt";
-
- if (loader->FindFile(result))
- return result;
- }
-
- return Text();
-}
-
-// +--------------------------------------------------------------------+
-
-void
-ContentBundle::LoadBundle(const char* filename)
-{
- DataLoader* loader = DataLoader::GetLoader();
- if (loader && filename && *filename) {
- BYTE* buffer = 0;
- loader->LoadBuffer(filename, buffer, true, true);
- if (buffer && *buffer) {
- char key[1024];
- char val[2048];
- char* p = (char*) buffer;
- int s = 0, ik = 0, iv = 0;
-
- key[0] = 0;
- val[0] = 0;
-
- while (*p) {
- if (*p == '=') {
- s = 1;
- }
- else if (*p == '\n' || *p == '\r') {
- if (key[0] && val[0])
- values.insert(Text(key).trim(), Text(val).trim());
-
- ZeroMemory(key, 1024);
- ZeroMemory(val, 2048);
- s = 0;
- ik = 0;
- iv = 0;
- }
- else if (s == 0) {
- if (!key[0]) {
- if (*p == '#') {
- s = -1; // comment
- }
- else if (!isspace(*p)) {
- key[ik++] = *p;
- }
- }
- else {
- key[ik++] = *p;
- }
- }
- else if (s == 1) {
- if (!isspace(*p)) {
- s = 2;
- val[iv++] = *p;
- }
- }
- else if (s == 2) {
- val[iv++] = *p;
- }
-
- p++;
- }
-
- loader->ReleaseBuffer(buffer);
- }
- }
-}
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: nGenEx.lib
+ FILE: ContentBundle.cpp
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Chained collection of localized strings
+*/
+
+#include "MemDebug.h"
+#include "ContentBundle.h"
+#include "DataLoader.h"
+
+void Print(const char* fmt, ...);
+
+// +--------------------------------------------------------------------+
+
+ContentBundle::ContentBundle(const char* bundle, Locale* locale)
+{
+ Text file = FindFile(bundle, locale);
+ if (file.length() > 0) {
+ LoadBundle(file);
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+ContentBundle::~ContentBundle()
+{
+}
+
+// +--------------------------------------------------------------------+
+
+Text
+ContentBundle::GetText(const char* key) const
+{
+ return values.find(key, Text(key));
+}
+
+// +--------------------------------------------------------------------+
+
+Text
+ContentBundle::FindFile(const char* bundle, Locale* locale)
+{
+ Text result;
+ Text basename = Text(bundle);
+ DataLoader* loader = DataLoader::GetLoader();
+
+ if (loader && bundle) {
+ if (locale) {
+ result = basename + locale->GetFullCode() + ".txt";
+
+ if (loader->FindFile(result))
+ return result;
+
+ result = basename + "_" + locale->GetLanguage() + ".txt";
+
+ if (loader->FindFile(result))
+ return result;
+ }
+
+ result = basename + ".txt";
+
+ if (loader->FindFile(result))
+ return result;
+ }
+
+ return Text();
+}
+
+// +--------------------------------------------------------------------+
+
+void
+ContentBundle::LoadBundle(const char* filename)
+{
+ DataLoader* loader = DataLoader::GetLoader();
+ if (loader && filename && *filename) {
+ BYTE* buffer = 0;
+ loader->LoadBuffer(filename, buffer, true, true);
+ if (buffer && *buffer) {
+ char key[1024];
+ char val[2048];
+ char* p = (char*) buffer;
+ int s = 0, ik = 0, iv = 0;
+
+ key[0] = 0;
+ val[0] = 0;
+
+ while (*p) {
+ if (*p == '=') {
+ s = 1;
+ }
+ else if (*p == '\n' || *p == '\r') {
+ if (key[0] && val[0])
+ values.insert(Text(key).trim(), Text(val).trim());
+
+ ZeroMemory(key, 1024);
+ ZeroMemory(val, 2048);
+ s = 0;
+ ik = 0;
+ iv = 0;
+ }
+ else if (s == 0) {
+ if (!key[0]) {
+ if (*p == '#') {
+ s = -1; // comment
+ }
+ else if (!isspace(*p)) {
+ key[ik++] = *p;
+ }
+ }
+ else {
+ key[ik++] = *p;
+ }
+ }
+ else if (s == 1) {
+ if (!isspace(*p)) {
+ s = 2;
+ val[iv++] = *p;
+ }
+ }
+ else if (s == 2) {
+ val[iv++] = *p;
+ }
+
+ p++;
+ }
+
+ loader->ReleaseBuffer(buffer);
+ }
+ }
+}
diff --git a/Magic2/ContentBundle.h b/Magic2/ContentBundle.h
index 4848716..d75a817 100644
--- a/Magic2/ContentBundle.h
+++ b/Magic2/ContentBundle.h
@@ -1,48 +1,72 @@
-/* Project nGenEx
- Destroyer Studios LLC
- Copyright © 1997-2006. All Rights Reserved.
-
- SUBSYSTEM: nGenEx.lib
- FILE: ContentBundle.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Chained collection of localized strings
-*/
-
-#ifndef ContentBundle_h
-#define ContentBundle_h
-
-#include "Types.h"
-#include "Dictionary.h"
-#include "Text.h"
-#include "Locale_ss.h"
-
-// +--------------------------------------------------------------------+
-
-class ContentBundle
-{
-public:
- static const char* TYPENAME() { return "ContentBundle"; }
-
- ContentBundle(const char* bundle, Locale* locale);
- virtual ~ContentBundle();
-
- int operator == (const ContentBundle& that) const { return this == &that; }
-
- const Text& GetName() const { return name; }
- Text GetText(const char* key) const;
- bool IsLoaded() const { return !values.isEmpty(); }
-
-protected:
- void LoadBundle(const char* filename);
- Text FindFile(const char* bundle, Locale* locale);
-
- Text name;
- Dictionary<Text> values;
-};
-
-#endif ContentBundle_h
-
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: nGenEx.lib
+ FILE: ContentBundle.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Chained collection of localized strings
+*/
+
+#ifndef ContentBundle_h
+#define ContentBundle_h
+
+#include "Types.h"
+#include "Dictionary.h"
+#include "Text.h"
+#include "Locale_ss.h"
+
+// +--------------------------------------------------------------------+
+
+class ContentBundle
+{
+public:
+ static const char* TYPENAME() { return "ContentBundle"; }
+
+ ContentBundle(const char* bundle, Locale* locale);
+ virtual ~ContentBundle();
+
+ int operator == (const ContentBundle& that) const { return this == &that; }
+
+ const Text& GetName() const { return name; }
+ Text GetText(const char* key) const;
+ bool IsLoaded() const { return !values.isEmpty(); }
+
+protected:
+ void LoadBundle(const char* filename);
+ Text FindFile(const char* bundle, Locale* locale);
+
+ Text name;
+ Dictionary<Text> values;
+};
+
+#endif ContentBundle_h
+
diff --git a/Magic2/Editor.cpp b/Magic2/Editor.cpp
index cfaf40d..24ac589 100644
--- a/Magic2/Editor.cpp
+++ b/Magic2/Editor.cpp
@@ -1,412 +1,436 @@
-/* Project MAGIC
- John DiCamillo Software Consulting
- Copyright © 1994-1997. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe Application
- FILE: Editor.cpp
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Source file for implementation of Selector
-*/
-
-
-#include "stdafx.h"
-#include "Editor.h"
-#include "MagicDoc.h"
-#include "ModelView.h"
-#include "Selection.h"
-
-// +----------------------------------------------------------------------+
-
-
-static float project_u(Vec3& v, int style)
-{
- switch (style) {
- case 0: return v.x; // PLAN
- case 1: return v.x; // FRONT
- case 2: return v.z; // SIDE
- }
-
- return v.x;
-}
-
-static float project_v(Vec3& v, int style)
-{
- switch (style) {
- case 0: return -v.y; // PLAN
- case 1: return -v.z; // FRONT
- case 2: return -v.y; // SIDE
- }
-
- return -v.y;
-}
-
-static float project_u_cylindrical(Vec3& v, int axis)
-{
- float t = 0.0f;
-
- switch (axis) {
- // PLAN
- case 0: if (v.x == 0)
- return 0.0f;
- t = v.y/v.x;
- return (float) atan(t);
-
- // FRONT
- case 1: if (v.x == 0)
- return 0.0f;
- t = v.z/v.x;
- return (float) atan(t);
-
- // SIDE
- case 2: return (float) atan2(v.z, v.y); // SIDE
- }
-
- return project_u(v, axis);
-}
-
-static float project_v_cylindrical(Vec3& v, int axis)
-{
- switch (axis) {
- case 0: return v.z; // PLAN
- case 1: return v.y; // FRONT
- case 2: return v.x; // SIDE
- }
-
- return project_v(v, axis);
-}
-
-void
-Editor::ApplyMaterial(Material* material, List<Poly>& polys,
- int mapping, int axis, float scale_u, float scale_v,
- int flip, int mirror, int rotate)
-{
- // save state:
- EditCommand* command = new EditCommand("ApplyMaterial", document);
- document->Exec(command);
-
- // do the job:
- if (mapping == MAP_CYLINDRICAL) {
- ApplyMaterialCylindrical(material, polys, axis, scale_u, scale_v, flip, mirror, rotate);
- return;
- }
-
- if (mapping == MAP_SPHERICAL) {
- ApplyMaterialSpherical(material, polys, axis, scale_u, scale_v, flip, mirror, rotate);
- return;
- }
-
- VertexSet* vset = polys.first()->vertex_set;
-
- Vec3* loc = vset->loc;
- float min_u = 100000.0f, max_u = -100000.0f;
- float min_v = 100000.0f, max_v = -100000.0f;
-
- ListIter<Poly> iter = polys;
-
- // compute range and scale:
- if (mapping == MAP_PLANAR) {
- while (++iter) {
- Poly* poly = iter.value();
- for (int i = 0; i < poly->nverts; i++) {
- int v = poly->verts[i];
-
- float u0 = project_u(loc[v], axis);
- float v0 = project_v(loc[v], axis);
-
- if (u0 < min_u) min_u = u0;
- if (v0 < min_v) min_v = v0;
- if (u0 > max_u) max_u = u0;
- if (v0 > max_v) max_v = v0;
- }
- }
- }
-
- float base_u = 0.0f;
- float base_v = 0.0f;
-
- if (max_u != min_u) base_u = 1.0f / (max_u - min_u);
- if (max_v != min_v) base_v = 1.0f / (max_v - min_v);
-
- iter.reset();
-
- // assign texture id and coordinates:
- while (++iter) {
- Poly* poly = iter.value();
-
- poly->material = material;
-
- if (mapping == MAP_NONE)
- continue;
-
- for (int i = 0; i < poly->nverts; i++) {
- int v = poly->verts[i];
-
- // planar projection
- if (mapping == MAP_PLANAR) {
- if (!rotate) {
- if (mirror)
- vset->tu[v] = (1.0f - base_u * (project_u(loc[v], axis) - min_u)) * scale_u;
- else
- vset->tu[v] = (project_u(loc[v], axis) - min_u) * scale_u * base_u;
-
- if (flip)
- vset->tv[v] = (1.0f - base_v * (project_v(loc[v], axis) - min_v)) * scale_v;
- else
- vset->tv[v] = (project_v(loc[v], axis) - min_v) * scale_v * base_v;
- }
- else {
- if (!mirror)
- vset->tv[v] = (1.0f - base_u * (project_u(loc[v], axis) - min_u)) * scale_u;
- else
- vset->tv[v] = (project_u(loc[v], axis) - min_u) * scale_u * base_u;
-
- if (flip)
- vset->tu[v] = (1.0f - base_v * (project_v(loc[v], axis) - min_v)) * scale_v;
- else
- vset->tu[v] = (project_v(loc[v], axis) - min_v) * scale_v * base_v;
- }
- }
-
- // stretch to fit
- else if (mapping == MAP_STRETCH) {
- if (scale_u < 0.001) scale_u = 1;
- if (scale_v < 0.001) scale_v = 1;
-
- if (!rotate) {
- if (mirror)
- vset->tu[v] = scale_u * (float) (i < 1 || i > 2);
- else
- vset->tu[v] = scale_u * (float) (i > 0 && i < 3);
-
- if (flip)
- vset->tv[v] = scale_v * (float) (i <= 1);
- else
- vset->tv[v] = scale_v * (float) (i > 1);
- }
- else {
- if (!mirror)
- vset->tv[v] = scale_v * (float) (i < 1 || i > 2);
- else
- vset->tv[v] = scale_v * (float) (i > 0 && i < 3);
-
- if (flip)
- vset->tu[v] = scale_u * (float) (i <= 1);
- else
- vset->tu[v] = scale_u * (float) (i > 1);
- }
- }
- }
- }
-
- Resegment();
-}
-
-void
-Editor::ApplyMaterialCylindrical(Material* material, List<Poly>& polys,
- int axis, float scale_u, float scale_v,
- int flip, int mirror, int rotate)
-{
- VertexSet* vset = polys.first()->vertex_set;
-
- Vec3* loc = vset->loc;
- float min_u = 100000.0f, max_u = -100000.0f;
- float min_v = 100000.0f, max_v = -100000.0f;
-
- ListIter<Poly> iter = polys;
-
- // compute range and scale:
- while (++iter) {
- Poly* poly = iter.value();
- for (int i = 0; i < poly->nverts; i++) {
- int v = poly->verts[i];
-
- float u0 = project_u_cylindrical(loc[v], axis);
- float v0 = project_v_cylindrical(loc[v], axis);
-
- if (u0 < min_u) min_u = u0;
- if (v0 < min_v) min_v = v0;
- if (u0 > max_u) max_u = u0;
- if (v0 > max_v) max_v = v0;
- }
- }
-
- float base_u = 0.0f;
- float base_v = 0.0f;
-
- if (max_u != min_u) base_u = 1.0f / (max_u - min_u);
- if (max_v != min_v) base_v = 1.0f / (max_v - min_v);
-
- iter.reset();
-
- // assign texture id and coordinates:
- while (++iter) {
- Poly* poly = iter.value();
-
- poly->material = material;
-
- for (int i = 0; i < poly->nverts; i++) {
- int v = poly->verts[i];
- float u0 = project_u_cylindrical(loc[v], axis);
- float v0 = project_v_cylindrical(loc[v], axis);
-
- if (!rotate) {
- if (mirror)
- vset->tu[v] = (1.0f - base_u * (u0 - min_u)) * scale_u;
- else
- vset->tu[v] = (u0 - min_u) * scale_u * base_u;
-
- if (flip)
- vset->tv[v] = (1.0f - base_v * (v0 - min_v)) * scale_v;
- else
- vset->tv[v] = (v0 - min_v) * scale_v * base_v;
- }
- else {
- if (!mirror)
- vset->tv[v] = (1.0f - base_u * (u0 - min_u)) * scale_u;
- else
- vset->tv[v] = (u0 - min_u) * scale_u * base_u;
-
- if (flip)
- vset->tu[v] = (1.0f - base_v * (v0 - min_v)) * scale_v;
- else
- vset->tu[v] = (v0 - min_v) * scale_v * base_v;
- }
- }
- }
-
- Resegment();
-}
-
-void
-Editor::ApplyMaterialSpherical(Material* material, List<Poly>& polys,
- int axis, float scale_u, float scale_v,
- int flip, int mirror, int rotate)
-{
-}
-
-// +----------------------------------------------------------------------+
-
-static int mcomp(const void* a, const void* b)
-{
- Poly* pa = (Poly*) a;
- Poly* pb = (Poly*) b;
-
- if (pa->sortval == pb->sortval)
- return 0;
-
- if (pa->sortval < pb->sortval)
- return -1;
-
- return 1;
-}
-
-void
-Editor::Resegment()
-{
- if (model) {
- ListIter<Surface> iter = model->GetSurfaces();
- while (++iter) {
- Surface* surface = iter.value();
- Poly* polys = surface->GetPolys();
- int npolys = surface->NumPolys();
-
- for (int n = 0; n < npolys; n++) {
- Poly* p = polys + n;
- Material* m = p->material;
- int sortval = model->GetMaterials().index(m) + 1;
-
- if (p->sortval != sortval)
- p->sortval = sortval;
- }
-
- // destroy the old segments and video data:
- VideoPrivateData* video_data = surface->GetVideoPrivateData();
- surface->SetVideoPrivateData(0);
- surface->GetSegments().destroy();
-
- delete video_data;
-
- // sort the polys by material index:
- qsort((void*) polys, npolys, sizeof(Poly), mcomp);
-
- // create new cohesive segments:
- Segment* segment = 0;
-
- for (int n = 0; n < npolys; n++) {
- if (segment && segment->material == polys[n].material) {
- segment->npolys++;
- }
- else {
- segment = 0;
- }
-
- if (!segment) {
- segment = new Segment;
-
- segment->npolys = 1;
- segment->polys = polys + n;
- segment->material = segment->polys->material;
-
- surface->GetSegments().append(segment);
- }
- }
- }
- }
-}
-
-
-// +----------------------------------------------------------------------+
-// +----------------------------------------------------------------------+
-// +----------------------------------------------------------------------+
-
-EditCommand::EditCommand(const char* n, MagicDoc* d)
- : Command(n, d), model1(0), model2(0)
-{
-}
-
-EditCommand::~EditCommand()
-{
- delete model1;
- delete model2;
-}
-
-// +----------------------------------------------------------------------+
-
-void
-EditCommand::Do()
-{
- if (document) {
- Solid* solid = document->GetSolid();
-
- // first application:
- if (!model2) {
- if (!model1)
- model1 = new Model(*solid->GetModel());
- }
- // re-do:
- else {
- solid->GetModel()->operator=(*model2);
- }
- }
-}
-
-// +----------------------------------------------------------------------+
-
-void
-EditCommand::Undo()
-{
- if (document && model1) {
- Solid* solid = document->GetSolid();
-
- // save current state for later re-do:
- if (!model2)
- model2 = new Model(*solid->GetModel());
-
- solid->GetModel()->operator=(*model1);
- }
-}
-
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe Application
+ FILE: Editor.cpp
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Source file for implementation of Selector
+*/
+
+
+#include "stdafx.h"
+#include "Editor.h"
+#include "MagicDoc.h"
+#include "ModelView.h"
+#include "Selection.h"
+
+// +----------------------------------------------------------------------+
+
+
+static float project_u(Vec3& v, int style)
+{
+ switch (style) {
+ case 0: return v.x; // PLAN
+ case 1: return v.x; // FRONT
+ case 2: return v.z; // SIDE
+ }
+
+ return v.x;
+}
+
+static float project_v(Vec3& v, int style)
+{
+ switch (style) {
+ case 0: return -v.y; // PLAN
+ case 1: return -v.z; // FRONT
+ case 2: return -v.y; // SIDE
+ }
+
+ return -v.y;
+}
+
+static float project_u_cylindrical(Vec3& v, int axis)
+{
+ float t = 0.0f;
+
+ switch (axis) {
+ // PLAN
+ case 0: if (v.x == 0)
+ return 0.0f;
+ t = v.y/v.x;
+ return (float) atan(t);
+
+ // FRONT
+ case 1: if (v.x == 0)
+ return 0.0f;
+ t = v.z/v.x;
+ return (float) atan(t);
+
+ // SIDE
+ case 2: return (float) atan2(v.z, v.y); // SIDE
+ }
+
+ return project_u(v, axis);
+}
+
+static float project_v_cylindrical(Vec3& v, int axis)
+{
+ switch (axis) {
+ case 0: return v.z; // PLAN
+ case 1: return v.y; // FRONT
+ case 2: return v.x; // SIDE
+ }
+
+ return project_v(v, axis);
+}
+
+void
+Editor::ApplyMaterial(Material* material, List<Poly>& polys,
+ int mapping, int axis, float scale_u, float scale_v,
+ int flip, int mirror, int rotate)
+{
+ // save state:
+ EditCommand* command = new EditCommand("ApplyMaterial", document);
+ document->Exec(command);
+
+ // do the job:
+ if (mapping == MAP_CYLINDRICAL) {
+ ApplyMaterialCylindrical(material, polys, axis, scale_u, scale_v, flip, mirror, rotate);
+ return;
+ }
+
+ if (mapping == MAP_SPHERICAL) {
+ ApplyMaterialSpherical(material, polys, axis, scale_u, scale_v, flip, mirror, rotate);
+ return;
+ }
+
+ VertexSet* vset = polys.first()->vertex_set;
+
+ Vec3* loc = vset->loc;
+ float min_u = 100000.0f, max_u = -100000.0f;
+ float min_v = 100000.0f, max_v = -100000.0f;
+
+ ListIter<Poly> iter = polys;
+
+ // compute range and scale:
+ if (mapping == MAP_PLANAR) {
+ while (++iter) {
+ Poly* poly = iter.value();
+ for (int i = 0; i < poly->nverts; i++) {
+ int v = poly->verts[i];
+
+ float u0 = project_u(loc[v], axis);
+ float v0 = project_v(loc[v], axis);
+
+ if (u0 < min_u) min_u = u0;
+ if (v0 < min_v) min_v = v0;
+ if (u0 > max_u) max_u = u0;
+ if (v0 > max_v) max_v = v0;
+ }
+ }
+ }
+
+ float base_u = 0.0f;
+ float base_v = 0.0f;
+
+ if (max_u != min_u) base_u = 1.0f / (max_u - min_u);
+ if (max_v != min_v) base_v = 1.0f / (max_v - min_v);
+
+ iter.reset();
+
+ // assign texture id and coordinates:
+ while (++iter) {
+ Poly* poly = iter.value();
+
+ poly->material = material;
+
+ if (mapping == MAP_NONE)
+ continue;
+
+ for (int i = 0; i < poly->nverts; i++) {
+ int v = poly->verts[i];
+
+ // planar projection
+ if (mapping == MAP_PLANAR) {
+ if (!rotate) {
+ if (mirror)
+ vset->tu[v] = (1.0f - base_u * (project_u(loc[v], axis) - min_u)) * scale_u;
+ else
+ vset->tu[v] = (project_u(loc[v], axis) - min_u) * scale_u * base_u;
+
+ if (flip)
+ vset->tv[v] = (1.0f - base_v * (project_v(loc[v], axis) - min_v)) * scale_v;
+ else
+ vset->tv[v] = (project_v(loc[v], axis) - min_v) * scale_v * base_v;
+ }
+ else {
+ if (!mirror)
+ vset->tv[v] = (1.0f - base_u * (project_u(loc[v], axis) - min_u)) * scale_u;
+ else
+ vset->tv[v] = (project_u(loc[v], axis) - min_u) * scale_u * base_u;
+
+ if (flip)
+ vset->tu[v] = (1.0f - base_v * (project_v(loc[v], axis) - min_v)) * scale_v;
+ else
+ vset->tu[v] = (project_v(loc[v], axis) - min_v) * scale_v * base_v;
+ }
+ }
+
+ // stretch to fit
+ else if (mapping == MAP_STRETCH) {
+ if (scale_u < 0.001) scale_u = 1;
+ if (scale_v < 0.001) scale_v = 1;
+
+ if (!rotate) {
+ if (mirror)
+ vset->tu[v] = scale_u * (float) (i < 1 || i > 2);
+ else
+ vset->tu[v] = scale_u * (float) (i > 0 && i < 3);
+
+ if (flip)
+ vset->tv[v] = scale_v * (float) (i <= 1);
+ else
+ vset->tv[v] = scale_v * (float) (i > 1);
+ }
+ else {
+ if (!mirror)
+ vset->tv[v] = scale_v * (float) (i < 1 || i > 2);
+ else
+ vset->tv[v] = scale_v * (float) (i > 0 && i < 3);
+
+ if (flip)
+ vset->tu[v] = scale_u * (float) (i <= 1);
+ else
+ vset->tu[v] = scale_u * (float) (i > 1);
+ }
+ }
+ }
+ }
+
+ Resegment();
+}
+
+void
+Editor::ApplyMaterialCylindrical(Material* material, List<Poly>& polys,
+ int axis, float scale_u, float scale_v,
+ int flip, int mirror, int rotate)
+{
+ VertexSet* vset = polys.first()->vertex_set;
+
+ Vec3* loc = vset->loc;
+ float min_u = 100000.0f, max_u = -100000.0f;
+ float min_v = 100000.0f, max_v = -100000.0f;
+
+ ListIter<Poly> iter = polys;
+
+ // compute range and scale:
+ while (++iter) {
+ Poly* poly = iter.value();
+ for (int i = 0; i < poly->nverts; i++) {
+ int v = poly->verts[i];
+
+ float u0 = project_u_cylindrical(loc[v], axis);
+ float v0 = project_v_cylindrical(loc[v], axis);
+
+ if (u0 < min_u) min_u = u0;
+ if (v0 < min_v) min_v = v0;
+ if (u0 > max_u) max_u = u0;
+ if (v0 > max_v) max_v = v0;
+ }
+ }
+
+ float base_u = 0.0f;
+ float base_v = 0.0f;
+
+ if (max_u != min_u) base_u = 1.0f / (max_u - min_u);
+ if (max_v != min_v) base_v = 1.0f / (max_v - min_v);
+
+ iter.reset();
+
+ // assign texture id and coordinates:
+ while (++iter) {
+ Poly* poly = iter.value();
+
+ poly->material = material;
+
+ for (int i = 0; i < poly->nverts; i++) {
+ int v = poly->verts[i];
+ float u0 = project_u_cylindrical(loc[v], axis);
+ float v0 = project_v_cylindrical(loc[v], axis);
+
+ if (!rotate) {
+ if (mirror)
+ vset->tu[v] = (1.0f - base_u * (u0 - min_u)) * scale_u;
+ else
+ vset->tu[v] = (u0 - min_u) * scale_u * base_u;
+
+ if (flip)
+ vset->tv[v] = (1.0f - base_v * (v0 - min_v)) * scale_v;
+ else
+ vset->tv[v] = (v0 - min_v) * scale_v * base_v;
+ }
+ else {
+ if (!mirror)
+ vset->tv[v] = (1.0f - base_u * (u0 - min_u)) * scale_u;
+ else
+ vset->tv[v] = (u0 - min_u) * scale_u * base_u;
+
+ if (flip)
+ vset->tu[v] = (1.0f - base_v * (v0 - min_v)) * scale_v;
+ else
+ vset->tu[v] = (v0 - min_v) * scale_v * base_v;
+ }
+ }
+ }
+
+ Resegment();
+}
+
+void
+Editor::ApplyMaterialSpherical(Material* material, List<Poly>& polys,
+ int axis, float scale_u, float scale_v,
+ int flip, int mirror, int rotate)
+{
+}
+
+// +----------------------------------------------------------------------+
+
+static int mcomp(const void* a, const void* b)
+{
+ Poly* pa = (Poly*) a;
+ Poly* pb = (Poly*) b;
+
+ if (pa->sortval == pb->sortval)
+ return 0;
+
+ if (pa->sortval < pb->sortval)
+ return -1;
+
+ return 1;
+}
+
+void
+Editor::Resegment()
+{
+ if (model) {
+ ListIter<Surface> iter = model->GetSurfaces();
+ while (++iter) {
+ Surface* surface = iter.value();
+ Poly* polys = surface->GetPolys();
+ int npolys = surface->NumPolys();
+
+ for (int n = 0; n < npolys; n++) {
+ Poly* p = polys + n;
+ Material* m = p->material;
+ int sortval = model->GetMaterials().index(m) + 1;
+
+ if (p->sortval != sortval)
+ p->sortval = sortval;
+ }
+
+ // destroy the old segments and video data:
+ VideoPrivateData* video_data = surface->GetVideoPrivateData();
+ surface->SetVideoPrivateData(0);
+ surface->GetSegments().destroy();
+
+ delete video_data;
+
+ // sort the polys by material index:
+ qsort((void*) polys, npolys, sizeof(Poly), mcomp);
+
+ // create new cohesive segments:
+ Segment* segment = 0;
+
+ for (int n = 0; n < npolys; n++) {
+ if (segment && segment->material == polys[n].material) {
+ segment->npolys++;
+ }
+ else {
+ segment = 0;
+ }
+
+ if (!segment) {
+ segment = new Segment;
+
+ segment->npolys = 1;
+ segment->polys = polys + n;
+ segment->material = segment->polys->material;
+
+ surface->GetSegments().append(segment);
+ }
+ }
+ }
+ }
+}
+
+
+// +----------------------------------------------------------------------+
+// +----------------------------------------------------------------------+
+// +----------------------------------------------------------------------+
+
+EditCommand::EditCommand(const char* n, MagicDoc* d)
+ : Command(n, d), model1(0), model2(0)
+{
+}
+
+EditCommand::~EditCommand()
+{
+ delete model1;
+ delete model2;
+}
+
+// +----------------------------------------------------------------------+
+
+void
+EditCommand::Do()
+{
+ if (document) {
+ Solid* solid = document->GetSolid();
+
+ // first application:
+ if (!model2) {
+ if (!model1)
+ model1 = new Model(*solid->GetModel());
+ }
+ // re-do:
+ else {
+ solid->GetModel()->operator=(*model2);
+ }
+ }
+}
+
+// +----------------------------------------------------------------------+
+
+void
+EditCommand::Undo()
+{
+ if (document && model1) {
+ Solid* solid = document->GetSolid();
+
+ // save current state for later re-do:
+ if (!model2)
+ model2 = new Model(*solid->GetModel());
+
+ solid->GetModel()->operator=(*model1);
+ }
+}
+
diff --git a/Magic2/Editor.h b/Magic2/Editor.h
index c0326e2..b8cba52 100644
--- a/Magic2/Editor.h
+++ b/Magic2/Editor.h
@@ -1,84 +1,108 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: Editor.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Classes for rendering solid meshes of polygons
-*/
-
-#ifndef Editor_h
-#define Editor_h
-
-#include "MagicDoc.h"
-#include "Command.h"
-#include "Polygon.h"
-#include "Solid.h"
-#include "Video.h"
-#include "List.h"
-
-// +--------------------------------------------------------------------+
-
-class Selection;
-class ModelView;
-
-// +--------------------------------------------------------------------+
-
-class Editor
-{
-public:
- Editor(MagicDoc* doc) : document(doc), model(0) { }
-
- // accessors / mutators
- void UseModel(Model* m) { model = m; }
- Model* GetModel() const { return model; }
-
- // operations
-
- enum { MAP_NONE, MAP_PLANAR, MAP_CYLINDRICAL, MAP_SPHERICAL, MAP_STRETCH };
-
- void ApplyMaterial(Material* material, List<Poly>& polys,
- int mapping, int axis, float scale_u, float scale_v,
- int flip, int mirror, int rotate);
-
- void ApplyMaterialCylindrical(Material* material, List<Poly>& polys,
- int axis, float scale_u, float scale_v,
- int flip, int mirror, int rotate);
-
- void ApplyMaterialSpherical(Material* material, List<Poly>& polys,
- int axis, float scale_u, float scale_v,
- int flip, int mirror, int rotate);
-
-
- void Resegment();
-
-protected:
- MagicDoc* document;
- Model* model;
-};
-
-// +--------------------------------------------------------------------+
-
-class EditCommand : public Command
-{
-public:
- EditCommand(const char* name, MagicDoc* doc);
- virtual ~EditCommand();
-
- virtual void Do();
- virtual void Undo();
-
-private:
- Model* model1;
- Model* model2;
-};
-
-// +--------------------------------------------------------------------+
-
-#endif Editor_h
-
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: Editor.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Classes for rendering solid meshes of polygons
+*/
+
+#ifndef Editor_h
+#define Editor_h
+
+#include "MagicDoc.h"
+#include "Command.h"
+#include "Polygon.h"
+#include "Solid.h"
+#include "Video.h"
+#include "List.h"
+
+// +--------------------------------------------------------------------+
+
+class Selection;
+class ModelView;
+
+// +--------------------------------------------------------------------+
+
+class Editor
+{
+public:
+ Editor(MagicDoc* doc) : document(doc), model(0) { }
+
+ // accessors / mutators
+ void UseModel(Model* m) { model = m; }
+ Model* GetModel() const { return model; }
+
+ // operations
+
+ enum { MAP_NONE, MAP_PLANAR, MAP_CYLINDRICAL, MAP_SPHERICAL, MAP_STRETCH };
+
+ void ApplyMaterial(Material* material, List<Poly>& polys,
+ int mapping, int axis, float scale_u, float scale_v,
+ int flip, int mirror, int rotate);
+
+ void ApplyMaterialCylindrical(Material* material, List<Poly>& polys,
+ int axis, float scale_u, float scale_v,
+ int flip, int mirror, int rotate);
+
+ void ApplyMaterialSpherical(Material* material, List<Poly>& polys,
+ int axis, float scale_u, float scale_v,
+ int flip, int mirror, int rotate);
+
+
+ void Resegment();
+
+protected:
+ MagicDoc* document;
+ Model* model;
+};
+
+// +--------------------------------------------------------------------+
+
+class EditCommand : public Command
+{
+public:
+ EditCommand(const char* name, MagicDoc* doc);
+ virtual ~EditCommand();
+
+ virtual void Do();
+ virtual void Undo();
+
+private:
+ Model* model1;
+ Model* model2;
+};
+
+// +--------------------------------------------------------------------+
+
+#endif Editor_h
+
diff --git a/Magic2/Grid.cpp b/Magic2/Grid.cpp
index 3499591..133f26c 100644
--- a/Magic2/Grid.cpp
+++ b/Magic2/Grid.cpp
@@ -1,346 +1,370 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: Grid.cpp
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Implementation of the Grid class
-*/
-
-#include "stdafx.h"
-#include "Magic.h"
-
-#include "MagicDoc.h"
-#include "Grid.h"
-
-#include "ActiveWindow.h"
-#include "Color.h"
-#include "Polygon.h"
-#include "Scene.h"
-#include "Screen.h"
-#include "Solid.h"
-#include "Video.h"
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
-#endif
-
-const int MAJOR_COUNT = 64;
-
-// +--------------------------------------------------------------------+
-
-Grid::Grid()
- : x_major(0), y_major(0), x_minor(0), y_minor(0),
- bmp_plan(0), bmp_front(0), bmp_side(0)
-{
- strcpy(name, "Grid");
-
- plane = GRID_XZ; // plan
-
- show = true;
- show_ref = true;
- snap = true;
- minor = true;
-
- x_size = 4;
- y_size = 4;
- x_skip = 4;
- y_skip = 4;
-
- x_major = new Vec3[2*MAJOR_COUNT];
- y_major = new Vec3[2*MAJOR_COUNT];
-}
-
-Grid::~Grid()
-{
- delete [] x_major;
- delete [] y_major;
- delete [] x_minor;
- delete [] y_minor;
-}
-
-// +--------------------------------------------------------------------+
-
-const char*
-Grid::GetReferencePlan() const
-{
- if (bmp_plan)
- return bmp_plan->GetFilename();
-
- return "";
-}
-
-void
-Grid::SetReferencePlan(const char* fname)
-{
- bmp_plan = 0;
-
- if (fname && *fname)
- LoadTexture(fname, bmp_plan);
-}
-
-// +--------------------------------------------------------------------+
-
-const char*
-Grid::GetReferenceFront() const
-{
- if (bmp_front)
- return bmp_front->GetFilename();
-
- return "";
-}
-
-void
-Grid::SetReferenceFront(const char* fname)
-{
- bmp_front = 0;
-
- if (fname && *fname)
- LoadTexture(fname, bmp_front);
-}
-
-// +--------------------------------------------------------------------+
-
-const char*
-Grid::GetReferenceSide() const
-{
- if (bmp_side)
- return bmp_side->GetFilename();
-
- return "";
-}
-
-void
-Grid::SetReferenceSide(const char* fname)
-{
- bmp_side = 0;
-
- if (fname && *fname)
- LoadTexture(fname, bmp_side);
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Grid::Render(Video* video, DWORD flags)
-{
- Vec3 origin[4];
-
- for (int i = 0; i < 4; i++)
- origin[i] = loc;
-
- const float EXTENT = (float) MAJOR_COUNT * 64.0f;
-
- switch (plane) {
- case GRID_XY: // FRONT
- origin[0].x += -EXTENT;
- origin[1].x += EXTENT;
- origin[2].y += -EXTENT;
- origin[3].y += EXTENT;
-
- for (int i = 0; i < 2*MAJOR_COUNT; i += 2) {
- float x = (float) (i-MAJOR_COUNT) * 64.0f;
- float y = (float) (i-MAJOR_COUNT) * 64.0f;
-
- x_major[i ] = loc + Vec3(x, -EXTENT, 0.0f);
- x_major[i+1] = loc + Vec3(x, EXTENT, 0.0f);
- y_major[i ] = loc + Vec3(-EXTENT, y, 0.0f);
- y_major[i+1] = loc + Vec3( EXTENT, y, 0.0f);
- }
-
- break;
-
- case GRID_XZ: // PLAN
- origin[0].x += -EXTENT;
- origin[1].x += EXTENT;
- origin[2].z += -EXTENT;
- origin[3].z += EXTENT;
-
- for (int i = 0; i < 2*MAJOR_COUNT; i += 2) {
- float x = (float) (i-MAJOR_COUNT) * 64.0f;
- float z = (float) (i-MAJOR_COUNT) * 64.0f;
-
- x_major[i ] = loc + Vec3(x, 0.0f, -EXTENT);
- x_major[i+1] = loc + Vec3(x, 0.0f, EXTENT);
- y_major[i ] = loc + Vec3(-EXTENT, 0.0f, z);
- y_major[i+1] = loc + Vec3( EXTENT, 0.0f, z);
- }
-
- break;
-
- case GRID_YZ: // SIDE
- origin[0].y += -EXTENT;
- origin[1].y += EXTENT;
- origin[2].z += -EXTENT;
- origin[3].z += EXTENT;
-
- for (int i = 0; i < 2*MAJOR_COUNT; i += 2) {
- float y = (float) (i-MAJOR_COUNT) * 64.0f;
- float z = (float) (i-MAJOR_COUNT) * 64.0f;
-
- x_major[i ] = loc + Vec3(0.0f, y, -EXTENT);
- x_major[i+1] = loc + Vec3(0.0f, y, EXTENT);
- y_major[i ] = loc + Vec3(0.0f, -EXTENT, z);
- y_major[i+1] = loc + Vec3(0.0f, EXTENT, z);
- }
-
- break;
- }
-
- RenderReference(video);
-
- video->SetRenderState(Video::FILL_MODE, Video::FILL_SOLID);
- video->SetRenderState(Video::LIGHTING_ENABLE, FALSE);
- video->SetRenderState(Video::Z_ENABLE, TRUE);
- video->SetRenderState(Video::Z_WRITE_ENABLE, TRUE);
-
- video->DrawLines(MAJOR_COUNT, x_major, Color::Gray, 1);
- video->DrawLines(MAJOR_COUNT, y_major, Color::Gray, 1);
- video->DrawLines( 2, origin, Color::DarkGray, 1);
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Grid::RenderReference(Video* video)
-{
- if (!show_ref) return;
-
- Bitmap* bmp = 0;
-
- switch (plane) {
- case GRID_XY: bmp = bmp_front; break;
- case GRID_XZ: bmp = bmp_plan; break;
- case GRID_YZ: bmp = bmp_side; break;
- }
-
- if (!bmp) return;
-
- Material mtl;
- VertexSet vset(4);
- Poly poly;
- Vec3 nrm;
-
- float vx = (float) bmp->Width();
- float vy = (float) bmp->Height();
- float vz = -100.0f;
-
- if (vx <= 256 || vy <= 256) {
- vx *= 2.0f;
- vy *= 2.0f;
- }
-
- switch (plane) {
- case GRID_XY: // FRONT
- nrm = Vec3(0.0f, 0.0f, 1.0f);
- vset.loc[0] = loc + Vec3(-vx, -vy, vz);
- vset.loc[1] = loc + Vec3( vx, -vy, vz);
- vset.loc[2] = loc + Vec3( vx, vy, vz);
- vset.loc[3] = loc + Vec3(-vx, vy, vz);
- break;
-
- case GRID_XZ: // PLAN
- nrm = Vec3(0.0f, 1.0f, 0.0f);
- vset.loc[0] = loc + Vec3(-vx, vz, vy);
- vset.loc[1] = loc + Vec3( vx, vz, vy);
- vset.loc[2] = loc + Vec3( vx, vz, -vy);
- vset.loc[3] = loc + Vec3(-vx, vz, -vy);
- break;
-
- case GRID_YZ: // SIDE
- nrm = Vec3(1.0f, 0.0f, 0.0f);
- vset.loc[0] = loc + Vec3( vz, -vx, -vy);
- vset.loc[1] = loc + Vec3( vz, vx, -vy);
- vset.loc[2] = loc + Vec3( vz, vx, vy);
- vset.loc[3] = loc + Vec3( vz, -vx, vy);
- break;
-
- default:
- return;
- }
-
- mtl.Ka = Color::White;
- mtl.Kd = Color::Black;
- mtl.tex_diffuse = bmp;
-
- vset.nrm[0] = nrm;
- vset.nrm[1] = nrm;
- vset.nrm[2] = nrm;
- vset.nrm[3] = nrm;
-
- vset.tu[0] = 0.0f;
- vset.tv[0] = 0.0f;
- vset.tu[1] = 1.0f;
- vset.tv[1] = 0.0f;
- vset.tu[2] = 1.0f;
- vset.tv[2] = 1.0f;
- vset.tu[3] = 0.0f;
- vset.tv[3] = 1.0f;
-
- poly.nverts = 4;
- poly.verts[0] = 0;
- poly.verts[1] = 1;
- poly.verts[2] = 2;
- poly.verts[3] = 3;
- poly.material = &mtl;
- poly.vertex_set = &vset;
-
- video->SetRenderState(Video::FILL_MODE, Video::FILL_SOLID);
- video->SetRenderState(Video::LIGHTING_ENABLE, TRUE);
- video->SetRenderState(Video::Z_ENABLE, FALSE);
- video->SetRenderState(Video::Z_WRITE_ENABLE, FALSE);
- video->SetAmbient(Color::White);
-
- video->DrawPolys(1, &poly);
-}
-
-// +----------------------------------------------------------------------+
-
-CPoint&
-Grid::Snap(CPoint& p)
-{
- p.x = snapto(p.x, x_size);
- p.y = snapto(p.y, y_size);
-
- return p;
-}
-
-// +----------------------------------------------------------------------+
-
-int
-Grid::snapto(int i, int dim)
-{
- if (!snap)
- return i;
-
- int n = i + dim/2;
- int m = n % dim;
-
- return (n - m);
-}
-
-// +----------------------------------------------------------------------+
-
-void
-Grid::SetSize(int x, int y)
-{
- x_size = x;
- y_size = y ? y : x;
-}
-
-// +----------------------------------------------------------------------+
-
-void
-Grid::SetSkip(int x, int y)
-{
- x_skip = x;
- y_skip = y ? y : x;
-}
-
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: Grid.cpp
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Implementation of the Grid class
+*/
+
+#include "stdafx.h"
+#include "Magic.h"
+
+#include "MagicDoc.h"
+#include "Grid.h"
+
+#include "ActiveWindow.h"
+#include "Color.h"
+#include "Polygon.h"
+#include "Scene.h"
+#include "Screen.h"
+#include "Solid.h"
+#include "Video.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+const int MAJOR_COUNT = 64;
+
+// +--------------------------------------------------------------------+
+
+Grid::Grid()
+ : x_major(0), y_major(0), x_minor(0), y_minor(0),
+ bmp_plan(0), bmp_front(0), bmp_side(0)
+{
+ strcpy(name, "Grid");
+
+ plane = GRID_XZ; // plan
+
+ show = true;
+ show_ref = true;
+ snap = true;
+ minor = true;
+
+ x_size = 4;
+ y_size = 4;
+ x_skip = 4;
+ y_skip = 4;
+
+ x_major = new Vec3[2*MAJOR_COUNT];
+ y_major = new Vec3[2*MAJOR_COUNT];
+}
+
+Grid::~Grid()
+{
+ delete [] x_major;
+ delete [] y_major;
+ delete [] x_minor;
+ delete [] y_minor;
+}
+
+// +--------------------------------------------------------------------+
+
+const char*
+Grid::GetReferencePlan() const
+{
+ if (bmp_plan)
+ return bmp_plan->GetFilename();
+
+ return "";
+}
+
+void
+Grid::SetReferencePlan(const char* fname)
+{
+ bmp_plan = 0;
+
+ if (fname && *fname)
+ LoadTexture(fname, bmp_plan);
+}
+
+// +--------------------------------------------------------------------+
+
+const char*
+Grid::GetReferenceFront() const
+{
+ if (bmp_front)
+ return bmp_front->GetFilename();
+
+ return "";
+}
+
+void
+Grid::SetReferenceFront(const char* fname)
+{
+ bmp_front = 0;
+
+ if (fname && *fname)
+ LoadTexture(fname, bmp_front);
+}
+
+// +--------------------------------------------------------------------+
+
+const char*
+Grid::GetReferenceSide() const
+{
+ if (bmp_side)
+ return bmp_side->GetFilename();
+
+ return "";
+}
+
+void
+Grid::SetReferenceSide(const char* fname)
+{
+ bmp_side = 0;
+
+ if (fname && *fname)
+ LoadTexture(fname, bmp_side);
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Grid::Render(Video* video, DWORD flags)
+{
+ Vec3 origin[4];
+
+ for (int i = 0; i < 4; i++)
+ origin[i] = loc;
+
+ const float EXTENT = (float) MAJOR_COUNT * 64.0f;
+
+ switch (plane) {
+ case GRID_XY: // FRONT
+ origin[0].x += -EXTENT;
+ origin[1].x += EXTENT;
+ origin[2].y += -EXTENT;
+ origin[3].y += EXTENT;
+
+ for (int i = 0; i < 2*MAJOR_COUNT; i += 2) {
+ float x = (float) (i-MAJOR_COUNT) * 64.0f;
+ float y = (float) (i-MAJOR_COUNT) * 64.0f;
+
+ x_major[i ] = loc + Vec3(x, -EXTENT, 0.0f);
+ x_major[i+1] = loc + Vec3(x, EXTENT, 0.0f);
+ y_major[i ] = loc + Vec3(-EXTENT, y, 0.0f);
+ y_major[i+1] = loc + Vec3( EXTENT, y, 0.0f);
+ }
+
+ break;
+
+ case GRID_XZ: // PLAN
+ origin[0].x += -EXTENT;
+ origin[1].x += EXTENT;
+ origin[2].z += -EXTENT;
+ origin[3].z += EXTENT;
+
+ for (int i = 0; i < 2*MAJOR_COUNT; i += 2) {
+ float x = (float) (i-MAJOR_COUNT) * 64.0f;
+ float z = (float) (i-MAJOR_COUNT) * 64.0f;
+
+ x_major[i ] = loc + Vec3(x, 0.0f, -EXTENT);
+ x_major[i+1] = loc + Vec3(x, 0.0f, EXTENT);
+ y_major[i ] = loc + Vec3(-EXTENT, 0.0f, z);
+ y_major[i+1] = loc + Vec3( EXTENT, 0.0f, z);
+ }
+
+ break;
+
+ case GRID_YZ: // SIDE
+ origin[0].y += -EXTENT;
+ origin[1].y += EXTENT;
+ origin[2].z += -EXTENT;
+ origin[3].z += EXTENT;
+
+ for (int i = 0; i < 2*MAJOR_COUNT; i += 2) {
+ float y = (float) (i-MAJOR_COUNT) * 64.0f;
+ float z = (float) (i-MAJOR_COUNT) * 64.0f;
+
+ x_major[i ] = loc + Vec3(0.0f, y, -EXTENT);
+ x_major[i+1] = loc + Vec3(0.0f, y, EXTENT);
+ y_major[i ] = loc + Vec3(0.0f, -EXTENT, z);
+ y_major[i+1] = loc + Vec3(0.0f, EXTENT, z);
+ }
+
+ break;
+ }
+
+ RenderReference(video);
+
+ video->SetRenderState(Video::FILL_MODE, Video::FILL_SOLID);
+ video->SetRenderState(Video::LIGHTING_ENABLE, FALSE);
+ video->SetRenderState(Video::Z_ENABLE, TRUE);
+ video->SetRenderState(Video::Z_WRITE_ENABLE, TRUE);
+
+ video->DrawLines(MAJOR_COUNT, x_major, Color::Gray, 1);
+ video->DrawLines(MAJOR_COUNT, y_major, Color::Gray, 1);
+ video->DrawLines( 2, origin, Color::DarkGray, 1);
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Grid::RenderReference(Video* video)
+{
+ if (!show_ref) return;
+
+ Bitmap* bmp = 0;
+
+ switch (plane) {
+ case GRID_XY: bmp = bmp_front; break;
+ case GRID_XZ: bmp = bmp_plan; break;
+ case GRID_YZ: bmp = bmp_side; break;
+ }
+
+ if (!bmp) return;
+
+ Material mtl;
+ VertexSet vset(4);
+ Poly poly;
+ Vec3 nrm;
+
+ float vx = (float) bmp->Width();
+ float vy = (float) bmp->Height();
+ float vz = -100.0f;
+
+ if (vx <= 256 || vy <= 256) {
+ vx *= 2.0f;
+ vy *= 2.0f;
+ }
+
+ switch (plane) {
+ case GRID_XY: // FRONT
+ nrm = Vec3(0.0f, 0.0f, 1.0f);
+ vset.loc[0] = loc + Vec3(-vx, -vy, vz);
+ vset.loc[1] = loc + Vec3( vx, -vy, vz);
+ vset.loc[2] = loc + Vec3( vx, vy, vz);
+ vset.loc[3] = loc + Vec3(-vx, vy, vz);
+ break;
+
+ case GRID_XZ: // PLAN
+ nrm = Vec3(0.0f, 1.0f, 0.0f);
+ vset.loc[0] = loc + Vec3(-vx, vz, vy);
+ vset.loc[1] = loc + Vec3( vx, vz, vy);
+ vset.loc[2] = loc + Vec3( vx, vz, -vy);
+ vset.loc[3] = loc + Vec3(-vx, vz, -vy);
+ break;
+
+ case GRID_YZ: // SIDE
+ nrm = Vec3(1.0f, 0.0f, 0.0f);
+ vset.loc[0] = loc + Vec3( vz, -vx, -vy);
+ vset.loc[1] = loc + Vec3( vz, vx, -vy);
+ vset.loc[2] = loc + Vec3( vz, vx, vy);
+ vset.loc[3] = loc + Vec3( vz, -vx, vy);
+ break;
+
+ default:
+ return;
+ }
+
+ mtl.Ka = Color::White;
+ mtl.Kd = Color::Black;
+ mtl.tex_diffuse = bmp;
+
+ vset.nrm[0] = nrm;
+ vset.nrm[1] = nrm;
+ vset.nrm[2] = nrm;
+ vset.nrm[3] = nrm;
+
+ vset.tu[0] = 0.0f;
+ vset.tv[0] = 0.0f;
+ vset.tu[1] = 1.0f;
+ vset.tv[1] = 0.0f;
+ vset.tu[2] = 1.0f;
+ vset.tv[2] = 1.0f;
+ vset.tu[3] = 0.0f;
+ vset.tv[3] = 1.0f;
+
+ poly.nverts = 4;
+ poly.verts[0] = 0;
+ poly.verts[1] = 1;
+ poly.verts[2] = 2;
+ poly.verts[3] = 3;
+ poly.material = &mtl;
+ poly.vertex_set = &vset;
+
+ video->SetRenderState(Video::FILL_MODE, Video::FILL_SOLID);
+ video->SetRenderState(Video::LIGHTING_ENABLE, TRUE);
+ video->SetRenderState(Video::Z_ENABLE, FALSE);
+ video->SetRenderState(Video::Z_WRITE_ENABLE, FALSE);
+ video->SetAmbient(Color::White);
+
+ video->DrawPolys(1, &poly);
+}
+
+// +----------------------------------------------------------------------+
+
+CPoint&
+Grid::Snap(CPoint& p)
+{
+ p.x = snapto(p.x, x_size);
+ p.y = snapto(p.y, y_size);
+
+ return p;
+}
+
+// +----------------------------------------------------------------------+
+
+int
+Grid::snapto(int i, int dim)
+{
+ if (!snap)
+ return i;
+
+ int n = i + dim/2;
+ int m = n % dim;
+
+ return (n - m);
+}
+
+// +----------------------------------------------------------------------+
+
+void
+Grid::SetSize(int x, int y)
+{
+ x_size = x;
+ y_size = y ? y : x;
+}
+
+// +----------------------------------------------------------------------+
+
+void
+Grid::SetSkip(int x, int y)
+{
+ x_skip = x;
+ y_skip = y ? y : x;
+}
+
diff --git a/Magic2/Grid.h b/Magic2/Grid.h
index 93c0201..7e0491c 100644
--- a/Magic2/Grid.h
+++ b/Magic2/Grid.h
@@ -1,81 +1,105 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: Grid.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Interface of the Grid class
-*/
-
-
-#ifndef Grid_h
-#define Grid_h
-
-#include "Bitmap.h"
-#include "Graphic.h"
-
-// +--------------------------------------------------------------------+
-
-class Grid : public Graphic
-{
-public:
- enum PLANE { GRID_XY, GRID_XZ, GRID_YZ };
-
- Grid();
- virtual ~Grid();
-
- CPoint& Snap(CPoint& p);
-
- bool IsSnap() const { return snap; }
- bool IsShow() const { return show; }
- void SetSnap(bool s) { snap = s; }
- void SetShow(bool s) { show = s; }
- void SetSize(int x, int y = 0);
- void SetSkip(int x, int y = 0);
- void ShowMinor(bool show) { minor = show; }
- void ShowPlane(int p) { plane = p; }
- void ShowReference(bool show) { show_ref = show; }
-
- const char* GetReferencePlan() const;
- void SetReferencePlan(const char* fname);
- const char* GetReferenceFront() const;
- void SetReferenceFront(const char* fname);
- const char* GetReferenceSide() const;
- void SetReferenceSide(const char* fname);
-
- int GetSize() const { return x_size; }
-
- // operations
- virtual void Render(Video* video, DWORD flags);
- virtual void RenderReference(Video* video);
-
-protected:
- int snapto(int i, int dim);
-
- bool show;
- bool show_ref;
- bool snap;
- bool minor;
-
- int x_size, y_size;
- int x_skip, y_skip;
- int plane;
-
- Vec3* x_major;
- Vec3* x_minor;
- Vec3* y_major;
- Vec3* y_minor;
-
- Bitmap* bmp_plan;
- Bitmap* bmp_front;
- Bitmap* bmp_side;
-};
-
-// +--------------------------------------------------------------------+
-
-#endif Grid_h
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: Grid.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Interface of the Grid class
+*/
+
+
+#ifndef Grid_h
+#define Grid_h
+
+#include "Bitmap.h"
+#include "Graphic.h"
+
+// +--------------------------------------------------------------------+
+
+class Grid : public Graphic
+{
+public:
+ enum PLANE { GRID_XY, GRID_XZ, GRID_YZ };
+
+ Grid();
+ virtual ~Grid();
+
+ CPoint& Snap(CPoint& p);
+
+ bool IsSnap() const { return snap; }
+ bool IsShow() const { return show; }
+ void SetSnap(bool s) { snap = s; }
+ void SetShow(bool s) { show = s; }
+ void SetSize(int x, int y = 0);
+ void SetSkip(int x, int y = 0);
+ void ShowMinor(bool show) { minor = show; }
+ void ShowPlane(int p) { plane = p; }
+ void ShowReference(bool show) { show_ref = show; }
+
+ const char* GetReferencePlan() const;
+ void SetReferencePlan(const char* fname);
+ const char* GetReferenceFront() const;
+ void SetReferenceFront(const char* fname);
+ const char* GetReferenceSide() const;
+ void SetReferenceSide(const char* fname);
+
+ int GetSize() const { return x_size; }
+
+ // operations
+ virtual void Render(Video* video, DWORD flags);
+ virtual void RenderReference(Video* video);
+
+protected:
+ int snapto(int i, int dim);
+
+ bool show;
+ bool show_ref;
+ bool snap;
+ bool minor;
+
+ int x_size, y_size;
+ int x_skip, y_skip;
+ int plane;
+
+ Vec3* x_major;
+ Vec3* x_minor;
+ Vec3* y_major;
+ Vec3* y_minor;
+
+ Bitmap* bmp_plan;
+ Bitmap* bmp_front;
+ Bitmap* bmp_side;
+};
+
+// +--------------------------------------------------------------------+
+
+#endif Grid_h
diff --git a/Magic2/GridProps.cpp b/Magic2/GridProps.cpp
index d375ea9..89ff991 100644
--- a/Magic2/GridProps.cpp
+++ b/Magic2/GridProps.cpp
@@ -1,126 +1,150 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: GridProps.cpp
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Grid Properties Dialog implementation file
-*/
-
-
-#include "stdafx.h"
-#include "Magic.h"
-#include "GridProps.h"
-#include "Grid.h"
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
-#endif
-
-// +--------------------------------------------------------------------+
-// GridProps dialog
-// +--------------------------------------------------------------------+
-
-GridProps::GridProps(Grid* g, CWnd* pParent /*=NULL*/)
- : CDialog(GridProps::IDD, pParent), grid(g)
-{
- //{{AFX_DATA_INIT(GridProps)
- mGridShow = grid->IsShow();
- mGridSnap = grid->IsSnap();
- mReferencePlan = grid->GetReferencePlan();
- mReferenceFront = grid->GetReferenceFront();
- mReferenceSide = grid->GetReferenceSide();
- mGridSize = grid->GetSize();
- //}}AFX_DATA_INIT
-}
-
-static const char* C(CString& str)
-{
- static char buf[512];
- int i;
- for (i = 0; i < str.GetLength(); i++)
- buf[i] = (char) str.GetAt(i);
- buf[i] = 0;
-
- return buf;
-}
-
-void GridProps::DoDataExchange(CDataExchange* pDX)
-{
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(GridProps)
- DDX_Check(pDX, IDC_GRID_SHOW, mGridShow);
- DDX_Check(pDX, IDC_GRID_SNAP, mGridSnap);
- DDX_Text(pDX, IDC_REFERENCE_PLAN, mReferencePlan);
- DDX_Text(pDX, IDC_REFERENCE_FRONT, mReferenceFront);
- DDX_Text(pDX, IDC_REFERENCE_SIDE, mReferenceSide);
- DDX_Text(pDX, IDC_GRID_SIZE, mGridSize);
- DDV_MinMaxInt(pDX, mGridSize, 1, 64);
- //}}AFX_DATA_MAP
-
- // if saving, write the values back to the grid
- if (pDX->m_bSaveAndValidate) {
- grid->SetSnap(mGridSnap ? true : false);
- grid->SetShow(mGridShow ? true : false);
- grid->SetSize(mGridSize);
-
- grid->SetReferencePlan(C(mReferencePlan));
- grid->SetReferenceFront(C(mReferenceFront));
- grid->SetReferenceSide(C(mReferenceSide));
- }
-}
-
-
-BEGIN_MESSAGE_MAP(GridProps, CDialog)
- //{{AFX_MSG_MAP(GridProps)
- ON_BN_CLICKED(IDC_FILE_PLAN, OnFilePlan)
- ON_BN_CLICKED(IDC_FILE_FRONT, OnFileFront)
- ON_BN_CLICKED(IDC_FILE_SIDE, OnFileSide)
- //}}AFX_MSG_MAP
-END_MESSAGE_MAP()
-
-// +--------------------------------------------------------------------+
-
-static void OnImageFile(CString& strImageFile)
-{
- char filename[512];
- filename[0] = '\0';
- CFileDialog ofd(TRUE, "pcx");
-
- ofd.m_ofn.lpstrFilter = "PCX Files\0*.pcx\0All Files\0*.*\0\0";
- ofd.m_ofn.lpstrFile = filename;
- ofd.m_ofn.nMaxFile = sizeof(filename);
-
- if (ofd.DoModal() != IDOK)
- return;
-
- char tex_name[512];
- sprintf(tex_name, "%s", ofd.GetFileName().GetBuffer(0));
-
- strImageFile = tex_name;
-}
-
-void GridProps::OnFilePlan()
-{
- OnImageFile(mReferencePlan);
- UpdateData(FALSE);
-}
-
-void GridProps::OnFileFront()
-{
- OnImageFile(mReferenceFront);
- UpdateData(FALSE);
-}
-
-void GridProps::OnFileSide()
-{
- OnImageFile(mReferenceSide);
- UpdateData(FALSE);
-}
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: GridProps.cpp
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Grid Properties Dialog implementation file
+*/
+
+
+#include "stdafx.h"
+#include "Magic.h"
+#include "GridProps.h"
+#include "Grid.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+// +--------------------------------------------------------------------+
+// GridProps dialog
+// +--------------------------------------------------------------------+
+
+GridProps::GridProps(Grid* g, CWnd* pParent /*=NULL*/)
+ : CDialog(GridProps::IDD, pParent), grid(g)
+{
+ //{{AFX_DATA_INIT(GridProps)
+ mGridShow = grid->IsShow();
+ mGridSnap = grid->IsSnap();
+ mReferencePlan = grid->GetReferencePlan();
+ mReferenceFront = grid->GetReferenceFront();
+ mReferenceSide = grid->GetReferenceSide();
+ mGridSize = grid->GetSize();
+ //}}AFX_DATA_INIT
+}
+
+static const char* C(CString& str)
+{
+ static char buf[512];
+ int i;
+ for (i = 0; i < str.GetLength(); i++)
+ buf[i] = (char) str.GetAt(i);
+ buf[i] = 0;
+
+ return buf;
+}
+
+void GridProps::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(GridProps)
+ DDX_Check(pDX, IDC_GRID_SHOW, mGridShow);
+ DDX_Check(pDX, IDC_GRID_SNAP, mGridSnap);
+ DDX_Text(pDX, IDC_REFERENCE_PLAN, mReferencePlan);
+ DDX_Text(pDX, IDC_REFERENCE_FRONT, mReferenceFront);
+ DDX_Text(pDX, IDC_REFERENCE_SIDE, mReferenceSide);
+ DDX_Text(pDX, IDC_GRID_SIZE, mGridSize);
+ DDV_MinMaxInt(pDX, mGridSize, 1, 64);
+ //}}AFX_DATA_MAP
+
+ // if saving, write the values back to the grid
+ if (pDX->m_bSaveAndValidate) {
+ grid->SetSnap(mGridSnap ? true : false);
+ grid->SetShow(mGridShow ? true : false);
+ grid->SetSize(mGridSize);
+
+ grid->SetReferencePlan(C(mReferencePlan));
+ grid->SetReferenceFront(C(mReferenceFront));
+ grid->SetReferenceSide(C(mReferenceSide));
+ }
+}
+
+
+BEGIN_MESSAGE_MAP(GridProps, CDialog)
+ //{{AFX_MSG_MAP(GridProps)
+ ON_BN_CLICKED(IDC_FILE_PLAN, OnFilePlan)
+ ON_BN_CLICKED(IDC_FILE_FRONT, OnFileFront)
+ ON_BN_CLICKED(IDC_FILE_SIDE, OnFileSide)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+// +--------------------------------------------------------------------+
+
+static void OnImageFile(CString& strImageFile)
+{
+ char filename[512];
+ filename[0] = '\0';
+ CFileDialog ofd(TRUE, "pcx");
+
+ ofd.m_ofn.lpstrFilter = "PCX Files\0*.pcx\0All Files\0*.*\0\0";
+ ofd.m_ofn.lpstrFile = filename;
+ ofd.m_ofn.nMaxFile = sizeof(filename);
+
+ if (ofd.DoModal() != IDOK)
+ return;
+
+ char tex_name[512];
+ sprintf(tex_name, "%s", ofd.GetFileName().GetBuffer(0));
+
+ strImageFile = tex_name;
+}
+
+void GridProps::OnFilePlan()
+{
+ OnImageFile(mReferencePlan);
+ UpdateData(FALSE);
+}
+
+void GridProps::OnFileFront()
+{
+ OnImageFile(mReferenceFront);
+ UpdateData(FALSE);
+}
+
+void GridProps::OnFileSide()
+{
+ OnImageFile(mReferenceSide);
+ UpdateData(FALSE);
+}
diff --git a/Magic2/GridProps.h b/Magic2/GridProps.h
index c2dd77a..e5412e9 100644
--- a/Magic2/GridProps.h
+++ b/Magic2/GridProps.h
@@ -1,69 +1,93 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: GridProps.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Grid Properties Dialog interface file
-*/
-
-#if !defined(AFX_GRIDPROPS_H__79C78890_ABB9_4789_BFFC_29617CAC606E__INCLUDED_)
-#define AFX_GRIDPROPS_H__79C78890_ABB9_4789_BFFC_29617CAC606E__INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif
-
-// +--------------------------------------------------------------------+
-// GridProps dialog
-// +--------------------------------------------------------------------+
-
-class Grid;
-
-class GridProps : public CDialog
-{
-// Construction
-public:
- GridProps(Grid* g, CWnd* pParent = NULL); // standard constructor
-
-// Dialog Data
- //{{AFX_DATA(GridProps)
- enum { IDD = IDD_GRIDPROPS };
- BOOL mGridShow;
- BOOL mGridSnap;
- CString mReferencePlan;
- CString mReferenceFront;
- CString mReferenceSide;
- int mGridSize;
- //}}AFX_DATA
-
-
-// Overrides
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(GridProps)
- protected:
- virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
- //}}AFX_VIRTUAL
-
-// Implementation
-protected:
- Grid* grid;
-
- // Generated message map functions
- //{{AFX_MSG(GridProps)
- afx_msg void OnFilePlan();
- afx_msg void OnFileFront();
- afx_msg void OnFileSide();
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
-};
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
-
-#endif
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: GridProps.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Grid Properties Dialog interface file
+*/
+
+#if !defined(AFX_GRIDPROPS_H__79C78890_ABB9_4789_BFFC_29617CAC606E__INCLUDED_)
+#define AFX_GRIDPROPS_H__79C78890_ABB9_4789_BFFC_29617CAC606E__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+// +--------------------------------------------------------------------+
+// GridProps dialog
+// +--------------------------------------------------------------------+
+
+class Grid;
+
+class GridProps : public CDialog
+{
+// Construction
+public:
+ GridProps(Grid* g, CWnd* pParent = NULL); // standard constructor
+
+// Dialog Data
+ //{{AFX_DATA(GridProps)
+ enum { IDD = IDD_GRIDPROPS };
+ BOOL mGridShow;
+ BOOL mGridSnap;
+ CString mReferencePlan;
+ CString mReferenceFront;
+ CString mReferenceSide;
+ int mGridSize;
+ //}}AFX_DATA
+
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(GridProps)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+ Grid* grid;
+
+ // Generated message map functions
+ //{{AFX_MSG(GridProps)
+ afx_msg void OnFilePlan();
+ afx_msg void OnFileFront();
+ afx_msg void OnFileSide();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif
diff --git a/Magic2/Locale_ss.cpp b/Magic2/Locale_ss.cpp
index 9a87650..d079791 100644
--- a/Magic2/Locale_ss.cpp
+++ b/Magic2/Locale_ss.cpp
@@ -1,237 +1,261 @@
-/* Project nGenEx
- Destroyer Studios LLC
- Copyright © 1997-2006. All Rights Reserved.
-
- SUBSYSTEM: nGenEx.lib
- FILE: Locale.cpp
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- 3D Locale (Polygon) Object
-*/
-
-#include "MemDebug.h"
-#include "Locale_ss.h"
-
-void Print(const char* fmt, ...);
-
-// +--------------------------------------------------------------------+
-
-static List<Locale> locales;
-
-// +--------------------------------------------------------------------+
-
-Locale::Locale(const char* l, const char* c, const char* v)
-{
- ZeroMemory(this, sizeof(Locale));
- if (l && *l) {
- strncpy_s(language, l, 6);
- char* p = language;
- while (*p) {
- *p = tolower(*p);
- p++;
- }
- }
-
- if (c && *c) {
- strncpy_s(country, c, 6);
- char* p = country;
- while (*p) {
- *p = toupper(*p);
- p++;
- }
- }
-
- if (v && *v) {
- strncpy_s(variant, v, 6);
- char* p = variant;
- while (*p) {
- *p = tolower(*p);
- p++;
- }
- }
-
- locales.append(this);
-}
-
-// +--------------------------------------------------------------------+
-
-Locale::~Locale()
-{
- locales.remove(this);
-}
-
-// +--------------------------------------------------------------------+
-
-int
-Locale::operator == (const Locale& that) const
-{
- if (this == &that) return 1;
-
- return !_stricmp(language, that.language) &&
- !_stricmp(country, that.country) &&
- !_stricmp(variant, that.variant);
-}
-
-// +--------------------------------------------------------------------+
-
-Locale*
-Locale::ParseLocale(const char* str)
-{
- if (str && *str) {
- int i = 0;
- char s1[4];
- char s2[4];
- char s3[4];
-
- while (*str && *str != '_' && i < 3) {
- s1[i] = *str++;
- i++;
- }
- s1[i] = 0;
- i = 0;
-
- if (*str == '_')
- str++;
-
- while (*str && *str != '_' && i < 3) {
- s2[i] = *str++;
- i++;
- }
- s2[i] = 0;
- i = 0;
-
- if (*str == '_')
- str++;
-
- while (*str && *str != '_' && i < 3) {
- s3[i] = *str++;
- i++;
- }
- s3[i] = 0;
- i = 0;
-
- return CreateLocale(s1, s2, s3);
- }
-
- return 0;
-}
-
-// +--------------------------------------------------------------------+
-
-Locale*
-Locale::CreateLocale(const char* l, const char* c, const char* v)
-{
- ListIter<Locale> iter = locales;
- while (++iter) {
- Locale* loc = iter.value();
- if (!_stricmp(l, loc->GetLanguage())) {
- if (c && *c) {
- if (!_stricmp(c, loc->GetCountry())) {
- if (v && *v) {
- if (!_stricmp(v, loc->GetVariant())) {
- return loc;
- }
- }
- else {
- return loc;
- }
- }
- }
- else {
- return loc;
- }
- }
- }
-
- if (l[0]) {
- if (c[0]) {
- if (v[0]) {
- return new(__FILE__,__LINE__) Locale(l, c, v);
- }
- return new(__FILE__,__LINE__) Locale(l, c);
- }
- return new(__FILE__,__LINE__) Locale(l);
- }
-
- return 0;
-}
-
-// +--------------------------------------------------------------------+
-
-const List<Locale>&
-Locale::GetAllLocales()
-{
- return locales;
-}
-
-// +--------------------------------------------------------------------+
-
-const Text
-Locale::GetFullCode() const
-{
- Text result = language;
- if (*country) {
- result.append("_");
- result.append(country);
-
- if (*variant) {
- result.append("_");
- result.append(variant);
- }
- }
- return result;
-}
-
-// +--------------------------------------------------------------------+
-
-static const char* languages[] = {
- "en", "English",
- "fr", "French",
- "de", "German",
- "it", "Italian",
- "pt", "Portuguese",
- "ru", "Russian",
- "es", "Spanish"
-};
-
-static const char* countries[] = {
- "US", "USA",
- "CA", "Canada",
- "FR", "France",
- "DE", "Germany",
- "IT", "Italy",
- "PT", "Portugal",
- "RU", "Russia",
- "ES", "Spain",
- "UK", "United Kingdom"
-};
-
-const Text
-Locale::GetDisplayName() const
-{
- Text result;
- if (*language) {
- for (int i = 0; i < 14; i += 2) {
- if (!_stricmp(language, languages[i])) {
- result = languages[i+1];
- break;
- }
- }
-
- if (*country) {
- for (int i = 0; i < 18; i += 2) {
- if (!_stricmp(country, countries[i])) {
- result.append(" - ");
- result.append(countries[i+1]);
- break;
- }
- }
- }
-
- }
- return result;
-}
-
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: nGenEx.lib
+ FILE: Locale.cpp
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ 3D Locale (Polygon) Object
+*/
+
+#include "MemDebug.h"
+#include "Locale_ss.h"
+
+void Print(const char* fmt, ...);
+
+// +--------------------------------------------------------------------+
+
+static List<Locale> locales;
+
+// +--------------------------------------------------------------------+
+
+Locale::Locale(const char* l, const char* c, const char* v)
+{
+ ZeroMemory(this, sizeof(Locale));
+ if (l && *l) {
+ strncpy_s(language, l, 6);
+ char* p = language;
+ while (*p) {
+ *p = tolower(*p);
+ p++;
+ }
+ }
+
+ if (c && *c) {
+ strncpy_s(country, c, 6);
+ char* p = country;
+ while (*p) {
+ *p = toupper(*p);
+ p++;
+ }
+ }
+
+ if (v && *v) {
+ strncpy_s(variant, v, 6);
+ char* p = variant;
+ while (*p) {
+ *p = tolower(*p);
+ p++;
+ }
+ }
+
+ locales.append(this);
+}
+
+// +--------------------------------------------------------------------+
+
+Locale::~Locale()
+{
+ locales.remove(this);
+}
+
+// +--------------------------------------------------------------------+
+
+int
+Locale::operator == (const Locale& that) const
+{
+ if (this == &that) return 1;
+
+ return !_stricmp(language, that.language) &&
+ !_stricmp(country, that.country) &&
+ !_stricmp(variant, that.variant);
+}
+
+// +--------------------------------------------------------------------+
+
+Locale*
+Locale::ParseLocale(const char* str)
+{
+ if (str && *str) {
+ int i = 0;
+ char s1[4];
+ char s2[4];
+ char s3[4];
+
+ while (*str && *str != '_' && i < 3) {
+ s1[i] = *str++;
+ i++;
+ }
+ s1[i] = 0;
+ i = 0;
+
+ if (*str == '_')
+ str++;
+
+ while (*str && *str != '_' && i < 3) {
+ s2[i] = *str++;
+ i++;
+ }
+ s2[i] = 0;
+ i = 0;
+
+ if (*str == '_')
+ str++;
+
+ while (*str && *str != '_' && i < 3) {
+ s3[i] = *str++;
+ i++;
+ }
+ s3[i] = 0;
+ i = 0;
+
+ return CreateLocale(s1, s2, s3);
+ }
+
+ return 0;
+}
+
+// +--------------------------------------------------------------------+
+
+Locale*
+Locale::CreateLocale(const char* l, const char* c, const char* v)
+{
+ ListIter<Locale> iter = locales;
+ while (++iter) {
+ Locale* loc = iter.value();
+ if (!_stricmp(l, loc->GetLanguage())) {
+ if (c && *c) {
+ if (!_stricmp(c, loc->GetCountry())) {
+ if (v && *v) {
+ if (!_stricmp(v, loc->GetVariant())) {
+ return loc;
+ }
+ }
+ else {
+ return loc;
+ }
+ }
+ }
+ else {
+ return loc;
+ }
+ }
+ }
+
+ if (l[0]) {
+ if (c[0]) {
+ if (v[0]) {
+ return new(__FILE__,__LINE__) Locale(l, c, v);
+ }
+ return new(__FILE__,__LINE__) Locale(l, c);
+ }
+ return new(__FILE__,__LINE__) Locale(l);
+ }
+
+ return 0;
+}
+
+// +--------------------------------------------------------------------+
+
+const List<Locale>&
+Locale::GetAllLocales()
+{
+ return locales;
+}
+
+// +--------------------------------------------------------------------+
+
+const Text
+Locale::GetFullCode() const
+{
+ Text result = language;
+ if (*country) {
+ result.append("_");
+ result.append(country);
+
+ if (*variant) {
+ result.append("_");
+ result.append(variant);
+ }
+ }
+ return result;
+}
+
+// +--------------------------------------------------------------------+
+
+static const char* languages[] = {
+ "en", "English",
+ "fr", "French",
+ "de", "German",
+ "it", "Italian",
+ "pt", "Portuguese",
+ "ru", "Russian",
+ "es", "Spanish"
+};
+
+static const char* countries[] = {
+ "US", "USA",
+ "CA", "Canada",
+ "FR", "France",
+ "DE", "Germany",
+ "IT", "Italy",
+ "PT", "Portugal",
+ "RU", "Russia",
+ "ES", "Spain",
+ "UK", "United Kingdom"
+};
+
+const Text
+Locale::GetDisplayName() const
+{
+ Text result;
+ if (*language) {
+ for (int i = 0; i < 14; i += 2) {
+ if (!_stricmp(language, languages[i])) {
+ result = languages[i+1];
+ break;
+ }
+ }
+
+ if (*country) {
+ for (int i = 0; i < 18; i += 2) {
+ if (!_stricmp(country, countries[i])) {
+ result.append(" - ");
+ result.append(countries[i+1]);
+ break;
+ }
+ }
+ }
+
+ }
+ return result;
+}
+
diff --git a/Magic2/Locale_ss.h b/Magic2/Locale_ss.h
index 551c379..29c12cf 100644
--- a/Magic2/Locale_ss.h
+++ b/Magic2/Locale_ss.h
@@ -1,53 +1,77 @@
-/* Project nGenEx
- Destroyer Studios LLC
- Copyright © 1997-2006. All Rights Reserved.
-
- SUBSYSTEM: nGenEx.lib
- FILE: Locale.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Description of locale by ISO language, country, and variant
-*/
-
-#ifndef Locale_h
-#define Locale_h
-
-#include "List.h"
-#include "Text.h"
-
-// +--------------------------------------------------------------------+
-
-class Locale
-{
-public:
- static const char* TYPENAME() { return "Locale"; }
-
- Locale(const char* language, const char* country=0, const char* variant=0);
- ~Locale();
-
- int operator == (const Locale& that) const;
-
- // Operations:
- static const List<Locale>& GetAllLocales();
- static Locale* ParseLocale(const char* str);
-
- // Property accessors:
- const char* GetLanguage() const { return language; }
- const char* GetCountry() const { return country; }
- const char* GetVariant() const { return variant; }
- const Text GetFullCode() const;
- const Text GetDisplayName() const;
-
-
-protected:
- static Locale* CreateLocale(const char* language, const char* country=0, const char* variant=0);
- char language[8];
- char country[8];
- char variant[8];
-};
-
-#endif Locale_h
-
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: nGenEx.lib
+ FILE: Locale.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Description of locale by ISO language, country, and variant
+*/
+
+#ifndef Locale_h
+#define Locale_h
+
+#include "List.h"
+#include "Text.h"
+
+// +--------------------------------------------------------------------+
+
+class Locale
+{
+public:
+ static const char* TYPENAME() { return "Locale"; }
+
+ Locale(const char* language, const char* country=0, const char* variant=0);
+ ~Locale();
+
+ int operator == (const Locale& that) const;
+
+ // Operations:
+ static const List<Locale>& GetAllLocales();
+ static Locale* ParseLocale(const char* str);
+
+ // Property accessors:
+ const char* GetLanguage() const { return language; }
+ const char* GetCountry() const { return country; }
+ const char* GetVariant() const { return variant; }
+ const Text GetFullCode() const;
+ const Text GetDisplayName() const;
+
+
+protected:
+ static Locale* CreateLocale(const char* language, const char* country=0, const char* variant=0);
+ char language[8];
+ char country[8];
+ char variant[8];
+};
+
+#endif Locale_h
+
diff --git a/Magic2/M3DS.cpp b/Magic2/M3DS.cpp
index 21ac41a..f5b5fc5 100644
--- a/Magic2/M3DS.cpp
+++ b/Magic2/M3DS.cpp
@@ -1,263 +1,287 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: ModelFile3DS.cpp
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- File loader for 3DStudio MAX 3DS format models
-*/
-
-#include "stdafx.h"
-#include "Magic.h"
-#include "MagicDoc.h"
-#include "ModelFile3DS.h"
-
-#include "Bitmap.h"
-#include "Polygon.h"
-#include "Text.h"
-#include "List.h"
-#include "ArrayList.h"
-
-// +--------------------------------------------------------------------+
-
-struct Chunk
-{
- WORD id;
- DWORD len;
- BYTE* start;
-
- List<Chunk> chunks;
-};
-
-// +--------------------------------------------------------------------+
-
-struct Vec2
-{
- float u,v;
-};
-
-struct Triangle
-{
- WORD a,b,c;
-};
-
-struct Triangle2
-{
- Vec3 vloc[3];
- Vec3 vnrm[3];
- Vec2 vtex[3];
- Vec3 fnrm;
- DWORD mtl_id;
-};
-
-struct TextureMap
-{
- char fname[256];
- float strength;
- float u_scale;
- float v_scale;
- float u_offset;
- float v_offset;
- float angle;
-};
-
-// +--------------------------------------------------------------------+
-
-class Object3DS
-{
-public:
- Object3DS();
- virtual ~Object3DS();
-
- virtual const char* GetName();
- virtual bool IsObject(const char* name);
-
-protected:
- Text name;
-};
-
-// +--------------------------------------------------------------------+
-
-class Material3DS : public Object3DS
-{
-public:
- Material3DS();
- virtual ~Material3DS();
-
- DWORD GetID();
- TextureMap& GetTextureMap1();
- TextureMap& GetTextureMap2();
- TextureMap& GetOpacityMap();
- TextureMap& GetSpecularMap();
- TextureMap& GetBumpMap();
- TextureMap& GetReflectionMap();
- ColorValue GetAmbientColor();
- ColorValue GetDiffuseColor();
- ColorValue GetSpecularColor();
- float GetShininess();
- float GetTransparency();
- DWORD GetShadingType();
-
- // this methods should not be used by the "user", they're used internally to fill the class
- // with valid data when reading from file. If you're about to add an importer for another format you'LL
- // have to use these methods
-
- void SetID(DWORD value);
- void SetAmbientColor(const ColorValue &color);
- void SetDiffuseColor(const ColorValue &color);
- void SetSpecularColor(const ColorValue &color);
- void SetShininess(float value);
- void SetTransparency(float value);
- void SetShadingType(DWORD shading);
-
-protected:
- int id;
- TextureMap texMap1;
- TextureMap texMap2;
- TextureMap opacMap;
- TextureMap refTextureMap;
- TextureMap bumpMap;
- TextureMap specMap;
- ColorValue ambient;
- ColorValue diffuse;
- ColorValue specular;
- float shininess;
- float transparency;
- DWORD shading;
-};
-
-// +--------------------------------------------------------------------+
-
-class Mesh3DS : public Object3DS
-{
-public:
- Mesh3DS();
- virtual ~Mesh3DS();
-
- void Clear();
-
- DWORD GetVertexCount();
- void SetVertexArraySize(DWORD value);
- DWORD GetTriangleCount();
- void SetTriangleArraySize(DWORD value);
-
- const Vec3& GetVertex(DWORD index);
- const Vec3& GetNormal(DWORD index);
- const Vec2& GetUV(DWORD index);
- const Vec3& GetTangent(DWORD index);
- const Vec3& GetBinormal(DWORD index);
-
- void SetVertex(const Vec3 &vec, DWORD index);
- void SetNormal(const Vec3 &vec, DWORD index);
- void SetUV(const Vec2 &vec, DWORD index);
- void SetTangent(const Vec3 &vec, DWORD index);
- void SetBinormal(const Vec3 &vec, DWORD index);
-
- const Triangle& GetTriangle(DWORD index);
- Triangle2 GetTriangle2(DWORD index);
-
- Matrix& GetMatrix();
- void SetMatrix(Matrix& m);
- void Optimize(int level);
-
- DWORD GetMaterial(DWORD index);
- DWORD AddMaterial(DWORD id);
- DWORD GetMaterialCount();
-
-protected:
- // the vertices, normals, etc.
- List<Vec3> vertices;
- List<Vec3> normals;
- List<Vec3> binormals;
- List<Vec3> tangents;
- List<Vec2> uv;
-
- // triangles
- List<Triangle> triangles;
-
- // the transformation matrix.
- Matrix matrix;
-
- // the material ID array
- ArrayList materials;
-
- void CalcNormals(bool useSmoothingGroups);
- void CalcTextureSpace();
-
- void TransformVertices();
-};
-
-
-// +--------------------------------------------------------------------+
-// +--------------------------------------------------------------------+
-// +--------------------------------------------------------------------+
-
-ModelFile3DS::ModelFile3DS(const char* fname)
- : ModelFile(fname)
-{
-}
-
-ModelFile3DS::~ModelFile3DS()
-{
-}
-
-// +--------------------------------------------------------------------+
-
-static int mcomp(const void* a, const void* b)
-{
- Poly* pa = (Poly*) a;
- Poly* pb = (Poly*) b;
-
- if (pa->sortval == pb->sortval)
- return 0;
-
- if (pa->sortval < pb->sortval)
- return 1;
-
- return -1;
-}
-
-bool
-ModelFile3DS::Load(Model* m, double scale)
-{
- if (m && scale > 0 && strlen(filename) > 0) {
- ModelFile::Load(m, scale);
-
- FILE* fp = fopen(filename, "rb");
- fclose(fp);
-
- m->Normalize();
- return true;
- }
-
- return false;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-ModelFile3DS::Save(Model* m)
-{
- if (m) {
- ModelFile::Save(m);
-
- FILE* f = fopen(filename, "w");
- if (!f) {
- ::MessageBox(0, "Export Failed: Magic could not open the file for writing", "ERROR", MB_OK);
- return false;
- }
-
- fclose(f);
-
- return true;
- }
-
- return false;
-}
-
-// +--------------------------------------------------------------------+
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: ModelFile3DS.cpp
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ File loader for 3DStudio MAX 3DS format models
+*/
+
+#include "stdafx.h"
+#include "Magic.h"
+#include "MagicDoc.h"
+#include "ModelFile3DS.h"
+
+#include "Bitmap.h"
+#include "Polygon.h"
+#include "Text.h"
+#include "List.h"
+#include "ArrayList.h"
+
+// +--------------------------------------------------------------------+
+
+struct Chunk
+{
+ WORD id;
+ DWORD len;
+ BYTE* start;
+
+ List<Chunk> chunks;
+};
+
+// +--------------------------------------------------------------------+
+
+struct Vec2
+{
+ float u,v;
+};
+
+struct Triangle
+{
+ WORD a,b,c;
+};
+
+struct Triangle2
+{
+ Vec3 vloc[3];
+ Vec3 vnrm[3];
+ Vec2 vtex[3];
+ Vec3 fnrm;
+ DWORD mtl_id;
+};
+
+struct TextureMap
+{
+ char fname[256];
+ float strength;
+ float u_scale;
+ float v_scale;
+ float u_offset;
+ float v_offset;
+ float angle;
+};
+
+// +--------------------------------------------------------------------+
+
+class Object3DS
+{
+public:
+ Object3DS();
+ virtual ~Object3DS();
+
+ virtual const char* GetName();
+ virtual bool IsObject(const char* name);
+
+protected:
+ Text name;
+};
+
+// +--------------------------------------------------------------------+
+
+class Material3DS : public Object3DS
+{
+public:
+ Material3DS();
+ virtual ~Material3DS();
+
+ DWORD GetID();
+ TextureMap& GetTextureMap1();
+ TextureMap& GetTextureMap2();
+ TextureMap& GetOpacityMap();
+ TextureMap& GetSpecularMap();
+ TextureMap& GetBumpMap();
+ TextureMap& GetReflectionMap();
+ ColorValue GetAmbientColor();
+ ColorValue GetDiffuseColor();
+ ColorValue GetSpecularColor();
+ float GetShininess();
+ float GetTransparency();
+ DWORD GetShadingType();
+
+ // this methods should not be used by the "user", they're used internally to fill the class
+ // with valid data when reading from file. If you're about to add an importer for another format you'LL
+ // have to use these methods
+
+ void SetID(DWORD value);
+ void SetAmbientColor(const ColorValue &color);
+ void SetDiffuseColor(const ColorValue &color);
+ void SetSpecularColor(const ColorValue &color);
+ void SetShininess(float value);
+ void SetTransparency(float value);
+ void SetShadingType(DWORD shading);
+
+protected:
+ int id;
+ TextureMap texMap1;
+ TextureMap texMap2;
+ TextureMap opacMap;
+ TextureMap refTextureMap;
+ TextureMap bumpMap;
+ TextureMap specMap;
+ ColorValue ambient;
+ ColorValue diffuse;
+ ColorValue specular;
+ float shininess;
+ float transparency;
+ DWORD shading;
+};
+
+// +--------------------------------------------------------------------+
+
+class Mesh3DS : public Object3DS
+{
+public:
+ Mesh3DS();
+ virtual ~Mesh3DS();
+
+ void Clear();
+
+ DWORD GetVertexCount();
+ void SetVertexArraySize(DWORD value);
+ DWORD GetTriangleCount();
+ void SetTriangleArraySize(DWORD value);
+
+ const Vec3& GetVertex(DWORD index);
+ const Vec3& GetNormal(DWORD index);
+ const Vec2& GetUV(DWORD index);
+ const Vec3& GetTangent(DWORD index);
+ const Vec3& GetBinormal(DWORD index);
+
+ void SetVertex(const Vec3 &vec, DWORD index);
+ void SetNormal(const Vec3 &vec, DWORD index);
+ void SetUV(const Vec2 &vec, DWORD index);
+ void SetTangent(const Vec3 &vec, DWORD index);
+ void SetBinormal(const Vec3 &vec, DWORD index);
+
+ const Triangle& GetTriangle(DWORD index);
+ Triangle2 GetTriangle2(DWORD index);
+
+ Matrix& GetMatrix();
+ void SetMatrix(Matrix& m);
+ void Optimize(int level);
+
+ DWORD GetMaterial(DWORD index);
+ DWORD AddMaterial(DWORD id);
+ DWORD GetMaterialCount();
+
+protected:
+ // the vertices, normals, etc.
+ List<Vec3> vertices;
+ List<Vec3> normals;
+ List<Vec3> binormals;
+ List<Vec3> tangents;
+ List<Vec2> uv;
+
+ // triangles
+ List<Triangle> triangles;
+
+ // the transformation matrix.
+ Matrix matrix;
+
+ // the material ID array
+ ArrayList materials;
+
+ void CalcNormals(bool useSmoothingGroups);
+ void CalcTextureSpace();
+
+ void TransformVertices();
+};
+
+
+// +--------------------------------------------------------------------+
+// +--------------------------------------------------------------------+
+// +--------------------------------------------------------------------+
+
+ModelFile3DS::ModelFile3DS(const char* fname)
+ : ModelFile(fname)
+{
+}
+
+ModelFile3DS::~ModelFile3DS()
+{
+}
+
+// +--------------------------------------------------------------------+
+
+static int mcomp(const void* a, const void* b)
+{
+ Poly* pa = (Poly*) a;
+ Poly* pb = (Poly*) b;
+
+ if (pa->sortval == pb->sortval)
+ return 0;
+
+ if (pa->sortval < pb->sortval)
+ return 1;
+
+ return -1;
+}
+
+bool
+ModelFile3DS::Load(Model* m, double scale)
+{
+ if (m && scale > 0 && strlen(filename) > 0) {
+ ModelFile::Load(m, scale);
+
+ FILE* fp = fopen(filename, "rb");
+ fclose(fp);
+
+ m->Normalize();
+ return true;
+ }
+
+ return false;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+ModelFile3DS::Save(Model* m)
+{
+ if (m) {
+ ModelFile::Save(m);
+
+ FILE* f = fopen(filename, "w");
+ if (!f) {
+ ::MessageBox(0, "Export Failed: Magic could not open the file for writing", "ERROR", MB_OK);
+ return false;
+ }
+
+ fclose(f);
+
+ return true;
+ }
+
+ return false;
+}
+
+// +--------------------------------------------------------------------+
diff --git a/Magic2/M3DS.h b/Magic2/M3DS.h
index b60ff71..f9b002a 100644
--- a/Magic2/M3DS.h
+++ b/Magic2/M3DS.h
@@ -1,329 +1,353 @@
-/* Project nGenEx
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: nGenEx.lib
- FILE: M3DS.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Window class
-*/
-
-// parts copyright (c) 2001-2002 Lev Povalahev
-
-#ifndef M3DS_H
-#define M3DS_H
-
-#include "List.h"
-
-// +--------------------------------------------------------------------+
-
-struct Chunk
-{
- WORD id;
- DWORD len;
- BYTE* start;
-
- List<Chunk> chunks;
-};
-
-// +--------------------------------------------------------------------+
-
-struct LTriangle
-{
- WORD a,b,c;
-};
-
-struct LTriangle2
-{
- Point vertices[3];
- Vec3 vertexNormals[3];
- LVector2 textureCoords[3];
- Vec3 faceNormal;
- DWORD materialId;
-};
-
-struct TextureMap
-{
- char fname[256];
- float strength;
- float u_scale;
- float v_scale;
- float u_offset;
- float v_offset;
- float angle;
-};
-
-// +--------------------------------------------------------------------+
-
-class LObject
-{
-public:
- LObject();
- virtual ~LObject();
-
- virtual const char* GetName();
- virtual bool IsObject(const const char* name);
-
-protected:
- Text name;
-};
-
-// +--------------------------------------------------------------------+
-
-class LMaterial : public LObject
-{
-public:
- LMaterial();
- virtual ~LMaterial();
-
- DWORD GetID();
- TextureMap& GetTextureMap1();
- TextureMap& GetTextureMap2();
- TextureMap& GetOpacityMap();
- TextureMap& GetSpecularMap();
- TextureMap& GetBumpMap();
- TextureMap& GetReflectionMap();
- ColorValue GetAmbientColor();
- ColorValue GetDiffuseColor();
- ColorValue GetSpecularColor();
- float GetShininess();
- float GetTransparency();
- DWORD GetShadingType();
-
- // this methods should not be used by the "user", they're used internally to fill the class
- // with valid data when reading from file. If you're about to add an importer for another format you'LL
- // have to use these methods
-
- void SetID(DWORD value);
- void SetAmbientColor(const ColorValue &color);
- void SetDiffuseColor(const ColorValue &color);
- void SetSpecularColor(const ColorValue &color);
- void SetShininess(float value);
- void SetTransparency(float value);
- void SetShadingType(DWORD shading);
-
-protected:
- int id;
- TextureMap texMap1;
- TextureMap texMap2;
- TextureMap opacMap;
- TextureMap refTextureMap;
- TextureMap bumpMap;
- TextureMap specMap;
- ColorValue ambient;
- ColorValue diffuse;
- ColorValue specular;
- float shininess;
- float transparency;
- DWORD shading;
-};
-
-// +--------------------------------------------------------------------+
-
-class LMesh : public LObject
-{
-public:
- LMesh();
- virtual ~LMesh();
-
- void Clear();
-
- DWORD GetVertexCount();
- void SetVertexArraySize(DWORD value);
- DWORD GetTriangleCount();
- void SetTriangleArraySize(DWORD value);
-
- // returns given vertex
- const LVector4& GetVertex(DWORD index);
- // returns the given normal
- const LVector3& GetNormal(DWORD index);
- // returns the given texture coordinates vector
- const LVector2& GetUV(DWORD index);
- // returns the pointer to the array of tangents
- const LVector3& GetTangent(DWORD index);
- // returns the pointer to the array of binormals
- const LVector3& GetBinormal(DWORD index);
- // sets the vertex at a given index to "vec" - for internal use
- void SetVertex(const LVector4 &vec, DWORD index);
- // sets the normal at a given index to "vec" - for internal use
- void SetNormal(const LVector3 &vec, DWORD index);
- // sets the texture coordinates vector at a given index to "vec" - for internal use
- void SetUV(const LVector2 &vec, DWORD index);
- // sets the tangent at a given index to "vec" - for internal use
- void SetTangent(const LVector3 &vec, DWORD index);
- // sets the binormal at a given index to "vec" - for internal use
- void SetBinormal(const LVector3 &vec, DWORD index);
- // returns the triangle with a given index
- const LTriangle& GetTriangle(DWORD index);
- // returns the triangle with a given index, see LTriangle2 structure description
- LTriangle2 GetTriangle2(DWORD index);
- // returns the mesh matrix, should be identity matrix after loading
- LMatrix4 GetMatrix();
- // sets the mesh matrix to a given matrix - for internal use
- void SetMatrix(LMatrix4 m);
- // optimizises the mesh using a given optimization level
- void Optimize(LOptimizationLevel value);
- // sets an internal triangle structure with index "index" - for internal use only
- void SetTri(const LTri &tri, DWORD index);
- // returns the pointer to the internal triangle structure - for internal use only
- LTri& GetTri(DWORD index);
- // returns the material id with a given index for the mesh
- DWORD GetMaterial(DWORD index);
- // adds a material to the mesh and returns its index - for internal use
- DWORD AddMaterial(DWORD id);
- // returns the number of materials used in the mesh
- DWORD GetMaterialCount();
-protected:
- // the vertices, normals, etc.
- List<LVector4> vertices;
- List<LVector3> normals;
- List<LVector3> binormals;
- List<LVector3> tangents;
- List<LVector2> uv;
-
- // triangles
- List<LTriangle> triangles;
-
- //used internally
- List<LTri> tris;
-
- // the transformation matrix.
- Matrix matrix;
-
- // the material ID array
- List<DWORD> materials;
-
- // calculates the normals, either using the smoothing groups information or not
- void CalcNormals(bool useSmoothingGroups);
- // calculates the texture(tangent) space for each vertex
- void CalcTextureSpace();
- // transforms the vertices by the mesh matrix
- void TransformVertices();
-};
-
-//------------------------------------------------
-
-class LImporter
-{
-public:
- // the default constructor
- LImporter();
- // the destructor
- virtual ~LImporter();
- // reads the model from a file, must be overriden by the child classes
- virtual bool LoadFile(const char *filename) = 0;
- // returns the number of meshes in the scene
- DWORD GetMeshCount();
- // returns the number of lights in the scene
- DWORD GetLightCount();
- // returns the number of materials in the scene
- DWORD GetMaterialCount();
- // returns a pointer to a mesh
- LMesh& GetMesh(DWORD index);
- // returns a pointer to a light at a given index
- LLight& GetLight(DWORD index);
- // returns the pointer to the material
- LMaterial& GetMaterial(DWORD index);
- // returns the pointer to the material with a given name, or NULL if the material was not found
- LMaterial* FindMaterial(const Text &name);
- // returns the pointer to the mesh with a given name, or NULL if the mesh with such name
- // is not present in the scene
- LMesh* FindMesh(const Text &name);
- // returns the pointer to the light with a given name, or NULL if not found
- LLight* FindLight(const Text &name);
- // sets the optimization level to a given value
- void SetOptimizationLevel(LOptimizationLevel value);
- // returns the current optimization level
- LOptimizationLevel GetOptimizationLevel();
-protected:
- // the lights found in the scene
- List<LLight> lights;
- // triangular meshes
- List<LMesh> meshes;
- // the materials in the scene
- List<LMaterial> materials;
- // level of optimization to perform on the meshes
- LOptimizationLevel optLevel;
- // clears all data.
- virtual void Clear();
-};
-//------------------------------------------------
-
-class L3DS : public LImporter
-{
-public:
- // the default contructor
- L3DS();
- // constructs the object and loads the file
- L3DS(const char *filename);
- // destructor
- virtual ~L3DS();
- // load 3ds file
- virtual bool LoadFile(const char *filename);
-protected:
- // used internally for reading
- char objName[100];
- // true if end of file is reached
- bool eof;
- // buffer for loading, used for speedup
- unsigned char *buffer;
- // the size of the buffer
- DWORD bufferSize;
- // the current cursor position in the buffer
- DWORD pos;
-
- // reads a short value from the buffer
- short ReadShort();
- // reads an int value from the buffer
- int ReadInt();
- // reads a char from the buffer
- char ReadChar();
- //reada a floatvalue from the buffer
- float ReadFloat();
- //reads an unsigned byte from the buffer
- byte ReadByte();
- //reads an asciiz string
- int ReadASCIIZ(char *buf, int max_count);
- // seek wihtin the buffer
- void Seek(int offset, int origin);
- // returns the position of the cursor
- DWORD Pos();
-
- // read the chunk and return it.
- LChunk ReadChunk();
- // read until given chunk is found
- bool FindChunk(LChunk &target, const LChunk &parent);
- // skip to the end of chunk "chunk"
- void SkipChunk(const LChunk &chunk);
- // goes to the beginning of the data in teh given chunk
- void GotoChunk(const LChunk &chunk);
-
- // the function read the color chunk (any of the color chunks)
- ColorValue ReadColor(const LChunk &chunk);
- // the function that read the percentage chunk and returns a float from 0 to 1
- float ReadPercentage(const LChunk &chunk);
- // this is where 3ds file is being read
- bool Read3DS();
- // read a light chunk
- void ReadLight(const LChunk &parent);
- // read a trimesh chunk
- void ReadMesh(const LChunk &parent);
- // reads the face list, face materials, smoothing groups... and fill rthe information into the mesh
- void ReadFaceList(const LChunk &chunk, LMesh &mesh);
- // reads the material
- void ReadMaterial(const LChunk &parent);
- // reads the map info and fills the given map with this information
- void ReadMap(const LChunk &chunk, TextureMap& map);
- // reads keyframer data of the OBJECT_NODE_TAG chunk
- void ReadKeyframeData(const LChunk &parent);
- // reads the keyheader structure from the current offset and returns the frame number
- long ReadKeyheader();
-};
-
-//---------------------------------------------------------
-
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: nGenEx.lib
+ FILE: M3DS.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Window class
+*/
+
+// parts copyright (c) 2001-2002 Lev Povalahev
+
+#ifndef M3DS_H
+#define M3DS_H
+
+#include "List.h"
+
+// +--------------------------------------------------------------------+
+
+struct Chunk
+{
+ WORD id;
+ DWORD len;
+ BYTE* start;
+
+ List<Chunk> chunks;
+};
+
+// +--------------------------------------------------------------------+
+
+struct LTriangle
+{
+ WORD a,b,c;
+};
+
+struct LTriangle2
+{
+ Point vertices[3];
+ Vec3 vertexNormals[3];
+ LVector2 textureCoords[3];
+ Vec3 faceNormal;
+ DWORD materialId;
+};
+
+struct TextureMap
+{
+ char fname[256];
+ float strength;
+ float u_scale;
+ float v_scale;
+ float u_offset;
+ float v_offset;
+ float angle;
+};
+
+// +--------------------------------------------------------------------+
+
+class LObject
+{
+public:
+ LObject();
+ virtual ~LObject();
+
+ virtual const char* GetName();
+ virtual bool IsObject(const const char* name);
+
+protected:
+ Text name;
+};
+
+// +--------------------------------------------------------------------+
+
+class LMaterial : public LObject
+{
+public:
+ LMaterial();
+ virtual ~LMaterial();
+
+ DWORD GetID();
+ TextureMap& GetTextureMap1();
+ TextureMap& GetTextureMap2();
+ TextureMap& GetOpacityMap();
+ TextureMap& GetSpecularMap();
+ TextureMap& GetBumpMap();
+ TextureMap& GetReflectionMap();
+ ColorValue GetAmbientColor();
+ ColorValue GetDiffuseColor();
+ ColorValue GetSpecularColor();
+ float GetShininess();
+ float GetTransparency();
+ DWORD GetShadingType();
+
+ // this methods should not be used by the "user", they're used internally to fill the class
+ // with valid data when reading from file. If you're about to add an importer for another format you'LL
+ // have to use these methods
+
+ void SetID(DWORD value);
+ void SetAmbientColor(const ColorValue &color);
+ void SetDiffuseColor(const ColorValue &color);
+ void SetSpecularColor(const ColorValue &color);
+ void SetShininess(float value);
+ void SetTransparency(float value);
+ void SetShadingType(DWORD shading);
+
+protected:
+ int id;
+ TextureMap texMap1;
+ TextureMap texMap2;
+ TextureMap opacMap;
+ TextureMap refTextureMap;
+ TextureMap bumpMap;
+ TextureMap specMap;
+ ColorValue ambient;
+ ColorValue diffuse;
+ ColorValue specular;
+ float shininess;
+ float transparency;
+ DWORD shading;
+};
+
+// +--------------------------------------------------------------------+
+
+class LMesh : public LObject
+{
+public:
+ LMesh();
+ virtual ~LMesh();
+
+ void Clear();
+
+ DWORD GetVertexCount();
+ void SetVertexArraySize(DWORD value);
+ DWORD GetTriangleCount();
+ void SetTriangleArraySize(DWORD value);
+
+ // returns given vertex
+ const LVector4& GetVertex(DWORD index);
+ // returns the given normal
+ const LVector3& GetNormal(DWORD index);
+ // returns the given texture coordinates vector
+ const LVector2& GetUV(DWORD index);
+ // returns the pointer to the array of tangents
+ const LVector3& GetTangent(DWORD index);
+ // returns the pointer to the array of binormals
+ const LVector3& GetBinormal(DWORD index);
+ // sets the vertex at a given index to "vec" - for internal use
+ void SetVertex(const LVector4 &vec, DWORD index);
+ // sets the normal at a given index to "vec" - for internal use
+ void SetNormal(const LVector3 &vec, DWORD index);
+ // sets the texture coordinates vector at a given index to "vec" - for internal use
+ void SetUV(const LVector2 &vec, DWORD index);
+ // sets the tangent at a given index to "vec" - for internal use
+ void SetTangent(const LVector3 &vec, DWORD index);
+ // sets the binormal at a given index to "vec" - for internal use
+ void SetBinormal(const LVector3 &vec, DWORD index);
+ // returns the triangle with a given index
+ const LTriangle& GetTriangle(DWORD index);
+ // returns the triangle with a given index, see LTriangle2 structure description
+ LTriangle2 GetTriangle2(DWORD index);
+ // returns the mesh matrix, should be identity matrix after loading
+ LMatrix4 GetMatrix();
+ // sets the mesh matrix to a given matrix - for internal use
+ void SetMatrix(LMatrix4 m);
+ // optimizises the mesh using a given optimization level
+ void Optimize(LOptimizationLevel value);
+ // sets an internal triangle structure with index "index" - for internal use only
+ void SetTri(const LTri &tri, DWORD index);
+ // returns the pointer to the internal triangle structure - for internal use only
+ LTri& GetTri(DWORD index);
+ // returns the material id with a given index for the mesh
+ DWORD GetMaterial(DWORD index);
+ // adds a material to the mesh and returns its index - for internal use
+ DWORD AddMaterial(DWORD id);
+ // returns the number of materials used in the mesh
+ DWORD GetMaterialCount();
+protected:
+ // the vertices, normals, etc.
+ List<LVector4> vertices;
+ List<LVector3> normals;
+ List<LVector3> binormals;
+ List<LVector3> tangents;
+ List<LVector2> uv;
+
+ // triangles
+ List<LTriangle> triangles;
+
+ //used internally
+ List<LTri> tris;
+
+ // the transformation matrix.
+ Matrix matrix;
+
+ // the material ID array
+ List<DWORD> materials;
+
+ // calculates the normals, either using the smoothing groups information or not
+ void CalcNormals(bool useSmoothingGroups);
+ // calculates the texture(tangent) space for each vertex
+ void CalcTextureSpace();
+ // transforms the vertices by the mesh matrix
+ void TransformVertices();
+};
+
+//------------------------------------------------
+
+class LImporter
+{
+public:
+ // the default constructor
+ LImporter();
+ // the destructor
+ virtual ~LImporter();
+ // reads the model from a file, must be overriden by the child classes
+ virtual bool LoadFile(const char *filename) = 0;
+ // returns the number of meshes in the scene
+ DWORD GetMeshCount();
+ // returns the number of lights in the scene
+ DWORD GetLightCount();
+ // returns the number of materials in the scene
+ DWORD GetMaterialCount();
+ // returns a pointer to a mesh
+ LMesh& GetMesh(DWORD index);
+ // returns a pointer to a light at a given index
+ LLight& GetLight(DWORD index);
+ // returns the pointer to the material
+ LMaterial& GetMaterial(DWORD index);
+ // returns the pointer to the material with a given name, or NULL if the material was not found
+ LMaterial* FindMaterial(const Text &name);
+ // returns the pointer to the mesh with a given name, or NULL if the mesh with such name
+ // is not present in the scene
+ LMesh* FindMesh(const Text &name);
+ // returns the pointer to the light with a given name, or NULL if not found
+ LLight* FindLight(const Text &name);
+ // sets the optimization level to a given value
+ void SetOptimizationLevel(LOptimizationLevel value);
+ // returns the current optimization level
+ LOptimizationLevel GetOptimizationLevel();
+protected:
+ // the lights found in the scene
+ List<LLight> lights;
+ // triangular meshes
+ List<LMesh> meshes;
+ // the materials in the scene
+ List<LMaterial> materials;
+ // level of optimization to perform on the meshes
+ LOptimizationLevel optLevel;
+ // clears all data.
+ virtual void Clear();
+};
+//------------------------------------------------
+
+class L3DS : public LImporter
+{
+public:
+ // the default contructor
+ L3DS();
+ // constructs the object and loads the file
+ L3DS(const char *filename);
+ // destructor
+ virtual ~L3DS();
+ // load 3ds file
+ virtual bool LoadFile(const char *filename);
+protected:
+ // used internally for reading
+ char objName[100];
+ // true if end of file is reached
+ bool eof;
+ // buffer for loading, used for speedup
+ unsigned char *buffer;
+ // the size of the buffer
+ DWORD bufferSize;
+ // the current cursor position in the buffer
+ DWORD pos;
+
+ // reads a short value from the buffer
+ short ReadShort();
+ // reads an int value from the buffer
+ int ReadInt();
+ // reads a char from the buffer
+ char ReadChar();
+ //reada a floatvalue from the buffer
+ float ReadFloat();
+ //reads an unsigned byte from the buffer
+ byte ReadByte();
+ //reads an asciiz string
+ int ReadASCIIZ(char *buf, int max_count);
+ // seek wihtin the buffer
+ void Seek(int offset, int origin);
+ // returns the position of the cursor
+ DWORD Pos();
+
+ // read the chunk and return it.
+ LChunk ReadChunk();
+ // read until given chunk is found
+ bool FindChunk(LChunk &target, const LChunk &parent);
+ // skip to the end of chunk "chunk"
+ void SkipChunk(const LChunk &chunk);
+ // goes to the beginning of the data in teh given chunk
+ void GotoChunk(const LChunk &chunk);
+
+ // the function read the color chunk (any of the color chunks)
+ ColorValue ReadColor(const LChunk &chunk);
+ // the function that read the percentage chunk and returns a float from 0 to 1
+ float ReadPercentage(const LChunk &chunk);
+ // this is where 3ds file is being read
+ bool Read3DS();
+ // read a light chunk
+ void ReadLight(const LChunk &parent);
+ // read a trimesh chunk
+ void ReadMesh(const LChunk &parent);
+ // reads the face list, face materials, smoothing groups... and fill rthe information into the mesh
+ void ReadFaceList(const LChunk &chunk, LMesh &mesh);
+ // reads the material
+ void ReadMaterial(const LChunk &parent);
+ // reads the map info and fills the given map with this information
+ void ReadMap(const LChunk &chunk, TextureMap& map);
+ // reads keyframer data of the OBJECT_NODE_TAG chunk
+ void ReadKeyframeData(const LChunk &parent);
+ // reads the keyheader structure from the current offset and returns the frame number
+ long ReadKeyheader();
+};
+
+//---------------------------------------------------------
+
#endif \ No newline at end of file
diff --git a/Magic2/Magic.cpp b/Magic2/Magic.cpp
index d9d626a..f1bc859 100644
--- a/Magic2/Magic.cpp
+++ b/Magic2/Magic.cpp
@@ -1,202 +1,226 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: Magic.cpp
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Implementation of the main application class
-*/
-
-#include "stdafx.h"
-#include "Magic.h"
-
-#include "MainFrm.h"
-#include "MagicDoc.h"
-#include "MagicView.h"
-
-#include "MachineInfo.h"
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
-#endif
-
-// +--------------------------------------------------------------------+
-
-BEGIN_MESSAGE_MAP(Magic, CWinApp)
- //{{AFX_MSG_MAP(Magic)
- ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
- // NOTE - the ClassWizard will add and remove mapping macros here.
- // DO NOT EDIT what you see in these blocks of generated code!
- //}}AFX_MSG_MAP
- // Standard file based document commands
- ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
- ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
- // Standard print setup command
- ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
-END_MESSAGE_MAP()
-
-// +--------------------------------------------------------------------+
-
-extern FILE* ErrLog;
-extern int VD3D_describe_things;
-void Print(const char* msg, ...);
-
-static void PrintLogHeader()
-{
- ErrLog = fopen("errlog.txt", "w");
- Print("+====================================================================+\n");
- Print("| Magic 2.0 |\n");
-
- VD3D_describe_things = 4;
- MachineInfo::DescribeMachine();
-}
-
-// +--------------------------------------------------------------------+
-
-Magic::Magic()
-{
- PrintLogHeader();
-}
-
-Magic::~Magic()
-{
- Print("+====================================================================+\n");
- Print(" END OF LINE.\n");
-
- fclose(ErrLog);
-}
-
-// +--------------------------------------------------------------------+
-//
-// The one and only Magic object
-
-Magic theApp;
-
-// +--------------------------------------------------------------------+
-//
-// Magic initialization
-
-BOOL Magic::InitInstance()
-{
- AfxEnableControlContainer();
-
- // Standard initialization
- // If you are not using these features and wish to reduce the size
- // of your final executable, you should remove from the following
- // the specific initialization routines you do not need.
-
-//#ifdef _AFXDLL
-// Enable3dControls(); // Call this when using MFC in a shared DLL
-//#else
-// Enable3dControlsStatic(); // Call this when linking to MFC statically
-//#endif
-
- // Change the registry key under which our settings are stored.
- // TODO: You should modify this string to be something appropriate
- // such as the name of your company or organization.
- SetRegistryKey(_T("Local AppWizard-Generated Applications"));
-
- LoadStdProfileSettings(); // Load standard INI file options (including MRU)
-
- // Register the application's document templates. Document templates
- // serve as the connection between documents, frame windows and views.
-
- CSingleDocTemplate* pDocTemplate;
- pDocTemplate = new CSingleDocTemplate(
- IDR_MAINFRAME,
- RUNTIME_CLASS(MagicDoc),
- RUNTIME_CLASS(MainFrame), // main SDI frame window
- RUNTIME_CLASS(MagicView));
- AddDocTemplate(pDocTemplate);
-
- // Parse command line for standard shell commands, DDE, file open
- CCommandLineInfo cmdInfo;
- ParseCommandLine(cmdInfo);
-
- // Dispatch commands specified on the command line
- if (!ProcessShellCommand(cmdInfo))
- return FALSE;
-
- // The one and only window has been initialized, so show and update it.
- m_pMainWnd->ShowWindow(SW_SHOW);
- m_pMainWnd->UpdateWindow();
-
- return TRUE;
-}
-
-
-// +--------------------------------------------------------------------+
-//
-// CAboutDlg dialog used for App About
-
-class CAboutDlg : public CDialog
-{
-public:
- CAboutDlg();
-
-// Dialog Data
- //{{AFX_DATA(CAboutDlg)
- enum { IDD = IDD_ABOUTBOX };
- //}}AFX_DATA
-
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(CAboutDlg)
- protected:
- virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
- //}}AFX_VIRTUAL
-
-// Implementation
-protected:
- //{{AFX_MSG(CAboutDlg)
- // No message handlers
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
-};
-
-CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
-{
- //{{AFX_DATA_INIT(CAboutDlg)
- //}}AFX_DATA_INIT
-}
-
-void CAboutDlg::DoDataExchange(CDataExchange* pDX)
-{
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CAboutDlg)
- //}}AFX_DATA_MAP
-}
-
-BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
- //{{AFX_MSG_MAP(CAboutDlg)
- // No message handlers
- //}}AFX_MSG_MAP
-END_MESSAGE_MAP()
-
-// App command to run the dialog
-void Magic::OnAppAbout()
-{
- CAboutDlg aboutDlg;
- aboutDlg.DoModal();
-}
-
-// +--------------------------------------------------------------------+
-//
-// Magic message handlers
-
-BOOL Magic::OnIdle(LONG lCount)
-{
- CWinApp::OnIdle(lCount);
-
- if (!app_active)
- Sleep(50);
-
- m_pMainWnd->SendMessage(WM_COMMAND, ID_VIEW_RENDER);
- return TRUE; // always request more time
-}
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: Magic.cpp
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Implementation of the main application class
+*/
+
+#include "stdafx.h"
+#include "Magic.h"
+
+#include "MainFrm.h"
+#include "MagicDoc.h"
+#include "MagicView.h"
+
+#include "MachineInfo.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+// +--------------------------------------------------------------------+
+
+BEGIN_MESSAGE_MAP(Magic, CWinApp)
+ //{{AFX_MSG_MAP(Magic)
+ ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
+ // NOTE - the ClassWizard will add and remove mapping macros here.
+ // DO NOT EDIT what you see in these blocks of generated code!
+ //}}AFX_MSG_MAP
+ // Standard file based document commands
+ ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
+ ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
+ // Standard print setup command
+ ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
+END_MESSAGE_MAP()
+
+// +--------------------------------------------------------------------+
+
+extern FILE* ErrLog;
+extern int VD3D_describe_things;
+void Print(const char* msg, ...);
+
+static void PrintLogHeader()
+{
+ ErrLog = fopen("errlog.txt", "w");
+ Print("+====================================================================+\n");
+ Print("| Magic 2.0 |\n");
+
+ VD3D_describe_things = 4;
+ MachineInfo::DescribeMachine();
+}
+
+// +--------------------------------------------------------------------+
+
+Magic::Magic()
+{
+ PrintLogHeader();
+}
+
+Magic::~Magic()
+{
+ Print("+====================================================================+\n");
+ Print(" END OF LINE.\n");
+
+ fclose(ErrLog);
+}
+
+// +--------------------------------------------------------------------+
+//
+// The one and only Magic object
+
+Magic theApp;
+
+// +--------------------------------------------------------------------+
+//
+// Magic initialization
+
+BOOL Magic::InitInstance()
+{
+ AfxEnableControlContainer();
+
+ // Standard initialization
+ // If you are not using these features and wish to reduce the size
+ // of your final executable, you should remove from the following
+ // the specific initialization routines you do not need.
+
+//#ifdef _AFXDLL
+// Enable3dControls(); // Call this when using MFC in a shared DLL
+//#else
+// Enable3dControlsStatic(); // Call this when linking to MFC statically
+//#endif
+
+ // Change the registry key under which our settings are stored.
+ // TODO: You should modify this string to be something appropriate
+ // such as the name of your company or organization.
+ SetRegistryKey(_T("Local AppWizard-Generated Applications"));
+
+ LoadStdProfileSettings(); // Load standard INI file options (including MRU)
+
+ // Register the application's document templates. Document templates
+ // serve as the connection between documents, frame windows and views.
+
+ CSingleDocTemplate* pDocTemplate;
+ pDocTemplate = new CSingleDocTemplate(
+ IDR_MAINFRAME,
+ RUNTIME_CLASS(MagicDoc),
+ RUNTIME_CLASS(MainFrame), // main SDI frame window
+ RUNTIME_CLASS(MagicView));
+ AddDocTemplate(pDocTemplate);
+
+ // Parse command line for standard shell commands, DDE, file open
+ CCommandLineInfo cmdInfo;
+ ParseCommandLine(cmdInfo);
+
+ // Dispatch commands specified on the command line
+ if (!ProcessShellCommand(cmdInfo))
+ return FALSE;
+
+ // The one and only window has been initialized, so show and update it.
+ m_pMainWnd->ShowWindow(SW_SHOW);
+ m_pMainWnd->UpdateWindow();
+
+ return TRUE;
+}
+
+
+// +--------------------------------------------------------------------+
+//
+// CAboutDlg dialog used for App About
+
+class CAboutDlg : public CDialog
+{
+public:
+ CAboutDlg();
+
+// Dialog Data
+ //{{AFX_DATA(CAboutDlg)
+ enum { IDD = IDD_ABOUTBOX };
+ //}}AFX_DATA
+
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CAboutDlg)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+ //{{AFX_MSG(CAboutDlg)
+ // No message handlers
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
+{
+ //{{AFX_DATA_INIT(CAboutDlg)
+ //}}AFX_DATA_INIT
+}
+
+void CAboutDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CAboutDlg)
+ //}}AFX_DATA_MAP
+}
+
+BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
+ //{{AFX_MSG_MAP(CAboutDlg)
+ // No message handlers
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+// App command to run the dialog
+void Magic::OnAppAbout()
+{
+ CAboutDlg aboutDlg;
+ aboutDlg.DoModal();
+}
+
+// +--------------------------------------------------------------------+
+//
+// Magic message handlers
+
+BOOL Magic::OnIdle(LONG lCount)
+{
+ CWinApp::OnIdle(lCount);
+
+ if (!app_active)
+ Sleep(50);
+
+ m_pMainWnd->SendMessage(WM_COMMAND, ID_VIEW_RENDER);
+ return TRUE; // always request more time
+}
diff --git a/Magic2/Magic.h b/Magic2/Magic.h
index 07318b1..8320542 100644
--- a/Magic2/Magic.h
+++ b/Magic2/Magic.h
@@ -1,63 +1,87 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: Magic.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Interface of the main application class
-*/
-
-
-#if !defined(AFX_MAGIC_H__E61FB5C3_42B6_42D1_BEFA_17F0B038E33B__INCLUDED_)
-#define AFX_MAGIC_H__E61FB5C3_42B6_42D1_BEFA_17F0B038E33B__INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-#ifndef __AFXWIN_H__
- #error include 'stdafx.h' before including this file for PCH
-#endif
-
-#include "resource.h" // main symbols
-
-
-class Magic : public CWinApp
-{
-public:
- Magic();
- virtual ~Magic();
-
- bool AppActivated() const { return app_active; }
- void SetAppActivated(bool a) { app_active = a; }
-
-// Overrides
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(Magic)
- public:
- virtual BOOL InitInstance();
- virtual BOOL OnIdle(LONG lCount);
- //}}AFX_VIRTUAL
-
-// Implementation
- //{{AFX_MSG(Magic)
- afx_msg void OnAppAbout();
- // NOTE - the ClassWizard will add and remove member functions here.
- // DO NOT EDIT what you see in these blocks of generated code !
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
-
-private:
- bool app_active;
-};
-
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
-
-#endif // !defined(AFX_MAGIC_H__E61FB5C3_42B6_42D1_BEFA_17F0B038E33B__INCLUDED_)
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: Magic.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Interface of the main application class
+*/
+
+
+#if !defined(AFX_MAGIC_H__E61FB5C3_42B6_42D1_BEFA_17F0B038E33B__INCLUDED_)
+#define AFX_MAGIC_H__E61FB5C3_42B6_42D1_BEFA_17F0B038E33B__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#ifndef __AFXWIN_H__
+ #error include 'stdafx.h' before including this file for PCH
+#endif
+
+#include "resource.h" // main symbols
+
+
+class Magic : public CWinApp
+{
+public:
+ Magic();
+ virtual ~Magic();
+
+ bool AppActivated() const { return app_active; }
+ void SetAppActivated(bool a) { app_active = a; }
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(Magic)
+ public:
+ virtual BOOL InitInstance();
+ virtual BOOL OnIdle(LONG lCount);
+ //}}AFX_VIRTUAL
+
+// Implementation
+ //{{AFX_MSG(Magic)
+ afx_msg void OnAppAbout();
+ // NOTE - the ClassWizard will add and remove member functions here.
+ // DO NOT EDIT what you see in these blocks of generated code !
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+
+private:
+ bool app_active;
+};
+
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_MAGIC_H__E61FB5C3_42B6_42D1_BEFA_17F0B038E33B__INCLUDED_)
diff --git a/Magic2/MagicDoc.cpp b/Magic2/MagicDoc.cpp
index 7b8e6f8..f0c7929 100644
--- a/Magic2/MagicDoc.cpp
+++ b/Magic2/MagicDoc.cpp
@@ -1,615 +1,639 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: MagicDoc.cpp
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Implementation of the MagicDoc class
-*/
-
-#include "stdafx.h"
-#include "Magic.h"
-
-#include "MagicDoc.h"
-#include "ModelFileMAG.h"
-#include "ModelFileOBJ.h"
-#include "ModelFile3DS.h"
-#include "Selection.h"
-#include "Selector.h"
-#include "Editor.h"
-#include "Command.h"
-
-#include "Bitmap.h"
-#include "Color.h"
-#include "D3DXImage.h"
-#include "Geometry.h"
-#include "Pcx.h"
-#include "Polygon.h"
-#include "Solid.h"
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
-#endif
-
-// +--------------------------------------------------------------------+
-
-IMPLEMENT_DYNCREATE(MagicDoc, CDocument)
-
-BEGIN_MESSAGE_MAP(MagicDoc, CDocument)
- //{{AFX_MSG_MAP(MagicDoc)
- ON_COMMAND(ID_SURFACE_OPTIMIZE, OnSurfaceOptimize)
- ON_COMMAND(ID_SURFACE_EXPLODE, OnSurfaceExplode)
- ON_UPDATE_COMMAND_UI(ID_SURFACE_OPTIMIZE, OnUpdateSurfaceOptimize)
- ON_UPDATE_COMMAND_UI(ID_SURFACE_EXPLODE, OnUpdateSurfaceExplode)
- //}}AFX_MSG_MAP
-END_MESSAGE_MAP()
-
-// +--------------------------------------------------------------------+
-
-MagicDoc::MagicDoc()
- : solid(0), selection(0)
-{
- solid = new Solid;
- selection = new Selection;
- selector = new Selector(selection);
- editor = new Editor(this);
-}
-
-MagicDoc::~MagicDoc()
-{
- if (editor) delete editor;
- if (selector) delete selector;
- if (selection) delete selection;
- if (solid) delete solid;
-}
-
-// +--------------------------------------------------------------------+
-
-void
-MagicDoc::InitCommandStack()
-{
- nundo = 0;
- commands.destroy();
-}
-
-void
-MagicDoc::Exec(Command* command)
-{
- int nredo = commands.size() - nundo;
-
- while (nredo) {
- delete commands.removeIndex(commands.size()-1);
- nredo--;
- }
-
- if (nundo < 100) {
- nundo++;
- }
- else {
- delete commands.removeIndex(0);
- }
-
- command->Do();
- commands.append(command);
-}
-
-int
-MagicDoc::NumUndo() const
-{
- return nundo;
-}
-
-int
-MagicDoc::NumRedo() const
-{
- return commands.size() - nundo;
-}
-
-const char*
-MagicDoc::GetUndoName() const
-{
- if (nundo > 0 && nundo <= commands.size())
- return commands[nundo-1]->Name();
- else
- return "";
-}
-
-const char*
-MagicDoc::GetRedoName() const
-{
- if (nundo >= 0 && nundo < commands.size())
- return commands[nundo]->Name();
- else
- return "";
-}
-
-void
-MagicDoc::Undo()
-{
- if (nundo > 0 && nundo <= commands.size())
- commands[--nundo]->Undo();
-}
-
-void
-MagicDoc::Redo()
-{
- if (nundo >= 0 && nundo < commands.size())
- commands[nundo++]->Do();
-}
-
-// +--------------------------------------------------------------------+
-
-BOOL MagicDoc::OnNewDocument()
-{
- if (!CDocument::OnNewDocument())
- return FALSE;
-
- InitCommandStack();
-
- if (solid) delete solid;
- solid = new Solid;
-
- if (selection)
- selection->Clear();
-
- return TRUE;
-}
-
-// +--------------------------------------------------------------------+
-
-void MagicDoc::Serialize(CArchive& ar)
-{
-}
-
-// +--------------------------------------------------------------------+
-
-#ifdef _DEBUG
-void MagicDoc::AssertValid() const
-{
- CDocument::AssertValid();
-}
-
-void MagicDoc::Dump(CDumpContext& dc) const
-{
- CDocument::Dump(dc);
-}
-#endif //_DEBUG
-
-// +--------------------------------------------------------------------+
-
-BOOL MagicDoc::OnSaveDocument(LPCTSTR path_name)
-{
- SetModifiedFlag(FALSE);
-
- ModelFileMAG mod_file(path_name);
- mod_file.Save(solid->GetModel());
-
- SetModifiedFlag(FALSE);
- UpdateAllViews(NULL);
- return TRUE;
-}
-
-BOOL MagicDoc::OnOpenDocument(LPCTSTR path_name)
-{
- FILE* fp = fopen(path_name, "rb");
- if (!fp) {
- ::MessageBox(0, "Open Failed: could not open file", "ERROR", MB_OK);
- return FALSE;
- }
-
- int version = 1;
- char file_id[5];
- fread(file_id, 4, 1, fp);
- file_id[4] = '\0';
- fclose(fp);
-
- if (strncmp(file_id, "MAG", 3)) {
- ::MessageBox(0, "Open Failed: Invalid file type", "ERROR", MB_OK);
- return FALSE;
- }
-
- switch (file_id[3]) {
- case '6': version = 6; break;
- case '5': version = 5; break;
- default: version = 0; break;
- }
-
- if (version < 5 || version > 6) {
- ::MessageBox(0, "Open Failed: Unsupported version", "ERROR", MB_OK);
- return FALSE;
- }
-
- DeleteContents();
-
- ModelFileMAG mod_file(path_name);
- solid->Load(&mod_file);
- solid->CreateShadows();
-
- SetModifiedFlag(FALSE);
- UpdateAllViews(NULL);
- return TRUE;
-}
-
-bool
-MagicDoc::ImportFile(LPCTSTR path_name)
-{
- if (strstr(path_name, ".obj") || strstr(path_name, ".OBJ")) {
- ModelFileOBJ obj_file(path_name);
-
- if (solid->GetModel()) {
- Solid* s = new Solid;
-
- if (s->Load(&obj_file)) {
- // todo: insert command here
- Model* orig = solid->GetModel();
- Model* imported = s->GetModel();
-
- orig->GetMaterials().append(imported->GetMaterials());
- orig->GetSurfaces().append(imported->GetSurfaces());
- orig->OptimizeMaterials();
-
- imported->GetMaterials().clear();
- imported->GetSurfaces().clear();
-
- SetModifiedFlag(FALSE);
- UpdateAllViews(NULL);
- delete s;
- return true;
- }
-
- delete s;
- }
- else {
- if (solid->Load(&obj_file)) {
- SetModifiedFlag(FALSE);
- UpdateAllViews(NULL);
- return true;
- }
- }
-
- return false;
- }
-
- if (strstr(path_name, ".3ds") || strstr(path_name, ".3DS")) {
- ModelFile3DS model_file(path_name);
-
- if (solid->GetModel()) {
- Solid* s = new Solid;
-
- if (s->Load(&model_file)) {
- // todo: insert command here
- Model* orig = solid->GetModel();
- Model* imported = s->GetModel();
-
- orig->GetMaterials().append(imported->GetMaterials());
- orig->GetSurfaces().append(imported->GetSurfaces());
- orig->OptimizeMaterials();
-
- imported->GetMaterials().clear();
- imported->GetSurfaces().clear();
-
- SetModifiedFlag(FALSE);
- UpdateAllViews(NULL);
- delete s;
- return true;
- }
-
- delete s;
- }
- else {
- if (solid->Load(&model_file)) {
- SetModifiedFlag(FALSE);
- UpdateAllViews(NULL);
- return true;
- }
- }
-
- return false;
- }
-
- FILE* fp = fopen(path_name, "rb");
- if (!fp) {
- ::MessageBox(0, "Import Failed: could not open file", "ERROR", MB_OK);
- return false;
- }
-
- int version = 1;
- char file_id[5];
- fread(file_id, 4, 1, fp);
- file_id[4] = '\0';
- fclose(fp);
-
- if (strncmp(file_id, "MAG", 3)) {
- ::MessageBox(0, "Open Failed: Invalid file type", "ERROR", MB_OK);
- return false;
- }
-
- switch (file_id[3]) {
- case '6': version = 6; break;
- case '5': version = 5; break;
- default: version = 0; break;
- }
-
- if (version < 5 || version > 6) {
- ::MessageBox(0, "Open Failed: Unsupported version", "ERROR", MB_OK);
- return false;
- }
-
- ModelFileMAG mag_file(path_name);
-
- if (solid->GetModel()) {
- Solid* s = new Solid;
- if (s->Load(&mag_file)) {
- // todo: insert command here
- Model* orig = solid->GetModel();
- Model* imported = s->GetModel();
-
- orig->GetMaterials().append(imported->GetMaterials());
- orig->GetSurfaces().append(imported->GetSurfaces());
- orig->OptimizeMaterials();
-
- imported->GetMaterials().clear();
- imported->GetSurfaces().clear();
-
- SetModifiedFlag(FALSE);
- UpdateAllViews(NULL);
- delete s;
- return true;
- }
-
- delete s;
- }
- else {
- InitCommandStack();
-
- if (solid->Load(&mag_file)) {
- SetModifiedFlag(FALSE);
- UpdateAllViews(NULL);
- return true;
- }
- }
-
- return false;
-}
-
-bool
-MagicDoc::ExportFile(LPCTSTR path_name)
-{
- if (!solid->GetModel())
- return false;
-
- if (strstr(path_name, ".obj") || strstr(path_name, ".OBJ")) {
- ModelFileOBJ obj_file(path_name);
- obj_file.Save(solid->GetModel());
- return true;
- }
-
- if (strstr(path_name, ".3ds") || strstr(path_name, ".3DS")) {
- return false;
- }
-
- if (strstr(path_name, ".mag") || strstr(path_name, ".MAG")) {
- ModelFileMAG mod_file(path_name);
- mod_file.Save(solid->GetModel());
- return true;
- }
-
- return false;
-}
-
-// +--------------------------------------------------------------------+
-
-int LoadBuffer(const char* filename, BYTE*& buf, bool null_terminate)
-{
- buf = 0;
-
- FILE* f = ::fopen(filename, "rb");
-
- if (f) {
- ::fseek(f, 0, SEEK_END);
- int len = ftell(f);
- ::fseek(f, 0, SEEK_SET);
-
- if (null_terminate) {
- buf = new BYTE[len+1];
- if (buf)
- buf[len] = 0;
- }
-
- else {
- buf = new BYTE[len];
- }
-
- if (buf)
- ::fread(buf, len, 1, f);
-
- ::fclose(f);
-
- return len;
- }
-
- return 0;
-}
-
-// +--------------------------------------------------------------------+
-
-void MagicDoc::DeleteContents()
-{
- CDocument::DeleteContents();
- InitCommandStack();
-
- if (solid) {
- delete solid;
- solid = new Solid;
- }
-
- if (selection)
- selection->Clear();
-}
-
-// +--------------------------------------------------------------------+
-
-int LoadTexture(const char* fname, Bitmap*& bitmap, int type)
-{
- int result = 0;
-
- if (!fname || !*fname)
- return result;
-
- bitmap = Bitmap::CheckCache(fname);
-
- if (!bitmap) {
- bool pcx_file = strstr(fname, ".pcx") || strstr(fname, ".PCX");
-
- // handle PCX formats:
- if (pcx_file) {
- PcxImage pcx;
-
- if (pcx.Load((char*) fname) == PCX_OK) {
- bitmap = new Bitmap;
-
- // 32-bit image
- if (pcx.himap) {
- bitmap->CopyHighColorImage(pcx.width, pcx.height, pcx.himap);
- }
-
- // 8-bit image, check for 32-bit image as well
- else if (pcx.bitmap) {
- bitmap->CopyImage(pcx.width, pcx.height, pcx.bitmap);
-
- char tmp[256];
- int len = strlen(fname);
- bool found = false;
-
- ZeroMemory(tmp, sizeof(tmp));
-
- for (int i = 0; i < len && !found; i++) {
- if (strstr(fname + i, ".pcx") == (fname+i)) {
- found = true;
- }
- else {
- tmp[i] = fname[i];
- }
- }
-
- if (found) {
- strcat_s(tmp, "+.pcx");
- if (pcx.Load(tmp) == PCX_OK && pcx.himap != 0) {
- bitmap->CopyHighColorImage(pcx.width, pcx.height, pcx.himap);
- }
- }
- }
- }
- }
-
- // for all other formats, use D3DX:
- else {
- D3DXImage d3dx;
- if (d3dx.Load((char*) fname)) {
- bitmap = new Bitmap;
- bitmap->CopyHighColorImage(d3dx.width, d3dx.height, d3dx.image);
- }
- }
-
- if (bitmap) {
- LoadAlpha(fname, *bitmap, type);
-
- bitmap->SetFilename(fname);
- bitmap->SetType(type);
- bitmap->MakeTexture();
-
- Bitmap::AddToCache(bitmap);
- }
- }
-
- return result;
-}
-
-int LoadAlpha(const char* name, Bitmap& bitmap, int type)
-{
- PcxImage pcx;
- D3DXImage d3dx;
- bool pcx_file = strstr(name, ".pcx") || strstr(name, ".PCX");
- bool bmp_file = strstr(name, ".bmp") || strstr(name, ".BMP");
- bool jpg_file = strstr(name, ".jpg") || strstr(name, ".JPG");
- bool png_file = strstr(name, ".png") || strstr(name, ".PNG");
- bool tga_file = strstr(name, ".tga") || strstr(name, ".TGA");
-
- // check for an associated alpha-only (grayscale) bitmap:
- char filename[256];
- strcpy_s(filename, name);
-
- char* dot = strrchr(filename, '.');
- if (dot && pcx_file)
- strcpy(dot, "@.pcx");
- else if (dot && bmp_file)
- strcpy(dot, "@.bmp");
- else if (dot && jpg_file)
- strcpy(dot, "@.jpg");
- else if (dot && png_file)
- strcpy(dot, "@.png");
- else if (dot && tga_file)
- strcpy(dot, "@.tga");
- else
- return 0;
-
- // first try to load from current directory:
- bool loaded = false;
-
- if (pcx_file)
- loaded = pcx.Load(filename) == PCX_OK;
-
- else
- loaded = d3dx.Load(filename);
-
- // now copy the alpha values into the bitmap:
- if (loaded) {
- if (pcx_file && pcx.bitmap) {
- bitmap.CopyAlphaImage(pcx.width, pcx.height, pcx.bitmap);
- }
- else if (pcx_file && pcx.himap) {
- bitmap.CopyAlphaRedChannel(pcx.width, pcx.height, pcx.himap);
- }
- else if (d3dx.image) {
- bitmap.CopyAlphaRedChannel(d3dx.width, d3dx.height, d3dx.image);
- }
- }
-
- return 0;
-}
-
-
-void MagicDoc::OnSurfaceOptimize()
-{
- if (solid && solid->GetModel()) {
- solid->GetModel()->OptimizeMesh();
- solid->InvalidateSurfaceData();
- solid->InvalidateSegmentData();
- }
-}
-
-void MagicDoc::OnUpdateSurfaceOptimize(CCmdUI* pCmdUI)
-{
- pCmdUI->Enable(solid && solid->GetModel());
-}
-
-void MagicDoc::OnSurfaceExplode()
-{
- if (solid && solid->GetModel()) {
- solid->GetModel()->ExplodeMesh();
- solid->InvalidateSurfaceData();
- solid->InvalidateSegmentData();
- }
-}
-
-void MagicDoc::OnUpdateSurfaceExplode(CCmdUI* pCmdUI)
-{
- pCmdUI->Enable(solid && solid->GetModel());
-}
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: MagicDoc.cpp
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Implementation of the MagicDoc class
+*/
+
+#include "stdafx.h"
+#include "Magic.h"
+
+#include "MagicDoc.h"
+#include "ModelFileMAG.h"
+#include "ModelFileOBJ.h"
+#include "ModelFile3DS.h"
+#include "Selection.h"
+#include "Selector.h"
+#include "Editor.h"
+#include "Command.h"
+
+#include "Bitmap.h"
+#include "Color.h"
+#include "D3DXImage.h"
+#include "Geometry.h"
+#include "Pcx.h"
+#include "Polygon.h"
+#include "Solid.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+// +--------------------------------------------------------------------+
+
+IMPLEMENT_DYNCREATE(MagicDoc, CDocument)
+
+BEGIN_MESSAGE_MAP(MagicDoc, CDocument)
+ //{{AFX_MSG_MAP(MagicDoc)
+ ON_COMMAND(ID_SURFACE_OPTIMIZE, OnSurfaceOptimize)
+ ON_COMMAND(ID_SURFACE_EXPLODE, OnSurfaceExplode)
+ ON_UPDATE_COMMAND_UI(ID_SURFACE_OPTIMIZE, OnUpdateSurfaceOptimize)
+ ON_UPDATE_COMMAND_UI(ID_SURFACE_EXPLODE, OnUpdateSurfaceExplode)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+// +--------------------------------------------------------------------+
+
+MagicDoc::MagicDoc()
+ : solid(0), selection(0)
+{
+ solid = new Solid;
+ selection = new Selection;
+ selector = new Selector(selection);
+ editor = new Editor(this);
+}
+
+MagicDoc::~MagicDoc()
+{
+ if (editor) delete editor;
+ if (selector) delete selector;
+ if (selection) delete selection;
+ if (solid) delete solid;
+}
+
+// +--------------------------------------------------------------------+
+
+void
+MagicDoc::InitCommandStack()
+{
+ nundo = 0;
+ commands.destroy();
+}
+
+void
+MagicDoc::Exec(Command* command)
+{
+ int nredo = commands.size() - nundo;
+
+ while (nredo) {
+ delete commands.removeIndex(commands.size()-1);
+ nredo--;
+ }
+
+ if (nundo < 100) {
+ nundo++;
+ }
+ else {
+ delete commands.removeIndex(0);
+ }
+
+ command->Do();
+ commands.append(command);
+}
+
+int
+MagicDoc::NumUndo() const
+{
+ return nundo;
+}
+
+int
+MagicDoc::NumRedo() const
+{
+ return commands.size() - nundo;
+}
+
+const char*
+MagicDoc::GetUndoName() const
+{
+ if (nundo > 0 && nundo <= commands.size())
+ return commands[nundo-1]->Name();
+ else
+ return "";
+}
+
+const char*
+MagicDoc::GetRedoName() const
+{
+ if (nundo >= 0 && nundo < commands.size())
+ return commands[nundo]->Name();
+ else
+ return "";
+}
+
+void
+MagicDoc::Undo()
+{
+ if (nundo > 0 && nundo <= commands.size())
+ commands[--nundo]->Undo();
+}
+
+void
+MagicDoc::Redo()
+{
+ if (nundo >= 0 && nundo < commands.size())
+ commands[nundo++]->Do();
+}
+
+// +--------------------------------------------------------------------+
+
+BOOL MagicDoc::OnNewDocument()
+{
+ if (!CDocument::OnNewDocument())
+ return FALSE;
+
+ InitCommandStack();
+
+ if (solid) delete solid;
+ solid = new Solid;
+
+ if (selection)
+ selection->Clear();
+
+ return TRUE;
+}
+
+// +--------------------------------------------------------------------+
+
+void MagicDoc::Serialize(CArchive& ar)
+{
+}
+
+// +--------------------------------------------------------------------+
+
+#ifdef _DEBUG
+void MagicDoc::AssertValid() const
+{
+ CDocument::AssertValid();
+}
+
+void MagicDoc::Dump(CDumpContext& dc) const
+{
+ CDocument::Dump(dc);
+}
+#endif //_DEBUG
+
+// +--------------------------------------------------------------------+
+
+BOOL MagicDoc::OnSaveDocument(LPCTSTR path_name)
+{
+ SetModifiedFlag(FALSE);
+
+ ModelFileMAG mod_file(path_name);
+ mod_file.Save(solid->GetModel());
+
+ SetModifiedFlag(FALSE);
+ UpdateAllViews(NULL);
+ return TRUE;
+}
+
+BOOL MagicDoc::OnOpenDocument(LPCTSTR path_name)
+{
+ FILE* fp = fopen(path_name, "rb");
+ if (!fp) {
+ ::MessageBox(0, "Open Failed: could not open file", "ERROR", MB_OK);
+ return FALSE;
+ }
+
+ int version = 1;
+ char file_id[5];
+ fread(file_id, 4, 1, fp);
+ file_id[4] = '\0';
+ fclose(fp);
+
+ if (strncmp(file_id, "MAG", 3)) {
+ ::MessageBox(0, "Open Failed: Invalid file type", "ERROR", MB_OK);
+ return FALSE;
+ }
+
+ switch (file_id[3]) {
+ case '6': version = 6; break;
+ case '5': version = 5; break;
+ default: version = 0; break;
+ }
+
+ if (version < 5 || version > 6) {
+ ::MessageBox(0, "Open Failed: Unsupported version", "ERROR", MB_OK);
+ return FALSE;
+ }
+
+ DeleteContents();
+
+ ModelFileMAG mod_file(path_name);
+ solid->Load(&mod_file);
+ solid->CreateShadows();
+
+ SetModifiedFlag(FALSE);
+ UpdateAllViews(NULL);
+ return TRUE;
+}
+
+bool
+MagicDoc::ImportFile(LPCTSTR path_name)
+{
+ if (strstr(path_name, ".obj") || strstr(path_name, ".OBJ")) {
+ ModelFileOBJ obj_file(path_name);
+
+ if (solid->GetModel()) {
+ Solid* s = new Solid;
+
+ if (s->Load(&obj_file)) {
+ // todo: insert command here
+ Model* orig = solid->GetModel();
+ Model* imported = s->GetModel();
+
+ orig->GetMaterials().append(imported->GetMaterials());
+ orig->GetSurfaces().append(imported->GetSurfaces());
+ orig->OptimizeMaterials();
+
+ imported->GetMaterials().clear();
+ imported->GetSurfaces().clear();
+
+ SetModifiedFlag(FALSE);
+ UpdateAllViews(NULL);
+ delete s;
+ return true;
+ }
+
+ delete s;
+ }
+ else {
+ if (solid->Load(&obj_file)) {
+ SetModifiedFlag(FALSE);
+ UpdateAllViews(NULL);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ if (strstr(path_name, ".3ds") || strstr(path_name, ".3DS")) {
+ ModelFile3DS model_file(path_name);
+
+ if (solid->GetModel()) {
+ Solid* s = new Solid;
+
+ if (s->Load(&model_file)) {
+ // todo: insert command here
+ Model* orig = solid->GetModel();
+ Model* imported = s->GetModel();
+
+ orig->GetMaterials().append(imported->GetMaterials());
+ orig->GetSurfaces().append(imported->GetSurfaces());
+ orig->OptimizeMaterials();
+
+ imported->GetMaterials().clear();
+ imported->GetSurfaces().clear();
+
+ SetModifiedFlag(FALSE);
+ UpdateAllViews(NULL);
+ delete s;
+ return true;
+ }
+
+ delete s;
+ }
+ else {
+ if (solid->Load(&model_file)) {
+ SetModifiedFlag(FALSE);
+ UpdateAllViews(NULL);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ FILE* fp = fopen(path_name, "rb");
+ if (!fp) {
+ ::MessageBox(0, "Import Failed: could not open file", "ERROR", MB_OK);
+ return false;
+ }
+
+ int version = 1;
+ char file_id[5];
+ fread(file_id, 4, 1, fp);
+ file_id[4] = '\0';
+ fclose(fp);
+
+ if (strncmp(file_id, "MAG", 3)) {
+ ::MessageBox(0, "Open Failed: Invalid file type", "ERROR", MB_OK);
+ return false;
+ }
+
+ switch (file_id[3]) {
+ case '6': version = 6; break;
+ case '5': version = 5; break;
+ default: version = 0; break;
+ }
+
+ if (version < 5 || version > 6) {
+ ::MessageBox(0, "Open Failed: Unsupported version", "ERROR", MB_OK);
+ return false;
+ }
+
+ ModelFileMAG mag_file(path_name);
+
+ if (solid->GetModel()) {
+ Solid* s = new Solid;
+ if (s->Load(&mag_file)) {
+ // todo: insert command here
+ Model* orig = solid->GetModel();
+ Model* imported = s->GetModel();
+
+ orig->GetMaterials().append(imported->GetMaterials());
+ orig->GetSurfaces().append(imported->GetSurfaces());
+ orig->OptimizeMaterials();
+
+ imported->GetMaterials().clear();
+ imported->GetSurfaces().clear();
+
+ SetModifiedFlag(FALSE);
+ UpdateAllViews(NULL);
+ delete s;
+ return true;
+ }
+
+ delete s;
+ }
+ else {
+ InitCommandStack();
+
+ if (solid->Load(&mag_file)) {
+ SetModifiedFlag(FALSE);
+ UpdateAllViews(NULL);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool
+MagicDoc::ExportFile(LPCTSTR path_name)
+{
+ if (!solid->GetModel())
+ return false;
+
+ if (strstr(path_name, ".obj") || strstr(path_name, ".OBJ")) {
+ ModelFileOBJ obj_file(path_name);
+ obj_file.Save(solid->GetModel());
+ return true;
+ }
+
+ if (strstr(path_name, ".3ds") || strstr(path_name, ".3DS")) {
+ return false;
+ }
+
+ if (strstr(path_name, ".mag") || strstr(path_name, ".MAG")) {
+ ModelFileMAG mod_file(path_name);
+ mod_file.Save(solid->GetModel());
+ return true;
+ }
+
+ return false;
+}
+
+// +--------------------------------------------------------------------+
+
+int LoadBuffer(const char* filename, BYTE*& buf, bool null_terminate)
+{
+ buf = 0;
+
+ FILE* f = ::fopen(filename, "rb");
+
+ if (f) {
+ ::fseek(f, 0, SEEK_END);
+ int len = ftell(f);
+ ::fseek(f, 0, SEEK_SET);
+
+ if (null_terminate) {
+ buf = new BYTE[len+1];
+ if (buf)
+ buf[len] = 0;
+ }
+
+ else {
+ buf = new BYTE[len];
+ }
+
+ if (buf)
+ ::fread(buf, len, 1, f);
+
+ ::fclose(f);
+
+ return len;
+ }
+
+ return 0;
+}
+
+// +--------------------------------------------------------------------+
+
+void MagicDoc::DeleteContents()
+{
+ CDocument::DeleteContents();
+ InitCommandStack();
+
+ if (solid) {
+ delete solid;
+ solid = new Solid;
+ }
+
+ if (selection)
+ selection->Clear();
+}
+
+// +--------------------------------------------------------------------+
+
+int LoadTexture(const char* fname, Bitmap*& bitmap, int type)
+{
+ int result = 0;
+
+ if (!fname || !*fname)
+ return result;
+
+ bitmap = Bitmap::CheckCache(fname);
+
+ if (!bitmap) {
+ bool pcx_file = strstr(fname, ".pcx") || strstr(fname, ".PCX");
+
+ // handle PCX formats:
+ if (pcx_file) {
+ PcxImage pcx;
+
+ if (pcx.Load((char*) fname) == PCX_OK) {
+ bitmap = new Bitmap;
+
+ // 32-bit image
+ if (pcx.himap) {
+ bitmap->CopyHighColorImage(pcx.width, pcx.height, pcx.himap);
+ }
+
+ // 8-bit image, check for 32-bit image as well
+ else if (pcx.bitmap) {
+ bitmap->CopyImage(pcx.width, pcx.height, pcx.bitmap);
+
+ char tmp[256];
+ int len = strlen(fname);
+ bool found = false;
+
+ ZeroMemory(tmp, sizeof(tmp));
+
+ for (int i = 0; i < len && !found; i++) {
+ if (strstr(fname + i, ".pcx") == (fname+i)) {
+ found = true;
+ }
+ else {
+ tmp[i] = fname[i];
+ }
+ }
+
+ if (found) {
+ strcat_s(tmp, "+.pcx");
+ if (pcx.Load(tmp) == PCX_OK && pcx.himap != 0) {
+ bitmap->CopyHighColorImage(pcx.width, pcx.height, pcx.himap);
+ }
+ }
+ }
+ }
+ }
+
+ // for all other formats, use D3DX:
+ else {
+ D3DXImage d3dx;
+ if (d3dx.Load((char*) fname)) {
+ bitmap = new Bitmap;
+ bitmap->CopyHighColorImage(d3dx.width, d3dx.height, d3dx.image);
+ }
+ }
+
+ if (bitmap) {
+ LoadAlpha(fname, *bitmap, type);
+
+ bitmap->SetFilename(fname);
+ bitmap->SetType(type);
+ bitmap->MakeTexture();
+
+ Bitmap::AddToCache(bitmap);
+ }
+ }
+
+ return result;
+}
+
+int LoadAlpha(const char* name, Bitmap& bitmap, int type)
+{
+ PcxImage pcx;
+ D3DXImage d3dx;
+ bool pcx_file = strstr(name, ".pcx") || strstr(name, ".PCX");
+ bool bmp_file = strstr(name, ".bmp") || strstr(name, ".BMP");
+ bool jpg_file = strstr(name, ".jpg") || strstr(name, ".JPG");
+ bool png_file = strstr(name, ".png") || strstr(name, ".PNG");
+ bool tga_file = strstr(name, ".tga") || strstr(name, ".TGA");
+
+ // check for an associated alpha-only (grayscale) bitmap:
+ char filename[256];
+ strcpy_s(filename, name);
+
+ char* dot = strrchr(filename, '.');
+ if (dot && pcx_file)
+ strcpy(dot, "@.pcx");
+ else if (dot && bmp_file)
+ strcpy(dot, "@.bmp");
+ else if (dot && jpg_file)
+ strcpy(dot, "@.jpg");
+ else if (dot && png_file)
+ strcpy(dot, "@.png");
+ else if (dot && tga_file)
+ strcpy(dot, "@.tga");
+ else
+ return 0;
+
+ // first try to load from current directory:
+ bool loaded = false;
+
+ if (pcx_file)
+ loaded = pcx.Load(filename) == PCX_OK;
+
+ else
+ loaded = d3dx.Load(filename);
+
+ // now copy the alpha values into the bitmap:
+ if (loaded) {
+ if (pcx_file && pcx.bitmap) {
+ bitmap.CopyAlphaImage(pcx.width, pcx.height, pcx.bitmap);
+ }
+ else if (pcx_file && pcx.himap) {
+ bitmap.CopyAlphaRedChannel(pcx.width, pcx.height, pcx.himap);
+ }
+ else if (d3dx.image) {
+ bitmap.CopyAlphaRedChannel(d3dx.width, d3dx.height, d3dx.image);
+ }
+ }
+
+ return 0;
+}
+
+
+void MagicDoc::OnSurfaceOptimize()
+{
+ if (solid && solid->GetModel()) {
+ solid->GetModel()->OptimizeMesh();
+ solid->InvalidateSurfaceData();
+ solid->InvalidateSegmentData();
+ }
+}
+
+void MagicDoc::OnUpdateSurfaceOptimize(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(solid && solid->GetModel());
+}
+
+void MagicDoc::OnSurfaceExplode()
+{
+ if (solid && solid->GetModel()) {
+ solid->GetModel()->ExplodeMesh();
+ solid->InvalidateSurfaceData();
+ solid->InvalidateSegmentData();
+ }
+}
+
+void MagicDoc::OnUpdateSurfaceExplode(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(solid && solid->GetModel());
+}
diff --git a/Magic2/MagicDoc.h b/Magic2/MagicDoc.h
index 489f5dc..a40c879 100644
--- a/Magic2/MagicDoc.h
+++ b/Magic2/MagicDoc.h
@@ -1,120 +1,144 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: MagicDoc.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Interface of the MagicDoc class
-*/
-
-
-#if !defined(AFX_MAGICDOC_H__8B8D63A3_30F9_4023_BFA8_DB79891487C2__INCLUDED_)
-#define AFX_MAGICDOC_H__8B8D63A3_30F9_4023_BFA8_DB79891487C2__INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-// +--------------------------------------------------------------------+
-
-#include "List.h"
-
-// +--------------------------------------------------------------------+
-
-class Bitmap;
-class Command;
-class Editor;
-class Solid;
-class Model;
-class Surface;
-class Segment;
-class Selection;
-class Selector;
-
-// +--------------------------------------------------------------------+
-
-class MagicDoc : public CDocument
-{
-protected: // create from serialization only
- MagicDoc();
- DECLARE_DYNCREATE(MagicDoc)
-
-// Attributes
-public:
-
-// Operations
-public:
-
-// Overrides
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(MagicDoc)
- public:
- virtual BOOL OnNewDocument();
- virtual void Serialize(CArchive& ar);
- virtual BOOL OnSaveDocument(LPCTSTR lpszPathName);
- virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);
- virtual void DeleteContents();
- //}}AFX_VIRTUAL
-
- void InitCommandStack();
- void Exec(Command* command);
- void Undo();
- void Redo();
- int NumUndo() const;
- int NumRedo() const;
- const char* GetUndoName() const;
- const char* GetRedoName() const;
-
-// Implementation
-public:
- virtual ~MagicDoc();
-#ifdef _DEBUG
- virtual void AssertValid() const;
- virtual void Dump(CDumpContext& dc) const;
-#endif
-
- Solid* GetSolid() { return solid; }
- Selection* GetSelection() { return selection; }
- Selector* GetSelector() { return selector; }
- Editor* GetEditor() { return editor; }
-
- bool ImportFile(LPCTSTR path_name);
- bool ExportFile(LPCTSTR path_name);
-
-protected:
- Solid* solid;
- Selection* selection;
- Selector* selector;
- Editor* editor;
-
- List<Command> commands;
- int nundo;
-
-// Generated message map functions
-protected:
- //{{AFX_MSG(MagicDoc)
- afx_msg void OnSurfaceOptimize();
- afx_msg void OnSurfaceExplode();
- afx_msg void OnUpdateSurfaceOptimize(CCmdUI* pCmdUI);
- afx_msg void OnUpdateSurfaceExplode(CCmdUI* pCmdUI);
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
-};
-
-// +--------------------------------------------------------------------+
-
-int LoadBuffer(const char* filename, BYTE*& buf, bool null_terminate=false);
-int LoadTexture(const char* name, Bitmap*& bmp, int type=0);
-int LoadAlpha(const char* name, Bitmap& bitmap, int type=0);
-
-// +--------------------------------------------------------------------+
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
-
-#endif // !defined(AFX_MAGICDOC_H__8B8D63A3_30F9_4023_BFA8_DB79891487C2__INCLUDED_)
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: MagicDoc.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Interface of the MagicDoc class
+*/
+
+
+#if !defined(AFX_MAGICDOC_H__8B8D63A3_30F9_4023_BFA8_DB79891487C2__INCLUDED_)
+#define AFX_MAGICDOC_H__8B8D63A3_30F9_4023_BFA8_DB79891487C2__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+// +--------------------------------------------------------------------+
+
+#include "List.h"
+
+// +--------------------------------------------------------------------+
+
+class Bitmap;
+class Command;
+class Editor;
+class Solid;
+class Model;
+class Surface;
+class Segment;
+class Selection;
+class Selector;
+
+// +--------------------------------------------------------------------+
+
+class MagicDoc : public CDocument
+{
+protected: // create from serialization only
+ MagicDoc();
+ DECLARE_DYNCREATE(MagicDoc)
+
+// Attributes
+public:
+
+// Operations
+public:
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(MagicDoc)
+ public:
+ virtual BOOL OnNewDocument();
+ virtual void Serialize(CArchive& ar);
+ virtual BOOL OnSaveDocument(LPCTSTR lpszPathName);
+ virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);
+ virtual void DeleteContents();
+ //}}AFX_VIRTUAL
+
+ void InitCommandStack();
+ void Exec(Command* command);
+ void Undo();
+ void Redo();
+ int NumUndo() const;
+ int NumRedo() const;
+ const char* GetUndoName() const;
+ const char* GetRedoName() const;
+
+// Implementation
+public:
+ virtual ~MagicDoc();
+#ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+#endif
+
+ Solid* GetSolid() { return solid; }
+ Selection* GetSelection() { return selection; }
+ Selector* GetSelector() { return selector; }
+ Editor* GetEditor() { return editor; }
+
+ bool ImportFile(LPCTSTR path_name);
+ bool ExportFile(LPCTSTR path_name);
+
+protected:
+ Solid* solid;
+ Selection* selection;
+ Selector* selector;
+ Editor* editor;
+
+ List<Command> commands;
+ int nundo;
+
+// Generated message map functions
+protected:
+ //{{AFX_MSG(MagicDoc)
+ afx_msg void OnSurfaceOptimize();
+ afx_msg void OnSurfaceExplode();
+ afx_msg void OnUpdateSurfaceOptimize(CCmdUI* pCmdUI);
+ afx_msg void OnUpdateSurfaceExplode(CCmdUI* pCmdUI);
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+// +--------------------------------------------------------------------+
+
+int LoadBuffer(const char* filename, BYTE*& buf, bool null_terminate=false);
+int LoadTexture(const char* name, Bitmap*& bmp, int type=0);
+int LoadAlpha(const char* name, Bitmap& bitmap, int type=0);
+
+// +--------------------------------------------------------------------+
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_MAGICDOC_H__8B8D63A3_30F9_4023_BFA8_DB79891487C2__INCLUDED_)
diff --git a/Magic2/MagicView.cpp b/Magic2/MagicView.cpp
index 294c794..e29e5d3 100644
--- a/Magic2/MagicView.cpp
+++ b/Magic2/MagicView.cpp
@@ -1,1437 +1,1461 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: MagicView.cpp
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Implementation of the MagicView class
-*/
-
-#include "stdafx.h"
-#include "Magic.h"
-
-#include "MagicDoc.h"
-#include "MagicView.h"
-#include "MainFrm.h"
-#include "MaterialDialog.h"
-#include "SurfacePropertiesDialog.h"
-#include "TextureMapDialog.h"
-#include "Editor.h"
-#include "Grid.h"
-#include "GridProps.h"
-#include "Selection.h"
-#include "Selector.h"
-#include "UVMapView.h"
-
-#include "ActiveWindow.h"
-#include "Color.h"
-#include "Layout.h"
-#include "Light.h"
-#include "Scene.h"
-#include "Screen.h"
-#include "Shadow.h"
-#include "Solid.h"
-#include "Video.h"
-#include "VideoDX9.h"
-#include "VideoSettings.h"
-
-#include "ModelView.h"
-
-DWORD GetRealTime();
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
-#endif
-
-extern PALETTEENTRY standard_palette[256];
-extern BYTE inverse_palette[32768];
-
-// +--------------------------------------------------------------------+
-
-IMPLEMENT_DYNCREATE(MagicView, CView)
-
-BEGIN_MESSAGE_MAP(MagicView, CView)
- //{{AFX_MSG_MAP(MagicView)
- ON_WM_SIZE()
- ON_COMMAND(ID_VIEW_RENDER, OnRender)
- ON_WM_PAINT()
- ON_COMMAND(ID_VIEW_ALL, OnViewAll)
- ON_UPDATE_COMMAND_UI(ID_VIEW_ALL, OnUpdateViewAll)
- ON_COMMAND(ID_VIEW_FRONT, OnViewFront)
- ON_UPDATE_COMMAND_UI(ID_VIEW_FRONT, OnUpdateViewFront)
- ON_COMMAND(ID_VIEW_PERSPECTIVE, OnViewPerspective)
- ON_UPDATE_COMMAND_UI(ID_VIEW_PERSPECTIVE, OnUpdateViewPerspective)
- ON_COMMAND(ID_VIEW_SIDE, OnViewSide)
- ON_UPDATE_COMMAND_UI(ID_VIEW_SIDE, OnUpdateViewSide)
- ON_COMMAND(ID_VIEW_TOP, OnViewTop)
- ON_UPDATE_COMMAND_UI(ID_VIEW_TOP, OnUpdateViewTop)
- ON_COMMAND(ID_MODIFY_TEXTURE_MAP, OnTextureMap)
- ON_COMMAND(ID_MODIFY_MATERIAL, OnModifyMaterial)
- ON_WM_LBUTTONDOWN()
- ON_WM_LBUTTONUP()
- ON_WM_LBUTTONDBLCLK()
- ON_WM_RBUTTONDOWN()
- ON_WM_RBUTTONUP()
- ON_WM_MOUSEMOVE()
- ON_WM_MOUSEWHEEL()
- ON_COMMAND(ID_VIEW_ZOOM_NORMAL, OnViewZoomNormal)
- ON_COMMAND(ID_VIEW_ZOOM_IN, OnViewZoomIn)
- ON_COMMAND(ID_VIEW_ZOOM_OUT, OnViewZoomOut)
- ON_COMMAND(ID_VIEW_MODE_WIREFRAME, OnViewModeWireframe)
- ON_COMMAND(ID_VIEW_MODE_SOLID, OnViewModeSolid)
- ON_COMMAND(ID_VIEW_MODE_TEXTURED, OnViewModeTextured)
- ON_WM_RBUTTONDBLCLK()
- ON_COMMAND(ID_PROP_GRID, OnGridProperties)
- ON_COMMAND(ID_GRID_SHOW, OnGridShow)
- ON_COMMAND(ID_GRID_SNAP, OnGridSnap)
- ON_UPDATE_COMMAND_UI(ID_GRID_SNAP, OnUpdateGridSnap)
- ON_COMMAND(ID_VIEW_BACK_COLOR, OnViewBackColor)
- ON_COMMAND(ID_FILE_IMPORT, OnFileImport)
- ON_COMMAND(ID_FILE_EXPORT, OnFileExport)
- ON_COMMAND(ID_EDIT_SELECT_ALL, OnSelectAll)
- ON_COMMAND(ID_EDIT_SELECT_NONE, OnSelectNone)
- ON_UPDATE_COMMAND_UI(ID_MODIFY_TEXTURE_MAP, OnUpdateTextureMap)
- ON_UPDATE_COMMAND_UI(ID_MODIFY_MATERIAL, OnUpdateModifyMaterial)
- ON_COMMAND(ID_EDIT_SELECT_INVERSE, OnSelectInverse)
- ON_COMMAND(ID_MODIFY_UV_MAP, OnModifyUVMap)
- ON_UPDATE_COMMAND_UI(ID_MODIFY_UV_MAP, OnUpdateModifyUVMap)
- ON_COMMAND(ID_VIEW_SHADOWS, OnViewShadows)
- ON_UPDATE_COMMAND_UI(ID_VIEW_SHADOWS, OnUpdateViewShadows)
- ON_COMMAND(ID_VIEW_ANIMATELIGHT, OnViewAnimatelight)
- ON_UPDATE_COMMAND_UI(ID_VIEW_ANIMATELIGHT, OnUpdateViewAnimatelight)
- ON_COMMAND(ID_VIEW_BUMPMAPS, OnViewBumpmaps)
- ON_UPDATE_COMMAND_UI(ID_VIEW_BUMPMAPS, OnUpdateViewBumpmaps)
- ON_COMMAND(ID_VIEW_VERTEXSHADER, OnViewVertexshader)
- ON_UPDATE_COMMAND_UI(ID_VIEW_VERTEXSHADER, OnUpdateViewVertexshader)
- ON_COMMAND(ID_VIEW_PIXELSHADER, OnViewPixelshader)
- ON_UPDATE_COMMAND_UI(ID_VIEW_PIXELSHADER, OnUpdateViewPixelshader)
- ON_COMMAND(ID_VIEW_VISIBLESHADOWS, OnViewVisibleshadows)
- ON_UPDATE_COMMAND_UI(ID_VIEW_VISIBLESHADOWS, OnUpdateViewVisibleshadows)
- ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
- ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo)
- ON_COMMAND(ID_EDIT_REDO, OnEditRedo)
- ON_UPDATE_COMMAND_UI(ID_EDIT_REDO, OnUpdateEditRedo)
- ON_COMMAND(ID_PROP_SURFACE, OnSurfaceProperties)
- ON_UPDATE_COMMAND_UI(ID_PROP_SURFACE, OnUpdateSurfaceProperties)
- //}}AFX_MSG_MAP
- // Standard printing commands
- ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
- ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
- ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
-END_MESSAGE_MAP()
-
-// +--------------------------------------------------------------------+
-
-static MagicView* magic_view = 0;
-
-MagicView::MagicView()
- : video(0), video_settings(0), screen(0), scene(0),
- drag_left(false), drag_right(false), grid(0),
- main_light(0), back_light(0), view_shadows(true), view_bumpmaps(true),
- animate_light(false)
-{
- window_style = 0;
- is_minimized = false;
- is_maximized = false;
- is_sizing = false;
- view_mode = VIEW_ALL;
-
- main_win = 0;
- view_win[0] = 0;
- view_win[1] = 0;
- view_win[2] = 0;
- view_win[3] = 0;
- model_view[0] = 0;
- model_view[1] = 0;
- model_view[2] = 0;
- model_view[3] = 0;
- uvmap_win = 0;
-
- grid = new Grid;
- magic_view = this;
-
- Solid::EnableCollision(false);
-}
-
-MagicView::~MagicView()
-{
- if (grid) {
- delete grid;
- }
-
- if (scene) {
- scene->Graphics().clear();
- delete scene;
- }
-
- if (screen) delete screen;
- if (video) delete video;
- if (video_settings) delete video_settings;
-
- if (magic_view == this)
- magic_view = 0;
-}
-
-MagicView* MagicView::GetInstance()
-{
- return magic_view;
-}
-
-BOOL MagicView::PreCreateWindow(CREATESTRUCT& cs)
-{
- return CView::PreCreateWindow(cs);
-}
-
-// +--------------------------------------------------------------------+
-//
-// MagicView diagnostics
-
-#ifdef _DEBUG
-void MagicView::AssertValid() const
-{
- CView::AssertValid();
-}
-
-void MagicView::Dump(CDumpContext& dc) const
-{
- CView::Dump(dc);
-}
-
-MagicDoc* MagicView::GetDocument() // non-debug version is inline
-{
- ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(MagicDoc)));
- return (MagicDoc*)m_pDocument;
-}
-#endif //_DEBUG
-
-
-// +--------------------------------------------------------------------+
-
-void MagicView::OnInitialUpdate()
-{
- CView::OnInitialUpdate();
- Color::SetPalette(standard_palette, 256, inverse_palette);
-
- if (!video_settings)
- video_settings = new VideoSettings;
-
- GetClientRect(&client_rect);
-
- // Use client area to set video window size
- int w = client_rect.right - client_rect.left;
- int h = client_rect.bottom - client_rect.top;
-
- video_settings->is_windowed = true;
- video_settings->window_width = w;
- video_settings->window_height = h;
-
- if (!video) {
- video = new VideoDX9(GetSafeHwnd(), video_settings);
- *video_settings = *video->GetVideoSettings();
-
- if (video) {
- Color::UseVideo(video);
- video->UseXFont("System", 12, false, false);
-
- screen = new Screen(video);
- if (!screen) {
- ::Print("ERROR: Could not create Screen object.\n");
- return;
- }
-
- ::Print(" Created screen object (%d x %d).\n", w, h);
-
- if (!screen->SetBackgroundColor(Color::Black))
- ::Print(" WARNING: could not set video background color to Black\n");
-
- screen->ClearAllFrames(true);
-
- ::Print(" Established requested video parameters.\n");
- ::Print(" ---------------------------------------\n\n");
-
- if (!scene) {
- scene = new Scene;
-
- scene->SetAmbient(Color(60,60,60));
-
- Point light_pos(3e6, 5e6, 4e6);
-
- main_light = new Light(1.0f); //1.25f);
- main_light->MoveTo(light_pos);
- main_light->SetType(Light::LIGHT_DIRECTIONAL);
- main_light->SetColor(Color::White);
- main_light->SetShadow(true);
-
- scene->AddLight(main_light);
-
- back_light = new Light(0.5f);
- back_light->MoveTo(light_pos * -1);
- back_light->SetType(Light::LIGHT_DIRECTIONAL);
- back_light->SetColor(Color::White);
-
- scene->AddLight(back_light);
-
- Selection* seln = GetDocument()->GetSelection();
- Selector* selector = GetDocument()->GetSelector();
-
- if (seln && selector) {
- scene->Graphics().clear();
- scene->AddGraphic(seln);
- scene->AddGraphic(selector);
-
- selector->UseModel(0);
- }
- }
-
- int mins[2] = { 0, 0 };
- float weights[2] = { 1, 1 };
-
- main_win = new ActiveWindow(screen, 0, 0, w, h, 100, 0);
- main_win->UseLayout(2, 2, mins, mins, weights, weights);
- main_win->SetBackColor(Color::Gray);
-
- screen->AddWindow(main_win);
-
- DWORD view_types[] = {
- ModelView::VIEW_PLAN,
- ModelView::VIEW_PROJECT,
- ModelView::VIEW_SIDE,
- ModelView::VIEW_FRONT
- };
-
- for (int row = 0; row < 2; row++) {
- for (int col = 0; col < 2; col++) {
- int index = 2*row + col;
-
- ActiveWindow* win = new ActiveWindow(screen,
- col*w/2,
- row*h/2,
- w/2,
- h/2,
- 101+index,
- WIN_BLACK_FRAME,
- main_win);
-
- win->SetCells(col, row, 1, 1);
- win->SetCellInsets(Insets(1,1,1,1));
- win->SetBackColor(Color(160,160,160));
-
- ModelView* mv = new ModelView(win, scene, view_types[index]);
-
- if (view_types[index] == ModelView::VIEW_PROJECT)
- mv->SetFillMode(ModelView::FILL_TEXTURE);
-
- mv->UseGrid(grid);
- win->AddView(mv);
-
- view_win[index] = win;
- model_view[index] = mv;
- }
- }
-
- view_win[0]->SetStyle(WIN_WHITE_FRAME);
-
- uvmap_win = new ActiveWindow(screen, 0, 0, w, h, 110, WIN_BLACK_FRAME, main_win);
- uvmap_view = new UVMapView(uvmap_win);
- uvmap_win->AddView(uvmap_view);
-
- main_win->DoLayout();
- }
-
- else {
- ::Print(" Could not establish requested video parameters.\n");
- ::Print(" -----------------------------------------------\n\n");
- }
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-MagicView::SetupModelViews()
-{
- switch (view_mode) {
- case VIEW_ALL: {
- for (int row = 0; row < 2; row++) {
- for (int col = 0; col < 2; col++) {
- int index = 2*row + col;
-
- ActiveWindow* win = view_win[index];
-
- win->Show();
- win->SetCells(col, row, 1, 1);
- win->SetCellInsets(Insets(1,1,1,1));
- }
- }
-
- uvmap_win->Hide();
- uvmap_win->SetCells(0,0,0,0);
- }
- break;
-
- case VIEW_TOP:
- case VIEW_SIDE:
- case VIEW_FRONT:
- case VIEW_PERSPECTIVE: {
- view_focus = view_mode;
-
- for (int i = 0; i < 4; i++) {
- ActiveWindow* win = view_win[i];
-
- if (i == view_mode) {
- win->Show();
- win->SetCells(0,0,2,2);
- win->SetStyle(WIN_WHITE_FRAME);
- }
-
- else {
- win->Hide();
- win->SetCells(0,0,0,0);
- win->SetStyle(WIN_BLACK_FRAME);
- }
- }
-
- uvmap_win->Hide();
- uvmap_win->SetCells(0,0,0,0);
- }
- break;
-
- case VIEW_UV_MAP: {
- view_focus = view_mode;
-
- for (int i = 0; i < 4; i++) {
- ActiveWindow* win = view_win[i];
- win->Hide();
- win->SetCells(0,0,0,0);
- win->SetStyle(WIN_BLACK_FRAME);
- }
-
- uvmap_win->Show();
- uvmap_win->SetCells(0,0,2,2);
- }
- break;
-
- default:
- break;
- }
-
- main_win->DoLayout();
-}
-
-void
-MagicView::SetFocusModelView(int f)
-{
- if (view_mode == VIEW_ALL) {
- view_focus = f;
-
- for (int row = 0; row < 2; row++) {
- for (int col = 0; col < 2; col++) {
- int index = 2*row + col;
-
- ActiveWindow* win = view_win[index];
-
- win->Show();
- win->SetCells(col, row, 1, 1);
- win->SetCellInsets(Insets(1,1,1,1));
-
- if (index == view_focus) {
- win->SetStyle(WIN_WHITE_FRAME);
- }
- else {
- win->SetStyle(WIN_BLACK_FRAME);
- }
- }
- }
- }
- else if (IsUVEdit()) {
- view_focus = view_mode;
- }
- else {
- view_mode = f;
- view_focus = f;
-
- for (int i = 0; i < 4; i++) {
- ActiveWindow* win = view_win[i];
-
- if (i == view_mode) {
- win->Show();
- win->SetCells(0,0,2,2);
- win->SetStyle(WIN_WHITE_FRAME);
- }
-
- else {
- win->Hide();
- win->SetCells(0,0,0,0);
- win->SetStyle(WIN_BLACK_FRAME);
- }
- }
- }
-
- main_win->DoLayout();
-}
-
-int
-MagicView::GetWinIndexByPoint(int x, int y)
-{
- if (view_mode == VIEW_ALL) {
- for (int row = 0; row < 2; row++) {
- for (int col = 0; col < 2; col++) {
- int index = 2*row + col;
-
- ActiveWindow* win = view_win[index];
- if (win->GetRect().Contains(x, y))
- return index;
- }
- }
- }
-
- return view_mode;
-}
-
-ModelView*
-MagicView::GetModelViewByIndex(int index)
-{
- if (index >= 0 && index < 4) {
- return model_view[index];
- }
-
- return model_view[0];
-}
-
-// +--------------------------------------------------------------------+
-
-void MagicView::OnPaint()
-{
- ValidateRect(0);
- OnRender();
-}
-
-void MagicView::OnDraw(CDC* dc)
-{
-}
-
-// +--------------------------------------------------------------------+
-
-void MagicView::ResizeVideo()
-{
- if (!video || !video_settings) return;
-
- HRESULT hr = S_OK;
- RECT client_old;
-
- client_old = client_rect;
-
- // Update window properties
- GetClientRect(&client_rect);
-
- if (client_old.right - client_old.left !=
- client_rect.right - client_rect.left ||
- client_old.bottom - client_old.top !=
- client_rect.bottom - client_rect.top) {
-
- // A new window size will require a new backbuffer
- // size, so the 3D structures must be changed accordingly.
-
- video_settings->is_windowed = true;
- video_settings->window_width = client_rect.right - client_rect.left;
- video_settings->window_height = client_rect.bottom - client_rect.top;
-
- ::Print("ResizeVideo() %d x %d\n", video_settings->window_width, video_settings->window_height);
-
- if (video) {
- video->Reset(video_settings);
- }
- }
-
- // save a copy of the device-specific video settings:
- if (video->GetVideoSettings()) {
- *video_settings = *video->GetVideoSettings();
- }
-
- if (screen)
- screen->Resize(video_settings->window_width,
- video_settings->window_height);
-
- video->InvalidateCache();
- video->SetShadowEnabled(view_shadows);
- video->SetBumpMapEnabled(view_bumpmaps);
-}
-
-// +--------------------------------------------------------------------+
-
-void MagicView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
-{
- CView::OnUpdate(pSender, lHint, pHint);
-
- Solid* solid = GetDocument()->GetSolid();
- Selection* seln = GetDocument()->GetSelection();
- Selector* selector = GetDocument()->GetSelector();
-
- if (solid && scene) {
- scene->Graphics().clear();
- scene->AddGraphic(solid);
- scene->AddGraphic(seln);
- scene->AddGraphic(selector);
- }
-
- if (selector)
- selector->UseModel(solid->GetModel());
-}
-
-CPoint
-MagicView::LPtoWP(const CPoint& p)
-{
- CPoint result;
- ModelView* view = GetModelViewByIndex(view_focus);
- CPoint origin = view->ProjectPoint(Vec3(0,0,0));
- double scale = view->GetFieldOfView() / 2;
-
- result.x = (LONG) (( p.x - origin.x) / scale);
- result.y = (LONG) ((-p.y + origin.y) / scale);
-
- return result;
-}
-
-// +--------------------------------------------------------------------+
-//
-// MagicView message handlers
-
-void MagicView::OnEnterSizeMove()
-{
- is_sizing = true;
-}
-
-void MagicView::OnExitSizeMove()
-{
- is_sizing = false;
- ResizeVideo();
-}
-
-void MagicView::OnSize(UINT nType, int cx, int cy)
-{
- CView::OnSize(nType, cx, cy);
-
- window_style = GetWindowLong(m_hWnd, GWL_STYLE);
-
- if (nType == SIZE_MINIMIZED) {
- is_minimized = true;
- is_maximized = false;
- }
-
- else if (nType == SIZE_MAXIMIZED) {
- is_minimized = false;
- is_maximized = true;
- ResizeVideo();
- }
-
- else if (nType == SIZE_RESTORED) {
- if (is_maximized) {
- is_maximized = false;
- ResizeVideo();
- }
-
- else if (is_minimized) {
- is_minimized = false;
- ResizeVideo();
- }
- else if (!is_sizing) {
- // if this is not a resize due to dragging...
- ResizeVideo();
- }
- else {
- // If we're neither maximized nor minimized, the window size
- // is changing by the user dragging the window edges. In this
- // case, we don't reset the device yet -- we wait until the
- // user stops dragging, and a WM_EXITSIZEMOVE message comes.
- }
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void MagicView::OnRender()
-{
- if (!screen || !video)
- return;
-
- double s = sin(timeGetTime() * 0.001);
- double c = cos(timeGetTime() * 0.001);
-
- // IF LIGHTS ANIMATED:
- if (animate_light) {
- Point light_pos(3e6*s, 5e6*c, 4e6*s);
-
- if (main_light) {
- main_light->SetType(Light::LIGHT_POINT);
- main_light->MoveTo(light_pos);
- main_light->SetType(Light::LIGHT_DIRECTIONAL);
- }
-
- if (back_light) {
- back_light->SetType(Light::LIGHT_POINT);
- back_light->MoveTo(light_pos * -1);
- back_light->SetType(Light::LIGHT_DIRECTIONAL);
- }
- }
-
- if (screen->Refresh()) {
- video->Present();
- }
- else {
- ::Print("ERROR: Screen refresh failed.\n");
- }
-}
-
-void MagicView::CloseUVEditor()
-{
- if (IsUVEdit()) {
- MagicDoc* doc = GetDocument();
- Editor* editor = doc->GetEditor();
- Solid* solid = doc->GetSolid();
-
- if (editor && solid) {
- editor->UseModel(solid->GetModel());
- editor->Resegment();
- }
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void MagicView::OnViewAll()
-{
- CloseUVEditor();
- view_mode = VIEW_ALL;
- SetupModelViews();
-}
-
-void MagicView::OnUpdateViewAll(CCmdUI* pCmdUI)
-{
- if (pCmdUI)
- pCmdUI->SetCheck(view_mode == VIEW_ALL);
-}
-
-void MagicView::OnViewFront()
-{
- CloseUVEditor();
- view_mode = VIEW_FRONT;
- SetupModelViews();
-}
-
-void MagicView::OnUpdateViewFront(CCmdUI* pCmdUI)
-{
- if (pCmdUI)
- pCmdUI->SetCheck(view_mode == VIEW_FRONT);
-}
-
-void MagicView::OnViewPerspective()
-{
- CloseUVEditor();
- view_mode = VIEW_PERSPECTIVE;
- SetupModelViews();
-}
-
-void MagicView::OnUpdateViewPerspective(CCmdUI* pCmdUI)
-{
- if (pCmdUI)
- pCmdUI->SetCheck(view_mode == VIEW_PERSPECTIVE);
-}
-
-void MagicView::OnViewSide()
-{
- CloseUVEditor();
- view_mode = VIEW_SIDE;
- SetupModelViews();
-}
-
-void MagicView::OnUpdateViewSide(CCmdUI* pCmdUI)
-{
- if (pCmdUI)
- pCmdUI->SetCheck(view_mode == VIEW_SIDE);
-}
-
-void MagicView::OnViewTop()
-{
- CloseUVEditor();
- view_mode = VIEW_TOP;
- SetupModelViews();
-}
-
-void MagicView::OnUpdateViewTop(CCmdUI* pCmdUI)
-{
- if (pCmdUI)
- pCmdUI->SetCheck(view_mode == VIEW_TOP);
-}
-
-// +--------------------------------------------------------------------+
-
-void MagicView::OnFileImport()
-{
- DWORD err = 0;
- char filename[256];
- filename[0] = '\0';
- CFileDialog ofd(TRUE, "mag");
-
- ofd.m_ofn.lpstrFilter = "All 3D Files\0*.mag; *.obj; *.3ds\0Magic Files (*.mag)\0*.mag\0Wavefront/OBJ Files (*.obj)\0*.obj\0003DS MAX Files (*.3ds)\0*.3ds\0\0";
- ofd.m_ofn.lpstrFile = filename;
- ofd.m_ofn.nMaxFile = sizeof(filename);
-
- if (ofd.DoModal() != IDOK)
- return;
-
- char mag_name[256];
- sprintf_s(mag_name, "%s", ofd.GetFileName().GetBuffer(0));
-
- MagicDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
-
- if (pDoc->ImportFile(mag_name)) {
- Invalidate();
- pDoc->SetModifiedFlag(TRUE);
- pDoc->UpdateAllViews(this);
- }
-}
-
-void MagicView::OnFileExport()
-{
- DWORD err = 0;
- char filename[256];
- filename[0] = '\0';
- CFileDialog ofd(FALSE, "mag");
-
- ofd.m_ofn.lpstrFilter = "All 3D Files\0*.mag; *.obj; *.3ds\0Magic Files (*.mag)\0*.mag\0Wavefront/OBJ Files (*.obj)\0*.obj\0003DS MAX Files (*.3ds)\0*.3ds\0\0";
- ofd.m_ofn.lpstrFile = filename;
- ofd.m_ofn.nMaxFile = sizeof(filename);
-
- if (ofd.DoModal() != IDOK)
- return;
-
- char mag_name[256];
- sprintf_s(mag_name, "%s", ofd.GetFileName().GetBuffer(0));
-
- MagicDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
-
- if (pDoc->ExportFile(mag_name)) {
- pDoc->SetModifiedFlag(FALSE);
- pDoc->UpdateAllViews(this);
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void MagicView::OnSurfaceProperties()
-{
- SurfacePropertiesDialog dlg(this);
- dlg.DoModal();
-}
-
-void MagicView::OnUpdateSurfaceProperties(CCmdUI* pCmdUI)
-{
- Solid* solid = GetDocument()->GetSolid();
- pCmdUI->Enable(solid && solid->GetModel());
-}
-
-// +--------------------------------------------------------------------+
-
-void MagicView::OnTextureMap()
-{
- TextureMapDialog dlg(this);
- if (dlg.DoModal() == IDOK) {
- MagicDoc* doc = GetDocument();
- Solid* solid = doc->GetSolid();
- Selection* seln = doc->GetSelection();
- Selector* selector = doc->GetSelector();
- Editor* editor = doc->GetEditor();
- Material* mtl = 0;
-
- if (dlg.mMaterialIndex >= 0) {
- mtl = solid->GetModel()->GetMaterials()[dlg.mMaterialIndex];
- }
-
- editor->UseModel(solid->GetModel());
- editor->ApplyMaterial(mtl, seln->GetPolys(),
- dlg.mMapType, 2-dlg.mAxis, (float) dlg.mScaleU, (float) dlg.mScaleV,
- dlg.mFlip, dlg.mMirror, dlg.mRotate);
-
- selector->Reselect();
-
- Invalidate();
- doc->SetModifiedFlag(TRUE);
- doc->UpdateAllViews(this);
- }
-}
-
-void MagicView::OnUpdateTextureMap(CCmdUI* pCmdUI)
-{
- Solid* solid = GetDocument()->GetSolid();
- Selection* seln = GetDocument()->GetSelection();
-
- pCmdUI->Enable(solid && solid->GetModel() && seln && seln->GetPolys().size() > 0);
-}
-
-void MagicView::OnModifyMaterial()
-{
- MaterialDialog dlg(this);
- dlg.DoModal();
-
- Invalidate();
- GetDocument()->SetModifiedFlag(TRUE);
- GetDocument()->UpdateAllViews(this);
-}
-
-void MagicView::OnUpdateModifyMaterial(CCmdUI* pCmdUI)
-{
- Solid* solid = GetDocument()->GetSolid();
- pCmdUI->Enable(solid && solid->GetModel());
-}
-
-void MagicView::OnModifyUVMap()
-{
- Selection* seln = GetDocument()->GetSelection();
-
- view_mode = VIEW_UV_MAP;
- SetupModelViews();
-
- if (seln && uvmap_view) {
- Poly* p = seln->GetPolys().first();
-
- if (p) {
- uvmap_view->UseMaterial(p->material);
- uvmap_view->UsePolys(seln->GetPolys());
- }
- }
-}
-
-void MagicView::OnUpdateModifyUVMap(CCmdUI* pCmdUI)
-{
- OnUpdateTextureMap(pCmdUI);
-}
-
-// +--------------------------------------------------------------------+
-
-void MagicView::OnGridProperties()
-{
- GridProps dlg(grid, this);
- dlg.DoModal();
-}
-
-void MagicView::OnGridShow()
-{
- if (grid)
- grid->SetShow(!grid->IsShow());
-}
-
-void MagicView::OnGridSnap()
-{
- if (grid)
- grid->SetSnap(!grid->IsSnap());
-}
-
-void MagicView::OnUpdateGridSnap(CCmdUI* pCmdUI)
-{
- if (grid)
- pCmdUI->SetCheck(grid->IsSnap());
-}
-
-// +--------------------------------------------------------------------+
-
-void MagicView::OnLButtonDown(UINT nFlags, CPoint point)
-{
- CView::OnLButtonDown(nFlags, point);
- SetCapture();
-
- // set focus to the view that was clicked:
- int index = GetWinIndexByPoint(point.x, point.y);
- SetFocusModelView(index);
-
- drag_start = point;
- drag_left = true;
- drag_right = false;
-
- ModelView* mv = GetModelViewByIndex(index);
- MagicDoc* pDoc = GetDocument();
- Model* model = pDoc->GetSolid()->GetModel();
- Selector* selector = pDoc->GetSelector();
-
- if (IsUVEdit()) {
- int select_mode = UVMapView::SELECT_APPEND;
-
- if (nFlags & MK_CONTROL)
- select_mode = UVMapView::SELECT_REMOVE;
-
- if (!uvmap_view->WillSelect(point)) {
- uvmap_view->Begin(select_mode);
- uvmap_view->AddMark(point);
- }
- }
-
- else if (mv && selector) {
- int select_mode = Selector::SELECT_APPEND;
-
- if (nFlags & MK_CONTROL)
- select_mode = Selector::SELECT_REMOVE;
-
- selector->Begin(model, mv->GetViewMode(), select_mode);
- selector->AddMark(point);
- }
-}
-
-void MagicView::OnLButtonUp(UINT nFlags, CPoint point)
-{
- CView::OnLButtonUp(nFlags, point);
- ReleaseCapture();
-
- drag_left = false;
-
- MagicDoc* pDoc = GetDocument();
- Selector* selector = pDoc->GetSelector();
-
- if (IsUVEdit())
- uvmap_view->End();
-
- else if (selector && selector->IsActive())
- selector->End();
-}
-
-void MagicView::OnLButtonDblClk(UINT nFlags, CPoint point)
-{
- CView::OnLButtonDblClk(nFlags, point);
-
- drag_left = false;
-
- MagicDoc* pDoc = GetDocument();
- Selector* selector = pDoc->GetSelector();
-
- if (IsUVEdit())
- uvmap_view->Clear();
-
- else if (selector)
- selector->Clear();
-}
-
-void MagicView::OnRButtonDown(UINT nFlags, CPoint point)
-{
- CView::OnRButtonDown(nFlags, point);
- SetCapture();
-
- // set focus to the view that was clicked:
- int index = GetWinIndexByPoint(point.x, point.y);
- SetFocusModelView(index);
-
- drag_start = point;
- drag_left = false;
- drag_right = true;
-}
-
-void MagicView::OnRButtonUp(UINT nFlags, CPoint point)
-{
- CView::OnRButtonUp(nFlags, point);
- ReleaseCapture();
-
- drag_right = false;
-}
-
-void MagicView::OnRButtonDblClk(UINT nFlags, CPoint point)
-{
- CView::OnRButtonDblClk(nFlags, point);
- ReleaseCapture();
-
- drag_right = false;
-
- if (view_mode == VIEW_ALL) {
- view_mode = view_focus;
- }
- else if (IsUVEdit()) {
- CloseUVEditor();
- view_mode = VIEW_ALL;
- SetupModelViews();
- }
- else {
- view_mode = VIEW_ALL;
- }
-
- SetFocusModelView(view_focus);
-}
-
-void MagicView::OnMouseMove(UINT nFlags, CPoint point)
-{
- if (drag_right) {
- CPoint offset = point - drag_start;
-
- if (view_focus == VIEW_PERSPECTIVE) {
- ModelView* view = GetModelViewByIndex(view_focus);
- view->SpinBy(offset.x * 0.5 * DEGREES,
- offset.y * 0.5 * DEGREES);
- }
-
- else if (IsUVEdit()) {
- uvmap_view->MoveBy(offset.x, offset.y);
- }
-
- else {
- ModelView* view = GetModelViewByIndex(view_focus);
- view->MoveBy(offset.x, offset.y);
- }
-
- drag_start = point;
- Invalidate();
- }
-
- else if (drag_left) {
- CPoint offset = point - drag_start;
- MagicDoc* pDoc = GetDocument();
- Selector* selector = pDoc->GetSelector();
-
- if (IsUVEdit()) {
- if (uvmap_view->IsActive()) {
- uvmap_view->AddMark(point);
- }
- else {
- uvmap_view->DragBy(offset.x, offset.y);
- drag_start = point;
- }
- }
-
- else if (selector && selector->IsActive()) {
- selector->AddMark(point);
- }
- }
-
- // xy status message:
- if (view_focus != VIEW_PERSPECTIVE) {
- char xy[80];
- CPoint mouse = LPtoWP(point);
- Selection* seln = GetDocument()->GetSelection();
-
- int nv = seln ? seln->GetVerts().size() : 0;
- int np = seln ? seln->GetPolys().size() : 0;
-
- if (np || nv)
- sprintf_s(xy, "(%05d,%05d) Verts:%d Polys:%d", mouse.x, mouse.y, nv, np);
- else
- sprintf_s(xy, "(%05d,%05d)", mouse.x, mouse.y);
- MainFrame::StatusXY(xy);
- }
-
- CView::OnMouseMove(nFlags, point);
-}
-
-BOOL MagicView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
-{
- if (view_focus == VIEW_PERSPECTIVE) {
- ModelView* view = GetModelViewByIndex(view_focus);
-
- if (view) {
- Camera* cam = view->GetCamera();
- Point pos = cam->Pos();
- double len = pos.length();
-
- if (zDelta < 0) {
- if (len < 10000)
- pos *= 1.15;
- }
- else {
- if (len > 0.10)
- pos *= 0.85;
- }
-
- cam->MoveTo(pos);
- }
- }
-
- else if (IsUVEdit()) {
- if (zDelta < 0) {
- uvmap_view->ZoomOut();
- }
- else {
- uvmap_view->ZoomIn();
- }
- }
-
- else {
- if (zDelta > 0)
- OnViewZoomIn();
- else
- OnViewZoomOut();
- }
-
- return 0;
-}
-
-// +--------------------------------------------------------------------+
-
-void MagicView::OnViewZoomNormal()
-{
- for (int i = 0; i < 4; i++) {
- ModelView* view = GetModelViewByIndex(i);
-
- if (view) {
- view->ZoomNormal();
- }
- }
-}
-
-void MagicView::OnViewZoomIn()
-{
- for (int i = 0; i < 4; i++) {
- ModelView* view = GetModelViewByIndex(i);
-
- if (view && view->GetViewMode() != ModelView::VIEW_PROJECT) {
- double fov = view->GetFieldOfView() * 1.15;
- view->SetFieldOfView(fov);
- }
- }
-}
-
-void MagicView::OnViewZoomOut()
-{
- for (int i = 0; i < 4; i++) {
- ModelView* view = GetModelViewByIndex(i);
-
- if (view && view->GetViewMode() != ModelView::VIEW_PROJECT) {
- double fov = view->GetFieldOfView() * 0.85;
- view->SetFieldOfView(fov);
- }
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void MagicView::OnViewModeWireframe()
-{
- ModelView* view = GetModelViewByIndex(view_focus);
-
- if (view) {
- view->SetFillMode(ModelView::FILL_WIRE);
- }
-}
-
-void MagicView::OnViewModeSolid()
-{
- ModelView* view = GetModelViewByIndex(view_focus);
-
- if (view) {
- view->SetFillMode(ModelView::FILL_SOLID);
- }
-}
-
-void MagicView::OnViewModeTextured()
-{
- ModelView* view = GetModelViewByIndex(view_focus);
-
- if (view) {
- view->SetFillMode(ModelView::FILL_TEXTURE);
- }
-}
-
-void MagicView::OnViewBackColor()
-{
- ModelView* view = GetModelViewByIndex(view_focus);
-
- if (view) {
- ActiveWindow* win = (ActiveWindow*) view->GetWindow();
- Color c = win->GetBackColor();
- COLORREF crgb = RGB(c.Red(), c.Green(), c.Blue());
- CColorDialog chooser(crgb);
-
- if (chooser.DoModal() == IDOK) {
- crgb = chooser.GetColor();
- win->SetBackColor( Color(GetRValue(crgb), GetGValue(crgb), GetBValue(crgb)) );
- }
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void MagicView::OnSelectAll()
-{
- Solid* solid = GetDocument()->GetSolid();
- Selector* selector = GetDocument()->GetSelector();
-
- if (IsUVEdit()) {
- uvmap_view->SelectAll();
- }
-
- else if (solid && selector) {
- selector->UseModel(solid->GetModel());
- selector->SelectAll(Selector::SELECT_APPEND);
- }
-}
-
-void MagicView::OnSelectNone()
-{
- Solid* solid = GetDocument()->GetSolid();
- Selector* selector = GetDocument()->GetSelector();
-
- if (IsUVEdit()) {
- uvmap_view->SelectNone();
- }
-
- else if (solid && selector) {
- selector->UseModel(solid->GetModel());
- selector->SelectAll(Selector::SELECT_REMOVE);
- }
-}
-
-void MagicView::OnSelectInverse()
-{
- Solid* solid = GetDocument()->GetSolid();
- Selector* selector = GetDocument()->GetSelector();
-
- if (IsUVEdit()) {
- uvmap_view->SelectInverse();
- }
-
- else if (solid && selector) {
- selector->UseModel(solid->GetModel());
- selector->SelectInverse();
- }
-}
-
-void MagicView::OnViewShadows()
-{
- view_shadows = !view_shadows;
-
- if (video)
- video->SetShadowEnabled(view_shadows);
-}
-
-void MagicView::OnUpdateViewShadows(CCmdUI* pCmdUI)
-{
- pCmdUI->SetCheck(view_shadows);
-}
-
-void MagicView::OnViewAnimatelight()
-{
- animate_light = !animate_light;
-}
-
-void MagicView::OnUpdateViewAnimatelight(CCmdUI* pCmdUI)
-{
- pCmdUI->SetCheck(animate_light);
-}
-
-void MagicView::OnViewBumpmaps()
-{
- view_bumpmaps = !view_bumpmaps;
-
- if (video)
- video->SetBumpMapEnabled(view_bumpmaps);
-}
-
-void MagicView::OnUpdateViewBumpmaps(CCmdUI* pCmdUI)
-{
- pCmdUI->SetCheck(view_bumpmaps);
-}
-
-void MagicView::OnViewVertexshader()
-{
- if (video) {
- VideoSettings* vs = (VideoSettings*) video->GetVideoSettings();
- vs->enable_vs = !vs->enable_vs;
- }
-}
-
-void MagicView::OnUpdateViewVertexshader(CCmdUI* pCmdUI)
-{
- if (video)
- pCmdUI->SetCheck(video->GetVideoSettings()->enable_vs);
-}
-
-void MagicView::OnViewPixelshader()
-{
- if (video) {
- VideoSettings* vs = (VideoSettings*) video->GetVideoSettings();
- vs->enable_ps = !vs->enable_ps;
- }
-}
-
-void MagicView::OnUpdateViewPixelshader(CCmdUI* pCmdUI)
-{
- if (video)
- pCmdUI->SetCheck(video->GetVideoSettings()->enable_ps);
-}
-
-void MagicView::OnViewVisibleshadows()
-{
- Shadow::SetVisibleShadowVolumes(!Shadow::GetVisibleShadowVolumes());
-}
-
-void MagicView::OnUpdateViewVisibleshadows(CCmdUI* pCmdUI)
-{
- pCmdUI->SetCheck(Shadow::GetVisibleShadowVolumes());
-}
-
-void MagicView::OnEditUndo()
-{
- MagicDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- pDoc->Undo();
-
- Solid* solid = GetDocument()->GetSolid();
- Selector* selector = GetDocument()->GetSelector();
-
- if (selector) {
- selector->UseModel(solid->GetModel());
- selector->Reselect();
- }
-
- Invalidate();
- pDoc->SetModifiedFlag(TRUE);
- pDoc->UpdateAllViews(this);
-}
-
-void MagicView::OnUpdateEditUndo(CCmdUI* pCmdUI)
-{
- MagicDoc* pDoc = GetDocument();
-
- if (pDoc->NumUndo() > 0) {
- pCmdUI->Enable(TRUE);
- pCmdUI->SetText(CString("Undo ") + pDoc->GetUndoName() + CString("\tCtrl+Z"));
- }
- else {
- pCmdUI->Enable(FALSE);
- pCmdUI->SetText("Can't Undo\tCtrl+Z");
- }
-}
-
-void MagicView::OnEditRedo()
-{
- MagicDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- pDoc->Redo();
-
- Solid* solid = GetDocument()->GetSolid();
- Selector* selector = GetDocument()->GetSelector();
-
- if (selector) {
- selector->UseModel(solid->GetModel());
- selector->Reselect();
- }
-
- Invalidate();
- pDoc->SetModifiedFlag(TRUE);
- pDoc->UpdateAllViews(this);
-}
-
-void MagicView::OnUpdateEditRedo(CCmdUI* pCmdUI)
-{
- MagicDoc* pDoc = GetDocument();
-
- if (pDoc->NumRedo() > 0) {
- pCmdUI->Enable(TRUE);
- pCmdUI->SetText(CString("Redo ") + pDoc->GetRedoName() + CString("\tCtrl+Y"));
- }
- else {
- pCmdUI->Enable(FALSE);
- pCmdUI->SetText("Can't Redo");
- }
-}
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: MagicView.cpp
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Implementation of the MagicView class
+*/
+
+#include "stdafx.h"
+#include "Magic.h"
+
+#include "MagicDoc.h"
+#include "MagicView.h"
+#include "MainFrm.h"
+#include "MaterialDialog.h"
+#include "SurfacePropertiesDialog.h"
+#include "TextureMapDialog.h"
+#include "Editor.h"
+#include "Grid.h"
+#include "GridProps.h"
+#include "Selection.h"
+#include "Selector.h"
+#include "UVMapView.h"
+
+#include "ActiveWindow.h"
+#include "Color.h"
+#include "Layout.h"
+#include "Light.h"
+#include "Scene.h"
+#include "Screen.h"
+#include "Shadow.h"
+#include "Solid.h"
+#include "Video.h"
+#include "VideoDX9.h"
+#include "VideoSettings.h"
+
+#include "ModelView.h"
+
+DWORD GetRealTime();
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+extern PALETTEENTRY standard_palette[256];
+extern BYTE inverse_palette[32768];
+
+// +--------------------------------------------------------------------+
+
+IMPLEMENT_DYNCREATE(MagicView, CView)
+
+BEGIN_MESSAGE_MAP(MagicView, CView)
+ //{{AFX_MSG_MAP(MagicView)
+ ON_WM_SIZE()
+ ON_COMMAND(ID_VIEW_RENDER, OnRender)
+ ON_WM_PAINT()
+ ON_COMMAND(ID_VIEW_ALL, OnViewAll)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_ALL, OnUpdateViewAll)
+ ON_COMMAND(ID_VIEW_FRONT, OnViewFront)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_FRONT, OnUpdateViewFront)
+ ON_COMMAND(ID_VIEW_PERSPECTIVE, OnViewPerspective)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_PERSPECTIVE, OnUpdateViewPerspective)
+ ON_COMMAND(ID_VIEW_SIDE, OnViewSide)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_SIDE, OnUpdateViewSide)
+ ON_COMMAND(ID_VIEW_TOP, OnViewTop)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_TOP, OnUpdateViewTop)
+ ON_COMMAND(ID_MODIFY_TEXTURE_MAP, OnTextureMap)
+ ON_COMMAND(ID_MODIFY_MATERIAL, OnModifyMaterial)
+ ON_WM_LBUTTONDOWN()
+ ON_WM_LBUTTONUP()
+ ON_WM_LBUTTONDBLCLK()
+ ON_WM_RBUTTONDOWN()
+ ON_WM_RBUTTONUP()
+ ON_WM_MOUSEMOVE()
+ ON_WM_MOUSEWHEEL()
+ ON_COMMAND(ID_VIEW_ZOOM_NORMAL, OnViewZoomNormal)
+ ON_COMMAND(ID_VIEW_ZOOM_IN, OnViewZoomIn)
+ ON_COMMAND(ID_VIEW_ZOOM_OUT, OnViewZoomOut)
+ ON_COMMAND(ID_VIEW_MODE_WIREFRAME, OnViewModeWireframe)
+ ON_COMMAND(ID_VIEW_MODE_SOLID, OnViewModeSolid)
+ ON_COMMAND(ID_VIEW_MODE_TEXTURED, OnViewModeTextured)
+ ON_WM_RBUTTONDBLCLK()
+ ON_COMMAND(ID_PROP_GRID, OnGridProperties)
+ ON_COMMAND(ID_GRID_SHOW, OnGridShow)
+ ON_COMMAND(ID_GRID_SNAP, OnGridSnap)
+ ON_UPDATE_COMMAND_UI(ID_GRID_SNAP, OnUpdateGridSnap)
+ ON_COMMAND(ID_VIEW_BACK_COLOR, OnViewBackColor)
+ ON_COMMAND(ID_FILE_IMPORT, OnFileImport)
+ ON_COMMAND(ID_FILE_EXPORT, OnFileExport)
+ ON_COMMAND(ID_EDIT_SELECT_ALL, OnSelectAll)
+ ON_COMMAND(ID_EDIT_SELECT_NONE, OnSelectNone)
+ ON_UPDATE_COMMAND_UI(ID_MODIFY_TEXTURE_MAP, OnUpdateTextureMap)
+ ON_UPDATE_COMMAND_UI(ID_MODIFY_MATERIAL, OnUpdateModifyMaterial)
+ ON_COMMAND(ID_EDIT_SELECT_INVERSE, OnSelectInverse)
+ ON_COMMAND(ID_MODIFY_UV_MAP, OnModifyUVMap)
+ ON_UPDATE_COMMAND_UI(ID_MODIFY_UV_MAP, OnUpdateModifyUVMap)
+ ON_COMMAND(ID_VIEW_SHADOWS, OnViewShadows)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_SHADOWS, OnUpdateViewShadows)
+ ON_COMMAND(ID_VIEW_ANIMATELIGHT, OnViewAnimatelight)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_ANIMATELIGHT, OnUpdateViewAnimatelight)
+ ON_COMMAND(ID_VIEW_BUMPMAPS, OnViewBumpmaps)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_BUMPMAPS, OnUpdateViewBumpmaps)
+ ON_COMMAND(ID_VIEW_VERTEXSHADER, OnViewVertexshader)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_VERTEXSHADER, OnUpdateViewVertexshader)
+ ON_COMMAND(ID_VIEW_PIXELSHADER, OnViewPixelshader)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_PIXELSHADER, OnUpdateViewPixelshader)
+ ON_COMMAND(ID_VIEW_VISIBLESHADOWS, OnViewVisibleshadows)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_VISIBLESHADOWS, OnUpdateViewVisibleshadows)
+ ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
+ ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo)
+ ON_COMMAND(ID_EDIT_REDO, OnEditRedo)
+ ON_UPDATE_COMMAND_UI(ID_EDIT_REDO, OnUpdateEditRedo)
+ ON_COMMAND(ID_PROP_SURFACE, OnSurfaceProperties)
+ ON_UPDATE_COMMAND_UI(ID_PROP_SURFACE, OnUpdateSurfaceProperties)
+ //}}AFX_MSG_MAP
+ // Standard printing commands
+ ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
+ ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
+ ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
+END_MESSAGE_MAP()
+
+// +--------------------------------------------------------------------+
+
+static MagicView* magic_view = 0;
+
+MagicView::MagicView()
+ : video(0), video_settings(0), screen(0), scene(0),
+ drag_left(false), drag_right(false), grid(0),
+ main_light(0), back_light(0), view_shadows(true), view_bumpmaps(true),
+ animate_light(false)
+{
+ window_style = 0;
+ is_minimized = false;
+ is_maximized = false;
+ is_sizing = false;
+ view_mode = VIEW_ALL;
+
+ main_win = 0;
+ view_win[0] = 0;
+ view_win[1] = 0;
+ view_win[2] = 0;
+ view_win[3] = 0;
+ model_view[0] = 0;
+ model_view[1] = 0;
+ model_view[2] = 0;
+ model_view[3] = 0;
+ uvmap_win = 0;
+
+ grid = new Grid;
+ magic_view = this;
+
+ Solid::EnableCollision(false);
+}
+
+MagicView::~MagicView()
+{
+ if (grid) {
+ delete grid;
+ }
+
+ if (scene) {
+ scene->Graphics().clear();
+ delete scene;
+ }
+
+ if (screen) delete screen;
+ if (video) delete video;
+ if (video_settings) delete video_settings;
+
+ if (magic_view == this)
+ magic_view = 0;
+}
+
+MagicView* MagicView::GetInstance()
+{
+ return magic_view;
+}
+
+BOOL MagicView::PreCreateWindow(CREATESTRUCT& cs)
+{
+ return CView::PreCreateWindow(cs);
+}
+
+// +--------------------------------------------------------------------+
+//
+// MagicView diagnostics
+
+#ifdef _DEBUG
+void MagicView::AssertValid() const
+{
+ CView::AssertValid();
+}
+
+void MagicView::Dump(CDumpContext& dc) const
+{
+ CView::Dump(dc);
+}
+
+MagicDoc* MagicView::GetDocument() // non-debug version is inline
+{
+ ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(MagicDoc)));
+ return (MagicDoc*)m_pDocument;
+}
+#endif //_DEBUG
+
+
+// +--------------------------------------------------------------------+
+
+void MagicView::OnInitialUpdate()
+{
+ CView::OnInitialUpdate();
+ Color::SetPalette(standard_palette, 256, inverse_palette);
+
+ if (!video_settings)
+ video_settings = new VideoSettings;
+
+ GetClientRect(&client_rect);
+
+ // Use client area to set video window size
+ int w = client_rect.right - client_rect.left;
+ int h = client_rect.bottom - client_rect.top;
+
+ video_settings->is_windowed = true;
+ video_settings->window_width = w;
+ video_settings->window_height = h;
+
+ if (!video) {
+ video = new VideoDX9(GetSafeHwnd(), video_settings);
+ *video_settings = *video->GetVideoSettings();
+
+ if (video) {
+ Color::UseVideo(video);
+ video->UseXFont("System", 12, false, false);
+
+ screen = new Screen(video);
+ if (!screen) {
+ ::Print("ERROR: Could not create Screen object.\n");
+ return;
+ }
+
+ ::Print(" Created screen object (%d x %d).\n", w, h);
+
+ if (!screen->SetBackgroundColor(Color::Black))
+ ::Print(" WARNING: could not set video background color to Black\n");
+
+ screen->ClearAllFrames(true);
+
+ ::Print(" Established requested video parameters.\n");
+ ::Print(" ---------------------------------------\n\n");
+
+ if (!scene) {
+ scene = new Scene;
+
+ scene->SetAmbient(Color(60,60,60));
+
+ Point light_pos(3e6, 5e6, 4e6);
+
+ main_light = new Light(1.0f); //1.25f);
+ main_light->MoveTo(light_pos);
+ main_light->SetType(Light::LIGHT_DIRECTIONAL);
+ main_light->SetColor(Color::White);
+ main_light->SetShadow(true);
+
+ scene->AddLight(main_light);
+
+ back_light = new Light(0.5f);
+ back_light->MoveTo(light_pos * -1);
+ back_light->SetType(Light::LIGHT_DIRECTIONAL);
+ back_light->SetColor(Color::White);
+
+ scene->AddLight(back_light);
+
+ Selection* seln = GetDocument()->GetSelection();
+ Selector* selector = GetDocument()->GetSelector();
+
+ if (seln && selector) {
+ scene->Graphics().clear();
+ scene->AddGraphic(seln);
+ scene->AddGraphic(selector);
+
+ selector->UseModel(0);
+ }
+ }
+
+ int mins[2] = { 0, 0 };
+ float weights[2] = { 1, 1 };
+
+ main_win = new ActiveWindow(screen, 0, 0, w, h, 100, 0);
+ main_win->UseLayout(2, 2, mins, mins, weights, weights);
+ main_win->SetBackColor(Color::Gray);
+
+ screen->AddWindow(main_win);
+
+ DWORD view_types[] = {
+ ModelView::VIEW_PLAN,
+ ModelView::VIEW_PROJECT,
+ ModelView::VIEW_SIDE,
+ ModelView::VIEW_FRONT
+ };
+
+ for (int row = 0; row < 2; row++) {
+ for (int col = 0; col < 2; col++) {
+ int index = 2*row + col;
+
+ ActiveWindow* win = new ActiveWindow(screen,
+ col*w/2,
+ row*h/2,
+ w/2,
+ h/2,
+ 101+index,
+ WIN_BLACK_FRAME,
+ main_win);
+
+ win->SetCells(col, row, 1, 1);
+ win->SetCellInsets(Insets(1,1,1,1));
+ win->SetBackColor(Color(160,160,160));
+
+ ModelView* mv = new ModelView(win, scene, view_types[index]);
+
+ if (view_types[index] == ModelView::VIEW_PROJECT)
+ mv->SetFillMode(ModelView::FILL_TEXTURE);
+
+ mv->UseGrid(grid);
+ win->AddView(mv);
+
+ view_win[index] = win;
+ model_view[index] = mv;
+ }
+ }
+
+ view_win[0]->SetStyle(WIN_WHITE_FRAME);
+
+ uvmap_win = new ActiveWindow(screen, 0, 0, w, h, 110, WIN_BLACK_FRAME, main_win);
+ uvmap_view = new UVMapView(uvmap_win);
+ uvmap_win->AddView(uvmap_view);
+
+ main_win->DoLayout();
+ }
+
+ else {
+ ::Print(" Could not establish requested video parameters.\n");
+ ::Print(" -----------------------------------------------\n\n");
+ }
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void
+MagicView::SetupModelViews()
+{
+ switch (view_mode) {
+ case VIEW_ALL: {
+ for (int row = 0; row < 2; row++) {
+ for (int col = 0; col < 2; col++) {
+ int index = 2*row + col;
+
+ ActiveWindow* win = view_win[index];
+
+ win->Show();
+ win->SetCells(col, row, 1, 1);
+ win->SetCellInsets(Insets(1,1,1,1));
+ }
+ }
+
+ uvmap_win->Hide();
+ uvmap_win->SetCells(0,0,0,0);
+ }
+ break;
+
+ case VIEW_TOP:
+ case VIEW_SIDE:
+ case VIEW_FRONT:
+ case VIEW_PERSPECTIVE: {
+ view_focus = view_mode;
+
+ for (int i = 0; i < 4; i++) {
+ ActiveWindow* win = view_win[i];
+
+ if (i == view_mode) {
+ win->Show();
+ win->SetCells(0,0,2,2);
+ win->SetStyle(WIN_WHITE_FRAME);
+ }
+
+ else {
+ win->Hide();
+ win->SetCells(0,0,0,0);
+ win->SetStyle(WIN_BLACK_FRAME);
+ }
+ }
+
+ uvmap_win->Hide();
+ uvmap_win->SetCells(0,0,0,0);
+ }
+ break;
+
+ case VIEW_UV_MAP: {
+ view_focus = view_mode;
+
+ for (int i = 0; i < 4; i++) {
+ ActiveWindow* win = view_win[i];
+ win->Hide();
+ win->SetCells(0,0,0,0);
+ win->SetStyle(WIN_BLACK_FRAME);
+ }
+
+ uvmap_win->Show();
+ uvmap_win->SetCells(0,0,2,2);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ main_win->DoLayout();
+}
+
+void
+MagicView::SetFocusModelView(int f)
+{
+ if (view_mode == VIEW_ALL) {
+ view_focus = f;
+
+ for (int row = 0; row < 2; row++) {
+ for (int col = 0; col < 2; col++) {
+ int index = 2*row + col;
+
+ ActiveWindow* win = view_win[index];
+
+ win->Show();
+ win->SetCells(col, row, 1, 1);
+ win->SetCellInsets(Insets(1,1,1,1));
+
+ if (index == view_focus) {
+ win->SetStyle(WIN_WHITE_FRAME);
+ }
+ else {
+ win->SetStyle(WIN_BLACK_FRAME);
+ }
+ }
+ }
+ }
+ else if (IsUVEdit()) {
+ view_focus = view_mode;
+ }
+ else {
+ view_mode = f;
+ view_focus = f;
+
+ for (int i = 0; i < 4; i++) {
+ ActiveWindow* win = view_win[i];
+
+ if (i == view_mode) {
+ win->Show();
+ win->SetCells(0,0,2,2);
+ win->SetStyle(WIN_WHITE_FRAME);
+ }
+
+ else {
+ win->Hide();
+ win->SetCells(0,0,0,0);
+ win->SetStyle(WIN_BLACK_FRAME);
+ }
+ }
+ }
+
+ main_win->DoLayout();
+}
+
+int
+MagicView::GetWinIndexByPoint(int x, int y)
+{
+ if (view_mode == VIEW_ALL) {
+ for (int row = 0; row < 2; row++) {
+ for (int col = 0; col < 2; col++) {
+ int index = 2*row + col;
+
+ ActiveWindow* win = view_win[index];
+ if (win->GetRect().Contains(x, y))
+ return index;
+ }
+ }
+ }
+
+ return view_mode;
+}
+
+ModelView*
+MagicView::GetModelViewByIndex(int index)
+{
+ if (index >= 0 && index < 4) {
+ return model_view[index];
+ }
+
+ return model_view[0];
+}
+
+// +--------------------------------------------------------------------+
+
+void MagicView::OnPaint()
+{
+ ValidateRect(0);
+ OnRender();
+}
+
+void MagicView::OnDraw(CDC* dc)
+{
+}
+
+// +--------------------------------------------------------------------+
+
+void MagicView::ResizeVideo()
+{
+ if (!video || !video_settings) return;
+
+ HRESULT hr = S_OK;
+ RECT client_old;
+
+ client_old = client_rect;
+
+ // Update window properties
+ GetClientRect(&client_rect);
+
+ if (client_old.right - client_old.left !=
+ client_rect.right - client_rect.left ||
+ client_old.bottom - client_old.top !=
+ client_rect.bottom - client_rect.top) {
+
+ // A new window size will require a new backbuffer
+ // size, so the 3D structures must be changed accordingly.
+
+ video_settings->is_windowed = true;
+ video_settings->window_width = client_rect.right - client_rect.left;
+ video_settings->window_height = client_rect.bottom - client_rect.top;
+
+ ::Print("ResizeVideo() %d x %d\n", video_settings->window_width, video_settings->window_height);
+
+ if (video) {
+ video->Reset(video_settings);
+ }
+ }
+
+ // save a copy of the device-specific video settings:
+ if (video->GetVideoSettings()) {
+ *video_settings = *video->GetVideoSettings();
+ }
+
+ if (screen)
+ screen->Resize(video_settings->window_width,
+ video_settings->window_height);
+
+ video->InvalidateCache();
+ video->SetShadowEnabled(view_shadows);
+ video->SetBumpMapEnabled(view_bumpmaps);
+}
+
+// +--------------------------------------------------------------------+
+
+void MagicView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
+{
+ CView::OnUpdate(pSender, lHint, pHint);
+
+ Solid* solid = GetDocument()->GetSolid();
+ Selection* seln = GetDocument()->GetSelection();
+ Selector* selector = GetDocument()->GetSelector();
+
+ if (solid && scene) {
+ scene->Graphics().clear();
+ scene->AddGraphic(solid);
+ scene->AddGraphic(seln);
+ scene->AddGraphic(selector);
+ }
+
+ if (selector)
+ selector->UseModel(solid->GetModel());
+}
+
+CPoint
+MagicView::LPtoWP(const CPoint& p)
+{
+ CPoint result;
+ ModelView* view = GetModelViewByIndex(view_focus);
+ CPoint origin = view->ProjectPoint(Vec3(0,0,0));
+ double scale = view->GetFieldOfView() / 2;
+
+ result.x = (LONG) (( p.x - origin.x) / scale);
+ result.y = (LONG) ((-p.y + origin.y) / scale);
+
+ return result;
+}
+
+// +--------------------------------------------------------------------+
+//
+// MagicView message handlers
+
+void MagicView::OnEnterSizeMove()
+{
+ is_sizing = true;
+}
+
+void MagicView::OnExitSizeMove()
+{
+ is_sizing = false;
+ ResizeVideo();
+}
+
+void MagicView::OnSize(UINT nType, int cx, int cy)
+{
+ CView::OnSize(nType, cx, cy);
+
+ window_style = GetWindowLong(m_hWnd, GWL_STYLE);
+
+ if (nType == SIZE_MINIMIZED) {
+ is_minimized = true;
+ is_maximized = false;
+ }
+
+ else if (nType == SIZE_MAXIMIZED) {
+ is_minimized = false;
+ is_maximized = true;
+ ResizeVideo();
+ }
+
+ else if (nType == SIZE_RESTORED) {
+ if (is_maximized) {
+ is_maximized = false;
+ ResizeVideo();
+ }
+
+ else if (is_minimized) {
+ is_minimized = false;
+ ResizeVideo();
+ }
+ else if (!is_sizing) {
+ // if this is not a resize due to dragging...
+ ResizeVideo();
+ }
+ else {
+ // If we're neither maximized nor minimized, the window size
+ // is changing by the user dragging the window edges. In this
+ // case, we don't reset the device yet -- we wait until the
+ // user stops dragging, and a WM_EXITSIZEMOVE message comes.
+ }
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void MagicView::OnRender()
+{
+ if (!screen || !video)
+ return;
+
+ double s = sin(timeGetTime() * 0.001);
+ double c = cos(timeGetTime() * 0.001);
+
+ // IF LIGHTS ANIMATED:
+ if (animate_light) {
+ Point light_pos(3e6*s, 5e6*c, 4e6*s);
+
+ if (main_light) {
+ main_light->SetType(Light::LIGHT_POINT);
+ main_light->MoveTo(light_pos);
+ main_light->SetType(Light::LIGHT_DIRECTIONAL);
+ }
+
+ if (back_light) {
+ back_light->SetType(Light::LIGHT_POINT);
+ back_light->MoveTo(light_pos * -1);
+ back_light->SetType(Light::LIGHT_DIRECTIONAL);
+ }
+ }
+
+ if (screen->Refresh()) {
+ video->Present();
+ }
+ else {
+ ::Print("ERROR: Screen refresh failed.\n");
+ }
+}
+
+void MagicView::CloseUVEditor()
+{
+ if (IsUVEdit()) {
+ MagicDoc* doc = GetDocument();
+ Editor* editor = doc->GetEditor();
+ Solid* solid = doc->GetSolid();
+
+ if (editor && solid) {
+ editor->UseModel(solid->GetModel());
+ editor->Resegment();
+ }
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void MagicView::OnViewAll()
+{
+ CloseUVEditor();
+ view_mode = VIEW_ALL;
+ SetupModelViews();
+}
+
+void MagicView::OnUpdateViewAll(CCmdUI* pCmdUI)
+{
+ if (pCmdUI)
+ pCmdUI->SetCheck(view_mode == VIEW_ALL);
+}
+
+void MagicView::OnViewFront()
+{
+ CloseUVEditor();
+ view_mode = VIEW_FRONT;
+ SetupModelViews();
+}
+
+void MagicView::OnUpdateViewFront(CCmdUI* pCmdUI)
+{
+ if (pCmdUI)
+ pCmdUI->SetCheck(view_mode == VIEW_FRONT);
+}
+
+void MagicView::OnViewPerspective()
+{
+ CloseUVEditor();
+ view_mode = VIEW_PERSPECTIVE;
+ SetupModelViews();
+}
+
+void MagicView::OnUpdateViewPerspective(CCmdUI* pCmdUI)
+{
+ if (pCmdUI)
+ pCmdUI->SetCheck(view_mode == VIEW_PERSPECTIVE);
+}
+
+void MagicView::OnViewSide()
+{
+ CloseUVEditor();
+ view_mode = VIEW_SIDE;
+ SetupModelViews();
+}
+
+void MagicView::OnUpdateViewSide(CCmdUI* pCmdUI)
+{
+ if (pCmdUI)
+ pCmdUI->SetCheck(view_mode == VIEW_SIDE);
+}
+
+void MagicView::OnViewTop()
+{
+ CloseUVEditor();
+ view_mode = VIEW_TOP;
+ SetupModelViews();
+}
+
+void MagicView::OnUpdateViewTop(CCmdUI* pCmdUI)
+{
+ if (pCmdUI)
+ pCmdUI->SetCheck(view_mode == VIEW_TOP);
+}
+
+// +--------------------------------------------------------------------+
+
+void MagicView::OnFileImport()
+{
+ DWORD err = 0;
+ char filename[256];
+ filename[0] = '\0';
+ CFileDialog ofd(TRUE, "mag");
+
+ ofd.m_ofn.lpstrFilter = "All 3D Files\0*.mag; *.obj; *.3ds\0Magic Files (*.mag)\0*.mag\0Wavefront/OBJ Files (*.obj)\0*.obj\0003DS MAX Files (*.3ds)\0*.3ds\0\0";
+ ofd.m_ofn.lpstrFile = filename;
+ ofd.m_ofn.nMaxFile = sizeof(filename);
+
+ if (ofd.DoModal() != IDOK)
+ return;
+
+ char mag_name[256];
+ sprintf_s(mag_name, "%s", ofd.GetFileName().GetBuffer(0));
+
+ MagicDoc* pDoc = GetDocument();
+ ASSERT_VALID(pDoc);
+
+ if (pDoc->ImportFile(mag_name)) {
+ Invalidate();
+ pDoc->SetModifiedFlag(TRUE);
+ pDoc->UpdateAllViews(this);
+ }
+}
+
+void MagicView::OnFileExport()
+{
+ DWORD err = 0;
+ char filename[256];
+ filename[0] = '\0';
+ CFileDialog ofd(FALSE, "mag");
+
+ ofd.m_ofn.lpstrFilter = "All 3D Files\0*.mag; *.obj; *.3ds\0Magic Files (*.mag)\0*.mag\0Wavefront/OBJ Files (*.obj)\0*.obj\0003DS MAX Files (*.3ds)\0*.3ds\0\0";
+ ofd.m_ofn.lpstrFile = filename;
+ ofd.m_ofn.nMaxFile = sizeof(filename);
+
+ if (ofd.DoModal() != IDOK)
+ return;
+
+ char mag_name[256];
+ sprintf_s(mag_name, "%s", ofd.GetFileName().GetBuffer(0));
+
+ MagicDoc* pDoc = GetDocument();
+ ASSERT_VALID(pDoc);
+
+ if (pDoc->ExportFile(mag_name)) {
+ pDoc->SetModifiedFlag(FALSE);
+ pDoc->UpdateAllViews(this);
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void MagicView::OnSurfaceProperties()
+{
+ SurfacePropertiesDialog dlg(this);
+ dlg.DoModal();
+}
+
+void MagicView::OnUpdateSurfaceProperties(CCmdUI* pCmdUI)
+{
+ Solid* solid = GetDocument()->GetSolid();
+ pCmdUI->Enable(solid && solid->GetModel());
+}
+
+// +--------------------------------------------------------------------+
+
+void MagicView::OnTextureMap()
+{
+ TextureMapDialog dlg(this);
+ if (dlg.DoModal() == IDOK) {
+ MagicDoc* doc = GetDocument();
+ Solid* solid = doc->GetSolid();
+ Selection* seln = doc->GetSelection();
+ Selector* selector = doc->GetSelector();
+ Editor* editor = doc->GetEditor();
+ Material* mtl = 0;
+
+ if (dlg.mMaterialIndex >= 0) {
+ mtl = solid->GetModel()->GetMaterials()[dlg.mMaterialIndex];
+ }
+
+ editor->UseModel(solid->GetModel());
+ editor->ApplyMaterial(mtl, seln->GetPolys(),
+ dlg.mMapType, 2-dlg.mAxis, (float) dlg.mScaleU, (float) dlg.mScaleV,
+ dlg.mFlip, dlg.mMirror, dlg.mRotate);
+
+ selector->Reselect();
+
+ Invalidate();
+ doc->SetModifiedFlag(TRUE);
+ doc->UpdateAllViews(this);
+ }
+}
+
+void MagicView::OnUpdateTextureMap(CCmdUI* pCmdUI)
+{
+ Solid* solid = GetDocument()->GetSolid();
+ Selection* seln = GetDocument()->GetSelection();
+
+ pCmdUI->Enable(solid && solid->GetModel() && seln && seln->GetPolys().size() > 0);
+}
+
+void MagicView::OnModifyMaterial()
+{
+ MaterialDialog dlg(this);
+ dlg.DoModal();
+
+ Invalidate();
+ GetDocument()->SetModifiedFlag(TRUE);
+ GetDocument()->UpdateAllViews(this);
+}
+
+void MagicView::OnUpdateModifyMaterial(CCmdUI* pCmdUI)
+{
+ Solid* solid = GetDocument()->GetSolid();
+ pCmdUI->Enable(solid && solid->GetModel());
+}
+
+void MagicView::OnModifyUVMap()
+{
+ Selection* seln = GetDocument()->GetSelection();
+
+ view_mode = VIEW_UV_MAP;
+ SetupModelViews();
+
+ if (seln && uvmap_view) {
+ Poly* p = seln->GetPolys().first();
+
+ if (p) {
+ uvmap_view->UseMaterial(p->material);
+ uvmap_view->UsePolys(seln->GetPolys());
+ }
+ }
+}
+
+void MagicView::OnUpdateModifyUVMap(CCmdUI* pCmdUI)
+{
+ OnUpdateTextureMap(pCmdUI);
+}
+
+// +--------------------------------------------------------------------+
+
+void MagicView::OnGridProperties()
+{
+ GridProps dlg(grid, this);
+ dlg.DoModal();
+}
+
+void MagicView::OnGridShow()
+{
+ if (grid)
+ grid->SetShow(!grid->IsShow());
+}
+
+void MagicView::OnGridSnap()
+{
+ if (grid)
+ grid->SetSnap(!grid->IsSnap());
+}
+
+void MagicView::OnUpdateGridSnap(CCmdUI* pCmdUI)
+{
+ if (grid)
+ pCmdUI->SetCheck(grid->IsSnap());
+}
+
+// +--------------------------------------------------------------------+
+
+void MagicView::OnLButtonDown(UINT nFlags, CPoint point)
+{
+ CView::OnLButtonDown(nFlags, point);
+ SetCapture();
+
+ // set focus to the view that was clicked:
+ int index = GetWinIndexByPoint(point.x, point.y);
+ SetFocusModelView(index);
+
+ drag_start = point;
+ drag_left = true;
+ drag_right = false;
+
+ ModelView* mv = GetModelViewByIndex(index);
+ MagicDoc* pDoc = GetDocument();
+ Model* model = pDoc->GetSolid()->GetModel();
+ Selector* selector = pDoc->GetSelector();
+
+ if (IsUVEdit()) {
+ int select_mode = UVMapView::SELECT_APPEND;
+
+ if (nFlags & MK_CONTROL)
+ select_mode = UVMapView::SELECT_REMOVE;
+
+ if (!uvmap_view->WillSelect(point)) {
+ uvmap_view->Begin(select_mode);
+ uvmap_view->AddMark(point);
+ }
+ }
+
+ else if (mv && selector) {
+ int select_mode = Selector::SELECT_APPEND;
+
+ if (nFlags & MK_CONTROL)
+ select_mode = Selector::SELECT_REMOVE;
+
+ selector->Begin(model, mv->GetViewMode(), select_mode);
+ selector->AddMark(point);
+ }
+}
+
+void MagicView::OnLButtonUp(UINT nFlags, CPoint point)
+{
+ CView::OnLButtonUp(nFlags, point);
+ ReleaseCapture();
+
+ drag_left = false;
+
+ MagicDoc* pDoc = GetDocument();
+ Selector* selector = pDoc->GetSelector();
+
+ if (IsUVEdit())
+ uvmap_view->End();
+
+ else if (selector && selector->IsActive())
+ selector->End();
+}
+
+void MagicView::OnLButtonDblClk(UINT nFlags, CPoint point)
+{
+ CView::OnLButtonDblClk(nFlags, point);
+
+ drag_left = false;
+
+ MagicDoc* pDoc = GetDocument();
+ Selector* selector = pDoc->GetSelector();
+
+ if (IsUVEdit())
+ uvmap_view->Clear();
+
+ else if (selector)
+ selector->Clear();
+}
+
+void MagicView::OnRButtonDown(UINT nFlags, CPoint point)
+{
+ CView::OnRButtonDown(nFlags, point);
+ SetCapture();
+
+ // set focus to the view that was clicked:
+ int index = GetWinIndexByPoint(point.x, point.y);
+ SetFocusModelView(index);
+
+ drag_start = point;
+ drag_left = false;
+ drag_right = true;
+}
+
+void MagicView::OnRButtonUp(UINT nFlags, CPoint point)
+{
+ CView::OnRButtonUp(nFlags, point);
+ ReleaseCapture();
+
+ drag_right = false;
+}
+
+void MagicView::OnRButtonDblClk(UINT nFlags, CPoint point)
+{
+ CView::OnRButtonDblClk(nFlags, point);
+ ReleaseCapture();
+
+ drag_right = false;
+
+ if (view_mode == VIEW_ALL) {
+ view_mode = view_focus;
+ }
+ else if (IsUVEdit()) {
+ CloseUVEditor();
+ view_mode = VIEW_ALL;
+ SetupModelViews();
+ }
+ else {
+ view_mode = VIEW_ALL;
+ }
+
+ SetFocusModelView(view_focus);
+}
+
+void MagicView::OnMouseMove(UINT nFlags, CPoint point)
+{
+ if (drag_right) {
+ CPoint offset = point - drag_start;
+
+ if (view_focus == VIEW_PERSPECTIVE) {
+ ModelView* view = GetModelViewByIndex(view_focus);
+ view->SpinBy(offset.x * 0.5 * DEGREES,
+ offset.y * 0.5 * DEGREES);
+ }
+
+ else if (IsUVEdit()) {
+ uvmap_view->MoveBy(offset.x, offset.y);
+ }
+
+ else {
+ ModelView* view = GetModelViewByIndex(view_focus);
+ view->MoveBy(offset.x, offset.y);
+ }
+
+ drag_start = point;
+ Invalidate();
+ }
+
+ else if (drag_left) {
+ CPoint offset = point - drag_start;
+ MagicDoc* pDoc = GetDocument();
+ Selector* selector = pDoc->GetSelector();
+
+ if (IsUVEdit()) {
+ if (uvmap_view->IsActive()) {
+ uvmap_view->AddMark(point);
+ }
+ else {
+ uvmap_view->DragBy(offset.x, offset.y);
+ drag_start = point;
+ }
+ }
+
+ else if (selector && selector->IsActive()) {
+ selector->AddMark(point);
+ }
+ }
+
+ // xy status message:
+ if (view_focus != VIEW_PERSPECTIVE) {
+ char xy[80];
+ CPoint mouse = LPtoWP(point);
+ Selection* seln = GetDocument()->GetSelection();
+
+ int nv = seln ? seln->GetVerts().size() : 0;
+ int np = seln ? seln->GetPolys().size() : 0;
+
+ if (np || nv)
+ sprintf_s(xy, "(%05d,%05d) Verts:%d Polys:%d", mouse.x, mouse.y, nv, np);
+ else
+ sprintf_s(xy, "(%05d,%05d)", mouse.x, mouse.y);
+ MainFrame::StatusXY(xy);
+ }
+
+ CView::OnMouseMove(nFlags, point);
+}
+
+BOOL MagicView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
+{
+ if (view_focus == VIEW_PERSPECTIVE) {
+ ModelView* view = GetModelViewByIndex(view_focus);
+
+ if (view) {
+ Camera* cam = view->GetCamera();
+ Point pos = cam->Pos();
+ double len = pos.length();
+
+ if (zDelta < 0) {
+ if (len < 10000)
+ pos *= 1.15;
+ }
+ else {
+ if (len > 0.10)
+ pos *= 0.85;
+ }
+
+ cam->MoveTo(pos);
+ }
+ }
+
+ else if (IsUVEdit()) {
+ if (zDelta < 0) {
+ uvmap_view->ZoomOut();
+ }
+ else {
+ uvmap_view->ZoomIn();
+ }
+ }
+
+ else {
+ if (zDelta > 0)
+ OnViewZoomIn();
+ else
+ OnViewZoomOut();
+ }
+
+ return 0;
+}
+
+// +--------------------------------------------------------------------+
+
+void MagicView::OnViewZoomNormal()
+{
+ for (int i = 0; i < 4; i++) {
+ ModelView* view = GetModelViewByIndex(i);
+
+ if (view) {
+ view->ZoomNormal();
+ }
+ }
+}
+
+void MagicView::OnViewZoomIn()
+{
+ for (int i = 0; i < 4; i++) {
+ ModelView* view = GetModelViewByIndex(i);
+
+ if (view && view->GetViewMode() != ModelView::VIEW_PROJECT) {
+ double fov = view->GetFieldOfView() * 1.15;
+ view->SetFieldOfView(fov);
+ }
+ }
+}
+
+void MagicView::OnViewZoomOut()
+{
+ for (int i = 0; i < 4; i++) {
+ ModelView* view = GetModelViewByIndex(i);
+
+ if (view && view->GetViewMode() != ModelView::VIEW_PROJECT) {
+ double fov = view->GetFieldOfView() * 0.85;
+ view->SetFieldOfView(fov);
+ }
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void MagicView::OnViewModeWireframe()
+{
+ ModelView* view = GetModelViewByIndex(view_focus);
+
+ if (view) {
+ view->SetFillMode(ModelView::FILL_WIRE);
+ }
+}
+
+void MagicView::OnViewModeSolid()
+{
+ ModelView* view = GetModelViewByIndex(view_focus);
+
+ if (view) {
+ view->SetFillMode(ModelView::FILL_SOLID);
+ }
+}
+
+void MagicView::OnViewModeTextured()
+{
+ ModelView* view = GetModelViewByIndex(view_focus);
+
+ if (view) {
+ view->SetFillMode(ModelView::FILL_TEXTURE);
+ }
+}
+
+void MagicView::OnViewBackColor()
+{
+ ModelView* view = GetModelViewByIndex(view_focus);
+
+ if (view) {
+ ActiveWindow* win = (ActiveWindow*) view->GetWindow();
+ Color c = win->GetBackColor();
+ COLORREF crgb = RGB(c.Red(), c.Green(), c.Blue());
+ CColorDialog chooser(crgb);
+
+ if (chooser.DoModal() == IDOK) {
+ crgb = chooser.GetColor();
+ win->SetBackColor( Color(GetRValue(crgb), GetGValue(crgb), GetBValue(crgb)) );
+ }
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void MagicView::OnSelectAll()
+{
+ Solid* solid = GetDocument()->GetSolid();
+ Selector* selector = GetDocument()->GetSelector();
+
+ if (IsUVEdit()) {
+ uvmap_view->SelectAll();
+ }
+
+ else if (solid && selector) {
+ selector->UseModel(solid->GetModel());
+ selector->SelectAll(Selector::SELECT_APPEND);
+ }
+}
+
+void MagicView::OnSelectNone()
+{
+ Solid* solid = GetDocument()->GetSolid();
+ Selector* selector = GetDocument()->GetSelector();
+
+ if (IsUVEdit()) {
+ uvmap_view->SelectNone();
+ }
+
+ else if (solid && selector) {
+ selector->UseModel(solid->GetModel());
+ selector->SelectAll(Selector::SELECT_REMOVE);
+ }
+}
+
+void MagicView::OnSelectInverse()
+{
+ Solid* solid = GetDocument()->GetSolid();
+ Selector* selector = GetDocument()->GetSelector();
+
+ if (IsUVEdit()) {
+ uvmap_view->SelectInverse();
+ }
+
+ else if (solid && selector) {
+ selector->UseModel(solid->GetModel());
+ selector->SelectInverse();
+ }
+}
+
+void MagicView::OnViewShadows()
+{
+ view_shadows = !view_shadows;
+
+ if (video)
+ video->SetShadowEnabled(view_shadows);
+}
+
+void MagicView::OnUpdateViewShadows(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetCheck(view_shadows);
+}
+
+void MagicView::OnViewAnimatelight()
+{
+ animate_light = !animate_light;
+}
+
+void MagicView::OnUpdateViewAnimatelight(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetCheck(animate_light);
+}
+
+void MagicView::OnViewBumpmaps()
+{
+ view_bumpmaps = !view_bumpmaps;
+
+ if (video)
+ video->SetBumpMapEnabled(view_bumpmaps);
+}
+
+void MagicView::OnUpdateViewBumpmaps(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetCheck(view_bumpmaps);
+}
+
+void MagicView::OnViewVertexshader()
+{
+ if (video) {
+ VideoSettings* vs = (VideoSettings*) video->GetVideoSettings();
+ vs->enable_vs = !vs->enable_vs;
+ }
+}
+
+void MagicView::OnUpdateViewVertexshader(CCmdUI* pCmdUI)
+{
+ if (video)
+ pCmdUI->SetCheck(video->GetVideoSettings()->enable_vs);
+}
+
+void MagicView::OnViewPixelshader()
+{
+ if (video) {
+ VideoSettings* vs = (VideoSettings*) video->GetVideoSettings();
+ vs->enable_ps = !vs->enable_ps;
+ }
+}
+
+void MagicView::OnUpdateViewPixelshader(CCmdUI* pCmdUI)
+{
+ if (video)
+ pCmdUI->SetCheck(video->GetVideoSettings()->enable_ps);
+}
+
+void MagicView::OnViewVisibleshadows()
+{
+ Shadow::SetVisibleShadowVolumes(!Shadow::GetVisibleShadowVolumes());
+}
+
+void MagicView::OnUpdateViewVisibleshadows(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetCheck(Shadow::GetVisibleShadowVolumes());
+}
+
+void MagicView::OnEditUndo()
+{
+ MagicDoc* pDoc = GetDocument();
+ ASSERT_VALID(pDoc);
+ pDoc->Undo();
+
+ Solid* solid = GetDocument()->GetSolid();
+ Selector* selector = GetDocument()->GetSelector();
+
+ if (selector) {
+ selector->UseModel(solid->GetModel());
+ selector->Reselect();
+ }
+
+ Invalidate();
+ pDoc->SetModifiedFlag(TRUE);
+ pDoc->UpdateAllViews(this);
+}
+
+void MagicView::OnUpdateEditUndo(CCmdUI* pCmdUI)
+{
+ MagicDoc* pDoc = GetDocument();
+
+ if (pDoc->NumUndo() > 0) {
+ pCmdUI->Enable(TRUE);
+ pCmdUI->SetText(CString("Undo ") + pDoc->GetUndoName() + CString("\tCtrl+Z"));
+ }
+ else {
+ pCmdUI->Enable(FALSE);
+ pCmdUI->SetText("Can't Undo\tCtrl+Z");
+ }
+}
+
+void MagicView::OnEditRedo()
+{
+ MagicDoc* pDoc = GetDocument();
+ ASSERT_VALID(pDoc);
+ pDoc->Redo();
+
+ Solid* solid = GetDocument()->GetSolid();
+ Selector* selector = GetDocument()->GetSelector();
+
+ if (selector) {
+ selector->UseModel(solid->GetModel());
+ selector->Reselect();
+ }
+
+ Invalidate();
+ pDoc->SetModifiedFlag(TRUE);
+ pDoc->UpdateAllViews(this);
+}
+
+void MagicView::OnUpdateEditRedo(CCmdUI* pCmdUI)
+{
+ MagicDoc* pDoc = GetDocument();
+
+ if (pDoc->NumRedo() > 0) {
+ pCmdUI->Enable(TRUE);
+ pCmdUI->SetText(CString("Redo ") + pDoc->GetRedoName() + CString("\tCtrl+Y"));
+ }
+ else {
+ pCmdUI->Enable(FALSE);
+ pCmdUI->SetText("Can't Redo");
+ }
+}
diff --git a/Magic2/MagicView.h b/Magic2/MagicView.h
index 8bd5e28..287982c 100644
--- a/Magic2/MagicView.h
+++ b/Magic2/MagicView.h
@@ -1,201 +1,225 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: MagicView.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Interface of the MagicView class
-*/
-
-
-#if !defined(AFX_MAGICVIEW_H__387B567A_8235_41B8_A993_E41567E680D7__INCLUDED_)
-#define AFX_MAGICVIEW_H__387B567A_8235_41B8_A993_E41567E680D7__INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-// +--------------------------------------------------------------------+
-
-class MagicDoc;
-class ActiveWindow;
-class Grid;
-class Light;
-class Scene;
-class Screen;
-class Video;
-class VideoSettings;
-class ModelView;
-class UVMapView;
-
-// +--------------------------------------------------------------------+
-
-class MagicView : public CView
-{
-protected: // create from serialization only
- MagicView();
- DECLARE_DYNCREATE(MagicView)
-
-// Attributes
-public:
- MagicDoc* GetDocument();
-
- static MagicView* GetInstance();
-
-// Operations
-public:
-
-// Overrides
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(MagicView)
- public:
- virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
- virtual void OnInitialUpdate();
- protected:
- virtual void OnDraw(CDC* pDC);
- virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint);
- //}}AFX_VIRTUAL
-
-// Implementation
-public:
- virtual ~MagicView();
-#ifdef _DEBUG
- virtual void AssertValid() const;
- virtual void Dump(CDumpContext& dc) const;
-#endif
-
- virtual void OnEnterSizeMove();
- virtual void OnExitSizeMove();
- virtual void ResizeVideo();
- virtual CPoint LPtoWP(const CPoint& p);
-
-protected:
- Video* video;
- VideoSettings* video_settings;
- Screen* screen;
- RECT client_rect;
- DWORD window_style;
- bool is_minimized;
- bool is_maximized;
- bool is_sizing;
-
- Grid* grid;
- Scene* scene;
- Light* main_light;
- Light* back_light;
- ActiveWindow* main_win;
- ActiveWindow* view_win[4];
- ModelView* model_view[4];
- ActiveWindow* uvmap_win;
- UVMapView* uvmap_view;
- int view_mode;
- int view_focus;
- bool drag_left;
- bool drag_right;
- CPoint drag_start;
-
- bool view_bumpmaps;
- bool view_shadows;
- bool animate_light;
-
- enum VIEW_MODE {
- VIEW_TOP = 0,
- VIEW_PERSPECTIVE = 1,
- VIEW_SIDE = 2,
- VIEW_FRONT = 3,
- VIEW_ALL = 4,
- VIEW_UV_MAP = 5
- };
-
- virtual void SetupModelViews();
- virtual void SetFocusModelView(int f);
- virtual int GetWinIndexByPoint(int x, int y);
- ModelView* GetModelViewByIndex(int index);
-
- bool IsUVEdit() const { return (view_mode == VIEW_UV_MAP) && (uvmap_view != 0); }
- void CloseUVEditor();
-
-// Generated message map functions
-protected:
- //{{AFX_MSG(MagicView)
- afx_msg void OnSize(UINT nType, int cx, int cy);
- afx_msg void OnRender();
- afx_msg void OnPaint();
- afx_msg void OnViewAll();
- afx_msg void OnUpdateViewAll(CCmdUI* pCmdUI);
- afx_msg void OnViewFront();
- afx_msg void OnUpdateViewFront(CCmdUI* pCmdUI);
- afx_msg void OnViewPerspective();
- afx_msg void OnUpdateViewPerspective(CCmdUI* pCmdUI);
- afx_msg void OnViewSide();
- afx_msg void OnUpdateViewSide(CCmdUI* pCmdUI);
- afx_msg void OnViewTop();
- afx_msg void OnUpdateViewTop(CCmdUI* pCmdUI);
- afx_msg void OnTextureMap();
- afx_msg void OnModifyMaterial();
- afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
- afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
- afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
- afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
- afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
- afx_msg void OnMouseMove(UINT nFlags, CPoint point);
- afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
- afx_msg void OnViewZoomNormal();
- afx_msg void OnViewZoomIn();
- afx_msg void OnViewZoomOut();
- afx_msg void OnViewModeWireframe();
- afx_msg void OnViewModeSolid();
- afx_msg void OnViewModeTextured();
- afx_msg void OnRButtonDblClk(UINT nFlags, CPoint point);
- afx_msg void OnGridProperties();
- afx_msg void OnGridShow();
- afx_msg void OnGridSnap();
- afx_msg void OnUpdateGridSnap(CCmdUI* pCmdUI);
- afx_msg void OnViewBackColor();
- afx_msg void OnFileImport();
- afx_msg void OnFileExport();
- afx_msg void OnSelectAll();
- afx_msg void OnSelectNone();
- afx_msg void OnUpdateTextureMap(CCmdUI* pCmdUI);
- afx_msg void OnUpdateModifyMaterial(CCmdUI* pCmdUI);
- afx_msg void OnSelectInverse();
- afx_msg void OnModifyUVMap();
- afx_msg void OnUpdateModifyUVMap(CCmdUI* pCmdUI);
- afx_msg void OnViewShadows();
- afx_msg void OnUpdateViewShadows(CCmdUI* pCmdUI);
- afx_msg void OnViewAnimatelight();
- afx_msg void OnUpdateViewAnimatelight(CCmdUI* pCmdUI);
- afx_msg void OnViewBumpmaps();
- afx_msg void OnUpdateViewBumpmaps(CCmdUI* pCmdUI);
- afx_msg void OnViewVertexshader();
- afx_msg void OnUpdateViewVertexshader(CCmdUI* pCmdUI);
- afx_msg void OnViewPixelshader();
- afx_msg void OnUpdateViewPixelshader(CCmdUI* pCmdUI);
- afx_msg void OnViewVisibleshadows();
- afx_msg void OnUpdateViewVisibleshadows(CCmdUI* pCmdUI);
- afx_msg void OnEditUndo();
- afx_msg void OnUpdateEditUndo(CCmdUI* pCmdUI);
- afx_msg void OnEditRedo();
- afx_msg void OnUpdateEditRedo(CCmdUI* pCmdUI);
- afx_msg void OnSurfaceProperties();
- afx_msg void OnUpdateSurfaceProperties(CCmdUI* pCmdUI);
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
-};
-
-#ifndef _DEBUG // debug version in MagicView.cpp
-inline MagicDoc* MagicView::GetDocument()
- { return (MagicDoc*)m_pDocument; }
-#endif
-
-// +--------------------------------------------------------------------+
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
-
-#endif // !defined(AFX_MAGICVIEW_H__387B567A_8235_41B8_A993_E41567E680D7__INCLUDED_)
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: MagicView.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Interface of the MagicView class
+*/
+
+
+#if !defined(AFX_MAGICVIEW_H__387B567A_8235_41B8_A993_E41567E680D7__INCLUDED_)
+#define AFX_MAGICVIEW_H__387B567A_8235_41B8_A993_E41567E680D7__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+// +--------------------------------------------------------------------+
+
+class MagicDoc;
+class ActiveWindow;
+class Grid;
+class Light;
+class Scene;
+class Screen;
+class Video;
+class VideoSettings;
+class ModelView;
+class UVMapView;
+
+// +--------------------------------------------------------------------+
+
+class MagicView : public CView
+{
+protected: // create from serialization only
+ MagicView();
+ DECLARE_DYNCREATE(MagicView)
+
+// Attributes
+public:
+ MagicDoc* GetDocument();
+
+ static MagicView* GetInstance();
+
+// Operations
+public:
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(MagicView)
+ public:
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+ virtual void OnInitialUpdate();
+ protected:
+ virtual void OnDraw(CDC* pDC);
+ virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint);
+ //}}AFX_VIRTUAL
+
+// Implementation
+public:
+ virtual ~MagicView();
+#ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+#endif
+
+ virtual void OnEnterSizeMove();
+ virtual void OnExitSizeMove();
+ virtual void ResizeVideo();
+ virtual CPoint LPtoWP(const CPoint& p);
+
+protected:
+ Video* video;
+ VideoSettings* video_settings;
+ Screen* screen;
+ RECT client_rect;
+ DWORD window_style;
+ bool is_minimized;
+ bool is_maximized;
+ bool is_sizing;
+
+ Grid* grid;
+ Scene* scene;
+ Light* main_light;
+ Light* back_light;
+ ActiveWindow* main_win;
+ ActiveWindow* view_win[4];
+ ModelView* model_view[4];
+ ActiveWindow* uvmap_win;
+ UVMapView* uvmap_view;
+ int view_mode;
+ int view_focus;
+ bool drag_left;
+ bool drag_right;
+ CPoint drag_start;
+
+ bool view_bumpmaps;
+ bool view_shadows;
+ bool animate_light;
+
+ enum VIEW_MODE {
+ VIEW_TOP = 0,
+ VIEW_PERSPECTIVE = 1,
+ VIEW_SIDE = 2,
+ VIEW_FRONT = 3,
+ VIEW_ALL = 4,
+ VIEW_UV_MAP = 5
+ };
+
+ virtual void SetupModelViews();
+ virtual void SetFocusModelView(int f);
+ virtual int GetWinIndexByPoint(int x, int y);
+ ModelView* GetModelViewByIndex(int index);
+
+ bool IsUVEdit() const { return (view_mode == VIEW_UV_MAP) && (uvmap_view != 0); }
+ void CloseUVEditor();
+
+// Generated message map functions
+protected:
+ //{{AFX_MSG(MagicView)
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ afx_msg void OnRender();
+ afx_msg void OnPaint();
+ afx_msg void OnViewAll();
+ afx_msg void OnUpdateViewAll(CCmdUI* pCmdUI);
+ afx_msg void OnViewFront();
+ afx_msg void OnUpdateViewFront(CCmdUI* pCmdUI);
+ afx_msg void OnViewPerspective();
+ afx_msg void OnUpdateViewPerspective(CCmdUI* pCmdUI);
+ afx_msg void OnViewSide();
+ afx_msg void OnUpdateViewSide(CCmdUI* pCmdUI);
+ afx_msg void OnViewTop();
+ afx_msg void OnUpdateViewTop(CCmdUI* pCmdUI);
+ afx_msg void OnTextureMap();
+ afx_msg void OnModifyMaterial();
+ afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
+ afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
+ afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove(UINT nFlags, CPoint point);
+ afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
+ afx_msg void OnViewZoomNormal();
+ afx_msg void OnViewZoomIn();
+ afx_msg void OnViewZoomOut();
+ afx_msg void OnViewModeWireframe();
+ afx_msg void OnViewModeSolid();
+ afx_msg void OnViewModeTextured();
+ afx_msg void OnRButtonDblClk(UINT nFlags, CPoint point);
+ afx_msg void OnGridProperties();
+ afx_msg void OnGridShow();
+ afx_msg void OnGridSnap();
+ afx_msg void OnUpdateGridSnap(CCmdUI* pCmdUI);
+ afx_msg void OnViewBackColor();
+ afx_msg void OnFileImport();
+ afx_msg void OnFileExport();
+ afx_msg void OnSelectAll();
+ afx_msg void OnSelectNone();
+ afx_msg void OnUpdateTextureMap(CCmdUI* pCmdUI);
+ afx_msg void OnUpdateModifyMaterial(CCmdUI* pCmdUI);
+ afx_msg void OnSelectInverse();
+ afx_msg void OnModifyUVMap();
+ afx_msg void OnUpdateModifyUVMap(CCmdUI* pCmdUI);
+ afx_msg void OnViewShadows();
+ afx_msg void OnUpdateViewShadows(CCmdUI* pCmdUI);
+ afx_msg void OnViewAnimatelight();
+ afx_msg void OnUpdateViewAnimatelight(CCmdUI* pCmdUI);
+ afx_msg void OnViewBumpmaps();
+ afx_msg void OnUpdateViewBumpmaps(CCmdUI* pCmdUI);
+ afx_msg void OnViewVertexshader();
+ afx_msg void OnUpdateViewVertexshader(CCmdUI* pCmdUI);
+ afx_msg void OnViewPixelshader();
+ afx_msg void OnUpdateViewPixelshader(CCmdUI* pCmdUI);
+ afx_msg void OnViewVisibleshadows();
+ afx_msg void OnUpdateViewVisibleshadows(CCmdUI* pCmdUI);
+ afx_msg void OnEditUndo();
+ afx_msg void OnUpdateEditUndo(CCmdUI* pCmdUI);
+ afx_msg void OnEditRedo();
+ afx_msg void OnUpdateEditRedo(CCmdUI* pCmdUI);
+ afx_msg void OnSurfaceProperties();
+ afx_msg void OnUpdateSurfaceProperties(CCmdUI* pCmdUI);
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+#ifndef _DEBUG // debug version in MagicView.cpp
+inline MagicDoc* MagicView::GetDocument()
+ { return (MagicDoc*)m_pDocument; }
+#endif
+
+// +--------------------------------------------------------------------+
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_MAGICVIEW_H__387B567A_8235_41B8_A993_E41567E680D7__INCLUDED_)
diff --git a/Magic2/MainFrm.cpp b/Magic2/MainFrm.cpp
index 97ee18b..3d2d256 100644
--- a/Magic2/MainFrm.cpp
+++ b/Magic2/MainFrm.cpp
@@ -1,152 +1,178 @@
-// MainFrm.cpp : implementation of the MainFrame class
-//
-
-#include "stdafx.h"
-#include "Magic.h"
-
-#include "MainFrm.h"
-#include "MagicView.h"
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
-#endif
-
-/////////////////////////////////////////////////////////////////////////////
-// MainFrame
-
-#include "Bitmap.h"
-
-IMPLEMENT_DYNCREATE(MainFrame, CFrameWnd)
-
-BEGIN_MESSAGE_MAP(MainFrame, CFrameWnd)
- //{{AFX_MSG_MAP(MainFrame)
- ON_WM_CREATE()
- ON_WM_ACTIVATEAPP()
- ON_COMMAND(ID_VIEW_RENDER, OnRender)
- //}}AFX_MSG_MAP
-END_MESSAGE_MAP()
-
-static UINT indicators[] =
-{
- ID_SEPARATOR, // status line indicator
- ID_SEPARATOR, // xy indicator
- ID_INDICATOR_CAPS,
- ID_INDICATOR_NUM,
- ID_INDICATOR_SCRL,
-};
-
-/////////////////////////////////////////////////////////////////////////////
-// MainFrame construction/destruction
-
-MainFrame* MainFrame::statframe;
-
-
-MainFrame::MainFrame()
-{
- statframe = this;
-
-}
-
-MainFrame::~MainFrame()
-{
- Bitmap::ClearCache();
-}
-
-BOOL MainFrame::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
-{
- if (message == WM_ENTERSIZEMOVE) {
- MagicView* magic_view = MagicView::GetInstance();
- if (magic_view)
- magic_view->OnEnterSizeMove();
- }
-
- else if (message == WM_EXITSIZEMOVE) {
- MagicView* magic_view = MagicView::GetInstance();
- if (magic_view)
- magic_view->OnExitSizeMove();
- }
-
- return CFrameWnd::OnWndMsg(message, wParam, lParam, pResult);
-}
-
-int MainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
-{
- if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
- return -1;
-
- if (!m_wndToolBar.Create(this) ||
- !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
- {
- TRACE0("Failed to create toolbar\n");
- return -1; // fail to create
- }
-
- if (!m_wndStatusBar.Create(this) ||
- !m_wndStatusBar.SetIndicators(indicators,
- sizeof(indicators)/sizeof(UINT)))
- {
- TRACE0("Failed to create status bar\n");
- return -1; // fail to create
- }
-
- // TODO: Remove this if you don't want tool tips or a resizeable toolbar
- m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
- CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
-
- // TODO: Delete these three lines if you don't want the toolbar to
- // be dockable
- m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
- EnableDocking(CBRS_ALIGN_ANY);
- DockControlBar(&m_wndToolBar);
-
- return 0;
-}
-
-BOOL MainFrame::PreCreateWindow(CREATESTRUCT& cs)
-{
- if( !CFrameWnd::PreCreateWindow(cs) )
- return FALSE;
- // TODO: Modify the Window class or styles here by modifying
- // the CREATESTRUCT cs
-
- return TRUE;
-}
-
-void MainFrame::StatusXY(const char* xy)
-{
- statframe->m_wndStatusBar.SetPaneText(1, xy, TRUE);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// MainFrame diagnostics
-
-#ifdef _DEBUG
-void MainFrame::AssertValid() const
-{
- CFrameWnd::AssertValid();
-}
-
-void MainFrame::Dump(CDumpContext& dc) const
-{
- CFrameWnd::Dump(dc);
-}
-
-#endif //_DEBUG
-
-/////////////////////////////////////////////////////////////////////////////
-// MainFrame message handlers
-
-
-void MainFrame::OnActivateApp(BOOL bActive, DWORD dwThreadID)
-{
- ((Magic*)AfxGetApp())->SetAppActivated(bActive ? true : false);
-}
-
-void MainFrame::OnRender()
-{
- MagicView* magic_view = MagicView::GetInstance();
- if (magic_view)
- magic_view->SendMessage(WM_COMMAND, ID_VIEW_RENDER);
-}
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "stdafx.h"
+#include "Magic.h"
+
+#include "MainFrm.h"
+#include "MagicView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// MainFrame
+
+#include "Bitmap.h"
+
+IMPLEMENT_DYNCREATE(MainFrame, CFrameWnd)
+
+BEGIN_MESSAGE_MAP(MainFrame, CFrameWnd)
+ //{{AFX_MSG_MAP(MainFrame)
+ ON_WM_CREATE()
+ ON_WM_ACTIVATEAPP()
+ ON_COMMAND(ID_VIEW_RENDER, OnRender)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+static UINT indicators[] =
+{
+ ID_SEPARATOR, // status line indicator
+ ID_SEPARATOR, // xy indicator
+ ID_INDICATOR_CAPS,
+ ID_INDICATOR_NUM,
+ ID_INDICATOR_SCRL,
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// MainFrame construction/destruction
+
+MainFrame* MainFrame::statframe;
+
+
+MainFrame::MainFrame()
+{
+ statframe = this;
+
+}
+
+MainFrame::~MainFrame()
+{
+ Bitmap::ClearCache();
+}
+
+BOOL MainFrame::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
+{
+ if (message == WM_ENTERSIZEMOVE) {
+ MagicView* magic_view = MagicView::GetInstance();
+ if (magic_view)
+ magic_view->OnEnterSizeMove();
+ }
+
+ else if (message == WM_EXITSIZEMOVE) {
+ MagicView* magic_view = MagicView::GetInstance();
+ if (magic_view)
+ magic_view->OnExitSizeMove();
+ }
+
+ return CFrameWnd::OnWndMsg(message, wParam, lParam, pResult);
+}
+
+int MainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+ if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
+ return -1;
+
+ if (!m_wndToolBar.Create(this) ||
+ !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
+ {
+ TRACE0("Failed to create toolbar\n");
+ return -1; // fail to create
+ }
+
+ if (!m_wndStatusBar.Create(this) ||
+ !m_wndStatusBar.SetIndicators(indicators,
+ sizeof(indicators)/sizeof(UINT)))
+ {
+ TRACE0("Failed to create status bar\n");
+ return -1; // fail to create
+ }
+
+ // TODO: Remove this if you don't want tool tips or a resizeable toolbar
+ m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
+ CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
+
+ // TODO: Delete these three lines if you don't want the toolbar to
+ // be dockable
+ m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
+ EnableDocking(CBRS_ALIGN_ANY);
+ DockControlBar(&m_wndToolBar);
+
+ return 0;
+}
+
+BOOL MainFrame::PreCreateWindow(CREATESTRUCT& cs)
+{
+ if( !CFrameWnd::PreCreateWindow(cs) )
+ return FALSE;
+ // TODO: Modify the Window class or styles here by modifying
+ // the CREATESTRUCT cs
+
+ return TRUE;
+}
+
+void MainFrame::StatusXY(const char* xy)
+{
+ statframe->m_wndStatusBar.SetPaneText(1, xy, TRUE);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// MainFrame diagnostics
+
+#ifdef _DEBUG
+void MainFrame::AssertValid() const
+{
+ CFrameWnd::AssertValid();
+}
+
+void MainFrame::Dump(CDumpContext& dc) const
+{
+ CFrameWnd::Dump(dc);
+}
+
+#endif //_DEBUG
+
+/////////////////////////////////////////////////////////////////////////////
+// MainFrame message handlers
+
+
+void MainFrame::OnActivateApp(BOOL bActive, DWORD dwThreadID)
+{
+ ((Magic*)AfxGetApp())->SetAppActivated(bActive ? true : false);
+}
+
+void MainFrame::OnRender()
+{
+ MagicView* magic_view = MagicView::GetInstance();
+ if (magic_view)
+ magic_view->SendMessage(WM_COMMAND, ID_VIEW_RENDER);
+}
diff --git a/Magic2/MainFrm.h b/Magic2/MainFrm.h
index 8d51197..39e43bd 100644
--- a/Magic2/MainFrm.h
+++ b/Magic2/MainFrm.h
@@ -1,62 +1,87 @@
-// MainFrm.h : interface of the MainFrame class
-//
-/////////////////////////////////////////////////////////////////////////////
-
-#if !defined(AFX_MAINFRM_H__F5D788D5_8FA2_4A6B_94F0_7938C797BE5D__INCLUDED_)
-#define AFX_MAINFRM_H__F5D788D5_8FA2_4A6B_94F0_7938C797BE5D__INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-class MainFrame : public CFrameWnd
-{
-
-protected: // create from serialization only
- MainFrame();
- DECLARE_DYNCREATE(MainFrame)
-
-// Attributes
-public:
- static MainFrame* statframe;
-
-// Operations
-public:
- static void StatusXY(const char* xy);
-
-// Overrides
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(MainFrame)
- virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
- //}}AFX_VIRTUAL
-
-// Implementation
-public:
- virtual ~MainFrame();
-#ifdef _DEBUG
- virtual void AssertValid() const;
- virtual void Dump(CDumpContext& dc) const;
-#endif
-
-protected: // control bar embedded members
- CStatusBar m_wndStatusBar;
- CToolBar m_wndToolBar;
-
- virtual BOOL OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult);
-
-// Generated message map functions
-protected:
- //{{AFX_MSG(MainFrame)
- afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
- afx_msg void OnActivateApp(BOOL bActive, DWORD dwThreadID);
- afx_msg void OnRender();
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
-};
-
-/////////////////////////////////////////////////////////////////////////////
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
-
-#endif // !defined(AFX_MAINFRM_H__F5D788D5_8FA2_4A6B_94F0_7938C797BE5D__INCLUDED_)
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if !defined(AFX_MAINFRM_H__F5D788D5_8FA2_4A6B_94F0_7938C797BE5D__INCLUDED_)
+#define AFX_MAINFRM_H__F5D788D5_8FA2_4A6B_94F0_7938C797BE5D__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+class MainFrame : public CFrameWnd
+{
+
+protected: // create from serialization only
+ MainFrame();
+ DECLARE_DYNCREATE(MainFrame)
+
+// Attributes
+public:
+ static MainFrame* statframe;
+
+// Operations
+public:
+ static void StatusXY(const char* xy);
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(MainFrame)
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+ //}}AFX_VIRTUAL
+
+// Implementation
+public:
+ virtual ~MainFrame();
+#ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+#endif
+
+protected: // control bar embedded members
+ CStatusBar m_wndStatusBar;
+ CToolBar m_wndToolBar;
+
+ virtual BOOL OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult);
+
+// Generated message map functions
+protected:
+ //{{AFX_MSG(MainFrame)
+ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+ afx_msg void OnActivateApp(BOOL bActive, DWORD dwThreadID);
+ afx_msg void OnRender();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_MAINFRM_H__F5D788D5_8FA2_4A6B_94F0_7938C797BE5D__INCLUDED_)
diff --git a/Magic2/MaterialDialog.cpp b/Magic2/MaterialDialog.cpp
index 1acef19..15d13a8 100644
--- a/Magic2/MaterialDialog.cpp
+++ b/Magic2/MaterialDialog.cpp
@@ -1,693 +1,717 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: MaterialDialog.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Material Editor Dialog interface file
-*/
-
-#include "stdafx.h"
-#include "Magic.h"
-#include "MagicDoc.h"
-#include "MagicView.h"
-#include "MaterialDialog.h"
-#include "Selection.h"
-#include "Selector.h"
-#include "Thumbnail.h"
-
-#include "Bitmap.h"
-#include "Polygon.h"
-#include "Solid.h"
-#include "Video.h"
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
-#endif
-
-inline int BlendModeToSelection(int mode)
-{
- switch (mode) {
- case Material::MTL_SOLID: return 0;
- case Material::MTL_TRANSLUCENT: return 1;
- case Material::MTL_ADDITIVE: return 2;
- }
-
- return 0;
-}
-
-inline int SelectionToBlendMode(int sel)
-{
- switch (sel) {
- case 0: return Material::MTL_SOLID;
- case 1: return Material::MTL_TRANSLUCENT;
- case 2: return Material::MTL_ADDITIVE;
- }
-
- return Material::MTL_SOLID;
-}
-
-// +--------------------------------------------------------------------+
-// MaterialDialog dialog
-// +--------------------------------------------------------------------+
-
-static Material emergency_material;
-
-MaterialDialog::MaterialDialog(MagicView* pParent /*=NULL*/)
- : CDialog(MaterialDialog::IDD, pParent), solid(0), material(0), doc(0)
-{
- //{{AFX_DATA_INIT(MaterialDialog)
- mAmbientValue = 0.0;
- mBrillianceValue = 0.0;
- mBumpValue = 0.0;
- mDiffuseValue = 0.0;
- mEmissiveValue = 0.0;
- mMaterialName = _T("");
- mPowerValue = 0.0;
- mSpecularValue = 0.0;
- mSpecularTexture = _T("");
- mDiffuseTexture = _T("");
- mBumpTexture = _T("");
- mEmissiveTexture = _T("");
- mMaterialShader = _T("");
- //}}AFX_DATA_INIT
-
- doc = pParent->GetDocument();
-
- if (doc && doc->GetSolid()) {
- solid = doc->GetSolid();
-
- Selection* seln = doc->GetSelection();
-
- if (seln->GetPolys().size() > 0) {
- material = seln->GetPolys().first()->material;
- }
- }
-}
-
-MaterialDialog::~MaterialDialog()
-{
-}
-
-
-void MaterialDialog::DoDataExchange(CDataExchange* pDX)
-{
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(MaterialDialog)
- DDX_Control(pDX, IDC_SHADOW, mShadowList);
- DDX_Control(pDX, IDC_BLEND_MODE, mBlendModeList);
- DDX_Control(pDX, IDC_MATERIAL_LIST, mMaterialList);
- DDX_Control(pDX, IDC_MATERIAL_PREVIEW, mMaterialThumb);
- DDX_Control(pDX, IDC_SPECULAR_COLOR, mSpecularColor);
- DDX_Control(pDX, IDC_EMISSIVE_COLOR, mEmissiveColor);
- DDX_Control(pDX, IDC_DIFFUSE_COLOR, mDiffuseColor);
- DDX_Control(pDX, IDC_AMBIENT_COLOR, mAmbientColor);
- DDX_Text(pDX, IDC_AMBIENT_VALUE, mAmbientValue);
- DDX_Text(pDX, IDC_BRILLIANCE_VALUE, mBrillianceValue);
- DDX_Text(pDX, IDC_BUMP_VALUE, mBumpValue);
- DDX_Text(pDX, IDC_DIFFUSE_VALUE, mDiffuseValue);
- DDX_Text(pDX, IDC_EMISSIVE_VALUE, mEmissiveValue);
- DDX_Text(pDX, IDC_MATERIAL_NAME, mMaterialName);
- DDX_Text(pDX, IDC_POWER_VALUE, mPowerValue);
- DDX_Text(pDX, IDC_SPECULAR_VALUE, mSpecularValue);
- DDX_Text(pDX, IDC_SPECULAR_TEXTURE, mSpecularTexture);
- DDX_Text(pDX, IDC_DIFFUSE_TEXTURE, mDiffuseTexture);
- DDX_Text(pDX, IDC_BUMP_TEXTURE, mBumpTexture);
- DDX_Text(pDX, IDC_EMISSIVE_TEXTURE, mEmissiveTexture);
- DDX_Text(pDX, IDC_MATERIAL_SHADER, mMaterialShader);
- //}}AFX_DATA_MAP
-
- if (!pDX->m_bSaveAndValidate) {
- if (solid && solid->GetModel()) {
- mMaterialList.ResetContent();
-
- Model* model = solid->GetModel();
- for (int i = 0; i < model->NumMaterials(); i++) {
- Material* m = model->GetMaterials()[i];
- mMaterialList.AddString(m->name);
-
- if (m == material)
- mMaterialList.SetCurSel(i);
- }
- }
-
- if (mBlendModeList.GetSafeHwnd())
- mBlendModeList.SetCurSel(BlendModeToSelection(material->blend));
-
- if (mShadowList.GetSafeHwnd())
- mShadowList.SetCurSel(material->shadow);
- }
-}
-
-
-BEGIN_MESSAGE_MAP(MaterialDialog, CDialog)
- //{{AFX_MSG_MAP(MaterialDialog)
- ON_WM_PAINT()
- ON_BN_CLICKED(IDC_AMBIENT_COLOR, OnAmbientColor)
- ON_BN_CLICKED(IDC_DIFFUSE_COLOR, OnDiffuseColor)
- ON_BN_CLICKED(IDC_EMISSIVE_COLOR, OnEmissiveColor)
- ON_BN_CLICKED(IDC_SPECULAR_COLOR, OnSpecularColor)
- ON_WM_DRAWITEM()
- ON_EN_CHANGE(IDC_AMBIENT_VALUE, OnChangeMaterialValue)
- ON_BN_CLICKED(IDC_FILE_DIFFUSE, OnFileDiffuse)
- ON_BN_CLICKED(IDC_FILE_SPECULAR, OnFileSpecular)
- ON_BN_CLICKED(IDC_FILE_EMISSIVE, OnFileEmissive)
- ON_BN_CLICKED(IDC_FILE_BUMP, OnFileBump)
- ON_EN_CHANGE(IDC_DIFFUSE_TEXTURE, OnChangeDiffuseTexture)
- ON_EN_CHANGE(IDC_SPECULAR_TEXTURE, OnChangeSpecularTexture)
- ON_EN_CHANGE(IDC_EMISSIVE_TEXTURE, OnChangeEmissiveTexture)
- ON_EN_CHANGE(IDC_BUMP_TEXTURE, OnChangeBumpTexture)
- ON_EN_CHANGE(IDC_MATERIAL_NAME, OnChangeMaterialName)
- ON_LBN_SELCHANGE(IDC_MATERIAL_LIST, OnSelectMaterial)
- ON_BN_CLICKED(IDC_SELECT_POLYS, OnSelectPolys)
- ON_BN_CLICKED(IDC_NEW_MATERIAL, OnNewMaterial)
- ON_BN_CLICKED(IDC_DEL_MATERIAL, OnDelMaterial)
- ON_CBN_SELCHANGE(IDC_BLEND_MODE, OnSelectBlendMode)
- ON_CBN_SELCHANGE(IDC_SHADOW, OnSelectShadow)
- ON_EN_CHANGE(IDC_BRILLIANCE_VALUE, OnChangeMaterialValue)
- ON_EN_CHANGE(IDC_BUMP_VALUE, OnChangeMaterialValue)
- ON_EN_CHANGE(IDC_DIFFUSE_VALUE, OnChangeMaterialValue)
- ON_EN_CHANGE(IDC_EMISSIVE_VALUE, OnChangeMaterialValue)
- ON_EN_CHANGE(IDC_POWER_VALUE, OnChangeMaterialValue)
- ON_EN_CHANGE(IDC_SPECULAR_VALUE, OnChangeMaterialValue)
- ON_EN_CHANGE(IDC_MATERIAL_SHADER, OnChangeMaterialShader)
- //}}AFX_MSG_MAP
-END_MESSAGE_MAP()
-
-// +--------------------------------------------------------------------+
-
-void MaterialDialog::UpdateMaterial()
-{
- if (material) {
- UpdateData();
-
- strcpy_s(material->name, mMaterialName);
- strcpy_s(material->shader, mMaterialShader);
-
- material->ambient_value = mAmbientValue;
- material->diffuse_value = mDiffuseValue;
- material->specular_value = mSpecularValue;
- material->emissive_value = mEmissiveValue;
- material->power = mPowerValue;
- material->brilliance = mBrillianceValue;
- material->bump = mBumpValue;
- material->blend = SelectionToBlendMode(mBlendModeList.GetCurSel());
- material->shadow = mShadowList.GetCurSel() ? true : false;
-
- material->Ka = ColorValue(material->ambient_color) * material->ambient_value;
- material->Kd = ColorValue(material->diffuse_color) * material->diffuse_value;
- material->Ks = ColorValue(material->specular_color) * material->specular_value;
- material->Ke = ColorValue(material->emissive_color) * material->emissive_value;
-
- material->CreateThumbnail();
-
- InvalidateRect(NULL, FALSE);
- }
-}
-
-// +--------------------------------------------------------------------+
-// MaterialDialog message handlers
-// +--------------------------------------------------------------------+
-
-BOOL MaterialDialog::OnInitDialog()
-{
- if (solid && solid->GetModel() && !material) {
- Model* model = solid->GetModel();
-
- if (model->NumMaterials() > 0)
- material = model->GetMaterials().first();
- }
-
- if (!material)
- material = &emergency_material;
-
- mMaterialName = material->name;
- mMaterialShader = material->shader;
- mAmbientValue = material->ambient_value;
- mDiffuseValue = material->diffuse_value;
- mSpecularValue = material->specular_value;
- mEmissiveValue = material->emissive_value;
- mPowerValue = material->power;
- mBrillianceValue = material->brilliance;
- mBumpValue = material->bump;
-
- mDiffuseTexture = material->tex_diffuse ?
- material->tex_diffuse->GetFilename() : "";
-
- mSpecularTexture = material->tex_specular ?
- material->tex_specular->GetFilename() : "";
-
- mEmissiveTexture = material->tex_emissive ?
- material->tex_emissive->GetFilename() : "";
-
- mBumpTexture = material->tex_bumpmap ?
- material->tex_bumpmap->GetFilename() : "";
-
- CDialog::OnInitDialog();
-
- UpdateMaterial();
-
- return TRUE; // return TRUE unless you set the focus to a control
- // EXCEPTION: OCX Property Pages should return FALSE
-}
-
-void MaterialDialog::OnPaint()
-{
- CPaintDC dc(this); // device context for painting
-
- if (material && material->thumbnail) {
- ThumbPreview(mMaterialThumb.GetSafeHwnd(), material->thumbnail);
- }
-}
-
-void MaterialDialog::OnAmbientColor()
-{
- if (material) {
- Color c = material->ambient_color;
- COLORREF crgb = RGB(c.Red(), c.Green(), c.Blue());
- CColorDialog chooser(crgb);
-
- if (chooser.DoModal() == IDOK) {
- crgb = chooser.GetColor();
- material->ambient_color = Color(GetRValue(crgb), GetGValue(crgb), GetBValue(crgb));
- UpdateMaterial();
- }
- }
-}
-
-void MaterialDialog::OnDiffuseColor()
-{
- if (material) {
- Color c = material->diffuse_color;
- COLORREF crgb = RGB(c.Red(), c.Green(), c.Blue());
- CColorDialog chooser(crgb);
-
- if (chooser.DoModal() == IDOK) {
- crgb = chooser.GetColor();
- material->diffuse_color = Color(GetRValue(crgb), GetGValue(crgb), GetBValue(crgb));
- UpdateMaterial();
- }
- }
-}
-
-void MaterialDialog::OnSpecularColor()
-{
- if (material) {
- Color c = material->specular_color;
- COLORREF crgb = RGB(c.Red(), c.Green(), c.Blue());
- CColorDialog chooser(crgb);
-
- if (chooser.DoModal() == IDOK) {
- crgb = chooser.GetColor();
- material->specular_color = Color(GetRValue(crgb), GetGValue(crgb), GetBValue(crgb));
- UpdateMaterial();
- }
- }
-}
-
-void MaterialDialog::OnEmissiveColor()
-{
- if (material) {
- Color c = material->emissive_color;
- COLORREF crgb = RGB(c.Red(), c.Green(), c.Blue());
- CColorDialog chooser(crgb);
-
- if (chooser.DoModal() == IDOK) {
- crgb = chooser.GetColor();
- material->emissive_color = Color(GetRValue(crgb), GetGValue(crgb), GetBValue(crgb));
- UpdateMaterial();
- }
- }
-}
-
-void MaterialDialog::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
-{
- CWnd* wnd = GetDlgItem(nIDCtl);
- Color c = Color::LightGray;
-
- if (material) {
- if (wnd->GetSafeHwnd() == mAmbientColor.GetSafeHwnd())
- c = material->ambient_color;
-
- else if (wnd->GetSafeHwnd() == mDiffuseColor.GetSafeHwnd())
- c = material->diffuse_color;
-
- else if (wnd->GetSafeHwnd() == mSpecularColor.GetSafeHwnd())
- c = material->specular_color;
-
- else if (wnd->GetSafeHwnd() == mEmissiveColor.GetSafeHwnd())
- c = material->emissive_color;
- }
-
- CBrush brush(RGB(c.Red(), c.Green(), c.Blue()));
-
- ::FillRect(lpDrawItemStruct->hDC,
- &lpDrawItemStruct->rcItem,
- brush);
-
- CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
-}
-
-// +--------------------------------------------------------------------+
-
-void MaterialDialog::OnChangeMaterialValue()
-{
- UpdateMaterial();
-}
-
-// +--------------------------------------------------------------------+
-
-void MaterialDialog::OnFileTexture(int type)
-{
- if (!material)
- return;
-
- char filename[512];
- filename[0] = '\0';
- CFileDialog ofd(TRUE, "pcx");
-
- ofd.m_ofn.lpstrFilter = "All Image Files\0*.bmp; *.dds; *.jpg; *.pcx; *.png; *.tga\0Bitmap Files (*.bmp)\0*.bmp\0JPEG Files (*.jpg)\0*.pcx\0PCX Files (*.pcx)\0*.pcx\0PNG Files (*.png)\0*.png\0Truevision Targa Files (*.tga)\0*.png\0All Files\0*.*\0\0";
- ofd.m_ofn.lpstrFile = filename;
- ofd.m_ofn.nMaxFile = sizeof(filename);
-
- if (ofd.DoModal() != IDOK)
- return;
-
- char tex_name[512];
- sprintf_s(tex_name, "%s", ofd.GetFileName().GetBuffer(0));
-
- ChangeFileTexture(tex_name, type);
-}
-
-void MaterialDialog::ChangeFileTexture(char* fname, int type)
-{
- Bitmap* bmp = 0;
-
- LoadTexture(fname, bmp);
-
- if (bmp) {
- switch (type) {
- case 0:
- material->tex_diffuse = bmp;
- mDiffuseTexture = fname;
- break;
-
- case 1:
- material->tex_specular = bmp;
- mSpecularTexture = fname;
- break;
-
- case 2:
- material->tex_emissive = bmp;
- mEmissiveTexture = fname;
- break;
-
- case 3:
- material->tex_bumpmap = bmp;
- mBumpTexture = fname;
- break;
- }
-
- UpdateData(FALSE);
- UpdateMaterial();
- }
-}
-
-void MaterialDialog::OnFileDiffuse()
-{
- OnFileTexture(0);
-}
-
-void MaterialDialog::OnFileSpecular()
-{
- OnFileTexture(1);
-}
-
-void MaterialDialog::OnFileEmissive()
-{
- OnFileTexture(2);
-}
-
-void MaterialDialog::OnFileBump()
-{
- OnFileTexture(3);
-}
-
-void MaterialDialog::OnChangeDiffuseTexture()
-{
- if (material) {
- UpdateData();
-
- if (mDiffuseTexture.GetLength() < 1) {
- material->tex_diffuse = 0;
- UpdateMaterial();
- return;
- }
-
- char* filename = mDiffuseTexture.LockBuffer();
- ChangeFileTexture(filename, 0);
- mDiffuseTexture.UnlockBuffer();
- }
-}
-
-void MaterialDialog::OnChangeSpecularTexture()
-{
- if (material) {
- UpdateData();
-
- if (mSpecularTexture.GetLength() < 1) {
- material->tex_specular = 0;
- UpdateMaterial();
- return;
- }
-
- char* filename = mSpecularTexture.LockBuffer();
- ChangeFileTexture(filename, 1);
- mSpecularTexture.UnlockBuffer();
- }
-}
-
-void MaterialDialog::OnChangeEmissiveTexture()
-{
- if (material) {
- UpdateData();
-
- if (mEmissiveTexture.GetLength() < 1) {
- material->tex_emissive = 0;
- UpdateMaterial();
- return;
- }
-
- char* filename = mEmissiveTexture.LockBuffer();
- ChangeFileTexture(filename, 2);
- mEmissiveTexture.UnlockBuffer();
- }
-}
-
-void MaterialDialog::OnChangeBumpTexture()
-{
- if (material) {
- UpdateData();
-
- if (mBumpTexture.GetLength() < 1) {
- material->tex_bumpmap = 0;
- UpdateMaterial();
- return;
- }
-
- char* filename = mBumpTexture.LockBuffer();
- ChangeFileTexture(filename, 3);
- mBumpTexture.UnlockBuffer();
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void MaterialDialog::OnChangeMaterialName()
-{
- if (material) {
- UpdateData();
- strcpy_s(material->name, mMaterialName);
- }
-}
-
-void MaterialDialog::OnChangeMaterialShader()
-{
- if (material) {
- UpdateData();
- strcpy_s(material->shader, mMaterialShader);
- }
-}
-
-void MaterialDialog::OnSelectMaterial()
-{
- int selected = mMaterialList.GetCurSel();
- Material* mtl = 0;
-
- if (solid && solid->GetModel()) {
- Model* model = solid->GetModel();
-
- if (model->NumMaterials() > 0 && selected < model->NumMaterials())
- mtl = model->GetMaterials()[selected];
- }
-
- if (!mtl)
- mtl = &emergency_material;
-
- if (material != mtl) {
- material = mtl;
-
- mMaterialName = material->name;
- mMaterialShader = material->shader;
- mAmbientValue = material->ambient_value;
- mDiffuseValue = material->diffuse_value;
- mSpecularValue = material->specular_value;
- mEmissiveValue = material->emissive_value;
- mPowerValue = material->power;
- mBrillianceValue = material->brilliance;
- mBumpValue = material->bump;
-
- mDiffuseTexture = material->tex_diffuse ?
- material->tex_diffuse->GetFilename() : "";
-
- mSpecularTexture = material->tex_specular ?
- material->tex_specular->GetFilename() : "";
-
- mEmissiveTexture = material->tex_emissive ?
- material->tex_emissive->GetFilename() : "";
-
- mBumpTexture = material->tex_bumpmap ?
- material->tex_bumpmap->GetFilename() : "";
-
- if (mBlendModeList.GetSafeHwnd())
- mBlendModeList.SetCurSel(BlendModeToSelection(material->blend));
-
- if (mShadowList.GetSafeHwnd())
- mShadowList.SetCurSel(material->shadow);
-
- UpdateData(FALSE);
- UpdateMaterial();
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void MaterialDialog::OnNewMaterial()
-{
- if (solid && material && material != &emergency_material) {
- Model* model = solid->GetModel();
- Material* mtl = new Material;
-
- if (model && mtl) {
- mtl->Ka = Color::DarkGray;
- mtl->Kd = Color::LightGray;
- mtl->Ks = ColorValue(0.1f,0.1f,0.1f);
- mtl->power = 10.0f;
-
- mtl->ambient_value = 0.2f;
- mtl->ambient_color = Color::DarkGray;
- mtl->diffuse_value = 0.8f;
- mtl->diffuse_color = Color::LightGray;
- mtl->specular_value = 0.5f;
- mtl->specular_color = Color::White;
- strcpy_s(mtl->name, "(new)");
-
- model->GetMaterials().append(mtl);
-
- material = 0;
- mMaterialList.AddString(mtl->name);
- mMaterialList.SetCurSel(model->NumMaterials()-1);
-
- mBlendModeList.SetCurSel(0);
- mShadowList.SetCurSel(1);
-
- OnSelectMaterial();
- }
- }
-}
-
-void MaterialDialog::OnDelMaterial()
-{
- if (solid && material && material != &emergency_material) {
- Model* model = solid->GetModel();
-
- // do not delete the last material:
- if (model->NumMaterials() > 1 && model->GetMaterials().contains(material)) {
- Material* mtl = model->GetMaterials().first();
-
- if (mtl == material)
- mtl = model->GetMaterials()[1];
-
- // reassign the material for any polys and segments
- // that are using the one we are about to delete:
- ListIter<Surface> iter = model->GetSurfaces();
-
- while (++iter) {
- Surface* s = iter.value();
-
- for (int i = 0; i < s->NumPolys(); i++) {
- Poly* p = s->GetPolys() + i;
-
- if (p->material == material) {
- p->material = mtl;
- }
- }
-
- ListIter<Segment> seg_iter = s->GetSegments();
- while (++seg_iter) {
- Segment* segment = seg_iter.value();
- if (segment->material == material)
- segment->material = mtl;
- }
- }
-
- // now delete the material:
- model->GetMaterials().remove(material);
- delete material;
-
- material = 0;
- mMaterialList.SetCurSel(0);
- OnSelectMaterial();
- }
- }
-}
-
-void MaterialDialog::OnSelectPolys()
-{
- if (solid && doc && doc->GetSelector()) {
- Selector* selector = doc->GetSelector();
-
- if (!material || material == &emergency_material)
- selector->SelectMaterial(0);
- else
- selector->SelectMaterial(material);
- }
-}
-
-void MaterialDialog::OnSelectBlendMode()
-{
- if (material)
- material->blend = SelectionToBlendMode(mBlendModeList.GetCurSel());
-}
-
-void MaterialDialog::OnSelectShadow()
-{
- if (material)
- material->shadow = mShadowList.GetCurSel() ? true : false;
-}
-
-void MaterialDialog::OnOK()
-{
- Video* video = Video::GetInstance();
- if (video)
- video->InvalidateCache();
-
- CDialog::OnOK();
-}
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: MaterialDialog.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Material Editor Dialog interface file
+*/
+
+#include "stdafx.h"
+#include "Magic.h"
+#include "MagicDoc.h"
+#include "MagicView.h"
+#include "MaterialDialog.h"
+#include "Selection.h"
+#include "Selector.h"
+#include "Thumbnail.h"
+
+#include "Bitmap.h"
+#include "Polygon.h"
+#include "Solid.h"
+#include "Video.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+inline int BlendModeToSelection(int mode)
+{
+ switch (mode) {
+ case Material::MTL_SOLID: return 0;
+ case Material::MTL_TRANSLUCENT: return 1;
+ case Material::MTL_ADDITIVE: return 2;
+ }
+
+ return 0;
+}
+
+inline int SelectionToBlendMode(int sel)
+{
+ switch (sel) {
+ case 0: return Material::MTL_SOLID;
+ case 1: return Material::MTL_TRANSLUCENT;
+ case 2: return Material::MTL_ADDITIVE;
+ }
+
+ return Material::MTL_SOLID;
+}
+
+// +--------------------------------------------------------------------+
+// MaterialDialog dialog
+// +--------------------------------------------------------------------+
+
+static Material emergency_material;
+
+MaterialDialog::MaterialDialog(MagicView* pParent /*=NULL*/)
+ : CDialog(MaterialDialog::IDD, pParent), solid(0), material(0), doc(0)
+{
+ //{{AFX_DATA_INIT(MaterialDialog)
+ mAmbientValue = 0.0;
+ mBrillianceValue = 0.0;
+ mBumpValue = 0.0;
+ mDiffuseValue = 0.0;
+ mEmissiveValue = 0.0;
+ mMaterialName = _T("");
+ mPowerValue = 0.0;
+ mSpecularValue = 0.0;
+ mSpecularTexture = _T("");
+ mDiffuseTexture = _T("");
+ mBumpTexture = _T("");
+ mEmissiveTexture = _T("");
+ mMaterialShader = _T("");
+ //}}AFX_DATA_INIT
+
+ doc = pParent->GetDocument();
+
+ if (doc && doc->GetSolid()) {
+ solid = doc->GetSolid();
+
+ Selection* seln = doc->GetSelection();
+
+ if (seln->GetPolys().size() > 0) {
+ material = seln->GetPolys().first()->material;
+ }
+ }
+}
+
+MaterialDialog::~MaterialDialog()
+{
+}
+
+
+void MaterialDialog::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(MaterialDialog)
+ DDX_Control(pDX, IDC_SHADOW, mShadowList);
+ DDX_Control(pDX, IDC_BLEND_MODE, mBlendModeList);
+ DDX_Control(pDX, IDC_MATERIAL_LIST, mMaterialList);
+ DDX_Control(pDX, IDC_MATERIAL_PREVIEW, mMaterialThumb);
+ DDX_Control(pDX, IDC_SPECULAR_COLOR, mSpecularColor);
+ DDX_Control(pDX, IDC_EMISSIVE_COLOR, mEmissiveColor);
+ DDX_Control(pDX, IDC_DIFFUSE_COLOR, mDiffuseColor);
+ DDX_Control(pDX, IDC_AMBIENT_COLOR, mAmbientColor);
+ DDX_Text(pDX, IDC_AMBIENT_VALUE, mAmbientValue);
+ DDX_Text(pDX, IDC_BRILLIANCE_VALUE, mBrillianceValue);
+ DDX_Text(pDX, IDC_BUMP_VALUE, mBumpValue);
+ DDX_Text(pDX, IDC_DIFFUSE_VALUE, mDiffuseValue);
+ DDX_Text(pDX, IDC_EMISSIVE_VALUE, mEmissiveValue);
+ DDX_Text(pDX, IDC_MATERIAL_NAME, mMaterialName);
+ DDX_Text(pDX, IDC_POWER_VALUE, mPowerValue);
+ DDX_Text(pDX, IDC_SPECULAR_VALUE, mSpecularValue);
+ DDX_Text(pDX, IDC_SPECULAR_TEXTURE, mSpecularTexture);
+ DDX_Text(pDX, IDC_DIFFUSE_TEXTURE, mDiffuseTexture);
+ DDX_Text(pDX, IDC_BUMP_TEXTURE, mBumpTexture);
+ DDX_Text(pDX, IDC_EMISSIVE_TEXTURE, mEmissiveTexture);
+ DDX_Text(pDX, IDC_MATERIAL_SHADER, mMaterialShader);
+ //}}AFX_DATA_MAP
+
+ if (!pDX->m_bSaveAndValidate) {
+ if (solid && solid->GetModel()) {
+ mMaterialList.ResetContent();
+
+ Model* model = solid->GetModel();
+ for (int i = 0; i < model->NumMaterials(); i++) {
+ Material* m = model->GetMaterials()[i];
+ mMaterialList.AddString(m->name);
+
+ if (m == material)
+ mMaterialList.SetCurSel(i);
+ }
+ }
+
+ if (mBlendModeList.GetSafeHwnd())
+ mBlendModeList.SetCurSel(BlendModeToSelection(material->blend));
+
+ if (mShadowList.GetSafeHwnd())
+ mShadowList.SetCurSel(material->shadow);
+ }
+}
+
+
+BEGIN_MESSAGE_MAP(MaterialDialog, CDialog)
+ //{{AFX_MSG_MAP(MaterialDialog)
+ ON_WM_PAINT()
+ ON_BN_CLICKED(IDC_AMBIENT_COLOR, OnAmbientColor)
+ ON_BN_CLICKED(IDC_DIFFUSE_COLOR, OnDiffuseColor)
+ ON_BN_CLICKED(IDC_EMISSIVE_COLOR, OnEmissiveColor)
+ ON_BN_CLICKED(IDC_SPECULAR_COLOR, OnSpecularColor)
+ ON_WM_DRAWITEM()
+ ON_EN_CHANGE(IDC_AMBIENT_VALUE, OnChangeMaterialValue)
+ ON_BN_CLICKED(IDC_FILE_DIFFUSE, OnFileDiffuse)
+ ON_BN_CLICKED(IDC_FILE_SPECULAR, OnFileSpecular)
+ ON_BN_CLICKED(IDC_FILE_EMISSIVE, OnFileEmissive)
+ ON_BN_CLICKED(IDC_FILE_BUMP, OnFileBump)
+ ON_EN_CHANGE(IDC_DIFFUSE_TEXTURE, OnChangeDiffuseTexture)
+ ON_EN_CHANGE(IDC_SPECULAR_TEXTURE, OnChangeSpecularTexture)
+ ON_EN_CHANGE(IDC_EMISSIVE_TEXTURE, OnChangeEmissiveTexture)
+ ON_EN_CHANGE(IDC_BUMP_TEXTURE, OnChangeBumpTexture)
+ ON_EN_CHANGE(IDC_MATERIAL_NAME, OnChangeMaterialName)
+ ON_LBN_SELCHANGE(IDC_MATERIAL_LIST, OnSelectMaterial)
+ ON_BN_CLICKED(IDC_SELECT_POLYS, OnSelectPolys)
+ ON_BN_CLICKED(IDC_NEW_MATERIAL, OnNewMaterial)
+ ON_BN_CLICKED(IDC_DEL_MATERIAL, OnDelMaterial)
+ ON_CBN_SELCHANGE(IDC_BLEND_MODE, OnSelectBlendMode)
+ ON_CBN_SELCHANGE(IDC_SHADOW, OnSelectShadow)
+ ON_EN_CHANGE(IDC_BRILLIANCE_VALUE, OnChangeMaterialValue)
+ ON_EN_CHANGE(IDC_BUMP_VALUE, OnChangeMaterialValue)
+ ON_EN_CHANGE(IDC_DIFFUSE_VALUE, OnChangeMaterialValue)
+ ON_EN_CHANGE(IDC_EMISSIVE_VALUE, OnChangeMaterialValue)
+ ON_EN_CHANGE(IDC_POWER_VALUE, OnChangeMaterialValue)
+ ON_EN_CHANGE(IDC_SPECULAR_VALUE, OnChangeMaterialValue)
+ ON_EN_CHANGE(IDC_MATERIAL_SHADER, OnChangeMaterialShader)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+// +--------------------------------------------------------------------+
+
+void MaterialDialog::UpdateMaterial()
+{
+ if (material) {
+ UpdateData();
+
+ strcpy_s(material->name, mMaterialName);
+ strcpy_s(material->shader, mMaterialShader);
+
+ material->ambient_value = mAmbientValue;
+ material->diffuse_value = mDiffuseValue;
+ material->specular_value = mSpecularValue;
+ material->emissive_value = mEmissiveValue;
+ material->power = mPowerValue;
+ material->brilliance = mBrillianceValue;
+ material->bump = mBumpValue;
+ material->blend = SelectionToBlendMode(mBlendModeList.GetCurSel());
+ material->shadow = mShadowList.GetCurSel() ? true : false;
+
+ material->Ka = ColorValue(material->ambient_color) * material->ambient_value;
+ material->Kd = ColorValue(material->diffuse_color) * material->diffuse_value;
+ material->Ks = ColorValue(material->specular_color) * material->specular_value;
+ material->Ke = ColorValue(material->emissive_color) * material->emissive_value;
+
+ material->CreateThumbnail();
+
+ InvalidateRect(NULL, FALSE);
+ }
+}
+
+// +--------------------------------------------------------------------+
+// MaterialDialog message handlers
+// +--------------------------------------------------------------------+
+
+BOOL MaterialDialog::OnInitDialog()
+{
+ if (solid && solid->GetModel() && !material) {
+ Model* model = solid->GetModel();
+
+ if (model->NumMaterials() > 0)
+ material = model->GetMaterials().first();
+ }
+
+ if (!material)
+ material = &emergency_material;
+
+ mMaterialName = material->name;
+ mMaterialShader = material->shader;
+ mAmbientValue = material->ambient_value;
+ mDiffuseValue = material->diffuse_value;
+ mSpecularValue = material->specular_value;
+ mEmissiveValue = material->emissive_value;
+ mPowerValue = material->power;
+ mBrillianceValue = material->brilliance;
+ mBumpValue = material->bump;
+
+ mDiffuseTexture = material->tex_diffuse ?
+ material->tex_diffuse->GetFilename() : "";
+
+ mSpecularTexture = material->tex_specular ?
+ material->tex_specular->GetFilename() : "";
+
+ mEmissiveTexture = material->tex_emissive ?
+ material->tex_emissive->GetFilename() : "";
+
+ mBumpTexture = material->tex_bumpmap ?
+ material->tex_bumpmap->GetFilename() : "";
+
+ CDialog::OnInitDialog();
+
+ UpdateMaterial();
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void MaterialDialog::OnPaint()
+{
+ CPaintDC dc(this); // device context for painting
+
+ if (material && material->thumbnail) {
+ ThumbPreview(mMaterialThumb.GetSafeHwnd(), material->thumbnail);
+ }
+}
+
+void MaterialDialog::OnAmbientColor()
+{
+ if (material) {
+ Color c = material->ambient_color;
+ COLORREF crgb = RGB(c.Red(), c.Green(), c.Blue());
+ CColorDialog chooser(crgb);
+
+ if (chooser.DoModal() == IDOK) {
+ crgb = chooser.GetColor();
+ material->ambient_color = Color(GetRValue(crgb), GetGValue(crgb), GetBValue(crgb));
+ UpdateMaterial();
+ }
+ }
+}
+
+void MaterialDialog::OnDiffuseColor()
+{
+ if (material) {
+ Color c = material->diffuse_color;
+ COLORREF crgb = RGB(c.Red(), c.Green(), c.Blue());
+ CColorDialog chooser(crgb);
+
+ if (chooser.DoModal() == IDOK) {
+ crgb = chooser.GetColor();
+ material->diffuse_color = Color(GetRValue(crgb), GetGValue(crgb), GetBValue(crgb));
+ UpdateMaterial();
+ }
+ }
+}
+
+void MaterialDialog::OnSpecularColor()
+{
+ if (material) {
+ Color c = material->specular_color;
+ COLORREF crgb = RGB(c.Red(), c.Green(), c.Blue());
+ CColorDialog chooser(crgb);
+
+ if (chooser.DoModal() == IDOK) {
+ crgb = chooser.GetColor();
+ material->specular_color = Color(GetRValue(crgb), GetGValue(crgb), GetBValue(crgb));
+ UpdateMaterial();
+ }
+ }
+}
+
+void MaterialDialog::OnEmissiveColor()
+{
+ if (material) {
+ Color c = material->emissive_color;
+ COLORREF crgb = RGB(c.Red(), c.Green(), c.Blue());
+ CColorDialog chooser(crgb);
+
+ if (chooser.DoModal() == IDOK) {
+ crgb = chooser.GetColor();
+ material->emissive_color = Color(GetRValue(crgb), GetGValue(crgb), GetBValue(crgb));
+ UpdateMaterial();
+ }
+ }
+}
+
+void MaterialDialog::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
+{
+ CWnd* wnd = GetDlgItem(nIDCtl);
+ Color c = Color::LightGray;
+
+ if (material) {
+ if (wnd->GetSafeHwnd() == mAmbientColor.GetSafeHwnd())
+ c = material->ambient_color;
+
+ else if (wnd->GetSafeHwnd() == mDiffuseColor.GetSafeHwnd())
+ c = material->diffuse_color;
+
+ else if (wnd->GetSafeHwnd() == mSpecularColor.GetSafeHwnd())
+ c = material->specular_color;
+
+ else if (wnd->GetSafeHwnd() == mEmissiveColor.GetSafeHwnd())
+ c = material->emissive_color;
+ }
+
+ CBrush brush(RGB(c.Red(), c.Green(), c.Blue()));
+
+ ::FillRect(lpDrawItemStruct->hDC,
+ &lpDrawItemStruct->rcItem,
+ brush);
+
+ CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
+}
+
+// +--------------------------------------------------------------------+
+
+void MaterialDialog::OnChangeMaterialValue()
+{
+ UpdateMaterial();
+}
+
+// +--------------------------------------------------------------------+
+
+void MaterialDialog::OnFileTexture(int type)
+{
+ if (!material)
+ return;
+
+ char filename[512];
+ filename[0] = '\0';
+ CFileDialog ofd(TRUE, "pcx");
+
+ ofd.m_ofn.lpstrFilter = "All Image Files\0*.bmp; *.dds; *.jpg; *.pcx; *.png; *.tga\0Bitmap Files (*.bmp)\0*.bmp\0JPEG Files (*.jpg)\0*.pcx\0PCX Files (*.pcx)\0*.pcx\0PNG Files (*.png)\0*.png\0Truevision Targa Files (*.tga)\0*.png\0All Files\0*.*\0\0";
+ ofd.m_ofn.lpstrFile = filename;
+ ofd.m_ofn.nMaxFile = sizeof(filename);
+
+ if (ofd.DoModal() != IDOK)
+ return;
+
+ char tex_name[512];
+ sprintf_s(tex_name, "%s", ofd.GetFileName().GetBuffer(0));
+
+ ChangeFileTexture(tex_name, type);
+}
+
+void MaterialDialog::ChangeFileTexture(char* fname, int type)
+{
+ Bitmap* bmp = 0;
+
+ LoadTexture(fname, bmp);
+
+ if (bmp) {
+ switch (type) {
+ case 0:
+ material->tex_diffuse = bmp;
+ mDiffuseTexture = fname;
+ break;
+
+ case 1:
+ material->tex_specular = bmp;
+ mSpecularTexture = fname;
+ break;
+
+ case 2:
+ material->tex_emissive = bmp;
+ mEmissiveTexture = fname;
+ break;
+
+ case 3:
+ material->tex_bumpmap = bmp;
+ mBumpTexture = fname;
+ break;
+ }
+
+ UpdateData(FALSE);
+ UpdateMaterial();
+ }
+}
+
+void MaterialDialog::OnFileDiffuse()
+{
+ OnFileTexture(0);
+}
+
+void MaterialDialog::OnFileSpecular()
+{
+ OnFileTexture(1);
+}
+
+void MaterialDialog::OnFileEmissive()
+{
+ OnFileTexture(2);
+}
+
+void MaterialDialog::OnFileBump()
+{
+ OnFileTexture(3);
+}
+
+void MaterialDialog::OnChangeDiffuseTexture()
+{
+ if (material) {
+ UpdateData();
+
+ if (mDiffuseTexture.GetLength() < 1) {
+ material->tex_diffuse = 0;
+ UpdateMaterial();
+ return;
+ }
+
+ char* filename = mDiffuseTexture.LockBuffer();
+ ChangeFileTexture(filename, 0);
+ mDiffuseTexture.UnlockBuffer();
+ }
+}
+
+void MaterialDialog::OnChangeSpecularTexture()
+{
+ if (material) {
+ UpdateData();
+
+ if (mSpecularTexture.GetLength() < 1) {
+ material->tex_specular = 0;
+ UpdateMaterial();
+ return;
+ }
+
+ char* filename = mSpecularTexture.LockBuffer();
+ ChangeFileTexture(filename, 1);
+ mSpecularTexture.UnlockBuffer();
+ }
+}
+
+void MaterialDialog::OnChangeEmissiveTexture()
+{
+ if (material) {
+ UpdateData();
+
+ if (mEmissiveTexture.GetLength() < 1) {
+ material->tex_emissive = 0;
+ UpdateMaterial();
+ return;
+ }
+
+ char* filename = mEmissiveTexture.LockBuffer();
+ ChangeFileTexture(filename, 2);
+ mEmissiveTexture.UnlockBuffer();
+ }
+}
+
+void MaterialDialog::OnChangeBumpTexture()
+{
+ if (material) {
+ UpdateData();
+
+ if (mBumpTexture.GetLength() < 1) {
+ material->tex_bumpmap = 0;
+ UpdateMaterial();
+ return;
+ }
+
+ char* filename = mBumpTexture.LockBuffer();
+ ChangeFileTexture(filename, 3);
+ mBumpTexture.UnlockBuffer();
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void MaterialDialog::OnChangeMaterialName()
+{
+ if (material) {
+ UpdateData();
+ strcpy_s(material->name, mMaterialName);
+ }
+}
+
+void MaterialDialog::OnChangeMaterialShader()
+{
+ if (material) {
+ UpdateData();
+ strcpy_s(material->shader, mMaterialShader);
+ }
+}
+
+void MaterialDialog::OnSelectMaterial()
+{
+ int selected = mMaterialList.GetCurSel();
+ Material* mtl = 0;
+
+ if (solid && solid->GetModel()) {
+ Model* model = solid->GetModel();
+
+ if (model->NumMaterials() > 0 && selected < model->NumMaterials())
+ mtl = model->GetMaterials()[selected];
+ }
+
+ if (!mtl)
+ mtl = &emergency_material;
+
+ if (material != mtl) {
+ material = mtl;
+
+ mMaterialName = material->name;
+ mMaterialShader = material->shader;
+ mAmbientValue = material->ambient_value;
+ mDiffuseValue = material->diffuse_value;
+ mSpecularValue = material->specular_value;
+ mEmissiveValue = material->emissive_value;
+ mPowerValue = material->power;
+ mBrillianceValue = material->brilliance;
+ mBumpValue = material->bump;
+
+ mDiffuseTexture = material->tex_diffuse ?
+ material->tex_diffuse->GetFilename() : "";
+
+ mSpecularTexture = material->tex_specular ?
+ material->tex_specular->GetFilename() : "";
+
+ mEmissiveTexture = material->tex_emissive ?
+ material->tex_emissive->GetFilename() : "";
+
+ mBumpTexture = material->tex_bumpmap ?
+ material->tex_bumpmap->GetFilename() : "";
+
+ if (mBlendModeList.GetSafeHwnd())
+ mBlendModeList.SetCurSel(BlendModeToSelection(material->blend));
+
+ if (mShadowList.GetSafeHwnd())
+ mShadowList.SetCurSel(material->shadow);
+
+ UpdateData(FALSE);
+ UpdateMaterial();
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void MaterialDialog::OnNewMaterial()
+{
+ if (solid && material && material != &emergency_material) {
+ Model* model = solid->GetModel();
+ Material* mtl = new Material;
+
+ if (model && mtl) {
+ mtl->Ka = Color::DarkGray;
+ mtl->Kd = Color::LightGray;
+ mtl->Ks = ColorValue(0.1f,0.1f,0.1f);
+ mtl->power = 10.0f;
+
+ mtl->ambient_value = 0.2f;
+ mtl->ambient_color = Color::DarkGray;
+ mtl->diffuse_value = 0.8f;
+ mtl->diffuse_color = Color::LightGray;
+ mtl->specular_value = 0.5f;
+ mtl->specular_color = Color::White;
+ strcpy_s(mtl->name, "(new)");
+
+ model->GetMaterials().append(mtl);
+
+ material = 0;
+ mMaterialList.AddString(mtl->name);
+ mMaterialList.SetCurSel(model->NumMaterials()-1);
+
+ mBlendModeList.SetCurSel(0);
+ mShadowList.SetCurSel(1);
+
+ OnSelectMaterial();
+ }
+ }
+}
+
+void MaterialDialog::OnDelMaterial()
+{
+ if (solid && material && material != &emergency_material) {
+ Model* model = solid->GetModel();
+
+ // do not delete the last material:
+ if (model->NumMaterials() > 1 && model->GetMaterials().contains(material)) {
+ Material* mtl = model->GetMaterials().first();
+
+ if (mtl == material)
+ mtl = model->GetMaterials()[1];
+
+ // reassign the material for any polys and segments
+ // that are using the one we are about to delete:
+ ListIter<Surface> iter = model->GetSurfaces();
+
+ while (++iter) {
+ Surface* s = iter.value();
+
+ for (int i = 0; i < s->NumPolys(); i++) {
+ Poly* p = s->GetPolys() + i;
+
+ if (p->material == material) {
+ p->material = mtl;
+ }
+ }
+
+ ListIter<Segment> seg_iter = s->GetSegments();
+ while (++seg_iter) {
+ Segment* segment = seg_iter.value();
+ if (segment->material == material)
+ segment->material = mtl;
+ }
+ }
+
+ // now delete the material:
+ model->GetMaterials().remove(material);
+ delete material;
+
+ material = 0;
+ mMaterialList.SetCurSel(0);
+ OnSelectMaterial();
+ }
+ }
+}
+
+void MaterialDialog::OnSelectPolys()
+{
+ if (solid && doc && doc->GetSelector()) {
+ Selector* selector = doc->GetSelector();
+
+ if (!material || material == &emergency_material)
+ selector->SelectMaterial(0);
+ else
+ selector->SelectMaterial(material);
+ }
+}
+
+void MaterialDialog::OnSelectBlendMode()
+{
+ if (material)
+ material->blend = SelectionToBlendMode(mBlendModeList.GetCurSel());
+}
+
+void MaterialDialog::OnSelectShadow()
+{
+ if (material)
+ material->shadow = mShadowList.GetCurSel() ? true : false;
+}
+
+void MaterialDialog::OnOK()
+{
+ Video* video = Video::GetInstance();
+ if (video)
+ video->InvalidateCache();
+
+ CDialog::OnOK();
+}
diff --git a/Magic2/MaterialDialog.h b/Magic2/MaterialDialog.h
index b6fabcf..24f33b4 100644
--- a/Magic2/MaterialDialog.h
+++ b/Magic2/MaterialDialog.h
@@ -1,117 +1,141 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: MaterialDialog.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Material Editor Dialog interface file
-*/
-
-#if !defined(AFX_MATERIALDIALOG_H__DD978D83_EB03_479B_92A4_D1FCC333BECA__INCLUDED_)
-#define AFX_MATERIALDIALOG_H__DD978D83_EB03_479B_92A4_D1FCC333BECA__INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif
-
-// +--------------------------------------------------------------------+
-
-class MagicDoc;
-class MagicView;
-struct Material;
-
-// +--------------------------------------------------------------------+
-// MaterialDialog dialog
-// +--------------------------------------------------------------------+
-
-class MaterialDialog : public CDialog
-{
-// Construction
-public:
- MaterialDialog(MagicView* pParent = NULL);
- virtual ~MaterialDialog();
-
-// Dialog Data
- //{{AFX_DATA(MaterialDialog)
- enum { IDD = IDD_MODIFY_MATERIAL };
- CComboBox mShadowList;
- CComboBox mBlendModeList;
- CListBox mMaterialList;
- CStatic mMaterialThumb;
- CStatic mSpecularColor;
- CStatic mEmissiveColor;
- CStatic mDiffuseColor;
- CStatic mAmbientColor;
- float mAmbientValue;
- float mBrillianceValue;
- float mBumpValue;
- float mDiffuseValue;
- float mEmissiveValue;
- CString mMaterialName;
- float mPowerValue;
- float mSpecularValue;
- CString mSpecularTexture;
- CString mDiffuseTexture;
- CString mBumpTexture;
- CString mEmissiveTexture;
- CString mMaterialShader;
- //}}AFX_DATA
-
-
-// Overrides
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(MaterialDialog)
- protected:
- virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
- //}}AFX_VIRTUAL
-
-// Implementation
-protected:
- void UpdateMaterial();
- void OnFileTexture(int type);
- void ChangeFileTexture(char* fname, int type);
-
- MagicDoc* doc;
- Solid* solid;
- Material* material;
-
- // Generated message map functions
- //{{AFX_MSG(MaterialDialog)
- virtual BOOL OnInitDialog();
- afx_msg void OnPaint();
- afx_msg void OnAmbientColor();
- afx_msg void OnDiffuseColor();
- afx_msg void OnEmissiveColor();
- afx_msg void OnSpecularColor();
- afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
- afx_msg void OnChangeMaterialValue();
- afx_msg void OnFileDiffuse();
- afx_msg void OnFileSpecular();
- afx_msg void OnFileEmissive();
- afx_msg void OnFileBump();
- afx_msg void OnChangeDiffuseTexture();
- afx_msg void OnChangeSpecularTexture();
- afx_msg void OnChangeEmissiveTexture();
- afx_msg void OnChangeBumpTexture();
- afx_msg void OnChangeMaterialName();
- afx_msg void OnSelectMaterial();
- afx_msg void OnSelectPolys();
- afx_msg void OnNewMaterial();
- afx_msg void OnDelMaterial();
- afx_msg void OnSelectBlendMode();
- afx_msg void OnSelectShadow();
- virtual void OnOK();
- afx_msg void OnChangeMaterialShader();
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
-};
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
-
-#endif
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: MaterialDialog.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Material Editor Dialog interface file
+*/
+
+#if !defined(AFX_MATERIALDIALOG_H__DD978D83_EB03_479B_92A4_D1FCC333BECA__INCLUDED_)
+#define AFX_MATERIALDIALOG_H__DD978D83_EB03_479B_92A4_D1FCC333BECA__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+// +--------------------------------------------------------------------+
+
+class MagicDoc;
+class MagicView;
+struct Material;
+
+// +--------------------------------------------------------------------+
+// MaterialDialog dialog
+// +--------------------------------------------------------------------+
+
+class MaterialDialog : public CDialog
+{
+// Construction
+public:
+ MaterialDialog(MagicView* pParent = NULL);
+ virtual ~MaterialDialog();
+
+// Dialog Data
+ //{{AFX_DATA(MaterialDialog)
+ enum { IDD = IDD_MODIFY_MATERIAL };
+ CComboBox mShadowList;
+ CComboBox mBlendModeList;
+ CListBox mMaterialList;
+ CStatic mMaterialThumb;
+ CStatic mSpecularColor;
+ CStatic mEmissiveColor;
+ CStatic mDiffuseColor;
+ CStatic mAmbientColor;
+ float mAmbientValue;
+ float mBrillianceValue;
+ float mBumpValue;
+ float mDiffuseValue;
+ float mEmissiveValue;
+ CString mMaterialName;
+ float mPowerValue;
+ float mSpecularValue;
+ CString mSpecularTexture;
+ CString mDiffuseTexture;
+ CString mBumpTexture;
+ CString mEmissiveTexture;
+ CString mMaterialShader;
+ //}}AFX_DATA
+
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(MaterialDialog)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+ void UpdateMaterial();
+ void OnFileTexture(int type);
+ void ChangeFileTexture(char* fname, int type);
+
+ MagicDoc* doc;
+ Solid* solid;
+ Material* material;
+
+ // Generated message map functions
+ //{{AFX_MSG(MaterialDialog)
+ virtual BOOL OnInitDialog();
+ afx_msg void OnPaint();
+ afx_msg void OnAmbientColor();
+ afx_msg void OnDiffuseColor();
+ afx_msg void OnEmissiveColor();
+ afx_msg void OnSpecularColor();
+ afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
+ afx_msg void OnChangeMaterialValue();
+ afx_msg void OnFileDiffuse();
+ afx_msg void OnFileSpecular();
+ afx_msg void OnFileEmissive();
+ afx_msg void OnFileBump();
+ afx_msg void OnChangeDiffuseTexture();
+ afx_msg void OnChangeSpecularTexture();
+ afx_msg void OnChangeEmissiveTexture();
+ afx_msg void OnChangeBumpTexture();
+ afx_msg void OnChangeMaterialName();
+ afx_msg void OnSelectMaterial();
+ afx_msg void OnSelectPolys();
+ afx_msg void OnNewMaterial();
+ afx_msg void OnDelMaterial();
+ afx_msg void OnSelectBlendMode();
+ afx_msg void OnSelectShadow();
+ virtual void OnOK();
+ afx_msg void OnChangeMaterialShader();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif
diff --git a/Magic2/ModelFile3DS.cpp b/Magic2/ModelFile3DS.cpp
index db309ba..7094f00 100644
--- a/Magic2/ModelFile3DS.cpp
+++ b/Magic2/ModelFile3DS.cpp
@@ -1,283 +1,307 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: ModelFile3DS.cpp
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- File loader for 3DStudio MAX 3DS format models
-*/
-
-#include "stdafx.h"
-#include "Magic.h"
-#include "MagicDoc.h"
-#include "ModelFile3DS.h"
-
-#include "Bitmap.h"
-#include "Polygon.h"
-#include "Text.h"
-#include "List.h"
-#include "l3ds.h"
-
-// +--------------------------------------------------------------------+
-
-ModelFile3DS::ModelFile3DS(const char* fname)
- : ModelFile(fname)
-{
-}
-
-ModelFile3DS::~ModelFile3DS()
-{
-}
-
-// +--------------------------------------------------------------------+
-
-static int mcomp(const void* a, const void* b)
-{
- Poly* pa = (Poly*) a;
- Poly* pb = (Poly*) b;
-
- if (pa->sortval == pb->sortval)
- return 0;
-
- if (pa->sortval < pb->sortval)
- return 1;
-
- return -1;
-}
-
-bool
-ModelFile3DS::Load(Model* model, double scale)
-{
- if (model && scale > 0 && strlen(filename) > 0) {
- ModelFile::Load(model, scale);
-
- L3DS loader;
-
- if (!loader.LoadFile(filename)) {
- ::MessageBox(0, "3DS Import Failed: Magic could not open the file for reading", "ERROR", MB_OK);
- return false;
- }
-
- int ntex = 0;
- int nsurfs = 0;
- int nverts = 0;
- int npolys = 0;
- int nmatls = 0;
- int nmeshs = loader.GetMeshCount();
-
- int* mesh_verts = new int[nmeshs];
-
- for (int m = 0; m < nmeshs; m++) {
- LMesh& mesh = loader.GetMesh(m);
-
- mesh_verts[m] = nverts;
-
- // count verts and polys:
- nverts += mesh.GetVertexCount();
- npolys += mesh.GetTriangleCount();
- }
-
- if (nverts > Model::MAX_VERTS || npolys > Model::MAX_POLYS) {
- ::MessageBox(0, "3DS Import Failed: model was too large (max 16000 polys)", "ERROR", MB_OK);
- delete [] mesh_verts;
- return FALSE;
- }
-
- // get materials:
- nmatls = loader.GetMaterialCount();
-
- for (int i = 0; i < nmatls; i++) {
- LMaterial& matl = loader.GetMaterial(i);
- LMap& tex_diff = matl.GetTextureMap1();
- LMap& tex_spec = matl.GetSpecularMap();
- LMap& tex_bump = matl.GetBumpMap();
- LMap& tex_glow = matl.GetTextureMap2();
-
- Material* material = new Material;
-
- strncpy(material->name, matl.GetName().c_str(), Material::NAMELEN);
-
- material->Ka.Set( matl.GetAmbientColor().r,
- matl.GetAmbientColor().g,
- matl.GetAmbientColor().b );
-
- material->ambient_value = 1.0f;
- material->ambient_color = material->Ka.ToColor();
-
- material->Kd.Set( matl.GetDiffuseColor().r,
- matl.GetDiffuseColor().g,
- matl.GetDiffuseColor().b );
-
- material->diffuse_value = 1.0f;
- material->diffuse_color = material->Kd.ToColor();
-
- material->Ks.Set( matl.GetSpecularColor().r,
- matl.GetSpecularColor().g,
- matl.GetSpecularColor().b );
-
- material->specular_value = 1.0f;
- material->specular_color = material->Ks.ToColor();
-
- material->power = matl.GetShininess() * 100;
-
- if (tex_diff.mapName[0])
- LoadTexture(tex_diff.mapName, material->tex_diffuse);
-
- if (tex_spec.mapName[0])
- LoadTexture(tex_spec.mapName, material->tex_specular);
-
- if (tex_bump.mapName[0])
- LoadTexture(tex_bump.mapName, material->tex_bumpmap);
-
- if (tex_glow.mapName[0])
- LoadTexture(tex_glow.mapName, material->tex_emissive);
-
- model->GetMaterials().append(material);
- }
-
- Surface* surface = new Surface;
- model->GetSurfaces().append(surface);
-
- surface->CreateVerts(nverts);
- surface->CreatePolys(npolys);
-
- VertexSet* vset = surface->GetVertexSet();
- Poly* polys = surface->GetPolys();
- float radius = 0;
- int v = 0;
-
- for (int m = 0; m < nmeshs && v < nverts; m++) {
- LMesh& mesh = loader.GetMesh(m);
-
- // read vertex set:
- for (int i = 0; i < mesh.GetVertexCount() && v < nverts; i++) {
- vset->loc[v].x = mesh.GetVertex(i).x;
- vset->loc[v].y = mesh.GetVertex(i).z;
- vset->loc[v].z = mesh.GetVertex(i).y;
-
- vset->nrm[v].x = mesh.GetNormal(i).x;
- vset->nrm[v].y = mesh.GetNormal(i).z;
- vset->nrm[v].z = mesh.GetNormal(i).y;
-
- vset->tu[v] = mesh.GetUV(i).x;
- vset->tv[v] = mesh.GetUV(i).y;
-
- float d = vset->loc[v].length();
- if (d > radius)
- radius = d;
-
- v++;
- }
- }
-
- if (radius < 16) {
- model->ScaleBy(256.0f / radius);
- radius = 256.0f;
- }
-
- int n = 0;
-
- for (int m = 0; m < nmeshs && n < npolys; m++) {
- LMesh& mesh = loader.GetMesh(m);
-
- // read polys:
- int mesh_tris = mesh.GetTriangleCount();
- for (int i = 0; i < mesh_tris && n < npolys; i++) {
- Poly* p = surface->GetPolys() + n++;
- const LTriangle& tri = mesh.GetTriangle(i);
- LTriangle2 tri2 = mesh.GetTriangle2(i);
-
- p->nverts = 3;
-
- p->verts[0] = tri.a + mesh_verts[m];
- p->verts[1] = tri.b + mesh_verts[m];
- p->verts[2] = tri.c + mesh_verts[m];
-
- if (p->verts[0] > nverts || p->verts[1] > nverts || p->verts[2] > nverts) {
- p->verts[0] = 0;
- p->verts[1] = 1;
- p->verts[2] = 2;
- }
-
- if (tri2.vertexNormals[0] == tri2.vertexNormals[1] &&
- tri2.vertexNormals[0] == tri2.vertexNormals[2])
- p->flatness = 1.0f;
- else
- p->flatness = 0.0f;
-
- p->vertex_set = vset;
- p->material = model->GetMaterials()[ tri2.materialId ];
- p->sortval = tri2.materialId;
-
- p->plane = Plane(vset->loc[ p->verts[0] ],
- vset->loc[ p->verts[2] ],
- vset->loc[ p->verts[1] ]);
-
- surface->AddIndices(p->nverts);
- }
- }
-
- // sort the polys by material index:
- qsort((void*) polys, npolys, sizeof(Poly), mcomp);
-
- // then assign them to cohesive segments:
- Segment* segment = 0;
-
- for (int n = 0; n < npolys; n++) {
- if (segment && segment->material == polys[n].material) {
- segment->npolys++;
- }
- else {
- segment = 0;
- }
-
- if (!segment) {
- segment = new Segment;
-
- segment->npolys = 1;
- segment->polys = &polys[n];
- segment->material = segment->polys->material;
-
- surface->GetSegments().append(segment);
- }
- }
-
- *pnverts = nverts;
- *pnpolys = npolys;
- *pradius = radius;
-
- model->Normalize();
- return true;
- }
-
- return false;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-ModelFile3DS::Save(Model* m)
-{
- if (m) {
- ModelFile::Save(m);
-
- FILE* f = fopen(filename, "w");
- if (!f) {
- ::MessageBox(0, "3DS Export Failed: Magic could not open the file for writing", "ERROR", MB_OK);
- return false;
- }
-
- fclose(f);
-
- return true;
- }
-
- return false;
-}
-
-// +--------------------------------------------------------------------+
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: ModelFile3DS.cpp
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ File loader for 3DStudio MAX 3DS format models
+*/
+
+#include "stdafx.h"
+#include "Magic.h"
+#include "MagicDoc.h"
+#include "ModelFile3DS.h"
+
+#include "Bitmap.h"
+#include "Polygon.h"
+#include "Text.h"
+#include "List.h"
+#include "l3ds.h"
+
+// +--------------------------------------------------------------------+
+
+ModelFile3DS::ModelFile3DS(const char* fname)
+ : ModelFile(fname)
+{
+}
+
+ModelFile3DS::~ModelFile3DS()
+{
+}
+
+// +--------------------------------------------------------------------+
+
+static int mcomp(const void* a, const void* b)
+{
+ Poly* pa = (Poly*) a;
+ Poly* pb = (Poly*) b;
+
+ if (pa->sortval == pb->sortval)
+ return 0;
+
+ if (pa->sortval < pb->sortval)
+ return 1;
+
+ return -1;
+}
+
+bool
+ModelFile3DS::Load(Model* model, double scale)
+{
+ if (model && scale > 0 && strlen(filename) > 0) {
+ ModelFile::Load(model, scale);
+
+ L3DS loader;
+
+ if (!loader.LoadFile(filename)) {
+ ::MessageBox(0, "3DS Import Failed: Magic could not open the file for reading", "ERROR", MB_OK);
+ return false;
+ }
+
+ int ntex = 0;
+ int nsurfs = 0;
+ int nverts = 0;
+ int npolys = 0;
+ int nmatls = 0;
+ int nmeshs = loader.GetMeshCount();
+
+ int* mesh_verts = new int[nmeshs];
+
+ for (int m = 0; m < nmeshs; m++) {
+ LMesh& mesh = loader.GetMesh(m);
+
+ mesh_verts[m] = nverts;
+
+ // count verts and polys:
+ nverts += mesh.GetVertexCount();
+ npolys += mesh.GetTriangleCount();
+ }
+
+ if (nverts > Model::MAX_VERTS || npolys > Model::MAX_POLYS) {
+ ::MessageBox(0, "3DS Import Failed: model was too large (max 16000 polys)", "ERROR", MB_OK);
+ delete [] mesh_verts;
+ return FALSE;
+ }
+
+ // get materials:
+ nmatls = loader.GetMaterialCount();
+
+ for (int i = 0; i < nmatls; i++) {
+ LMaterial& matl = loader.GetMaterial(i);
+ LMap& tex_diff = matl.GetTextureMap1();
+ LMap& tex_spec = matl.GetSpecularMap();
+ LMap& tex_bump = matl.GetBumpMap();
+ LMap& tex_glow = matl.GetTextureMap2();
+
+ Material* material = new Material;
+
+ strncpy(material->name, matl.GetName().c_str(), Material::NAMELEN);
+
+ material->Ka.Set( matl.GetAmbientColor().r,
+ matl.GetAmbientColor().g,
+ matl.GetAmbientColor().b );
+
+ material->ambient_value = 1.0f;
+ material->ambient_color = material->Ka.ToColor();
+
+ material->Kd.Set( matl.GetDiffuseColor().r,
+ matl.GetDiffuseColor().g,
+ matl.GetDiffuseColor().b );
+
+ material->diffuse_value = 1.0f;
+ material->diffuse_color = material->Kd.ToColor();
+
+ material->Ks.Set( matl.GetSpecularColor().r,
+ matl.GetSpecularColor().g,
+ matl.GetSpecularColor().b );
+
+ material->specular_value = 1.0f;
+ material->specular_color = material->Ks.ToColor();
+
+ material->power = matl.GetShininess() * 100;
+
+ if (tex_diff.mapName[0])
+ LoadTexture(tex_diff.mapName, material->tex_diffuse);
+
+ if (tex_spec.mapName[0])
+ LoadTexture(tex_spec.mapName, material->tex_specular);
+
+ if (tex_bump.mapName[0])
+ LoadTexture(tex_bump.mapName, material->tex_bumpmap);
+
+ if (tex_glow.mapName[0])
+ LoadTexture(tex_glow.mapName, material->tex_emissive);
+
+ model->GetMaterials().append(material);
+ }
+
+ Surface* surface = new Surface;
+ model->GetSurfaces().append(surface);
+
+ surface->CreateVerts(nverts);
+ surface->CreatePolys(npolys);
+
+ VertexSet* vset = surface->GetVertexSet();
+ Poly* polys = surface->GetPolys();
+ float radius = 0;
+ int v = 0;
+
+ for (int m = 0; m < nmeshs && v < nverts; m++) {
+ LMesh& mesh = loader.GetMesh(m);
+
+ // read vertex set:
+ for (int i = 0; i < mesh.GetVertexCount() && v < nverts; i++) {
+ vset->loc[v].x = mesh.GetVertex(i).x;
+ vset->loc[v].y = mesh.GetVertex(i).z;
+ vset->loc[v].z = mesh.GetVertex(i).y;
+
+ vset->nrm[v].x = mesh.GetNormal(i).x;
+ vset->nrm[v].y = mesh.GetNormal(i).z;
+ vset->nrm[v].z = mesh.GetNormal(i).y;
+
+ vset->tu[v] = mesh.GetUV(i).x;
+ vset->tv[v] = mesh.GetUV(i).y;
+
+ float d = vset->loc[v].length();
+ if (d > radius)
+ radius = d;
+
+ v++;
+ }
+ }
+
+ if (radius < 16) {
+ model->ScaleBy(256.0f / radius);
+ radius = 256.0f;
+ }
+
+ int n = 0;
+
+ for (int m = 0; m < nmeshs && n < npolys; m++) {
+ LMesh& mesh = loader.GetMesh(m);
+
+ // read polys:
+ int mesh_tris = mesh.GetTriangleCount();
+ for (int i = 0; i < mesh_tris && n < npolys; i++) {
+ Poly* p = surface->GetPolys() + n++;
+ const LTriangle& tri = mesh.GetTriangle(i);
+ LTriangle2 tri2 = mesh.GetTriangle2(i);
+
+ p->nverts = 3;
+
+ p->verts[0] = tri.a + mesh_verts[m];
+ p->verts[1] = tri.b + mesh_verts[m];
+ p->verts[2] = tri.c + mesh_verts[m];
+
+ if (p->verts[0] > nverts || p->verts[1] > nverts || p->verts[2] > nverts) {
+ p->verts[0] = 0;
+ p->verts[1] = 1;
+ p->verts[2] = 2;
+ }
+
+ if (tri2.vertexNormals[0] == tri2.vertexNormals[1] &&
+ tri2.vertexNormals[0] == tri2.vertexNormals[2])
+ p->flatness = 1.0f;
+ else
+ p->flatness = 0.0f;
+
+ p->vertex_set = vset;
+ p->material = model->GetMaterials()[ tri2.materialId ];
+ p->sortval = tri2.materialId;
+
+ p->plane = Plane(vset->loc[ p->verts[0] ],
+ vset->loc[ p->verts[2] ],
+ vset->loc[ p->verts[1] ]);
+
+ surface->AddIndices(p->nverts);
+ }
+ }
+
+ // sort the polys by material index:
+ qsort((void*) polys, npolys, sizeof(Poly), mcomp);
+
+ // then assign them to cohesive segments:
+ Segment* segment = 0;
+
+ for (int n = 0; n < npolys; n++) {
+ if (segment && segment->material == polys[n].material) {
+ segment->npolys++;
+ }
+ else {
+ segment = 0;
+ }
+
+ if (!segment) {
+ segment = new Segment;
+
+ segment->npolys = 1;
+ segment->polys = &polys[n];
+ segment->material = segment->polys->material;
+
+ surface->GetSegments().append(segment);
+ }
+ }
+
+ *pnverts = nverts;
+ *pnpolys = npolys;
+ *pradius = radius;
+
+ model->Normalize();
+ return true;
+ }
+
+ return false;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+ModelFile3DS::Save(Model* m)
+{
+ if (m) {
+ ModelFile::Save(m);
+
+ FILE* f = fopen(filename, "w");
+ if (!f) {
+ ::MessageBox(0, "3DS Export Failed: Magic could not open the file for writing", "ERROR", MB_OK);
+ return false;
+ }
+
+ fclose(f);
+
+ return true;
+ }
+
+ return false;
+}
+
+// +--------------------------------------------------------------------+
diff --git a/Magic2/ModelFile3DS.h b/Magic2/ModelFile3DS.h
index bf49d09..19a255a 100644
--- a/Magic2/ModelFile3DS.h
+++ b/Magic2/ModelFile3DS.h
@@ -1,37 +1,61 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: ModelFile3DS.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- File loader for 3DStudio MAX 3DS format models
-*/
-
-#ifndef ModelFile3DS_h
-#define ModelFile3DS_h
-
-#include "Solid.h"
-
-// +--------------------------------------------------------------------+
-
-class ModelFile3DS : public ModelFile
-{
-public:
- ModelFile3DS(const char* fname);
- virtual ~ModelFile3DS();
-
- virtual bool Load(Model* m, double scale=1.0);
- virtual bool Save(Model* m);
-
-protected:
-};
-
-// +--------------------------------------------------------------------+
-
-#endif ModelFile3DS_h
-
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: ModelFile3DS.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ File loader for 3DStudio MAX 3DS format models
+*/
+
+#ifndef ModelFile3DS_h
+#define ModelFile3DS_h
+
+#include "Solid.h"
+
+// +--------------------------------------------------------------------+
+
+class ModelFile3DS : public ModelFile
+{
+public:
+ ModelFile3DS(const char* fname);
+ virtual ~ModelFile3DS();
+
+ virtual bool Load(Model* m, double scale=1.0);
+ virtual bool Save(Model* m);
+
+protected:
+};
+
+// +--------------------------------------------------------------------+
+
+#endif ModelFile3DS_h
+
diff --git a/Magic2/ModelFileMAG.cpp b/Magic2/ModelFileMAG.cpp
index 953f22d..51c6a46 100644
--- a/Magic2/ModelFileMAG.cpp
+++ b/Magic2/ModelFileMAG.cpp
@@ -1,825 +1,849 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: ModelFileMAG.cpp
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- File loader for MAG format models
-*/
-
-#include "stdafx.h"
-#include "Magic.h"
-#include "MagicDoc.h"
-#include "ModelFileMAG.h"
-
-#include "Bitmap.h"
-#include "Polygon.h"
-#include "List.h"
-
-// +--------------------------------------------------------------------+
-
-struct MaterialMag6 {
- char name[Material::NAMELEN];
- char shader[Material::NAMELEN];
- float power; // highlight sharpness (big=shiny)
- float brilliance; // diffuse power function
- float bump; // bump level (0=none)
- DWORD blend; // alpha blend type
- bool shadow; // material casts shadow
- bool luminous; // verts have their own lighting
-
- Color ambient_color;
- Color diffuse_color;
- Color specular_color;
- Color emissive_color;
-
- float ambient_value;
- float diffuse_value;
- float specular_value;
- float emissive_value;
-
- BYTE tex_diffuse;
- BYTE tex_specular;
- BYTE tex_bumpmap;
- BYTE tex_emissive;
-};
-
-// +--------------------------------------------------------------------+
-
-ModelFileMAG::ModelFileMAG(const char* fname)
- : ModelFile(fname)
-{
-}
-
-ModelFileMAG::~ModelFileMAG()
-{
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-ModelFileMAG::Load(Model* m, double scale)
-{
- if (m && scale > 0 && strlen(filename) > 0) {
- ModelFile::Load(m, scale);
-
- bool result = false;
- FILE* fp = fopen(filename, "rb");
-
- // check MAG file:
- if (!fp) {
- ::MessageBox(0, "File Open Failed:\nMagic could not open the requested file.", "ERROR", MB_OK);
- return result;
- }
-
- ZeroMemory(pname, 64);
- strncpy(pname, filename, 63);
-
- char file_id[5];
- fread(file_id, 4, 1, fp);
- file_id[4] = '\0';
- int version = 1;
-
- if (!strcmp(file_id, "MAG6")) {
- version = 6;
- }
- else if (!strcmp(file_id, "MAG5")) {
- version = 5;
- }
- else if (!strcmp(file_id, "MAG4")) {
- version = 4;
- }
- else {
- ::MessageBox(0, "File Open Failed:\nThe requested file uses an invalid format.", "ERROR", MB_OK);
- fclose(fp);
- return result;
- }
-
- // get ready to load, delete existing model:
- m->GetSurfaces().destroy();
- m->GetMaterials().destroy();
- *pnverts = 0;
- *pnpolys = 0;
-
- // now load the model:
- switch (version) {
- case 4:
- case 5:
- result = LoadMag5(fp, m, scale);
- break;
-
- case 6:
- result = LoadMag6(fp, m, scale);
- break;
-
- default:
- break;
- }
-
- fclose(fp);
- return true;
- }
-
- return false;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-ModelFileMAG::Save(Model* m)
-{
- if (m) {
- ModelFile::Save(m);
-
- FILE* fp = fopen(filename, "wb");
- if (!fp) {
- ::MessageBox(0, "Save Failed:\nMagic could not open the file for writing.", "ERROR", MB_OK);
- return FALSE;
- }
-
- fwrite("MAG6", 4, 1, fp);
-
- int i = 0;
- int ntex = 0;
- int nmtls = 0;
- int nsurfs = m->NumSurfaces();
- List<Bitmap> textures;
-
- ListIter<Material> m_iter = m->GetMaterials();
- while (++m_iter) {
- Material* mtl = m_iter.value();
- Bitmap* bmp = mtl->tex_diffuse;
-
- if (bmp && !textures.contains(bmp)) {
- textures.append(bmp);
- }
-
- bmp = mtl->tex_specular;
-
- if (bmp && !textures.contains(bmp)) {
- textures.append(bmp);
- }
-
- bmp = mtl->tex_emissive;
-
- if (bmp && !textures.contains(bmp)) {
- textures.append(bmp);
- }
-
- bmp = mtl->tex_bumpmap;
-
- if (bmp && !textures.contains(bmp)) {
- textures.append(bmp);
- }
-
- nmtls++;
- }
-
- ListIter<Bitmap> t_iter = textures;
- while (++t_iter) {
- Bitmap* bmp = t_iter.value();
- ntex += strlen(bmp->GetFilename()) + 1;
- }
-
- nsurfs = m->GetSurfaces().size();
-
- fwrite(&ntex, 4, 1, fp);
- fwrite(&nmtls, 4, 1, fp);
- fwrite(&nsurfs, 4, 1, fp);
-
- if (ntex) {
- t_iter.reset();
- while (++t_iter) {
- Bitmap* bmp = t_iter.value();
-
- fwrite(bmp->GetFilename(),
- strlen(bmp->GetFilename()) + 1,
- 1,
- fp);
- }
- }
-
- if (nmtls) {
- m_iter.reset();
- while (++m_iter) {
- Material* mtl = m_iter.value();
- MaterialMag6 m6;
-
- ZeroMemory(&m6, sizeof(m6));
-
- CopyMemory(m6.name, mtl->name, Material::NAMELEN);
- CopyMemory(m6.shader, mtl->shader, Material::NAMELEN);
-
- m6.ambient_value = mtl->ambient_value;
- m6.ambient_color = mtl->ambient_color;
- m6.diffuse_value = mtl->diffuse_value;
- m6.diffuse_color = mtl->diffuse_color;
- m6.specular_value = mtl->specular_value;
- m6.specular_color = mtl->specular_color;
- m6.emissive_value = mtl->emissive_value;
- m6.emissive_color = mtl->emissive_color;
-
- m6.power = mtl->power;
- m6.brilliance = mtl->brilliance;
- m6.bump = mtl->bump;
- m6.blend = mtl->blend;
- m6.shadow = mtl->shadow;
- m6.luminous = mtl->luminous;
-
- if (mtl->tex_diffuse)
- m6.tex_diffuse = textures.index(mtl->tex_diffuse) + 1;
-
- if (mtl->tex_specular)
- m6.tex_specular = textures.index(mtl->tex_specular) + 1;
-
- if (mtl->tex_emissive)
- m6.tex_emissive = textures.index(mtl->tex_emissive) + 1;
-
- if (mtl->tex_bumpmap)
- m6.tex_bumpmap = textures.index(mtl->tex_bumpmap) + 1;
-
- fwrite(&m6, sizeof(m6), 1, fp);
- }
- }
-
- ListIter<Surface> s_iter = m->GetSurfaces();
- while (++s_iter) {
- Surface* s = s_iter.value();
-
- int nverts = s->NumVerts();
- int npolys = s->NumPolys();
- BYTE namelen = strlen(s->Name()) + 1;
-
- fwrite(&nverts, 4, 1, fp);
- fwrite(&npolys, 4, 1, fp);
- fwrite(&namelen, 1, 1, fp);
- fwrite(s->Name(), 1, namelen, fp);
-
- VertexSet* vset = s->GetVertexSet();
- Poly* polys = s->GetPolys();
-
- // write vertex set:
- for (int v = 0; v < nverts; v++) {
- fwrite(&vset->loc[v], sizeof(float), 3, fp);
- fwrite(&vset->nrm[v], sizeof(float), 3, fp);
- fwrite(&vset->tu[v], sizeof(float), 1, fp);
- fwrite(&vset->tv[v], sizeof(float), 1, fp);
- }
-
- // write polys:
- for (int n = 0; n < npolys; n++) {
- Poly& poly = polys[n];
- BYTE poly_nverts = (BYTE) poly.nverts;
- BYTE material_index = 0;
- WORD poly_verts[8];
-
- m_iter.reset();
- while (++m_iter && !material_index) {
- if (poly.material == m_iter.value())
- material_index = m_iter.index() + 1;
- }
-
- for (int i = 0; i < poly_nverts; i++) {
- poly_verts[i] = poly.verts[i];
- }
-
- fwrite(&poly_nverts, sizeof(BYTE), 1, fp);
- fwrite(&material_index, sizeof(BYTE), 1, fp);
- fwrite(&poly_verts[0], sizeof(WORD), poly_nverts, fp);
- }
- }
-
- return true;
- }
-
- return false;
-}
-
-// +--------------------------------------------------------------------+
-
-struct HomogenousPlane
-{
- double distance;
- double normal_x;
- double normal_y;
- double normal_z;
- double normal_w;
-};
-
-static void LoadPlane(Plane& p, FILE* fp)
-{
- HomogenousPlane tmp;
- fread(&tmp, sizeof(HomogenousPlane), 1, fp);
-}
-
-static void LoadFlags(LPDWORD flags, FILE* fp)
-{
- DWORD magic_flags;
- fread(&magic_flags, sizeof(DWORD), 1, fp);
-
- /** MAGIC FLAGS
- enum { FLAT_SHADED = 1,
- LUMINOUS = 2,
- TRANSLUCENT = 4, \\ must swap
- CHROMAKEY = 8, // these two
- FOREGROUND = 16, -- not used
- WIREFRAME = 32, -- not used
- SPECULAR1 = 64,
- SPECULAR2 = 128 };
- ***/
-
- const DWORD magic_mask = 0x0fc3;
-
- *flags = magic_flags & magic_mask;
-}
-
-// +--------------------------------------------------------------------+
-
-static int mcomp(const void* a, const void* b)
-{
- Poly* pa = (Poly*) a;
- Poly* pb = (Poly*) b;
-
- if (pa->sortval == pb->sortval)
- return 0;
-
- if (pa->sortval < pb->sortval)
- return -1;
-
- return 1;
-}
-
-bool
-ModelFileMAG::LoadMag5(FILE* fp, Model* m, double scale)
-{
- bool result = false;
- int ntex = 0;
- int nsurfs = 0;
- double radius = 0;
-
- fread(&ntex, sizeof(ntex), 1, fp);
- fread(&nsurfs, sizeof(nsurfs), 1, fp);
-
- // create a default gray material:
- Material* mtl = new Material;
-
- if (mtl) {
- mtl->Ka = Color::DarkGray;
- mtl->Kd = Color::LightGray;
- mtl->Ks = ColorValue(0.1f,0.1f,0.1f);
- mtl->power = 10.0f;
-
- mtl->ambient_value = 0.2f;
- mtl->ambient_color = Color::DarkGray;
- mtl->diffuse_value = 0.8f;
- mtl->diffuse_color = Color::LightGray;
- mtl->specular_value = 0.5f;
- mtl->specular_color = Color::White;
- strcpy_s(mtl->name, "(default)");
-
- m->GetMaterials().append(mtl);
- }
-
- // read texture list:
- for (int i = 0; i < ntex; i++) {
- Material* mtl = new Material;
- char tname[32];
-
- if (mtl) {
- mtl->Ka = ColorValue(0.5f,0.5f,0.5f);
- mtl->Kd = ColorValue(1.0f,1.0f,1.0f);
- mtl->Ks = ColorValue(0.2f,0.2f,0.2f);
- mtl->power = 20.0f;
-
- mtl->ambient_value = 1.0f;
- mtl->ambient_color = Color::Gray;
- mtl->diffuse_value = 1.0f;
- mtl->diffuse_color = Color::White;
- mtl->specular_value = 0.2f;
- mtl->specular_color = Color::White;
-
- fread(tname, 32, 1, fp);
- LoadTexture(tname, mtl->tex_diffuse, Bitmap::BMP_SOLID);
- strcpy_s(mtl->name, tname);
-
- char* dot = strrchr(mtl->name, '.');
- if (dot)
- *dot = 0;
-
- char* plus = strrchr(mtl->name, '+');
- if (plus)
- *plus = 0;
-
- m->GetMaterials().append(mtl);
- }
- }
-
- int nverts = 0;
- int npolys = 0;
-
- fread(&nverts, 4, 1, fp);
- fread(&npolys, 4, 1, fp);
-
- // plan on creating four verts per poly:
- int mag_nverts = nverts;
- int next_vert = nverts;
-
- nverts = npolys * 4;
- Surface* s = new Surface;
- VertexSet* vset = 0;
- Poly* polys = 0;
-
- if (s) {
- s->SetName("default");
- s->CreateVerts(nverts);
- s->CreatePolys(npolys);
-
- vset = s->GetVertexSet();
- polys = s->GetPolys();
-
- ZeroMemory(vset->loc, nverts * sizeof(Vec3));
- ZeroMemory(vset->diffuse, nverts * sizeof(DWORD));
- ZeroMemory(vset->specular, nverts * sizeof(DWORD));
- ZeroMemory(vset->tu, nverts * sizeof(float));
- ZeroMemory(vset->tv, nverts * sizeof(float));
- ZeroMemory(vset->rw, nverts * sizeof(float));
-
- // read vertex set:
- int v;
- for (v = 0; v < mag_nverts; v++) {
- Vec3 vert, norm;
- DWORD vstate;
-
- fread(&vert, sizeof(Vec3), 1, fp);
- fread(&norm, sizeof(Vec3), 1, fp);
- fread(&vstate, sizeof(DWORD), 1, fp);
-
- vert.SwapYZ();
- vert *= (float) scale;
-
- norm.SwapYZ();
-
- vset->loc[v] = vert;
- vset->nrm[v] = norm;
-
- double d = vert.length();
- if (d > radius)
- radius = (float) d;
- }
-
- while (v < nverts)
- vset->nrm[v++] = Vec3(1,0,0);
-
- // read polys:
- Vec3 dummy_center;
- DWORD dummy_flags;
- DWORD dummy_color;
- int texture_num;
- int poly_nverts;
- int vert_index_buffer[32];
- float texture_index_buffer[32];
-
- for (int n = 0; n < npolys; n++) {
- Poly& poly = polys[n];
- poly.vertex_set = vset;
-
- fread(&dummy_flags, sizeof(DWORD), 1, fp);
- fread(&dummy_center, sizeof(Vec3), 1, fp);
- LoadPlane(poly.plane, fp);
- fread(&dummy_color, sizeof(DWORD), 1, fp);
- fread(&texture_num, sizeof(int), 1, fp);
-
- if (texture_num >= 0 && texture_num < ntex) {
- texture_num++;
-
- poly.material = m->GetMaterials()[texture_num];
- poly.sortval = texture_num;
-
- if (dummy_flags & 2) { // luminous
- Material* mtl = m->GetMaterials()[texture_num];
-
- mtl->ambient_value = 0.0f;
- mtl->ambient_color = Color::Black;
- mtl->diffuse_value = 0.0f;
- mtl->diffuse_color = Color::Black;
- mtl->specular_value = 0.0f;
- mtl->specular_color = Color::Black;
- mtl->emissive_value = 1.0f;
- mtl->emissive_color = Color::White;
-
- mtl->Ka = ColorValue(0,0,0,0);
- mtl->Kd = ColorValue(0,0,0,0);
- mtl->Ks = ColorValue(0,0,0,0);
- mtl->Ke = ColorValue(1,1,1,1);
-
- mtl->tex_emissive = mtl->tex_diffuse;
- }
- }
- else {
- poly.material = m->GetMaterials().first(); // default material
- poly.sortval = 1000;
- }
-
- // hack: store flat shaded flag in unused visible byte
- poly.visible = (BYTE) (dummy_flags & 1);
-
- fread(&poly_nverts, sizeof(int), 1, fp);
- fread(vert_index_buffer, sizeof(int), poly_nverts, fp);
-
- if (poly_nverts == 3)
- s->AddIndices(3);
-
- else if (poly_nverts == 4)
- s->AddIndices(6);
-
- poly.nverts = poly_nverts;
- for (int vi = 0; vi < poly_nverts; vi++) {
- int v = vert_index_buffer[vi];
-
- if (vset->rw[v] > 0) {
- vset->CopyVertex(next_vert, v);
- v = next_vert++;
- }
-
- vset->rw[v] = 1;
- poly.verts[vi] = v;
- }
-
- fread(texture_index_buffer, sizeof(float), poly_nverts, fp); // tu's
- for (int vi = 0; vi < poly_nverts; vi++) {
- int v = poly.verts[vi];
- vset->tu[v] = texture_index_buffer[vi];
- }
-
- fread(texture_index_buffer, sizeof(float), poly_nverts, fp); // tv's
- for (int vi = 0; vi < poly_nverts; vi++) {
- int v = poly.verts[vi];
- vset->tv[v] = texture_index_buffer[vi];
- }
-
- DWORD unused[32];
- fread(unused, 16, 1, fp);
- }
-
- // pass 2 (adjust vertex normals for flat polys):
- for (int n = 0; n < npolys; n++) {
- Poly& poly = polys[n];
-
- poly.plane = Plane(vset->loc[poly.verts[0]],
- vset->loc[poly.verts[2]],
- vset->loc[poly.verts[1]]);
-
- // hack: retrieve flat shaded flag from unused visible byte
- if (poly.visible) {
- int poly_nverts = poly.nverts;
-
- for (int vi = 0; vi < poly_nverts; vi++) {
- int v = poly.verts[vi];
- vset->nrm[v] = poly.plane.normal;
- }
- }
- }
-
- // sort the polys by material index:
- qsort((void*) polys, npolys, sizeof(Poly), mcomp);
-
- // then assign them to cohesive segments:
- Segment* segment = 0;
-
- for (int n = 0; n < npolys; n++) {
- if (segment && segment->material == polys[n].material) {
- segment->npolys++;
- }
- else {
- segment = 0;
- }
-
- if (!segment) {
- segment = new Segment;
-
- segment->npolys = 1;
- segment->polys = &polys[n];
- segment->material = segment->polys->material;
-
- s->GetSegments().append(segment);
- }
- }
-
- s->BuildHull();
- m->GetSurfaces().append(s);
-
- *pnverts = nverts;
- *pnpolys = npolys;
- *pradius = (float) radius;
-
- result = nverts && npolys;
- }
-
- return result;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-ModelFileMAG::LoadMag6(FILE* fp, Model* m, double scale)
-{
- bool result = false;
- int i = 0;
- int ntex = 0;
- int nmtls = 0;
- int nsurfs = 0;
- double radius = 0;
- List<Bitmap> textures;
-
- fread(&ntex, sizeof(ntex), 1, fp); // size of texture block
- fread(&nmtls, sizeof(nmtls), 1, fp); // number of materials
- fread(&nsurfs, sizeof(nsurfs), 1, fp); // number of surfaces
-
- // read texture list:
- if (ntex) {
- char* buffer = new char[ntex];
- char* p = buffer;
- Bitmap* bmp = 0;
-
- fread(buffer, ntex, 1, fp);
-
- while (p < buffer + ntex) {
- LoadTexture(p, bmp, Bitmap::BMP_SOLID);
- textures.append(bmp);
-
- p += strlen(p) + 1;
- }
-
- delete [] buffer;
- }
-
- for (i = 0; i < nmtls; i++) {
- MaterialMag6 m6;
- Material* mtl = new Material;
-
- fread(&m6, sizeof(m6), 1, fp);
-
- if (mtl) {
- CopyMemory(mtl->name, m6.name, Material::NAMELEN);
- CopyMemory(mtl->shader, m6.shader, Material::NAMELEN);
-
- mtl->ambient_value = m6.ambient_value;
- mtl->ambient_color = m6.ambient_color;
- mtl->diffuse_value = m6.diffuse_value;
- mtl->diffuse_color = m6.diffuse_color;
- mtl->specular_value = m6.specular_value;
- mtl->specular_color = m6.specular_color;
- mtl->emissive_value = m6.emissive_value;
- mtl->emissive_color = m6.emissive_color;
-
- mtl->Ka = ColorValue(mtl->ambient_color) * mtl->ambient_value;
- mtl->Kd = ColorValue(mtl->diffuse_color) * mtl->diffuse_value;
- mtl->Ks = ColorValue(mtl->specular_color) * mtl->specular_value;
- mtl->Ke = ColorValue(mtl->emissive_color) * mtl->emissive_value;
-
- mtl->power = m6.power;
- mtl->brilliance = m6.brilliance;
- mtl->bump = m6.bump;
- mtl->blend = m6.blend;
- mtl->shadow = m6.shadow;
- mtl->luminous = m6.luminous;
-
- if (m6.tex_diffuse && m6.tex_diffuse <= textures.size())
- mtl->tex_diffuse = textures[m6.tex_diffuse - 1];
-
- if (m6.tex_specular && m6.tex_specular <= textures.size())
- mtl->tex_specular = textures[m6.tex_specular - 1];
-
- if (m6.tex_emissive && m6.tex_emissive <= textures.size())
- mtl->tex_emissive = textures[m6.tex_emissive - 1];
-
- if (m6.tex_bumpmap && m6.tex_bumpmap <= textures.size())
- mtl->tex_bumpmap = textures[m6.tex_bumpmap - 1];
-
- m->GetMaterials().append(mtl);
- }
- }
-
- for (i = 0; i < nsurfs; i++) {
- int nverts = 0;
- int npolys = 0;
- BYTE namelen = 0;
- char name[128];
-
- fread(&nverts, 4, 1, fp);
- fread(&npolys, 4, 1, fp);
- fread(&namelen, 1, 1, fp);
- fread(name, 1, namelen, fp);
-
- Surface* surface = new Surface;
- surface->SetName(name);
- surface->CreateVerts(nverts);
- surface->CreatePolys(npolys);
-
- VertexSet* vset = surface->GetVertexSet();
- Poly* polys = surface->GetPolys();
-
- ZeroMemory(polys, sizeof(Poly) * npolys);
-
- // read vertex set:
- for (int v = 0; v < nverts; v++) {
- fread(&vset->loc[v], sizeof(float), 3, fp);
- fread(&vset->nrm[v], sizeof(float), 3, fp);
- fread(&vset->tu[v], sizeof(float), 1, fp);
- fread(&vset->tv[v], sizeof(float), 1, fp);
-
- double d = vset->loc[v].length();
- if (d > radius)
- radius = d;
- }
-
- // read polys:
- for (int n = 0; n < npolys; n++) {
- Poly& poly = polys[n];
- BYTE poly_nverts = 0;
- BYTE material_index = 0;
- WORD poly_verts[8];
-
- fread(&poly_nverts, sizeof(BYTE), 1, fp);
- fread(&material_index, sizeof(BYTE), 1, fp);
- fread(&poly_verts[0], sizeof(WORD), poly_nverts, fp);
-
- if (poly_nverts >= 3) {
- poly.nverts = poly_nverts;
-
- for (int i = 0; i < poly_nverts; i++) {
- poly.verts[i] = poly_verts[i];
- }
- }
- else {
- poly.sortval = 666;
- }
-
- if (material_index > 0) {
- poly.material = m->GetMaterials()[material_index-1];
- poly.sortval = material_index;
- }
- else if (m->NumMaterials()) {
- poly.material = m->GetMaterials().first();
- poly.sortval = 1;
- }
- else {
- poly.sortval = 1000;
- }
-
- if (poly.nverts == 3)
- surface->AddIndices(3);
-
- else if (poly.nverts == 4)
- surface->AddIndices(6);
-
- poly.vertex_set = vset;
- poly.plane = Plane(vset->loc[poly.verts[0]],
- vset->loc[poly.verts[2]],
- vset->loc[poly.verts[1]]);
- }
-
- // sort the polys by material index:
- qsort((void*) polys, npolys, sizeof(Poly), mcomp);
-
- // then assign them to cohesive segments:
- Segment* segment = 0;
-
- for (int n = 0; n < npolys; n++) {
- if (segment && segment->material == polys[n].material) {
- segment->npolys++;
- }
- else {
- segment = 0;
- }
-
- if (!segment) {
- segment = new Segment;
-
- segment->npolys = 1;
- segment->polys = &polys[n];
- segment->material = segment->polys->material;
-
- surface->GetSegments().append(segment);
- }
- }
-
- surface->ComputeTangents();
- surface->BuildHull();
- m->GetSurfaces().append(surface);
-
- *pnverts = nverts;
- *pnpolys = npolys;
- *pradius = (float) radius;
-
- result = nverts && npolys;
- }
-
- return result;
-}
-
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: ModelFileMAG.cpp
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ File loader for MAG format models
+*/
+
+#include "stdafx.h"
+#include "Magic.h"
+#include "MagicDoc.h"
+#include "ModelFileMAG.h"
+
+#include "Bitmap.h"
+#include "Polygon.h"
+#include "List.h"
+
+// +--------------------------------------------------------------------+
+
+struct MaterialMag6 {
+ char name[Material::NAMELEN];
+ char shader[Material::NAMELEN];
+ float power; // highlight sharpness (big=shiny)
+ float brilliance; // diffuse power function
+ float bump; // bump level (0=none)
+ DWORD blend; // alpha blend type
+ bool shadow; // material casts shadow
+ bool luminous; // verts have their own lighting
+
+ Color ambient_color;
+ Color diffuse_color;
+ Color specular_color;
+ Color emissive_color;
+
+ float ambient_value;
+ float diffuse_value;
+ float specular_value;
+ float emissive_value;
+
+ BYTE tex_diffuse;
+ BYTE tex_specular;
+ BYTE tex_bumpmap;
+ BYTE tex_emissive;
+};
+
+// +--------------------------------------------------------------------+
+
+ModelFileMAG::ModelFileMAG(const char* fname)
+ : ModelFile(fname)
+{
+}
+
+ModelFileMAG::~ModelFileMAG()
+{
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+ModelFileMAG::Load(Model* m, double scale)
+{
+ if (m && scale > 0 && strlen(filename) > 0) {
+ ModelFile::Load(m, scale);
+
+ bool result = false;
+ FILE* fp = fopen(filename, "rb");
+
+ // check MAG file:
+ if (!fp) {
+ ::MessageBox(0, "File Open Failed:\nMagic could not open the requested file.", "ERROR", MB_OK);
+ return result;
+ }
+
+ ZeroMemory(pname, 64);
+ strncpy(pname, filename, 63);
+
+ char file_id[5];
+ fread(file_id, 4, 1, fp);
+ file_id[4] = '\0';
+ int version = 1;
+
+ if (!strcmp(file_id, "MAG6")) {
+ version = 6;
+ }
+ else if (!strcmp(file_id, "MAG5")) {
+ version = 5;
+ }
+ else if (!strcmp(file_id, "MAG4")) {
+ version = 4;
+ }
+ else {
+ ::MessageBox(0, "File Open Failed:\nThe requested file uses an invalid format.", "ERROR", MB_OK);
+ fclose(fp);
+ return result;
+ }
+
+ // get ready to load, delete existing model:
+ m->GetSurfaces().destroy();
+ m->GetMaterials().destroy();
+ *pnverts = 0;
+ *pnpolys = 0;
+
+ // now load the model:
+ switch (version) {
+ case 4:
+ case 5:
+ result = LoadMag5(fp, m, scale);
+ break;
+
+ case 6:
+ result = LoadMag6(fp, m, scale);
+ break;
+
+ default:
+ break;
+ }
+
+ fclose(fp);
+ return true;
+ }
+
+ return false;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+ModelFileMAG::Save(Model* m)
+{
+ if (m) {
+ ModelFile::Save(m);
+
+ FILE* fp = fopen(filename, "wb");
+ if (!fp) {
+ ::MessageBox(0, "Save Failed:\nMagic could not open the file for writing.", "ERROR", MB_OK);
+ return FALSE;
+ }
+
+ fwrite("MAG6", 4, 1, fp);
+
+ int i = 0;
+ int ntex = 0;
+ int nmtls = 0;
+ int nsurfs = m->NumSurfaces();
+ List<Bitmap> textures;
+
+ ListIter<Material> m_iter = m->GetMaterials();
+ while (++m_iter) {
+ Material* mtl = m_iter.value();
+ Bitmap* bmp = mtl->tex_diffuse;
+
+ if (bmp && !textures.contains(bmp)) {
+ textures.append(bmp);
+ }
+
+ bmp = mtl->tex_specular;
+
+ if (bmp && !textures.contains(bmp)) {
+ textures.append(bmp);
+ }
+
+ bmp = mtl->tex_emissive;
+
+ if (bmp && !textures.contains(bmp)) {
+ textures.append(bmp);
+ }
+
+ bmp = mtl->tex_bumpmap;
+
+ if (bmp && !textures.contains(bmp)) {
+ textures.append(bmp);
+ }
+
+ nmtls++;
+ }
+
+ ListIter<Bitmap> t_iter = textures;
+ while (++t_iter) {
+ Bitmap* bmp = t_iter.value();
+ ntex += strlen(bmp->GetFilename()) + 1;
+ }
+
+ nsurfs = m->GetSurfaces().size();
+
+ fwrite(&ntex, 4, 1, fp);
+ fwrite(&nmtls, 4, 1, fp);
+ fwrite(&nsurfs, 4, 1, fp);
+
+ if (ntex) {
+ t_iter.reset();
+ while (++t_iter) {
+ Bitmap* bmp = t_iter.value();
+
+ fwrite(bmp->GetFilename(),
+ strlen(bmp->GetFilename()) + 1,
+ 1,
+ fp);
+ }
+ }
+
+ if (nmtls) {
+ m_iter.reset();
+ while (++m_iter) {
+ Material* mtl = m_iter.value();
+ MaterialMag6 m6;
+
+ ZeroMemory(&m6, sizeof(m6));
+
+ CopyMemory(m6.name, mtl->name, Material::NAMELEN);
+ CopyMemory(m6.shader, mtl->shader, Material::NAMELEN);
+
+ m6.ambient_value = mtl->ambient_value;
+ m6.ambient_color = mtl->ambient_color;
+ m6.diffuse_value = mtl->diffuse_value;
+ m6.diffuse_color = mtl->diffuse_color;
+ m6.specular_value = mtl->specular_value;
+ m6.specular_color = mtl->specular_color;
+ m6.emissive_value = mtl->emissive_value;
+ m6.emissive_color = mtl->emissive_color;
+
+ m6.power = mtl->power;
+ m6.brilliance = mtl->brilliance;
+ m6.bump = mtl->bump;
+ m6.blend = mtl->blend;
+ m6.shadow = mtl->shadow;
+ m6.luminous = mtl->luminous;
+
+ if (mtl->tex_diffuse)
+ m6.tex_diffuse = textures.index(mtl->tex_diffuse) + 1;
+
+ if (mtl->tex_specular)
+ m6.tex_specular = textures.index(mtl->tex_specular) + 1;
+
+ if (mtl->tex_emissive)
+ m6.tex_emissive = textures.index(mtl->tex_emissive) + 1;
+
+ if (mtl->tex_bumpmap)
+ m6.tex_bumpmap = textures.index(mtl->tex_bumpmap) + 1;
+
+ fwrite(&m6, sizeof(m6), 1, fp);
+ }
+ }
+
+ ListIter<Surface> s_iter = m->GetSurfaces();
+ while (++s_iter) {
+ Surface* s = s_iter.value();
+
+ int nverts = s->NumVerts();
+ int npolys = s->NumPolys();
+ BYTE namelen = strlen(s->Name()) + 1;
+
+ fwrite(&nverts, 4, 1, fp);
+ fwrite(&npolys, 4, 1, fp);
+ fwrite(&namelen, 1, 1, fp);
+ fwrite(s->Name(), 1, namelen, fp);
+
+ VertexSet* vset = s->GetVertexSet();
+ Poly* polys = s->GetPolys();
+
+ // write vertex set:
+ for (int v = 0; v < nverts; v++) {
+ fwrite(&vset->loc[v], sizeof(float), 3, fp);
+ fwrite(&vset->nrm[v], sizeof(float), 3, fp);
+ fwrite(&vset->tu[v], sizeof(float), 1, fp);
+ fwrite(&vset->tv[v], sizeof(float), 1, fp);
+ }
+
+ // write polys:
+ for (int n = 0; n < npolys; n++) {
+ Poly& poly = polys[n];
+ BYTE poly_nverts = (BYTE) poly.nverts;
+ BYTE material_index = 0;
+ WORD poly_verts[8];
+
+ m_iter.reset();
+ while (++m_iter && !material_index) {
+ if (poly.material == m_iter.value())
+ material_index = m_iter.index() + 1;
+ }
+
+ for (int i = 0; i < poly_nverts; i++) {
+ poly_verts[i] = poly.verts[i];
+ }
+
+ fwrite(&poly_nverts, sizeof(BYTE), 1, fp);
+ fwrite(&material_index, sizeof(BYTE), 1, fp);
+ fwrite(&poly_verts[0], sizeof(WORD), poly_nverts, fp);
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+// +--------------------------------------------------------------------+
+
+struct HomogenousPlane
+{
+ double distance;
+ double normal_x;
+ double normal_y;
+ double normal_z;
+ double normal_w;
+};
+
+static void LoadPlane(Plane& p, FILE* fp)
+{
+ HomogenousPlane tmp;
+ fread(&tmp, sizeof(HomogenousPlane), 1, fp);
+}
+
+static void LoadFlags(LPDWORD flags, FILE* fp)
+{
+ DWORD magic_flags;
+ fread(&magic_flags, sizeof(DWORD), 1, fp);
+
+ /** MAGIC FLAGS
+ enum { FLAT_SHADED = 1,
+ LUMINOUS = 2,
+ TRANSLUCENT = 4, \\ must swap
+ CHROMAKEY = 8, // these two
+ FOREGROUND = 16, -- not used
+ WIREFRAME = 32, -- not used
+ SPECULAR1 = 64,
+ SPECULAR2 = 128 };
+ ***/
+
+ const DWORD magic_mask = 0x0fc3;
+
+ *flags = magic_flags & magic_mask;
+}
+
+// +--------------------------------------------------------------------+
+
+static int mcomp(const void* a, const void* b)
+{
+ Poly* pa = (Poly*) a;
+ Poly* pb = (Poly*) b;
+
+ if (pa->sortval == pb->sortval)
+ return 0;
+
+ if (pa->sortval < pb->sortval)
+ return -1;
+
+ return 1;
+}
+
+bool
+ModelFileMAG::LoadMag5(FILE* fp, Model* m, double scale)
+{
+ bool result = false;
+ int ntex = 0;
+ int nsurfs = 0;
+ double radius = 0;
+
+ fread(&ntex, sizeof(ntex), 1, fp);
+ fread(&nsurfs, sizeof(nsurfs), 1, fp);
+
+ // create a default gray material:
+ Material* mtl = new Material;
+
+ if (mtl) {
+ mtl->Ka = Color::DarkGray;
+ mtl->Kd = Color::LightGray;
+ mtl->Ks = ColorValue(0.1f,0.1f,0.1f);
+ mtl->power = 10.0f;
+
+ mtl->ambient_value = 0.2f;
+ mtl->ambient_color = Color::DarkGray;
+ mtl->diffuse_value = 0.8f;
+ mtl->diffuse_color = Color::LightGray;
+ mtl->specular_value = 0.5f;
+ mtl->specular_color = Color::White;
+ strcpy_s(mtl->name, "(default)");
+
+ m->GetMaterials().append(mtl);
+ }
+
+ // read texture list:
+ for (int i = 0; i < ntex; i++) {
+ Material* mtl = new Material;
+ char tname[32];
+
+ if (mtl) {
+ mtl->Ka = ColorValue(0.5f,0.5f,0.5f);
+ mtl->Kd = ColorValue(1.0f,1.0f,1.0f);
+ mtl->Ks = ColorValue(0.2f,0.2f,0.2f);
+ mtl->power = 20.0f;
+
+ mtl->ambient_value = 1.0f;
+ mtl->ambient_color = Color::Gray;
+ mtl->diffuse_value = 1.0f;
+ mtl->diffuse_color = Color::White;
+ mtl->specular_value = 0.2f;
+ mtl->specular_color = Color::White;
+
+ fread(tname, 32, 1, fp);
+ LoadTexture(tname, mtl->tex_diffuse, Bitmap::BMP_SOLID);
+ strcpy_s(mtl->name, tname);
+
+ char* dot = strrchr(mtl->name, '.');
+ if (dot)
+ *dot = 0;
+
+ char* plus = strrchr(mtl->name, '+');
+ if (plus)
+ *plus = 0;
+
+ m->GetMaterials().append(mtl);
+ }
+ }
+
+ int nverts = 0;
+ int npolys = 0;
+
+ fread(&nverts, 4, 1, fp);
+ fread(&npolys, 4, 1, fp);
+
+ // plan on creating four verts per poly:
+ int mag_nverts = nverts;
+ int next_vert = nverts;
+
+ nverts = npolys * 4;
+ Surface* s = new Surface;
+ VertexSet* vset = 0;
+ Poly* polys = 0;
+
+ if (s) {
+ s->SetName("default");
+ s->CreateVerts(nverts);
+ s->CreatePolys(npolys);
+
+ vset = s->GetVertexSet();
+ polys = s->GetPolys();
+
+ ZeroMemory(vset->loc, nverts * sizeof(Vec3));
+ ZeroMemory(vset->diffuse, nverts * sizeof(DWORD));
+ ZeroMemory(vset->specular, nverts * sizeof(DWORD));
+ ZeroMemory(vset->tu, nverts * sizeof(float));
+ ZeroMemory(vset->tv, nverts * sizeof(float));
+ ZeroMemory(vset->rw, nverts * sizeof(float));
+
+ // read vertex set:
+ int v;
+ for (v = 0; v < mag_nverts; v++) {
+ Vec3 vert, norm;
+ DWORD vstate;
+
+ fread(&vert, sizeof(Vec3), 1, fp);
+ fread(&norm, sizeof(Vec3), 1, fp);
+ fread(&vstate, sizeof(DWORD), 1, fp);
+
+ vert.SwapYZ();
+ vert *= (float) scale;
+
+ norm.SwapYZ();
+
+ vset->loc[v] = vert;
+ vset->nrm[v] = norm;
+
+ double d = vert.length();
+ if (d > radius)
+ radius = (float) d;
+ }
+
+ while (v < nverts)
+ vset->nrm[v++] = Vec3(1,0,0);
+
+ // read polys:
+ Vec3 dummy_center;
+ DWORD dummy_flags;
+ DWORD dummy_color;
+ int texture_num;
+ int poly_nverts;
+ int vert_index_buffer[32];
+ float texture_index_buffer[32];
+
+ for (int n = 0; n < npolys; n++) {
+ Poly& poly = polys[n];
+ poly.vertex_set = vset;
+
+ fread(&dummy_flags, sizeof(DWORD), 1, fp);
+ fread(&dummy_center, sizeof(Vec3), 1, fp);
+ LoadPlane(poly.plane, fp);
+ fread(&dummy_color, sizeof(DWORD), 1, fp);
+ fread(&texture_num, sizeof(int), 1, fp);
+
+ if (texture_num >= 0 && texture_num < ntex) {
+ texture_num++;
+
+ poly.material = m->GetMaterials()[texture_num];
+ poly.sortval = texture_num;
+
+ if (dummy_flags & 2) { // luminous
+ Material* mtl = m->GetMaterials()[texture_num];
+
+ mtl->ambient_value = 0.0f;
+ mtl->ambient_color = Color::Black;
+ mtl->diffuse_value = 0.0f;
+ mtl->diffuse_color = Color::Black;
+ mtl->specular_value = 0.0f;
+ mtl->specular_color = Color::Black;
+ mtl->emissive_value = 1.0f;
+ mtl->emissive_color = Color::White;
+
+ mtl->Ka = ColorValue(0,0,0,0);
+ mtl->Kd = ColorValue(0,0,0,0);
+ mtl->Ks = ColorValue(0,0,0,0);
+ mtl->Ke = ColorValue(1,1,1,1);
+
+ mtl->tex_emissive = mtl->tex_diffuse;
+ }
+ }
+ else {
+ poly.material = m->GetMaterials().first(); // default material
+ poly.sortval = 1000;
+ }
+
+ // hack: store flat shaded flag in unused visible byte
+ poly.visible = (BYTE) (dummy_flags & 1);
+
+ fread(&poly_nverts, sizeof(int), 1, fp);
+ fread(vert_index_buffer, sizeof(int), poly_nverts, fp);
+
+ if (poly_nverts == 3)
+ s->AddIndices(3);
+
+ else if (poly_nverts == 4)
+ s->AddIndices(6);
+
+ poly.nverts = poly_nverts;
+ for (int vi = 0; vi < poly_nverts; vi++) {
+ int v = vert_index_buffer[vi];
+
+ if (vset->rw[v] > 0) {
+ vset->CopyVertex(next_vert, v);
+ v = next_vert++;
+ }
+
+ vset->rw[v] = 1;
+ poly.verts[vi] = v;
+ }
+
+ fread(texture_index_buffer, sizeof(float), poly_nverts, fp); // tu's
+ for (int vi = 0; vi < poly_nverts; vi++) {
+ int v = poly.verts[vi];
+ vset->tu[v] = texture_index_buffer[vi];
+ }
+
+ fread(texture_index_buffer, sizeof(float), poly_nverts, fp); // tv's
+ for (int vi = 0; vi < poly_nverts; vi++) {
+ int v = poly.verts[vi];
+ vset->tv[v] = texture_index_buffer[vi];
+ }
+
+ DWORD unused[32];
+ fread(unused, 16, 1, fp);
+ }
+
+ // pass 2 (adjust vertex normals for flat polys):
+ for (int n = 0; n < npolys; n++) {
+ Poly& poly = polys[n];
+
+ poly.plane = Plane(vset->loc[poly.verts[0]],
+ vset->loc[poly.verts[2]],
+ vset->loc[poly.verts[1]]);
+
+ // hack: retrieve flat shaded flag from unused visible byte
+ if (poly.visible) {
+ int poly_nverts = poly.nverts;
+
+ for (int vi = 0; vi < poly_nverts; vi++) {
+ int v = poly.verts[vi];
+ vset->nrm[v] = poly.plane.normal;
+ }
+ }
+ }
+
+ // sort the polys by material index:
+ qsort((void*) polys, npolys, sizeof(Poly), mcomp);
+
+ // then assign them to cohesive segments:
+ Segment* segment = 0;
+
+ for (int n = 0; n < npolys; n++) {
+ if (segment && segment->material == polys[n].material) {
+ segment->npolys++;
+ }
+ else {
+ segment = 0;
+ }
+
+ if (!segment) {
+ segment = new Segment;
+
+ segment->npolys = 1;
+ segment->polys = &polys[n];
+ segment->material = segment->polys->material;
+
+ s->GetSegments().append(segment);
+ }
+ }
+
+ s->BuildHull();
+ m->GetSurfaces().append(s);
+
+ *pnverts = nverts;
+ *pnpolys = npolys;
+ *pradius = (float) radius;
+
+ result = nverts && npolys;
+ }
+
+ return result;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+ModelFileMAG::LoadMag6(FILE* fp, Model* m, double scale)
+{
+ bool result = false;
+ int i = 0;
+ int ntex = 0;
+ int nmtls = 0;
+ int nsurfs = 0;
+ double radius = 0;
+ List<Bitmap> textures;
+
+ fread(&ntex, sizeof(ntex), 1, fp); // size of texture block
+ fread(&nmtls, sizeof(nmtls), 1, fp); // number of materials
+ fread(&nsurfs, sizeof(nsurfs), 1, fp); // number of surfaces
+
+ // read texture list:
+ if (ntex) {
+ char* buffer = new char[ntex];
+ char* p = buffer;
+ Bitmap* bmp = 0;
+
+ fread(buffer, ntex, 1, fp);
+
+ while (p < buffer + ntex) {
+ LoadTexture(p, bmp, Bitmap::BMP_SOLID);
+ textures.append(bmp);
+
+ p += strlen(p) + 1;
+ }
+
+ delete [] buffer;
+ }
+
+ for (i = 0; i < nmtls; i++) {
+ MaterialMag6 m6;
+ Material* mtl = new Material;
+
+ fread(&m6, sizeof(m6), 1, fp);
+
+ if (mtl) {
+ CopyMemory(mtl->name, m6.name, Material::NAMELEN);
+ CopyMemory(mtl->shader, m6.shader, Material::NAMELEN);
+
+ mtl->ambient_value = m6.ambient_value;
+ mtl->ambient_color = m6.ambient_color;
+ mtl->diffuse_value = m6.diffuse_value;
+ mtl->diffuse_color = m6.diffuse_color;
+ mtl->specular_value = m6.specular_value;
+ mtl->specular_color = m6.specular_color;
+ mtl->emissive_value = m6.emissive_value;
+ mtl->emissive_color = m6.emissive_color;
+
+ mtl->Ka = ColorValue(mtl->ambient_color) * mtl->ambient_value;
+ mtl->Kd = ColorValue(mtl->diffuse_color) * mtl->diffuse_value;
+ mtl->Ks = ColorValue(mtl->specular_color) * mtl->specular_value;
+ mtl->Ke = ColorValue(mtl->emissive_color) * mtl->emissive_value;
+
+ mtl->power = m6.power;
+ mtl->brilliance = m6.brilliance;
+ mtl->bump = m6.bump;
+ mtl->blend = m6.blend;
+ mtl->shadow = m6.shadow;
+ mtl->luminous = m6.luminous;
+
+ if (m6.tex_diffuse && m6.tex_diffuse <= textures.size())
+ mtl->tex_diffuse = textures[m6.tex_diffuse - 1];
+
+ if (m6.tex_specular && m6.tex_specular <= textures.size())
+ mtl->tex_specular = textures[m6.tex_specular - 1];
+
+ if (m6.tex_emissive && m6.tex_emissive <= textures.size())
+ mtl->tex_emissive = textures[m6.tex_emissive - 1];
+
+ if (m6.tex_bumpmap && m6.tex_bumpmap <= textures.size())
+ mtl->tex_bumpmap = textures[m6.tex_bumpmap - 1];
+
+ m->GetMaterials().append(mtl);
+ }
+ }
+
+ for (i = 0; i < nsurfs; i++) {
+ int nverts = 0;
+ int npolys = 0;
+ BYTE namelen = 0;
+ char name[128];
+
+ fread(&nverts, 4, 1, fp);
+ fread(&npolys, 4, 1, fp);
+ fread(&namelen, 1, 1, fp);
+ fread(name, 1, namelen, fp);
+
+ Surface* surface = new Surface;
+ surface->SetName(name);
+ surface->CreateVerts(nverts);
+ surface->CreatePolys(npolys);
+
+ VertexSet* vset = surface->GetVertexSet();
+ Poly* polys = surface->GetPolys();
+
+ ZeroMemory(polys, sizeof(Poly) * npolys);
+
+ // read vertex set:
+ for (int v = 0; v < nverts; v++) {
+ fread(&vset->loc[v], sizeof(float), 3, fp);
+ fread(&vset->nrm[v], sizeof(float), 3, fp);
+ fread(&vset->tu[v], sizeof(float), 1, fp);
+ fread(&vset->tv[v], sizeof(float), 1, fp);
+
+ double d = vset->loc[v].length();
+ if (d > radius)
+ radius = d;
+ }
+
+ // read polys:
+ for (int n = 0; n < npolys; n++) {
+ Poly& poly = polys[n];
+ BYTE poly_nverts = 0;
+ BYTE material_index = 0;
+ WORD poly_verts[8];
+
+ fread(&poly_nverts, sizeof(BYTE), 1, fp);
+ fread(&material_index, sizeof(BYTE), 1, fp);
+ fread(&poly_verts[0], sizeof(WORD), poly_nverts, fp);
+
+ if (poly_nverts >= 3) {
+ poly.nverts = poly_nverts;
+
+ for (int i = 0; i < poly_nverts; i++) {
+ poly.verts[i] = poly_verts[i];
+ }
+ }
+ else {
+ poly.sortval = 666;
+ }
+
+ if (material_index > 0) {
+ poly.material = m->GetMaterials()[material_index-1];
+ poly.sortval = material_index;
+ }
+ else if (m->NumMaterials()) {
+ poly.material = m->GetMaterials().first();
+ poly.sortval = 1;
+ }
+ else {
+ poly.sortval = 1000;
+ }
+
+ if (poly.nverts == 3)
+ surface->AddIndices(3);
+
+ else if (poly.nverts == 4)
+ surface->AddIndices(6);
+
+ poly.vertex_set = vset;
+ poly.plane = Plane(vset->loc[poly.verts[0]],
+ vset->loc[poly.verts[2]],
+ vset->loc[poly.verts[1]]);
+ }
+
+ // sort the polys by material index:
+ qsort((void*) polys, npolys, sizeof(Poly), mcomp);
+
+ // then assign them to cohesive segments:
+ Segment* segment = 0;
+
+ for (int n = 0; n < npolys; n++) {
+ if (segment && segment->material == polys[n].material) {
+ segment->npolys++;
+ }
+ else {
+ segment = 0;
+ }
+
+ if (!segment) {
+ segment = new Segment;
+
+ segment->npolys = 1;
+ segment->polys = &polys[n];
+ segment->material = segment->polys->material;
+
+ surface->GetSegments().append(segment);
+ }
+ }
+
+ surface->ComputeTangents();
+ surface->BuildHull();
+ m->GetSurfaces().append(surface);
+
+ *pnverts = nverts;
+ *pnpolys = npolys;
+ *pradius = (float) radius;
+
+ result = nverts && npolys;
+ }
+
+ return result;
+}
+
diff --git a/Magic2/ModelFileMAG.h b/Magic2/ModelFileMAG.h
index cf3d6de..e693e71 100644
--- a/Magic2/ModelFileMAG.h
+++ b/Magic2/ModelFileMAG.h
@@ -1,39 +1,63 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: ModelFileMAG.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- File loader for MAG format models
-*/
-
-#ifndef ModelFileMAG_h
-#define ModelFileMAG_h
-
-#include "Solid.h"
-
-// +--------------------------------------------------------------------+
-
-class ModelFileMAG : public ModelFile
-{
-public:
- ModelFileMAG(const char* fname);
- virtual ~ModelFileMAG();
-
- virtual bool Load(Model* m, double scale=1.0);
- virtual bool Save(Model* m);
-
-protected:
- virtual bool LoadMag5(FILE* fp, Model* m, double scale);
- virtual bool LoadMag6(FILE* fp, Model* m, double scale);
-};
-
-// +--------------------------------------------------------------------+
-
-#endif ModelFileMAG_h
-
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: ModelFileMAG.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ File loader for MAG format models
+*/
+
+#ifndef ModelFileMAG_h
+#define ModelFileMAG_h
+
+#include "Solid.h"
+
+// +--------------------------------------------------------------------+
+
+class ModelFileMAG : public ModelFile
+{
+public:
+ ModelFileMAG(const char* fname);
+ virtual ~ModelFileMAG();
+
+ virtual bool Load(Model* m, double scale=1.0);
+ virtual bool Save(Model* m);
+
+protected:
+ virtual bool LoadMag5(FILE* fp, Model* m, double scale);
+ virtual bool LoadMag6(FILE* fp, Model* m, double scale);
+};
+
+// +--------------------------------------------------------------------+
+
+#endif ModelFileMAG_h
+
diff --git a/Magic2/ModelFileOBJ.cpp b/Magic2/ModelFileOBJ.cpp
index e3e35de..f27a2bd 100644
--- a/Magic2/ModelFileOBJ.cpp
+++ b/Magic2/ModelFileOBJ.cpp
@@ -1,790 +1,814 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: ModelFileOBJ.cpp
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- File loader for Wavefront/OBJ format models
-*/
-
-#include "stdafx.h"
-#include "Magic.h"
-#include "MagicDoc.h"
-#include "ModelFileOBJ.h"
-
-#include "Bitmap.h"
-#include "Polygon.h"
-#include "List.h"
-#include "Text.h"
-
-// +--------------------------------------------------------------------+
-
-ModelFileOBJ::ModelFileOBJ(const char* fname)
- : ModelFile(fname)
-{
-}
-
-ModelFileOBJ::~ModelFileOBJ()
-{
-}
-
-// +--------------------------------------------------------------------+
-
-const int MAX_OBJ_FACE_VERTS = 32;
-
-struct ObjFace {
- int v[MAX_OBJ_FACE_VERTS];
- int n[MAX_OBJ_FACE_VERTS];
- int t[MAX_OBJ_FACE_VERTS];
-
- int nverts;
-
- ObjFace() {
- nverts = 0;
-
- for (int i = 0; i < MAX_OBJ_FACE_VERTS; i++)
- v[i] = n[i] = t[i] = 0;
- }
-
- ObjFace(const ObjFace& f) {
- nverts = f.nverts;
-
- for (int i = 0; i < MAX_OBJ_FACE_VERTS; i++) {
- v[i] = f.v[i];
- n[i] = f.n[i];
- t[i] = f.t[i];
- }
- }
-
- void ReverseOrder() {
- int i, tmp[MAX_OBJ_FACE_VERTS];
-
- for (i = 0; i < nverts; i++) tmp[i] = v[i];
- for (i = 0; i < nverts; i++) v[i] = tmp[nverts-1-i];
-
- for (i = 0; i < nverts; i++) tmp[i] = n[i];
- for (i = 0; i < nverts; i++) n[i] = tmp[nverts-1-i];
-
- for (i = 0; i < nverts; i++) tmp[i] = t[i];
- for (i = 0; i < nverts; i++) t[i] = tmp[nverts-1-i];
- }
-};
-
-static void ParsePoly(const char* line, ObjFace* face)
-{
- int v[MAX_OBJ_FACE_VERTS];
- int n[MAX_OBJ_FACE_VERTS];
- int t[MAX_OBJ_FACE_VERTS];
-
- for (int i = 0; i < MAX_OBJ_FACE_VERTS; i++) {
- v[i] = n[i] = t[i] = 0;
- }
-
- const char* p = line + 1;
-
- while (isspace(*p))
- p++;
-
- int i = 0;
- while (*p && i < MAX_OBJ_FACE_VERTS) {
- int factor = 1;
-
- if (*p == '-') {
- factor = -1;
- p++;
- }
-
- while (isdigit(*p)) {
- v[i] = v[i]*10 + *p - '0';
- p++;
- }
- v[i] *= factor;
-
- if (*p == '/') { p++; // slash one
-
- factor = 1;
-
- if (*p == '-') {
- factor = -1;
- p++;
- }
-
- while (isdigit(*p)) {
- t[i] = t[i]*10 + *p - '0';
- p++;
- }
- t[i] *= factor;
-
- if (*p == '/') { p++; // slash two
-
- factor = 1;
-
- if (*p == '-') {
- factor = -1;
- p++;
- }
-
- while (isdigit(*p)) {
- n[i] = n[i]*10 + *p - '0';
- p++;
- }
- n[i] *= factor;
- }}
-
- while (isspace(*p)) p++;
- i++;
- }
-
- face->nverts = i;
-
- for (i = 0; i < MAX_OBJ_FACE_VERTS; i++) {
- face->v[i] = v[i];
- face->n[i] = n[i];
- face->t[i] = t[i];
- }
-}
-
-static int LoadMatls(const char* lpszPathName, Model* m)
-{
- int nmatls = 0;
-
- FILE* fp = fopen(lpszPathName, "r");
- if (!fp) {
- ::MessageBox(0, "Open Failed: could not open file", "ERROR", MB_OK);
- return 0;
- }
-
- Material* mtl = 0;
-
- while (!feof(fp)) {
- char raw_line[512];
- char line[512];
- fgets(raw_line, 512, fp);
-
- strcpy(line, Text(raw_line).trim().data());
-
- if (strstr(line, "newmtl")) {
- mtl = new Material;
- strncpy(mtl->name, line+7, Material::NAMELEN - 1);
-
- m->GetMaterials().append(mtl);
- }
-
- else if (line[0] == 'K' && line[1] == 'a') {
- float r,g,b;
- sscanf(line, "Ka %f %f %f", &r, &g, &b);
- mtl->Ka = ColorValue(r,g,b);
-
- mtl->ambient_value = 1.0f;
- mtl->ambient_color = mtl->Ka.ToColor();
- }
-
- else if (line[0] == 'K' && line[1] == 'd') {
- float r,g,b;
- sscanf(line, "Kd %f %f %f", &r, &g, &b);
- mtl->Kd = ColorValue(r,g,b);
-
- mtl->diffuse_value = 1.0f;
- mtl->diffuse_color = mtl->Kd.ToColor();
- }
-
- else if (line[0] == 'K' && line[1] == 's') {
- float r,g,b;
- sscanf(line, "Ks %f %f %f", &r, &g, &b);
- mtl->Ks = ColorValue(r,g,b);
-
- mtl->specular_value = 1.0f;
- mtl->specular_color = mtl->Ks.ToColor();
- }
-
- else if (line[0] == 'N' && line[1] == 's') {
- float ns;
- sscanf(line, "Ns %f", &ns);
- mtl->power = ns;
- }
-
- else if (strstr(line, "map_Kd")) {
- const char* src = strstr(line, "map_Kd") + 7;
- while (!isalnum(*src)) src++;
-
- LoadTexture(src, mtl->tex_diffuse, Bitmap::BMP_SOLID);
- }
- }
-
- fclose(fp);
- return nmatls;
-}
-
-static Material* FindMatl(const char* mtl_name, Model* model)
-{
- ListIter<Material> iter = model->GetMaterials();
- while (++iter) {
- Material* m = iter.value();
- if (!strcmp(m->name, mtl_name))
- return m;
- }
-
- return 0;
-}
-
-// +--------------------------------------------------------------------+
-
-static int mcomp(const void* a, const void* b)
-{
- Poly* pa = (Poly*) a;
- Poly* pb = (Poly*) b;
-
- if (pa->sortval == pb->sortval)
- return 0;
-
- if (pa->sortval < pb->sortval)
- return 1;
-
- return -1;
-}
-
-bool
-ModelFileOBJ::Load(Model* m, double scale)
-{
- if (m && scale > 0 && strlen(filename) > 0) {
- ModelFile::Load(m, scale);
-
- FILE* fp = fopen(filename, "rb");
-
- if (fp == NULL) {
- ::MessageBox(0, "Wavefront/OBJ Import Failed: Unable to open file", "ERROR", MB_OK);
- return false;
- }
-
- // ok, now start reading the data:
- int ntex = 0;
- int nverts = 0;
- int npv = 0;
- int npolys = 0;
- int vi = 0;
- int vn = 0;
- int vt = 0;
-
- char root_path[256];
- ZeroMemory(root_path, 256);
-
- if (strrchr(filename, '\\')) {
- strcpy(root_path, filename);
- char* p = strrchr(root_path, '\\');
- if (p)
- *(p+1) = 0;
- }
-
- else if (strrchr(filename, '/')) {
- strcpy(root_path, filename);
- char* p = strrchr(root_path, '/');
- if (p)
- *(p+1) = 0;
- }
-
- // count verts and polys:
- while (!feof(fp)) {
- char line[256];
- fgets(line, 255, fp);
-
- if (line[0] == 'v') {
- switch (line[1]) {
- case ' ': vi++; break;
- case 'n': vn++; break;
- case 't': vt++; break;
- }
- }
-
- else if (line[0] == 'f' && line[1] == ' ') {
- npolys++;
-
- ObjFace f;
- ParsePoly(line, &f);
- f.ReverseOrder();
-
- npv += f.nverts;
- }
-
- else if (strstr(line, "mtllib")) {
- const char* libname = strstr(line, "mtllib");
- libname += 7;
- while (isspace(*libname))
- libname++;
-
- char libpath[256];
- strcpy(libpath, root_path);
- strcat(libpath, libname);
- int n = strlen(libpath);
- if (n > 0) {
- char* p = &libpath[n-1];
- while (isspace(*p)) *p-- = 0;
- }
-
- int nmatls = LoadMatls(libpath, model);
- }
- }
-
- nverts = npv;
- if (vi > nverts) nverts = vi;
- if (vn > nverts) nverts = vn;
- if (vt > nverts) nverts = vt;
-
- if (nverts > Model::MAX_VERTS || npolys > Model::MAX_POLYS) {
- ::MessageBox(0, "Wavefront/OBJ Import Failed: that model is just too darn complicated!", "ERROR", MB_OK);
- return false;
- }
-
- vi = 0;
- vn = 0;
- vt = 0;
-
- fseek(fp, 0, SEEK_SET);
-
- Surface* surface = new Surface;
- m->GetSurfaces().append(surface);
-
- surface->CreateVerts(nverts);
- surface->CreatePolys(npolys);
-
- VertexSet* vset = surface->GetVertexSet();
- Poly* polys = surface->GetPolys();
-
- // read vertex set:
- Vec3* vloc = new Vec3[nverts];
- Vec3* vnrm = new Vec3[nverts];
- float* vtu = new float[nverts];
- float* vtv = new float[nverts];
-
- float radius = 0;
-
- while (!feof(fp)) {
- char line[256];
- fgets(line, 255, fp);
-
- if (line[0] == 'v') {
- if (line[1] == ' ') {
- const char* p = line + 2;
-
- while (isspace(*p)) p++;
- sscanf(p, "%f", &vloc[vi].x);
-
- while (!isspace(*p)) p++;
- while (isspace(*p)) p++;
- sscanf(p, "%f", &vloc[vi].y);
-
- while (!isspace(*p)) p++;
- while (isspace(*p)) p++;
- sscanf(p, "%f", &vloc[vi].z);
-
- float d = vloc[vi].length();
- if (d > radius)
- radius = d;
-
- vi++;
- }
-
- else if (line[1] == 'n') {
- const char* p = line + 2;
-
- while (isspace(*p)) p++;
- sscanf(p, "%f", &vnrm[vn].x);
-
- while (!isspace(*p)) p++;
- while (isspace(*p)) p++;
- sscanf(p, "%f", &vnrm[vn].y);
-
- while (!isspace(*p)) p++;
- while (isspace(*p)) p++;
- sscanf(p, "%f", &vnrm[vn].z);
-
- vn++;
- }
-
- else if (line[1] == 't') {
- const char* p = line + 2;
-
- while (isspace(*p)) p++;
- sscanf(p, "%f", &vtu[vt]);
-
- while (!isspace(*p)) p++;
- while (isspace(*p)) p++;
- sscanf(p, "%f", &vtv[vt]);
-
- vtv[vt] = 1.0f - vtv[vt];
-
- vt++;
- }
- }
- }
-
- fseek(fp, 0, SEEK_SET);
-
- // read polys:
- int poly = 0;
- char line[256];
- ObjFace face;
- Material* material = 0;
- int mtl_index = 0;
-
- if (m->NumMaterials())
- material = m->GetMaterials().first();
-
- int current_v = 1;
- int current_vn = 1;
- int current_vt = 1;
- int v = 0; // vset index pointer
-
- while (!feof(fp)) {
- char raw_line[256];
- fgets(raw_line, 256, fp);
-
- strcpy(line, Text(raw_line).trim().data());
-
- if (strstr(line, "usemtl")) {
- material = FindMatl(line + 7, model);
- ListIter<Material> iter = model->GetMaterials();
- while (++iter)
- if (material == iter.value())
- mtl_index = iter.index();
- }
-
- else if (line[0] == 'v') {
- if (line[1] == ' ') current_v++;
- else if (line[1] == 'n') current_vn++;
- else if (line[1] == 't') current_vt++;
- }
-
- else if (line[0] == 'f') {
- ParsePoly(line, &face);
- face.ReverseOrder();
-
- for (int n = 0; n < face.nverts; n++) {
- if (face.v[n] < 0)
- face.v[n] += current_v;
-
- if (face.n[n] < 0)
- face.n[n] += current_vn;
-
- if (face.t[n] < 0)
- face.t[n] += current_vt;
- }
-
- if (face.nverts > 4) {
- npolys += face.nverts - 3;
-
- for (int tri = 2; tri < face.nverts; tri++) {
- Poly* p = polys + poly;
- poly++;
-
- p->nverts = 3;
-
- vset->loc[v+0] = vloc[face.v[ tri ] -1];
- vset->loc[v+1] = vloc[face.v[ tri-1 ] -1];
- vset->loc[v+2] = vloc[face.v[ 0] -1];
-
- if (face.n[0] > 0) {
- vset->nrm[v+0] = vnrm[face.n[ tri ] -1];
- vset->nrm[v+1] = vnrm[face.n[ tri-1 ] -1];
- vset->nrm[v+2] = vnrm[face.n[ 0] -1];
- }
- else {
- vset->nrm[v+0] = vloc[v+0]; vset->nrm[v+0].Normalize();
- vset->nrm[v+1] = vloc[v+1]; vset->nrm[v+1].Normalize();
- vset->nrm[v+2] = vloc[v+2]; vset->nrm[v+2].Normalize();
- }
-
- if (face.t[0] > 0) {
- vset->tu[v+0] = vtu[face.t[ tri ] -1];
- vset->tv[v+0] = vtv[face.t[ tri ] -1];
- vset->tu[v+1] = vtu[face.t[ tri-1 ] -1];
- vset->tv[v+1] = vtv[face.t[ tri-1 ] -1];
- vset->tu[v+2] = vtu[face.t[ 0 ] -1];
- vset->tv[v+2] = vtv[face.t[ 0 ] -1];
- }
-
- p->verts[0] = v+0;
- p->verts[1] = v+1;
- p->verts[2] = v+2;
-
- p->material = material;
- p->sortval = mtl_index;
- p->vertex_set = vset;
-
- p->plane = Plane(vset->loc[p->verts[0]],
- vset->loc[p->verts[2]],
- vset->loc[p->verts[1]]);
-
- v += p->nverts;
- }
- }
-
- else if (face.nverts == 3 || face.nverts == 4) {
- Poly* p = polys + poly;
- poly++;
-
- p->nverts = face.nverts;
-
- bool flat = true;
- int first = v;
-
- for (int i = 0; i < p->nverts; i++) {
- int face_index = i;
-
- vset->loc[v] = vloc[face.v[face_index]-1];
-
- if (face.n[face_index] > 0)
- vset->nrm[v] = vnrm[face.n[face_index]-1];
- else
- vset->nrm[v] = vset->loc[v];
-
- vset->nrm[v].Normalize();
-
- if (vset->nrm[v] != vset->nrm[first])
- flat = false;
-
- if (face.t[face_index] > 0) {
- vset->tu[v] = vtu [face.t[face_index]-1];
- vset->tv[v] = vtv [face.t[face_index]-1];
- }
-
- p->verts[i] = v++;
- }
-
- p->material = material;
- p->sortval = mtl_index;
- p->flatness = flat ? 1.0f : 0.0f;
-
- if (p->nverts == 3)
- surface->AddIndices(3);
-
- else if (p->nverts == 4)
- surface->AddIndices(6);
-
- p->vertex_set = vset;
- p->plane = Plane(vset->loc[p->verts[0]],
- vset->loc[p->verts[2]],
- vset->loc[p->verts[1]]);
- }
-
- if (poly >= npolys)
- break;
- }
- }
-
- // sort the polys by material index:
- qsort((void*) polys, npolys, sizeof(Poly), mcomp);
-
- // then assign them to cohesive segments:
- Segment* segment = 0;
-
- for (int n = 0; n < npolys; n++) {
- if (segment && segment->material == polys[n].material) {
- segment->npolys++;
- }
- else {
- segment = 0;
- }
-
- if (!segment) {
- segment = new Segment;
-
- segment->npolys = 1;
- segment->polys = &polys[n];
- segment->material = segment->polys->material;
-
- surface->GetSegments().append(segment);
- }
- }
-
- delete [] vloc;
- delete [] vnrm;
- delete [] vtu;
- delete [] vtv;
-
- *pnverts = nverts;
- *pnpolys = npolys;
- *pradius = radius;
-
- fclose(fp);
-
- m->Normalize();
- return true;
- }
-
- return false;
-}
-
-// +--------------------------------------------------------------------+
-
-static bool
-SaveWaveFrontMatLib(const char* path, const char* root, Model* model)
-{
- char filename[256];
- sprintf(filename, "%s%s.mtl", path, root);
-
- FILE* f = fopen(filename, "w");
- if (f) {
- fprintf(f, "#\n# %s Material Library exported by Magic 2.0\n#\n\n", root);
-
- ListIter<Material> iter = model->GetMaterials();
- while (++iter) {
- Material* mtl = iter.value();
-
- fprintf(f, "newmtl %s\n", mtl->name);
- fprintf(f, "Ka %.5f %.5f %.5f\n", mtl->Ka.Red(), mtl->Ka.Green(), mtl->Ka.Blue());
- fprintf(f, "Kd %.5f %.5f %.5f\n", mtl->Kd.Red(), mtl->Kd.Green(), mtl->Kd.Blue());
- fprintf(f, "Ks %.5f %.5f %.5f\n", mtl->Ks.Red(), mtl->Ks.Green(), mtl->Ks.Blue());
- fprintf(f, "Ns %.5f\n", mtl->power);
- fprintf(f, "illum 2\n");
- if (mtl->tex_diffuse)
- fprintf(f, "map_Kd %s\n", mtl->tex_diffuse->GetFilename());
- fprintf(f, "\n");
- }
-
- fclose(f);
- return true;
- }
-
- return false;
-}
-
-bool
-ModelFileOBJ::Save(Model* m)
-{
- if (m) {
- ModelFile::Save(m);
- char pathname[256];
- char rootname[256];
-
- ZeroMemory(pathname, sizeof(pathname));
- ZeroMemory(rootname, sizeof(rootname));
-
- const char* ext = strstr(filename, ".obj");
- if (!ext)
- ext = strstr(filename, ".OBJ");
-
- const char* sep = strrchr(filename, '/');
- if (!sep)
- sep = strrchr(filename, '\\');
-
- const char* src = filename;
- char* dst = pathname;
-
- if (sep) {
- while (src != sep)
- *dst++ = *src++;
- *dst++ = *src++;
- }
-
- if (ext) {
- dst = rootname;
- while (src != ext)
- *dst++ = *src++;
- }
- else {
- strcpy(rootname, src);
- }
-
- strcpy(filename, pathname);
- strcat(filename, rootname);
- strcat(filename, ".obj");
-
- FILE* f = fopen(filename, "w");
- if (!f) {
- ::MessageBox(0, "Export Failed: Magic could not open the file for writing", "ERROR", MB_OK);
- return false;
- }
-
- fprintf(f, "# Wavefront OBJ exported by Magic 2.0\n\n");
- fprintf(f, "mtllib %s.mtl\n", rootname);
-
- ListIter<Surface> s_iter = m->GetSurfaces();
-
- // vertex locations
- fprintf(f, "\n# VERTEX LOCATIONS: %d\n", m->NumVerts());
- while (++s_iter) {
- Surface* s = s_iter.value();
- VertexSet* vset = s->GetVertexSet();
-
- for (int n = 0; n < vset->nverts; n++) {
- fprintf(f, "v %12.5f %12.5f %12.5f\n",
- vset->loc[n].x,
- vset->loc[n].y,
- vset->loc[n].z);
- }
- }
-
- s_iter.reset();
-
- // vertex normals
- fprintf(f, "\n# VERTEX NORMALS: %d\n", m->NumVerts());
- while (++s_iter) {
- Surface* s = s_iter.value();
- VertexSet* vset = s->GetVertexSet();
-
- for (int n = 0; n < vset->nverts; n++) {
- fprintf(f, "vn %8.3f %8.3f %8.3f\n",
- vset->nrm[n].x,
- vset->nrm[n].y,
- vset->nrm[n].z);
- }
- }
-
- s_iter.reset();
-
- // texture coordinates
- fprintf(f, "\n# TEXTURE COORDINATES: %d\n", m->NumVerts());
- while (++s_iter) {
- Surface* s = s_iter.value();
- VertexSet* vset = s->GetVertexSet();
-
- for (int n = 0; n < vset->nverts; n++) {
- fprintf(f, "vt %8.3f %8.3f\n",
- vset->tu[n], 1 - vset->tv[n]);
- }
- }
-
- s_iter.reset();
-
- // faces
- Material* current_material = 0;
-
- fprintf(f, "\n# FACES: %d\n", m->NumPolys());
- while (++s_iter) {
- Surface* s = s_iter.value();
-
- for (int n = 0; n < s->NumPolys(); n++) {
- const Poly* p = s->GetPolys() + n;
- int nv = p->nverts;
- Material* mtl = p->material;
-
- if (current_material != mtl) {
- fprintf(f, "\n\nusemtl %s\n", mtl->name);
- current_material = mtl;
- }
-
- fprintf(f, "\nf ");
- for (int v = nv-1; v >= 0; v--) {
- fprintf(f, "%d/%d/%d ",
- p->verts[v] + 1,
- p->verts[v] + 1,
- p->verts[v] + 1);
- }
- }
- }
-
- fprintf(f, "\n\n\n# END OF FILE.\n");
- fclose(f);
-
- return SaveWaveFrontMatLib(pathname, rootname, m);
- }
-
- return false;
-}
-
-// +--------------------------------------------------------------------+
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: ModelFileOBJ.cpp
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ File loader for Wavefront/OBJ format models
+*/
+
+#include "stdafx.h"
+#include "Magic.h"
+#include "MagicDoc.h"
+#include "ModelFileOBJ.h"
+
+#include "Bitmap.h"
+#include "Polygon.h"
+#include "List.h"
+#include "Text.h"
+
+// +--------------------------------------------------------------------+
+
+ModelFileOBJ::ModelFileOBJ(const char* fname)
+ : ModelFile(fname)
+{
+}
+
+ModelFileOBJ::~ModelFileOBJ()
+{
+}
+
+// +--------------------------------------------------------------------+
+
+const int MAX_OBJ_FACE_VERTS = 32;
+
+struct ObjFace {
+ int v[MAX_OBJ_FACE_VERTS];
+ int n[MAX_OBJ_FACE_VERTS];
+ int t[MAX_OBJ_FACE_VERTS];
+
+ int nverts;
+
+ ObjFace() {
+ nverts = 0;
+
+ for (int i = 0; i < MAX_OBJ_FACE_VERTS; i++)
+ v[i] = n[i] = t[i] = 0;
+ }
+
+ ObjFace(const ObjFace& f) {
+ nverts = f.nverts;
+
+ for (int i = 0; i < MAX_OBJ_FACE_VERTS; i++) {
+ v[i] = f.v[i];
+ n[i] = f.n[i];
+ t[i] = f.t[i];
+ }
+ }
+
+ void ReverseOrder() {
+ int i, tmp[MAX_OBJ_FACE_VERTS];
+
+ for (i = 0; i < nverts; i++) tmp[i] = v[i];
+ for (i = 0; i < nverts; i++) v[i] = tmp[nverts-1-i];
+
+ for (i = 0; i < nverts; i++) tmp[i] = n[i];
+ for (i = 0; i < nverts; i++) n[i] = tmp[nverts-1-i];
+
+ for (i = 0; i < nverts; i++) tmp[i] = t[i];
+ for (i = 0; i < nverts; i++) t[i] = tmp[nverts-1-i];
+ }
+};
+
+static void ParsePoly(const char* line, ObjFace* face)
+{
+ int v[MAX_OBJ_FACE_VERTS];
+ int n[MAX_OBJ_FACE_VERTS];
+ int t[MAX_OBJ_FACE_VERTS];
+
+ for (int i = 0; i < MAX_OBJ_FACE_VERTS; i++) {
+ v[i] = n[i] = t[i] = 0;
+ }
+
+ const char* p = line + 1;
+
+ while (isspace(*p))
+ p++;
+
+ int i = 0;
+ while (*p && i < MAX_OBJ_FACE_VERTS) {
+ int factor = 1;
+
+ if (*p == '-') {
+ factor = -1;
+ p++;
+ }
+
+ while (isdigit(*p)) {
+ v[i] = v[i]*10 + *p - '0';
+ p++;
+ }
+ v[i] *= factor;
+
+ if (*p == '/') { p++; // slash one
+
+ factor = 1;
+
+ if (*p == '-') {
+ factor = -1;
+ p++;
+ }
+
+ while (isdigit(*p)) {
+ t[i] = t[i]*10 + *p - '0';
+ p++;
+ }
+ t[i] *= factor;
+
+ if (*p == '/') { p++; // slash two
+
+ factor = 1;
+
+ if (*p == '-') {
+ factor = -1;
+ p++;
+ }
+
+ while (isdigit(*p)) {
+ n[i] = n[i]*10 + *p - '0';
+ p++;
+ }
+ n[i] *= factor;
+ }}
+
+ while (isspace(*p)) p++;
+ i++;
+ }
+
+ face->nverts = i;
+
+ for (i = 0; i < MAX_OBJ_FACE_VERTS; i++) {
+ face->v[i] = v[i];
+ face->n[i] = n[i];
+ face->t[i] = t[i];
+ }
+}
+
+static int LoadMatls(const char* lpszPathName, Model* m)
+{
+ int nmatls = 0;
+
+ FILE* fp = fopen(lpszPathName, "r");
+ if (!fp) {
+ ::MessageBox(0, "Open Failed: could not open file", "ERROR", MB_OK);
+ return 0;
+ }
+
+ Material* mtl = 0;
+
+ while (!feof(fp)) {
+ char raw_line[512];
+ char line[512];
+ fgets(raw_line, 512, fp);
+
+ strcpy(line, Text(raw_line).trim().data());
+
+ if (strstr(line, "newmtl")) {
+ mtl = new Material;
+ strncpy(mtl->name, line+7, Material::NAMELEN - 1);
+
+ m->GetMaterials().append(mtl);
+ }
+
+ else if (line[0] == 'K' && line[1] == 'a') {
+ float r,g,b;
+ sscanf(line, "Ka %f %f %f", &r, &g, &b);
+ mtl->Ka = ColorValue(r,g,b);
+
+ mtl->ambient_value = 1.0f;
+ mtl->ambient_color = mtl->Ka.ToColor();
+ }
+
+ else if (line[0] == 'K' && line[1] == 'd') {
+ float r,g,b;
+ sscanf(line, "Kd %f %f %f", &r, &g, &b);
+ mtl->Kd = ColorValue(r,g,b);
+
+ mtl->diffuse_value = 1.0f;
+ mtl->diffuse_color = mtl->Kd.ToColor();
+ }
+
+ else if (line[0] == 'K' && line[1] == 's') {
+ float r,g,b;
+ sscanf(line, "Ks %f %f %f", &r, &g, &b);
+ mtl->Ks = ColorValue(r,g,b);
+
+ mtl->specular_value = 1.0f;
+ mtl->specular_color = mtl->Ks.ToColor();
+ }
+
+ else if (line[0] == 'N' && line[1] == 's') {
+ float ns;
+ sscanf(line, "Ns %f", &ns);
+ mtl->power = ns;
+ }
+
+ else if (strstr(line, "map_Kd")) {
+ const char* src = strstr(line, "map_Kd") + 7;
+ while (!isalnum(*src)) src++;
+
+ LoadTexture(src, mtl->tex_diffuse, Bitmap::BMP_SOLID);
+ }
+ }
+
+ fclose(fp);
+ return nmatls;
+}
+
+static Material* FindMatl(const char* mtl_name, Model* model)
+{
+ ListIter<Material> iter = model->GetMaterials();
+ while (++iter) {
+ Material* m = iter.value();
+ if (!strcmp(m->name, mtl_name))
+ return m;
+ }
+
+ return 0;
+}
+
+// +--------------------------------------------------------------------+
+
+static int mcomp(const void* a, const void* b)
+{
+ Poly* pa = (Poly*) a;
+ Poly* pb = (Poly*) b;
+
+ if (pa->sortval == pb->sortval)
+ return 0;
+
+ if (pa->sortval < pb->sortval)
+ return 1;
+
+ return -1;
+}
+
+bool
+ModelFileOBJ::Load(Model* m, double scale)
+{
+ if (m && scale > 0 && strlen(filename) > 0) {
+ ModelFile::Load(m, scale);
+
+ FILE* fp = fopen(filename, "rb");
+
+ if (fp == NULL) {
+ ::MessageBox(0, "Wavefront/OBJ Import Failed: Unable to open file", "ERROR", MB_OK);
+ return false;
+ }
+
+ // ok, now start reading the data:
+ int ntex = 0;
+ int nverts = 0;
+ int npv = 0;
+ int npolys = 0;
+ int vi = 0;
+ int vn = 0;
+ int vt = 0;
+
+ char root_path[256];
+ ZeroMemory(root_path, 256);
+
+ if (strrchr(filename, '\\')) {
+ strcpy(root_path, filename);
+ char* p = strrchr(root_path, '\\');
+ if (p)
+ *(p+1) = 0;
+ }
+
+ else if (strrchr(filename, '/')) {
+ strcpy(root_path, filename);
+ char* p = strrchr(root_path, '/');
+ if (p)
+ *(p+1) = 0;
+ }
+
+ // count verts and polys:
+ while (!feof(fp)) {
+ char line[256];
+ fgets(line, 255, fp);
+
+ if (line[0] == 'v') {
+ switch (line[1]) {
+ case ' ': vi++; break;
+ case 'n': vn++; break;
+ case 't': vt++; break;
+ }
+ }
+
+ else if (line[0] == 'f' && line[1] == ' ') {
+ npolys++;
+
+ ObjFace f;
+ ParsePoly(line, &f);
+ f.ReverseOrder();
+
+ npv += f.nverts;
+ }
+
+ else if (strstr(line, "mtllib")) {
+ const char* libname = strstr(line, "mtllib");
+ libname += 7;
+ while (isspace(*libname))
+ libname++;
+
+ char libpath[256];
+ strcpy(libpath, root_path);
+ strcat(libpath, libname);
+ int n = strlen(libpath);
+ if (n > 0) {
+ char* p = &libpath[n-1];
+ while (isspace(*p)) *p-- = 0;
+ }
+
+ int nmatls = LoadMatls(libpath, model);
+ }
+ }
+
+ nverts = npv;
+ if (vi > nverts) nverts = vi;
+ if (vn > nverts) nverts = vn;
+ if (vt > nverts) nverts = vt;
+
+ if (nverts > Model::MAX_VERTS || npolys > Model::MAX_POLYS) {
+ ::MessageBox(0, "Wavefront/OBJ Import Failed: that model is just too darn complicated!", "ERROR", MB_OK);
+ return false;
+ }
+
+ vi = 0;
+ vn = 0;
+ vt = 0;
+
+ fseek(fp, 0, SEEK_SET);
+
+ Surface* surface = new Surface;
+ m->GetSurfaces().append(surface);
+
+ surface->CreateVerts(nverts);
+ surface->CreatePolys(npolys);
+
+ VertexSet* vset = surface->GetVertexSet();
+ Poly* polys = surface->GetPolys();
+
+ // read vertex set:
+ Vec3* vloc = new Vec3[nverts];
+ Vec3* vnrm = new Vec3[nverts];
+ float* vtu = new float[nverts];
+ float* vtv = new float[nverts];
+
+ float radius = 0;
+
+ while (!feof(fp)) {
+ char line[256];
+ fgets(line, 255, fp);
+
+ if (line[0] == 'v') {
+ if (line[1] == ' ') {
+ const char* p = line + 2;
+
+ while (isspace(*p)) p++;
+ sscanf(p, "%f", &vloc[vi].x);
+
+ while (!isspace(*p)) p++;
+ while (isspace(*p)) p++;
+ sscanf(p, "%f", &vloc[vi].y);
+
+ while (!isspace(*p)) p++;
+ while (isspace(*p)) p++;
+ sscanf(p, "%f", &vloc[vi].z);
+
+ float d = vloc[vi].length();
+ if (d > radius)
+ radius = d;
+
+ vi++;
+ }
+
+ else if (line[1] == 'n') {
+ const char* p = line + 2;
+
+ while (isspace(*p)) p++;
+ sscanf(p, "%f", &vnrm[vn].x);
+
+ while (!isspace(*p)) p++;
+ while (isspace(*p)) p++;
+ sscanf(p, "%f", &vnrm[vn].y);
+
+ while (!isspace(*p)) p++;
+ while (isspace(*p)) p++;
+ sscanf(p, "%f", &vnrm[vn].z);
+
+ vn++;
+ }
+
+ else if (line[1] == 't') {
+ const char* p = line + 2;
+
+ while (isspace(*p)) p++;
+ sscanf(p, "%f", &vtu[vt]);
+
+ while (!isspace(*p)) p++;
+ while (isspace(*p)) p++;
+ sscanf(p, "%f", &vtv[vt]);
+
+ vtv[vt] = 1.0f - vtv[vt];
+
+ vt++;
+ }
+ }
+ }
+
+ fseek(fp, 0, SEEK_SET);
+
+ // read polys:
+ int poly = 0;
+ char line[256];
+ ObjFace face;
+ Material* material = 0;
+ int mtl_index = 0;
+
+ if (m->NumMaterials())
+ material = m->GetMaterials().first();
+
+ int current_v = 1;
+ int current_vn = 1;
+ int current_vt = 1;
+ int v = 0; // vset index pointer
+
+ while (!feof(fp)) {
+ char raw_line[256];
+ fgets(raw_line, 256, fp);
+
+ strcpy(line, Text(raw_line).trim().data());
+
+ if (strstr(line, "usemtl")) {
+ material = FindMatl(line + 7, model);
+ ListIter<Material> iter = model->GetMaterials();
+ while (++iter)
+ if (material == iter.value())
+ mtl_index = iter.index();
+ }
+
+ else if (line[0] == 'v') {
+ if (line[1] == ' ') current_v++;
+ else if (line[1] == 'n') current_vn++;
+ else if (line[1] == 't') current_vt++;
+ }
+
+ else if (line[0] == 'f') {
+ ParsePoly(line, &face);
+ face.ReverseOrder();
+
+ for (int n = 0; n < face.nverts; n++) {
+ if (face.v[n] < 0)
+ face.v[n] += current_v;
+
+ if (face.n[n] < 0)
+ face.n[n] += current_vn;
+
+ if (face.t[n] < 0)
+ face.t[n] += current_vt;
+ }
+
+ if (face.nverts > 4) {
+ npolys += face.nverts - 3;
+
+ for (int tri = 2; tri < face.nverts; tri++) {
+ Poly* p = polys + poly;
+ poly++;
+
+ p->nverts = 3;
+
+ vset->loc[v+0] = vloc[face.v[ tri ] -1];
+ vset->loc[v+1] = vloc[face.v[ tri-1 ] -1];
+ vset->loc[v+2] = vloc[face.v[ 0] -1];
+
+ if (face.n[0] > 0) {
+ vset->nrm[v+0] = vnrm[face.n[ tri ] -1];
+ vset->nrm[v+1] = vnrm[face.n[ tri-1 ] -1];
+ vset->nrm[v+2] = vnrm[face.n[ 0] -1];
+ }
+ else {
+ vset->nrm[v+0] = vloc[v+0]; vset->nrm[v+0].Normalize();
+ vset->nrm[v+1] = vloc[v+1]; vset->nrm[v+1].Normalize();
+ vset->nrm[v+2] = vloc[v+2]; vset->nrm[v+2].Normalize();
+ }
+
+ if (face.t[0] > 0) {
+ vset->tu[v+0] = vtu[face.t[ tri ] -1];
+ vset->tv[v+0] = vtv[face.t[ tri ] -1];
+ vset->tu[v+1] = vtu[face.t[ tri-1 ] -1];
+ vset->tv[v+1] = vtv[face.t[ tri-1 ] -1];
+ vset->tu[v+2] = vtu[face.t[ 0 ] -1];
+ vset->tv[v+2] = vtv[face.t[ 0 ] -1];
+ }
+
+ p->verts[0] = v+0;
+ p->verts[1] = v+1;
+ p->verts[2] = v+2;
+
+ p->material = material;
+ p->sortval = mtl_index;
+ p->vertex_set = vset;
+
+ p->plane = Plane(vset->loc[p->verts[0]],
+ vset->loc[p->verts[2]],
+ vset->loc[p->verts[1]]);
+
+ v += p->nverts;
+ }
+ }
+
+ else if (face.nverts == 3 || face.nverts == 4) {
+ Poly* p = polys + poly;
+ poly++;
+
+ p->nverts = face.nverts;
+
+ bool flat = true;
+ int first = v;
+
+ for (int i = 0; i < p->nverts; i++) {
+ int face_index = i;
+
+ vset->loc[v] = vloc[face.v[face_index]-1];
+
+ if (face.n[face_index] > 0)
+ vset->nrm[v] = vnrm[face.n[face_index]-1];
+ else
+ vset->nrm[v] = vset->loc[v];
+
+ vset->nrm[v].Normalize();
+
+ if (vset->nrm[v] != vset->nrm[first])
+ flat = false;
+
+ if (face.t[face_index] > 0) {
+ vset->tu[v] = vtu [face.t[face_index]-1];
+ vset->tv[v] = vtv [face.t[face_index]-1];
+ }
+
+ p->verts[i] = v++;
+ }
+
+ p->material = material;
+ p->sortval = mtl_index;
+ p->flatness = flat ? 1.0f : 0.0f;
+
+ if (p->nverts == 3)
+ surface->AddIndices(3);
+
+ else if (p->nverts == 4)
+ surface->AddIndices(6);
+
+ p->vertex_set = vset;
+ p->plane = Plane(vset->loc[p->verts[0]],
+ vset->loc[p->verts[2]],
+ vset->loc[p->verts[1]]);
+ }
+
+ if (poly >= npolys)
+ break;
+ }
+ }
+
+ // sort the polys by material index:
+ qsort((void*) polys, npolys, sizeof(Poly), mcomp);
+
+ // then assign them to cohesive segments:
+ Segment* segment = 0;
+
+ for (int n = 0; n < npolys; n++) {
+ if (segment && segment->material == polys[n].material) {
+ segment->npolys++;
+ }
+ else {
+ segment = 0;
+ }
+
+ if (!segment) {
+ segment = new Segment;
+
+ segment->npolys = 1;
+ segment->polys = &polys[n];
+ segment->material = segment->polys->material;
+
+ surface->GetSegments().append(segment);
+ }
+ }
+
+ delete [] vloc;
+ delete [] vnrm;
+ delete [] vtu;
+ delete [] vtv;
+
+ *pnverts = nverts;
+ *pnpolys = npolys;
+ *pradius = radius;
+
+ fclose(fp);
+
+ m->Normalize();
+ return true;
+ }
+
+ return false;
+}
+
+// +--------------------------------------------------------------------+
+
+static bool
+SaveWaveFrontMatLib(const char* path, const char* root, Model* model)
+{
+ char filename[256];
+ sprintf(filename, "%s%s.mtl", path, root);
+
+ FILE* f = fopen(filename, "w");
+ if (f) {
+ fprintf(f, "#\n# %s Material Library exported by Magic 2.0\n#\n\n", root);
+
+ ListIter<Material> iter = model->GetMaterials();
+ while (++iter) {
+ Material* mtl = iter.value();
+
+ fprintf(f, "newmtl %s\n", mtl->name);
+ fprintf(f, "Ka %.5f %.5f %.5f\n", mtl->Ka.Red(), mtl->Ka.Green(), mtl->Ka.Blue());
+ fprintf(f, "Kd %.5f %.5f %.5f\n", mtl->Kd.Red(), mtl->Kd.Green(), mtl->Kd.Blue());
+ fprintf(f, "Ks %.5f %.5f %.5f\n", mtl->Ks.Red(), mtl->Ks.Green(), mtl->Ks.Blue());
+ fprintf(f, "Ns %.5f\n", mtl->power);
+ fprintf(f, "illum 2\n");
+ if (mtl->tex_diffuse)
+ fprintf(f, "map_Kd %s\n", mtl->tex_diffuse->GetFilename());
+ fprintf(f, "\n");
+ }
+
+ fclose(f);
+ return true;
+ }
+
+ return false;
+}
+
+bool
+ModelFileOBJ::Save(Model* m)
+{
+ if (m) {
+ ModelFile::Save(m);
+ char pathname[256];
+ char rootname[256];
+
+ ZeroMemory(pathname, sizeof(pathname));
+ ZeroMemory(rootname, sizeof(rootname));
+
+ const char* ext = strstr(filename, ".obj");
+ if (!ext)
+ ext = strstr(filename, ".OBJ");
+
+ const char* sep = strrchr(filename, '/');
+ if (!sep)
+ sep = strrchr(filename, '\\');
+
+ const char* src = filename;
+ char* dst = pathname;
+
+ if (sep) {
+ while (src != sep)
+ *dst++ = *src++;
+ *dst++ = *src++;
+ }
+
+ if (ext) {
+ dst = rootname;
+ while (src != ext)
+ *dst++ = *src++;
+ }
+ else {
+ strcpy(rootname, src);
+ }
+
+ strcpy(filename, pathname);
+ strcat(filename, rootname);
+ strcat(filename, ".obj");
+
+ FILE* f = fopen(filename, "w");
+ if (!f) {
+ ::MessageBox(0, "Export Failed: Magic could not open the file for writing", "ERROR", MB_OK);
+ return false;
+ }
+
+ fprintf(f, "# Wavefront OBJ exported by Magic 2.0\n\n");
+ fprintf(f, "mtllib %s.mtl\n", rootname);
+
+ ListIter<Surface> s_iter = m->GetSurfaces();
+
+ // vertex locations
+ fprintf(f, "\n# VERTEX LOCATIONS: %d\n", m->NumVerts());
+ while (++s_iter) {
+ Surface* s = s_iter.value();
+ VertexSet* vset = s->GetVertexSet();
+
+ for (int n = 0; n < vset->nverts; n++) {
+ fprintf(f, "v %12.5f %12.5f %12.5f\n",
+ vset->loc[n].x,
+ vset->loc[n].y,
+ vset->loc[n].z);
+ }
+ }
+
+ s_iter.reset();
+
+ // vertex normals
+ fprintf(f, "\n# VERTEX NORMALS: %d\n", m->NumVerts());
+ while (++s_iter) {
+ Surface* s = s_iter.value();
+ VertexSet* vset = s->GetVertexSet();
+
+ for (int n = 0; n < vset->nverts; n++) {
+ fprintf(f, "vn %8.3f %8.3f %8.3f\n",
+ vset->nrm[n].x,
+ vset->nrm[n].y,
+ vset->nrm[n].z);
+ }
+ }
+
+ s_iter.reset();
+
+ // texture coordinates
+ fprintf(f, "\n# TEXTURE COORDINATES: %d\n", m->NumVerts());
+ while (++s_iter) {
+ Surface* s = s_iter.value();
+ VertexSet* vset = s->GetVertexSet();
+
+ for (int n = 0; n < vset->nverts; n++) {
+ fprintf(f, "vt %8.3f %8.3f\n",
+ vset->tu[n], 1 - vset->tv[n]);
+ }
+ }
+
+ s_iter.reset();
+
+ // faces
+ Material* current_material = 0;
+
+ fprintf(f, "\n# FACES: %d\n", m->NumPolys());
+ while (++s_iter) {
+ Surface* s = s_iter.value();
+
+ for (int n = 0; n < s->NumPolys(); n++) {
+ const Poly* p = s->GetPolys() + n;
+ int nv = p->nverts;
+ Material* mtl = p->material;
+
+ if (current_material != mtl) {
+ fprintf(f, "\n\nusemtl %s\n", mtl->name);
+ current_material = mtl;
+ }
+
+ fprintf(f, "\nf ");
+ for (int v = nv-1; v >= 0; v--) {
+ fprintf(f, "%d/%d/%d ",
+ p->verts[v] + 1,
+ p->verts[v] + 1,
+ p->verts[v] + 1);
+ }
+ }
+ }
+
+ fprintf(f, "\n\n\n# END OF FILE.\n");
+ fclose(f);
+
+ return SaveWaveFrontMatLib(pathname, rootname, m);
+ }
+
+ return false;
+}
+
+// +--------------------------------------------------------------------+
diff --git a/Magic2/ModelFileOBJ.h b/Magic2/ModelFileOBJ.h
index 1fe123b..3c13a45 100644
--- a/Magic2/ModelFileOBJ.h
+++ b/Magic2/ModelFileOBJ.h
@@ -1,37 +1,61 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: ModelFileOBJ.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- File loader for Wavefront/OBJ format models
-*/
-
-#ifndef ModelFileOBJ_h
-#define ModelFileOBJ_h
-
-#include "Solid.h"
-
-// +--------------------------------------------------------------------+
-
-class ModelFileOBJ : public ModelFile
-{
-public:
- ModelFileOBJ(const char* fname);
- virtual ~ModelFileOBJ();
-
- virtual bool Load(Model* m, double scale=1.0);
- virtual bool Save(Model* m);
-
-protected:
-};
-
-// +--------------------------------------------------------------------+
-
-#endif ModelFileOBJ_h
-
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: ModelFileOBJ.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ File loader for Wavefront/OBJ format models
+*/
+
+#ifndef ModelFileOBJ_h
+#define ModelFileOBJ_h
+
+#include "Solid.h"
+
+// +--------------------------------------------------------------------+
+
+class ModelFileOBJ : public ModelFile
+{
+public:
+ ModelFileOBJ(const char* fname);
+ virtual ~ModelFileOBJ();
+
+ virtual bool Load(Model* m, double scale=1.0);
+ virtual bool Save(Model* m);
+
+protected:
+};
+
+// +--------------------------------------------------------------------+
+
+#endif ModelFileOBJ_h
+
diff --git a/Magic2/ModelView.cpp b/Magic2/ModelView.cpp
index 21feaa8..68ab304 100644
--- a/Magic2/ModelView.cpp
+++ b/Magic2/ModelView.cpp
@@ -1,417 +1,441 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: ModelView.cpp
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Implementation of the ModelView class
-*/
-
-#include "stdafx.h"
-#include "Magic.h"
-
-#include "MagicDoc.h"
-#include "ModelView.h"
-#include "Grid.h"
-#include "Selector.h"
-#include "Selection.h"
-
-#include "ActiveWindow.h"
-#include "Color.h"
-#include "Light.h"
-#include "Scene.h"
-#include "Screen.h"
-#include "Shadow.h"
-#include "Solid.h"
-#include "Video.h"
-
-DWORD GetRealTime();
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
-#endif
-
-static ModelView* views[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-
-// +--------------------------------------------------------------------+
-
-ModelView::ModelView(Window* c, Scene* s, DWORD m)
- : CameraView(c, 0, s), view_mode(100), fill_mode(FILL_WIRE),
- grid(0), az(-PI/4), el(PI/4)
-{
- UseCamera(&cam);
- SetViewMode(m);
-}
-
-ModelView::~ModelView()
-{
- if (views[view_mode] == this)
- views[view_mode] = 0;
-}
-
-// +--------------------------------------------------------------------+
-
-void
-ModelView::SetViewMode(DWORD m)
-{
- if (view_mode != m) {
- view_mode = m;
-
- double x = 1e3 * sin(az) * cos(el);
- double y = 1e3 * cos(az) * cos(el);
- double z = 1e3 * sin(el);
-
- switch (view_mode) {
- case VIEW_PLAN:
- cam.LookAt(Point(0,0,0),
- Point(0,1e3,0),
- Point(0,0,1));
- SetProjectionType(Video::PROJECTION_ORTHOGONAL);
- SetFieldOfView(1.75);
- break;
-
- case VIEW_FRONT:
- cam.LookAt(Point(0,0,0),
- Point(0,0,1e3),
- Point(0,1,0));
- SetProjectionType(Video::PROJECTION_ORTHOGONAL);
- SetFieldOfView(1.75);
- break;
-
- case VIEW_SIDE:
- cam.LookAt(Point(0,0,0),
- Point(1e3,0,0),
- Point(0,1,0));
- SetProjectionType(Video::PROJECTION_ORTHOGONAL);
- SetFieldOfView(1.75);
- break;
-
- case VIEW_PROJECT:
- cam.LookAt(Point(0,0,0),
- Point(x,z,y),
- Point(0,1,0));
- SetProjectionType(Video::PROJECTION_PERSPECTIVE);
- SetFieldOfView(1.75);
- break;
- }
-
- views[view_mode] = this;
- }
-}
-
-ModelView*
-ModelView::FindView(DWORD mode)
-{
- if (mode >= 0 && mode < 8)
- return views[mode];
-
- return 0;
-}
-
-// +--------------------------------------------------------------------+
-
-void
-ModelView::MoveTo(Point pos)
-{
- switch (view_mode) {
- case VIEW_PLAN:
- cam.LookAt( pos - Point(0,1e3,0),
- pos,
- Point(0,0,1));
- break;
-
- case VIEW_FRONT:
- cam.LookAt( pos - Point(0,0,1e3),
- pos,
- Point(0,1,0));
- break;
-
- case VIEW_SIDE:
- cam.LookAt( pos - Point(1e3,0,0),
- pos,
- Point(0,1,0));
- break;
- }
-}
-
-void
-ModelView::MoveBy(double dx, double dy)
-{
- Point pos = cam.Pos();
-
- dx *= 2.00/GetFieldOfView();
- dy *= 2.00/GetFieldOfView();
-
- switch (view_mode) {
- case VIEW_PLAN:
- pos.x -= dx;
- pos.z += dy;
-
- cam.LookAt( pos - Point(0,1e3,0),
- pos,
- Point(0,0,1));
- break;
-
- case VIEW_FRONT:
- pos.x += dx;
- pos.y += dy;
-
- cam.LookAt( pos - Point(0,0,1e3),
- pos,
- Point(0,1,0));
- break;
-
- case VIEW_SIDE:
- pos.z -= dx;
- pos.y += dy;
-
- cam.LookAt( pos - Point(1e3,0,0),
- pos,
- Point(0,1,0));
- break;
- }
-}
-
-void
-ModelView::SpinBy(double phi, double theta)
-{
- const double limit = (0.43 * PI);
-
- Point pos = cam.Pos();
- double len = pos.length();
-
- az += phi;
- el += theta;
-
- if (az > PI)
- az = -2*PI + az;
-
- else if (az < -PI)
- az = 2*PI + az;
-
- if (el > limit)
- el = limit;
- else if (el < -limit)
- el = -limit;
-
- double x = len * sin(az) * cos(el);
- double y = len * cos(az) * cos(el);
- double z = len * sin(el);
-
- cam.LookAt(Point(0,0,0), Point(x,z,y), Point(0,1,0));
-}
-
-void
-ModelView::UseGrid(Grid* g)
-{
- grid = g;
-}
-
-void
-ModelView::ZoomNormal()
-{
- DWORD v = view_mode; // remember current view mode
- view_mode = 100; // force set view mode to setup the view
- az = -PI/4; // if this happens to be a perspective view,
- el = PI/4; // reset the spin to the original 3/4ths view
-
- SetViewMode(v); // restore default view params for this mode
-}
-
-// +--------------------------------------------------------------------+
-
-void
-ModelView::RenderScene()
-{
- // activate all lights:
- ListIter<Light> light_iter = scene->Lights();
-
- while (++light_iter) {
- Light* light = light_iter.value();
- light->SetActive(true);
- }
-
- video->SetLights(scene->Lights());
-
- RenderGrid();
-
-
- bool old_shadows = video->IsShadowEnabled();
- bool old_bumps = video->IsBumpMapEnabled();
-
- if (fill_mode != FILL_TEXTURE) {
- video->SetShadowEnabled(false);
- video->SetBumpMapEnabled(false);
- CameraView::RenderScene();
- }
-
- else {
- CameraView::RenderScene();
- }
-
- const char* title = "ModelView";
- switch (view_mode) {
- case VIEW_PLAN: title = "Top"; break;
- case VIEW_FRONT: title = "Front"; break;
- case VIEW_SIDE: title = "Right Side"; break;
- case VIEW_PROJECT: title = "Perspective"; break;
- }
-
- int len = strlen(title);
- Rect r(6,4,200,20);
-
- r.x += window->GetRect().x;
- r.y += window->GetRect().y;
-
- video->DrawText(title, len, r, DT_LEFT|DT_SINGLELINE, Color::Black);
-
- r.x--;
- r.y--;
-
- video->DrawText(title, len, r, DT_LEFT|DT_SINGLELINE, Color::White);
- video->SetShadowEnabled(old_shadows);
- video->SetBumpMapEnabled(old_bumps);
-}
-
-// +--------------------------------------------------------------------+
-
-void
-ModelView::Render(Graphic* g, DWORD flags)
-{
- if (!g)
- return;
-
- if (!strcmp(g->Name(), "Selector")) {
- Selector* selector = (Selector*) g;
-
- if (selector->GetViewMode() != (int) view_mode)
- return;
- }
-
- else if (!strcmp(g->Name(), "Selection")) {
- Selection* selection = (Selection*) g;
- selection->UseView(this);
- }
-
- if (fill_mode == FILL_WIRE) {
- Material m;
- video->UseMaterial(&m);
- video->SetRenderState(Video::Z_ENABLE, FALSE);
-
- if (g->IsSolid()) {
- m.Kd = ColorValue(0.0f, 0.0f, 0.0f, 0.5f);
- m.Ke = ColorValue(0.8f, 0.8f, 0.9f, 1.0f);
- m.blend = Video::BLEND_ALPHA;
- m.luminous = true;
-
- video->SetRenderState(Video::FILL_MODE, Video::FILL_SOLID);
- g->Render(video, flags);
- }
-
- m.Ka = Color::Black;
- m.Kd = Color::Black;
- m.Ks = Color::Black;
- m.Ke = Color::Black;
- m.blend = Video::BLEND_SOLID;
-
- video->SetRenderState(Video::FILL_MODE, Video::FILL_WIREFRAME);
-
- g->Render(video, flags);
- video->UseMaterial(0);
- }
-
- else if (fill_mode == FILL_SOLID) {
- if (g->IsSolid() && flags != Graphic::RENDER_SOLID)
- return;
-
- Material m;
- video->UseMaterial(&m);
- video->SetRenderState(Video::Z_ENABLE, TRUE);
-
- m.Kd = ColorValue(0.5f, 0.5f, 0.5f, 1.0f);
- m.blend = Video::BLEND_SOLID;
-
- video->SetRenderState(Video::FILL_MODE, Video::FILL_SOLID);
-
- if (g->IsSolid()) {
- MarkVisibleLights(g, flags);
- video->SetLights(scene->Lights());
- }
-
- g->Render(video, flags);
- video->UseMaterial(0);
- }
-
- else if (fill_mode == FILL_TEXTURE) {
- video->SetRenderState(Video::Z_ENABLE, TRUE);
- video->UseMaterial(0);
-
- if (g->IsSolid()) {
- MarkVisibleLights(g, flags);
- video->SetLights(scene->Lights());
- }
-
- g->Render(video, flags);
- }
-}
-
-void
-ModelView::RenderGrid()
-{
- if (!grid || !grid->IsShow())
- return;
-
- int plane = Grid::GRID_XZ;
-
- if (view_mode == VIEW_FRONT)
- plane = Grid::GRID_XY;
-
- else if (view_mode == VIEW_SIDE)
- plane = Grid::GRID_YZ;
-
- grid->ShowPlane(plane);
- grid->MoveTo(camera_loc * -1);
- grid->ShowReference(view_mode != VIEW_PROJECT);
- grid->Render(video, Graphic::RENDER_SOLID);
-
- video->SetRenderState(Video::Z_ENABLE, TRUE);
- video->SetRenderState(Video::LIGHTING_ENABLE, TRUE);
- video->UseMaterial(0);
-}
-
-// +--------------------------------------------------------------------+
-
-CPoint
-ModelView::ProjectPoint(Vec3& p)
-{
- CPoint result;
-
- switch (view_mode) {
- case VIEW_PLAN:
- case VIEW_FRONT:
- case VIEW_SIDE:
- case VIEW_PROJECT: {
- Vec3 pt = p;
- projector.Transform(pt);
- projector.Project(pt, false);
-
- result.x = (LONG) (pt.x + GetWindow()->X());
- result.y = (LONG) (pt.y + GetWindow()->Y());
- }
- break;
-
- default:
- result.x = 0;
- result.y = 0;
- break;
- }
-
- return result;
-}
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: ModelView.cpp
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Implementation of the ModelView class
+*/
+
+#include "stdafx.h"
+#include "Magic.h"
+
+#include "MagicDoc.h"
+#include "ModelView.h"
+#include "Grid.h"
+#include "Selector.h"
+#include "Selection.h"
+
+#include "ActiveWindow.h"
+#include "Color.h"
+#include "Light.h"
+#include "Scene.h"
+#include "Screen.h"
+#include "Shadow.h"
+#include "Solid.h"
+#include "Video.h"
+
+DWORD GetRealTime();
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+static ModelView* views[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+// +--------------------------------------------------------------------+
+
+ModelView::ModelView(Window* c, Scene* s, DWORD m)
+ : CameraView(c, 0, s), view_mode(100), fill_mode(FILL_WIRE),
+ grid(0), az(-PI/4), el(PI/4)
+{
+ UseCamera(&cam);
+ SetViewMode(m);
+}
+
+ModelView::~ModelView()
+{
+ if (views[view_mode] == this)
+ views[view_mode] = 0;
+}
+
+// +--------------------------------------------------------------------+
+
+void
+ModelView::SetViewMode(DWORD m)
+{
+ if (view_mode != m) {
+ view_mode = m;
+
+ double x = 1e3 * sin(az) * cos(el);
+ double y = 1e3 * cos(az) * cos(el);
+ double z = 1e3 * sin(el);
+
+ switch (view_mode) {
+ case VIEW_PLAN:
+ cam.LookAt(Point(0,0,0),
+ Point(0,1e3,0),
+ Point(0,0,1));
+ SetProjectionType(Video::PROJECTION_ORTHOGONAL);
+ SetFieldOfView(1.75);
+ break;
+
+ case VIEW_FRONT:
+ cam.LookAt(Point(0,0,0),
+ Point(0,0,1e3),
+ Point(0,1,0));
+ SetProjectionType(Video::PROJECTION_ORTHOGONAL);
+ SetFieldOfView(1.75);
+ break;
+
+ case VIEW_SIDE:
+ cam.LookAt(Point(0,0,0),
+ Point(1e3,0,0),
+ Point(0,1,0));
+ SetProjectionType(Video::PROJECTION_ORTHOGONAL);
+ SetFieldOfView(1.75);
+ break;
+
+ case VIEW_PROJECT:
+ cam.LookAt(Point(0,0,0),
+ Point(x,z,y),
+ Point(0,1,0));
+ SetProjectionType(Video::PROJECTION_PERSPECTIVE);
+ SetFieldOfView(1.75);
+ break;
+ }
+
+ views[view_mode] = this;
+ }
+}
+
+ModelView*
+ModelView::FindView(DWORD mode)
+{
+ if (mode >= 0 && mode < 8)
+ return views[mode];
+
+ return 0;
+}
+
+// +--------------------------------------------------------------------+
+
+void
+ModelView::MoveTo(Point pos)
+{
+ switch (view_mode) {
+ case VIEW_PLAN:
+ cam.LookAt( pos - Point(0,1e3,0),
+ pos,
+ Point(0,0,1));
+ break;
+
+ case VIEW_FRONT:
+ cam.LookAt( pos - Point(0,0,1e3),
+ pos,
+ Point(0,1,0));
+ break;
+
+ case VIEW_SIDE:
+ cam.LookAt( pos - Point(1e3,0,0),
+ pos,
+ Point(0,1,0));
+ break;
+ }
+}
+
+void
+ModelView::MoveBy(double dx, double dy)
+{
+ Point pos = cam.Pos();
+
+ dx *= 2.00/GetFieldOfView();
+ dy *= 2.00/GetFieldOfView();
+
+ switch (view_mode) {
+ case VIEW_PLAN:
+ pos.x -= dx;
+ pos.z += dy;
+
+ cam.LookAt( pos - Point(0,1e3,0),
+ pos,
+ Point(0,0,1));
+ break;
+
+ case VIEW_FRONT:
+ pos.x += dx;
+ pos.y += dy;
+
+ cam.LookAt( pos - Point(0,0,1e3),
+ pos,
+ Point(0,1,0));
+ break;
+
+ case VIEW_SIDE:
+ pos.z -= dx;
+ pos.y += dy;
+
+ cam.LookAt( pos - Point(1e3,0,0),
+ pos,
+ Point(0,1,0));
+ break;
+ }
+}
+
+void
+ModelView::SpinBy(double phi, double theta)
+{
+ const double limit = (0.43 * PI);
+
+ Point pos = cam.Pos();
+ double len = pos.length();
+
+ az += phi;
+ el += theta;
+
+ if (az > PI)
+ az = -2*PI + az;
+
+ else if (az < -PI)
+ az = 2*PI + az;
+
+ if (el > limit)
+ el = limit;
+ else if (el < -limit)
+ el = -limit;
+
+ double x = len * sin(az) * cos(el);
+ double y = len * cos(az) * cos(el);
+ double z = len * sin(el);
+
+ cam.LookAt(Point(0,0,0), Point(x,z,y), Point(0,1,0));
+}
+
+void
+ModelView::UseGrid(Grid* g)
+{
+ grid = g;
+}
+
+void
+ModelView::ZoomNormal()
+{
+ DWORD v = view_mode; // remember current view mode
+ view_mode = 100; // force set view mode to setup the view
+ az = -PI/4; // if this happens to be a perspective view,
+ el = PI/4; // reset the spin to the original 3/4ths view
+
+ SetViewMode(v); // restore default view params for this mode
+}
+
+// +--------------------------------------------------------------------+
+
+void
+ModelView::RenderScene()
+{
+ // activate all lights:
+ ListIter<Light> light_iter = scene->Lights();
+
+ while (++light_iter) {
+ Light* light = light_iter.value();
+ light->SetActive(true);
+ }
+
+ video->SetLights(scene->Lights());
+
+ RenderGrid();
+
+
+ bool old_shadows = video->IsShadowEnabled();
+ bool old_bumps = video->IsBumpMapEnabled();
+
+ if (fill_mode != FILL_TEXTURE) {
+ video->SetShadowEnabled(false);
+ video->SetBumpMapEnabled(false);
+ CameraView::RenderScene();
+ }
+
+ else {
+ CameraView::RenderScene();
+ }
+
+ const char* title = "ModelView";
+ switch (view_mode) {
+ case VIEW_PLAN: title = "Top"; break;
+ case VIEW_FRONT: title = "Front"; break;
+ case VIEW_SIDE: title = "Right Side"; break;
+ case VIEW_PROJECT: title = "Perspective"; break;
+ }
+
+ int len = strlen(title);
+ Rect r(6,4,200,20);
+
+ r.x += window->GetRect().x;
+ r.y += window->GetRect().y;
+
+ video->DrawText(title, len, r, DT_LEFT|DT_SINGLELINE, Color::Black);
+
+ r.x--;
+ r.y--;
+
+ video->DrawText(title, len, r, DT_LEFT|DT_SINGLELINE, Color::White);
+ video->SetShadowEnabled(old_shadows);
+ video->SetBumpMapEnabled(old_bumps);
+}
+
+// +--------------------------------------------------------------------+
+
+void
+ModelView::Render(Graphic* g, DWORD flags)
+{
+ if (!g)
+ return;
+
+ if (!strcmp(g->Name(), "Selector")) {
+ Selector* selector = (Selector*) g;
+
+ if (selector->GetViewMode() != (int) view_mode)
+ return;
+ }
+
+ else if (!strcmp(g->Name(), "Selection")) {
+ Selection* selection = (Selection*) g;
+ selection->UseView(this);
+ }
+
+ if (fill_mode == FILL_WIRE) {
+ Material m;
+ video->UseMaterial(&m);
+ video->SetRenderState(Video::Z_ENABLE, FALSE);
+
+ if (g->IsSolid()) {
+ m.Kd = ColorValue(0.0f, 0.0f, 0.0f, 0.5f);
+ m.Ke = ColorValue(0.8f, 0.8f, 0.9f, 1.0f);
+ m.blend = Video::BLEND_ALPHA;
+ m.luminous = true;
+
+ video->SetRenderState(Video::FILL_MODE, Video::FILL_SOLID);
+ g->Render(video, flags);
+ }
+
+ m.Ka = Color::Black;
+ m.Kd = Color::Black;
+ m.Ks = Color::Black;
+ m.Ke = Color::Black;
+ m.blend = Video::BLEND_SOLID;
+
+ video->SetRenderState(Video::FILL_MODE, Video::FILL_WIREFRAME);
+
+ g->Render(video, flags);
+ video->UseMaterial(0);
+ }
+
+ else if (fill_mode == FILL_SOLID) {
+ if (g->IsSolid() && flags != Graphic::RENDER_SOLID)
+ return;
+
+ Material m;
+ video->UseMaterial(&m);
+ video->SetRenderState(Video::Z_ENABLE, TRUE);
+
+ m.Kd = ColorValue(0.5f, 0.5f, 0.5f, 1.0f);
+ m.blend = Video::BLEND_SOLID;
+
+ video->SetRenderState(Video::FILL_MODE, Video::FILL_SOLID);
+
+ if (g->IsSolid()) {
+ MarkVisibleLights(g, flags);
+ video->SetLights(scene->Lights());
+ }
+
+ g->Render(video, flags);
+ video->UseMaterial(0);
+ }
+
+ else if (fill_mode == FILL_TEXTURE) {
+ video->SetRenderState(Video::Z_ENABLE, TRUE);
+ video->UseMaterial(0);
+
+ if (g->IsSolid()) {
+ MarkVisibleLights(g, flags);
+ video->SetLights(scene->Lights());
+ }
+
+ g->Render(video, flags);
+ }
+}
+
+void
+ModelView::RenderGrid()
+{
+ if (!grid || !grid->IsShow())
+ return;
+
+ int plane = Grid::GRID_XZ;
+
+ if (view_mode == VIEW_FRONT)
+ plane = Grid::GRID_XY;
+
+ else if (view_mode == VIEW_SIDE)
+ plane = Grid::GRID_YZ;
+
+ grid->ShowPlane(plane);
+ grid->MoveTo(camera_loc * -1);
+ grid->ShowReference(view_mode != VIEW_PROJECT);
+ grid->Render(video, Graphic::RENDER_SOLID);
+
+ video->SetRenderState(Video::Z_ENABLE, TRUE);
+ video->SetRenderState(Video::LIGHTING_ENABLE, TRUE);
+ video->UseMaterial(0);
+}
+
+// +--------------------------------------------------------------------+
+
+CPoint
+ModelView::ProjectPoint(Vec3& p)
+{
+ CPoint result;
+
+ switch (view_mode) {
+ case VIEW_PLAN:
+ case VIEW_FRONT:
+ case VIEW_SIDE:
+ case VIEW_PROJECT: {
+ Vec3 pt = p;
+ projector.Transform(pt);
+ projector.Project(pt, false);
+
+ result.x = (LONG) (pt.x + GetWindow()->X());
+ result.y = (LONG) (pt.y + GetWindow()->Y());
+ }
+ break;
+
+ default:
+ result.x = 0;
+ result.y = 0;
+ break;
+ }
+
+ return result;
+}
diff --git a/Magic2/ModelView.h b/Magic2/ModelView.h
index 27fc9b6..58c2924 100644
--- a/Magic2/ModelView.h
+++ b/Magic2/ModelView.h
@@ -1,64 +1,88 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: ModelView.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Interface of the ModelView class
-*/
-
-
-#ifndef ModelView_h
-#define ModelView_h
-
-#include "CameraView.h"
-#include "Grid.h"
-
-// +--------------------------------------------------------------------+
-
-class ModelView : public CameraView
-{
-public:
- enum VIEW_MODE { VIEW_PLAN=1, VIEW_FRONT, VIEW_SIDE, VIEW_PROJECT };
- enum FILL_MODE { FILL_WIRE=1, FILL_SOLID, FILL_TEXTURE };
-
- ModelView(Window* c, Scene* s, DWORD m);
- virtual ~ModelView();
-
- virtual void RenderScene();
- virtual void Render(Graphic* g, DWORD flags);
-
- DWORD GetViewMode() const { return view_mode; }
- void SetViewMode(DWORD m);
- DWORD GetFillMode() const { return fill_mode; }
- void SetFillMode(DWORD m) { fill_mode = m; }
-
- void MoveTo(Point origin);
- void MoveBy(double dx, double dy);
- void SpinBy(double phi, double theta);
-
- void UseGrid(Grid* g);
- void RenderGrid();
- void ZoomNormal();
-
- CPoint ProjectPoint(Vec3& p);
-
- static ModelView* FindView(DWORD mode);
-
-protected:
- Camera cam;
- DWORD view_mode;
- DWORD fill_mode;
- double az;
- double el;
- Grid* grid;
-};
-
-// +--------------------------------------------------------------------+
-
-#endif ModelView_h
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: ModelView.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Interface of the ModelView class
+*/
+
+
+#ifndef ModelView_h
+#define ModelView_h
+
+#include "CameraView.h"
+#include "Grid.h"
+
+// +--------------------------------------------------------------------+
+
+class ModelView : public CameraView
+{
+public:
+ enum VIEW_MODE { VIEW_PLAN=1, VIEW_FRONT, VIEW_SIDE, VIEW_PROJECT };
+ enum FILL_MODE { FILL_WIRE=1, FILL_SOLID, FILL_TEXTURE };
+
+ ModelView(Window* c, Scene* s, DWORD m);
+ virtual ~ModelView();
+
+ virtual void RenderScene();
+ virtual void Render(Graphic* g, DWORD flags);
+
+ DWORD GetViewMode() const { return view_mode; }
+ void SetViewMode(DWORD m);
+ DWORD GetFillMode() const { return fill_mode; }
+ void SetFillMode(DWORD m) { fill_mode = m; }
+
+ void MoveTo(Point origin);
+ void MoveBy(double dx, double dy);
+ void SpinBy(double phi, double theta);
+
+ void UseGrid(Grid* g);
+ void RenderGrid();
+ void ZoomNormal();
+
+ CPoint ProjectPoint(Vec3& p);
+
+ static ModelView* FindView(DWORD mode);
+
+protected:
+ Camera cam;
+ DWORD view_mode;
+ DWORD fill_mode;
+ double az;
+ double el;
+ Grid* grid;
+};
+
+// +--------------------------------------------------------------------+
+
+#endif ModelView_h
diff --git a/Magic2/Primitives.cpp b/Magic2/Primitives.cpp
index 8846646..d1ae4e2 100644
--- a/Magic2/Primitives.cpp
+++ b/Magic2/Primitives.cpp
@@ -1,52 +1,76 @@
-/* Project MAGIC
- John DiCamillo Software Consulting
- Copyright © 1994-1997. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe Application
- FILE: Primitives.cpp
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Commands for adding basic geometric primitives to a mesh
-*/
-
-
-#include "stdafx.h"
-#include "Primitives.h"
-#include "MagicDoc.h"
-#include "ModelView.h"
-#include "Selection.h"
-
-// +----------------------------------------------------------------------+
-// +----------------------------------------------------------------------+
-// +----------------------------------------------------------------------+
-
-CreatePolyCommand::CreatePolyCommand(MagicDoc* d)
- : Command(n, d)
-{
-}
-
-CreatePolyCommand::~CreatePolyCommand()
-{
-}
-
-// +----------------------------------------------------------------------+
-
-void
-CreatePolyCommand::Do()
-{
- if (document) {
- }
-}
-
-// +----------------------------------------------------------------------+
-
-void
-EditCommand::Undo()
-{
- if (document) {
- }
-}
-
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe Application
+ FILE: Primitives.cpp
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Commands for adding basic geometric primitives to a mesh
+*/
+
+
+#include "stdafx.h"
+#include "Primitives.h"
+#include "MagicDoc.h"
+#include "ModelView.h"
+#include "Selection.h"
+
+// +----------------------------------------------------------------------+
+// +----------------------------------------------------------------------+
+// +----------------------------------------------------------------------+
+
+CreatePolyCommand::CreatePolyCommand(MagicDoc* d)
+ : Command(n, d)
+{
+}
+
+CreatePolyCommand::~CreatePolyCommand()
+{
+}
+
+// +----------------------------------------------------------------------+
+
+void
+CreatePolyCommand::Do()
+{
+ if (document) {
+ }
+}
+
+// +----------------------------------------------------------------------+
+
+void
+EditCommand::Undo()
+{
+ if (document) {
+ }
+}
+
diff --git a/Magic2/Primitives.h b/Magic2/Primitives.h
index 2da16fe..56cf26c 100644
--- a/Magic2/Primitives.h
+++ b/Magic2/Primitives.h
@@ -1,55 +1,79 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: Primitives.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Commands for adding basic geometric primitives to a mesh
-*/
-
-#ifndef Primitives_h
-#define Primitives_h
-
-#include "MagicDoc.h"
-#include "Command.h"
-#include "Polygon.h"
-#include "Solid.h"
-#include "Video.h"
-#include "List.h"
-
-// +--------------------------------------------------------------------+
-
-class Selection;
-class ModelView;
-
-// +--------------------------------------------------------------------+
-
-class CreatePolyCommand : public Command
-{
-public:
- CreatePolyCommand(MagicDoc* doc,
- int nsides,
- double lx,
- double ly,
- double lz);
- virtual ~CreatePolyCommand();
-
- virtual void Do();
- virtual void Undo();
-
-private:
- int nsides;
- double lx;
- double ly;
- double lz;
-};
-
-// +--------------------------------------------------------------------+
-
-#endif Primitives_h
-
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: Primitives.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Commands for adding basic geometric primitives to a mesh
+*/
+
+#ifndef Primitives_h
+#define Primitives_h
+
+#include "MagicDoc.h"
+#include "Command.h"
+#include "Polygon.h"
+#include "Solid.h"
+#include "Video.h"
+#include "List.h"
+
+// +--------------------------------------------------------------------+
+
+class Selection;
+class ModelView;
+
+// +--------------------------------------------------------------------+
+
+class CreatePolyCommand : public Command
+{
+public:
+ CreatePolyCommand(MagicDoc* doc,
+ int nsides,
+ double lx,
+ double ly,
+ double lz);
+ virtual ~CreatePolyCommand();
+
+ virtual void Do();
+ virtual void Undo();
+
+private:
+ int nsides;
+ double lx;
+ double ly;
+ double lz;
+};
+
+// +--------------------------------------------------------------------+
+
+#endif Primitives_h
+
diff --git a/Magic2/Selection.cpp b/Magic2/Selection.cpp
index 3db43db..570ab21 100644
--- a/Magic2/Selection.cpp
+++ b/Magic2/Selection.cpp
@@ -1,192 +1,216 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: Selection.cpp
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Classes for rendering solid meshes of polygons
-*/
-
-#include "stdafx.h"
-#include "Magic.h"
-#include "Selection.h"
-#include "ModelView.h"
-#include "Projector.h"
-
-#include "Solid.h"
-#include "Scene.h"
-#include "Bitmap.h"
-
-#include <stdio.h>
-
-// +--------------------------------------------------------------------+
-
-Selection::Selection()
- : model(0), model_view(0)
-{
- strcpy_s(name, "Selection");
-}
-
-// +--------------------------------------------------------------------+
-
-Selection::~Selection()
-{
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Selection::Render(Video* video, DWORD flags)
-{
- if (video && flags == Graphic::RENDER_ALPHA) {
- ListIter<Poly> iter = polys;
- while (++iter) {
- Poly* p = iter.value();
- Vec3 vloc[16];
-
- if (p->nverts >= 3) {
- for (int i = 0; i < p->nverts; i++) {
- int n = (i==p->nverts-1) ? 0 : i+1;
-
- vloc[2*i+0] = loc + p->vertex_set->loc[ p->verts[i] ];
- vloc[2*i+1] = loc + p->vertex_set->loc[ p->verts[n] ];
- }
-
- video->SetRenderState(Video::Z_ENABLE, FALSE);
- video->DrawLines(p->nverts, vloc, Color(255,255,128));
- }
- }
-
- if (model) {
- for (size_t i = 0; i < verts.size(); i++) {
- DWORD value = verts[i];
- WORD index = (WORD) (value >> 16);
- WORD vert = (WORD) (value & 0xffff);
-
- if (index < model->NumSurfaces()) {
- Surface* s = model->GetSurfaces()[index];
- Vec3 v = loc + s->GetVertexSet()->loc[vert];
-
- if (model_view) {
- CPoint p = model_view->ProjectPoint(v);
- float handle[16];
- int x1 = p.x-1;
- int y1 = p.y-1;
- int x2 = p.x+1;
- int y2 = p.y+1;
-
- handle[ 0] = (float) x1;
- handle[ 1] = (float) y1;
- handle[ 2] = (float) x2;
- handle[ 3] = (float) y1;
-
- handle[ 4] = (float) x2;
- handle[ 5] = (float) y1;
- handle[ 6] = (float) x2;
- handle[ 7] = (float) y2;
-
- handle[ 8] = (float) x2;
- handle[ 9] = (float) y2;
- handle[10] = (float) x1;
- handle[11] = (float) y2;
-
- handle[12] = (float) x1;
- handle[13] = (float) y2;
- handle[14] = (float) x1;
- handle[15] = (float) y1;
-
- video->DrawScreenLines(4, handle, Color(255,255,128));
- }
-
- else {
- Vec3 vloc[8];
-
- vloc[0] = v + Vec3(-1.0f, -1.0f, 0.0f);
- vloc[1] = v + Vec3( 1.0f, -1.0f, 0.0f);
- vloc[2] = v + Vec3( 1.0f, -1.0f, 0.0f);
- vloc[3] = v + Vec3( 1.0f, 1.0f, 0.0f);
- vloc[4] = v + Vec3( 1.0f, 1.0f, 0.0f);
- vloc[5] = v + Vec3(-1.0f, 1.0f, 0.0f);
- vloc[6] = v + Vec3(-1.0f, 1.0f, 0.0f);
- vloc[7] = v + Vec3(-1.0f, -1.0f, 0.0f);
-
- video->SetRenderState(Video::Z_ENABLE, FALSE);
- video->DrawLines(4, vloc, Color(255,255,128));
- }
- }
- }
- }
-
- video->UseMaterial(0);
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-Selection::AddPoly(Poly* p)
-{
- if (!polys.contains(p))
- polys.append(p);
-}
-
-void
-Selection::RemovePoly(Poly* p)
-{
- polys.remove(p);
-}
-
-bool
-Selection::Contains(Poly* p) const
-{
- return polys.contains(p);
-}
-
-void
-Selection::AddVert(WORD s, WORD v)
-{
- DWORD value = (s << 16) | v;
-
- bool contains = false;
- for (auto vi = verts.begin(); vi != verts.end(); ++vi) {
- if (*vi == value) {
- contains = true;
- break;
- }
- }
-
- if (!contains)
- verts.push_back(value);
-}
-
-void
-Selection::RemoveVert(WORD s, WORD v)
-{
- DWORD value = (s << 16) | v;
-
- for (auto vi = verts.begin(); vi != verts.end(); ++vi) {
- if (*vi == value) {
- verts.erase(vi);
- return;
- }
- }
-}
-
-bool
-Selection::Contains(WORD s, WORD v) const
-{
- DWORD value = (s << 16) | v;
-
- for (auto vi = verts.begin(); vi != verts.end(); ++vi) {
- if (*vi == value) {
- return true;
- }
- }
-
- return false;
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: Selection.cpp
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Classes for rendering solid meshes of polygons
+*/
+
+#include "stdafx.h"
+#include "Magic.h"
+#include "Selection.h"
+#include "ModelView.h"
+#include "Projector.h"
+
+#include "Solid.h"
+#include "Scene.h"
+#include "Bitmap.h"
+
+#include <stdio.h>
+
+// +--------------------------------------------------------------------+
+
+Selection::Selection()
+ : model(0), model_view(0)
+{
+ strcpy_s(name, "Selection");
+}
+
+// +--------------------------------------------------------------------+
+
+Selection::~Selection()
+{
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Selection::Render(Video* video, DWORD flags)
+{
+ if (video && flags == Graphic::RENDER_ALPHA) {
+ ListIter<Poly> iter = polys;
+ while (++iter) {
+ Poly* p = iter.value();
+ Vec3 vloc[16];
+
+ if (p->nverts >= 3) {
+ for (int i = 0; i < p->nverts; i++) {
+ int n = (i==p->nverts-1) ? 0 : i+1;
+
+ vloc[2*i+0] = loc + p->vertex_set->loc[ p->verts[i] ];
+ vloc[2*i+1] = loc + p->vertex_set->loc[ p->verts[n] ];
+ }
+
+ video->SetRenderState(Video::Z_ENABLE, FALSE);
+ video->DrawLines(p->nverts, vloc, Color(255,255,128));
+ }
+ }
+
+ if (model) {
+ for (size_t i = 0; i < verts.size(); i++) {
+ DWORD value = verts[i];
+ WORD index = (WORD) (value >> 16);
+ WORD vert = (WORD) (value & 0xffff);
+
+ if (index < model->NumSurfaces()) {
+ Surface* s = model->GetSurfaces()[index];
+ Vec3 v = loc + s->GetVertexSet()->loc[vert];
+
+ if (model_view) {
+ CPoint p = model_view->ProjectPoint(v);
+ float handle[16];
+ int x1 = p.x-1;
+ int y1 = p.y-1;
+ int x2 = p.x+1;
+ int y2 = p.y+1;
+
+ handle[ 0] = (float) x1;
+ handle[ 1] = (float) y1;
+ handle[ 2] = (float) x2;
+ handle[ 3] = (float) y1;
+
+ handle[ 4] = (float) x2;
+ handle[ 5] = (float) y1;
+ handle[ 6] = (float) x2;
+ handle[ 7] = (float) y2;
+
+ handle[ 8] = (float) x2;
+ handle[ 9] = (float) y2;
+ handle[10] = (float) x1;
+ handle[11] = (float) y2;
+
+ handle[12] = (float) x1;
+ handle[13] = (float) y2;
+ handle[14] = (float) x1;
+ handle[15] = (float) y1;
+
+ video->DrawScreenLines(4, handle, Color(255,255,128));
+ }
+
+ else {
+ Vec3 vloc[8];
+
+ vloc[0] = v + Vec3(-1.0f, -1.0f, 0.0f);
+ vloc[1] = v + Vec3( 1.0f, -1.0f, 0.0f);
+ vloc[2] = v + Vec3( 1.0f, -1.0f, 0.0f);
+ vloc[3] = v + Vec3( 1.0f, 1.0f, 0.0f);
+ vloc[4] = v + Vec3( 1.0f, 1.0f, 0.0f);
+ vloc[5] = v + Vec3(-1.0f, 1.0f, 0.0f);
+ vloc[6] = v + Vec3(-1.0f, 1.0f, 0.0f);
+ vloc[7] = v + Vec3(-1.0f, -1.0f, 0.0f);
+
+ video->SetRenderState(Video::Z_ENABLE, FALSE);
+ video->DrawLines(4, vloc, Color(255,255,128));
+ }
+ }
+ }
+ }
+
+ video->UseMaterial(0);
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Selection::AddPoly(Poly* p)
+{
+ if (!polys.contains(p))
+ polys.append(p);
+}
+
+void
+Selection::RemovePoly(Poly* p)
+{
+ polys.remove(p);
+}
+
+bool
+Selection::Contains(Poly* p) const
+{
+ return polys.contains(p);
+}
+
+void
+Selection::AddVert(WORD s, WORD v)
+{
+ DWORD value = (s << 16) | v;
+
+ bool contains = false;
+ for (auto vi = verts.begin(); vi != verts.end(); ++vi) {
+ if (*vi == value) {
+ contains = true;
+ break;
+ }
+ }
+
+ if (!contains)
+ verts.push_back(value);
+}
+
+void
+Selection::RemoveVert(WORD s, WORD v)
+{
+ DWORD value = (s << 16) | v;
+
+ for (auto vi = verts.begin(); vi != verts.end(); ++vi) {
+ if (*vi == value) {
+ verts.erase(vi);
+ return;
+ }
+ }
+}
+
+bool
+Selection::Contains(WORD s, WORD v) const
+{
+ DWORD value = (s << 16) | v;
+
+ for (auto vi = verts.begin(); vi != verts.end(); ++vi) {
+ if (*vi == value) {
+ return true;
+ }
+ }
+
+ return false;
} \ No newline at end of file
diff --git a/Magic2/Selection.h b/Magic2/Selection.h
index aba249a..e70a3b3 100644
--- a/Magic2/Selection.h
+++ b/Magic2/Selection.h
@@ -1,74 +1,98 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: Selection.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Classes for rendering solid meshes of polygons
-*/
-
-#ifndef Selection_h
-#define Selection_h
-
-#include <vector>
-#include "Polygon.h"
-#include "Graphic.h"
-#include "Video.h"
-#include "List.h"
-
-// +--------------------------------------------------------------------+
-
-class Selection;
-class Solid;
-class Model;
-class ModelView;
-class Surface;
-class Segment;
-
-// +--------------------------------------------------------------------+
-
-class Selection : public Graphic
-{
-public:
- static const char* TYPENAME() { return "Selection"; }
-
- Selection();
- virtual ~Selection();
-
- // operations
- virtual void Render(Video* video, DWORD flags);
- virtual bool CheckVisibility(Projector& projector) { return true; }
-
- // accessors / mutators
- void UseModel(Model* m) { model = m; }
- void UseView(ModelView* v){ model_view = v; }
- Model* GetModel() const { return model; }
- List<Poly>& GetPolys() { return polys; }
- std::vector<DWORD>& GetVerts() { return verts; }
-
- virtual void Clear() { polys.clear();
- verts.clear(); }
-
- void AddPoly(Poly* p);
- void AddVert(WORD s, WORD v);
- void RemovePoly(Poly* p);
- void RemoveVert(WORD s, WORD v);
- bool Contains(Poly* p) const;
- bool Contains(WORD s, WORD v) const;
-
-protected:
- Model* model;
- ModelView* model_view;
- List<Poly> polys;
- std::vector<DWORD> verts;
-};
-
-// +--------------------------------------------------------------------+
-
-#endif Selection_h
-
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: Selection.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Classes for rendering solid meshes of polygons
+*/
+
+#ifndef Selection_h
+#define Selection_h
+
+#include <vector>
+#include "Polygon.h"
+#include "Graphic.h"
+#include "Video.h"
+#include "List.h"
+
+// +--------------------------------------------------------------------+
+
+class Selection;
+class Solid;
+class Model;
+class ModelView;
+class Surface;
+class Segment;
+
+// +--------------------------------------------------------------------+
+
+class Selection : public Graphic
+{
+public:
+ static const char* TYPENAME() { return "Selection"; }
+
+ Selection();
+ virtual ~Selection();
+
+ // operations
+ virtual void Render(Video* video, DWORD flags);
+ virtual bool CheckVisibility(Projector& projector) { return true; }
+
+ // accessors / mutators
+ void UseModel(Model* m) { model = m; }
+ void UseView(ModelView* v){ model_view = v; }
+ Model* GetModel() const { return model; }
+ List<Poly>& GetPolys() { return polys; }
+ std::vector<DWORD>& GetVerts() { return verts; }
+
+ virtual void Clear() { polys.clear();
+ verts.clear(); }
+
+ void AddPoly(Poly* p);
+ void AddVert(WORD s, WORD v);
+ void RemovePoly(Poly* p);
+ void RemoveVert(WORD s, WORD v);
+ bool Contains(Poly* p) const;
+ bool Contains(WORD s, WORD v) const;
+
+protected:
+ Model* model;
+ ModelView* model_view;
+ List<Poly> polys;
+ std::vector<DWORD> verts;
+};
+
+// +--------------------------------------------------------------------+
+
+#endif Selection_h
+
diff --git a/Magic2/Selector.cpp b/Magic2/Selector.cpp
index 898355e..0b37f83 100644
--- a/Magic2/Selector.cpp
+++ b/Magic2/Selector.cpp
@@ -1,390 +1,414 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: Selector.cpp
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Source file for implementation of Selector
-*/
-
-
-#include "stdafx.h"
-#include "Selector.h"
-#include "MagicDoc.h"
-#include "ModelView.h"
-#include "Selection.h"
-
-#include "Solid.h"
-
-// +----------------------------------------------------------------------+
-
-Selector::Selector(Selection* s)
- : nmarks(0), view_mode(0), select_mode(SELECT_REPLACE), model(0)
-{
- if (s) {
- selection = s;
- own_selection = false;
- }
- else {
- selection = new Selection;
- own_selection = true;
- }
-
- strcpy_s(name, "Selector");
-}
-
-Selector::~Selector()
-{
- if (selection && own_selection)
- delete selection;
-}
-
-// +----------------------------------------------------------------------+
-
-const int BATCH_SIZE = 64;
-
-void
-Selector::Render(Video* video, DWORD flags)
-{
- if (nmarks < 2 || flags == Graphic::RENDER_SOLID)
- return;
-
- float points[4*BATCH_SIZE + 4];
-
- for (int batch = 0; batch < nmarks; batch += BATCH_SIZE) {
- int end = batch + BATCH_SIZE;
- if (end > nmarks-1)
- end = nmarks-1;
- int nlines = end-batch;
-
- for (int i = 0; i < nlines; i++) {
- points[4*i+0] = (float) marks[batch + i].x;
- points[4*i+1] = (float) marks[batch + i].y;
- points[4*i+2] = (float) marks[batch + i + 1].x;
- points[4*i+3] = (float) marks[batch + i + 1].y;
- }
-
- video->DrawScreenLines(nlines, points, Color::Cyan);
- }
-}
-
-// +----------------------------------------------------------------------+
-
-void
-Selector::Clear()
-{
- if (selection)
- selection->Clear();
-}
-
-void
-Selector::Begin(Model* m, int mode, int seln_mode)
-{
- nmarks = 0;
- model = m;
- view_mode = mode;
- select_mode = seln_mode;
-}
-
-void
-Selector::AddMark(CPoint& p)
-{
- if (nmarks < MAX_MARK)
- marks[nmarks++] = p;
-}
-
-void
-Selector::End()
-{
- ModelView* view = ModelView::FindView(view_mode);
- view_mode = 0;
-
- // get the model:
- if (!model || !nmarks || !view) return;
-
- // if not adding to selection:
- if (select_mode == SELECT_REPLACE) {
- Clear();
- }
-
- // if only one mark:
- if (nmarks < 2) {
- CPoint pts[Poly::MAX_VERTS];
-
- // find all selected polys:
- ListIter<Surface> s_iter = model->GetSurfaces();
- while (++s_iter) {
- Surface* s = s_iter.value();
-
- if (s->IsHidden() || s->IsLocked() || s->IsSimplified())
- continue;
-
- for (int i = 0; i < s->NumPolys(); i++) {
- Poly* poly = s->GetPolys() + i;
-
- if (poly->nverts < 3)
- continue;
-
- for (int v = 0; v < poly->nverts; v++)
- pts[v] = view->ProjectPoint(s->GetVertexSet()->loc[poly->verts[v]]);
-
- CRgn rgn;
- rgn.CreatePolygonRgn(pts, poly->nverts, ALTERNATE);
-
- if (rgn.PtInRegion(marks[0])) {
- if (select_mode == SELECT_REMOVE) {
- selection->RemovePoly(poly);
- }
- else {
- selection->AddPoly(poly);
- }
-
- for (int v = 0; v < poly->nverts; v++) {
- WORD vert = poly->verts[v];
- if (select_mode == SELECT_REMOVE) {
- selection->RemoveVert((WORD) s_iter.index(), vert);
- }
- else {
- selection->AddVert((WORD) s_iter.index(), vert);
- }
- }
- }
- }
- }
- }
-
- // otherwise, build a region:
- else {
- CRgn rgn;
- rgn.CreatePolygonRgn(marks, nmarks, WINDING);
-
- // find all selected verts:
- ListIter<Surface> s_iter = model->GetSurfaces();
- while (++s_iter) {
- Surface* s = s_iter.value();
- VertexSet* vset = s->GetVertexSet();
-
- if (s->IsHidden() || s->IsLocked() || s->IsSimplified())
- continue;
-
- for (WORD i = 0; i < vset->nverts; i++) {
- CPoint p = view->ProjectPoint(s->GetVertexSet()->loc[i]);
- if (rgn.PtInRegion(p)) {
- if (select_mode == SELECT_REMOVE) {
- selection->RemoveVert((WORD) s_iter.index(), i);
- }
- else {
- selection->AddVert((WORD) s_iter.index(), i);
- }
- }
- }
-
- // find all selected polys:
- for (int i = 0; i < s->NumPolys(); i++) {
- Poly* poly = s->GetPolys() + i;
-
- bool will_select = true;
- for (int v = 0; v < poly->nverts && will_select; v++)
- will_select = will_select &&
- selection->Contains((WORD) s_iter.index(), poly->verts[v]);
-
- if (will_select)
- selection->AddPoly(poly);
- else
- selection->RemovePoly(poly);
- }
- }
- }
-}
-
-// +----------------------------------------------------------------------+
-
-void
-Selector::UseModel(Model* m)
-{
- model = m;
-
- if (selection)
- selection->UseModel(model);
-}
-
-// +----------------------------------------------------------------------+
-
-void
-Selector::SelectAll(int select_mode)
-{
- Clear();
-
- if (model && select_mode != SELECT_REMOVE) {
- ListIter<Surface> iter = model->GetSurfaces();
-
- while (++iter) {
- Surface* s = iter.value();
-
- for (int i = 0; i < s->NumPolys(); i++) {
- selection->GetPolys().append(s->GetPolys() + i);
- }
-
- for (int i = 0; i < s->NumVerts(); i++) {
- DWORD value = (iter.index() << 16) | i;
- selection->GetVerts().push_back(value);
- }
- }
- }
-}
-
-// +----------------------------------------------------------------------+
-
-void
-Selector::SelectInverse()
-{
- if (model && selection) {
- ListIter<Surface> iter = model->GetSurfaces();
-
- while (++iter) {
- Surface* s = iter.value();
- WORD s_index = iter.index();
-
- for (int i = 0; i < s->NumPolys(); i++) {
- Poly* p = s->GetPolys() + i;
-
- if (selection->Contains(p))
- selection->RemovePoly(p);
- else
- selection->AddPoly(p);
- }
-
- for (int i = 0; i < s->NumVerts(); i++) {
- if (selection->Contains(s_index, i))
- selection->RemoveVert(s_index, i);
- else
- selection->AddVert(s_index, i);
- }
- }
- }
-}
-
-// +----------------------------------------------------------------------+
-
-void
-Selector::SelectSurface(Surface* s, int select_mode)
-{
- if (!s || !model)
- return;
-
- WORD index = (WORD) model->GetSurfaces().index(s);
-
- if (select_mode == SELECT_REMOVE) {
- for (int i = 0; i < s->NumPolys(); i++) {
- selection->RemovePoly(s->GetPolys() + i);
- }
-
- for (int i = 0; i < s->NumVerts(); i++) {
- selection->RemoveVert(index, i);
- }
- }
- else {
- for (WORD i = 0; i < s->NumPolys(); i++) {
- selection->AddPoly(s->GetPolys() + i);
- }
-
- for (int i = 0; i < s->NumVerts(); i++) {
- selection->AddVert(index, i);
- }
- }
-}
-
-void
-Selector::SelectVert(Surface* s, int v, int select_mode)
-{
- if (!s || !model)
- return;
-
- WORD index = (WORD) model->GetSurfaces().index(s);
-
- if (select_mode == SELECT_REMOVE) {
- selection->RemoveVert(index, (WORD) v);
- }
- else {
- selection->AddVert(index, (WORD) v);
- }
-}
-
-void
-Selector::SelectPoly(Poly* poly, int select_mode)
-{
- if (!poly || !model)
- return;
-
- if (select_mode == SELECT_REMOVE) {
- selection->RemovePoly(poly);
- }
- else {
- selection->AddPoly(poly);
- }
-}
-
-// +----------------------------------------------------------------------+
-
-void
-Selector::SelectMaterial(Material* m, int select_mode)
-{
- if (select_mode == SELECT_REPLACE)
- Clear();
-
- if (model && select_mode != SELECT_REMOVE) {
- ListIter<Surface> iter = model->GetSurfaces();
-
- while (++iter) {
- Surface* s = iter.value();
- WORD s_index = iter.index();
-
- for (int i = 0; i < s->NumPolys(); i++) {
- Poly* p = s->GetPolys() + i;
-
- if (p->material == m) {
- selection->AddPoly(p);
-
- for (int v = 0; v < p->nverts; v++) {
- selection->AddVert(s_index, p->verts[v]);
- }
- }
- }
- }
- }
-}
-
-// +----------------------------------------------------------------------+
-
-void
-Selector::Reselect()
-{
- selection->GetPolys().clear();
-
- if (model) {
- ListIter<Surface> iter = model->GetSurfaces();
-
- while (++iter) {
- Surface* s = iter.value();
- WORD s_index = iter.index();
-
- // find all selected polys:
- for (int i = 0; i < s->NumPolys(); i++) {
- Poly* poly = s->GetPolys() + i;
-
- bool will_select = true;
- for (int v = 0; v < poly->nverts && will_select; v++)
- will_select = will_select &&
- selection->Contains(s_index, poly->verts[v]);
-
- if (will_select)
- selection->AddPoly(poly);
- }
- }
- }
-}
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: Selector.cpp
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Source file for implementation of Selector
+*/
+
+
+#include "stdafx.h"
+#include "Selector.h"
+#include "MagicDoc.h"
+#include "ModelView.h"
+#include "Selection.h"
+
+#include "Solid.h"
+
+// +----------------------------------------------------------------------+
+
+Selector::Selector(Selection* s)
+ : nmarks(0), view_mode(0), select_mode(SELECT_REPLACE), model(0)
+{
+ if (s) {
+ selection = s;
+ own_selection = false;
+ }
+ else {
+ selection = new Selection;
+ own_selection = true;
+ }
+
+ strcpy_s(name, "Selector");
+}
+
+Selector::~Selector()
+{
+ if (selection && own_selection)
+ delete selection;
+}
+
+// +----------------------------------------------------------------------+
+
+const int BATCH_SIZE = 64;
+
+void
+Selector::Render(Video* video, DWORD flags)
+{
+ if (nmarks < 2 || flags == Graphic::RENDER_SOLID)
+ return;
+
+ float points[4*BATCH_SIZE + 4];
+
+ for (int batch = 0; batch < nmarks; batch += BATCH_SIZE) {
+ int end = batch + BATCH_SIZE;
+ if (end > nmarks-1)
+ end = nmarks-1;
+ int nlines = end-batch;
+
+ for (int i = 0; i < nlines; i++) {
+ points[4*i+0] = (float) marks[batch + i].x;
+ points[4*i+1] = (float) marks[batch + i].y;
+ points[4*i+2] = (float) marks[batch + i + 1].x;
+ points[4*i+3] = (float) marks[batch + i + 1].y;
+ }
+
+ video->DrawScreenLines(nlines, points, Color::Cyan);
+ }
+}
+
+// +----------------------------------------------------------------------+
+
+void
+Selector::Clear()
+{
+ if (selection)
+ selection->Clear();
+}
+
+void
+Selector::Begin(Model* m, int mode, int seln_mode)
+{
+ nmarks = 0;
+ model = m;
+ view_mode = mode;
+ select_mode = seln_mode;
+}
+
+void
+Selector::AddMark(CPoint& p)
+{
+ if (nmarks < MAX_MARK)
+ marks[nmarks++] = p;
+}
+
+void
+Selector::End()
+{
+ ModelView* view = ModelView::FindView(view_mode);
+ view_mode = 0;
+
+ // get the model:
+ if (!model || !nmarks || !view) return;
+
+ // if not adding to selection:
+ if (select_mode == SELECT_REPLACE) {
+ Clear();
+ }
+
+ // if only one mark:
+ if (nmarks < 2) {
+ CPoint pts[Poly::MAX_VERTS];
+
+ // find all selected polys:
+ ListIter<Surface> s_iter = model->GetSurfaces();
+ while (++s_iter) {
+ Surface* s = s_iter.value();
+
+ if (s->IsHidden() || s->IsLocked() || s->IsSimplified())
+ continue;
+
+ for (int i = 0; i < s->NumPolys(); i++) {
+ Poly* poly = s->GetPolys() + i;
+
+ if (poly->nverts < 3)
+ continue;
+
+ for (int v = 0; v < poly->nverts; v++)
+ pts[v] = view->ProjectPoint(s->GetVertexSet()->loc[poly->verts[v]]);
+
+ CRgn rgn;
+ rgn.CreatePolygonRgn(pts, poly->nverts, ALTERNATE);
+
+ if (rgn.PtInRegion(marks[0])) {
+ if (select_mode == SELECT_REMOVE) {
+ selection->RemovePoly(poly);
+ }
+ else {
+ selection->AddPoly(poly);
+ }
+
+ for (int v = 0; v < poly->nverts; v++) {
+ WORD vert = poly->verts[v];
+ if (select_mode == SELECT_REMOVE) {
+ selection->RemoveVert((WORD) s_iter.index(), vert);
+ }
+ else {
+ selection->AddVert((WORD) s_iter.index(), vert);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // otherwise, build a region:
+ else {
+ CRgn rgn;
+ rgn.CreatePolygonRgn(marks, nmarks, WINDING);
+
+ // find all selected verts:
+ ListIter<Surface> s_iter = model->GetSurfaces();
+ while (++s_iter) {
+ Surface* s = s_iter.value();
+ VertexSet* vset = s->GetVertexSet();
+
+ if (s->IsHidden() || s->IsLocked() || s->IsSimplified())
+ continue;
+
+ for (WORD i = 0; i < vset->nverts; i++) {
+ CPoint p = view->ProjectPoint(s->GetVertexSet()->loc[i]);
+ if (rgn.PtInRegion(p)) {
+ if (select_mode == SELECT_REMOVE) {
+ selection->RemoveVert((WORD) s_iter.index(), i);
+ }
+ else {
+ selection->AddVert((WORD) s_iter.index(), i);
+ }
+ }
+ }
+
+ // find all selected polys:
+ for (int i = 0; i < s->NumPolys(); i++) {
+ Poly* poly = s->GetPolys() + i;
+
+ bool will_select = true;
+ for (int v = 0; v < poly->nverts && will_select; v++)
+ will_select = will_select &&
+ selection->Contains((WORD) s_iter.index(), poly->verts[v]);
+
+ if (will_select)
+ selection->AddPoly(poly);
+ else
+ selection->RemovePoly(poly);
+ }
+ }
+ }
+}
+
+// +----------------------------------------------------------------------+
+
+void
+Selector::UseModel(Model* m)
+{
+ model = m;
+
+ if (selection)
+ selection->UseModel(model);
+}
+
+// +----------------------------------------------------------------------+
+
+void
+Selector::SelectAll(int select_mode)
+{
+ Clear();
+
+ if (model && select_mode != SELECT_REMOVE) {
+ ListIter<Surface> iter = model->GetSurfaces();
+
+ while (++iter) {
+ Surface* s = iter.value();
+
+ for (int i = 0; i < s->NumPolys(); i++) {
+ selection->GetPolys().append(s->GetPolys() + i);
+ }
+
+ for (int i = 0; i < s->NumVerts(); i++) {
+ DWORD value = (iter.index() << 16) | i;
+ selection->GetVerts().push_back(value);
+ }
+ }
+ }
+}
+
+// +----------------------------------------------------------------------+
+
+void
+Selector::SelectInverse()
+{
+ if (model && selection) {
+ ListIter<Surface> iter = model->GetSurfaces();
+
+ while (++iter) {
+ Surface* s = iter.value();
+ WORD s_index = iter.index();
+
+ for (int i = 0; i < s->NumPolys(); i++) {
+ Poly* p = s->GetPolys() + i;
+
+ if (selection->Contains(p))
+ selection->RemovePoly(p);
+ else
+ selection->AddPoly(p);
+ }
+
+ for (int i = 0; i < s->NumVerts(); i++) {
+ if (selection->Contains(s_index, i))
+ selection->RemoveVert(s_index, i);
+ else
+ selection->AddVert(s_index, i);
+ }
+ }
+ }
+}
+
+// +----------------------------------------------------------------------+
+
+void
+Selector::SelectSurface(Surface* s, int select_mode)
+{
+ if (!s || !model)
+ return;
+
+ WORD index = (WORD) model->GetSurfaces().index(s);
+
+ if (select_mode == SELECT_REMOVE) {
+ for (int i = 0; i < s->NumPolys(); i++) {
+ selection->RemovePoly(s->GetPolys() + i);
+ }
+
+ for (int i = 0; i < s->NumVerts(); i++) {
+ selection->RemoveVert(index, i);
+ }
+ }
+ else {
+ for (WORD i = 0; i < s->NumPolys(); i++) {
+ selection->AddPoly(s->GetPolys() + i);
+ }
+
+ for (int i = 0; i < s->NumVerts(); i++) {
+ selection->AddVert(index, i);
+ }
+ }
+}
+
+void
+Selector::SelectVert(Surface* s, int v, int select_mode)
+{
+ if (!s || !model)
+ return;
+
+ WORD index = (WORD) model->GetSurfaces().index(s);
+
+ if (select_mode == SELECT_REMOVE) {
+ selection->RemoveVert(index, (WORD) v);
+ }
+ else {
+ selection->AddVert(index, (WORD) v);
+ }
+}
+
+void
+Selector::SelectPoly(Poly* poly, int select_mode)
+{
+ if (!poly || !model)
+ return;
+
+ if (select_mode == SELECT_REMOVE) {
+ selection->RemovePoly(poly);
+ }
+ else {
+ selection->AddPoly(poly);
+ }
+}
+
+// +----------------------------------------------------------------------+
+
+void
+Selector::SelectMaterial(Material* m, int select_mode)
+{
+ if (select_mode == SELECT_REPLACE)
+ Clear();
+
+ if (model && select_mode != SELECT_REMOVE) {
+ ListIter<Surface> iter = model->GetSurfaces();
+
+ while (++iter) {
+ Surface* s = iter.value();
+ WORD s_index = iter.index();
+
+ for (int i = 0; i < s->NumPolys(); i++) {
+ Poly* p = s->GetPolys() + i;
+
+ if (p->material == m) {
+ selection->AddPoly(p);
+
+ for (int v = 0; v < p->nverts; v++) {
+ selection->AddVert(s_index, p->verts[v]);
+ }
+ }
+ }
+ }
+ }
+}
+
+// +----------------------------------------------------------------------+
+
+void
+Selector::Reselect()
+{
+ selection->GetPolys().clear();
+
+ if (model) {
+ ListIter<Surface> iter = model->GetSurfaces();
+
+ while (++iter) {
+ Surface* s = iter.value();
+ WORD s_index = iter.index();
+
+ // find all selected polys:
+ for (int i = 0; i < s->NumPolys(); i++) {
+ Poly* poly = s->GetPolys() + i;
+
+ bool will_select = true;
+ for (int v = 0; v < poly->nverts && will_select; v++)
+ will_select = will_select &&
+ selection->Contains(s_index, poly->verts[v]);
+
+ if (will_select)
+ selection->AddPoly(poly);
+ }
+ }
+ }
+}
diff --git a/Magic2/Selector.h b/Magic2/Selector.h
index 2962b59..524cccb 100644
--- a/Magic2/Selector.h
+++ b/Magic2/Selector.h
@@ -1,76 +1,100 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: Selector.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Class definition for Selector (free-form selection tool)
-*/
-
-#ifndef Selector_h
-#define Selector_h
-
-#include "Polygon.h"
-#include "Graphic.h"
-#include "Video.h"
-
-class ModelView;
-class Model;
-class Selection;
-class Surface;
-
-// +----------------------------------------------------------------------+
-
-class Selector : public Graphic
-{
-public:
- Selector(Selection* s=0);
- virtual ~Selector();
-
- enum SELECT_MODE { SELECT_REMOVE=-1, SELECT_REPLACE=0, SELECT_APPEND=1 };
-
- // Operations
- virtual void Render(Video* video, DWORD flags);
- virtual bool CheckVisibility(Projector& projector) { return true; }
-
- void Clear();
- void Begin(Model* m, int mode, int select_mode = SELECT_REPLACE);
- void AddMark(CPoint& p);
- void End();
-
- bool IsActive() const { return view_mode ? true : false; }
- int GetViewMode() const { return view_mode; }
- Selection* GetSelection() const { return selection; }
-
- void UseModel(Model* m);
- void SelectAll(int select_mode = SELECT_REPLACE);
- void SelectInverse();
- void SelectSurface(Surface* s, int select_mode = SELECT_REPLACE);
- void SelectVert(Surface* s, int v, int select_mode = SELECT_REPLACE);
- void SelectPoly(Poly* p, int select_mode = SELECT_REPLACE);
- void SelectMaterial(Material* m, int select_mode = SELECT_REPLACE);
-
- void Reselect();
-
-protected:
- enum { MAX_MARK = 4096 };
-
- int view_mode;
- int nmarks;
- CPoint marks[MAX_MARK];
- int select_mode;
-
- bool own_selection;
- Selection* selection;
- Model* model;
-};
-
-
-// +----------------------------------------------------------------------+
-
-#endif Selector_h
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: Selector.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Class definition for Selector (free-form selection tool)
+*/
+
+#ifndef Selector_h
+#define Selector_h
+
+#include "Polygon.h"
+#include "Graphic.h"
+#include "Video.h"
+
+class ModelView;
+class Model;
+class Selection;
+class Surface;
+
+// +----------------------------------------------------------------------+
+
+class Selector : public Graphic
+{
+public:
+ Selector(Selection* s=0);
+ virtual ~Selector();
+
+ enum SELECT_MODE { SELECT_REMOVE=-1, SELECT_REPLACE=0, SELECT_APPEND=1 };
+
+ // Operations
+ virtual void Render(Video* video, DWORD flags);
+ virtual bool CheckVisibility(Projector& projector) { return true; }
+
+ void Clear();
+ void Begin(Model* m, int mode, int select_mode = SELECT_REPLACE);
+ void AddMark(CPoint& p);
+ void End();
+
+ bool IsActive() const { return view_mode ? true : false; }
+ int GetViewMode() const { return view_mode; }
+ Selection* GetSelection() const { return selection; }
+
+ void UseModel(Model* m);
+ void SelectAll(int select_mode = SELECT_REPLACE);
+ void SelectInverse();
+ void SelectSurface(Surface* s, int select_mode = SELECT_REPLACE);
+ void SelectVert(Surface* s, int v, int select_mode = SELECT_REPLACE);
+ void SelectPoly(Poly* p, int select_mode = SELECT_REPLACE);
+ void SelectMaterial(Material* m, int select_mode = SELECT_REPLACE);
+
+ void Reselect();
+
+protected:
+ enum { MAX_MARK = 4096 };
+
+ int view_mode;
+ int nmarks;
+ CPoint marks[MAX_MARK];
+ int select_mode;
+
+ bool own_selection;
+ Selection* selection;
+ Model* model;
+};
+
+
+// +----------------------------------------------------------------------+
+
+#endif Selector_h
diff --git a/Magic2/StdAfx.cpp b/Magic2/StdAfx.cpp
index c2d4ca6..d244fd1 100644
--- a/Magic2/StdAfx.cpp
+++ b/Magic2/StdAfx.cpp
@@ -1,8 +1,8 @@
-// stdafx.cpp : source file that includes just the standard includes
-// Magic.pch will be the pre-compiled header
-// stdafx.obj will contain the pre-compiled type information
-
-#include "stdafx.h"
-
-
-
+// stdafx.cpp : source file that includes just the standard includes
+// Magic.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+
+
diff --git a/Magic2/StdAfx.h b/Magic2/StdAfx.h
index d6a3e3a..36a4cb6 100644
--- a/Magic2/StdAfx.h
+++ b/Magic2/StdAfx.h
@@ -1,46 +1,46 @@
-// stdafx.h : include file for standard system include files,
-// or project specific include files that are used frequently, but
-// are changed infrequently
-//
-
-#if !defined(AFX_STDAFX_H__E37C2030_8F5E_4A38_92DD_72F0EAE0DA81__INCLUDED_)
-#define AFX_STDAFX_H__E37C2030_8F5E_4A38_92DD_72F0EAE0DA81__INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
-#define WIN32_LEAN_AND_MEAN
-
-#if _MSC_VER <= 1600
-#define _WIN32_WINNT 0x0502 // XP is the lowest supported OS
-#else
-#define _WIN32_WINNT 0x0600 // VS2012 does not support XP, 0x0600 is Vista
-#endif
-
-#include <afxwin.h> // MFC core and standard components
-#include <afxext.h> // MFC extensions
-#include <afxdisp.h> // MFC Automation classes
-#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
-#ifndef _AFX_NO_AFXCMN_SUPPORT
-#include <afxcmn.h> // MFC support for Windows Common Controls
-#endif // _AFX_NO_AFXCMN_SUPPORT
-
-// Enable extra D3D debugging in debug builds if using the debug DirectX runtime.
-// This makes D3D objects work well in the debugger watch window, but slows down
-// performance slightly.
-#if defined(DEBUG) | defined(_DEBUG)
-#define D3D_DEBUG_INFO
-#endif
-
-// Direct3D includes
-#include <d3d9.h>
-#include <d3dx9.h>
-#include <mmsystem.h>
-#include <mmreg.h>
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
-
-#endif // !defined(AFX_STDAFX_H__E37C2030_8F5E_4A38_92DD_72F0EAE0DA81__INCLUDED_)
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#if !defined(AFX_STDAFX_H__E37C2030_8F5E_4A38_92DD_72F0EAE0DA81__INCLUDED_)
+#define AFX_STDAFX_H__E37C2030_8F5E_4A38_92DD_72F0EAE0DA81__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
+#define WIN32_LEAN_AND_MEAN
+
+#if _MSC_VER <= 1600
+#define _WIN32_WINNT 0x0502 // XP is the lowest supported OS
+#else
+#define _WIN32_WINNT 0x0600 // VS2012 does not support XP, 0x0600 is Vista
+#endif
+
+#include <afxwin.h> // MFC core and standard components
+#include <afxext.h> // MFC extensions
+#include <afxdisp.h> // MFC Automation classes
+#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h> // MFC support for Windows Common Controls
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+// Enable extra D3D debugging in debug builds if using the debug DirectX runtime.
+// This makes D3D objects work well in the debugger watch window, but slows down
+// performance slightly.
+#if defined(DEBUG) | defined(_DEBUG)
+#define D3D_DEBUG_INFO
+#endif
+
+// Direct3D includes
+#include <d3d9.h>
+#include <d3dx9.h>
+#include <mmsystem.h>
+#include <mmreg.h>
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_STDAFX_H__E37C2030_8F5E_4A38_92DD_72F0EAE0DA81__INCLUDED_)
diff --git a/Magic2/SurfacePropertiesDialog.cpp b/Magic2/SurfacePropertiesDialog.cpp
index d6fd7f4..a4a845c 100644
--- a/Magic2/SurfacePropertiesDialog.cpp
+++ b/Magic2/SurfacePropertiesDialog.cpp
@@ -1,93 +1,119 @@
-// SurfacePropertiesDialog.cpp : implementation file
-//
-
-#include "stdafx.h"
-#include "Magic.h"
-#include "MagicDoc.h"
-#include "MagicView.h"
-#include "Solid.h"
-#include "SurfacePropertiesDialog.h"
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
-#endif
-
-/////////////////////////////////////////////////////////////////////////////
-// SurfacePropertiesDialog dialog
-
-
-SurfacePropertiesDialog::SurfacePropertiesDialog(MagicView* pParent /*=NULL*/)
- : CDialog(SurfacePropertiesDialog::IDD, pParent), doc(0)
-{
- //{{AFX_DATA_INIT(SurfacePropertiesDialog)
- mSurfaceName = _T("");
- mNumPolys = _T("");
- mNumVerts = _T("");
- mSurfaceHeight = _T("");
- mSurfaceLength = _T("");
- mSurfaceRadius = _T("");
- mSurfaceWidth = _T("");
- //}}AFX_DATA_INIT
-
- if (pParent) {
- doc = pParent->GetDocument();
-
- if (doc && doc->GetSolid()) {
- Model* model = doc->GetSolid()->GetModel();
- Surface* surface = model->GetSurfaces().first();
- Point plus;
- Point minus;
-
- surface->GetVertexSet()->CalcExtents(plus, minus);
-
- char buffer[256];
- strcpy_s(buffer, surface->Name());
- mSurfaceName = buffer;
-
- sprintf_s(buffer, "%d", surface->NumPolys());
- mNumPolys = buffer;
-
- sprintf_s(buffer, "%d", surface->NumVerts());
- mNumVerts = buffer;
-
- sprintf_s(buffer, "%.1f", surface->Radius());
- mSurfaceRadius = buffer;
-
- sprintf_s(buffer, "%.1f (%.1f - %.1f)", plus.z-minus.z, minus.z, plus.z);
- mSurfaceLength = buffer;
-
- sprintf_s(buffer, "%.1f (%.1f - %.1f)", plus.x-minus.x, minus.x, plus.x);
- mSurfaceWidth = buffer;
-
- sprintf_s(buffer, "%.1f (%.1f - %.1f)", plus.y-minus.y, minus.y, plus.y);
- mSurfaceHeight = buffer;
- }
- }
-}
-
-
-void SurfacePropertiesDialog::DoDataExchange(CDataExchange* pDX)
-{
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(SurfacePropertiesDialog)
- DDX_CBString(pDX, IDC_SURFACE_NAME, mSurfaceName);
- DDX_Text(pDX, IDC_SURFACE_NPOLYS, mNumPolys);
- DDX_Text(pDX, IDC_SURFACE_NVERTS, mNumVerts);
- DDX_Text(pDX, IDC_SURFACE_HEIGHT, mSurfaceHeight);
- DDX_Text(pDX, IDC_SURFACE_LENGTH, mSurfaceLength);
- DDX_Text(pDX, IDC_SURFACE_RADIUS, mSurfaceRadius);
- DDX_Text(pDX, IDC_SURFACE_WIDTH, mSurfaceWidth);
- //}}AFX_DATA_MAP
-}
-
-
-BEGIN_MESSAGE_MAP(SurfacePropertiesDialog, CDialog)
- //{{AFX_MSG_MAP(SurfacePropertiesDialog)
- // NOTE: the ClassWizard will add message map macros here
- //}}AFX_MSG_MAP
-END_MESSAGE_MAP()
-
-/////////////////////////////////////////////////////////////////////////////
-// SurfacePropertiesDialog message handlers
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "stdafx.h"
+#include "Magic.h"
+#include "MagicDoc.h"
+#include "MagicView.h"
+#include "Solid.h"
+#include "SurfacePropertiesDialog.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// SurfacePropertiesDialog dialog
+
+
+SurfacePropertiesDialog::SurfacePropertiesDialog(MagicView* pParent /*=NULL*/)
+ : CDialog(SurfacePropertiesDialog::IDD, pParent), doc(0)
+{
+ //{{AFX_DATA_INIT(SurfacePropertiesDialog)
+ mSurfaceName = _T("");
+ mNumPolys = _T("");
+ mNumVerts = _T("");
+ mSurfaceHeight = _T("");
+ mSurfaceLength = _T("");
+ mSurfaceRadius = _T("");
+ mSurfaceWidth = _T("");
+ //}}AFX_DATA_INIT
+
+ if (pParent) {
+ doc = pParent->GetDocument();
+
+ if (doc && doc->GetSolid()) {
+ Model* model = doc->GetSolid()->GetModel();
+ Surface* surface = model->GetSurfaces().first();
+ Point plus;
+ Point minus;
+
+ surface->GetVertexSet()->CalcExtents(plus, minus);
+
+ char buffer[256];
+ strcpy_s(buffer, surface->Name());
+ mSurfaceName = buffer;
+
+ sprintf_s(buffer, "%d", surface->NumPolys());
+ mNumPolys = buffer;
+
+ sprintf_s(buffer, "%d", surface->NumVerts());
+ mNumVerts = buffer;
+
+ sprintf_s(buffer, "%.1f", surface->Radius());
+ mSurfaceRadius = buffer;
+
+ sprintf_s(buffer, "%.1f (%.1f - %.1f)", plus.z-minus.z, minus.z, plus.z);
+ mSurfaceLength = buffer;
+
+ sprintf_s(buffer, "%.1f (%.1f - %.1f)", plus.x-minus.x, minus.x, plus.x);
+ mSurfaceWidth = buffer;
+
+ sprintf_s(buffer, "%.1f (%.1f - %.1f)", plus.y-minus.y, minus.y, plus.y);
+ mSurfaceHeight = buffer;
+ }
+ }
+}
+
+
+void SurfacePropertiesDialog::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(SurfacePropertiesDialog)
+ DDX_CBString(pDX, IDC_SURFACE_NAME, mSurfaceName);
+ DDX_Text(pDX, IDC_SURFACE_NPOLYS, mNumPolys);
+ DDX_Text(pDX, IDC_SURFACE_NVERTS, mNumVerts);
+ DDX_Text(pDX, IDC_SURFACE_HEIGHT, mSurfaceHeight);
+ DDX_Text(pDX, IDC_SURFACE_LENGTH, mSurfaceLength);
+ DDX_Text(pDX, IDC_SURFACE_RADIUS, mSurfaceRadius);
+ DDX_Text(pDX, IDC_SURFACE_WIDTH, mSurfaceWidth);
+ //}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(SurfacePropertiesDialog, CDialog)
+ //{{AFX_MSG_MAP(SurfacePropertiesDialog)
+ // NOTE: the ClassWizard will add message map macros here
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// SurfacePropertiesDialog message handlers
diff --git a/Magic2/SurfacePropertiesDialog.h b/Magic2/SurfacePropertiesDialog.h
index ae9f687..71a7703 100644
--- a/Magic2/SurfacePropertiesDialog.h
+++ b/Magic2/SurfacePropertiesDialog.h
@@ -1,73 +1,97 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2005. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: SurfacePropertiesDialog.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Surface Properties Dialog interface file
-*/
-
-#if !defined(AFX_SURFACEPROPERTIESDIALOG_H__8121A894_106E_4A17_9CE1_ADDD88F6A0CD__INCLUDED_)
-#define AFX_SURFACEPROPERTIESDIALOG_H__8121A894_106E_4A17_9CE1_ADDD88F6A0CD__INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-// +--------------------------------------------------------------------+
-
-class Bitmap;
-class MagicDoc;
-class MagicView;
-class Model;
-
-// +--------------------------------------------------------------------+
-// SurfacePropertiesDialog dialog
-// +--------------------------------------------------------------------+
-
-class SurfacePropertiesDialog : public CDialog
-{
-// Construction
-public:
- SurfacePropertiesDialog(MagicView* pParent = NULL); // standard constructor
-
-// Dialog Data
- //{{AFX_DATA(SurfacePropertiesDialog)
- enum { IDD = IDD_SURFACE_PROPS };
- CString mSurfaceName;
- CString mNumPolys;
- CString mNumVerts;
- CString mSurfaceHeight;
- CString mSurfaceLength;
- CString mSurfaceRadius;
- CString mSurfaceWidth;
- //}}AFX_DATA
-
-
-// Overrides
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(SurfacePropertiesDialog)
- protected:
- virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
- //}}AFX_VIRTUAL
-
-// Implementation
-protected:
- MagicDoc* doc;
-
- // Generated message map functions
- //{{AFX_MSG(SurfacePropertiesDialog)
- // NOTE: the ClassWizard will add member functions here
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
-};
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
-
-#endif
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: SurfacePropertiesDialog.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Surface Properties Dialog interface file
+*/
+
+#if !defined(AFX_SURFACEPROPERTIESDIALOG_H__8121A894_106E_4A17_9CE1_ADDD88F6A0CD__INCLUDED_)
+#define AFX_SURFACEPROPERTIESDIALOG_H__8121A894_106E_4A17_9CE1_ADDD88F6A0CD__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+// +--------------------------------------------------------------------+
+
+class Bitmap;
+class MagicDoc;
+class MagicView;
+class Model;
+
+// +--------------------------------------------------------------------+
+// SurfacePropertiesDialog dialog
+// +--------------------------------------------------------------------+
+
+class SurfacePropertiesDialog : public CDialog
+{
+// Construction
+public:
+ SurfacePropertiesDialog(MagicView* pParent = NULL); // standard constructor
+
+// Dialog Data
+ //{{AFX_DATA(SurfacePropertiesDialog)
+ enum { IDD = IDD_SURFACE_PROPS };
+ CString mSurfaceName;
+ CString mNumPolys;
+ CString mNumVerts;
+ CString mSurfaceHeight;
+ CString mSurfaceLength;
+ CString mSurfaceRadius;
+ CString mSurfaceWidth;
+ //}}AFX_DATA
+
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(SurfacePropertiesDialog)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+ MagicDoc* doc;
+
+ // Generated message map functions
+ //{{AFX_MSG(SurfacePropertiesDialog)
+ // NOTE: the ClassWizard will add member functions here
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif
diff --git a/Magic2/TexCubeDX9.cpp b/Magic2/TexCubeDX9.cpp
index c623215..49bb607 100644
--- a/Magic2/TexCubeDX9.cpp
+++ b/Magic2/TexCubeDX9.cpp
@@ -1,120 +1,144 @@
-/* Project nGenEx
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: nGenEx.lib
- FILE: TexDX9.cpp
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Direct3D Texture Cache
-*/
-
-#include "MemDebug.h"
-#include "TexCubeDX9.h"
-#include "VideoDX9.h"
-#include "Bitmap.h"
-#include "Color.h"
-
-// +--------------------------------------------------------------------+
-
-void Print(const char* fmt, ...);
-void VideoDX9Error(const char* msg, HRESULT err);
-
-#ifndef RELEASE
-#define RELEASE(x) if (x) { x->Release(); x=NULL; }
-#endif
-
-// +--------------------------------------------------------------------+
-
-TexCubeDX9::TexCubeDX9(VideoDX9* v)
-: video(v), texture(0)
-{
- d3d = video->Direct3D();
- d3ddevice = video->D3DDevice();
-
- for (int i = 0; i < 6; i++) {
- faces[i] = 0;
- last_modified[i] = 0;
- }
-}
-
-TexCubeDX9::~TexCubeDX9()
-{
- RELEASE(texture);
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-TexCubeDX9::LoadTexture(Bitmap* bmp, int face_index)
-{
- if (!d3ddevice) return false;
-
- if (faces[face_index] == bmp && last_modified[face_index] >= bmp->LastModified())
- return true; // already loaded and hasn't been modified
-
- HRESULT hr = D3D_OK;
-
- // create the texture, if necessary
- if (!texture) {
- hr = d3ddevice->CreateCubeTexture(bmp->Width(),
- 1, // one mip level
- 0, // no specific usage
- D3DFMT_A8R8G8B8, // format matching Color::rgba
- D3DPOOL_MANAGED,
- &texture,
- 0);
-
- if (FAILED(hr) || !texture) {
- VideoDX9Error("LoadTexture - could not create cube texture", hr);
- return false;
- }
- }
-
- // lock the surface for writing
- D3DLOCKED_RECT locked_rect;
- D3DCUBEMAP_FACES face = (D3DCUBEMAP_FACES) face_index;
- hr = texture->LockRect(face, 0, &locked_rect, 0, 0);
-
- if (FAILED(hr)) {
- VideoDX9Error("LoadTexture - could not lock texture surface", hr);
- RELEASE(texture);
- return false;
- }
-
- // load the bitmap into the texture surface
- for (int i = 0; i < bmp->Height(); i++) {
- BYTE* src = (BYTE*) (bmp->HiPixels() + i * bmp->Width());
- BYTE* dst = (BYTE*) locked_rect.pBits + i * locked_rect.Pitch;
-
- CopyMemory(dst, src, bmp->Width() * sizeof(Color));
- }
-
- // unlock the surface
- texture->UnlockRect(face, 0);
-
- faces[face_index] = bmp;
- last_modified[face_index] = bmp->LastModified();
-
- return true;
-}
-
-// +--------------------------------------------------------------------+
-
-IDirect3DCubeTexture9*
-TexCubeDX9::GetTexture()
-{
- if (texture) {
- // need to refresh anything?
- for (int i = 0; i < 6; i++) {
- if (faces[i] && last_modified[i] < faces[i]->LastModified()) {
- LoadTexture(faces[i], i);
- }
- }
- }
-
- return texture;
-}
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: nGenEx.lib
+ FILE: TexDX9.cpp
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Direct3D Texture Cache
+*/
+
+#include "MemDebug.h"
+#include "TexCubeDX9.h"
+#include "VideoDX9.h"
+#include "Bitmap.h"
+#include "Color.h"
+
+// +--------------------------------------------------------------------+
+
+void Print(const char* fmt, ...);
+void VideoDX9Error(const char* msg, HRESULT err);
+
+#ifndef RELEASE
+#define RELEASE(x) if (x) { x->Release(); x=NULL; }
+#endif
+
+// +--------------------------------------------------------------------+
+
+TexCubeDX9::TexCubeDX9(VideoDX9* v)
+: video(v), texture(0)
+{
+ d3d = video->Direct3D();
+ d3ddevice = video->D3DDevice();
+
+ for (int i = 0; i < 6; i++) {
+ faces[i] = 0;
+ last_modified[i] = 0;
+ }
+}
+
+TexCubeDX9::~TexCubeDX9()
+{
+ RELEASE(texture);
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+TexCubeDX9::LoadTexture(Bitmap* bmp, int face_index)
+{
+ if (!d3ddevice) return false;
+
+ if (faces[face_index] == bmp && last_modified[face_index] >= bmp->LastModified())
+ return true; // already loaded and hasn't been modified
+
+ HRESULT hr = D3D_OK;
+
+ // create the texture, if necessary
+ if (!texture) {
+ hr = d3ddevice->CreateCubeTexture(bmp->Width(),
+ 1, // one mip level
+ 0, // no specific usage
+ D3DFMT_A8R8G8B8, // format matching Color::rgba
+ D3DPOOL_MANAGED,
+ &texture,
+ 0);
+
+ if (FAILED(hr) || !texture) {
+ VideoDX9Error("LoadTexture - could not create cube texture", hr);
+ return false;
+ }
+ }
+
+ // lock the surface for writing
+ D3DLOCKED_RECT locked_rect;
+ D3DCUBEMAP_FACES face = (D3DCUBEMAP_FACES) face_index;
+ hr = texture->LockRect(face, 0, &locked_rect, 0, 0);
+
+ if (FAILED(hr)) {
+ VideoDX9Error("LoadTexture - could not lock texture surface", hr);
+ RELEASE(texture);
+ return false;
+ }
+
+ // load the bitmap into the texture surface
+ for (int i = 0; i < bmp->Height(); i++) {
+ BYTE* src = (BYTE*) (bmp->HiPixels() + i * bmp->Width());
+ BYTE* dst = (BYTE*) locked_rect.pBits + i * locked_rect.Pitch;
+
+ CopyMemory(dst, src, bmp->Width() * sizeof(Color));
+ }
+
+ // unlock the surface
+ texture->UnlockRect(face, 0);
+
+ faces[face_index] = bmp;
+ last_modified[face_index] = bmp->LastModified();
+
+ return true;
+}
+
+// +--------------------------------------------------------------------+
+
+IDirect3DCubeTexture9*
+TexCubeDX9::GetTexture()
+{
+ if (texture) {
+ // need to refresh anything?
+ for (int i = 0; i < 6; i++) {
+ if (faces[i] && last_modified[i] < faces[i]->LastModified()) {
+ LoadTexture(faces[i], i);
+ }
+ }
+ }
+
+ return texture;
+}
diff --git a/Magic2/TexCubeDX9.h b/Magic2/TexCubeDX9.h
index 686bcb9..b636677 100644
--- a/Magic2/TexCubeDX9.h
+++ b/Magic2/TexCubeDX9.h
@@ -1,49 +1,73 @@
-/* Project nGenEx
- Destroyer Studios LLC
- Copyright © 1997-2006. All Rights Reserved.
-
- SUBSYSTEM: nGenEx.lib
- FILE: TexCubeDX9.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Direct 3D Texture Cube for Env Mapping
-*/
-
-#ifndef TexCubeDX9_h
-#define TexCubeDX9_h
-
-#include "Bitmap.h"
-
-// +--------------------------------------------------------------------+
-
-class Video;
-class VideoDX9;
-class Bitmap;
-struct VD3D_texture_format;
-
-// +--------------------------------------------------------------------+
-
-class TexCubeDX9
-{
-public:
- TexCubeDX9(VideoDX9* video);
- virtual ~TexCubeDX9();
-
- IDirect3DCubeTexture9* GetTexture();
- bool LoadTexture(Bitmap* bmp, int face);
-
-private:
- VideoDX9* video;
- IDirect3D9* d3d;
- IDirect3DDevice9* d3ddevice;
-
- IDirect3DCubeTexture9* texture;
- Bitmap* faces[6];
- DWORD last_modified[6];
-};
-
-#endif // TexCubeDX9_h
-
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: nGenEx.lib
+ FILE: TexCubeDX9.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Direct 3D Texture Cube for Env Mapping
+*/
+
+#ifndef TexCubeDX9_h
+#define TexCubeDX9_h
+
+#include "Bitmap.h"
+
+// +--------------------------------------------------------------------+
+
+class Video;
+class VideoDX9;
+class Bitmap;
+struct VD3D_texture_format;
+
+// +--------------------------------------------------------------------+
+
+class TexCubeDX9
+{
+public:
+ TexCubeDX9(VideoDX9* video);
+ virtual ~TexCubeDX9();
+
+ IDirect3DCubeTexture9* GetTexture();
+ bool LoadTexture(Bitmap* bmp, int face);
+
+private:
+ VideoDX9* video;
+ IDirect3D9* d3d;
+ IDirect3DDevice9* d3ddevice;
+
+ IDirect3DCubeTexture9* texture;
+ Bitmap* faces[6];
+ DWORD last_modified[6];
+};
+
+#endif // TexCubeDX9_h
+
diff --git a/Magic2/TextureMapDialog.cpp b/Magic2/TextureMapDialog.cpp
index e62e066..f7085a1 100644
--- a/Magic2/TextureMapDialog.cpp
+++ b/Magic2/TextureMapDialog.cpp
@@ -1,185 +1,209 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: TextureMapDialog.cpp
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Texture Mapping Dialog implementation file
-*/
-
-
-#include "stdafx.h"
-#include "Magic.h"
-#include "MagicDoc.h"
-#include "MagicView.h"
-#include "Selection.h"
-#include "TextureMapDialog.h"
-#include "Thumbnail.h"
-
-#include "Bitmap.h"
-#include "Solid.h"
-#include "Polygon.h"
-#include "Pcx.h"
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
-#endif
-
-// +--------------------------------------------------------------------+
-// TextureMapDialog dialog
-// +--------------------------------------------------------------------+
-
-TextureMapDialog::TextureMapDialog(MagicView* pParent)
- : CDialog(TextureMapDialog::IDD, pParent), doc(0), material(0), model(0), blank(0)
-{
- //{{AFX_DATA_INIT(TextureMapDialog)
- mMaterialIndex = -1;
- mFlip = FALSE;
- mMirror = FALSE;
- mRotate = FALSE;
- mScaleV = 0.0;
- mAxis = -1;
- mScaleU = 0.0;
- mMapType = -1;
- //}}AFX_DATA_INIT
-
- Color gray = Color::LightGray;
- blank = new Bitmap(1,1,&gray);
- blank->ScaleTo(128,128);
-
- if (pParent) {
- doc = pParent->GetDocument();
-
- if (doc && doc->GetSolid()) {
- model = doc->GetSolid()->GetModel();
- }
-
- if (doc && doc->GetSelection()) {
- Selection* seln = doc->GetSelection();
-
- if (seln->GetPolys().size() > 0) {
- material = seln->GetPolys().first()->material;
- mMaterialIndex = model->GetMaterials().index(material) + 1;
- }
- }
- }
-}
-
-TextureMapDialog::~TextureMapDialog()
-{
- delete blank;
-}
-
-void TextureMapDialog::DoDataExchange(CDataExchange* pDX)
-{
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(TextureMapDialog)
- DDX_Control(pDX, IDC_MAPPING, mMapping);
- DDX_Control(pDX, IDC_MATERIAL, mMaterialList);
- DDX_Control(pDX, IDC_TEXTURE_PREVIEW, mMaterialThumb);
- DDX_CBIndex(pDX, IDC_MATERIAL, mMaterialIndex);
- DDX_Check(pDX, IDC_ALIGN_FLIP, mFlip);
- DDX_Check(pDX, IDC_ALIGN_MIRROR, mMirror);
- DDX_Check(pDX, IDC_ALIGN_ROTATE, mRotate);
- DDX_Text(pDX, IDC_SCALE_V, mScaleV);
- DDX_Radio(pDX, IDC_ALIGN_X, mAxis);
- DDX_Text(pDX, IDC_SCALE_U, mScaleU);
- DDX_CBIndex(pDX, IDC_MAPPING, mMapType);
- //}}AFX_DATA_MAP
-
- if (pDX->m_bSaveAndValidate) {
- mMaterialIndex = mMaterialList.GetCurSel()-1;
- }
-}
-
-
-BEGIN_MESSAGE_MAP(TextureMapDialog, CDialog)
- //{{AFX_MSG_MAP(TextureMapDialog)
- ON_WM_PAINT()
- ON_CBN_SELCHANGE(IDC_MATERIAL, OnSelectMaterial)
- ON_BN_CLICKED(IDC_ALIGN_X, OnAlign)
- ON_BN_CLICKED(IDC_ALIGN_Y, OnAlign)
- ON_BN_CLICKED(IDC_ALIGN_Z, OnAlign)
- //}}AFX_MSG_MAP
-END_MESSAGE_MAP()
-
-// +--------------------------------------------------------------------+
-// TextureMapDialog message handlers
-// +--------------------------------------------------------------------+
-
-BOOL TextureMapDialog::OnInitDialog()
-{
- CDialog::OnInitDialog();
-
- mMaterialList.AddString("<none>");
-
- if (model && model->NumMaterials()) {
- ListIter<Material> iter = model->GetMaterials();
- while (++iter) {
- Material* mtl = iter.value();
- mMaterialList.AddString(mtl->name);
- }
- }
-
- mMaterialList.SetCurSel(mMaterialIndex);
- mMapping.SetCurSel(0);
-
- if (material) {
- material->CreateThumbnail();
- ThumbPreview(mMaterialThumb.GetSafeHwnd(), material->thumbnail);
- }
-
- return TRUE;
-}
-
-// +--------------------------------------------------------------------+
-
-void TextureMapDialog::OnPaint()
-{
- CPaintDC dc(this); // device context for painting
-
- if (material && material->thumbnail) {
- ThumbPreview(mMaterialThumb.GetSafeHwnd(), material->thumbnail);
- }
- else {
- ThumbPreview(mMaterialThumb.GetSafeHwnd(), blank);
- }
-}
-
-void TextureMapDialog::OnSelectMaterial()
-{
- mMaterialIndex = mMaterialList.GetCurSel()-1;
- material = 0;
-
- if (model && mMaterialIndex >= 0 && mMaterialIndex < model->NumMaterials()) {
- material = model->GetMaterials()[mMaterialIndex];
- }
-
- if (material) {
- material->CreateThumbnail();
- ThumbPreview(mMaterialThumb.GetSafeHwnd(), material->thumbnail);
- }
- else {
- ThumbPreview(mMaterialThumb.GetSafeHwnd(), blank);
- }
-}
-
-void TextureMapDialog::OnAlign()
-{
- if (mMapping.GetCurSel() == 0) {
- mMapping.SetCurSel(1);
- UpdateData(TRUE);
-
- mScaleU = 1;
- mScaleV = 1;
- mMaterialIndex++;
- UpdateData(FALSE);
- }
-}
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: TextureMapDialog.cpp
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Texture Mapping Dialog implementation file
+*/
+
+
+#include "stdafx.h"
+#include "Magic.h"
+#include "MagicDoc.h"
+#include "MagicView.h"
+#include "Selection.h"
+#include "TextureMapDialog.h"
+#include "Thumbnail.h"
+
+#include "Bitmap.h"
+#include "Solid.h"
+#include "Polygon.h"
+#include "Pcx.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+// +--------------------------------------------------------------------+
+// TextureMapDialog dialog
+// +--------------------------------------------------------------------+
+
+TextureMapDialog::TextureMapDialog(MagicView* pParent)
+ : CDialog(TextureMapDialog::IDD, pParent), doc(0), material(0), model(0), blank(0)
+{
+ //{{AFX_DATA_INIT(TextureMapDialog)
+ mMaterialIndex = -1;
+ mFlip = FALSE;
+ mMirror = FALSE;
+ mRotate = FALSE;
+ mScaleV = 0.0;
+ mAxis = -1;
+ mScaleU = 0.0;
+ mMapType = -1;
+ //}}AFX_DATA_INIT
+
+ Color gray = Color::LightGray;
+ blank = new Bitmap(1,1,&gray);
+ blank->ScaleTo(128,128);
+
+ if (pParent) {
+ doc = pParent->GetDocument();
+
+ if (doc && doc->GetSolid()) {
+ model = doc->GetSolid()->GetModel();
+ }
+
+ if (doc && doc->GetSelection()) {
+ Selection* seln = doc->GetSelection();
+
+ if (seln->GetPolys().size() > 0) {
+ material = seln->GetPolys().first()->material;
+ mMaterialIndex = model->GetMaterials().index(material) + 1;
+ }
+ }
+ }
+}
+
+TextureMapDialog::~TextureMapDialog()
+{
+ delete blank;
+}
+
+void TextureMapDialog::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(TextureMapDialog)
+ DDX_Control(pDX, IDC_MAPPING, mMapping);
+ DDX_Control(pDX, IDC_MATERIAL, mMaterialList);
+ DDX_Control(pDX, IDC_TEXTURE_PREVIEW, mMaterialThumb);
+ DDX_CBIndex(pDX, IDC_MATERIAL, mMaterialIndex);
+ DDX_Check(pDX, IDC_ALIGN_FLIP, mFlip);
+ DDX_Check(pDX, IDC_ALIGN_MIRROR, mMirror);
+ DDX_Check(pDX, IDC_ALIGN_ROTATE, mRotate);
+ DDX_Text(pDX, IDC_SCALE_V, mScaleV);
+ DDX_Radio(pDX, IDC_ALIGN_X, mAxis);
+ DDX_Text(pDX, IDC_SCALE_U, mScaleU);
+ DDX_CBIndex(pDX, IDC_MAPPING, mMapType);
+ //}}AFX_DATA_MAP
+
+ if (pDX->m_bSaveAndValidate) {
+ mMaterialIndex = mMaterialList.GetCurSel()-1;
+ }
+}
+
+
+BEGIN_MESSAGE_MAP(TextureMapDialog, CDialog)
+ //{{AFX_MSG_MAP(TextureMapDialog)
+ ON_WM_PAINT()
+ ON_CBN_SELCHANGE(IDC_MATERIAL, OnSelectMaterial)
+ ON_BN_CLICKED(IDC_ALIGN_X, OnAlign)
+ ON_BN_CLICKED(IDC_ALIGN_Y, OnAlign)
+ ON_BN_CLICKED(IDC_ALIGN_Z, OnAlign)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+// +--------------------------------------------------------------------+
+// TextureMapDialog message handlers
+// +--------------------------------------------------------------------+
+
+BOOL TextureMapDialog::OnInitDialog()
+{
+ CDialog::OnInitDialog();
+
+ mMaterialList.AddString("<none>");
+
+ if (model && model->NumMaterials()) {
+ ListIter<Material> iter = model->GetMaterials();
+ while (++iter) {
+ Material* mtl = iter.value();
+ mMaterialList.AddString(mtl->name);
+ }
+ }
+
+ mMaterialList.SetCurSel(mMaterialIndex);
+ mMapping.SetCurSel(0);
+
+ if (material) {
+ material->CreateThumbnail();
+ ThumbPreview(mMaterialThumb.GetSafeHwnd(), material->thumbnail);
+ }
+
+ return TRUE;
+}
+
+// +--------------------------------------------------------------------+
+
+void TextureMapDialog::OnPaint()
+{
+ CPaintDC dc(this); // device context for painting
+
+ if (material && material->thumbnail) {
+ ThumbPreview(mMaterialThumb.GetSafeHwnd(), material->thumbnail);
+ }
+ else {
+ ThumbPreview(mMaterialThumb.GetSafeHwnd(), blank);
+ }
+}
+
+void TextureMapDialog::OnSelectMaterial()
+{
+ mMaterialIndex = mMaterialList.GetCurSel()-1;
+ material = 0;
+
+ if (model && mMaterialIndex >= 0 && mMaterialIndex < model->NumMaterials()) {
+ material = model->GetMaterials()[mMaterialIndex];
+ }
+
+ if (material) {
+ material->CreateThumbnail();
+ ThumbPreview(mMaterialThumb.GetSafeHwnd(), material->thumbnail);
+ }
+ else {
+ ThumbPreview(mMaterialThumb.GetSafeHwnd(), blank);
+ }
+}
+
+void TextureMapDialog::OnAlign()
+{
+ if (mMapping.GetCurSel() == 0) {
+ mMapping.SetCurSel(1);
+ UpdateData(TRUE);
+
+ mScaleU = 1;
+ mScaleV = 1;
+ mMaterialIndex++;
+ UpdateData(FALSE);
+ }
+}
diff --git a/Magic2/TextureMapDialog.h b/Magic2/TextureMapDialog.h
index 3ca1791..aeb6f30 100644
--- a/Magic2/TextureMapDialog.h
+++ b/Magic2/TextureMapDialog.h
@@ -1,85 +1,109 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: TextureMapDialog.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Texture Mapping Dialog interface file
-*/
-
-#if !defined(AFX_TEXTUREMAPDIALOG_H__F8EDA550_FF19_4E91_9A9C_597FC357C563__INCLUDED_)
-#define AFX_TEXTUREMAPDIALOG_H__F8EDA550_FF19_4E91_9A9C_597FC357C563__INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif
-
-// +--------------------------------------------------------------------+
-
-class Bitmap;
-class MagicDoc;
-class MagicView;
-struct Material;
-class Model;
-
-// +--------------------------------------------------------------------+
-// TextureMapDialog dialog
-// +--------------------------------------------------------------------+
-
-class TextureMapDialog : public CDialog
-{
-// Construction
-public:
- TextureMapDialog(MagicView* pParent = NULL);
- virtual ~TextureMapDialog();
-
-// Dialog Data
- //{{AFX_DATA(TextureMapDialog)
- enum { IDD = IDD_MODIFY_TEXTURE };
- CComboBox mMapping;
- CComboBox mMaterialList;
- CStatic mMaterialThumb;
- int mMaterialIndex;
- BOOL mFlip;
- BOOL mMirror;
- BOOL mRotate;
- double mScaleV;
- int mAxis;
- double mScaleU;
- int mMapType;
- //}}AFX_DATA
-
-
-// Overrides
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(TextureMapDialog)
- protected:
- virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
- //}}AFX_VIRTUAL
-
-// Implementation
-protected:
- MagicDoc* doc;
- Material* material;
- Model* model;
- Bitmap* blank;
-
- // Generated message map functions
- //{{AFX_MSG(TextureMapDialog)
- virtual BOOL OnInitDialog();
- afx_msg void OnPaint();
- afx_msg void OnSelectMaterial();
- afx_msg void OnAlign();
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
-};
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
-
-#endif
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: TextureMapDialog.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Texture Mapping Dialog interface file
+*/
+
+#if !defined(AFX_TEXTUREMAPDIALOG_H__F8EDA550_FF19_4E91_9A9C_597FC357C563__INCLUDED_)
+#define AFX_TEXTUREMAPDIALOG_H__F8EDA550_FF19_4E91_9A9C_597FC357C563__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+// +--------------------------------------------------------------------+
+
+class Bitmap;
+class MagicDoc;
+class MagicView;
+struct Material;
+class Model;
+
+// +--------------------------------------------------------------------+
+// TextureMapDialog dialog
+// +--------------------------------------------------------------------+
+
+class TextureMapDialog : public CDialog
+{
+// Construction
+public:
+ TextureMapDialog(MagicView* pParent = NULL);
+ virtual ~TextureMapDialog();
+
+// Dialog Data
+ //{{AFX_DATA(TextureMapDialog)
+ enum { IDD = IDD_MODIFY_TEXTURE };
+ CComboBox mMapping;
+ CComboBox mMaterialList;
+ CStatic mMaterialThumb;
+ int mMaterialIndex;
+ BOOL mFlip;
+ BOOL mMirror;
+ BOOL mRotate;
+ double mScaleV;
+ int mAxis;
+ double mScaleU;
+ int mMapType;
+ //}}AFX_DATA
+
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(TextureMapDialog)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+ MagicDoc* doc;
+ Material* material;
+ Model* model;
+ Bitmap* blank;
+
+ // Generated message map functions
+ //{{AFX_MSG(TextureMapDialog)
+ virtual BOOL OnInitDialog();
+ afx_msg void OnPaint();
+ afx_msg void OnSelectMaterial();
+ afx_msg void OnAlign();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif
diff --git a/Magic2/Thumbnail.cpp b/Magic2/Thumbnail.cpp
index f855084..28bacbb 100644
--- a/Magic2/Thumbnail.cpp
+++ b/Magic2/Thumbnail.cpp
@@ -1,57 +1,81 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: Thumbnail.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Thumbnail.cpp : implementation file
-*/
-
-#include "stdafx.h"
-#include "Bitmap.h"
-
-// +--------------------------------------------------------------------+
-// Preview a bitmap image in the desired window
-// +--------------------------------------------------------------------+
-
-void ThumbPreview(HWND hprev, Bitmap* bitmap)
-{
- HDC hdc = ::GetDC(hprev);
- RECT rect;
- BITMAPINFO* pbmiDIB = new BITMAPINFO;
-
- if (!pbmiDIB)
- return;
-
- ::GetClientRect(hprev, &rect);
-
- pbmiDIB->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- pbmiDIB->bmiHeader.biWidth = bitmap->Width();
- pbmiDIB->bmiHeader.biHeight = -bitmap->Height();
- pbmiDIB->bmiHeader.biPlanes = 1;
- pbmiDIB->bmiHeader.biBitCount = 32;
- pbmiDIB->bmiHeader.biCompression = BI_RGB;
- pbmiDIB->bmiHeader.biSizeImage = 0;
- pbmiDIB->bmiHeader.biXPelsPerMeter = 0;
- pbmiDIB->bmiHeader.biYPelsPerMeter = 0;
- pbmiDIB->bmiHeader.biClrUsed = 0;
- pbmiDIB->bmiHeader.biClrImportant = 0;
-
- int result =
- ::StretchDIBits(hdc,
- 1, 1, 128, 128,
- 0, 0, bitmap->Width(), bitmap->Height(),
- bitmap->HiPixels(),
- pbmiDIB,
- DIB_RGB_COLORS,
- SRCCOPY);
-
- ::ReleaseDC(hprev, hdc);
-
- delete pbmiDIB;
-}
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: Thumbnail.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Thumbnail.cpp : implementation file
+*/
+
+#include "stdafx.h"
+#include "Bitmap.h"
+
+// +--------------------------------------------------------------------+
+// Preview a bitmap image in the desired window
+// +--------------------------------------------------------------------+
+
+void ThumbPreview(HWND hprev, Bitmap* bitmap)
+{
+ HDC hdc = ::GetDC(hprev);
+ RECT rect;
+ BITMAPINFO* pbmiDIB = new BITMAPINFO;
+
+ if (!pbmiDIB)
+ return;
+
+ ::GetClientRect(hprev, &rect);
+
+ pbmiDIB->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ pbmiDIB->bmiHeader.biWidth = bitmap->Width();
+ pbmiDIB->bmiHeader.biHeight = -bitmap->Height();
+ pbmiDIB->bmiHeader.biPlanes = 1;
+ pbmiDIB->bmiHeader.biBitCount = 32;
+ pbmiDIB->bmiHeader.biCompression = BI_RGB;
+ pbmiDIB->bmiHeader.biSizeImage = 0;
+ pbmiDIB->bmiHeader.biXPelsPerMeter = 0;
+ pbmiDIB->bmiHeader.biYPelsPerMeter = 0;
+ pbmiDIB->bmiHeader.biClrUsed = 0;
+ pbmiDIB->bmiHeader.biClrImportant = 0;
+
+ int result =
+ ::StretchDIBits(hdc,
+ 1, 1, 128, 128,
+ 0, 0, bitmap->Width(), bitmap->Height(),
+ bitmap->HiPixels(),
+ pbmiDIB,
+ DIB_RGB_COLORS,
+ SRCCOPY);
+
+ ::ReleaseDC(hprev, hdc);
+
+ delete pbmiDIB;
+}
diff --git a/Magic2/Thumbnail.h b/Magic2/Thumbnail.h
index 1f7acfc..9300fb9 100644
--- a/Magic2/Thumbnail.h
+++ b/Magic2/Thumbnail.h
@@ -1,31 +1,55 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: Thumbnail.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Function declarations for thumbnail img previewer
-*/
-
-#ifndef Thumbnail_h
-#define Thumbnail_h
-
-#ifndef __AFXWIN_H__
- #error include 'stdafx.h' before including 'Thumbnail.h' file for PCH
-#endif
-
-// +--------------------------------------------------------------------+
-
-class Bitmap;
-
-// +--------------------------------------------------------------------+
-
-void ThumbPreview(HWND hprev, Bitmap* bitmap);
-
-#endif Thumbnail_h
-
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: Thumbnail.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Function declarations for thumbnail img previewer
+*/
+
+#ifndef Thumbnail_h
+#define Thumbnail_h
+
+#ifndef __AFXWIN_H__
+ #error include 'stdafx.h' before including 'Thumbnail.h' file for PCH
+#endif
+
+// +--------------------------------------------------------------------+
+
+class Bitmap;
+
+// +--------------------------------------------------------------------+
+
+void ThumbPreview(HWND hprev, Bitmap* bitmap);
+
+#endif Thumbnail_h
+
diff --git a/Magic2/UVMapView.cpp b/Magic2/UVMapView.cpp
index 673745f..d775b5c 100644
--- a/Magic2/UVMapView.cpp
+++ b/Magic2/UVMapView.cpp
@@ -1,450 +1,474 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: UVMapView.cpp
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Implementation of the UVMapView class
-*/
-
-#include "stdafx.h"
-#include "Magic.h"
-
-#include "MagicDoc.h"
-#include "UVMapView.h"
-#include "Selector.h"
-#include "Selection.h"
-
-#include "ActiveWindow.h"
-#include "Color.h"
-#include "Screen.h"
-#include "Video.h"
-
-DWORD GetRealTime();
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
-#endif
-
-// +--------------------------------------------------------------------+
-
-UVMapView::UVMapView(Window* c)
- : View(c), material(0), zoom(1), x_offset(0), y_offset(0),
- nmarks(0), select_mode(SELECT_REPLACE), active(false)
-{
-}
-
-UVMapView::~UVMapView()
-{
-}
-
-// +--------------------------------------------------------------------+
-
-const int BATCH_SIZE = 64;
-
-void
-UVMapView::Refresh()
-{
- video = Video::GetInstance();
- if (!video)
- return;
-
- window->FillRect(window->GetRect(), Color::LightGray);
-
- if (material && material->tex_diffuse) {
- Bitmap* bmp = material->tex_diffuse;
- int w = bmp->Width();
- int h = bmp->Height();
-
- double cx = window->Width() / 2 + x_offset;
- double cy = window->Height() / 2 + y_offset;
-
- int x1 = (int) (cx - (zoom * w/2));
- int x2 = (int) (cx + (zoom * w/2));
- int y1 = (int) (cy - (zoom * h/2));
- int y2 = (int) (cy + (zoom * h/2));
-
- window->DrawBitmap(x1, y1, x2, y2, bmp);
-
- ListIter<Poly> iter = polys;
- while (++iter) {
- Poly* p = iter.value();
- VertexSet* vset = p->vertex_set;
-
- if (p->material != material)
- continue;
-
- for (int i = 0; i < p->nverts; i++) {
- int n1 = p->verts[i];
- int n2 = p->verts[0];
- if (i < p->nverts-1)
- n2 = p->verts[i+1];
-
- double tu1 = vset->tu[n1];
- double tv1 = vset->tv[n1];
- double tu2 = vset->tu[n2];
- double tv2 = vset->tv[n2];
-
- x1 = (int) (cx + zoom * w * (tu1-0.5));
- x2 = (int) (cx + zoom * w * (tu2-0.5));
- y1 = (int) (cy + zoom * h * (tv1-0.5));
- y2 = (int) (cy + zoom * h * (tv2-0.5));
-
- window->DrawLine(x1, y1, x2, y2, Color::Yellow);
-
- if (IsSelected(p, i))
- window->FillRect(x1-3, y1-3, x1+3, y1+3, Color::Yellow);
- else
- window->DrawRect(x1-2, y1-2, x1+2, y1+2, Color::Yellow);
- }
- }
- }
-
- if (active && nmarks > 1) {
- float points[4*BATCH_SIZE + 4];
-
- for (int batch = 0; batch < nmarks; batch += BATCH_SIZE) {
- int end = batch + BATCH_SIZE;
- if (end > nmarks-1)
- end = nmarks-1;
- int nlines = end-batch;
-
- for (int i = 0; i < nlines; i++) {
- points[4*i+0] = (float) marks[batch + i].x;
- points[4*i+1] = (float) marks[batch + i].y;
- points[4*i+2] = (float) marks[batch + i + 1].x;
- points[4*i+3] = (float) marks[batch + i + 1].y;
- }
-
- video->DrawScreenLines(nlines, points, Color::Cyan);
- }
- }
-
- const char* title = "UV Editor";
-
- int len = strlen(title);
- Rect r(6,4,200,20);
-
- r.x += window->GetRect().x;
- r.y += window->GetRect().y;
-
- video->DrawText(title, len, r, DT_LEFT|DT_SINGLELINE, Color::Black);
-
- r.x--;
- r.y--;
-
- video->DrawText(title, len, r, DT_LEFT|DT_SINGLELINE, Color::White);
-}
-
-// +--------------------------------------------------------------------+
-
-void
-UVMapView::UseMaterial(Material* m)
-{
- if (material != m) {
- material = m;
- zoom = 1;
- x_offset = 0;
- y_offset = 0;
- }
-}
-
-void
-UVMapView::UsePolys(List<Poly>& p)
-{
- polys.clear();
- polys.append(p);
-}
-
-void
-UVMapView::MoveBy(double dx, double dy)
-{
- x_offset += dx;
- y_offset += dy;
-}
-
-void
-UVMapView::DragBy(double dx, double dy)
-{
- if (!material || !material->tex_diffuse || selverts.size() < 1)
- return;
-
- Bitmap* bmp = material->tex_diffuse;
- double w = zoom * bmp->Width();
- double h = zoom * bmp->Height();
- float du = (float) (dx/w);
- float dv = (float) (dy/h);
-
- for (auto svi = selverts.begin(); svi != selverts.end(); ++svi) {
- DWORD value = *svi;
- DWORD p = value >> 16;
- DWORD n = value & 0xffff;
-
- Poly* poly = polys[p];
- if (poly && n < poly->nverts) {
- VertexSet* vset = poly->vertex_set;
- int v = poly->verts[n];
-
- vset->tu[v] += du;
- vset->tv[v] += dv;
- }
- }
-}
-
-// +----------------------------------------------------------------------+
-
-void
-UVMapView::Clear()
-{
- selverts.clear();
-}
-
-void
-UVMapView::Begin(int seln_mode)
-{
- nmarks = 0;
- select_mode = seln_mode;
- active = true;
-}
-
-void
-UVMapView::AddMark(CPoint& p)
-{
- if (nmarks < MAX_MARK)
- marks[nmarks++] = p;
-}
-
-void
-UVMapView::End()
-{
- active = false;
-
- // get the model:
- if (!nmarks || !material || !material->tex_diffuse) return;
-
- // if not adding to selection:
- if (select_mode == SELECT_REPLACE) {
- Clear();
- }
-
- Bitmap* bmp = material->tex_diffuse;
- int w = bmp->Width();
- int h = bmp->Height();
-
- double cx = window->Width() / 2 + x_offset;
- double cy = window->Height() / 2 + y_offset;
-
-
- // if only one mark:
- if (nmarks < 2) {
- // find all selected verts:
- ListIter<Poly> iter = polys;
- while (++iter) {
- Poly* p = iter.value();
- VertexSet* vset = p->vertex_set;
-
- for (int i = 0; i < p->nverts; i++) {
- int n1 = p->verts[i];
- double tu1 = vset->tu[n1];
- double tv1 = vset->tv[n1];
-
- int x1 = (int) (cx + zoom * w * (tu1-0.5));
- int y1 = (int) (cy + zoom * h * (tv1-0.5));
-
- int dx = abs(marks[0].x - x1);
- int dy = abs(marks[0].y - y1);
-
- if (dx < 4 && dy < 4) {
- WORD p_index = iter.index();
- DWORD value = (p_index << 16) | i;
-
- if (select_mode == SELECT_REMOVE) {
- for (auto svi = selverts.begin(); svi != selverts.end(); ++svi) {
- if (*svi == value) {
- selverts.erase(svi);
- }
- }
- }
- else {
- bool contains = false;
- for (auto svi = selverts.begin(); svi != selverts.end(); ++svi) {
- if (*svi == value) {
- contains = true;
- }
- }
- if (!contains)
- selverts.push_back(value);
- }
- }
- }
- }
- }
-
- // otherwise, build a region:
- else {
- CRgn rgn;
- rgn.CreatePolygonRgn(marks, nmarks, WINDING);
-
- // find all selected verts:
- ListIter<Poly> iter = polys;
- while (++iter) {
- Poly* p = iter.value();
- VertexSet* vset = p->vertex_set;
-
- for (int i = 0; i < p->nverts; i++) {
- int n1 = p->verts[i];
- double tu1 = vset->tu[n1];
- double tv1 = vset->tv[n1];
-
- int x1 = (int) (cx + zoom * w * (tu1-0.5));
- int y1 = (int) (cy + zoom * h * (tv1-0.5));
-
- CPoint p(x1,y1);
-
- if (rgn.PtInRegion(p)) {
- WORD p_index = iter.index();
- DWORD value = (p_index << 16) | i;
-
- if (select_mode == SELECT_REMOVE) {
- for (auto svi = selverts.begin(); svi != selverts.end(); ++svi) {
- if (*svi == value)
- selverts.erase(svi);
- }
- }
- else {
- bool contains = false;
- for (auto svi = selverts.begin(); svi != selverts.end(); ++svi) {
- if (*svi == value)
- contains = true;
- }
- if (!contains)
- selverts.push_back(value);
- }
- }
- }
- }
- }
-
- nmarks = 0;
-}
-
-// +----------------------------------------------------------------------+
-
-void
-UVMapView::SelectAll()
-{
- selverts.clear();
-
- ListIter<Poly> iter = polys;
- while (++iter) {
- Poly* p = iter.value();
-
- if (p->material != material)
- continue;
-
- for (int i = 0; i < p->nverts; i++) {
- WORD p_index = iter.index();
- DWORD value = (p_index << 16) | i;
- selverts.push_back(value);
- }
- }
-}
-
-void
-UVMapView::SelectNone()
-{
- selverts.clear();
-}
-
-void
-UVMapView::SelectInverse()
-{
- ListIter<Poly> iter = polys;
- while (++iter) {
- Poly* p = iter.value();
-
- if (p->material != material)
- continue;
-
- for (int i = 0; i < p->nverts; i++) {
- WORD p_index = iter.index();
- DWORD value = (p_index << 16) | i;
-
- bool contains = false;
- auto svi = selverts.begin();
- for (; svi != selverts.end(); ++svi) {
- if (*svi == value) {
- contains = true;
- break;
- }
- }
-
- if (contains)
- selverts.erase(svi);
- else
- selverts.push_back(value);
- }
- }
-}
-
-bool
-UVMapView::IsSelected(Poly* poly, WORD v)
-{
- WORD p = polys.index(poly);
- DWORD value = (p << 16) | v;
-
- bool contains = false;
-
- for (auto svi = selverts.begin(); svi != selverts.end(); ++svi) {
- if (*svi == value)
- return true;
- }
-
- return false;
-}
-
-bool
-UVMapView::WillSelect(CPoint& p)
-{
- if (!material || !material->tex_diffuse)
- return false;
-
- Bitmap* bmp = material->tex_diffuse;
- int w = bmp->Width();
- int h = bmp->Height();
-
- double cx = window->Width() / 2 + x_offset;
- double cy = window->Height() / 2 + y_offset;
-
- // find first selected vert:
- ListIter<Poly> iter = polys;
- while (++iter) {
- Poly* poly = iter.value();
- VertexSet* vset = poly->vertex_set;
-
- for (int i = 0; i < poly->nverts; i++) {
- int n1 = poly->verts[i];
- double tu1 = vset->tu[n1];
- double tv1 = vset->tv[n1];
-
- int x1 = (int) (cx + zoom * w * (tu1-0.5));
- int y1 = (int) (cy + zoom * h * (tv1-0.5));
-
- int dx = abs(p.x - x1);
- int dy = abs(p.y - y1);
-
- if (dx < 4 && dy < 4) {
- return true;
- }
- }
- }
-
- return false;
-}
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: UVMapView.cpp
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Implementation of the UVMapView class
+*/
+
+#include "stdafx.h"
+#include "Magic.h"
+
+#include "MagicDoc.h"
+#include "UVMapView.h"
+#include "Selector.h"
+#include "Selection.h"
+
+#include "ActiveWindow.h"
+#include "Color.h"
+#include "Screen.h"
+#include "Video.h"
+
+DWORD GetRealTime();
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+// +--------------------------------------------------------------------+
+
+UVMapView::UVMapView(Window* c)
+ : View(c), material(0), zoom(1), x_offset(0), y_offset(0),
+ nmarks(0), select_mode(SELECT_REPLACE), active(false)
+{
+}
+
+UVMapView::~UVMapView()
+{
+}
+
+// +--------------------------------------------------------------------+
+
+const int BATCH_SIZE = 64;
+
+void
+UVMapView::Refresh()
+{
+ video = Video::GetInstance();
+ if (!video)
+ return;
+
+ window->FillRect(window->GetRect(), Color::LightGray);
+
+ if (material && material->tex_diffuse) {
+ Bitmap* bmp = material->tex_diffuse;
+ int w = bmp->Width();
+ int h = bmp->Height();
+
+ double cx = window->Width() / 2 + x_offset;
+ double cy = window->Height() / 2 + y_offset;
+
+ int x1 = (int) (cx - (zoom * w/2));
+ int x2 = (int) (cx + (zoom * w/2));
+ int y1 = (int) (cy - (zoom * h/2));
+ int y2 = (int) (cy + (zoom * h/2));
+
+ window->DrawBitmap(x1, y1, x2, y2, bmp);
+
+ ListIter<Poly> iter = polys;
+ while (++iter) {
+ Poly* p = iter.value();
+ VertexSet* vset = p->vertex_set;
+
+ if (p->material != material)
+ continue;
+
+ for (int i = 0; i < p->nverts; i++) {
+ int n1 = p->verts[i];
+ int n2 = p->verts[0];
+ if (i < p->nverts-1)
+ n2 = p->verts[i+1];
+
+ double tu1 = vset->tu[n1];
+ double tv1 = vset->tv[n1];
+ double tu2 = vset->tu[n2];
+ double tv2 = vset->tv[n2];
+
+ x1 = (int) (cx + zoom * w * (tu1-0.5));
+ x2 = (int) (cx + zoom * w * (tu2-0.5));
+ y1 = (int) (cy + zoom * h * (tv1-0.5));
+ y2 = (int) (cy + zoom * h * (tv2-0.5));
+
+ window->DrawLine(x1, y1, x2, y2, Color::Yellow);
+
+ if (IsSelected(p, i))
+ window->FillRect(x1-3, y1-3, x1+3, y1+3, Color::Yellow);
+ else
+ window->DrawRect(x1-2, y1-2, x1+2, y1+2, Color::Yellow);
+ }
+ }
+ }
+
+ if (active && nmarks > 1) {
+ float points[4*BATCH_SIZE + 4];
+
+ for (int batch = 0; batch < nmarks; batch += BATCH_SIZE) {
+ int end = batch + BATCH_SIZE;
+ if (end > nmarks-1)
+ end = nmarks-1;
+ int nlines = end-batch;
+
+ for (int i = 0; i < nlines; i++) {
+ points[4*i+0] = (float) marks[batch + i].x;
+ points[4*i+1] = (float) marks[batch + i].y;
+ points[4*i+2] = (float) marks[batch + i + 1].x;
+ points[4*i+3] = (float) marks[batch + i + 1].y;
+ }
+
+ video->DrawScreenLines(nlines, points, Color::Cyan);
+ }
+ }
+
+ const char* title = "UV Editor";
+
+ int len = strlen(title);
+ Rect r(6,4,200,20);
+
+ r.x += window->GetRect().x;
+ r.y += window->GetRect().y;
+
+ video->DrawText(title, len, r, DT_LEFT|DT_SINGLELINE, Color::Black);
+
+ r.x--;
+ r.y--;
+
+ video->DrawText(title, len, r, DT_LEFT|DT_SINGLELINE, Color::White);
+}
+
+// +--------------------------------------------------------------------+
+
+void
+UVMapView::UseMaterial(Material* m)
+{
+ if (material != m) {
+ material = m;
+ zoom = 1;
+ x_offset = 0;
+ y_offset = 0;
+ }
+}
+
+void
+UVMapView::UsePolys(List<Poly>& p)
+{
+ polys.clear();
+ polys.append(p);
+}
+
+void
+UVMapView::MoveBy(double dx, double dy)
+{
+ x_offset += dx;
+ y_offset += dy;
+}
+
+void
+UVMapView::DragBy(double dx, double dy)
+{
+ if (!material || !material->tex_diffuse || selverts.size() < 1)
+ return;
+
+ Bitmap* bmp = material->tex_diffuse;
+ double w = zoom * bmp->Width();
+ double h = zoom * bmp->Height();
+ float du = (float) (dx/w);
+ float dv = (float) (dy/h);
+
+ for (auto svi = selverts.begin(); svi != selverts.end(); ++svi) {
+ DWORD value = *svi;
+ DWORD p = value >> 16;
+ DWORD n = value & 0xffff;
+
+ Poly* poly = polys[p];
+ if (poly && n < poly->nverts) {
+ VertexSet* vset = poly->vertex_set;
+ int v = poly->verts[n];
+
+ vset->tu[v] += du;
+ vset->tv[v] += dv;
+ }
+ }
+}
+
+// +----------------------------------------------------------------------+
+
+void
+UVMapView::Clear()
+{
+ selverts.clear();
+}
+
+void
+UVMapView::Begin(int seln_mode)
+{
+ nmarks = 0;
+ select_mode = seln_mode;
+ active = true;
+}
+
+void
+UVMapView::AddMark(CPoint& p)
+{
+ if (nmarks < MAX_MARK)
+ marks[nmarks++] = p;
+}
+
+void
+UVMapView::End()
+{
+ active = false;
+
+ // get the model:
+ if (!nmarks || !material || !material->tex_diffuse) return;
+
+ // if not adding to selection:
+ if (select_mode == SELECT_REPLACE) {
+ Clear();
+ }
+
+ Bitmap* bmp = material->tex_diffuse;
+ int w = bmp->Width();
+ int h = bmp->Height();
+
+ double cx = window->Width() / 2 + x_offset;
+ double cy = window->Height() / 2 + y_offset;
+
+
+ // if only one mark:
+ if (nmarks < 2) {
+ // find all selected verts:
+ ListIter<Poly> iter = polys;
+ while (++iter) {
+ Poly* p = iter.value();
+ VertexSet* vset = p->vertex_set;
+
+ for (int i = 0; i < p->nverts; i++) {
+ int n1 = p->verts[i];
+ double tu1 = vset->tu[n1];
+ double tv1 = vset->tv[n1];
+
+ int x1 = (int) (cx + zoom * w * (tu1-0.5));
+ int y1 = (int) (cy + zoom * h * (tv1-0.5));
+
+ int dx = abs(marks[0].x - x1);
+ int dy = abs(marks[0].y - y1);
+
+ if (dx < 4 && dy < 4) {
+ WORD p_index = iter.index();
+ DWORD value = (p_index << 16) | i;
+
+ if (select_mode == SELECT_REMOVE) {
+ for (auto svi = selverts.begin(); svi != selverts.end(); ++svi) {
+ if (*svi == value) {
+ selverts.erase(svi);
+ }
+ }
+ }
+ else {
+ bool contains = false;
+ for (auto svi = selverts.begin(); svi != selverts.end(); ++svi) {
+ if (*svi == value) {
+ contains = true;
+ }
+ }
+ if (!contains)
+ selverts.push_back(value);
+ }
+ }
+ }
+ }
+ }
+
+ // otherwise, build a region:
+ else {
+ CRgn rgn;
+ rgn.CreatePolygonRgn(marks, nmarks, WINDING);
+
+ // find all selected verts:
+ ListIter<Poly> iter = polys;
+ while (++iter) {
+ Poly* p = iter.value();
+ VertexSet* vset = p->vertex_set;
+
+ for (int i = 0; i < p->nverts; i++) {
+ int n1 = p->verts[i];
+ double tu1 = vset->tu[n1];
+ double tv1 = vset->tv[n1];
+
+ int x1 = (int) (cx + zoom * w * (tu1-0.5));
+ int y1 = (int) (cy + zoom * h * (tv1-0.5));
+
+ CPoint p(x1,y1);
+
+ if (rgn.PtInRegion(p)) {
+ WORD p_index = iter.index();
+ DWORD value = (p_index << 16) | i;
+
+ if (select_mode == SELECT_REMOVE) {
+ for (auto svi = selverts.begin(); svi != selverts.end(); ++svi) {
+ if (*svi == value)
+ selverts.erase(svi);
+ }
+ }
+ else {
+ bool contains = false;
+ for (auto svi = selverts.begin(); svi != selverts.end(); ++svi) {
+ if (*svi == value)
+ contains = true;
+ }
+ if (!contains)
+ selverts.push_back(value);
+ }
+ }
+ }
+ }
+ }
+
+ nmarks = 0;
+}
+
+// +----------------------------------------------------------------------+
+
+void
+UVMapView::SelectAll()
+{
+ selverts.clear();
+
+ ListIter<Poly> iter = polys;
+ while (++iter) {
+ Poly* p = iter.value();
+
+ if (p->material != material)
+ continue;
+
+ for (int i = 0; i < p->nverts; i++) {
+ WORD p_index = iter.index();
+ DWORD value = (p_index << 16) | i;
+ selverts.push_back(value);
+ }
+ }
+}
+
+void
+UVMapView::SelectNone()
+{
+ selverts.clear();
+}
+
+void
+UVMapView::SelectInverse()
+{
+ ListIter<Poly> iter = polys;
+ while (++iter) {
+ Poly* p = iter.value();
+
+ if (p->material != material)
+ continue;
+
+ for (int i = 0; i < p->nverts; i++) {
+ WORD p_index = iter.index();
+ DWORD value = (p_index << 16) | i;
+
+ bool contains = false;
+ auto svi = selverts.begin();
+ for (; svi != selverts.end(); ++svi) {
+ if (*svi == value) {
+ contains = true;
+ break;
+ }
+ }
+
+ if (contains)
+ selverts.erase(svi);
+ else
+ selverts.push_back(value);
+ }
+ }
+}
+
+bool
+UVMapView::IsSelected(Poly* poly, WORD v)
+{
+ WORD p = polys.index(poly);
+ DWORD value = (p << 16) | v;
+
+ bool contains = false;
+
+ for (auto svi = selverts.begin(); svi != selverts.end(); ++svi) {
+ if (*svi == value)
+ return true;
+ }
+
+ return false;
+}
+
+bool
+UVMapView::WillSelect(CPoint& p)
+{
+ if (!material || !material->tex_diffuse)
+ return false;
+
+ Bitmap* bmp = material->tex_diffuse;
+ int w = bmp->Width();
+ int h = bmp->Height();
+
+ double cx = window->Width() / 2 + x_offset;
+ double cy = window->Height() / 2 + y_offset;
+
+ // find first selected vert:
+ ListIter<Poly> iter = polys;
+ while (++iter) {
+ Poly* poly = iter.value();
+ VertexSet* vset = poly->vertex_set;
+
+ for (int i = 0; i < poly->nverts; i++) {
+ int n1 = poly->verts[i];
+ double tu1 = vset->tu[n1];
+ double tv1 = vset->tv[n1];
+
+ int x1 = (int) (cx + zoom * w * (tu1-0.5));
+ int y1 = (int) (cy + zoom * h * (tv1-0.5));
+
+ int dx = abs(p.x - x1);
+ int dy = abs(p.y - y1);
+
+ if (dx < 4 && dy < 4) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
diff --git a/Magic2/UVMapView.h b/Magic2/UVMapView.h
index fb40cbf..10e63c7 100644
--- a/Magic2/UVMapView.h
+++ b/Magic2/UVMapView.h
@@ -1,82 +1,106 @@
-/* Project Magic 2.0
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Magic.exe
- FILE: UVMapView.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Interface of the UVMapView class
-*/
-
-
-#ifndef UVMapView_h
-#define UVMapView_h
-
-#include <vector>
-#include "View.h"
-#include "Polygon.h"
-#include "List.h"
-
-// +--------------------------------------------------------------------+
-
-class Video;
-
-// +--------------------------------------------------------------------+
-
-class UVMapView : public View
-{
-public:
- UVMapView(Window* c);
- virtual ~UVMapView();
-
- enum SELECT_MODE { SELECT_REMOVE=-1, SELECT_REPLACE=0, SELECT_APPEND=1 };
-
- virtual void Refresh();
-
- void UseMaterial(Material* m);
- void UsePolys(List<Poly>& p);
-
- void MoveBy(double dx, double dy);
- void DragBy(double dx, double dy);
- void ZoomIn() { zoom *= 1.15; }
- void ZoomOut() { zoom *= 0.85; }
-
- void Clear();
- void Begin(int select_mode = SELECT_REPLACE);
- void AddMark(CPoint& p);
- void End();
-
- bool IsActive() const { return active; }
- void SelectAll();
- void SelectNone();
- void SelectInverse();
-
- bool IsSelected(Poly* p, WORD v);
- bool WillSelect(CPoint& p);
-
-protected:
- enum { MAX_MARK = 4096 };
-
- Material* material;
- List<Poly> polys;
- Video* video;
-
- double zoom;
- double x_offset;
- double y_offset;
-
- int nmarks;
- CPoint marks[MAX_MARK];
- int select_mode;
- bool active;
-
- std::vector<DWORD> selverts;
-};
-
-// +--------------------------------------------------------------------+
-
-#endif UVMapView_h
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Magic.exe
+ FILE: UVMapView.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Interface of the UVMapView class
+*/
+
+
+#ifndef UVMapView_h
+#define UVMapView_h
+
+#include <vector>
+#include "View.h"
+#include "Polygon.h"
+#include "List.h"
+
+// +--------------------------------------------------------------------+
+
+class Video;
+
+// +--------------------------------------------------------------------+
+
+class UVMapView : public View
+{
+public:
+ UVMapView(Window* c);
+ virtual ~UVMapView();
+
+ enum SELECT_MODE { SELECT_REMOVE=-1, SELECT_REPLACE=0, SELECT_APPEND=1 };
+
+ virtual void Refresh();
+
+ void UseMaterial(Material* m);
+ void UsePolys(List<Poly>& p);
+
+ void MoveBy(double dx, double dy);
+ void DragBy(double dx, double dy);
+ void ZoomIn() { zoom *= 1.15; }
+ void ZoomOut() { zoom *= 0.85; }
+
+ void Clear();
+ void Begin(int select_mode = SELECT_REPLACE);
+ void AddMark(CPoint& p);
+ void End();
+
+ bool IsActive() const { return active; }
+ void SelectAll();
+ void SelectNone();
+ void SelectInverse();
+
+ bool IsSelected(Poly* p, WORD v);
+ bool WillSelect(CPoint& p);
+
+protected:
+ enum { MAX_MARK = 4096 };
+
+ Material* material;
+ List<Poly> polys;
+ Video* video;
+
+ double zoom;
+ double x_offset;
+ double y_offset;
+
+ int nmarks;
+ CPoint marks[MAX_MARK];
+ int select_mode;
+ bool active;
+
+ std::vector<DWORD> selverts;
+};
+
+// +--------------------------------------------------------------------+
+
+#endif UVMapView_h
diff --git a/Magic2/VideoDX9.cpp b/Magic2/VideoDX9.cpp
index d3c623c..0c9e24d 100644
--- a/Magic2/VideoDX9.cpp
+++ b/Magic2/VideoDX9.cpp
@@ -1,3617 +1,3641 @@
-/* Project nGenEx
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: nGenEx.lib
- FILE: VideoDX9.cpp
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Direct3D Video class for DirectX 9
-*/
-
-#include "MemDebug.h"
-#include "VideoDX9.h"
-#include "VideoDX9Enum.h"
-#include "VideoDX9VertexBuffer.h"
-#include "TexDX9.h"
-#include "TexCubeDX9.h"
-#include "Camera.h"
-#include "Color.h"
-#include "DataLoader.h"
-#include "Polygon.h"
-#include "Light.h"
-#include "Solid.h"
-
-// +--------------------------------------------------------------------+
-
-void Print(const char* msg, ...);
-char* D3DErrStr(HRESULT dderr);
-void VideoDX9Error(const char* msg, HRESULT dderr);
-static TexCacheDX9* texcache = 0;
-static TexCubeDX9* environment_cube = 0;
-static bool surface_has_tangent_data = false;
-static Light* main_light;
-static Light* back_light;
-static D3DXMATRIX matrixWorld;
-static D3DXMATRIX matrixView;
-static D3DXMATRIX matrixProj;
-static D3DXMATRIX matrixWorldInverse;
-
-extern int VD3D_describe_things;
-
-#ifndef RELEASE
-#define RELEASE(x) if (x) { x->Release(); x=NULL; }
-#endif
-
-#ifndef F2DW
-#define F2DW(x) (*(DWORD*)(&x))
-#endif
-
-#ifndef DW2I
-#define DW2I(x) (*(int*)(&x))
-#endif
-
-// +--------------------------------------------------------------------+
-
-typedef HRESULT (WINAPI * LPDDCE)(GUID FAR *, LPVOID *, REFIID , IUnknown FAR *);
-
-static D3DMATRIX identity_matrix = {
- FLOAT(1.0), FLOAT(0.0), FLOAT(0.0), FLOAT(0.0),
- FLOAT(0.0), FLOAT(1.0), FLOAT(0.0), FLOAT(0.0),
- FLOAT(0.0), FLOAT(0.0), FLOAT(1.0), FLOAT(0.0),
- FLOAT(0.0), FLOAT(0.0), FLOAT(0.0), FLOAT(1.0)
-};
-
-// +--------------------------------------------------------------------+
-
-List<Model> model_clients;
-
-class VideoDX9SurfaceData : public VideoPrivateData
-{
-public:
- VideoDX9SurfaceData(Model* m) : model(m), vertex_buffer(0), index_buffer(0) {
- if (!model_clients.contains(model))
- model_clients.append(model);
- }
-
- virtual ~VideoDX9SurfaceData() {
- model_clients.remove(model);
-
- delete vertex_buffer;
- delete index_buffer;
- }
-
- enum { TYPE = 9001 };
- virtual int GetType() const { return TYPE; }
-
- Model* model;
- VideoDX9VertexBuffer* vertex_buffer;
- VideoDX9IndexBuffer* index_buffer;
-};
-
-class VideoDX9SegmentData : public VideoPrivateData
-{
-public:
- VideoDX9SegmentData() : first_vert(0), num_verts(0), first_index(0), num_tris(0) { }
- virtual ~VideoDX9SegmentData() { }
-
- enum { TYPE = 9002 };
- virtual int GetType() const { return TYPE; }
-
- int first_vert;
- int num_verts;
- int first_index;
- int num_tris;
-};
-
-// +--------------------------------------------------------------------+
-
-static int d3dstate_table[] = {
- D3DRS_FILLMODE, // FILL_MODE
- D3DRS_SHADEMODE, // SHADE_MODE
- D3DRS_LIGHTING, // LIGHTING_ENABLE
- D3DRS_ZENABLE, // Z_ENABLE
- D3DRS_ZWRITEENABLE, // Z_WRITE_ENABLE
- D3DRS_DEPTHBIAS, // Z_BIAS
- 0, // TEXTURE_FILTER
- D3DRS_DITHERENABLE, // DITHER_ENABLE
- D3DRS_SPECULARENABLE, // SPECULAR_ENABLE
- D3DRS_FOGENABLE, // FOG_ENABLE
- D3DRS_FOGCOLOR, // FOG_COLOR
- D3DRS_FOGDENSITY, // FOG_DENSITY
- D3DRS_STENCILENABLE, // STENCIL_ENABLE
- 0x11111111, // TEXTURE_WRAP (special case)
- 0 // LIGHTING_PASS
-};
-
-static const int NUM_SCREEN_VERTS = 1024;
-static const int NUM_SCREEN_INDICES = NUM_SCREEN_VERTS * 2;
-
-// +--------------------------------------------------------------------+
-
-struct VideoDX9ScreenVertex
-{
- FLOAT sx, sy, sz, rhw;
- DWORD diffuse;
- FLOAT tu, tv;
-
- static DWORD FVF;
-};
-
-DWORD VideoDX9ScreenVertex::FVF = D3DFVF_XYZRHW |
-D3DFVF_DIFFUSE |
-D3DFVF_TEX1;
-
-struct VideoDX9NormalVertex
-{
- FLOAT x, y, z;
- FLOAT nx, ny, nz;
- FLOAT t0u, t0v;
- FLOAT t1u, t1v;
- FLOAT tx, ty, tz;
- FLOAT bx, by, bz;
-
- static DWORD FVF;
-};
-
-DWORD VideoDX9NormalVertex::FVF = 0;
-
-// Global Vertex Declaration shared by shaders
-D3DVERTEXELEMENT9 videoDX9NormalVertexElements[] =
-{
- { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
- { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
- { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
- { 0, 32, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 },
- { 0, 40, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 2 },
- { 0, 52, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 3 },
- D3DDECL_END()
-};
-
-struct VideoDX9SolidVertex
-{
- FLOAT x, y, z;
- FLOAT nx, ny, nz;
- FLOAT tu, tv;
-
- static DWORD FVF;
-};
-
-DWORD VideoDX9SolidVertex::FVF = D3DFVF_XYZ |
-D3DFVF_NORMAL |
-D3DFVF_TEX1 |
-D3DFVF_TEXCOORDSIZE2(0);
-
-struct VideoDX9LuminousVertex
-{
- FLOAT x, y, z;
- DWORD diffuse;
- FLOAT tu, tv;
-
- static DWORD FVF;
-};
-
-DWORD VideoDX9LuminousVertex::FVF = D3DFVF_XYZ |
-D3DFVF_DIFFUSE |
-D3DFVF_TEX1 |
-D3DFVF_TEXCOORDSIZE2(0);
-
-struct VideoDX9DetailVertex
-{
- FLOAT x, y, z;
- DWORD diffuse;
- DWORD specular;
- FLOAT tu, tv;
- FLOAT tu1, tv1;
-
- static DWORD FVF;
-};
-
-DWORD VideoDX9DetailVertex::FVF = D3DFVF_XYZ |
-D3DFVF_DIFFUSE |
-D3DFVF_SPECULAR |
-D3DFVF_TEX2;
-
-struct VideoDX9LineVertex
-{
- FLOAT x, y, z;
- DWORD diffuse;
-
- static DWORD FVF;
-};
-
-DWORD VideoDX9LineVertex::FVF = D3DFVF_XYZ |
-D3DFVF_DIFFUSE;
-
-enum {
- DX9_STRATEGY_NONE,
- DX9_STRATEGY_SIMPLE,
- DX9_STRATEGY_GLOW,
- DX9_STRATEGY_SPECMAP,
- DX9_STRATEGY_EMISSIVE,
- DX9_STRATEGY_SPEC_EMISSIVE,
- DX9_STRATEGY_BLEND,
- DX9_STRATEGY_BLEND_DETAIL
-};
-
-// +--------------------------------------------------------------------+
-
-static VideoDX9* video_dx9_instance = 0;
-
-VideoDX9::VideoDX9(const HWND& window, VideoSettings* vs)
-: width(0), height(0), bpp(0), hwnd(window), surface(0),
-d3d(0), d3ddevice(0), device_lost(false), fade(0),
-zdepth(0), gamma(128), num_verts(0), first_vert(0),
-current_texture(0), screen_vbuf(0), screen_ibuf(0),
-font_verts(0), font_indices(0), font_nverts(0),
-nlights(0), use_material(0), d3dx_font(0),
-segment_material(0), strategy(0), passes(0),
-screen_line_verts(0), line_verts(0),
-vertex_declaration(0),
-magic_fx(0), magic_fx_code(0), magic_fx_code_len(0)
-{
- video_dx9_instance = this;
-
- Print("\n********************************\n");
- Print("* Direct 3D version 9 *\n");
- Print("********************************\n\n");
-
- status = VIDEO_ERR;
- HRESULT err = E_OUTOFMEMORY;
-
- d3d = Direct3DCreate9(D3D_SDK_VERSION);
- dx9enum = new(__FILE__,__LINE__) VideoDX9Enum(d3d);
-
- if (d3d && dx9enum) {
- if (vs) {
- dx9enum->req_fullscreen = vs->is_windowed ? false : true;
- dx9enum->req_windowed = vs->is_windowed ? true : false;
- dx9enum->min_stencil_bits = vs->shadows ? 8 : 0;
- dx9enum->uses_depth_buffer = true;
- }
- else {
- dx9enum->req_fullscreen = video_settings.is_windowed ? false : true;
- dx9enum->req_windowed = video_settings.is_windowed ? true : false;
- dx9enum->min_stencil_bits = video_settings.shadows ? 8 : 0;
- dx9enum->uses_depth_buffer = true;
- }
-
- err = dx9enum->Enumerate();
-
- if (FAILED(err)) {
- VideoDX9Error("(ctor) could not enumerate dx9 properties", err);
- delete dx9enum;
- return;
- }
- }
- else {
- VideoDX9Error("(ctor) could not create enumerator", err);
- return;
- }
-
- SetVideoSettings(vs);
-
- if (video_settings.is_windowed)
- dx9enum->SuggestWindowSettings(&video_settings);
- else
- dx9enum->SuggestFullscreenSettings(&video_settings);
-
- SetupParams();
-
- if (VD3D_describe_things > 2) {
- Print("\nD3DPRESENT_PARAMETERS:\n");
- Print(" BackBufferWidth: %d\n", d3dparams.BackBufferWidth);
- Print(" BackBufferHeight: %d\n", d3dparams.BackBufferHeight);
- Print(" BackBufferCount: %d\n", d3dparams.BackBufferCount);
- Print(" BackBufferFormat: %s\n", VideoDX9DisplayMode::D3DFormatToString(d3dparams.BackBufferFormat));
- Print(" Multisample Type: %d\n", d3dparams.MultiSampleType);
- Print(" Multisample Qual: %d\n", d3dparams.MultiSampleQuality);
- Print(" Swap Effect: %d\n", d3dparams.SwapEffect);
- Print(" Device Window: %08X\n", d3dparams.hDeviceWindow);
- Print(" Windowed: %s\n", d3dparams.Windowed ? "true" : "false");
- Print(" Enable Depth/Stencil: %s\n", d3dparams.EnableAutoDepthStencil ? "true" : "false");
- Print(" Depth/Stencil Format: %s\n", VideoDX9DisplayMode::D3DFormatToString(d3dparams.AutoDepthStencilFormat));
- Print(" Flags: %08X\n", d3dparams.Flags);
- Print(" Fullscreen Refresh: %d Hz\n", d3dparams.FullScreen_RefreshRateInHz);
-
- switch (d3dparams.PresentationInterval) {
- case D3DPRESENT_INTERVAL_IMMEDIATE:
- Print(" Present Interval: IMMEDIATE\n");
- break;
-
- case D3DPRESENT_INTERVAL_DEFAULT:
- Print(" Present Interval: DEFAULT\n");
- break;
-
- case D3DPRESENT_INTERVAL_ONE:
- Print(" Present Interval: ONE\n");
- break;
-
- case D3DPRESENT_INTERVAL_TWO:
- Print(" Present Interval: TWO\n");
- break;
-
- case D3DPRESENT_INTERVAL_THREE:
- Print(" Present Interval: THREE\n");
- break;
-
- case D3DPRESENT_INTERVAL_FOUR:
- Print(" Present Interval: FOUR\n");
- break;
-
- default:
- Print(" Present Interval: Unknown (%d)\n", d3dparams.PresentationInterval);
- break;
- }
-
- Print("\n");
- }
-
- Print(" Creating Video Device for HWND = %08x\n", window);
-
- err = d3d->CreateDevice(D3DADAPTER_DEFAULT,
- D3DDEVTYPE_HAL,
- window,
- D3DCREATE_HARDWARE_VERTEXPROCESSING,
- &d3dparams,
- &d3ddevice);
-
- if (FAILED(err)) {
- VideoDX9Error("(ctor) could not create device", err);
- return;
- }
-
- width = video_settings.GetWidth();
- height = video_settings.GetHeight();
- bpp = video_settings.GetDepth();
-
- shadow_enabled = vs->shadows;
- bump_enabled = vs->bumpmaps;
- spec_enabled = vs->specmaps;
-
- render_state[FILL_MODE] = FILL_SOLID;
- render_state[SHADE_MODE] = SHADE_GOURAUD;
- render_state[Z_ENABLE] = false;
- render_state[Z_WRITE_ENABLE] = false;
- render_state[Z_BIAS] = 0;
- render_state[TEXTURE_FILTER] = FILTER_LINEAR;
- render_state[DITHER_ENABLE] = false;
- render_state[SPECULAR_ENABLE] = true;
- render_state[FOG_ENABLE] = false;
- render_state[FOG_COLOR] = 0;
- render_state[FOG_DENSITY] = 0;
- render_state[STENCIL_ENABLE] = false;
- render_state[TEXTURE_WRAP] = true;
- render_state[LIGHTING_PASS] = 0;
-
- ZeroMemory(&rect, sizeof(rect));
-
- if (!texcache)
- texcache = new(__FILE__,__LINE__) TexCacheDX9(this);
-
- if (texcache)
- texcache->count++;
-
- if (VD3D_describe_things > 0) {
- DWORD vmf = VidMemFree() / (1024 * 1024);
- Print(" Available Texture Memory: %d MB\n\n", vmf);
- }
-
- if (CreateBuffers()) {
- d3ddevice->SetRenderState(D3DRS_ALPHATESTENABLE, false);
- d3ddevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
-
- d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
- d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
- d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
- d3ddevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
- d3ddevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
- d3ddevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
-
- status = VIDEO_OK;
- }
-
- ZeroMemory(font_name, 64);
- font_size = 0;
- font_bold = false;
- font_ital = false;
-}
-
-// +--------------------------------------------------------------------+
-
-VideoDX9::~VideoDX9()
-{
- DestroyBuffers();
-
- texcache->count--;
- if (!texcache->count) {
- delete texcache;
- texcache = 0;
- }
-
- delete environment_cube;
- delete dx9enum;
-
- RELEASE(d3dx_font);
- RELEASE(d3ddevice);
- RELEASE(d3d);
-
- if (magic_fx_code)
- delete [] magic_fx_code;
-
- Print(" VideoDX9: shutdown\n");
- video_dx9_instance = 0;
-}
-
-IDirect3DDevice9*
-VideoDX9::GetD3DDevice9()
-{
- if (video_dx9_instance)
- return video_dx9_instance->d3ddevice;
-
- return 0;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::SetupParams()
-{
- if (!dx9enum || dx9enum->NumAdapters() < 1) {
- status = VIDEO_ERR;
- return false;
- }
-
- int adapter_index = video_settings.GetAdapterIndex();
-
- if (adapter_index < 0 || adapter_index >= dx9enum->NumAdapters()) {
- ::Print("WARNING: VideoDX9 could not select adapter %d (max=%d)\n",
- adapter_index, dx9enum->NumAdapters());
-
- adapter_index = 0;
- }
-
- dx9enum->SelectAdapter(adapter_index);
-
- d3dparams.Windowed = video_settings.IsWindowed();
- d3dparams.BackBufferCount = 2;
- d3dparams.MultiSampleType = D3DMULTISAMPLE_NONE;
- d3dparams.MultiSampleQuality = 0;
- d3dparams.SwapEffect = D3DSWAPEFFECT_DISCARD;
- d3dparams.EnableAutoDepthStencil = dx9enum->uses_depth_buffer;
- d3dparams.hDeviceWindow = hwnd;
-
- if (dx9enum->uses_depth_buffer) {
- d3dparams.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
- d3dparams.AutoDepthStencilFormat = (D3DFORMAT) video_settings.GetDepthStencilFormat();
- }
- else {
- d3dparams.Flags = 0;
- }
-
- d3dparams.Flags |= D3DPRESENTFLAG_DEVICECLIP;
-
- if (video_settings.IsWindowed()) {
- d3dparams.BackBufferWidth = video_settings.window_width;
- d3dparams.BackBufferHeight = video_settings.window_height;
- d3dparams.BackBufferFormat = (D3DFORMAT) video_settings.GetBackBufferFormat();
- d3dparams.FullScreen_RefreshRateInHz = 0;
- d3dparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
- }
- else {
- d3dparams.BackBufferWidth = video_settings.GetWidth();
- d3dparams.BackBufferHeight = video_settings.GetHeight();
- d3dparams.BackBufferFormat = (D3DFORMAT) video_settings.GetBackBufferFormat();
- d3dparams.FullScreen_RefreshRateInHz = video_settings.GetRefreshRate();
- d3dparams.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
- }
-
- return true;
-}
-
-
-bool
-VideoDX9::IsModeSupported(int w, int h, int b) const
-{
- if (dx9enum)
- return dx9enum->IsModeSupported(w, h, b);
-
- return false;
-}
-
-bool
-VideoDX9::SetVideoSettings(const VideoSettings* vs)
-{
- // custom video settings:
- if (vs) {
- if (vs != &video_settings)
- CopyMemory(&video_settings, vs, sizeof(VideoSettings));
- }
-
- // default video settings:
- else {
- ZeroMemory(&video_settings, sizeof(VideoSettings));
-
- video_settings.fullscreen_mode.width = 800;
- video_settings.fullscreen_mode.height = 600;
- video_settings.fullscreen_mode.format = VideoMode::FMT_X8R8G8B8;
- }
-
- return true;
-}
-
-bool
-VideoDX9::Reset(const VideoSettings* vs)
-{
- if (!d3ddevice || !SetVideoSettings(vs)) {
- status = VIDEO_ERR;
- return false;
- }
-
- bool using_x_font = (d3dx_font != 0);
-
- RELEASE(d3dx_font);
- InvalidateCache();
- DestroyBuffers();
- SetupParams();
-
- HRESULT hr = d3ddevice->Reset(&d3dparams);
-
- if (FAILED(hr)) {
- VideoDX9Error("could not reset d3d device", hr);
- status = VIDEO_ERR;
- return false;
- }
-
- // Store render target surface desc
- IDirect3DSurface9* back_buffer;
- d3ddevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &back_buffer);
- back_buffer->GetDesc(&back_buffer_desc);
- RELEASE(back_buffer);
-
- width = video_settings.GetWidth();
- height = video_settings.GetHeight();
- bpp = video_settings.GetDepth();
-
- shadow_enabled = vs->shadows;
- bump_enabled = vs->bumpmaps;
- spec_enabled = vs->specmaps;
-
-
- if (CreateBuffers()) {
- d3ddevice->SetRenderState(D3DRS_ALPHATESTENABLE, false);
- d3ddevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
-
- d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
- d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
- d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
- d3ddevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
- d3ddevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
- d3ddevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
-
- D3DVIEWPORT9 view;
-
- hr = d3ddevice->GetViewport(&view);
- if (SUCCEEDED(hr)) {
- rect.x = view.X;
- rect.y = view.Y;
- rect.w = view.Width;
- rect.h = view.Height;
- }
-
- if (using_x_font)
- UseXFont(font_name, font_size, font_bold, font_ital);
-
- status = VIDEO_OK;
- }
-
- return status == VIDEO_OK;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::CreateBuffers()
-{
- if (d3ddevice) {
- UINT vertex_size = sizeof(VideoDX9ScreenVertex);
- UINT index_size = sizeof(WORD);
-
- if (!screen_vbuf) {
- screen_vbuf = new(__FILE__,__LINE__) VideoDX9VertexBuffer(
- this,
- NUM_SCREEN_VERTS,
- vertex_size,
- VideoDX9ScreenVertex::FVF,
- D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY);
- }
-
- if (!screen_ibuf) {
- screen_ibuf = new(__FILE__,__LINE__) VideoDX9IndexBuffer(
- this,
- NUM_SCREEN_INDICES,
- D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY);
- }
-
- screen_line_verts = new(__FILE__,__LINE__) VideoDX9ScreenVertex[256];
- line_verts = new(__FILE__,__LINE__) VideoDX9LineVertex[512];
-
- // create effects:
- LPD3DXBUFFER code_buffer = 0;
- DataLoader* loader = DataLoader::GetLoader();
- HRESULT hr = E_FAIL;
-
- hr = d3ddevice->CreateVertexDeclaration(videoDX9NormalVertexElements,
- &vertex_declaration);
-
- // The E - We want to load our shader from the standard filesystem by default, to allow for better modding.
- if (video_settings.use_effects && !magic_fx_code) {
- FILE* f;
- ::fopen_s(&f, "magic.fx", "rb");
-
- if (f) {
- ::fseek(f, 0, SEEK_END);
- magic_fx_code_len = ftell(f);
- ::fseek(f, 0, SEEK_SET);
-
- magic_fx_code = new(__FILE__,__LINE__) BYTE[magic_fx_code_len+1];
- if (magic_fx_code) {
- ::fread(magic_fx_code, magic_fx_code_len, 1, f);
- magic_fx_code[magic_fx_code_len] = 0;
- }
- ::fclose(f);
- } else if (loader) {
- magic_fx_code_len = loader->LoadBuffer("magic.fx", magic_fx_code, true, true);
- }
- }
-
- if (video_settings.use_effects && magic_fx_code && magic_fx_code_len) {
- hr = D3DXCreateEffect(d3ddevice,
- magic_fx_code,
- magic_fx_code_len,
- 0, 0, 0, 0,
- &magic_fx,
- &code_buffer);
-
- if (code_buffer) {
- ::Print("ERROR - Failed to compile 'magic.fx'\n");
- ::Print((const char*) code_buffer->GetBufferPointer());
- ::Print("\n\n");
- RELEASE(code_buffer);
- }
- }
- }
-
- return screen_vbuf && screen_ibuf;
-}
-
-bool
-VideoDX9::DestroyBuffers()
-{
- if (line_verts) {
- delete line_verts;
- line_verts = 0;
- }
-
- if (screen_line_verts) {
- delete screen_line_verts;
- screen_line_verts = 0;
- }
-
- if (screen_vbuf) {
- delete screen_vbuf;
- screen_vbuf = 0;
- }
-
- if (screen_ibuf) {
- delete screen_ibuf;
- screen_ibuf = 0;
- }
-
- if (font_verts) {
- delete [] font_verts;
- font_verts = 0;
- }
-
- if (font_indices) {
- delete [] font_indices;
- font_indices = 0;
- }
-
- font_nverts = 0;
-
- RELEASE(vertex_declaration);
- RELEASE(magic_fx);
-
- return true;
-}
-
-// +--------------------------------------------------------------------+
-
-DWORD
-VideoDX9::VidMemFree() const
-{
- UINT result = 0;
-
- if (d3ddevice)
- result = d3ddevice->GetAvailableTextureMem();
-
- return result;
-}
-
-int
-VideoDX9::MaxTexSize() const
-{
- if (d3d && dx9enum && dx9enum->GetAdapterInfo()) {
- VideoDX9DeviceInfo* dev_info = dx9enum->GetDeviceInfo(video_settings.GetDeviceType());
-
- if (dev_info) {
- return (int) dev_info->caps.MaxTextureWidth;
- }
- }
-
- return 0;
-}
-
-int
-VideoDX9::MaxTexAspect() const
-{
- if (d3d && dx9enum && dx9enum->GetAdapterInfo()) {
- VideoDX9DeviceInfo* dev_info = dx9enum->GetDeviceInfo(video_settings.GetDeviceType());
-
- if (dev_info) {
- return (int) dev_info->caps.MaxTextureAspectRatio;
- }
- }
-
- return 0;
-}
-
-// +--------------------------------------------------------------------+
-
-void
-VideoDX9::RecoverSurfaces()
-{
- Print("VideoDX9::RecoverSurfaces()\n");
-
- HRESULT hr = D3D_OK;
-
- surface = 0;
-
- hr = d3ddevice->TestCooperativeLevel();
-
- if (hr == D3DERR_DEVICELOST) {
- // This means that some app took exclusive mode access
- // we need to sit in a loop till we get back to the right mode.
- Print("D3DERR_DEVICELOST\n");
-
- do {
- Sleep(500);
- hr = d3ddevice->TestCooperativeLevel();
- } while (hr == D3DERR_DEVICELOST);
- }
-
- if (hr == D3DERR_DEVICENOTRESET) {
- if (Reset(&video_settings))
- hr = S_OK;
- }
-
- if (SUCCEEDED(hr)) {
- Print("* Invalidating Texture Cache\n");
- // Re-fill the contents of textures which just got restored:
- InvalidateCache();
-
- device_lost = false;
- }
-
- Print("* Vid Mem Free: %8d\n", VidMemFree());
- Print("* Recover Surfaces Complete.\n\n");
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::SetBackgroundColor(Color c)
-{
- background = c;
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// RampValue
-//
-// The gamma function with inputs in [0,255], scaled to a range with the
-// default range appropriate for D3DGAMMARAMP.
-//
-inline WORD
-RampValue(UINT i, double recip_gamma, double fade)
-{
- return (WORD) (65535.0 * fade * pow((double)i/255.f, recip_gamma));
-}
-
-//-----------------------------------------------------------------------------
-// ReciprocalGamma
-//
-// Given a gamma corrected i in [0,255], return 1/gamma
-//
-inline float
-ReciprocalGamma(UINT i)
-{
- return logf(i/255.f)/logf(0.5f);
-}
-
-//-----------------------------------------------------------------------------
-// GammaValue
-//
-// Given a gamma corrected color channel value in [0,255], return the gamma.
-//
-inline float
-GammaValue(UINT i)
-{
- return logf(0.5f)/logf(i/255.f);
-}
-
-bool
-VideoDX9::SetGammaLevel(int g)
-{
- HRESULT hr = E_FAIL;
- double f = Color::GetFade();
-
- if (gamma != g || fade != f) {
- if (d3ddevice) {
- //::Print("VideoDX9 - SetGammaLevel(%d) fade = %f\n", g, f);
-
- // compute 1/gamma
- float recip_gray = ReciprocalGamma(g);
-
- // compute i**(1/gamma) for all i and scale to range
- for (UINT i = 0; i < 256; i++) {
- int val = RampValue(i, recip_gray, f);
-
- gamma_ramp.red[i] = val;
- gamma_ramp.green[i] = val;
- gamma_ramp.blue[i] = val;
- }
-
- d3ddevice->SetGammaRamp(0, D3DSGR_NO_CALIBRATION, &gamma_ramp);
- hr = D3D_OK;
- }
-
- gamma = g;
- fade = f;
- }
-
- return SUCCEEDED(hr);
-}
-
-bool
-VideoDX9::SetObjTransform(const Matrix& orient, const Point& loc)
-{
- HRESULT hr = E_FAIL;
-
- if (d3ddevice) {
- D3DMATRIX world_matrix;
- CreateD3DMatrix(world_matrix, orient, loc);
- hr = d3ddevice->SetTransform(D3DTS_WORLD, &world_matrix);
-
- matrixWorld = world_matrix;
- D3DXMatrixInverse(&matrixWorldInverse, 0, &matrixWorld);
- }
-
- return SUCCEEDED(hr);
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::ClearAll()
-{
- HRESULT err;
-
- err = d3ddevice->Clear(0,
- NULL,
- D3DCLEAR_TARGET | D3DCLEAR_STENCIL | D3DCLEAR_ZBUFFER,
- background.Value(),
- 1.0f,
- 0);
-
- if (FAILED(err)) {
- static int report = 10;
- if (report > 0) {
- VideoDX9Error("Failed to clear device", err);
- report--;
- }
- }
-
- return true;
-}
-
-bool
-VideoDX9::ClearDepthBuffer()
-{
- HRESULT err;
-
- err = d3ddevice->Clear(0,
- NULL,
- D3DCLEAR_STENCIL | D3DCLEAR_ZBUFFER,
- 0,
- 1.0f,
- 0);
-
- if (FAILED(err)) {
- static int report = 10;
- if (report > 0) {
- VideoDX9Error("Failed to clear depth buffer", err);
- report--;
- }
- }
-
- return true;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::Present()
-{
- // Show the frame on the primary surface.
- HRESULT err = d3ddevice->Present( NULL, NULL, NULL, NULL );
-
- if (FAILED(err)) {
- if (err == D3DERR_DEVICELOST) {
- device_lost = true;
- }
-
- else {
- static int report = 10;
- if (report > 0) {
- VideoDX9Error("Could not present frame", err);
- report--;
- }
- }
- }
-
- return true;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::Pause()
-{
- return true;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::Resume()
-{
- return true;
-}
-
-// +--------------------------------------------------------------------+
-
-void
-VideoDX9::PreloadSurface(Surface* s)
-{
- if (s)
- PrepareSurface(s);
-}
-
-void
-VideoDX9::PreloadTexture(Bitmap* tex)
-{
- if (texcache && tex)
- texcache->FindTexture(tex);
-}
-
-void
-VideoDX9::InvalidateCache()
-{
- ListIter<Model> iter = model_clients;
- while (++iter) {
- // remove each model from the list...
- Model* model = iter.removeItem();
-
- // ...so that the buffer destructor doesn't
- // do it and mess up the iterator.
- model->DeletePrivateData();
- }
-
- if (texcache)
- texcache->InvalidateCache();
-}
-
-// +--------------------------------------------------------------------+
-
-void
-VideoDX9::CreateD3DMatrix(D3DMATRIX& result, const Matrix& m, const Point& p)
-{
- result._11 = (float) m.elem[0][0];
- result._12 = (float) m.elem[1][0];
- result._13 = (float) m.elem[2][0];
- result._14 = 0.0f;
-
- result._21 = (float) m.elem[0][1];
- result._22 = (float) m.elem[1][1];
- result._23 = (float) m.elem[2][1];
- result._24 = 0.0f;
-
- result._31 = (float) m.elem[0][2];
- result._32 = (float) m.elem[1][2];
- result._33 = (float) m.elem[2][2];
- result._34 = 0.0f;
-
- result._41 = (float) p.x;
- result._42 = (float) p.y;
- result._43 = (float) p.z;
- result._44 = 1.0f;
-}
-
-void
-VideoDX9::CreateD3DMatrix(D3DMATRIX& result, const Matrix& m, const Vec3& v)
-{
- result._11 = (float) m.elem[0][0];
- result._12 = (float) m.elem[1][0];
- result._13 = (float) m.elem[2][0];
- result._14 = 0.0f;
-
- result._21 = (float) m.elem[0][1];
- result._22 = (float) m.elem[1][1];
- result._23 = (float) m.elem[2][1];
- result._24 = 0.0f;
-
- result._31 = (float) m.elem[0][2];
- result._32 = (float) m.elem[1][2];
- result._33 = (float) m.elem[2][2];
- result._34 = 0.0f;
-
- result._41 = v.x;
- result._42 = v.y;
- result._43 = v.z;
- result._44 = 1.0f;
-}
-
-void
-VideoDX9::CreateD3DMaterial(D3DMATERIAL9& result, const Material& mtl)
-{
- CopyMemory(&result.Diffuse, &mtl.Kd, sizeof(D3DCOLORVALUE));
- CopyMemory(&result.Ambient, &mtl.Ka, sizeof(D3DCOLORVALUE));
- CopyMemory(&result.Specular, &mtl.Ks, sizeof(D3DCOLORVALUE));
- CopyMemory(&result.Emissive, &mtl.Ke, sizeof(D3DCOLORVALUE));
-
- result.Power = mtl.power;
-}
-
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::Capture(Bitmap& bmp)
-{
- if (d3ddevice) {
- HRESULT hr = E_FAIL;
- LPDIRECT3DSURFACE9 pSurf=NULL, pTempSurf=NULL;
- D3DSURFACE_DESC desc;
- D3DDISPLAYMODE dm;
-
- // get display dimensions
- // this will be the dimensions of the front buffer
- hr = d3ddevice->GetDisplayMode(0, &dm);
-
- if (FAILED(hr))
- VideoDX9Error("VideoDX9::Capture - Can't get display mode!", hr);
-
- desc.Width = dm.Width;
- desc.Height = dm.Height;
- desc.Format = D3DFMT_A8R8G8B8;
-
- hr = d3ddevice->CreateOffscreenPlainSurface(
- desc.Width,
- desc.Height,
- desc.Format,
- D3DPOOL_SYSTEMMEM,
- &pTempSurf,
- NULL);
-
- if (FAILED(hr)) {
- VideoDX9Error("VideoDX9::Capture - Cannot create offscreen buffer 1", hr);
- return false;
- }
-
- hr = d3ddevice->GetFrontBufferData(0, pTempSurf);
-
- if (FAILED(hr)) {
- RELEASE(pTempSurf);
- VideoDX9Error("VideoDX9::Capture - Can't get front buffer", hr);
- return false;
- }
-
-
- if (video_settings.IsWindowed()) {
- POINT pt={0, 0};
- RECT srcRect;
-
- // capture only the client area of the screen:
- ::GetClientRect(hwnd, &srcRect);
- ::ClientToScreen(hwnd, (LPPOINT) &srcRect);
- srcRect.right += srcRect.left;
- srcRect.bottom += srcRect.top;
-
- desc.Width = srcRect.right - srcRect.left;
- desc.Height = srcRect.bottom - srcRect.top;
- desc.Format = D3DFMT_A8R8G8B8; // this is what we get from the screen, so stick with it
-
- // NB we can't lock the back buffer direct because it's no created that way
- // and to do so hits performance, so copy to another surface
- // Must be the same format as the source surface
- hr = d3ddevice->CreateOffscreenPlainSurface(
- desc.Width,
- desc.Height,
- desc.Format,
- D3DPOOL_DEFAULT,
- &pSurf,
- NULL);
-
- if (FAILED(hr)) {
- RELEASE(pSurf);
- VideoDX9Error("VideoDX9::Capture - Cannot create offscreen buffer 2", hr);
- return false;
- }
-
- // Copy
- hr = d3ddevice->UpdateSurface(pTempSurf, &srcRect, pSurf, &pt);
-
- if (FAILED(hr)) {
- RELEASE(pTempSurf);
- RELEASE(pSurf);
- VideoDX9Error("VideoDX9::Capture - Cannot update surface", hr);
- return false;
- }
-
- RELEASE(pTempSurf);
- pTempSurf = pSurf;
- pSurf = NULL;
- }
-
- D3DLOCKED_RECT lockedRect;
- hr = pTempSurf->LockRect(&lockedRect, NULL,
- D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK);
-
- if (FAILED(hr)) {
- VideoDX9Error("VideoDX9::Capture - can't lock rect", hr);
- RELEASE(pTempSurf);
- return false;
- }
-
- // Allocate color buffer
- DWORD* buffer = new DWORD[desc.Width * desc.Height];
- BYTE* src = (BYTE*) lockedRect.pBits;
- BYTE* dst = (BYTE*) buffer;
- Color clr;
-
- for (DWORD y = 0; y < desc.Height; y++) {
- BYTE *pRow = src;
-
- for (DWORD x = 0; x < desc.Width; x++) {
- switch(desc.Format) {
- case D3DFMT_R5G6B5:
- clr = Color::Unformat(*((WORD*) (pRow)));
-
- *dst++ = (BYTE) clr.Red();
- *dst++ = (BYTE) clr.Green();
- *dst++ = (BYTE) clr.Blue();
- *dst++ = 255;
- break;
-
- case D3DFMT_A8R8G8B8:
- case D3DFMT_X8R8G8B8:
- *dst++ = pRow[0]; // R
- *dst++ = pRow[1]; // G
- *dst++ = pRow[2]; // B
- *dst++ = 255;
-
- pRow += 4;
- break;
-
- case D3DFMT_R8G8B8:
- *dst++ = pRow[0]; // R
- *dst++ = pRow[1]; // G
- *dst++ = pRow[2]; // B
- *dst++ = 255;
-
- pRow += 3;
- break;
- }
-
- }
-
- src += lockedRect.Pitch;
- }
-
- bmp.CopyHighColorImage(desc.Width, desc.Height, buffer);
-
- delete [] buffer;
-
- RELEASE(pTempSurf);
- RELEASE(pSurf);
-
- return SUCCEEDED(hr);
- }
-
- return false;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::GetWindowRect(Rect& r)
-{
- if (d3ddevice && (rect.w < 1 || rect.h < 1)) {
- D3DVIEWPORT9 view;
- HRESULT hr = d3ddevice->GetViewport(&view);
- if (SUCCEEDED(hr)) {
- rect.x = view.X;
- rect.y = view.Y;
- rect.w = view.Width;
- rect.h = view.Height;
- }
- }
-
- r = rect;
- return true;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::SetWindowRect(const Rect& r)
-{
- return SetViewport(r.x, r.y, r.w, r.h);
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::SetViewport(int x, int y, int w, int h)
-{
- if (!d3d || !d3ddevice)
- return false;
-
- HRESULT hr;
-
- // set up the viewport according to args:
- D3DVIEWPORT9 view;
-
- view.X = x;
- view.Y = y;
- view.Width = w;
- view.Height = h;
- view.MinZ = 0.0f;
- view.MaxZ = 1.0f;
-
- hr = d3ddevice->SetViewport(&view);
- if (FAILED(hr)) {
- VideoDX9Error("could not initialize viewport", hr);
- return false;
- }
-
- // set up the render state:
- for (int i = FILL_MODE; i < TEXTURE_WRAP; i++) {
- if (d3dstate_table[i]) {
- d3ddevice->SetRenderState((D3DRENDERSTATETYPE) d3dstate_table[i], render_state[i]);
- }
- }
-
- d3ddevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
-
- rect.x = x;
- rect.y = y;
- rect.w = w;
- rect.h = h;
-
- return true;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::SetAmbient(Color c)
-{
- ambient = c;
- return true;
-}
-
-bool
-VideoDX9::SetLights(const List<Light>& lights)
-{
- if (d3ddevice) {
- main_light = 0;
- back_light = 0;
-
- ListIter<Light> iter = (List<Light>&) lights;
- int index = -1;
-
- while (++iter) {
- Light* light = iter.value();
-
- if (light->IsActive()) {
- D3DLIGHT9 d3d_light;
- ZeroMemory(&d3d_light, sizeof(d3d_light));
- d3d_light.Type = (D3DLIGHTTYPE) light->Type();
-
- if (light->Type() == Light::LIGHT_DIRECTIONAL) {
- d3d_light.Direction.x = (float) (-light->Location().x);
- d3d_light.Direction.y = (float) (-light->Location().y);
- d3d_light.Direction.z = (float) (-light->Location().z);
-
- if (d3d_light.Direction.x == 0 &&
- d3d_light.Direction.y == 0 &&
- d3d_light.Direction.z == 0) {
-
- d3d_light.Direction.y = -1;
- }
-
- if (light->CastsShadow()) {
- if (!main_light || light->Intensity() > main_light->Intensity())
- main_light = light;
- }
- else if (!back_light) {
- back_light = light;
- }
- }
- else {
- d3d_light.Position.x = (float) ( light->Location().x);
- d3d_light.Position.y = (float) ( light->Location().y);
- d3d_light.Position.z = (float) ( light->Location().z);
- }
-
- float r = (light->GetColor().Red() / 255.0f) * light->Intensity();
- float g = (light->GetColor().Green() / 255.0f) * light->Intensity();
- float b = (light->GetColor().Blue() / 255.0f) * light->Intensity();
-
- d3d_light.Diffuse.r = r;
- d3d_light.Diffuse.g = g;
- d3d_light.Diffuse.b = b;
-
- d3d_light.Specular.r = r;
- d3d_light.Specular.g = g;
- d3d_light.Specular.b = b;
-
- d3d_light.Range = light->Intensity() * 10.0f;
- d3d_light.Attenuation0 = 0.1f;
- d3d_light.Attenuation1 = 0.7f;
- d3d_light.Attenuation2 = 0.0f;
-
- index++;
- d3ddevice->SetLight(index, &d3d_light);
- d3ddevice->LightEnable(index, TRUE);
- }
- }
-
- // turn off any unused lights from before:
- while (nlights > index+1) {
- d3ddevice->LightEnable(--nlights, FALSE);
- }
-
- nlights = index + 1;
-
- return true;
- }
-
- return false;
-}
-
-bool
-VideoDX9::SetCamera(const Camera* cam)
-{
- if (d3ddevice) {
- camera = cam;
-
- D3DMATRIX m;
- CreateD3DMatrix(m, cam->Orientation(), cam->Pos());
- d3ddevice->SetTransform(D3DTS_VIEW, &m);
- matrixView = m;
-
- return true;
- }
-
- return false;
-}
-
-bool
-VideoDX9::SetProjection(float fov, float znear, float zfar, DWORD type)
-{
- if (d3ddevice && zfar > znear) {
- D3DMATRIX m;
- float h, w, Q;
-
- double width = (float) (rect.w);
- double height = (float) (rect.h);
- ZeroMemory(&m, sizeof(m));
-
- /***
- *** PERSPECTIVE PROJECTION:
- ***/
-
- if (type == PROJECTION_PERSPECTIVE) {
- double xscale = width / fov;
- double yscale = height / fov;
-
- double maxscale = xscale;
- if (yscale > xscale) maxscale = yscale;
-
- double xangle = atan(fov/2 * maxscale/xscale);
-
- w = (float) (2/tan(xangle)); // 1/tan(x) == cot(x)
- h = (float) (w * width/height);
- Q = zfar/(zfar - znear);
-
- m._11 = w;
- m._22 = h;
- m._33 = Q;
- m._43 = -Q*znear;
- m._34 = 1;
- }
-
- /***
- *** ORTHOGONAL PROJECTION:
- ***/
-
- else if (type == PROJECTION_ORTHOGONAL) {
- m._11 = (float) (fov/width);
- m._22 = (float) (fov/height);
- m._33 = (float) (1/(zfar-znear));
- m._43 = (float) (znear/(znear-zfar));
- m._44 = (float) (1);
- }
-
- else {
- return false;
- }
-
- d3ddevice->SetTransform(D3DTS_PROJECTION, &m);
- matrixProj = m;
-
- return true;
- }
-
- return false;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::SetEnvironment(Bitmap** faces)
-{
- if (environment_cube && !faces) {
- delete environment_cube;
- environment_cube = 0;
- return true;
- }
-
- if (!environment_cube) {
- environment_cube = new(__FILE__,__LINE__) TexCubeDX9(this);
- }
-
- if (environment_cube) {
- bool ok = true;
- for (int i = 0; i < 6; i++)
- ok = ok && environment_cube->LoadTexture(faces[i], i);
- return ok;
- }
-
- return false;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::SetRenderState(RENDER_STATE state, DWORD value)
-{
- if (!d3ddevice)
- return false;
-
- if (render_state[state] == value || d3dstate_table[state] == 0) {
- render_state[state] = value;
- return true;
- }
-
- HRESULT hr = E_FAIL;
-
- // special case for texture wrapping:
- if (state == TEXTURE_WRAP) {
- DWORD wrap = D3DTADDRESS_CLAMP;
-
- if (value)
- wrap = D3DTADDRESS_WRAP;
-
- hr = d3ddevice->SetSamplerState(0, D3DSAMP_ADDRESSU, wrap);
- hr = d3ddevice->SetSamplerState(0, D3DSAMP_ADDRESSV, wrap);
- }
-
- // special case for fog enable:
- else if (state == FOG_ENABLE) {
- if (value) {
- hr = d3ddevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_EXP);
- hr = d3ddevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_NONE);
- }
-
- hr = d3ddevice->SetRenderState(D3DRS_FOGENABLE, value);
- }
-
- // special case for z bias
- else if (state == Z_BIAS) {
- if (value) {
- FLOAT bias_scale = 1.0f;
- FLOAT depth_bias = (FLOAT) (DW2I(value) / -10000.0);
-
- hr = d3ddevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, F2DW(bias_scale));
- hr = d3ddevice->SetRenderState(D3DRS_DEPTHBIAS, F2DW(depth_bias));
- }
- else {
- hr = d3ddevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0);
- hr = d3ddevice->SetRenderState(D3DRS_DEPTHBIAS, 0);
- }
- }
-
- // set default z func along with z enable
- else if (state == Z_ENABLE) {
- hr = d3ddevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
- hr = d3ddevice->SetRenderState(D3DRS_ZENABLE, value);
- }
-
- // all other render states:
- else {
- hr = d3ddevice->SetRenderState((D3DRENDERSTATETYPE) d3dstate_table[state], value);
- }
-
- if (FAILED(hr)) {
- VideoDX9Error("could not SetRenderState", hr);
- return false;
- }
- else {
- render_state[state] = value;
- }
-
- return true;
-}
-
-bool
-VideoDX9::SetBlendType(int blend_type)
-{
- if (blend_type == current_blend_state)
- return true;
-
- switch (blend_type) {
- default:
- // map misc blend types to SOLID
- // and fall through to that case
-
- blend_type = BLEND_SOLID;
-
- case BLEND_SOLID:
- d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
- break;
-
- case BLEND_ALPHA:
- d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
- d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
- d3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
- break;
-
- case BLEND_ADDITIVE:
- d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
- d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
- d3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
- break;
- }
-
- current_blend_state = blend_type;
- return true;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::StartFrame()
-{
- if (device_lost) {
- RecoverSurfaces();
-
- if (status != VIDEO_OK)
- return false;
- }
-
- stats.Clear();
-
- HRESULT err = 0;
- static int frame_number = 1;
- static int report_errs = 100;
-
- stats.nframe = frame_number;
- texcache->FrameNumber(frame_number++);
-
- // update gamma ramp for global fade value:
- SetGammaLevel(gamma);
-
- ClearAll();
-
- err = d3ddevice->BeginScene();
-
- if (FAILED(err)) {
- if (report_errs > 0) {
- report_errs--;
- VideoDX9Error("could not begin scene", err);
- }
-
- return false;
- }
-
- scene_active = 1;
- current_blend_state = -1;
-
- SetRenderState(LIGHTING_PASS, 0);
- SetRenderState(STENCIL_ENABLE, false);
-
- return true;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::EndFrame()
-{
- HRESULT err = 0;
-
- if (scene_active) {
- err = d3ddevice->EndScene();
-
- if (FAILED(err)) {
- VideoDX9Error("could not end scene", err);
- return false;
- }
- }
-
- scene_active = 0;
- return true;
-}
-
-// +--------------------------------------------------------------------+
-
-static DWORD ColorModulate(DWORD a, DWORD b)
-{
- float a0 = (float) ((a ) & 0xff)/255.0f;
- float a1 = (float) ((a>> 8) & 0xff)/255.0f;
- float a2 = (float) ((a>>16) & 0xff)/255.0f;
- float a3 = (float) ((a>>24) & 0xff)/255.0f;
-
- float b0 = (float) ((b ) & 0xff)/255.0f;
- float b1 = (float) ((b>> 8) & 0xff)/255.0f;
- float b2 = (float) ((b>>16) & 0xff)/255.0f;
- float b3 = (float) ((b>>24) & 0xff)/255.0f;
-
- return (DWORD) ((BYTE)(a3*b3*255.0f) << 24) |
- ((BYTE)(a2*b2*255.0f) << 16) |
- ((BYTE)(a1*b1*255.0f) << 8) |
- ((BYTE)(a0*b0*255.0f));
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::PopulateScreenVerts(VertexSet* vset)
-{
- if (!vset || !screen_vbuf)
- return false;
-
- num_verts = vset->nverts;
-
- VideoDX9ScreenVertex* v = (VideoDX9ScreenVertex*) screen_vbuf->Lock(num_verts);
-
- if (v) {
- first_vert = screen_vbuf->GetNextVert();
-
- for (int i = 0; i < num_verts; i++) {
- v->sx = vset->s_loc[i].x;
- v->sy = vset->s_loc[i].y;
- v->sz = vset->s_loc[i].z;
- v->rhw = vset->rw[i];
-
- v->diffuse = vset->diffuse[i];
-
- v->tu = vset->tu[i];
- v->tv = vset->tv[i];
-
- v++;
- }
-
- screen_vbuf->Unlock();
- return true;
- }
-
- Print(" VideoDX9: could not lock screen vbuf for %d verts.\n", num_verts);
- return false;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::DrawPolys(int npolys, Poly* polys)
-{
- bool result = false;
-
- if (d3ddevice && polys && npolys > 0) {
- // screen space polys:
- if (polys->vertex_set->space == VertexSet::SCREEN_SPACE)
- return DrawScreenPolys(npolys, polys);
-
- // world space polys:
- stats.ncalls++;
-
- VertexSet* vset = polys->vertex_set;
- int nverts = vset->nverts;
- bool luminous = false;
- bool detail = false;
- DWORD fvf = 0;
- void* verts = 0;
- int vsize = 0;
- WORD* indices = new(__FILE__,__LINE__) WORD[npolys*6];
-
- if (polys->material) {
- luminous = polys->material->luminous;
- }
-
- if (vset->tu1 != 0) {
- VideoDX9DetailVertex* v = new(__FILE__,__LINE__) VideoDX9DetailVertex[nverts];
- verts = v;
- vsize = sizeof(VideoDX9DetailVertex);
- fvf = VideoDX9DetailVertex::FVF;
-
- for (int i = 0; i < nverts; i++) {
- v->x = vset->loc[i].x;
- v->y = vset->loc[i].y;
- v->z = vset->loc[i].z;
-
- v->diffuse = vset->diffuse[i];
- v->specular = vset->specular[i];
-
- v->tu = vset->tu[i];
- v->tv = vset->tv[i];
- v->tu1 = vset->tu1[i];
- v->tv1 = vset->tv1[i];
-
- v++;
- }
- }
-
- else if (luminous) {
- VideoDX9LuminousVertex* v = new(__FILE__,__LINE__) VideoDX9LuminousVertex[nverts];
- verts = v;
- vsize = sizeof(VideoDX9LuminousVertex);
- fvf = VideoDX9LuminousVertex::FVF;
-
- for (int i = 0; i < nverts; i++) {
- v->x = vset->loc[i].x;
- v->y = vset->loc[i].y;
- v->z = vset->loc[i].z;
-
- v->diffuse = vset->diffuse[i];
-
- v->tu = vset->tu[i];
- v->tv = vset->tv[i];
-
- v++;
- }
- }
-
- else {
- VideoDX9SolidVertex* v = new(__FILE__,__LINE__) VideoDX9SolidVertex[nverts];
- verts = v;
- vsize = sizeof(VideoDX9SolidVertex);
- fvf = VideoDX9SolidVertex::FVF;
-
- for (int i = 0; i < nverts; i++) {
- v->x = vset->loc[i].x;
- v->y = vset->loc[i].y;
- v->z = vset->loc[i].z;
-
- v->nx = vset->nrm[i].x;
- v->ny = vset->nrm[i].y;
- v->nz = vset->nrm[i].z;
-
- v->tu = vset->tu[i];
- v->tv = vset->tv[i];
-
- v++;
- }
- }
-
- if (verts && indices) {
- HRESULT hr = E_FAIL;
-
- // fill index array
- int num_indices = 0;
- int num_tris = 0;
-
- WORD* s = indices;
- Poly* p = polys;
-
- for (int i = 0; i < npolys; i++) {
- if (p->nverts == 3) {
- num_indices += 3;
- num_tris += 1;
-
- *s++ = p->verts[0];
- *s++ = p->verts[1];
- *s++ = p->verts[2];
- }
-
- else if (p->nverts == 4) {
- num_indices += 6;
- num_tris += 2;
-
- *s++ = p->verts[0];
- *s++ = p->verts[1];
- *s++ = p->verts[2];
-
- *s++ = p->verts[0];
- *s++ = p->verts[2];
- *s++ = p->verts[3];
- }
-
- p++;
- }
-
- hr = d3ddevice->SetTransform(D3DTS_WORLD, &identity_matrix);
- hr = d3ddevice->SetVertexShader(NULL);
- hr = d3ddevice->SetFVF(fvf);
-
- // send primitives to the device
- Material* mtl = polys->material;
- IDirect3DTexture9* texture = 0;
-
- if (mtl && texcache && mtl->tex_diffuse) {
- texture = texcache->FindTexture(mtl->tex_diffuse);
- }
-
- if (current_texture != texture) {
- hr = d3ddevice->SetTexture(0, texture);
- current_texture = texture;
- }
-
- if (mtl && texcache && mtl->tex_detail) {
- texture = texcache->FindTexture(mtl->tex_detail);
- hr = d3ddevice->SetTexture(1, texture);
- }
-
- if (mtl && !luminous) {
- D3DMATERIAL9 d3dmtl;
- CreateD3DMaterial(d3dmtl, *mtl);
-
- hr = d3ddevice->SetMaterial(&d3dmtl);
- hr = d3ddevice->SetRenderState(D3DRS_AMBIENT, ambient.Value());
- }
-
- // set render states and select buffers
- SetRenderState(FILL_MODE, D3DFILL_SOLID);
- SetRenderState(LIGHTING_ENABLE, luminous ? FALSE : TRUE);
- SetBlendType(mtl->blend);
-
- d3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
- d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
- d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
- d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
- d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
-
- d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
-
-
- hr = d3ddevice->DrawIndexedPrimitiveUP(
- D3DPT_TRIANGLELIST,
- 0,
- nverts,
- num_tris,
- indices,
- D3DFMT_INDEX16,
- verts,
- vsize);
-
- if (FAILED(hr)) {
- static int report = 10;
- if (report-- > 0)
- VideoDX9Error("Could not draw 3D polys.", hr);
- }
-
- delete [] verts;
- delete [] indices;
-
- if (SUCCEEDED(hr)) {
- stats.nverts += nverts;
- stats.npolys += num_tris;
- result = true;
- }
- }
- }
-
- return result;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::DrawScreenPolys(int npolys, Poly* polys, int blend)
-{
- bool result = false;
- HRESULT hr = E_FAIL;
-
- if (d3ddevice && polys && npolys > 0 && screen_vbuf && screen_ibuf) {
- stats.ncalls++;
-
- // fill screen vertex buffer
- if (!PopulateScreenVerts(polys->vertex_set))
- return false;
-
- // fill screen index buffer
- int num_indices = 0;
- int num_tris = 0;
-
- // count the number of indices needed for these polys
- for (int i = 0; i < npolys; i++) {
- Poly* p = polys + i;
-
- if (p->nverts == 3) {
- num_indices += 3;
- num_tris += 1;
- }
-
- else if (p->nverts == 4) {
- num_indices += 6;
- num_tris += 2;
- }
- }
-
- WORD* screen_indices = screen_ibuf->Lock(num_indices);
- int first_index = screen_ibuf->GetNextIndex();
-
- if (!screen_indices) {
- Print(" VideoDX9: could not lock screen ibuf for %d indices.\n", num_indices);
- return false;
- }
-
- // copy the indices into the locked index buffer
- WORD* s = screen_indices;
- Poly* p = polys;
-
- for (int i = 0; i < npolys; i++) {
- if (p->nverts == 3) {
- *s++ = p->verts[0] + first_vert;
- *s++ = p->verts[1] + first_vert;
- *s++ = p->verts[2] + first_vert;
- }
- else if (p->nverts == 4) {
- *s++ = p->verts[0] + first_vert;
- *s++ = p->verts[1] + first_vert;
- *s++ = p->verts[2] + first_vert;
-
- *s++ = p->verts[0] + first_vert;
- *s++ = p->verts[2] + first_vert;
- *s++ = p->verts[3] + first_vert;
- }
-
- p++;
- }
-
- screen_ibuf->Unlock();
-
- // set render states and select buffers
- SetRenderState(FILL_MODE, D3DFILL_SOLID);
- SetRenderState(Z_ENABLE, D3DZB_FALSE);
- SetRenderState(Z_WRITE_ENABLE, D3DZB_FALSE);
- SetRenderState(LIGHTING_ENABLE, FALSE);
- SetBlendType(blend);
-
- d3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
- d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
- d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
- d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
- d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
-
- d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
-
- // send primitives to the device
- Material* mtl = polys->material;
- IDirect3DTexture9* texture = 0;
-
- if (mtl && texcache && mtl->tex_diffuse) {
- texture = texcache->FindTexture(mtl->tex_diffuse);
- }
-
- if (current_texture != texture) {
- hr = d3ddevice->SetTexture(0, texture);
- current_texture = texture;
- }
-
- screen_vbuf->Select(0);
- screen_ibuf->Select();
- hr = d3ddevice->SetVertexShader(NULL);
- hr = d3ddevice->SetFVF(VideoDX9ScreenVertex::FVF);
-
- hr = d3ddevice->DrawIndexedPrimitive(
- D3DPT_TRIANGLELIST,
- 0,
- first_vert,
- num_verts,
- first_index,
- num_tris);
-
- if (FAILED(hr)) {
- static int report = 10;
- if (report-- > 0)
- VideoDX9Error("Could not draw screen polys.", hr);
- }
- else {
- stats.nverts += num_verts;
- stats.npolys += num_tris;
- result = true;
- }
- }
-
- return result;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::DrawSolid(Solid* s, DWORD blend_modes)
-{
- bool result = false;
- HRESULT hr = E_FAIL;
-
- if (d3ddevice && s && s->GetModel()) {
- Model* model = s->GetModel();
- Matrix orient = s->Orientation();
- orient.Transpose();
-
- D3DMATRIX world_matrix;
- CreateD3DMatrix(world_matrix, orient, s->Location());
- d3ddevice->SetTransform(D3DTS_WORLD, &world_matrix);
- matrixWorld = world_matrix;
- D3DXMatrixInverse(&matrixWorldInverse, 0, &matrixWorld);
-
- ListIter<Surface> surf_iter = model->GetSurfaces();
- while (++surf_iter) {
- Surface* surf = surf_iter.value();
-
- if (surf->IsHidden() || surf->IsSimplified())
- continue;
-
- if (PrepareSurface(surf)) {
- result = true;
-
- VideoDX9SurfaceData* surf_data = (VideoDX9SurfaceData*) surf->GetVideoPrivateData();
- surf_data->vertex_buffer->Select(0);
- surf_data->index_buffer->Select();
-
- ListIter<Segment> seg_iter = surf->GetSegments();
- while (++seg_iter) {
- Segment* segment = seg_iter.value();
- Material* mtl = segment->material;
-
- if (mtl && (blend_modes & mtl->blend)) {
- result = result && DrawSegment(segment);
- }
- }
- }
- }
- }
-
- surface_has_tangent_data = false;
-
- return result;
-}
-
-bool
-VideoDX9::DrawSegment(Segment* segment)
-{
- bool result = false;
- bool detail = false;
- bool luminous = false;
- HRESULT hr = E_FAIL;
-
- if (segment && segment->video_data) {
- stats.ncalls++;
-
- VideoDX9SegmentData* seg_data = (VideoDX9SegmentData*) segment->video_data;
- int first_vert = seg_data->first_vert;
- int num_verts = seg_data->num_verts;
- int first_index = seg_data->first_index;
- int num_tris = seg_data->num_tris;
-
- if (segment->model)
- luminous = segment->model->IsLuminous();
-
- // set render states and select buffers
- d3ddevice->SetRenderState(D3DRS_AMBIENT, ambient.Value());
-
- Material* mtl = segment->material;
-
- if (use_material)
- mtl = use_material;
-
- if (segment->polys && segment->polys->vertex_set && segment->polys->vertex_set->tu1)
- detail = true;
-
- // send primitives to the device
- if (detail) {
- hr = d3ddevice->SetVertexShader(NULL);
- hr = d3ddevice->SetFVF(VideoDX9DetailVertex::FVF);
- }
-
- else if (luminous) {
- hr = d3ddevice->SetVertexShader(NULL);
- hr = d3ddevice->SetFVF(VideoDX9LuminousVertex::FVF);
- }
-
- else if (surface_has_tangent_data && vertex_declaration) {
- hr = d3ddevice->SetVertexDeclaration(vertex_declaration);
- hr = d3ddevice->SetVertexShader(NULL);
- }
-
- else {
- hr = d3ddevice->SetVertexShader(NULL);
- hr = d3ddevice->SetFVF(VideoDX9SolidVertex::FVF);
- }
-
- if (render_state[FILL_MODE] == FILL_WIREFRAME) {
- PrepareMaterial(mtl);
- SetupPass(0);
-
- for (int i = 0; i < segment->npolys; i++) {
- DrawPolyOutline(segment->polys + i);
- }
- }
-
- else if (luminous) {
- PrepareMaterial(mtl);
-
- SetRenderState(FILL_MODE, D3DFILL_SOLID);
- SetRenderState(LIGHTING_ENABLE, FALSE);
- SetBlendType(mtl->blend);
-
- for (int pass = 0; pass < passes; pass++) {
- SetupPass(pass);
-
- hr = d3ddevice->DrawIndexedPrimitive(
- D3DPT_TRIANGLELIST,
- 0,
- first_vert,
- num_verts,
- first_index,
- num_tris);
- }
-
- d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
- }
-
- else {
- PrepareMaterial(mtl);
-
- if (strategy == DX9_STRATEGY_GLOW && render_state[LIGHTING_PASS] > 0) {
- hr = 0;
- }
-
- else if (magic_fx && strategy < DX9_STRATEGY_BLEND && !detail) {
- DWORD vs_version = 0;
- DWORD ps_version = 0;
- bool shaders_ok = false;
-
- VideoDX9DeviceInfo* dev_info = dx9enum->GetDeviceInfo(video_settings.GetDeviceType());
-
- if (dev_info) {
- vs_version = video_settings.enable_vs ? dev_info->caps.VertexShaderVersion : 0;
- ps_version = video_settings.enable_ps ? dev_info->caps.PixelShaderVersion : 0;
-
- if (vs_version >= D3DVS_VERSION(1,1))
- shaders_ok = true;
- }
-
- if (surface_has_tangent_data && vertex_declaration) {
- hr = d3ddevice->SetVertexShader(NULL);
- hr = d3ddevice->SetVertexDeclaration(vertex_declaration);
- }
-
- else {
- hr = d3ddevice->SetVertexShader(NULL);
- hr = d3ddevice->SetFVF(VideoDX9SolidVertex::FVF);
- }
-
- bool would_bump = !IsBumpMapEnabled() && mtl->bump > 0.5;
-
- bool will_bump = IsBumpMapEnabled() && surface_has_tangent_data && shaders_ok && camera;
-
- bool do_pix = will_bump && render_state[LIGHTING_PASS] == 0;
- bool do_bump = will_bump && render_state[LIGHTING_PASS] > 0;
-
- D3DXMATRIX matrixWVP = matrixWorld * matrixView * matrixProj;
-
- D3DXVECTOR4 eyePos( (float) camera->Pos().x, (float) camera->Pos().y, (float) camera->Pos().z, 1.0f);
-
- D3DXVECTOR4 eyeObj;
- D3DXVec4Transform(&eyeObj, &eyePos, &matrixWorldInverse);
-
- D3DXVECTOR4 lightPos(100.0f, 100.0f, 100.0f, 1.0f);
- D3DXVECTOR4 lightColor(1,1,1,1);
- D3DXVECTOR4 ambientColor(0,0,0,1);
-
- ambientColor.x = ambient.fRed();
- ambientColor.y = ambient.fGreen();
- ambientColor.z = ambient.fBlue();
-
- if (main_light && (render_state[LIGHTING_PASS] > 0 || mtl->blend > Material::MTL_SOLID)) {
- lightPos.x = (float) main_light->Location().x;
- lightPos.y = (float) main_light->Location().y;
- lightPos.z = (float) main_light->Location().z;
-
- if (mtl->tex_bumpmap && do_bump)
- D3DXVec4Transform(&lightPos, &lightPos, &matrixWorldInverse);
-
- lightColor.x = main_light->GetColor().fRed() * main_light->Intensity();
- lightColor.y = main_light->GetColor().fGreen() * main_light->Intensity();
- lightColor.z = main_light->GetColor().fBlue() * main_light->Intensity();
- lightColor.w = 1.0f;
- }
-
- else if (back_light && render_state[LIGHTING_PASS] == 0) {
- lightPos.x = (float) back_light->Location().x;
- lightPos.y = (float) back_light->Location().y;
- lightPos.z = (float) back_light->Location().z;
-
- lightColor.x = back_light->GetColor().fRed() * back_light->Intensity();
- lightColor.y = back_light->GetColor().fGreen() * back_light->Intensity();
- lightColor.z = back_light->GetColor().fBlue() * back_light->Intensity();
- lightColor.w = 1.0f;
- }
-
- D3DXVECTOR4 lightDir = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f) - lightPos;
- D3DXVec4Normalize(&lightDir, &lightDir);
-
- magic_fx->SetMatrix("wvp", &matrixWVP);
- magic_fx->SetMatrix("world", &matrixWorld);
- magic_fx->SetMatrix("view", &matrixView);
- magic_fx->SetMatrix("proj", &matrixProj);
- magic_fx->SetMatrix("worldInv", &matrixWorldInverse);
-
- magic_fx->SetVector("light1Pos", &lightPos);
- magic_fx->SetVector("light1Dir", &lightDir);
- magic_fx->SetVector("light1Color", &lightColor);
- magic_fx->SetVector("ambientColor", &ambientColor);
- magic_fx->SetVector("eyeObj", &eyeObj);
-
- FLOAT base_bias = (FLOAT) (DW2I(render_state[Z_BIAS]) / -10000.0);
- magic_fx->SetFloat("bias", base_bias + video_settings.depth_bias);
-
- ColorValue orig_ks = mtl->Ks;
-
- if (would_bump && mtl->specular_value >= 0.5)
- mtl->Ks = mtl->Ks * 0.3;
-
- magic_fx->SetValue("Ka", &mtl->Ka, sizeof(ColorValue));
- magic_fx->SetValue("Kd", &mtl->Kd, sizeof(ColorValue));
- magic_fx->SetValue("Ke", &mtl->Ke, sizeof(ColorValue));
- magic_fx->SetValue("Ks", &mtl->Ks, sizeof(ColorValue));
- magic_fx->SetFloat("Ns", mtl->power);
-
- if (would_bump && mtl->specular_value >= 0.5)
- mtl->Ks = orig_ks;
-
- if (mtl->tex_diffuse) {
- IDirect3DTexture9* texture = texcache->FindTexture(mtl->tex_diffuse);
- magic_fx->SetTexture("tex_d", texture);
- } else {
- magic_fx->SetTexture("tex_d", 0);
- }
-
- if (mtl->tex_emissive) {
- IDirect3DTexture9* texture = texcache->FindTexture(mtl->tex_emissive);
- magic_fx->SetTexture("tex_e", texture);
- } else {
- magic_fx->SetTexture("tex_e", 0);
- }
-
- if (mtl->tex_specular && IsSpecMapEnabled()) {
- IDirect3DTexture9* texture = texcache->FindTexture(mtl->tex_specular);
- magic_fx->SetTexture("tex_s", texture);
- } else {
- magic_fx->SetTexture("tex_s", 0);
- }
-
- if (mtl->tex_bumpmap && do_bump) {
- IDirect3DTexture9* texture = texcache->FindNormalMap(mtl->tex_bumpmap, mtl->bump);
- magic_fx->SetTexture("tex_n", texture);
- magic_fx->SetFloat("offsetAmp", mtl->bump / mtl->tex_bumpmap->Height());
- } else if (mtl->tex_bumpmap && !do_bump) {
- IDirect3DTexture9* texture = texcache->FindTexture(mtl->tex_bumpmap);
- magic_fx->SetTexture("tex_x", texture);
- } else {
- magic_fx->SetTexture("tex_x", 0);
- }
-
- const char* mtl_shader = mtl->GetShader(render_state[LIGHTING_PASS]);
- D3DXHANDLE hnd_shader = 0;
-
- if (mtl_shader) {
- if (!strcmp(mtl_shader, "null"))
- return true;
-
- hnd_shader = magic_fx->GetTechniqueByName(mtl_shader);
- }
-
- if (hnd_shader) {
- hr = magic_fx->SetTechnique(hnd_shader);
- } else {
- if (will_bump) {
- if (mtl->tex_specular && IsSpecMapEnabled()) {
- if (mtl->tex_bumpmap && do_bump) {
- if (ps_version >= D3DPS_VERSION(2,0))
- hr = magic_fx->SetTechnique("BumpSpecMapPix");
- else
- hr = magic_fx->SetTechnique("BumpSpecMap");
- } else if (mtl->tex_emissive && render_state[LIGHTING_PASS] == 0) {
- if (ps_version >= D3DPS_VERSION(2,0))
- hr = magic_fx->SetTechnique("EmissiveSpecMapPix");
- else
- hr = magic_fx->SetTechnique("EmissiveSpecularTexture");
- } else {
- if (ps_version >= D3DPS_VERSION(2,0))
- hr = magic_fx->SetTechnique("SpecMapPix");
- else
- hr = magic_fx->SetTechnique("SpecularTexture");
- }
- } else {
- if (mtl->tex_bumpmap && do_bump) {
- if (ps_version >= D3DPS_VERSION(2,0))
- hr = magic_fx->SetTechnique("BumpMapPix");
- else
- hr = magic_fx->SetTechnique("BumpMap");
- } else if (mtl->tex_emissive && render_state[LIGHTING_PASS] == 0) {
- if (ps_version >= D3DPS_VERSION(2,0))
- hr = magic_fx->SetTechnique("EmissivePix");
- else
- hr = magic_fx->SetTechnique("EmissiveTexture");
- } else {
- if (ps_version >= D3DPS_VERSION(2,0))
- hr = magic_fx->SetTechnique("SimplePix");
- else
- hr = magic_fx->SetTechnique("SimpleTexture");
- }
- }
- }
-
- else if (texcache && mtl->tex_diffuse) {
- if (mtl->tex_specular && IsSpecMapEnabled()) {
- if (mtl->tex_emissive && render_state[LIGHTING_PASS] == 0) {
- hr = magic_fx->SetTechnique("EmissiveSpecularTexture");
- } else {
- hr = magic_fx->SetTechnique("SpecularTexture");
- }
- }
-
- else {
- if (mtl->tex_emissive && render_state[LIGHTING_PASS] == 0) {
- hr = magic_fx->SetTechnique("EmissiveTexture");
- } else {
- hr = magic_fx->SetTechnique("SimpleTexture");
- }
- }
- } else {
- hr = magic_fx->SetTechnique("SimpleMaterial");
- }
- }
-
- if (environment_cube != 0 && magic_fx->IsParameterUsed("env_cube", hnd_shader)) {
- D3DXMATRIX env_matrix;
- D3DXMatrixIdentity(&env_matrix);
-
- magic_fx->SetMatrix("env_matrix", &env_matrix);
- magic_fx->SetTexture("env_cube", environment_cube->GetTexture());
- }
-
- if (render_state[STENCIL_ENABLE]) {
- d3ddevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
- d3ddevice->SetRenderState(D3DRS_STENCILREF, 0x01);
- d3ddevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_GREATER);
- } else {
- d3ddevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
- }
-
- if (render_state[LIGHTING_PASS] > 0) {
- current_blend_state = 100;
- SetBlendType(BLEND_ADDITIVE);
- SetRenderState(Z_WRITE_ENABLE, FALSE);
- } else {
- current_blend_state = 100;
- SetBlendType(mtl->blend);
- }
-
- UINT nPasses = 0;
-
- hr = magic_fx->Begin(&nPasses, 0);
-
- for (UINT i = 0; i < nPasses; i++) {
- hr = magic_fx->BeginPass(i);
-
- hr = d3ddevice->DrawIndexedPrimitive(
- D3DPT_TRIANGLELIST,
- 0,
- first_vert,
- num_verts,
- first_index,
- num_tris);
-
- hr = magic_fx->EndPass();
- }
-
- hr = magic_fx->End();
- } else {
- for (int pass = 0; pass < passes; pass++) {
- SetupPass(pass);
-
- hr = d3ddevice->DrawIndexedPrimitive(
- D3DPT_TRIANGLELIST,
- 0,
- first_vert,
- num_verts,
- first_index,
- num_tris);
-
- if (detail) {
- hr = d3ddevice->SetVertexShader(NULL);
- hr = d3ddevice->SetFVF(VideoDX9DetailVertex::FVF);
- } else if (luminous) {
- hr = d3ddevice->SetVertexShader(NULL);
- hr = d3ddevice->SetFVF(VideoDX9LuminousVertex::FVF);
- } else if (surface_has_tangent_data && vertex_declaration) {
- hr = d3ddevice->SetVertexShader(NULL);
- hr = d3ddevice->SetVertexDeclaration(vertex_declaration);
- } else {
- hr = d3ddevice->SetVertexShader(NULL);
- hr = d3ddevice->SetFVF(VideoDX9SolidVertex::FVF);
- }
- }
- }
- }
-
- if (FAILED(hr)) {
- static int report = 10;
- if (report-- > 0)
- VideoDX9Error("Could not draw solid polys.", hr);
- } else {
- stats.nverts += num_verts;
- stats.npolys += num_tris;
- result = true;
- }
- }
-
- return result;
-}
-
-bool
-VideoDX9::DrawPolyOutline(Poly* p)
-{
- if (d3ddevice && p && p->nverts >= 3) {
- static VideoDX9LineVertex verts[8];
-
- int nlines = p->nverts;
- VertexSet* vset = p->vertex_set;
- WORD index = 0;
- Color color = Color::Black;
- HRESULT hr = E_FAIL;
-
- ZeroMemory(verts, sizeof(verts));
-
- if (p->material)
- color = p->material->Kd.ToColor();
-
- for (int i = 0; i < p->nverts; i++) {
- index = p->verts[i];
-
- verts[i].x = vset->loc[index].x;
- verts[i].y = vset->loc[index].y;
- verts[i].z = vset->loc[index].z;
- verts[i].diffuse = color.Value();
- }
-
- // last vertex, to close the loop
- index = p->verts[0];
- int i = p->nverts;
-
- verts[i].x = vset->loc[index].x;
- verts[i].y = vset->loc[index].y;
- verts[i].z = vset->loc[index].z;
- verts[i].diffuse = color.Value();
-
- current_texture = 0;
-
- hr = d3ddevice->SetVertexShader(NULL);
- hr = d3ddevice->SetFVF(VideoDX9LineVertex::FVF);
- hr = d3ddevice->SetTexture(0, 0);
- hr = d3ddevice->DrawPrimitiveUP(
- D3DPT_LINESTRIP,
- nlines,
- verts,
- sizeof(VideoDX9LineVertex));
- return true;
- }
-
- return false;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::DrawShadow(Solid* s, int nverts, Vec3* shadow_verts, bool visible)
-{
- bool result = false;
- HRESULT hr = E_FAIL;
-
- if (d3ddevice && s && nverts && shadow_verts && IsShadowEnabled()) {
- Matrix orient = s->Orientation();
- orient.Transpose();
-
- D3DMATRIX world_matrix;
- CreateD3DMatrix(world_matrix, orient, s->Location());
- d3ddevice->SetTransform(D3DTS_WORLD, &world_matrix);
- matrixWorld = world_matrix;
-
- // show shadow outlines:
- if (visible) {
- static VideoDX9LineVertex verts[4];
-
- d3ddevice->SetRenderState(D3DRS_ZENABLE, TRUE);
- d3ddevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
- d3ddevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
- d3ddevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
- d3ddevice->SetRenderState(D3DRS_LIGHTING, FALSE);
- d3ddevice->SetVertexShader(NULL);
- d3ddevice->SetFVF(VideoDX9LineVertex::FVF);
- d3ddevice->SetTexture(0, 0);
-
- SetBlendType(BLEND_ALPHA);
-
- for (int i = 0; i < nverts; i+=3) {
- DWORD c = 0xa0ffff80;
-
- verts[0].x = shadow_verts[i+0].x;
- verts[0].y = shadow_verts[i+0].y;
- verts[0].z = shadow_verts[i+0].z;
- verts[0].diffuse = c;
-
- verts[1].x = shadow_verts[i+1].x;
- verts[1].y = shadow_verts[i+1].y;
- verts[1].z = shadow_verts[i+1].z;
- verts[1].diffuse = c;
-
- verts[2].x = shadow_verts[i+2].x;
- verts[2].y = shadow_verts[i+2].y;
- verts[2].z = shadow_verts[i+2].z;
- verts[2].diffuse = c;
-
- verts[3].x = shadow_verts[i+0].x;
- verts[3].y = shadow_verts[i+0].y;
- verts[3].z = shadow_verts[i+0].z;
- verts[3].diffuse = c;
-
- hr = d3ddevice->DrawPrimitiveUP(
- D3DPT_LINESTRIP,
- 3,
- verts,
- sizeof(VideoDX9LineVertex));
- }
-
- // restore lighting state
- d3ddevice->SetRenderState(D3DRS_LIGHTING, render_state[LIGHTING_ENABLE]);
- }
-
- // render shadows into stencil buffer:
-
- // Disable z-buffer writes (note: z-testing still occurs), and enable the
- // stencil-buffer
- d3ddevice->SetRenderState(D3DRS_ZENABLE, TRUE);
- d3ddevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
- d3ddevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
-
- // Dont bother with interpolating color
- d3ddevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
-
- // Set up stencil compare fuction, reference value, and masks.
- // Stencil test passes if ((ref & mask) cmpfn (stencil & mask)) is true.
- // Note: since we set up the stencil-test to always pass, the STENCILFAIL
- // renderstate is really not needed.
- d3ddevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS );
- d3ddevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP );
- d3ddevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP );
-
- // If z-test passes, inc/decrement stencil buffer value
- d3ddevice->SetRenderState(D3DRS_STENCILREF, 0x1 );
- d3ddevice->SetRenderState(D3DRS_STENCILMASK, 0xff );
- d3ddevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xff );
- d3ddevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR );
-
- // Make sure that no pixels get drawn to the frame buffer
- d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE );
- d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO );
- d3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE );
-
- d3ddevice->SetVertexShader(NULL);
- d3ddevice->SetFVF(D3DFVF_XYZ);
-
- // Draw front-side of shadow volume in stencil/z only
- hr = d3ddevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, nverts/3, shadow_verts, sizeof(Vec3));
-
- // Now reverse cull order so back sides of shadow volume are written.
- d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW );
-
- // Decrement stencil buffer value
- d3ddevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_DECR );
-
- // Draw back-side of shadow volume in stencil/z only
- hr = d3ddevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, nverts/3, shadow_verts, sizeof(Vec3));
-
- // restore render states
- d3ddevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
- d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
- d3ddevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
- d3ddevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
-
- // force restore of current blend type
- int type = current_blend_state;
- current_blend_state = 100;
- SetBlendType(type);
-
- result = SUCCEEDED(hr);
- }
-
- return result;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::DrawLines(int nlines, Vec3* points, Color c, int blend)
-{
- bool result = false;
-
- if (d3ddevice && points && nlines > 0 && nlines <= 256) {
- stats.ncalls++;
-
- VideoDX9LineVertex* verts = line_verts;
-
- if (verts) {
- HRESULT hr = E_FAIL;
-
- for (int i = 0; i < 2*nlines; i++) {
- VideoDX9LineVertex* v = verts + i;
- Vec3* p = points + i;
-
- v->x = p->x;
- v->y = p->y;
- v->z = p->z;
- v->diffuse = c.Value();
- }
-
- hr = d3ddevice->SetTransform(D3DTS_WORLD, &identity_matrix);
- hr = d3ddevice->SetVertexShader(NULL);
- hr = d3ddevice->SetFVF(VideoDX9LineVertex::FVF);
-
- DWORD old_lighting = render_state[LIGHTING_ENABLE];
-
- // untextured lines:
- if (current_texture) {
- d3ddevice->SetTexture(0, 0);
- current_texture = 0;
- }
-
- SetRenderState(LIGHTING_ENABLE, FALSE);
- SetBlendType(blend);
-
- hr = d3ddevice->DrawPrimitiveUP(
- D3DPT_LINELIST,
- nlines,
- verts,
- sizeof(VideoDX9LineVertex));
-
- if (FAILED(hr)) {
- static int report = 10;
- if (report-- > 0)
- VideoDX9Error("Could not draw 3D lines.", hr);
- }
-
- SetRenderState(LIGHTING_ENABLE, old_lighting);
-
- if (SUCCEEDED(hr)) {
- stats.nverts += 2*nlines;
- stats.nlines += nlines;
- result = true;
- }
- }
- }
-
- return result;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::DrawScreenLines(int nlines, float* points, Color c, int blend)
-{
- bool result = false;
-
- if (d3ddevice && points && nlines > 0 && nlines <= 64) {
- stats.ncalls++;
-
- VideoDX9ScreenVertex* verts = screen_line_verts;
-
- if (verts) {
- HRESULT hr = E_FAIL;
-
- for (int i = 0; i < 2*nlines; i++) {
- VideoDX9ScreenVertex* v = verts + i;
-
- v->sx = points[2*i + 0];
- v->sy = points[2*i + 1];
- v->sz = 0.0f;
- v->rhw = 1.0f;
- v->diffuse = c.Value();
- v->tu = 0.0f;
- v->tv = 0.0f;
- }
-
- hr = d3ddevice->SetVertexShader(NULL);
- hr = d3ddevice->SetFVF(VideoDX9ScreenVertex::FVF);
-
- if (FAILED(hr)) {
- static int report = 10;
- if (report-- > 0)
- VideoDX9Error("Could not set FVF for screen lines.", hr);
- }
-
- else {
- if (current_texture != 0) {
- hr = d3ddevice->SetTexture(0, 0);
- current_texture = 0;
- }
-
- SetRenderState(FILL_MODE, D3DFILL_SOLID);
- SetRenderState(Z_ENABLE, D3DZB_FALSE);
- SetRenderState(LIGHTING_ENABLE, FALSE);
- SetBlendType(blend);
-
- hr = d3ddevice->DrawPrimitiveUP(
- D3DPT_LINELIST,
- nlines,
- verts,
- sizeof(VideoDX9ScreenVertex));
-
- if (FAILED(hr)) {
- static int report = 10;
- if (report-- > 0)
- VideoDX9Error("Could not draw screen lines.", hr);
- }
- }
-
- if (SUCCEEDED(hr)) {
- stats.nverts += 2*nlines;
- stats.nlines += nlines;
- result = true;
- }
- }
- }
-
- return result;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::DrawPoints(VertexSet* vset)
-{
- if (vset && vset->nverts) {
- HRESULT hr = E_FAIL;
-
- int nverts = vset->nverts;
- VideoDX9LineVertex* verts = new(__FILE__,__LINE__) VideoDX9LineVertex[nverts];
-
- if (verts) {
- for (int i = 0; i < nverts; i++) {
- VideoDX9LineVertex* v = verts + i;
- Vec3* p = vset->loc + i;
-
- v->x = p->x;
- v->y = p->y;
- v->z = p->z;
- v->diffuse = vset->diffuse[i];
- }
-
- SetRenderState(LIGHTING_ENABLE, FALSE);
-
- hr = d3ddevice->SetTransform(D3DTS_WORLD, &identity_matrix);
- hr = d3ddevice->SetVertexShader(NULL);
- hr = d3ddevice->SetFVF(VideoDX9LineVertex::FVF);
- hr = d3ddevice->SetTexture(0, 0);
- hr = d3ddevice->DrawPrimitiveUP(
- D3DPT_POINTLIST,
- nverts,
- verts,
- sizeof(VideoDX9LineVertex));
-
- delete [] verts;
- return true;
- }
- }
-
- return false;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::UseMaterial(Material* m)
-{
- use_material = m;
- return true;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::UseXFont(const char* name, int size, bool bold, bool ital)
-{
- if (d3ddevice && name && *name && size > 4) {
- RELEASE(d3dx_font);
-
- strcpy_s(font_name, name);
- font_size = size;
- font_bold = bold;
- font_ital = ital;
-
- HRESULT hr = E_FAIL;
- HDC hdc = GetDC(NULL);
- int nLogPixelsY = GetDeviceCaps(hdc, LOGPIXELSY);
-
- ReleaseDC(NULL, hdc);
-
- int nHeight = -size * nLogPixelsY / 72;
-
- hr = D3DXCreateFont(d3ddevice, // D3D device
- nHeight, // Height
- 0, // Width
- bold ? FW_BOLD : FW_NORMAL, // Weight
- 1, // MipLevels, 0 = autogen mipmaps
- ital, // Italic
- DEFAULT_CHARSET, // CharSet
- OUT_DEFAULT_PRECIS, // OutputPrecision
- DEFAULT_QUALITY, // Quality
- DEFAULT_PITCH | FF_DONTCARE, // PitchAndFamily
- name, // pFaceName
- &d3dx_font); // ppFont
-
- if (SUCCEEDED(hr)) {
- return true;
- }
- }
-
- RELEASE(d3dx_font);
- return false;
-}
-
-bool
-VideoDX9::DrawText(const char* text, int count, const Rect& rect, DWORD format, Color c)
-{
- if (d3ddevice && text && *text && d3dx_font) {
- RECT r;
- r.left = rect.x;
- r.top = rect.y;
- r.right = rect.x + rect.w;
- r.bottom = rect.y + rect.h;
-
- d3dx_font->DrawText(0, text, count, &r, format, c.Value());
- }
-
- return false;
-}
-
-// +--------------------------------------------------------------------+
-
-bool
-VideoDX9::PrepareSurface(Surface* surf)
-{
- if (surf) {
- int nverts = surf->NumVerts();
- int nindices = surf->NumIndices();
- bool detail = surf->GetVertexSet()->tu1 != 0;
- bool luminous = false;
- DWORD dynamic = 0;
-
- if (surf->GetModel()) {
- luminous = surf->GetModel()->IsLuminous();
- dynamic = surf->GetModel()->IsDynamic() ? D3DUSAGE_DYNAMIC : 0;
- }
-
- surface_has_tangent_data = !luminous && (surf->GetVertexSet()->tangent && surf->GetVertexSet()->binormal);
-
- VideoDX9SurfaceData* surf_data = (VideoDX9SurfaceData*) surf->GetVideoPrivateData();
-
- if (!surf_data) {
- surf_data = new(__FILE__,__LINE__) VideoDX9SurfaceData(surf->GetModel());
-
- surface_has_tangent_data = false;
-
- if (surf->GetVertexSet()->tangent && surf->GetVertexSet()->binormal) {
- surface_has_tangent_data = true;
- surf_data->vertex_buffer = new(__FILE__,__LINE__) VideoDX9VertexBuffer(
- this,
- nverts,
- sizeof(VideoDX9NormalVertex),
- 0, // not an FVF vertex buffer
- dynamic | D3DUSAGE_WRITEONLY);
- }
-
- else if (detail) {
- surf_data->vertex_buffer = new(__FILE__,__LINE__) VideoDX9VertexBuffer(
- this,
- nverts,
- sizeof(VideoDX9DetailVertex),
- VideoDX9DetailVertex::FVF,
- dynamic | D3DUSAGE_WRITEONLY);
- }
-
- else if (luminous) {
- surf_data->vertex_buffer = new(__FILE__,__LINE__) VideoDX9VertexBuffer(
- this,
- nverts,
- sizeof(VideoDX9LuminousVertex),
- VideoDX9LuminousVertex::FVF,
- dynamic | D3DUSAGE_WRITEONLY);
- }
-
- else {
- surf_data->vertex_buffer = new(__FILE__,__LINE__) VideoDX9VertexBuffer(
- this,
- nverts,
- sizeof(VideoDX9SolidVertex),
- VideoDX9SolidVertex::FVF,
- dynamic | D3DUSAGE_WRITEONLY);
- }
-
- surf_data->index_buffer = new(__FILE__,__LINE__) VideoDX9IndexBuffer(
- this,
- nindices,
- dynamic | D3DUSAGE_WRITEONLY);
-
- if (!surf_data->vertex_buffer || !surf_data->index_buffer) {
- Print("VideoDX9: Unable to prepare surface '%s'\n", surf->Name());
- delete surf_data;
- return false;
- }
-
- surf->SetVideoPrivateData(surf_data);
- }
-
- if (surf_data && !surf_data->IsValid()) {
- if (detail) {
- VideoDX9DetailVertex* v = (VideoDX9DetailVertex*) surf_data->vertex_buffer->Lock(nverts);
-
- if (v) {
- const VertexSet* vset = surf->GetVertexSet();
- for (int i = 0; i < nverts; i++) {
- v->x = vset->loc[i].x;
- v->y = vset->loc[i].y;
- v->z = vset->loc[i].z;
-
- v->diffuse = vset->diffuse[i];
- v->specular = vset->specular[i];
-
- v->tu = vset->tu[i];
- v->tv = vset->tv[i];
- v->tu1 = vset->tu1[i];
- v->tv1 = vset->tv1[i];
-
- v++;
- }
-
- surf_data->vertex_buffer->Unlock();
- }
- }
-
- else if (luminous) {
- VideoDX9LuminousVertex* v = (VideoDX9LuminousVertex*) surf_data->vertex_buffer->Lock(nverts);
-
- if (v) {
- const VertexSet* vset = surf->GetVertexSet();
- for (int i = 0; i < nverts; i++) {
- v->x = vset->loc[i].x;
- v->y = vset->loc[i].y;
- v->z = vset->loc[i].z;
-
- v->diffuse = vset->diffuse[i];
-
- v->tu = vset->tu[i];
- v->tv = vset->tv[i];
-
- v++;
- }
-
- surf_data->vertex_buffer->Unlock();
- }
- }
-
- else if (surface_has_tangent_data) {
- VideoDX9NormalVertex* v = (VideoDX9NormalVertex*) surf_data->vertex_buffer->Lock(nverts);
-
- if (v) {
- const VertexSet* vset = surf->GetVertexSet();
- for (int i = 0; i < nverts; i++) {
- v->x = vset->loc[i].x;
- v->y = vset->loc[i].y;
- v->z = vset->loc[i].z;
-
- v->nx = vset->nrm[i].x;
- v->ny = vset->nrm[i].y;
- v->nz = vset->nrm[i].z;
-
- v->t0u = vset->tu[i];
- v->t0v = vset->tv[i];
- v->t1u = vset->tu[i];
- v->t1v = vset->tv[i];
-
- v->tx = vset->tangent[i].x;
- v->ty = vset->tangent[i].y;
- v->tz = vset->tangent[i].z;
-
- v->bx = vset->binormal[i].x;
- v->by = vset->binormal[i].y;
- v->bz = vset->binormal[i].z;
-
- v++;
- }
-
- surf_data->vertex_buffer->Unlock();
- }
- }
-
- else {
- VideoDX9SolidVertex* v = (VideoDX9SolidVertex*) surf_data->vertex_buffer->Lock(nverts);
-
- if (v) {
- const VertexSet* vset = surf->GetVertexSet();
- for (int i = 0; i < nverts; i++) {
- v->x = vset->loc[i].x;
- v->y = vset->loc[i].y;
- v->z = vset->loc[i].z;
-
- v->nx = vset->nrm[i].x;
- v->ny = vset->nrm[i].y;
- v->nz = vset->nrm[i].z;
-
- v->tu = vset->tu[i];
- v->tv = vset->tv[i];
-
- v++;
- }
-
- surf_data->vertex_buffer->Unlock();
- }
- }
-
- WORD* indices = surf_data->index_buffer->Lock(nindices);
-
- if (indices) {
- // copy the indices into the locked index buffer
- WORD* s = indices;
- Poly* p = surf->GetPolys();
-
- for (int i = 0; i < surf->NumPolys(); i++) {
- if (p->nverts == 3) {
- *s++ = p->verts[0];
- *s++ = p->verts[2];
- *s++ = p->verts[1];
- }
- else if (p->nverts == 4) {
- *s++ = p->verts[0];
- *s++ = p->verts[2];
- *s++ = p->verts[1];
-
- *s++ = p->verts[0];
- *s++ = p->verts[3];
- *s++ = p->verts[2];
- }
-
- p++;
- }
-
- surf_data->index_buffer->Unlock();
- }
-
- surf_data->Validate();
- }
-
- int first_index = 0;
-
- ListIter<Segment> seg_iter = surf->GetSegments();
- while (++seg_iter) {
- Segment* segment = seg_iter.value();
-
- if (!segment->video_data) {
- VideoDX9SegmentData* seg_data = new(__FILE__,__LINE__) VideoDX9SegmentData;
-
- int num_tris = 0;
- for (int i = 0; i < segment->npolys; i++)
- num_tris += segment->polys[i].nverts-2;
-
- seg_data->first_vert = 0;
- seg_data->num_verts = surf->NumVerts();
- seg_data->first_index = first_index;
- seg_data->num_tris = num_tris;
-
- segment->video_data = seg_data;
-
- first_index += num_tris * 3;
- }
- }
- }
-
- return true;
-}
-
-// +--------------------------------------------------------------------+
-
-int
-VideoDX9::PrepareMaterial(Material* m)
-{
- segment_material = m;
- strategy = 0;
- passes = 0;
-
- if (m) {
- int max_stages = 1;
- int max_textures = 1;
- bool multiply_add = false;
- bool dotproduct3 = false;
- bool vertexshader = false;
- bool pixelshader = false;
- DWORD vs_version = 0;
- DWORD ps_version = 0;
-
- VideoDX9DeviceInfo* dev_info = dx9enum->GetDeviceInfo(video_settings.GetDeviceType());
-
- if (dev_info) {
- max_stages = (int) dev_info->caps.MaxTextureBlendStages;
- max_textures = (int) dev_info->caps.MaxSimultaneousTextures;
- multiply_add = (dev_info->caps.TextureOpCaps & D3DTEXOPCAPS_MULTIPLYADD) ? true : false;
- dotproduct3 = (dev_info->caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3) ? true : false;
-
- vs_version = video_settings.enable_vs ? dev_info->caps.VertexShaderVersion : 0;
- ps_version = video_settings.enable_ps ? dev_info->caps.PixelShaderVersion : 0;
-
- vertexshader = vs_version >= D3DVS_VERSION(1,1);
- pixelshader = ps_version >= D3DPS_VERSION(2,0);
- }
-
- strategy = DX9_STRATEGY_SIMPLE;
- passes = 1;
-
- if (m->tex_alternate) {
- if (m->tex_detail && max_textures > 2 && max_stages > 4)
- strategy = DX9_STRATEGY_BLEND_DETAIL;
-
- else if (max_textures > 1 && max_stages > 3)
- strategy = DX9_STRATEGY_BLEND;
- }
-
- else if (m->tex_emissive && (!m->tex_diffuse || m->tex_diffuse == m->tex_emissive)) {
- strategy = DX9_STRATEGY_GLOW;
- }
-
- else if (IsSpecMapEnabled() && m->tex_specular && !m->tex_emissive) {
- strategy = DX9_STRATEGY_SPECMAP;
-
- if (max_textures < 2 || max_stages < 2 || !multiply_add)
- passes = 2;
- }
-
- else if ((!IsSpecMapEnabled() || !m->tex_specular) && m->tex_emissive) {
- strategy = DX9_STRATEGY_EMISSIVE;
-
- if (max_textures < 2 || max_stages < 2)
- passes = 2;
- }
-
- else if (IsSpecMapEnabled() && m->tex_specular && m->tex_emissive) {
- strategy = DX9_STRATEGY_SPEC_EMISSIVE;
-
- if (max_textures < 2 || max_stages < 2)
- passes = 3;
-
- else if (max_textures < 3 || max_stages < 3 || !multiply_add)
- passes = 2;
- }
- }
-
- return passes;
-}
-
-bool
-VideoDX9::SetupPass(int pass)
-{
- if (pass < 0 || pass >= passes)
- return false;
-
- if (pass == 0) {
- D3DMATERIAL9 d3dmtl;
- IDirect3DTexture9* texture_0 = 0;
- IDirect3DTexture9* texture_1 = 0;
- IDirect3DTexture9* texture_2 = 0;
- Bitmap* tex_bmp_0 = 0;
- Bitmap* tex_bmp_1 = 0;
- Bitmap* tex_bmp_2 = 0;
- ColorValue orig_spec = segment_material->Ks;
- HRESULT hr = E_FAIL;
-
- if (segment_material->tex_specular && passes > 1)
- segment_material->Ks = Color::Black;
-
- CreateD3DMaterial(d3dmtl, *segment_material);
- segment_material->Ks = orig_spec;
-
- hr = d3ddevice->SetMaterial(&d3dmtl);
-
- if (strategy == DX9_STRATEGY_SIMPLE) {
- tex_bmp_0 = segment_material->tex_diffuse;
- }
-
- else if (strategy == DX9_STRATEGY_BLEND) {
- tex_bmp_0 = segment_material->tex_diffuse;
- tex_bmp_1 = segment_material->tex_alternate;
- }
-
- else if (strategy == DX9_STRATEGY_BLEND_DETAIL) {
- tex_bmp_0 = segment_material->tex_diffuse;
- tex_bmp_1 = segment_material->tex_alternate;
- tex_bmp_2 = segment_material->tex_detail;
- }
-
- else if (strategy == DX9_STRATEGY_SPECMAP) {
- if (passes == 1) {
- tex_bmp_0 = segment_material->tex_diffuse;
- tex_bmp_1 = segment_material->tex_specular;
- }
- else {
- tex_bmp_0 = segment_material->tex_diffuse;
- }
- }
-
- else if (strategy == DX9_STRATEGY_EMISSIVE && passes == 1 ||
- strategy == DX9_STRATEGY_SPEC_EMISSIVE && passes == 2) {
- if (segment_material->tex_diffuse) {
- tex_bmp_0 = segment_material->tex_diffuse;
- tex_bmp_1 = segment_material->tex_emissive;
- }
- else {
- tex_bmp_0 = segment_material->tex_emissive;
- }
- }
-
- else {
- tex_bmp_0 = segment_material->tex_emissive;
- }
-
- if (texcache && tex_bmp_0) {
- texture_0 = texcache->FindTexture(tex_bmp_0);
-
- hr = d3ddevice->SetTexture(0, texture_0);
- current_texture = texture_0;
-
- if (tex_bmp_1) {
- texture_1 = texcache->FindTexture(tex_bmp_1);
- hr = d3ddevice->SetTexture(1, texture_1);
-
- if (tex_bmp_2) {
- texture_2 = texcache->FindTexture(tex_bmp_2);
- hr = d3ddevice->SetTexture(2, texture_2);
- }
- }
- }
- else {
- hr = d3ddevice->SetTexture(0, 0);
- current_texture = 0;
- }
-
- SetBlendType(segment_material->blend);
-
- if (texture_0 && texture_1 && strategy == DX9_STRATEGY_BLEND) {
- d3ddevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
- d3ddevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
- d3ddevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
-
- d3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
- d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
- d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
-
- d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_BLENDCURRENTALPHA);
- d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
- d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE);
- d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
- d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
- d3ddevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);
-
- d3ddevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_MODULATE);
- d3ddevice->SetTextureStageState(2, D3DTSS_COLORARG1, D3DTA_CURRENT);
- d3ddevice->SetTextureStageState(2, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
- d3ddevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
- d3ddevice->SetTextureStageState(2, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
-
- d3ddevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE);
- }
-
- else if (texture_0 && texture_1 && texture_2 && strategy == DX9_STRATEGY_BLEND_DETAIL) {
- d3ddevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
- d3ddevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
- d3ddevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
- d3ddevice->SetSamplerState(2, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
- d3ddevice->SetSamplerState(2, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
- d3ddevice->SetSamplerState(2, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
-
- d3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
- d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
- d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
- d3ddevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
-
- d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_BLENDCURRENTALPHA);
- d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
- d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE);
- d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
- d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
- d3ddevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);
-
- d3ddevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
- d3ddevice->SetTextureStageState(2, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- d3ddevice->SetTextureStageState(2, D3DTSS_COLORARG2, D3DTA_CURRENT);
- d3ddevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
- d3ddevice->SetTextureStageState(2, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
- d3ddevice->SetTextureStageState(2, D3DTSS_TEXCOORDINDEX, 1);
-
- d3ddevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_MODULATE);
- d3ddevice->SetTextureStageState(3, D3DTSS_COLORARG1, D3DTA_CURRENT);
- d3ddevice->SetTextureStageState(3, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
- d3ddevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
- d3ddevice->SetTextureStageState(3, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
- }
-
- else if (texture_0 && strategy == DX9_STRATEGY_GLOW) {
- d3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
- d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
- d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
- d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
- }
-
- else if (texture_0) {
- d3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
- d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
- d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
- d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
- }
-
- if (texture_1 && strategy == DX9_STRATEGY_SPECMAP) {
- d3ddevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
- d3ddevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
- d3ddevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
-
- d3ddevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);
- d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MULTIPLYADD);
- d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_SPECULAR);
- d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
- d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
- }
-
- else if (texture_1 && strategy == DX9_STRATEGY_EMISSIVE) {
- d3ddevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
- d3ddevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
- d3ddevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
-
- d3ddevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);
- d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD);
- d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
- d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
- d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
- }
-
- else if (texture_1 && strategy == DX9_STRATEGY_SPEC_EMISSIVE) {
- d3ddevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
- d3ddevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
- d3ddevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
-
- d3ddevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);
- d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD);
- d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
- d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
- d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
- }
-
- else if (strategy < DX9_STRATEGY_BLEND) {
- d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
- }
- }
-
- else if (pass == 1) {
- D3DMATERIAL9 d3dmtl;
- IDirect3DTexture9* texture = 0;
- Bitmap* tex_bmp = 0;
- ColorValue orig_Ka = segment_material->Ka;
- ColorValue orig_Kd = segment_material->Kd;
- HRESULT hr = E_FAIL;
-
- if (segment_material->tex_specular) {
- segment_material->Ka = Color::Black;
- segment_material->Kd = Color::Black;
- }
-
- CreateD3DMaterial(d3dmtl, *segment_material);
-
- segment_material->Ka = orig_Ka;
- segment_material->Kd = orig_Kd;
-
- hr = d3ddevice->SetMaterial(&d3dmtl);
-
- if (strategy == DX9_STRATEGY_SPECMAP ||
- strategy == DX9_STRATEGY_SPEC_EMISSIVE) {
- tex_bmp = segment_material->tex_specular;
- d3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
- d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_SPECULAR);
- }
-
- else if (strategy == DX9_STRATEGY_EMISSIVE) {
- tex_bmp = segment_material->tex_emissive;
- d3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
- d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- }
-
- d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
-
- if (texcache && tex_bmp) {
- texture = texcache->FindTexture(tex_bmp);
- hr = d3ddevice->SetTexture(0, texture);
- current_texture = texture;
-
- SetBlendType(BLEND_ADDITIVE);
- }
- }
-
- if (render_state[STENCIL_ENABLE]) {
- d3ddevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
- d3ddevice->SetRenderState(D3DRS_STENCILREF, 0x01);
- d3ddevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_GREATER);
- }
- else {
- d3ddevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
- }
-
- if (render_state[LIGHTING_PASS] > 0) {
- SetBlendType(BLEND_ADDITIVE);
- SetRenderState(Z_WRITE_ENABLE, FALSE);
- }
-
- return true;
-}
-
-
-// +--------------------------------------------------------------------+
-
-void
-VideoDX9Error(const char* msg, HRESULT err)
-{
- Print(" VideoDX9: %s. [%s]\n", msg, D3DErrStr(err));
-}
-
-char* D3DErrStr(HRESULT hr)
-{
- static char errstrbuf[128];
-
- switch (hr) {
- default:
- sprintf_s(errstrbuf, "Unrecognized error value = %08x.", hr);
- return errstrbuf;
-
- case D3D_OK:
- return "No error.";
-
- case D3DERR_WRONGTEXTUREFORMAT:
- return "Wrong texture format.";
-
- case D3DERR_UNSUPPORTEDCOLOROPERATION:
- return "Unsupported color operation.";
-
- case D3DERR_UNSUPPORTEDCOLORARG:
- return "Unsupported color argument.";
-
- case D3DERR_UNSUPPORTEDALPHAOPERATION:
- return "Unsupported alpha operation.";
-
- case D3DERR_UNSUPPORTEDALPHAARG:
- return "Unsupported alpha argument.";
-
- case D3DERR_TOOMANYOPERATIONS:
- return "Too many operations.";
-
- case D3DERR_CONFLICTINGTEXTUREFILTER:
- return "Conflicting texture filter.";
-
- case D3DERR_UNSUPPORTEDFACTORVALUE:
- return "Unsupported factor value.";
-
- case D3DERR_CONFLICTINGRENDERSTATE:
- return "Conflicting render state.";
-
- case D3DERR_UNSUPPORTEDTEXTUREFILTER:
- return "Unsupported texture filter.";
-
- case D3DERR_CONFLICTINGTEXTUREPALETTE:
- return "Conflicting texture palette.";
-
- case D3DERR_DRIVERINTERNALERROR:
- return "Driver internal error.";
-
-
- case D3DERR_NOTFOUND:
- return "Resource was not found.";
-
- case D3DERR_MOREDATA:
- return "More data?";
-
- case D3DERR_DEVICELOST:
- return "Device lost.";
-
- case D3DERR_DEVICENOTRESET:
- return "Device is not reset.";
-
- case D3DERR_NOTAVAILABLE:
- return "Not available.";
-
- case D3DERR_OUTOFVIDEOMEMORY:
- return "Out of video memory.";
-
- case E_OUTOFMEMORY:
- return "Out of system memory.";
-
- case D3DERR_INVALIDDEVICE:
- return "Invalid device selection.";
-
- case D3DERR_INVALIDCALL:
- return "Invalid call or parameter.";
-
- case D3DERR_DRIVERINVALIDCALL:
- return "Driver invalid call.";
-
- case D3DERR_WASSTILLDRAWING:
- return "The device was still drawing.";
-
- case D3DOK_NOAUTOGEN:
- return "Autogeneration is not supported by this device.";
-
- }
-}
-
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: nGenEx.lib
+ FILE: VideoDX9.cpp
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Direct3D Video class for DirectX 9
+*/
+
+#include "MemDebug.h"
+#include "VideoDX9.h"
+#include "VideoDX9Enum.h"
+#include "VideoDX9VertexBuffer.h"
+#include "TexDX9.h"
+#include "TexCubeDX9.h"
+#include "Camera.h"
+#include "Color.h"
+#include "DataLoader.h"
+#include "Polygon.h"
+#include "Light.h"
+#include "Solid.h"
+
+// +--------------------------------------------------------------------+
+
+void Print(const char* msg, ...);
+char* D3DErrStr(HRESULT dderr);
+void VideoDX9Error(const char* msg, HRESULT dderr);
+static TexCacheDX9* texcache = 0;
+static TexCubeDX9* environment_cube = 0;
+static bool surface_has_tangent_data = false;
+static Light* main_light;
+static Light* back_light;
+static D3DXMATRIX matrixWorld;
+static D3DXMATRIX matrixView;
+static D3DXMATRIX matrixProj;
+static D3DXMATRIX matrixWorldInverse;
+
+extern int VD3D_describe_things;
+
+#ifndef RELEASE
+#define RELEASE(x) if (x) { x->Release(); x=NULL; }
+#endif
+
+#ifndef F2DW
+#define F2DW(x) (*(DWORD*)(&x))
+#endif
+
+#ifndef DW2I
+#define DW2I(x) (*(int*)(&x))
+#endif
+
+// +--------------------------------------------------------------------+
+
+typedef HRESULT (WINAPI * LPDDCE)(GUID FAR *, LPVOID *, REFIID , IUnknown FAR *);
+
+static D3DMATRIX identity_matrix = {
+ FLOAT(1.0), FLOAT(0.0), FLOAT(0.0), FLOAT(0.0),
+ FLOAT(0.0), FLOAT(1.0), FLOAT(0.0), FLOAT(0.0),
+ FLOAT(0.0), FLOAT(0.0), FLOAT(1.0), FLOAT(0.0),
+ FLOAT(0.0), FLOAT(0.0), FLOAT(0.0), FLOAT(1.0)
+};
+
+// +--------------------------------------------------------------------+
+
+List<Model> model_clients;
+
+class VideoDX9SurfaceData : public VideoPrivateData
+{
+public:
+ VideoDX9SurfaceData(Model* m) : model(m), vertex_buffer(0), index_buffer(0) {
+ if (!model_clients.contains(model))
+ model_clients.append(model);
+ }
+
+ virtual ~VideoDX9SurfaceData() {
+ model_clients.remove(model);
+
+ delete vertex_buffer;
+ delete index_buffer;
+ }
+
+ enum { TYPE = 9001 };
+ virtual int GetType() const { return TYPE; }
+
+ Model* model;
+ VideoDX9VertexBuffer* vertex_buffer;
+ VideoDX9IndexBuffer* index_buffer;
+};
+
+class VideoDX9SegmentData : public VideoPrivateData
+{
+public:
+ VideoDX9SegmentData() : first_vert(0), num_verts(0), first_index(0), num_tris(0) { }
+ virtual ~VideoDX9SegmentData() { }
+
+ enum { TYPE = 9002 };
+ virtual int GetType() const { return TYPE; }
+
+ int first_vert;
+ int num_verts;
+ int first_index;
+ int num_tris;
+};
+
+// +--------------------------------------------------------------------+
+
+static int d3dstate_table[] = {
+ D3DRS_FILLMODE, // FILL_MODE
+ D3DRS_SHADEMODE, // SHADE_MODE
+ D3DRS_LIGHTING, // LIGHTING_ENABLE
+ D3DRS_ZENABLE, // Z_ENABLE
+ D3DRS_ZWRITEENABLE, // Z_WRITE_ENABLE
+ D3DRS_DEPTHBIAS, // Z_BIAS
+ 0, // TEXTURE_FILTER
+ D3DRS_DITHERENABLE, // DITHER_ENABLE
+ D3DRS_SPECULARENABLE, // SPECULAR_ENABLE
+ D3DRS_FOGENABLE, // FOG_ENABLE
+ D3DRS_FOGCOLOR, // FOG_COLOR
+ D3DRS_FOGDENSITY, // FOG_DENSITY
+ D3DRS_STENCILENABLE, // STENCIL_ENABLE
+ 0x11111111, // TEXTURE_WRAP (special case)
+ 0 // LIGHTING_PASS
+};
+
+static const int NUM_SCREEN_VERTS = 1024;
+static const int NUM_SCREEN_INDICES = NUM_SCREEN_VERTS * 2;
+
+// +--------------------------------------------------------------------+
+
+struct VideoDX9ScreenVertex
+{
+ FLOAT sx, sy, sz, rhw;
+ DWORD diffuse;
+ FLOAT tu, tv;
+
+ static DWORD FVF;
+};
+
+DWORD VideoDX9ScreenVertex::FVF = D3DFVF_XYZRHW |
+D3DFVF_DIFFUSE |
+D3DFVF_TEX1;
+
+struct VideoDX9NormalVertex
+{
+ FLOAT x, y, z;
+ FLOAT nx, ny, nz;
+ FLOAT t0u, t0v;
+ FLOAT t1u, t1v;
+ FLOAT tx, ty, tz;
+ FLOAT bx, by, bz;
+
+ static DWORD FVF;
+};
+
+DWORD VideoDX9NormalVertex::FVF = 0;
+
+// Global Vertex Declaration shared by shaders
+D3DVERTEXELEMENT9 videoDX9NormalVertexElements[] =
+{
+ { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
+ { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
+ { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
+ { 0, 32, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 },
+ { 0, 40, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 2 },
+ { 0, 52, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 3 },
+ D3DDECL_END()
+};
+
+struct VideoDX9SolidVertex
+{
+ FLOAT x, y, z;
+ FLOAT nx, ny, nz;
+ FLOAT tu, tv;
+
+ static DWORD FVF;
+};
+
+DWORD VideoDX9SolidVertex::FVF = D3DFVF_XYZ |
+D3DFVF_NORMAL |
+D3DFVF_TEX1 |
+D3DFVF_TEXCOORDSIZE2(0);
+
+struct VideoDX9LuminousVertex
+{
+ FLOAT x, y, z;
+ DWORD diffuse;
+ FLOAT tu, tv;
+
+ static DWORD FVF;
+};
+
+DWORD VideoDX9LuminousVertex::FVF = D3DFVF_XYZ |
+D3DFVF_DIFFUSE |
+D3DFVF_TEX1 |
+D3DFVF_TEXCOORDSIZE2(0);
+
+struct VideoDX9DetailVertex
+{
+ FLOAT x, y, z;
+ DWORD diffuse;
+ DWORD specular;
+ FLOAT tu, tv;
+ FLOAT tu1, tv1;
+
+ static DWORD FVF;
+};
+
+DWORD VideoDX9DetailVertex::FVF = D3DFVF_XYZ |
+D3DFVF_DIFFUSE |
+D3DFVF_SPECULAR |
+D3DFVF_TEX2;
+
+struct VideoDX9LineVertex
+{
+ FLOAT x, y, z;
+ DWORD diffuse;
+
+ static DWORD FVF;
+};
+
+DWORD VideoDX9LineVertex::FVF = D3DFVF_XYZ |
+D3DFVF_DIFFUSE;
+
+enum {
+ DX9_STRATEGY_NONE,
+ DX9_STRATEGY_SIMPLE,
+ DX9_STRATEGY_GLOW,
+ DX9_STRATEGY_SPECMAP,
+ DX9_STRATEGY_EMISSIVE,
+ DX9_STRATEGY_SPEC_EMISSIVE,
+ DX9_STRATEGY_BLEND,
+ DX9_STRATEGY_BLEND_DETAIL
+};
+
+// +--------------------------------------------------------------------+
+
+static VideoDX9* video_dx9_instance = 0;
+
+VideoDX9::VideoDX9(const HWND& window, VideoSettings* vs)
+: width(0), height(0), bpp(0), hwnd(window), surface(0),
+d3d(0), d3ddevice(0), device_lost(false), fade(0),
+zdepth(0), gamma(128), num_verts(0), first_vert(0),
+current_texture(0), screen_vbuf(0), screen_ibuf(0),
+font_verts(0), font_indices(0), font_nverts(0),
+nlights(0), use_material(0), d3dx_font(0),
+segment_material(0), strategy(0), passes(0),
+screen_line_verts(0), line_verts(0),
+vertex_declaration(0),
+magic_fx(0), magic_fx_code(0), magic_fx_code_len(0)
+{
+ video_dx9_instance = this;
+
+ Print("\n********************************\n");
+ Print("* Direct 3D version 9 *\n");
+ Print("********************************\n\n");
+
+ status = VIDEO_ERR;
+ HRESULT err = E_OUTOFMEMORY;
+
+ d3d = Direct3DCreate9(D3D_SDK_VERSION);
+ dx9enum = new(__FILE__,__LINE__) VideoDX9Enum(d3d);
+
+ if (d3d && dx9enum) {
+ if (vs) {
+ dx9enum->req_fullscreen = vs->is_windowed ? false : true;
+ dx9enum->req_windowed = vs->is_windowed ? true : false;
+ dx9enum->min_stencil_bits = vs->shadows ? 8 : 0;
+ dx9enum->uses_depth_buffer = true;
+ }
+ else {
+ dx9enum->req_fullscreen = video_settings.is_windowed ? false : true;
+ dx9enum->req_windowed = video_settings.is_windowed ? true : false;
+ dx9enum->min_stencil_bits = video_settings.shadows ? 8 : 0;
+ dx9enum->uses_depth_buffer = true;
+ }
+
+ err = dx9enum->Enumerate();
+
+ if (FAILED(err)) {
+ VideoDX9Error("(ctor) could not enumerate dx9 properties", err);
+ delete dx9enum;
+ return;
+ }
+ }
+ else {
+ VideoDX9Error("(ctor) could not create enumerator", err);
+ return;
+ }
+
+ SetVideoSettings(vs);
+
+ if (video_settings.is_windowed)
+ dx9enum->SuggestWindowSettings(&video_settings);
+ else
+ dx9enum->SuggestFullscreenSettings(&video_settings);
+
+ SetupParams();
+
+ if (VD3D_describe_things > 2) {
+ Print("\nD3DPRESENT_PARAMETERS:\n");
+ Print(" BackBufferWidth: %d\n", d3dparams.BackBufferWidth);
+ Print(" BackBufferHeight: %d\n", d3dparams.BackBufferHeight);
+ Print(" BackBufferCount: %d\n", d3dparams.BackBufferCount);
+ Print(" BackBufferFormat: %s\n", VideoDX9DisplayMode::D3DFormatToString(d3dparams.BackBufferFormat));
+ Print(" Multisample Type: %d\n", d3dparams.MultiSampleType);
+ Print(" Multisample Qual: %d\n", d3dparams.MultiSampleQuality);
+ Print(" Swap Effect: %d\n", d3dparams.SwapEffect);
+ Print(" Device Window: %08X\n", d3dparams.hDeviceWindow);
+ Print(" Windowed: %s\n", d3dparams.Windowed ? "true" : "false");
+ Print(" Enable Depth/Stencil: %s\n", d3dparams.EnableAutoDepthStencil ? "true" : "false");
+ Print(" Depth/Stencil Format: %s\n", VideoDX9DisplayMode::D3DFormatToString(d3dparams.AutoDepthStencilFormat));
+ Print(" Flags: %08X\n", d3dparams.Flags);
+ Print(" Fullscreen Refresh: %d Hz\n", d3dparams.FullScreen_RefreshRateInHz);
+
+ switch (d3dparams.PresentationInterval) {
+ case D3DPRESENT_INTERVAL_IMMEDIATE:
+ Print(" Present Interval: IMMEDIATE\n");
+ break;
+
+ case D3DPRESENT_INTERVAL_DEFAULT:
+ Print(" Present Interval: DEFAULT\n");
+ break;
+
+ case D3DPRESENT_INTERVAL_ONE:
+ Print(" Present Interval: ONE\n");
+ break;
+
+ case D3DPRESENT_INTERVAL_TWO:
+ Print(" Present Interval: TWO\n");
+ break;
+
+ case D3DPRESENT_INTERVAL_THREE:
+ Print(" Present Interval: THREE\n");
+ break;
+
+ case D3DPRESENT_INTERVAL_FOUR:
+ Print(" Present Interval: FOUR\n");
+ break;
+
+ default:
+ Print(" Present Interval: Unknown (%d)\n", d3dparams.PresentationInterval);
+ break;
+ }
+
+ Print("\n");
+ }
+
+ Print(" Creating Video Device for HWND = %08x\n", window);
+
+ err = d3d->CreateDevice(D3DADAPTER_DEFAULT,
+ D3DDEVTYPE_HAL,
+ window,
+ D3DCREATE_HARDWARE_VERTEXPROCESSING,
+ &d3dparams,
+ &d3ddevice);
+
+ if (FAILED(err)) {
+ VideoDX9Error("(ctor) could not create device", err);
+ return;
+ }
+
+ width = video_settings.GetWidth();
+ height = video_settings.GetHeight();
+ bpp = video_settings.GetDepth();
+
+ shadow_enabled = vs->shadows;
+ bump_enabled = vs->bumpmaps;
+ spec_enabled = vs->specmaps;
+
+ render_state[FILL_MODE] = FILL_SOLID;
+ render_state[SHADE_MODE] = SHADE_GOURAUD;
+ render_state[Z_ENABLE] = false;
+ render_state[Z_WRITE_ENABLE] = false;
+ render_state[Z_BIAS] = 0;
+ render_state[TEXTURE_FILTER] = FILTER_LINEAR;
+ render_state[DITHER_ENABLE] = false;
+ render_state[SPECULAR_ENABLE] = true;
+ render_state[FOG_ENABLE] = false;
+ render_state[FOG_COLOR] = 0;
+ render_state[FOG_DENSITY] = 0;
+ render_state[STENCIL_ENABLE] = false;
+ render_state[TEXTURE_WRAP] = true;
+ render_state[LIGHTING_PASS] = 0;
+
+ ZeroMemory(&rect, sizeof(rect));
+
+ if (!texcache)
+ texcache = new(__FILE__,__LINE__) TexCacheDX9(this);
+
+ if (texcache)
+ texcache->count++;
+
+ if (VD3D_describe_things > 0) {
+ DWORD vmf = VidMemFree() / (1024 * 1024);
+ Print(" Available Texture Memory: %d MB\n\n", vmf);
+ }
+
+ if (CreateBuffers()) {
+ d3ddevice->SetRenderState(D3DRS_ALPHATESTENABLE, false);
+ d3ddevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
+
+ d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
+ d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
+ d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
+ d3ddevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
+ d3ddevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ d3ddevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
+
+ status = VIDEO_OK;
+ }
+
+ ZeroMemory(font_name, 64);
+ font_size = 0;
+ font_bold = false;
+ font_ital = false;
+}
+
+// +--------------------------------------------------------------------+
+
+VideoDX9::~VideoDX9()
+{
+ DestroyBuffers();
+
+ texcache->count--;
+ if (!texcache->count) {
+ delete texcache;
+ texcache = 0;
+ }
+
+ delete environment_cube;
+ delete dx9enum;
+
+ RELEASE(d3dx_font);
+ RELEASE(d3ddevice);
+ RELEASE(d3d);
+
+ if (magic_fx_code)
+ delete [] magic_fx_code;
+
+ Print(" VideoDX9: shutdown\n");
+ video_dx9_instance = 0;
+}
+
+IDirect3DDevice9*
+VideoDX9::GetD3DDevice9()
+{
+ if (video_dx9_instance)
+ return video_dx9_instance->d3ddevice;
+
+ return 0;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::SetupParams()
+{
+ if (!dx9enum || dx9enum->NumAdapters() < 1) {
+ status = VIDEO_ERR;
+ return false;
+ }
+
+ int adapter_index = video_settings.GetAdapterIndex();
+
+ if (adapter_index < 0 || adapter_index >= dx9enum->NumAdapters()) {
+ ::Print("WARNING: VideoDX9 could not select adapter %d (max=%d)\n",
+ adapter_index, dx9enum->NumAdapters());
+
+ adapter_index = 0;
+ }
+
+ dx9enum->SelectAdapter(adapter_index);
+
+ d3dparams.Windowed = video_settings.IsWindowed();
+ d3dparams.BackBufferCount = 2;
+ d3dparams.MultiSampleType = D3DMULTISAMPLE_NONE;
+ d3dparams.MultiSampleQuality = 0;
+ d3dparams.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ d3dparams.EnableAutoDepthStencil = dx9enum->uses_depth_buffer;
+ d3dparams.hDeviceWindow = hwnd;
+
+ if (dx9enum->uses_depth_buffer) {
+ d3dparams.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
+ d3dparams.AutoDepthStencilFormat = (D3DFORMAT) video_settings.GetDepthStencilFormat();
+ }
+ else {
+ d3dparams.Flags = 0;
+ }
+
+ d3dparams.Flags |= D3DPRESENTFLAG_DEVICECLIP;
+
+ if (video_settings.IsWindowed()) {
+ d3dparams.BackBufferWidth = video_settings.window_width;
+ d3dparams.BackBufferHeight = video_settings.window_height;
+ d3dparams.BackBufferFormat = (D3DFORMAT) video_settings.GetBackBufferFormat();
+ d3dparams.FullScreen_RefreshRateInHz = 0;
+ d3dparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
+ }
+ else {
+ d3dparams.BackBufferWidth = video_settings.GetWidth();
+ d3dparams.BackBufferHeight = video_settings.GetHeight();
+ d3dparams.BackBufferFormat = (D3DFORMAT) video_settings.GetBackBufferFormat();
+ d3dparams.FullScreen_RefreshRateInHz = video_settings.GetRefreshRate();
+ d3dparams.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
+ }
+
+ return true;
+}
+
+
+bool
+VideoDX9::IsModeSupported(int w, int h, int b) const
+{
+ if (dx9enum)
+ return dx9enum->IsModeSupported(w, h, b);
+
+ return false;
+}
+
+bool
+VideoDX9::SetVideoSettings(const VideoSettings* vs)
+{
+ // custom video settings:
+ if (vs) {
+ if (vs != &video_settings)
+ CopyMemory(&video_settings, vs, sizeof(VideoSettings));
+ }
+
+ // default video settings:
+ else {
+ ZeroMemory(&video_settings, sizeof(VideoSettings));
+
+ video_settings.fullscreen_mode.width = 800;
+ video_settings.fullscreen_mode.height = 600;
+ video_settings.fullscreen_mode.format = VideoMode::FMT_X8R8G8B8;
+ }
+
+ return true;
+}
+
+bool
+VideoDX9::Reset(const VideoSettings* vs)
+{
+ if (!d3ddevice || !SetVideoSettings(vs)) {
+ status = VIDEO_ERR;
+ return false;
+ }
+
+ bool using_x_font = (d3dx_font != 0);
+
+ RELEASE(d3dx_font);
+ InvalidateCache();
+ DestroyBuffers();
+ SetupParams();
+
+ HRESULT hr = d3ddevice->Reset(&d3dparams);
+
+ if (FAILED(hr)) {
+ VideoDX9Error("could not reset d3d device", hr);
+ status = VIDEO_ERR;
+ return false;
+ }
+
+ // Store render target surface desc
+ IDirect3DSurface9* back_buffer;
+ d3ddevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &back_buffer);
+ back_buffer->GetDesc(&back_buffer_desc);
+ RELEASE(back_buffer);
+
+ width = video_settings.GetWidth();
+ height = video_settings.GetHeight();
+ bpp = video_settings.GetDepth();
+
+ shadow_enabled = vs->shadows;
+ bump_enabled = vs->bumpmaps;
+ spec_enabled = vs->specmaps;
+
+
+ if (CreateBuffers()) {
+ d3ddevice->SetRenderState(D3DRS_ALPHATESTENABLE, false);
+ d3ddevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
+
+ d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
+ d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
+ d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
+ d3ddevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
+ d3ddevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ d3ddevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
+
+ D3DVIEWPORT9 view;
+
+ hr = d3ddevice->GetViewport(&view);
+ if (SUCCEEDED(hr)) {
+ rect.x = view.X;
+ rect.y = view.Y;
+ rect.w = view.Width;
+ rect.h = view.Height;
+ }
+
+ if (using_x_font)
+ UseXFont(font_name, font_size, font_bold, font_ital);
+
+ status = VIDEO_OK;
+ }
+
+ return status == VIDEO_OK;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::CreateBuffers()
+{
+ if (d3ddevice) {
+ UINT vertex_size = sizeof(VideoDX9ScreenVertex);
+ UINT index_size = sizeof(WORD);
+
+ if (!screen_vbuf) {
+ screen_vbuf = new(__FILE__,__LINE__) VideoDX9VertexBuffer(
+ this,
+ NUM_SCREEN_VERTS,
+ vertex_size,
+ VideoDX9ScreenVertex::FVF,
+ D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY);
+ }
+
+ if (!screen_ibuf) {
+ screen_ibuf = new(__FILE__,__LINE__) VideoDX9IndexBuffer(
+ this,
+ NUM_SCREEN_INDICES,
+ D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY);
+ }
+
+ screen_line_verts = new(__FILE__,__LINE__) VideoDX9ScreenVertex[256];
+ line_verts = new(__FILE__,__LINE__) VideoDX9LineVertex[512];
+
+ // create effects:
+ LPD3DXBUFFER code_buffer = 0;
+ DataLoader* loader = DataLoader::GetLoader();
+ HRESULT hr = E_FAIL;
+
+ hr = d3ddevice->CreateVertexDeclaration(videoDX9NormalVertexElements,
+ &vertex_declaration);
+
+ // The E - We want to load our shader from the standard filesystem by default, to allow for better modding.
+ if (video_settings.use_effects && !magic_fx_code) {
+ FILE* f;
+ ::fopen_s(&f, "magic.fx", "rb");
+
+ if (f) {
+ ::fseek(f, 0, SEEK_END);
+ magic_fx_code_len = ftell(f);
+ ::fseek(f, 0, SEEK_SET);
+
+ magic_fx_code = new(__FILE__,__LINE__) BYTE[magic_fx_code_len+1];
+ if (magic_fx_code) {
+ ::fread(magic_fx_code, magic_fx_code_len, 1, f);
+ magic_fx_code[magic_fx_code_len] = 0;
+ }
+ ::fclose(f);
+ } else if (loader) {
+ magic_fx_code_len = loader->LoadBuffer("magic.fx", magic_fx_code, true, true);
+ }
+ }
+
+ if (video_settings.use_effects && magic_fx_code && magic_fx_code_len) {
+ hr = D3DXCreateEffect(d3ddevice,
+ magic_fx_code,
+ magic_fx_code_len,
+ 0, 0, 0, 0,
+ &magic_fx,
+ &code_buffer);
+
+ if (code_buffer) {
+ ::Print("ERROR - Failed to compile 'magic.fx'\n");
+ ::Print((const char*) code_buffer->GetBufferPointer());
+ ::Print("\n\n");
+ RELEASE(code_buffer);
+ }
+ }
+ }
+
+ return screen_vbuf && screen_ibuf;
+}
+
+bool
+VideoDX9::DestroyBuffers()
+{
+ if (line_verts) {
+ delete line_verts;
+ line_verts = 0;
+ }
+
+ if (screen_line_verts) {
+ delete screen_line_verts;
+ screen_line_verts = 0;
+ }
+
+ if (screen_vbuf) {
+ delete screen_vbuf;
+ screen_vbuf = 0;
+ }
+
+ if (screen_ibuf) {
+ delete screen_ibuf;
+ screen_ibuf = 0;
+ }
+
+ if (font_verts) {
+ delete [] font_verts;
+ font_verts = 0;
+ }
+
+ if (font_indices) {
+ delete [] font_indices;
+ font_indices = 0;
+ }
+
+ font_nverts = 0;
+
+ RELEASE(vertex_declaration);
+ RELEASE(magic_fx);
+
+ return true;
+}
+
+// +--------------------------------------------------------------------+
+
+DWORD
+VideoDX9::VidMemFree() const
+{
+ UINT result = 0;
+
+ if (d3ddevice)
+ result = d3ddevice->GetAvailableTextureMem();
+
+ return result;
+}
+
+int
+VideoDX9::MaxTexSize() const
+{
+ if (d3d && dx9enum && dx9enum->GetAdapterInfo()) {
+ VideoDX9DeviceInfo* dev_info = dx9enum->GetDeviceInfo(video_settings.GetDeviceType());
+
+ if (dev_info) {
+ return (int) dev_info->caps.MaxTextureWidth;
+ }
+ }
+
+ return 0;
+}
+
+int
+VideoDX9::MaxTexAspect() const
+{
+ if (d3d && dx9enum && dx9enum->GetAdapterInfo()) {
+ VideoDX9DeviceInfo* dev_info = dx9enum->GetDeviceInfo(video_settings.GetDeviceType());
+
+ if (dev_info) {
+ return (int) dev_info->caps.MaxTextureAspectRatio;
+ }
+ }
+
+ return 0;
+}
+
+// +--------------------------------------------------------------------+
+
+void
+VideoDX9::RecoverSurfaces()
+{
+ Print("VideoDX9::RecoverSurfaces()\n");
+
+ HRESULT hr = D3D_OK;
+
+ surface = 0;
+
+ hr = d3ddevice->TestCooperativeLevel();
+
+ if (hr == D3DERR_DEVICELOST) {
+ // This means that some app took exclusive mode access
+ // we need to sit in a loop till we get back to the right mode.
+ Print("D3DERR_DEVICELOST\n");
+
+ do {
+ Sleep(500);
+ hr = d3ddevice->TestCooperativeLevel();
+ } while (hr == D3DERR_DEVICELOST);
+ }
+
+ if (hr == D3DERR_DEVICENOTRESET) {
+ if (Reset(&video_settings))
+ hr = S_OK;
+ }
+
+ if (SUCCEEDED(hr)) {
+ Print("* Invalidating Texture Cache\n");
+ // Re-fill the contents of textures which just got restored:
+ InvalidateCache();
+
+ device_lost = false;
+ }
+
+ Print("* Vid Mem Free: %8d\n", VidMemFree());
+ Print("* Recover Surfaces Complete.\n\n");
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::SetBackgroundColor(Color c)
+{
+ background = c;
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// RampValue
+//
+// The gamma function with inputs in [0,255], scaled to a range with the
+// default range appropriate for D3DGAMMARAMP.
+//
+inline WORD
+RampValue(UINT i, double recip_gamma, double fade)
+{
+ return (WORD) (65535.0 * fade * pow((double)i/255.f, recip_gamma));
+}
+
+//-----------------------------------------------------------------------------
+// ReciprocalGamma
+//
+// Given a gamma corrected i in [0,255], return 1/gamma
+//
+inline float
+ReciprocalGamma(UINT i)
+{
+ return logf(i/255.f)/logf(0.5f);
+}
+
+//-----------------------------------------------------------------------------
+// GammaValue
+//
+// Given a gamma corrected color channel value in [0,255], return the gamma.
+//
+inline float
+GammaValue(UINT i)
+{
+ return logf(0.5f)/logf(i/255.f);
+}
+
+bool
+VideoDX9::SetGammaLevel(int g)
+{
+ HRESULT hr = E_FAIL;
+ double f = Color::GetFade();
+
+ if (gamma != g || fade != f) {
+ if (d3ddevice) {
+ //::Print("VideoDX9 - SetGammaLevel(%d) fade = %f\n", g, f);
+
+ // compute 1/gamma
+ float recip_gray = ReciprocalGamma(g);
+
+ // compute i**(1/gamma) for all i and scale to range
+ for (UINT i = 0; i < 256; i++) {
+ int val = RampValue(i, recip_gray, f);
+
+ gamma_ramp.red[i] = val;
+ gamma_ramp.green[i] = val;
+ gamma_ramp.blue[i] = val;
+ }
+
+ d3ddevice->SetGammaRamp(0, D3DSGR_NO_CALIBRATION, &gamma_ramp);
+ hr = D3D_OK;
+ }
+
+ gamma = g;
+ fade = f;
+ }
+
+ return SUCCEEDED(hr);
+}
+
+bool
+VideoDX9::SetObjTransform(const Matrix& orient, const Point& loc)
+{
+ HRESULT hr = E_FAIL;
+
+ if (d3ddevice) {
+ D3DMATRIX world_matrix;
+ CreateD3DMatrix(world_matrix, orient, loc);
+ hr = d3ddevice->SetTransform(D3DTS_WORLD, &world_matrix);
+
+ matrixWorld = world_matrix;
+ D3DXMatrixInverse(&matrixWorldInverse, 0, &matrixWorld);
+ }
+
+ return SUCCEEDED(hr);
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::ClearAll()
+{
+ HRESULT err;
+
+ err = d3ddevice->Clear(0,
+ NULL,
+ D3DCLEAR_TARGET | D3DCLEAR_STENCIL | D3DCLEAR_ZBUFFER,
+ background.Value(),
+ 1.0f,
+ 0);
+
+ if (FAILED(err)) {
+ static int report = 10;
+ if (report > 0) {
+ VideoDX9Error("Failed to clear device", err);
+ report--;
+ }
+ }
+
+ return true;
+}
+
+bool
+VideoDX9::ClearDepthBuffer()
+{
+ HRESULT err;
+
+ err = d3ddevice->Clear(0,
+ NULL,
+ D3DCLEAR_STENCIL | D3DCLEAR_ZBUFFER,
+ 0,
+ 1.0f,
+ 0);
+
+ if (FAILED(err)) {
+ static int report = 10;
+ if (report > 0) {
+ VideoDX9Error("Failed to clear depth buffer", err);
+ report--;
+ }
+ }
+
+ return true;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::Present()
+{
+ // Show the frame on the primary surface.
+ HRESULT err = d3ddevice->Present( NULL, NULL, NULL, NULL );
+
+ if (FAILED(err)) {
+ if (err == D3DERR_DEVICELOST) {
+ device_lost = true;
+ }
+
+ else {
+ static int report = 10;
+ if (report > 0) {
+ VideoDX9Error("Could not present frame", err);
+ report--;
+ }
+ }
+ }
+
+ return true;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::Pause()
+{
+ return true;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::Resume()
+{
+ return true;
+}
+
+// +--------------------------------------------------------------------+
+
+void
+VideoDX9::PreloadSurface(Surface* s)
+{
+ if (s)
+ PrepareSurface(s);
+}
+
+void
+VideoDX9::PreloadTexture(Bitmap* tex)
+{
+ if (texcache && tex)
+ texcache->FindTexture(tex);
+}
+
+void
+VideoDX9::InvalidateCache()
+{
+ ListIter<Model> iter = model_clients;
+ while (++iter) {
+ // remove each model from the list...
+ Model* model = iter.removeItem();
+
+ // ...so that the buffer destructor doesn't
+ // do it and mess up the iterator.
+ model->DeletePrivateData();
+ }
+
+ if (texcache)
+ texcache->InvalidateCache();
+}
+
+// +--------------------------------------------------------------------+
+
+void
+VideoDX9::CreateD3DMatrix(D3DMATRIX& result, const Matrix& m, const Point& p)
+{
+ result._11 = (float) m.elem[0][0];
+ result._12 = (float) m.elem[1][0];
+ result._13 = (float) m.elem[2][0];
+ result._14 = 0.0f;
+
+ result._21 = (float) m.elem[0][1];
+ result._22 = (float) m.elem[1][1];
+ result._23 = (float) m.elem[2][1];
+ result._24 = 0.0f;
+
+ result._31 = (float) m.elem[0][2];
+ result._32 = (float) m.elem[1][2];
+ result._33 = (float) m.elem[2][2];
+ result._34 = 0.0f;
+
+ result._41 = (float) p.x;
+ result._42 = (float) p.y;
+ result._43 = (float) p.z;
+ result._44 = 1.0f;
+}
+
+void
+VideoDX9::CreateD3DMatrix(D3DMATRIX& result, const Matrix& m, const Vec3& v)
+{
+ result._11 = (float) m.elem[0][0];
+ result._12 = (float) m.elem[1][0];
+ result._13 = (float) m.elem[2][0];
+ result._14 = 0.0f;
+
+ result._21 = (float) m.elem[0][1];
+ result._22 = (float) m.elem[1][1];
+ result._23 = (float) m.elem[2][1];
+ result._24 = 0.0f;
+
+ result._31 = (float) m.elem[0][2];
+ result._32 = (float) m.elem[1][2];
+ result._33 = (float) m.elem[2][2];
+ result._34 = 0.0f;
+
+ result._41 = v.x;
+ result._42 = v.y;
+ result._43 = v.z;
+ result._44 = 1.0f;
+}
+
+void
+VideoDX9::CreateD3DMaterial(D3DMATERIAL9& result, const Material& mtl)
+{
+ CopyMemory(&result.Diffuse, &mtl.Kd, sizeof(D3DCOLORVALUE));
+ CopyMemory(&result.Ambient, &mtl.Ka, sizeof(D3DCOLORVALUE));
+ CopyMemory(&result.Specular, &mtl.Ks, sizeof(D3DCOLORVALUE));
+ CopyMemory(&result.Emissive, &mtl.Ke, sizeof(D3DCOLORVALUE));
+
+ result.Power = mtl.power;
+}
+
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::Capture(Bitmap& bmp)
+{
+ if (d3ddevice) {
+ HRESULT hr = E_FAIL;
+ LPDIRECT3DSURFACE9 pSurf=NULL, pTempSurf=NULL;
+ D3DSURFACE_DESC desc;
+ D3DDISPLAYMODE dm;
+
+ // get display dimensions
+ // this will be the dimensions of the front buffer
+ hr = d3ddevice->GetDisplayMode(0, &dm);
+
+ if (FAILED(hr))
+ VideoDX9Error("VideoDX9::Capture - Can't get display mode!", hr);
+
+ desc.Width = dm.Width;
+ desc.Height = dm.Height;
+ desc.Format = D3DFMT_A8R8G8B8;
+
+ hr = d3ddevice->CreateOffscreenPlainSurface(
+ desc.Width,
+ desc.Height,
+ desc.Format,
+ D3DPOOL_SYSTEMMEM,
+ &pTempSurf,
+ NULL);
+
+ if (FAILED(hr)) {
+ VideoDX9Error("VideoDX9::Capture - Cannot create offscreen buffer 1", hr);
+ return false;
+ }
+
+ hr = d3ddevice->GetFrontBufferData(0, pTempSurf);
+
+ if (FAILED(hr)) {
+ RELEASE(pTempSurf);
+ VideoDX9Error("VideoDX9::Capture - Can't get front buffer", hr);
+ return false;
+ }
+
+
+ if (video_settings.IsWindowed()) {
+ POINT pt={0, 0};
+ RECT srcRect;
+
+ // capture only the client area of the screen:
+ ::GetClientRect(hwnd, &srcRect);
+ ::ClientToScreen(hwnd, (LPPOINT) &srcRect);
+ srcRect.right += srcRect.left;
+ srcRect.bottom += srcRect.top;
+
+ desc.Width = srcRect.right - srcRect.left;
+ desc.Height = srcRect.bottom - srcRect.top;
+ desc.Format = D3DFMT_A8R8G8B8; // this is what we get from the screen, so stick with it
+
+ // NB we can't lock the back buffer direct because it's no created that way
+ // and to do so hits performance, so copy to another surface
+ // Must be the same format as the source surface
+ hr = d3ddevice->CreateOffscreenPlainSurface(
+ desc.Width,
+ desc.Height,
+ desc.Format,
+ D3DPOOL_DEFAULT,
+ &pSurf,
+ NULL);
+
+ if (FAILED(hr)) {
+ RELEASE(pSurf);
+ VideoDX9Error("VideoDX9::Capture - Cannot create offscreen buffer 2", hr);
+ return false;
+ }
+
+ // Copy
+ hr = d3ddevice->UpdateSurface(pTempSurf, &srcRect, pSurf, &pt);
+
+ if (FAILED(hr)) {
+ RELEASE(pTempSurf);
+ RELEASE(pSurf);
+ VideoDX9Error("VideoDX9::Capture - Cannot update surface", hr);
+ return false;
+ }
+
+ RELEASE(pTempSurf);
+ pTempSurf = pSurf;
+ pSurf = NULL;
+ }
+
+ D3DLOCKED_RECT lockedRect;
+ hr = pTempSurf->LockRect(&lockedRect, NULL,
+ D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK);
+
+ if (FAILED(hr)) {
+ VideoDX9Error("VideoDX9::Capture - can't lock rect", hr);
+ RELEASE(pTempSurf);
+ return false;
+ }
+
+ // Allocate color buffer
+ DWORD* buffer = new DWORD[desc.Width * desc.Height];
+ BYTE* src = (BYTE*) lockedRect.pBits;
+ BYTE* dst = (BYTE*) buffer;
+ Color clr;
+
+ for (DWORD y = 0; y < desc.Height; y++) {
+ BYTE *pRow = src;
+
+ for (DWORD x = 0; x < desc.Width; x++) {
+ switch(desc.Format) {
+ case D3DFMT_R5G6B5:
+ clr = Color::Unformat(*((WORD*) (pRow)));
+
+ *dst++ = (BYTE) clr.Red();
+ *dst++ = (BYTE) clr.Green();
+ *dst++ = (BYTE) clr.Blue();
+ *dst++ = 255;
+ break;
+
+ case D3DFMT_A8R8G8B8:
+ case D3DFMT_X8R8G8B8:
+ *dst++ = pRow[0]; // R
+ *dst++ = pRow[1]; // G
+ *dst++ = pRow[2]; // B
+ *dst++ = 255;
+
+ pRow += 4;
+ break;
+
+ case D3DFMT_R8G8B8:
+ *dst++ = pRow[0]; // R
+ *dst++ = pRow[1]; // G
+ *dst++ = pRow[2]; // B
+ *dst++ = 255;
+
+ pRow += 3;
+ break;
+ }
+
+ }
+
+ src += lockedRect.Pitch;
+ }
+
+ bmp.CopyHighColorImage(desc.Width, desc.Height, buffer);
+
+ delete [] buffer;
+
+ RELEASE(pTempSurf);
+ RELEASE(pSurf);
+
+ return SUCCEEDED(hr);
+ }
+
+ return false;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::GetWindowRect(Rect& r)
+{
+ if (d3ddevice && (rect.w < 1 || rect.h < 1)) {
+ D3DVIEWPORT9 view;
+ HRESULT hr = d3ddevice->GetViewport(&view);
+ if (SUCCEEDED(hr)) {
+ rect.x = view.X;
+ rect.y = view.Y;
+ rect.w = view.Width;
+ rect.h = view.Height;
+ }
+ }
+
+ r = rect;
+ return true;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::SetWindowRect(const Rect& r)
+{
+ return SetViewport(r.x, r.y, r.w, r.h);
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::SetViewport(int x, int y, int w, int h)
+{
+ if (!d3d || !d3ddevice)
+ return false;
+
+ HRESULT hr;
+
+ // set up the viewport according to args:
+ D3DVIEWPORT9 view;
+
+ view.X = x;
+ view.Y = y;
+ view.Width = w;
+ view.Height = h;
+ view.MinZ = 0.0f;
+ view.MaxZ = 1.0f;
+
+ hr = d3ddevice->SetViewport(&view);
+ if (FAILED(hr)) {
+ VideoDX9Error("could not initialize viewport", hr);
+ return false;
+ }
+
+ // set up the render state:
+ for (int i = FILL_MODE; i < TEXTURE_WRAP; i++) {
+ if (d3dstate_table[i]) {
+ d3ddevice->SetRenderState((D3DRENDERSTATETYPE) d3dstate_table[i], render_state[i]);
+ }
+ }
+
+ d3ddevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
+
+ rect.x = x;
+ rect.y = y;
+ rect.w = w;
+ rect.h = h;
+
+ return true;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::SetAmbient(Color c)
+{
+ ambient = c;
+ return true;
+}
+
+bool
+VideoDX9::SetLights(const List<Light>& lights)
+{
+ if (d3ddevice) {
+ main_light = 0;
+ back_light = 0;
+
+ ListIter<Light> iter = (List<Light>&) lights;
+ int index = -1;
+
+ while (++iter) {
+ Light* light = iter.value();
+
+ if (light->IsActive()) {
+ D3DLIGHT9 d3d_light;
+ ZeroMemory(&d3d_light, sizeof(d3d_light));
+ d3d_light.Type = (D3DLIGHTTYPE) light->Type();
+
+ if (light->Type() == Light::LIGHT_DIRECTIONAL) {
+ d3d_light.Direction.x = (float) (-light->Location().x);
+ d3d_light.Direction.y = (float) (-light->Location().y);
+ d3d_light.Direction.z = (float) (-light->Location().z);
+
+ if (d3d_light.Direction.x == 0 &&
+ d3d_light.Direction.y == 0 &&
+ d3d_light.Direction.z == 0) {
+
+ d3d_light.Direction.y = -1;
+ }
+
+ if (light->CastsShadow()) {
+ if (!main_light || light->Intensity() > main_light->Intensity())
+ main_light = light;
+ }
+ else if (!back_light) {
+ back_light = light;
+ }
+ }
+ else {
+ d3d_light.Position.x = (float) ( light->Location().x);
+ d3d_light.Position.y = (float) ( light->Location().y);
+ d3d_light.Position.z = (float) ( light->Location().z);
+ }
+
+ float r = (light->GetColor().Red() / 255.0f) * light->Intensity();
+ float g = (light->GetColor().Green() / 255.0f) * light->Intensity();
+ float b = (light->GetColor().Blue() / 255.0f) * light->Intensity();
+
+ d3d_light.Diffuse.r = r;
+ d3d_light.Diffuse.g = g;
+ d3d_light.Diffuse.b = b;
+
+ d3d_light.Specular.r = r;
+ d3d_light.Specular.g = g;
+ d3d_light.Specular.b = b;
+
+ d3d_light.Range = light->Intensity() * 10.0f;
+ d3d_light.Attenuation0 = 0.1f;
+ d3d_light.Attenuation1 = 0.7f;
+ d3d_light.Attenuation2 = 0.0f;
+
+ index++;
+ d3ddevice->SetLight(index, &d3d_light);
+ d3ddevice->LightEnable(index, TRUE);
+ }
+ }
+
+ // turn off any unused lights from before:
+ while (nlights > index+1) {
+ d3ddevice->LightEnable(--nlights, FALSE);
+ }
+
+ nlights = index + 1;
+
+ return true;
+ }
+
+ return false;
+}
+
+bool
+VideoDX9::SetCamera(const Camera* cam)
+{
+ if (d3ddevice) {
+ camera = cam;
+
+ D3DMATRIX m;
+ CreateD3DMatrix(m, cam->Orientation(), cam->Pos());
+ d3ddevice->SetTransform(D3DTS_VIEW, &m);
+ matrixView = m;
+
+ return true;
+ }
+
+ return false;
+}
+
+bool
+VideoDX9::SetProjection(float fov, float znear, float zfar, DWORD type)
+{
+ if (d3ddevice && zfar > znear) {
+ D3DMATRIX m;
+ float h, w, Q;
+
+ double width = (float) (rect.w);
+ double height = (float) (rect.h);
+ ZeroMemory(&m, sizeof(m));
+
+ /***
+ *** PERSPECTIVE PROJECTION:
+ ***/
+
+ if (type == PROJECTION_PERSPECTIVE) {
+ double xscale = width / fov;
+ double yscale = height / fov;
+
+ double maxscale = xscale;
+ if (yscale > xscale) maxscale = yscale;
+
+ double xangle = atan(fov/2 * maxscale/xscale);
+
+ w = (float) (2/tan(xangle)); // 1/tan(x) == cot(x)
+ h = (float) (w * width/height);
+ Q = zfar/(zfar - znear);
+
+ m._11 = w;
+ m._22 = h;
+ m._33 = Q;
+ m._43 = -Q*znear;
+ m._34 = 1;
+ }
+
+ /***
+ *** ORTHOGONAL PROJECTION:
+ ***/
+
+ else if (type == PROJECTION_ORTHOGONAL) {
+ m._11 = (float) (fov/width);
+ m._22 = (float) (fov/height);
+ m._33 = (float) (1/(zfar-znear));
+ m._43 = (float) (znear/(znear-zfar));
+ m._44 = (float) (1);
+ }
+
+ else {
+ return false;
+ }
+
+ d3ddevice->SetTransform(D3DTS_PROJECTION, &m);
+ matrixProj = m;
+
+ return true;
+ }
+
+ return false;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::SetEnvironment(Bitmap** faces)
+{
+ if (environment_cube && !faces) {
+ delete environment_cube;
+ environment_cube = 0;
+ return true;
+ }
+
+ if (!environment_cube) {
+ environment_cube = new(__FILE__,__LINE__) TexCubeDX9(this);
+ }
+
+ if (environment_cube) {
+ bool ok = true;
+ for (int i = 0; i < 6; i++)
+ ok = ok && environment_cube->LoadTexture(faces[i], i);
+ return ok;
+ }
+
+ return false;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::SetRenderState(RENDER_STATE state, DWORD value)
+{
+ if (!d3ddevice)
+ return false;
+
+ if (render_state[state] == value || d3dstate_table[state] == 0) {
+ render_state[state] = value;
+ return true;
+ }
+
+ HRESULT hr = E_FAIL;
+
+ // special case for texture wrapping:
+ if (state == TEXTURE_WRAP) {
+ DWORD wrap = D3DTADDRESS_CLAMP;
+
+ if (value)
+ wrap = D3DTADDRESS_WRAP;
+
+ hr = d3ddevice->SetSamplerState(0, D3DSAMP_ADDRESSU, wrap);
+ hr = d3ddevice->SetSamplerState(0, D3DSAMP_ADDRESSV, wrap);
+ }
+
+ // special case for fog enable:
+ else if (state == FOG_ENABLE) {
+ if (value) {
+ hr = d3ddevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_EXP);
+ hr = d3ddevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_NONE);
+ }
+
+ hr = d3ddevice->SetRenderState(D3DRS_FOGENABLE, value);
+ }
+
+ // special case for z bias
+ else if (state == Z_BIAS) {
+ if (value) {
+ FLOAT bias_scale = 1.0f;
+ FLOAT depth_bias = (FLOAT) (DW2I(value) / -10000.0);
+
+ hr = d3ddevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, F2DW(bias_scale));
+ hr = d3ddevice->SetRenderState(D3DRS_DEPTHBIAS, F2DW(depth_bias));
+ }
+ else {
+ hr = d3ddevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0);
+ hr = d3ddevice->SetRenderState(D3DRS_DEPTHBIAS, 0);
+ }
+ }
+
+ // set default z func along with z enable
+ else if (state == Z_ENABLE) {
+ hr = d3ddevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
+ hr = d3ddevice->SetRenderState(D3DRS_ZENABLE, value);
+ }
+
+ // all other render states:
+ else {
+ hr = d3ddevice->SetRenderState((D3DRENDERSTATETYPE) d3dstate_table[state], value);
+ }
+
+ if (FAILED(hr)) {
+ VideoDX9Error("could not SetRenderState", hr);
+ return false;
+ }
+ else {
+ render_state[state] = value;
+ }
+
+ return true;
+}
+
+bool
+VideoDX9::SetBlendType(int blend_type)
+{
+ if (blend_type == current_blend_state)
+ return true;
+
+ switch (blend_type) {
+ default:
+ // map misc blend types to SOLID
+ // and fall through to that case
+
+ blend_type = BLEND_SOLID;
+
+ case BLEND_SOLID:
+ d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
+ break;
+
+ case BLEND_ALPHA:
+ d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
+ d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ d3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+ break;
+
+ case BLEND_ADDITIVE:
+ d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
+ d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
+ d3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
+ break;
+ }
+
+ current_blend_state = blend_type;
+ return true;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::StartFrame()
+{
+ if (device_lost) {
+ RecoverSurfaces();
+
+ if (status != VIDEO_OK)
+ return false;
+ }
+
+ stats.Clear();
+
+ HRESULT err = 0;
+ static int frame_number = 1;
+ static int report_errs = 100;
+
+ stats.nframe = frame_number;
+ texcache->FrameNumber(frame_number++);
+
+ // update gamma ramp for global fade value:
+ SetGammaLevel(gamma);
+
+ ClearAll();
+
+ err = d3ddevice->BeginScene();
+
+ if (FAILED(err)) {
+ if (report_errs > 0) {
+ report_errs--;
+ VideoDX9Error("could not begin scene", err);
+ }
+
+ return false;
+ }
+
+ scene_active = 1;
+ current_blend_state = -1;
+
+ SetRenderState(LIGHTING_PASS, 0);
+ SetRenderState(STENCIL_ENABLE, false);
+
+ return true;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::EndFrame()
+{
+ HRESULT err = 0;
+
+ if (scene_active) {
+ err = d3ddevice->EndScene();
+
+ if (FAILED(err)) {
+ VideoDX9Error("could not end scene", err);
+ return false;
+ }
+ }
+
+ scene_active = 0;
+ return true;
+}
+
+// +--------------------------------------------------------------------+
+
+static DWORD ColorModulate(DWORD a, DWORD b)
+{
+ float a0 = (float) ((a ) & 0xff)/255.0f;
+ float a1 = (float) ((a>> 8) & 0xff)/255.0f;
+ float a2 = (float) ((a>>16) & 0xff)/255.0f;
+ float a3 = (float) ((a>>24) & 0xff)/255.0f;
+
+ float b0 = (float) ((b ) & 0xff)/255.0f;
+ float b1 = (float) ((b>> 8) & 0xff)/255.0f;
+ float b2 = (float) ((b>>16) & 0xff)/255.0f;
+ float b3 = (float) ((b>>24) & 0xff)/255.0f;
+
+ return (DWORD) ((BYTE)(a3*b3*255.0f) << 24) |
+ ((BYTE)(a2*b2*255.0f) << 16) |
+ ((BYTE)(a1*b1*255.0f) << 8) |
+ ((BYTE)(a0*b0*255.0f));
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::PopulateScreenVerts(VertexSet* vset)
+{
+ if (!vset || !screen_vbuf)
+ return false;
+
+ num_verts = vset->nverts;
+
+ VideoDX9ScreenVertex* v = (VideoDX9ScreenVertex*) screen_vbuf->Lock(num_verts);
+
+ if (v) {
+ first_vert = screen_vbuf->GetNextVert();
+
+ for (int i = 0; i < num_verts; i++) {
+ v->sx = vset->s_loc[i].x;
+ v->sy = vset->s_loc[i].y;
+ v->sz = vset->s_loc[i].z;
+ v->rhw = vset->rw[i];
+
+ v->diffuse = vset->diffuse[i];
+
+ v->tu = vset->tu[i];
+ v->tv = vset->tv[i];
+
+ v++;
+ }
+
+ screen_vbuf->Unlock();
+ return true;
+ }
+
+ Print(" VideoDX9: could not lock screen vbuf for %d verts.\n", num_verts);
+ return false;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::DrawPolys(int npolys, Poly* polys)
+{
+ bool result = false;
+
+ if (d3ddevice && polys && npolys > 0) {
+ // screen space polys:
+ if (polys->vertex_set->space == VertexSet::SCREEN_SPACE)
+ return DrawScreenPolys(npolys, polys);
+
+ // world space polys:
+ stats.ncalls++;
+
+ VertexSet* vset = polys->vertex_set;
+ int nverts = vset->nverts;
+ bool luminous = false;
+ bool detail = false;
+ DWORD fvf = 0;
+ void* verts = 0;
+ int vsize = 0;
+ WORD* indices = new(__FILE__,__LINE__) WORD[npolys*6];
+
+ if (polys->material) {
+ luminous = polys->material->luminous;
+ }
+
+ if (vset->tu1 != 0) {
+ VideoDX9DetailVertex* v = new(__FILE__,__LINE__) VideoDX9DetailVertex[nverts];
+ verts = v;
+ vsize = sizeof(VideoDX9DetailVertex);
+ fvf = VideoDX9DetailVertex::FVF;
+
+ for (int i = 0; i < nverts; i++) {
+ v->x = vset->loc[i].x;
+ v->y = vset->loc[i].y;
+ v->z = vset->loc[i].z;
+
+ v->diffuse = vset->diffuse[i];
+ v->specular = vset->specular[i];
+
+ v->tu = vset->tu[i];
+ v->tv = vset->tv[i];
+ v->tu1 = vset->tu1[i];
+ v->tv1 = vset->tv1[i];
+
+ v++;
+ }
+ }
+
+ else if (luminous) {
+ VideoDX9LuminousVertex* v = new(__FILE__,__LINE__) VideoDX9LuminousVertex[nverts];
+ verts = v;
+ vsize = sizeof(VideoDX9LuminousVertex);
+ fvf = VideoDX9LuminousVertex::FVF;
+
+ for (int i = 0; i < nverts; i++) {
+ v->x = vset->loc[i].x;
+ v->y = vset->loc[i].y;
+ v->z = vset->loc[i].z;
+
+ v->diffuse = vset->diffuse[i];
+
+ v->tu = vset->tu[i];
+ v->tv = vset->tv[i];
+
+ v++;
+ }
+ }
+
+ else {
+ VideoDX9SolidVertex* v = new(__FILE__,__LINE__) VideoDX9SolidVertex[nverts];
+ verts = v;
+ vsize = sizeof(VideoDX9SolidVertex);
+ fvf = VideoDX9SolidVertex::FVF;
+
+ for (int i = 0; i < nverts; i++) {
+ v->x = vset->loc[i].x;
+ v->y = vset->loc[i].y;
+ v->z = vset->loc[i].z;
+
+ v->nx = vset->nrm[i].x;
+ v->ny = vset->nrm[i].y;
+ v->nz = vset->nrm[i].z;
+
+ v->tu = vset->tu[i];
+ v->tv = vset->tv[i];
+
+ v++;
+ }
+ }
+
+ if (verts && indices) {
+ HRESULT hr = E_FAIL;
+
+ // fill index array
+ int num_indices = 0;
+ int num_tris = 0;
+
+ WORD* s = indices;
+ Poly* p = polys;
+
+ for (int i = 0; i < npolys; i++) {
+ if (p->nverts == 3) {
+ num_indices += 3;
+ num_tris += 1;
+
+ *s++ = p->verts[0];
+ *s++ = p->verts[1];
+ *s++ = p->verts[2];
+ }
+
+ else if (p->nverts == 4) {
+ num_indices += 6;
+ num_tris += 2;
+
+ *s++ = p->verts[0];
+ *s++ = p->verts[1];
+ *s++ = p->verts[2];
+
+ *s++ = p->verts[0];
+ *s++ = p->verts[2];
+ *s++ = p->verts[3];
+ }
+
+ p++;
+ }
+
+ hr = d3ddevice->SetTransform(D3DTS_WORLD, &identity_matrix);
+ hr = d3ddevice->SetVertexShader(NULL);
+ hr = d3ddevice->SetFVF(fvf);
+
+ // send primitives to the device
+ Material* mtl = polys->material;
+ IDirect3DTexture9* texture = 0;
+
+ if (mtl && texcache && mtl->tex_diffuse) {
+ texture = texcache->FindTexture(mtl->tex_diffuse);
+ }
+
+ if (current_texture != texture) {
+ hr = d3ddevice->SetTexture(0, texture);
+ current_texture = texture;
+ }
+
+ if (mtl && texcache && mtl->tex_detail) {
+ texture = texcache->FindTexture(mtl->tex_detail);
+ hr = d3ddevice->SetTexture(1, texture);
+ }
+
+ if (mtl && !luminous) {
+ D3DMATERIAL9 d3dmtl;
+ CreateD3DMaterial(d3dmtl, *mtl);
+
+ hr = d3ddevice->SetMaterial(&d3dmtl);
+ hr = d3ddevice->SetRenderState(D3DRS_AMBIENT, ambient.Value());
+ }
+
+ // set render states and select buffers
+ SetRenderState(FILL_MODE, D3DFILL_SOLID);
+ SetRenderState(LIGHTING_ENABLE, luminous ? FALSE : TRUE);
+ SetBlendType(mtl->blend);
+
+ d3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
+ d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
+ d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
+ d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
+ d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
+
+ d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
+
+
+ hr = d3ddevice->DrawIndexedPrimitiveUP(
+ D3DPT_TRIANGLELIST,
+ 0,
+ nverts,
+ num_tris,
+ indices,
+ D3DFMT_INDEX16,
+ verts,
+ vsize);
+
+ if (FAILED(hr)) {
+ static int report = 10;
+ if (report-- > 0)
+ VideoDX9Error("Could not draw 3D polys.", hr);
+ }
+
+ delete [] verts;
+ delete [] indices;
+
+ if (SUCCEEDED(hr)) {
+ stats.nverts += nverts;
+ stats.npolys += num_tris;
+ result = true;
+ }
+ }
+ }
+
+ return result;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::DrawScreenPolys(int npolys, Poly* polys, int blend)
+{
+ bool result = false;
+ HRESULT hr = E_FAIL;
+
+ if (d3ddevice && polys && npolys > 0 && screen_vbuf && screen_ibuf) {
+ stats.ncalls++;
+
+ // fill screen vertex buffer
+ if (!PopulateScreenVerts(polys->vertex_set))
+ return false;
+
+ // fill screen index buffer
+ int num_indices = 0;
+ int num_tris = 0;
+
+ // count the number of indices needed for these polys
+ for (int i = 0; i < npolys; i++) {
+ Poly* p = polys + i;
+
+ if (p->nverts == 3) {
+ num_indices += 3;
+ num_tris += 1;
+ }
+
+ else if (p->nverts == 4) {
+ num_indices += 6;
+ num_tris += 2;
+ }
+ }
+
+ WORD* screen_indices = screen_ibuf->Lock(num_indices);
+ int first_index = screen_ibuf->GetNextIndex();
+
+ if (!screen_indices) {
+ Print(" VideoDX9: could not lock screen ibuf for %d indices.\n", num_indices);
+ return false;
+ }
+
+ // copy the indices into the locked index buffer
+ WORD* s = screen_indices;
+ Poly* p = polys;
+
+ for (int i = 0; i < npolys; i++) {
+ if (p->nverts == 3) {
+ *s++ = p->verts[0] + first_vert;
+ *s++ = p->verts[1] + first_vert;
+ *s++ = p->verts[2] + first_vert;
+ }
+ else if (p->nverts == 4) {
+ *s++ = p->verts[0] + first_vert;
+ *s++ = p->verts[1] + first_vert;
+ *s++ = p->verts[2] + first_vert;
+
+ *s++ = p->verts[0] + first_vert;
+ *s++ = p->verts[2] + first_vert;
+ *s++ = p->verts[3] + first_vert;
+ }
+
+ p++;
+ }
+
+ screen_ibuf->Unlock();
+
+ // set render states and select buffers
+ SetRenderState(FILL_MODE, D3DFILL_SOLID);
+ SetRenderState(Z_ENABLE, D3DZB_FALSE);
+ SetRenderState(Z_WRITE_ENABLE, D3DZB_FALSE);
+ SetRenderState(LIGHTING_ENABLE, FALSE);
+ SetBlendType(blend);
+
+ d3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
+ d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
+ d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
+ d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
+ d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
+
+ d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
+
+ // send primitives to the device
+ Material* mtl = polys->material;
+ IDirect3DTexture9* texture = 0;
+
+ if (mtl && texcache && mtl->tex_diffuse) {
+ texture = texcache->FindTexture(mtl->tex_diffuse);
+ }
+
+ if (current_texture != texture) {
+ hr = d3ddevice->SetTexture(0, texture);
+ current_texture = texture;
+ }
+
+ screen_vbuf->Select(0);
+ screen_ibuf->Select();
+ hr = d3ddevice->SetVertexShader(NULL);
+ hr = d3ddevice->SetFVF(VideoDX9ScreenVertex::FVF);
+
+ hr = d3ddevice->DrawIndexedPrimitive(
+ D3DPT_TRIANGLELIST,
+ 0,
+ first_vert,
+ num_verts,
+ first_index,
+ num_tris);
+
+ if (FAILED(hr)) {
+ static int report = 10;
+ if (report-- > 0)
+ VideoDX9Error("Could not draw screen polys.", hr);
+ }
+ else {
+ stats.nverts += num_verts;
+ stats.npolys += num_tris;
+ result = true;
+ }
+ }
+
+ return result;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::DrawSolid(Solid* s, DWORD blend_modes)
+{
+ bool result = false;
+ HRESULT hr = E_FAIL;
+
+ if (d3ddevice && s && s->GetModel()) {
+ Model* model = s->GetModel();
+ Matrix orient = s->Orientation();
+ orient.Transpose();
+
+ D3DMATRIX world_matrix;
+ CreateD3DMatrix(world_matrix, orient, s->Location());
+ d3ddevice->SetTransform(D3DTS_WORLD, &world_matrix);
+ matrixWorld = world_matrix;
+ D3DXMatrixInverse(&matrixWorldInverse, 0, &matrixWorld);
+
+ ListIter<Surface> surf_iter = model->GetSurfaces();
+ while (++surf_iter) {
+ Surface* surf = surf_iter.value();
+
+ if (surf->IsHidden() || surf->IsSimplified())
+ continue;
+
+ if (PrepareSurface(surf)) {
+ result = true;
+
+ VideoDX9SurfaceData* surf_data = (VideoDX9SurfaceData*) surf->GetVideoPrivateData();
+ surf_data->vertex_buffer->Select(0);
+ surf_data->index_buffer->Select();
+
+ ListIter<Segment> seg_iter = surf->GetSegments();
+ while (++seg_iter) {
+ Segment* segment = seg_iter.value();
+ Material* mtl = segment->material;
+
+ if (mtl && (blend_modes & mtl->blend)) {
+ result = result && DrawSegment(segment);
+ }
+ }
+ }
+ }
+ }
+
+ surface_has_tangent_data = false;
+
+ return result;
+}
+
+bool
+VideoDX9::DrawSegment(Segment* segment)
+{
+ bool result = false;
+ bool detail = false;
+ bool luminous = false;
+ HRESULT hr = E_FAIL;
+
+ if (segment && segment->video_data) {
+ stats.ncalls++;
+
+ VideoDX9SegmentData* seg_data = (VideoDX9SegmentData*) segment->video_data;
+ int first_vert = seg_data->first_vert;
+ int num_verts = seg_data->num_verts;
+ int first_index = seg_data->first_index;
+ int num_tris = seg_data->num_tris;
+
+ if (segment->model)
+ luminous = segment->model->IsLuminous();
+
+ // set render states and select buffers
+ d3ddevice->SetRenderState(D3DRS_AMBIENT, ambient.Value());
+
+ Material* mtl = segment->material;
+
+ if (use_material)
+ mtl = use_material;
+
+ if (segment->polys && segment->polys->vertex_set && segment->polys->vertex_set->tu1)
+ detail = true;
+
+ // send primitives to the device
+ if (detail) {
+ hr = d3ddevice->SetVertexShader(NULL);
+ hr = d3ddevice->SetFVF(VideoDX9DetailVertex::FVF);
+ }
+
+ else if (luminous) {
+ hr = d3ddevice->SetVertexShader(NULL);
+ hr = d3ddevice->SetFVF(VideoDX9LuminousVertex::FVF);
+ }
+
+ else if (surface_has_tangent_data && vertex_declaration) {
+ hr = d3ddevice->SetVertexDeclaration(vertex_declaration);
+ hr = d3ddevice->SetVertexShader(NULL);
+ }
+
+ else {
+ hr = d3ddevice->SetVertexShader(NULL);
+ hr = d3ddevice->SetFVF(VideoDX9SolidVertex::FVF);
+ }
+
+ if (render_state[FILL_MODE] == FILL_WIREFRAME) {
+ PrepareMaterial(mtl);
+ SetupPass(0);
+
+ for (int i = 0; i < segment->npolys; i++) {
+ DrawPolyOutline(segment->polys + i);
+ }
+ }
+
+ else if (luminous) {
+ PrepareMaterial(mtl);
+
+ SetRenderState(FILL_MODE, D3DFILL_SOLID);
+ SetRenderState(LIGHTING_ENABLE, FALSE);
+ SetBlendType(mtl->blend);
+
+ for (int pass = 0; pass < passes; pass++) {
+ SetupPass(pass);
+
+ hr = d3ddevice->DrawIndexedPrimitive(
+ D3DPT_TRIANGLELIST,
+ 0,
+ first_vert,
+ num_verts,
+ first_index,
+ num_tris);
+ }
+
+ d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
+ }
+
+ else {
+ PrepareMaterial(mtl);
+
+ if (strategy == DX9_STRATEGY_GLOW && render_state[LIGHTING_PASS] > 0) {
+ hr = 0;
+ }
+
+ else if (magic_fx && strategy < DX9_STRATEGY_BLEND && !detail) {
+ DWORD vs_version = 0;
+ DWORD ps_version = 0;
+ bool shaders_ok = false;
+
+ VideoDX9DeviceInfo* dev_info = dx9enum->GetDeviceInfo(video_settings.GetDeviceType());
+
+ if (dev_info) {
+ vs_version = video_settings.enable_vs ? dev_info->caps.VertexShaderVersion : 0;
+ ps_version = video_settings.enable_ps ? dev_info->caps.PixelShaderVersion : 0;
+
+ if (vs_version >= D3DVS_VERSION(1,1))
+ shaders_ok = true;
+ }
+
+ if (surface_has_tangent_data && vertex_declaration) {
+ hr = d3ddevice->SetVertexShader(NULL);
+ hr = d3ddevice->SetVertexDeclaration(vertex_declaration);
+ }
+
+ else {
+ hr = d3ddevice->SetVertexShader(NULL);
+ hr = d3ddevice->SetFVF(VideoDX9SolidVertex::FVF);
+ }
+
+ bool would_bump = !IsBumpMapEnabled() && mtl->bump > 0.5;
+
+ bool will_bump = IsBumpMapEnabled() && surface_has_tangent_data && shaders_ok && camera;
+
+ bool do_pix = will_bump && render_state[LIGHTING_PASS] == 0;
+ bool do_bump = will_bump && render_state[LIGHTING_PASS] > 0;
+
+ D3DXMATRIX matrixWVP = matrixWorld * matrixView * matrixProj;
+
+ D3DXVECTOR4 eyePos( (float) camera->Pos().x, (float) camera->Pos().y, (float) camera->Pos().z, 1.0f);
+
+ D3DXVECTOR4 eyeObj;
+ D3DXVec4Transform(&eyeObj, &eyePos, &matrixWorldInverse);
+
+ D3DXVECTOR4 lightPos(100.0f, 100.0f, 100.0f, 1.0f);
+ D3DXVECTOR4 lightColor(1,1,1,1);
+ D3DXVECTOR4 ambientColor(0,0,0,1);
+
+ ambientColor.x = ambient.fRed();
+ ambientColor.y = ambient.fGreen();
+ ambientColor.z = ambient.fBlue();
+
+ if (main_light && (render_state[LIGHTING_PASS] > 0 || mtl->blend > Material::MTL_SOLID)) {
+ lightPos.x = (float) main_light->Location().x;
+ lightPos.y = (float) main_light->Location().y;
+ lightPos.z = (float) main_light->Location().z;
+
+ if (mtl->tex_bumpmap && do_bump)
+ D3DXVec4Transform(&lightPos, &lightPos, &matrixWorldInverse);
+
+ lightColor.x = main_light->GetColor().fRed() * main_light->Intensity();
+ lightColor.y = main_light->GetColor().fGreen() * main_light->Intensity();
+ lightColor.z = main_light->GetColor().fBlue() * main_light->Intensity();
+ lightColor.w = 1.0f;
+ }
+
+ else if (back_light && render_state[LIGHTING_PASS] == 0) {
+ lightPos.x = (float) back_light->Location().x;
+ lightPos.y = (float) back_light->Location().y;
+ lightPos.z = (float) back_light->Location().z;
+
+ lightColor.x = back_light->GetColor().fRed() * back_light->Intensity();
+ lightColor.y = back_light->GetColor().fGreen() * back_light->Intensity();
+ lightColor.z = back_light->GetColor().fBlue() * back_light->Intensity();
+ lightColor.w = 1.0f;
+ }
+
+ D3DXVECTOR4 lightDir = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f) - lightPos;
+ D3DXVec4Normalize(&lightDir, &lightDir);
+
+ magic_fx->SetMatrix("wvp", &matrixWVP);
+ magic_fx->SetMatrix("world", &matrixWorld);
+ magic_fx->SetMatrix("view", &matrixView);
+ magic_fx->SetMatrix("proj", &matrixProj);
+ magic_fx->SetMatrix("worldInv", &matrixWorldInverse);
+
+ magic_fx->SetVector("light1Pos", &lightPos);
+ magic_fx->SetVector("light1Dir", &lightDir);
+ magic_fx->SetVector("light1Color", &lightColor);
+ magic_fx->SetVector("ambientColor", &ambientColor);
+ magic_fx->SetVector("eyeObj", &eyeObj);
+
+ FLOAT base_bias = (FLOAT) (DW2I(render_state[Z_BIAS]) / -10000.0);
+ magic_fx->SetFloat("bias", base_bias + video_settings.depth_bias);
+
+ ColorValue orig_ks = mtl->Ks;
+
+ if (would_bump && mtl->specular_value >= 0.5)
+ mtl->Ks = mtl->Ks * 0.3;
+
+ magic_fx->SetValue("Ka", &mtl->Ka, sizeof(ColorValue));
+ magic_fx->SetValue("Kd", &mtl->Kd, sizeof(ColorValue));
+ magic_fx->SetValue("Ke", &mtl->Ke, sizeof(ColorValue));
+ magic_fx->SetValue("Ks", &mtl->Ks, sizeof(ColorValue));
+ magic_fx->SetFloat("Ns", mtl->power);
+
+ if (would_bump && mtl->specular_value >= 0.5)
+ mtl->Ks = orig_ks;
+
+ if (mtl->tex_diffuse) {
+ IDirect3DTexture9* texture = texcache->FindTexture(mtl->tex_diffuse);
+ magic_fx->SetTexture("tex_d", texture);
+ } else {
+ magic_fx->SetTexture("tex_d", 0);
+ }
+
+ if (mtl->tex_emissive) {
+ IDirect3DTexture9* texture = texcache->FindTexture(mtl->tex_emissive);
+ magic_fx->SetTexture("tex_e", texture);
+ } else {
+ magic_fx->SetTexture("tex_e", 0);
+ }
+
+ if (mtl->tex_specular && IsSpecMapEnabled()) {
+ IDirect3DTexture9* texture = texcache->FindTexture(mtl->tex_specular);
+ magic_fx->SetTexture("tex_s", texture);
+ } else {
+ magic_fx->SetTexture("tex_s", 0);
+ }
+
+ if (mtl->tex_bumpmap && do_bump) {
+ IDirect3DTexture9* texture = texcache->FindNormalMap(mtl->tex_bumpmap, mtl->bump);
+ magic_fx->SetTexture("tex_n", texture);
+ magic_fx->SetFloat("offsetAmp", mtl->bump / mtl->tex_bumpmap->Height());
+ } else if (mtl->tex_bumpmap && !do_bump) {
+ IDirect3DTexture9* texture = texcache->FindTexture(mtl->tex_bumpmap);
+ magic_fx->SetTexture("tex_x", texture);
+ } else {
+ magic_fx->SetTexture("tex_x", 0);
+ }
+
+ const char* mtl_shader = mtl->GetShader(render_state[LIGHTING_PASS]);
+ D3DXHANDLE hnd_shader = 0;
+
+ if (mtl_shader) {
+ if (!strcmp(mtl_shader, "null"))
+ return true;
+
+ hnd_shader = magic_fx->GetTechniqueByName(mtl_shader);
+ }
+
+ if (hnd_shader) {
+ hr = magic_fx->SetTechnique(hnd_shader);
+ } else {
+ if (will_bump) {
+ if (mtl->tex_specular && IsSpecMapEnabled()) {
+ if (mtl->tex_bumpmap && do_bump) {
+ if (ps_version >= D3DPS_VERSION(2,0))
+ hr = magic_fx->SetTechnique("BumpSpecMapPix");
+ else
+ hr = magic_fx->SetTechnique("BumpSpecMap");
+ } else if (mtl->tex_emissive && render_state[LIGHTING_PASS] == 0) {
+ if (ps_version >= D3DPS_VERSION(2,0))
+ hr = magic_fx->SetTechnique("EmissiveSpecMapPix");
+ else
+ hr = magic_fx->SetTechnique("EmissiveSpecularTexture");
+ } else {
+ if (ps_version >= D3DPS_VERSION(2,0))
+ hr = magic_fx->SetTechnique("SpecMapPix");
+ else
+ hr = magic_fx->SetTechnique("SpecularTexture");
+ }
+ } else {
+ if (mtl->tex_bumpmap && do_bump) {
+ if (ps_version >= D3DPS_VERSION(2,0))
+ hr = magic_fx->SetTechnique("BumpMapPix");
+ else
+ hr = magic_fx->SetTechnique("BumpMap");
+ } else if (mtl->tex_emissive && render_state[LIGHTING_PASS] == 0) {
+ if (ps_version >= D3DPS_VERSION(2,0))
+ hr = magic_fx->SetTechnique("EmissivePix");
+ else
+ hr = magic_fx->SetTechnique("EmissiveTexture");
+ } else {
+ if (ps_version >= D3DPS_VERSION(2,0))
+ hr = magic_fx->SetTechnique("SimplePix");
+ else
+ hr = magic_fx->SetTechnique("SimpleTexture");
+ }
+ }
+ }
+
+ else if (texcache && mtl->tex_diffuse) {
+ if (mtl->tex_specular && IsSpecMapEnabled()) {
+ if (mtl->tex_emissive && render_state[LIGHTING_PASS] == 0) {
+ hr = magic_fx->SetTechnique("EmissiveSpecularTexture");
+ } else {
+ hr = magic_fx->SetTechnique("SpecularTexture");
+ }
+ }
+
+ else {
+ if (mtl->tex_emissive && render_state[LIGHTING_PASS] == 0) {
+ hr = magic_fx->SetTechnique("EmissiveTexture");
+ } else {
+ hr = magic_fx->SetTechnique("SimpleTexture");
+ }
+ }
+ } else {
+ hr = magic_fx->SetTechnique("SimpleMaterial");
+ }
+ }
+
+ if (environment_cube != 0 && magic_fx->IsParameterUsed("env_cube", hnd_shader)) {
+ D3DXMATRIX env_matrix;
+ D3DXMatrixIdentity(&env_matrix);
+
+ magic_fx->SetMatrix("env_matrix", &env_matrix);
+ magic_fx->SetTexture("env_cube", environment_cube->GetTexture());
+ }
+
+ if (render_state[STENCIL_ENABLE]) {
+ d3ddevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
+ d3ddevice->SetRenderState(D3DRS_STENCILREF, 0x01);
+ d3ddevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_GREATER);
+ } else {
+ d3ddevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
+ }
+
+ if (render_state[LIGHTING_PASS] > 0) {
+ current_blend_state = 100;
+ SetBlendType(BLEND_ADDITIVE);
+ SetRenderState(Z_WRITE_ENABLE, FALSE);
+ } else {
+ current_blend_state = 100;
+ SetBlendType(mtl->blend);
+ }
+
+ UINT nPasses = 0;
+
+ hr = magic_fx->Begin(&nPasses, 0);
+
+ for (UINT i = 0; i < nPasses; i++) {
+ hr = magic_fx->BeginPass(i);
+
+ hr = d3ddevice->DrawIndexedPrimitive(
+ D3DPT_TRIANGLELIST,
+ 0,
+ first_vert,
+ num_verts,
+ first_index,
+ num_tris);
+
+ hr = magic_fx->EndPass();
+ }
+
+ hr = magic_fx->End();
+ } else {
+ for (int pass = 0; pass < passes; pass++) {
+ SetupPass(pass);
+
+ hr = d3ddevice->DrawIndexedPrimitive(
+ D3DPT_TRIANGLELIST,
+ 0,
+ first_vert,
+ num_verts,
+ first_index,
+ num_tris);
+
+ if (detail) {
+ hr = d3ddevice->SetVertexShader(NULL);
+ hr = d3ddevice->SetFVF(VideoDX9DetailVertex::FVF);
+ } else if (luminous) {
+ hr = d3ddevice->SetVertexShader(NULL);
+ hr = d3ddevice->SetFVF(VideoDX9LuminousVertex::FVF);
+ } else if (surface_has_tangent_data && vertex_declaration) {
+ hr = d3ddevice->SetVertexShader(NULL);
+ hr = d3ddevice->SetVertexDeclaration(vertex_declaration);
+ } else {
+ hr = d3ddevice->SetVertexShader(NULL);
+ hr = d3ddevice->SetFVF(VideoDX9SolidVertex::FVF);
+ }
+ }
+ }
+ }
+
+ if (FAILED(hr)) {
+ static int report = 10;
+ if (report-- > 0)
+ VideoDX9Error("Could not draw solid polys.", hr);
+ } else {
+ stats.nverts += num_verts;
+ stats.npolys += num_tris;
+ result = true;
+ }
+ }
+
+ return result;
+}
+
+bool
+VideoDX9::DrawPolyOutline(Poly* p)
+{
+ if (d3ddevice && p && p->nverts >= 3) {
+ static VideoDX9LineVertex verts[8];
+
+ int nlines = p->nverts;
+ VertexSet* vset = p->vertex_set;
+ WORD index = 0;
+ Color color = Color::Black;
+ HRESULT hr = E_FAIL;
+
+ ZeroMemory(verts, sizeof(verts));
+
+ if (p->material)
+ color = p->material->Kd.ToColor();
+
+ for (int i = 0; i < p->nverts; i++) {
+ index = p->verts[i];
+
+ verts[i].x = vset->loc[index].x;
+ verts[i].y = vset->loc[index].y;
+ verts[i].z = vset->loc[index].z;
+ verts[i].diffuse = color.Value();
+ }
+
+ // last vertex, to close the loop
+ index = p->verts[0];
+ int i = p->nverts;
+
+ verts[i].x = vset->loc[index].x;
+ verts[i].y = vset->loc[index].y;
+ verts[i].z = vset->loc[index].z;
+ verts[i].diffuse = color.Value();
+
+ current_texture = 0;
+
+ hr = d3ddevice->SetVertexShader(NULL);
+ hr = d3ddevice->SetFVF(VideoDX9LineVertex::FVF);
+ hr = d3ddevice->SetTexture(0, 0);
+ hr = d3ddevice->DrawPrimitiveUP(
+ D3DPT_LINESTRIP,
+ nlines,
+ verts,
+ sizeof(VideoDX9LineVertex));
+ return true;
+ }
+
+ return false;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::DrawShadow(Solid* s, int nverts, Vec3* shadow_verts, bool visible)
+{
+ bool result = false;
+ HRESULT hr = E_FAIL;
+
+ if (d3ddevice && s && nverts && shadow_verts && IsShadowEnabled()) {
+ Matrix orient = s->Orientation();
+ orient.Transpose();
+
+ D3DMATRIX world_matrix;
+ CreateD3DMatrix(world_matrix, orient, s->Location());
+ d3ddevice->SetTransform(D3DTS_WORLD, &world_matrix);
+ matrixWorld = world_matrix;
+
+ // show shadow outlines:
+ if (visible) {
+ static VideoDX9LineVertex verts[4];
+
+ d3ddevice->SetRenderState(D3DRS_ZENABLE, TRUE);
+ d3ddevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
+ d3ddevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
+ d3ddevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
+ d3ddevice->SetRenderState(D3DRS_LIGHTING, FALSE);
+ d3ddevice->SetVertexShader(NULL);
+ d3ddevice->SetFVF(VideoDX9LineVertex::FVF);
+ d3ddevice->SetTexture(0, 0);
+
+ SetBlendType(BLEND_ALPHA);
+
+ for (int i = 0; i < nverts; i+=3) {
+ DWORD c = 0xa0ffff80;
+
+ verts[0].x = shadow_verts[i+0].x;
+ verts[0].y = shadow_verts[i+0].y;
+ verts[0].z = shadow_verts[i+0].z;
+ verts[0].diffuse = c;
+
+ verts[1].x = shadow_verts[i+1].x;
+ verts[1].y = shadow_verts[i+1].y;
+ verts[1].z = shadow_verts[i+1].z;
+ verts[1].diffuse = c;
+
+ verts[2].x = shadow_verts[i+2].x;
+ verts[2].y = shadow_verts[i+2].y;
+ verts[2].z = shadow_verts[i+2].z;
+ verts[2].diffuse = c;
+
+ verts[3].x = shadow_verts[i+0].x;
+ verts[3].y = shadow_verts[i+0].y;
+ verts[3].z = shadow_verts[i+0].z;
+ verts[3].diffuse = c;
+
+ hr = d3ddevice->DrawPrimitiveUP(
+ D3DPT_LINESTRIP,
+ 3,
+ verts,
+ sizeof(VideoDX9LineVertex));
+ }
+
+ // restore lighting state
+ d3ddevice->SetRenderState(D3DRS_LIGHTING, render_state[LIGHTING_ENABLE]);
+ }
+
+ // render shadows into stencil buffer:
+
+ // Disable z-buffer writes (note: z-testing still occurs), and enable the
+ // stencil-buffer
+ d3ddevice->SetRenderState(D3DRS_ZENABLE, TRUE);
+ d3ddevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
+ d3ddevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
+
+ // Dont bother with interpolating color
+ d3ddevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
+
+ // Set up stencil compare fuction, reference value, and masks.
+ // Stencil test passes if ((ref & mask) cmpfn (stencil & mask)) is true.
+ // Note: since we set up the stencil-test to always pass, the STENCILFAIL
+ // renderstate is really not needed.
+ d3ddevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS );
+ d3ddevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP );
+ d3ddevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP );
+
+ // If z-test passes, inc/decrement stencil buffer value
+ d3ddevice->SetRenderState(D3DRS_STENCILREF, 0x1 );
+ d3ddevice->SetRenderState(D3DRS_STENCILMASK, 0xff );
+ d3ddevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xff );
+ d3ddevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR );
+
+ // Make sure that no pixels get drawn to the frame buffer
+ d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE );
+ d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO );
+ d3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE );
+
+ d3ddevice->SetVertexShader(NULL);
+ d3ddevice->SetFVF(D3DFVF_XYZ);
+
+ // Draw front-side of shadow volume in stencil/z only
+ hr = d3ddevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, nverts/3, shadow_verts, sizeof(Vec3));
+
+ // Now reverse cull order so back sides of shadow volume are written.
+ d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW );
+
+ // Decrement stencil buffer value
+ d3ddevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_DECR );
+
+ // Draw back-side of shadow volume in stencil/z only
+ hr = d3ddevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, nverts/3, shadow_verts, sizeof(Vec3));
+
+ // restore render states
+ d3ddevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
+ d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
+ d3ddevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
+ d3ddevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
+
+ // force restore of current blend type
+ int type = current_blend_state;
+ current_blend_state = 100;
+ SetBlendType(type);
+
+ result = SUCCEEDED(hr);
+ }
+
+ return result;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::DrawLines(int nlines, Vec3* points, Color c, int blend)
+{
+ bool result = false;
+
+ if (d3ddevice && points && nlines > 0 && nlines <= 256) {
+ stats.ncalls++;
+
+ VideoDX9LineVertex* verts = line_verts;
+
+ if (verts) {
+ HRESULT hr = E_FAIL;
+
+ for (int i = 0; i < 2*nlines; i++) {
+ VideoDX9LineVertex* v = verts + i;
+ Vec3* p = points + i;
+
+ v->x = p->x;
+ v->y = p->y;
+ v->z = p->z;
+ v->diffuse = c.Value();
+ }
+
+ hr = d3ddevice->SetTransform(D3DTS_WORLD, &identity_matrix);
+ hr = d3ddevice->SetVertexShader(NULL);
+ hr = d3ddevice->SetFVF(VideoDX9LineVertex::FVF);
+
+ DWORD old_lighting = render_state[LIGHTING_ENABLE];
+
+ // untextured lines:
+ if (current_texture) {
+ d3ddevice->SetTexture(0, 0);
+ current_texture = 0;
+ }
+
+ SetRenderState(LIGHTING_ENABLE, FALSE);
+ SetBlendType(blend);
+
+ hr = d3ddevice->DrawPrimitiveUP(
+ D3DPT_LINELIST,
+ nlines,
+ verts,
+ sizeof(VideoDX9LineVertex));
+
+ if (FAILED(hr)) {
+ static int report = 10;
+ if (report-- > 0)
+ VideoDX9Error("Could not draw 3D lines.", hr);
+ }
+
+ SetRenderState(LIGHTING_ENABLE, old_lighting);
+
+ if (SUCCEEDED(hr)) {
+ stats.nverts += 2*nlines;
+ stats.nlines += nlines;
+ result = true;
+ }
+ }
+ }
+
+ return result;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::DrawScreenLines(int nlines, float* points, Color c, int blend)
+{
+ bool result = false;
+
+ if (d3ddevice && points && nlines > 0 && nlines <= 64) {
+ stats.ncalls++;
+
+ VideoDX9ScreenVertex* verts = screen_line_verts;
+
+ if (verts) {
+ HRESULT hr = E_FAIL;
+
+ for (int i = 0; i < 2*nlines; i++) {
+ VideoDX9ScreenVertex* v = verts + i;
+
+ v->sx = points[2*i + 0];
+ v->sy = points[2*i + 1];
+ v->sz = 0.0f;
+ v->rhw = 1.0f;
+ v->diffuse = c.Value();
+ v->tu = 0.0f;
+ v->tv = 0.0f;
+ }
+
+ hr = d3ddevice->SetVertexShader(NULL);
+ hr = d3ddevice->SetFVF(VideoDX9ScreenVertex::FVF);
+
+ if (FAILED(hr)) {
+ static int report = 10;
+ if (report-- > 0)
+ VideoDX9Error("Could not set FVF for screen lines.", hr);
+ }
+
+ else {
+ if (current_texture != 0) {
+ hr = d3ddevice->SetTexture(0, 0);
+ current_texture = 0;
+ }
+
+ SetRenderState(FILL_MODE, D3DFILL_SOLID);
+ SetRenderState(Z_ENABLE, D3DZB_FALSE);
+ SetRenderState(LIGHTING_ENABLE, FALSE);
+ SetBlendType(blend);
+
+ hr = d3ddevice->DrawPrimitiveUP(
+ D3DPT_LINELIST,
+ nlines,
+ verts,
+ sizeof(VideoDX9ScreenVertex));
+
+ if (FAILED(hr)) {
+ static int report = 10;
+ if (report-- > 0)
+ VideoDX9Error("Could not draw screen lines.", hr);
+ }
+ }
+
+ if (SUCCEEDED(hr)) {
+ stats.nverts += 2*nlines;
+ stats.nlines += nlines;
+ result = true;
+ }
+ }
+ }
+
+ return result;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::DrawPoints(VertexSet* vset)
+{
+ if (vset && vset->nverts) {
+ HRESULT hr = E_FAIL;
+
+ int nverts = vset->nverts;
+ VideoDX9LineVertex* verts = new(__FILE__,__LINE__) VideoDX9LineVertex[nverts];
+
+ if (verts) {
+ for (int i = 0; i < nverts; i++) {
+ VideoDX9LineVertex* v = verts + i;
+ Vec3* p = vset->loc + i;
+
+ v->x = p->x;
+ v->y = p->y;
+ v->z = p->z;
+ v->diffuse = vset->diffuse[i];
+ }
+
+ SetRenderState(LIGHTING_ENABLE, FALSE);
+
+ hr = d3ddevice->SetTransform(D3DTS_WORLD, &identity_matrix);
+ hr = d3ddevice->SetVertexShader(NULL);
+ hr = d3ddevice->SetFVF(VideoDX9LineVertex::FVF);
+ hr = d3ddevice->SetTexture(0, 0);
+ hr = d3ddevice->DrawPrimitiveUP(
+ D3DPT_POINTLIST,
+ nverts,
+ verts,
+ sizeof(VideoDX9LineVertex));
+
+ delete [] verts;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::UseMaterial(Material* m)
+{
+ use_material = m;
+ return true;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::UseXFont(const char* name, int size, bool bold, bool ital)
+{
+ if (d3ddevice && name && *name && size > 4) {
+ RELEASE(d3dx_font);
+
+ strcpy_s(font_name, name);
+ font_size = size;
+ font_bold = bold;
+ font_ital = ital;
+
+ HRESULT hr = E_FAIL;
+ HDC hdc = GetDC(NULL);
+ int nLogPixelsY = GetDeviceCaps(hdc, LOGPIXELSY);
+
+ ReleaseDC(NULL, hdc);
+
+ int nHeight = -size * nLogPixelsY / 72;
+
+ hr = D3DXCreateFont(d3ddevice, // D3D device
+ nHeight, // Height
+ 0, // Width
+ bold ? FW_BOLD : FW_NORMAL, // Weight
+ 1, // MipLevels, 0 = autogen mipmaps
+ ital, // Italic
+ DEFAULT_CHARSET, // CharSet
+ OUT_DEFAULT_PRECIS, // OutputPrecision
+ DEFAULT_QUALITY, // Quality
+ DEFAULT_PITCH | FF_DONTCARE, // PitchAndFamily
+ name, // pFaceName
+ &d3dx_font); // ppFont
+
+ if (SUCCEEDED(hr)) {
+ return true;
+ }
+ }
+
+ RELEASE(d3dx_font);
+ return false;
+}
+
+bool
+VideoDX9::DrawText(const char* text, int count, const Rect& rect, DWORD format, Color c)
+{
+ if (d3ddevice && text && *text && d3dx_font) {
+ RECT r;
+ r.left = rect.x;
+ r.top = rect.y;
+ r.right = rect.x + rect.w;
+ r.bottom = rect.y + rect.h;
+
+ d3dx_font->DrawText(0, text, count, &r, format, c.Value());
+ }
+
+ return false;
+}
+
+// +--------------------------------------------------------------------+
+
+bool
+VideoDX9::PrepareSurface(Surface* surf)
+{
+ if (surf) {
+ int nverts = surf->NumVerts();
+ int nindices = surf->NumIndices();
+ bool detail = surf->GetVertexSet()->tu1 != 0;
+ bool luminous = false;
+ DWORD dynamic = 0;
+
+ if (surf->GetModel()) {
+ luminous = surf->GetModel()->IsLuminous();
+ dynamic = surf->GetModel()->IsDynamic() ? D3DUSAGE_DYNAMIC : 0;
+ }
+
+ surface_has_tangent_data = !luminous && (surf->GetVertexSet()->tangent && surf->GetVertexSet()->binormal);
+
+ VideoDX9SurfaceData* surf_data = (VideoDX9SurfaceData*) surf->GetVideoPrivateData();
+
+ if (!surf_data) {
+ surf_data = new(__FILE__,__LINE__) VideoDX9SurfaceData(surf->GetModel());
+
+ surface_has_tangent_data = false;
+
+ if (surf->GetVertexSet()->tangent && surf->GetVertexSet()->binormal) {
+ surface_has_tangent_data = true;
+ surf_data->vertex_buffer = new(__FILE__,__LINE__) VideoDX9VertexBuffer(
+ this,
+ nverts,
+ sizeof(VideoDX9NormalVertex),
+ 0, // not an FVF vertex buffer
+ dynamic | D3DUSAGE_WRITEONLY);
+ }
+
+ else if (detail) {
+ surf_data->vertex_buffer = new(__FILE__,__LINE__) VideoDX9VertexBuffer(
+ this,
+ nverts,
+ sizeof(VideoDX9DetailVertex),
+ VideoDX9DetailVertex::FVF,
+ dynamic | D3DUSAGE_WRITEONLY);
+ }
+
+ else if (luminous) {
+ surf_data->vertex_buffer = new(__FILE__,__LINE__) VideoDX9VertexBuffer(
+ this,
+ nverts,
+ sizeof(VideoDX9LuminousVertex),
+ VideoDX9LuminousVertex::FVF,
+ dynamic | D3DUSAGE_WRITEONLY);
+ }
+
+ else {
+ surf_data->vertex_buffer = new(__FILE__,__LINE__) VideoDX9VertexBuffer(
+ this,
+ nverts,
+ sizeof(VideoDX9SolidVertex),
+ VideoDX9SolidVertex::FVF,
+ dynamic | D3DUSAGE_WRITEONLY);
+ }
+
+ surf_data->index_buffer = new(__FILE__,__LINE__) VideoDX9IndexBuffer(
+ this,
+ nindices,
+ dynamic | D3DUSAGE_WRITEONLY);
+
+ if (!surf_data->vertex_buffer || !surf_data->index_buffer) {
+ Print("VideoDX9: Unable to prepare surface '%s'\n", surf->Name());
+ delete surf_data;
+ return false;
+ }
+
+ surf->SetVideoPrivateData(surf_data);
+ }
+
+ if (surf_data && !surf_data->IsValid()) {
+ if (detail) {
+ VideoDX9DetailVertex* v = (VideoDX9DetailVertex*) surf_data->vertex_buffer->Lock(nverts);
+
+ if (v) {
+ const VertexSet* vset = surf->GetVertexSet();
+ for (int i = 0; i < nverts; i++) {
+ v->x = vset->loc[i].x;
+ v->y = vset->loc[i].y;
+ v->z = vset->loc[i].z;
+
+ v->diffuse = vset->diffuse[i];
+ v->specular = vset->specular[i];
+
+ v->tu = vset->tu[i];
+ v->tv = vset->tv[i];
+ v->tu1 = vset->tu1[i];
+ v->tv1 = vset->tv1[i];
+
+ v++;
+ }
+
+ surf_data->vertex_buffer->Unlock();
+ }
+ }
+
+ else if (luminous) {
+ VideoDX9LuminousVertex* v = (VideoDX9LuminousVertex*) surf_data->vertex_buffer->Lock(nverts);
+
+ if (v) {
+ const VertexSet* vset = surf->GetVertexSet();
+ for (int i = 0; i < nverts; i++) {
+ v->x = vset->loc[i].x;
+ v->y = vset->loc[i].y;
+ v->z = vset->loc[i].z;
+
+ v->diffuse = vset->diffuse[i];
+
+ v->tu = vset->tu[i];
+ v->tv = vset->tv[i];
+
+ v++;
+ }
+
+ surf_data->vertex_buffer->Unlock();
+ }
+ }
+
+ else if (surface_has_tangent_data) {
+ VideoDX9NormalVertex* v = (VideoDX9NormalVertex*) surf_data->vertex_buffer->Lock(nverts);
+
+ if (v) {
+ const VertexSet* vset = surf->GetVertexSet();
+ for (int i = 0; i < nverts; i++) {
+ v->x = vset->loc[i].x;
+ v->y = vset->loc[i].y;
+ v->z = vset->loc[i].z;
+
+ v->nx = vset->nrm[i].x;
+ v->ny = vset->nrm[i].y;
+ v->nz = vset->nrm[i].z;
+
+ v->t0u = vset->tu[i];
+ v->t0v = vset->tv[i];
+ v->t1u = vset->tu[i];
+ v->t1v = vset->tv[i];
+
+ v->tx = vset->tangent[i].x;
+ v->ty = vset->tangent[i].y;
+ v->tz = vset->tangent[i].z;
+
+ v->bx = vset->binormal[i].x;
+ v->by = vset->binormal[i].y;
+ v->bz = vset->binormal[i].z;
+
+ v++;
+ }
+
+ surf_data->vertex_buffer->Unlock();
+ }
+ }
+
+ else {
+ VideoDX9SolidVertex* v = (VideoDX9SolidVertex*) surf_data->vertex_buffer->Lock(nverts);
+
+ if (v) {
+ const VertexSet* vset = surf->GetVertexSet();
+ for (int i = 0; i < nverts; i++) {
+ v->x = vset->loc[i].x;
+ v->y = vset->loc[i].y;
+ v->z = vset->loc[i].z;
+
+ v->nx = vset->nrm[i].x;
+ v->ny = vset->nrm[i].y;
+ v->nz = vset->nrm[i].z;
+
+ v->tu = vset->tu[i];
+ v->tv = vset->tv[i];
+
+ v++;
+ }
+
+ surf_data->vertex_buffer->Unlock();
+ }
+ }
+
+ WORD* indices = surf_data->index_buffer->Lock(nindices);
+
+ if (indices) {
+ // copy the indices into the locked index buffer
+ WORD* s = indices;
+ Poly* p = surf->GetPolys();
+
+ for (int i = 0; i < surf->NumPolys(); i++) {
+ if (p->nverts == 3) {
+ *s++ = p->verts[0];
+ *s++ = p->verts[2];
+ *s++ = p->verts[1];
+ }
+ else if (p->nverts == 4) {
+ *s++ = p->verts[0];
+ *s++ = p->verts[2];
+ *s++ = p->verts[1];
+
+ *s++ = p->verts[0];
+ *s++ = p->verts[3];
+ *s++ = p->verts[2];
+ }
+
+ p++;
+ }
+
+ surf_data->index_buffer->Unlock();
+ }
+
+ surf_data->Validate();
+ }
+
+ int first_index = 0;
+
+ ListIter<Segment> seg_iter = surf->GetSegments();
+ while (++seg_iter) {
+ Segment* segment = seg_iter.value();
+
+ if (!segment->video_data) {
+ VideoDX9SegmentData* seg_data = new(__FILE__,__LINE__) VideoDX9SegmentData;
+
+ int num_tris = 0;
+ for (int i = 0; i < segment->npolys; i++)
+ num_tris += segment->polys[i].nverts-2;
+
+ seg_data->first_vert = 0;
+ seg_data->num_verts = surf->NumVerts();
+ seg_data->first_index = first_index;
+ seg_data->num_tris = num_tris;
+
+ segment->video_data = seg_data;
+
+ first_index += num_tris * 3;
+ }
+ }
+ }
+
+ return true;
+}
+
+// +--------------------------------------------------------------------+
+
+int
+VideoDX9::PrepareMaterial(Material* m)
+{
+ segment_material = m;
+ strategy = 0;
+ passes = 0;
+
+ if (m) {
+ int max_stages = 1;
+ int max_textures = 1;
+ bool multiply_add = false;
+ bool dotproduct3 = false;
+ bool vertexshader = false;
+ bool pixelshader = false;
+ DWORD vs_version = 0;
+ DWORD ps_version = 0;
+
+ VideoDX9DeviceInfo* dev_info = dx9enum->GetDeviceInfo(video_settings.GetDeviceType());
+
+ if (dev_info) {
+ max_stages = (int) dev_info->caps.MaxTextureBlendStages;
+ max_textures = (int) dev_info->caps.MaxSimultaneousTextures;
+ multiply_add = (dev_info->caps.TextureOpCaps & D3DTEXOPCAPS_MULTIPLYADD) ? true : false;
+ dotproduct3 = (dev_info->caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3) ? true : false;
+
+ vs_version = video_settings.enable_vs ? dev_info->caps.VertexShaderVersion : 0;
+ ps_version = video_settings.enable_ps ? dev_info->caps.PixelShaderVersion : 0;
+
+ vertexshader = vs_version >= D3DVS_VERSION(1,1);
+ pixelshader = ps_version >= D3DPS_VERSION(2,0);
+ }
+
+ strategy = DX9_STRATEGY_SIMPLE;
+ passes = 1;
+
+ if (m->tex_alternate) {
+ if (m->tex_detail && max_textures > 2 && max_stages > 4)
+ strategy = DX9_STRATEGY_BLEND_DETAIL;
+
+ else if (max_textures > 1 && max_stages > 3)
+ strategy = DX9_STRATEGY_BLEND;
+ }
+
+ else if (m->tex_emissive && (!m->tex_diffuse || m->tex_diffuse == m->tex_emissive)) {
+ strategy = DX9_STRATEGY_GLOW;
+ }
+
+ else if (IsSpecMapEnabled() && m->tex_specular && !m->tex_emissive) {
+ strategy = DX9_STRATEGY_SPECMAP;
+
+ if (max_textures < 2 || max_stages < 2 || !multiply_add)
+ passes = 2;
+ }
+
+ else if ((!IsSpecMapEnabled() || !m->tex_specular) && m->tex_emissive) {
+ strategy = DX9_STRATEGY_EMISSIVE;
+
+ if (max_textures < 2 || max_stages < 2)
+ passes = 2;
+ }
+
+ else if (IsSpecMapEnabled() && m->tex_specular && m->tex_emissive) {
+ strategy = DX9_STRATEGY_SPEC_EMISSIVE;
+
+ if (max_textures < 2 || max_stages < 2)
+ passes = 3;
+
+ else if (max_textures < 3 || max_stages < 3 || !multiply_add)
+ passes = 2;
+ }
+ }
+
+ return passes;
+}
+
+bool
+VideoDX9::SetupPass(int pass)
+{
+ if (pass < 0 || pass >= passes)
+ return false;
+
+ if (pass == 0) {
+ D3DMATERIAL9 d3dmtl;
+ IDirect3DTexture9* texture_0 = 0;
+ IDirect3DTexture9* texture_1 = 0;
+ IDirect3DTexture9* texture_2 = 0;
+ Bitmap* tex_bmp_0 = 0;
+ Bitmap* tex_bmp_1 = 0;
+ Bitmap* tex_bmp_2 = 0;
+ ColorValue orig_spec = segment_material->Ks;
+ HRESULT hr = E_FAIL;
+
+ if (segment_material->tex_specular && passes > 1)
+ segment_material->Ks = Color::Black;
+
+ CreateD3DMaterial(d3dmtl, *segment_material);
+ segment_material->Ks = orig_spec;
+
+ hr = d3ddevice->SetMaterial(&d3dmtl);
+
+ if (strategy == DX9_STRATEGY_SIMPLE) {
+ tex_bmp_0 = segment_material->tex_diffuse;
+ }
+
+ else if (strategy == DX9_STRATEGY_BLEND) {
+ tex_bmp_0 = segment_material->tex_diffuse;
+ tex_bmp_1 = segment_material->tex_alternate;
+ }
+
+ else if (strategy == DX9_STRATEGY_BLEND_DETAIL) {
+ tex_bmp_0 = segment_material->tex_diffuse;
+ tex_bmp_1 = segment_material->tex_alternate;
+ tex_bmp_2 = segment_material->tex_detail;
+ }
+
+ else if (strategy == DX9_STRATEGY_SPECMAP) {
+ if (passes == 1) {
+ tex_bmp_0 = segment_material->tex_diffuse;
+ tex_bmp_1 = segment_material->tex_specular;
+ }
+ else {
+ tex_bmp_0 = segment_material->tex_diffuse;
+ }
+ }
+
+ else if (strategy == DX9_STRATEGY_EMISSIVE && passes == 1 ||
+ strategy == DX9_STRATEGY_SPEC_EMISSIVE && passes == 2) {
+ if (segment_material->tex_diffuse) {
+ tex_bmp_0 = segment_material->tex_diffuse;
+ tex_bmp_1 = segment_material->tex_emissive;
+ }
+ else {
+ tex_bmp_0 = segment_material->tex_emissive;
+ }
+ }
+
+ else {
+ tex_bmp_0 = segment_material->tex_emissive;
+ }
+
+ if (texcache && tex_bmp_0) {
+ texture_0 = texcache->FindTexture(tex_bmp_0);
+
+ hr = d3ddevice->SetTexture(0, texture_0);
+ current_texture = texture_0;
+
+ if (tex_bmp_1) {
+ texture_1 = texcache->FindTexture(tex_bmp_1);
+ hr = d3ddevice->SetTexture(1, texture_1);
+
+ if (tex_bmp_2) {
+ texture_2 = texcache->FindTexture(tex_bmp_2);
+ hr = d3ddevice->SetTexture(2, texture_2);
+ }
+ }
+ }
+ else {
+ hr = d3ddevice->SetTexture(0, 0);
+ current_texture = 0;
+ }
+
+ SetBlendType(segment_material->blend);
+
+ if (texture_0 && texture_1 && strategy == DX9_STRATEGY_BLEND) {
+ d3ddevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
+ d3ddevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ d3ddevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
+
+ d3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
+
+ d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_BLENDCURRENTALPHA);
+ d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
+ d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE);
+ d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
+ d3ddevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);
+
+ d3ddevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_MODULATE);
+ d3ddevice->SetTextureStageState(2, D3DTSS_COLORARG1, D3DTA_CURRENT);
+ d3ddevice->SetTextureStageState(2, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
+ d3ddevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ d3ddevice->SetTextureStageState(2, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
+
+ d3ddevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE);
+ }
+
+ else if (texture_0 && texture_1 && texture_2 && strategy == DX9_STRATEGY_BLEND_DETAIL) {
+ d3ddevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
+ d3ddevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ d3ddevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
+ d3ddevice->SetSamplerState(2, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
+ d3ddevice->SetSamplerState(2, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ d3ddevice->SetSamplerState(2, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
+
+ d3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
+ d3ddevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
+
+ d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_BLENDCURRENTALPHA);
+ d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
+ d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE);
+ d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
+ d3ddevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);
+
+ d3ddevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
+ d3ddevice->SetTextureStageState(2, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ d3ddevice->SetTextureStageState(2, D3DTSS_COLORARG2, D3DTA_CURRENT);
+ d3ddevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ d3ddevice->SetTextureStageState(2, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
+ d3ddevice->SetTextureStageState(2, D3DTSS_TEXCOORDINDEX, 1);
+
+ d3ddevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_MODULATE);
+ d3ddevice->SetTextureStageState(3, D3DTSS_COLORARG1, D3DTA_CURRENT);
+ d3ddevice->SetTextureStageState(3, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
+ d3ddevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ d3ddevice->SetTextureStageState(3, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
+ }
+
+ else if (texture_0 && strategy == DX9_STRATEGY_GLOW) {
+ d3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
+ d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
+ }
+
+ else if (texture_0) {
+ d3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
+ d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
+ d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
+ }
+
+ if (texture_1 && strategy == DX9_STRATEGY_SPECMAP) {
+ d3ddevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
+ d3ddevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ d3ddevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
+
+ d3ddevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);
+ d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MULTIPLYADD);
+ d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_SPECULAR);
+ d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
+ }
+
+ else if (texture_1 && strategy == DX9_STRATEGY_EMISSIVE) {
+ d3ddevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
+ d3ddevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ d3ddevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
+
+ d3ddevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);
+ d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD);
+ d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
+ d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
+ }
+
+ else if (texture_1 && strategy == DX9_STRATEGY_SPEC_EMISSIVE) {
+ d3ddevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
+ d3ddevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ d3ddevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
+
+ d3ddevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);
+ d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD);
+ d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ d3ddevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
+ d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ d3ddevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
+ }
+
+ else if (strategy < DX9_STRATEGY_BLEND) {
+ d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
+ }
+ }
+
+ else if (pass == 1) {
+ D3DMATERIAL9 d3dmtl;
+ IDirect3DTexture9* texture = 0;
+ Bitmap* tex_bmp = 0;
+ ColorValue orig_Ka = segment_material->Ka;
+ ColorValue orig_Kd = segment_material->Kd;
+ HRESULT hr = E_FAIL;
+
+ if (segment_material->tex_specular) {
+ segment_material->Ka = Color::Black;
+ segment_material->Kd = Color::Black;
+ }
+
+ CreateD3DMaterial(d3dmtl, *segment_material);
+
+ segment_material->Ka = orig_Ka;
+ segment_material->Kd = orig_Kd;
+
+ hr = d3ddevice->SetMaterial(&d3dmtl);
+
+ if (strategy == DX9_STRATEGY_SPECMAP ||
+ strategy == DX9_STRATEGY_SPEC_EMISSIVE) {
+ tex_bmp = segment_material->tex_specular;
+ d3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
+ d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_SPECULAR);
+ }
+
+ else if (strategy == DX9_STRATEGY_EMISSIVE) {
+ tex_bmp = segment_material->tex_emissive;
+ d3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ d3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ }
+
+ d3ddevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
+
+ if (texcache && tex_bmp) {
+ texture = texcache->FindTexture(tex_bmp);
+ hr = d3ddevice->SetTexture(0, texture);
+ current_texture = texture;
+
+ SetBlendType(BLEND_ADDITIVE);
+ }
+ }
+
+ if (render_state[STENCIL_ENABLE]) {
+ d3ddevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
+ d3ddevice->SetRenderState(D3DRS_STENCILREF, 0x01);
+ d3ddevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_GREATER);
+ }
+ else {
+ d3ddevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
+ }
+
+ if (render_state[LIGHTING_PASS] > 0) {
+ SetBlendType(BLEND_ADDITIVE);
+ SetRenderState(Z_WRITE_ENABLE, FALSE);
+ }
+
+ return true;
+}
+
+
+// +--------------------------------------------------------------------+
+
+void
+VideoDX9Error(const char* msg, HRESULT err)
+{
+ Print(" VideoDX9: %s. [%s]\n", msg, D3DErrStr(err));
+}
+
+char* D3DErrStr(HRESULT hr)
+{
+ static char errstrbuf[128];
+
+ switch (hr) {
+ default:
+ sprintf_s(errstrbuf, "Unrecognized error value = %08x.", hr);
+ return errstrbuf;
+
+ case D3D_OK:
+ return "No error.";
+
+ case D3DERR_WRONGTEXTUREFORMAT:
+ return "Wrong texture format.";
+
+ case D3DERR_UNSUPPORTEDCOLOROPERATION:
+ return "Unsupported color operation.";
+
+ case D3DERR_UNSUPPORTEDCOLORARG:
+ return "Unsupported color argument.";
+
+ case D3DERR_UNSUPPORTEDALPHAOPERATION:
+ return "Unsupported alpha operation.";
+
+ case D3DERR_UNSUPPORTEDALPHAARG:
+ return "Unsupported alpha argument.";
+
+ case D3DERR_TOOMANYOPERATIONS:
+ return "Too many operations.";
+
+ case D3DERR_CONFLICTINGTEXTUREFILTER:
+ return "Conflicting texture filter.";
+
+ case D3DERR_UNSUPPORTEDFACTORVALUE:
+ return "Unsupported factor value.";
+
+ case D3DERR_CONFLICTINGRENDERSTATE:
+ return "Conflicting render state.";
+
+ case D3DERR_UNSUPPORTEDTEXTUREFILTER:
+ return "Unsupported texture filter.";
+
+ case D3DERR_CONFLICTINGTEXTUREPALETTE:
+ return "Conflicting texture palette.";
+
+ case D3DERR_DRIVERINTERNALERROR:
+ return "Driver internal error.";
+
+
+ case D3DERR_NOTFOUND:
+ return "Resource was not found.";
+
+ case D3DERR_MOREDATA:
+ return "More data?";
+
+ case D3DERR_DEVICELOST:
+ return "Device lost.";
+
+ case D3DERR_DEVICENOTRESET:
+ return "Device is not reset.";
+
+ case D3DERR_NOTAVAILABLE:
+ return "Not available.";
+
+ case D3DERR_OUTOFVIDEOMEMORY:
+ return "Out of video memory.";
+
+ case E_OUTOFMEMORY:
+ return "Out of system memory.";
+
+ case D3DERR_INVALIDDEVICE:
+ return "Invalid device selection.";
+
+ case D3DERR_INVALIDCALL:
+ return "Invalid call or parameter.";
+
+ case D3DERR_DRIVERINVALIDCALL:
+ return "Driver invalid call.";
+
+ case D3DERR_WASSTILLDRAWING:
+ return "The device was still drawing.";
+
+ case D3DOK_NOAUTOGEN:
+ return "Autogeneration is not supported by this device.";
+
+ }
+}
+
diff --git a/Magic2/VideoDX9.h b/Magic2/VideoDX9.h
index a9e0d6f..fdc37ff 100644
--- a/Magic2/VideoDX9.h
+++ b/Magic2/VideoDX9.h
@@ -1,195 +1,219 @@
-/* Project nGenEx
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: nGenEx.lib
- FILE: VideoDX9.h
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Direct3D and Direct3D Video classes for DirectX 7
-*/
-
-#ifndef VideoDX9_h
-#define VideoDX9_h
-
-#include "Video.h"
-#include "VideoSettings.h"
-#include "List.h"
-
-// +--------------------------------------------------------------------+
-
-class VideoDX9;
-class VideoDX9Enum;
-class VideoDX9VertexBuffer;
-class VideoDX9IndexBuffer;
-struct VideoDX9ScreenVertex;
-class Surface;
-class Segment;
-
-struct VideoDX9ScreenVertex;
-struct VideoDX9SolidVertex;
-struct VideoDX9LuminousVertex;
-struct VideoDX9LineVertex;
-
-
-// +--------------------------------------------------------------------+
-
-class VideoDX9 : public Video
-{
-public:
- VideoDX9(const HWND& window, VideoSettings* vs);
- virtual ~VideoDX9();
-
- virtual const VideoSettings*
- GetVideoSettings() const { return &video_settings; }
- virtual bool SetVideoSettings(const VideoSettings* vs);
-
- virtual bool SetBackgroundColor(Color c);
- virtual bool SetGammaLevel(int g);
- virtual bool SetObjTransform(const Matrix& o, const Point& l);
-
- virtual bool SetupParams();
- virtual bool Reset(const VideoSettings* vs);
-
- virtual bool StartFrame();
- virtual bool EndFrame();
-
- virtual int Width() const { return width; }
- virtual int Height() const { return height; }
- virtual int Depth() const { return bpp; }
-
- virtual void RecoverSurfaces();
-
- virtual bool ClearAll();
- virtual bool ClearDepthBuffer();
- virtual bool Present();
- virtual bool Pause();
- virtual bool Resume();
-
- virtual IDirect3D9* Direct3D() const { return d3d; }
- virtual IDirect3DDevice9* D3DDevice() const { return d3ddevice; }
- static IDirect3DDevice9* GetD3DDevice9();
-
- virtual bool IsModeSupported(int width, int height, int bpp) const;
- virtual bool IsHardware() const { return true; }
- virtual int ZDepth() const { return zdepth; }
- virtual DWORD VidMemFree() const;
- virtual int D3DLevel() const { return 9; }
- virtual int MaxTexSize() const;
- virtual int MaxTexAspect() const;
- virtual int GammaLevel() const { return gamma; }
-
- virtual bool Capture(Bitmap& bmp);
- virtual bool GetWindowRect(Rect& r);
- virtual bool SetWindowRect(const Rect& r);
- virtual bool SetViewport(int x, int y, int w, int h);
- virtual bool SetCamera(const Camera* cam);
- virtual bool SetEnvironment(Bitmap** faces);
- virtual bool SetAmbient(Color c);
- virtual bool SetLights(const List<Light>& lights);
- virtual bool SetProjection(float fov,
- float znear=1.0f,
- float zfar=1.0e6f,
- DWORD type=PROJECTION_PERSPECTIVE);
- virtual bool SetRenderState(RENDER_STATE state, DWORD value);
- virtual bool SetBlendType(int blend_type);
-
- virtual bool DrawPolys(int npolys, Poly* p);
- virtual bool DrawScreenPolys(int npolys, Poly* p, int blend=0);
- virtual bool DrawSolid(Solid* s, DWORD blend_modes=0xf);
- virtual bool DrawShadow(Solid* s, int nverts, Vec3* verts, bool vis=false);
- virtual bool DrawLines(int nlines, Vec3* v, Color c, int blend=0);
- virtual bool DrawScreenLines(int nlines, float* v, Color c, int blend=0);
- virtual bool DrawPoints(VertexSet* v);
- virtual bool DrawPolyOutline(Poly* p);
- virtual bool UseMaterial(Material* m);
-
- virtual bool UseXFont(const char* name, int size, bool b, bool i);
- virtual bool DrawText(const char* text, int count, const Rect& rect,
- DWORD format, Color c);
-
- virtual void PreloadTexture(Bitmap* bmp);
- virtual void PreloadSurface(Surface* s);
- virtual void InvalidateCache();
-
- static void CreateD3DMatrix(D3DMATRIX& result, const Matrix& m, const Point& p);
- static void CreateD3DMatrix(D3DMATRIX& result, const Matrix& m, const Vec3& v);
- static void CreateD3DMaterial(D3DMATERIAL9& result, const Material& mtl);
-
-private:
- bool CreateBuffers();
- bool DestroyBuffers();
- bool PopulateScreenVerts(VertexSet* vset);
- bool PrepareSurface(Surface* s);
- bool DrawSegment(Segment* s);
-
- int PrepareMaterial(Material* m);
- bool SetupPass(int n);
-
- HWND hwnd;
- int width;
- int height;
- int bpp;
- int gamma;
- int zdepth;
- Color background;
-
- VideoDX9Enum* dx9enum;
- VideoSettings video_settings;
-
- IDirect3D9* d3d;
- IDirect3DDevice9* d3ddevice;
- D3DPRESENT_PARAMETERS d3dparams;
- D3DSURFACE_DESC back_buffer_desc;
- bool device_lost;
-
- BYTE* surface;
-
- DWORD texture_format[3];
- D3DGAMMARAMP gamma_ramp;
- double fade;
-
- Rect rect;
-
- IDirect3DVertexDeclaration9* vertex_declaration;
- ID3DXEffect* magic_fx;
- BYTE* magic_fx_code;
- int magic_fx_code_len;
-
- IDirect3DTexture9* current_texture;
- int current_blend_state;
- int scene_active;
- DWORD render_state[RENDER_STATE_MAX];
- Material* use_material;
-
- Material* segment_material;
- int strategy;
- int passes;
-
- ID3DXFont* d3dx_font;
- char font_name[64];
- int font_size;
- bool font_bold;
- bool font_ital;
-
- Color ambient;
- int nlights;
-
- int first_vert;
- int num_verts;
-
- VideoDX9VertexBuffer* screen_vbuf;
- VideoDX9IndexBuffer* screen_ibuf;
- VideoDX9ScreenVertex* font_verts;
- WORD* font_indices;
- int font_nverts;
-
- VideoDX9ScreenVertex* screen_line_verts;
- VideoDX9LineVertex* line_verts;
-};
-
-#endif VideoDX9_h
-
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: nGenEx.lib
+ FILE: VideoDX9.h
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Direct3D and Direct3D Video classes for DirectX 7
+*/
+
+#ifndef VideoDX9_h
+#define VideoDX9_h
+
+#include "Video.h"
+#include "VideoSettings.h"
+#include "List.h"
+
+// +--------------------------------------------------------------------+
+
+class VideoDX9;
+class VideoDX9Enum;
+class VideoDX9VertexBuffer;
+class VideoDX9IndexBuffer;
+struct VideoDX9ScreenVertex;
+class Surface;
+class Segment;
+
+struct VideoDX9ScreenVertex;
+struct VideoDX9SolidVertex;
+struct VideoDX9LuminousVertex;
+struct VideoDX9LineVertex;
+
+
+// +--------------------------------------------------------------------+
+
+class VideoDX9 : public Video
+{
+public:
+ VideoDX9(const HWND& window, VideoSettings* vs);
+ virtual ~VideoDX9();
+
+ virtual const VideoSettings*
+ GetVideoSettings() const { return &video_settings; }
+ virtual bool SetVideoSettings(const VideoSettings* vs);
+
+ virtual bool SetBackgroundColor(Color c);
+ virtual bool SetGammaLevel(int g);
+ virtual bool SetObjTransform(const Matrix& o, const Point& l);
+
+ virtual bool SetupParams();
+ virtual bool Reset(const VideoSettings* vs);
+
+ virtual bool StartFrame();
+ virtual bool EndFrame();
+
+ virtual int Width() const { return width; }
+ virtual int Height() const { return height; }
+ virtual int Depth() const { return bpp; }
+
+ virtual void RecoverSurfaces();
+
+ virtual bool ClearAll();
+ virtual bool ClearDepthBuffer();
+ virtual bool Present();
+ virtual bool Pause();
+ virtual bool Resume();
+
+ virtual IDirect3D9* Direct3D() const { return d3d; }
+ virtual IDirect3DDevice9* D3DDevice() const { return d3ddevice; }
+ static IDirect3DDevice9* GetD3DDevice9();
+
+ virtual bool IsModeSupported(int width, int height, int bpp) const;
+ virtual bool IsHardware() const { return true; }
+ virtual int ZDepth() const { return zdepth; }
+ virtual DWORD VidMemFree() const;
+ virtual int D3DLevel() const { return 9; }
+ virtual int MaxTexSize() const;
+ virtual int MaxTexAspect() const;
+ virtual int GammaLevel() const { return gamma; }
+
+ virtual bool Capture(Bitmap& bmp);
+ virtual bool GetWindowRect(Rect& r);
+ virtual bool SetWindowRect(const Rect& r);
+ virtual bool SetViewport(int x, int y, int w, int h);
+ virtual bool SetCamera(const Camera* cam);
+ virtual bool SetEnvironment(Bitmap** faces);
+ virtual bool SetAmbient(Color c);
+ virtual bool SetLights(const List<Light>& lights);
+ virtual bool SetProjection(float fov,
+ float znear=1.0f,
+ float zfar=1.0e6f,
+ DWORD type=PROJECTION_PERSPECTIVE);
+ virtual bool SetRenderState(RENDER_STATE state, DWORD value);
+ virtual bool SetBlendType(int blend_type);
+
+ virtual bool DrawPolys(int npolys, Poly* p);
+ virtual bool DrawScreenPolys(int npolys, Poly* p, int blend=0);
+ virtual bool DrawSolid(Solid* s, DWORD blend_modes=0xf);
+ virtual bool DrawShadow(Solid* s, int nverts, Vec3* verts, bool vis=false);
+ virtual bool DrawLines(int nlines, Vec3* v, Color c, int blend=0);
+ virtual bool DrawScreenLines(int nlines, float* v, Color c, int blend=0);
+ virtual bool DrawPoints(VertexSet* v);
+ virtual bool DrawPolyOutline(Poly* p);
+ virtual bool UseMaterial(Material* m);
+
+ virtual bool UseXFont(const char* name, int size, bool b, bool i);
+ virtual bool DrawText(const char* text, int count, const Rect& rect,
+ DWORD format, Color c);
+
+ virtual void PreloadTexture(Bitmap* bmp);
+ virtual void PreloadSurface(Surface* s);
+ virtual void InvalidateCache();
+
+ static void CreateD3DMatrix(D3DMATRIX& result, const Matrix& m, const Point& p);
+ static void CreateD3DMatrix(D3DMATRIX& result, const Matrix& m, const Vec3& v);
+ static void CreateD3DMaterial(D3DMATERIAL9& result, const Material& mtl);
+
+private:
+ bool CreateBuffers();
+ bool DestroyBuffers();
+ bool PopulateScreenVerts(VertexSet* vset);
+ bool PrepareSurface(Surface* s);
+ bool DrawSegment(Segment* s);
+
+ int PrepareMaterial(Material* m);
+ bool SetupPass(int n);
+
+ HWND hwnd;
+ int width;
+ int height;
+ int bpp;
+ int gamma;
+ int zdepth;
+ Color background;
+
+ VideoDX9Enum* dx9enum;
+ VideoSettings video_settings;
+
+ IDirect3D9* d3d;
+ IDirect3DDevice9* d3ddevice;
+ D3DPRESENT_PARAMETERS d3dparams;
+ D3DSURFACE_DESC back_buffer_desc;
+ bool device_lost;
+
+ BYTE* surface;
+
+ DWORD texture_format[3];
+ D3DGAMMARAMP gamma_ramp;
+ double fade;
+
+ Rect rect;
+
+ IDirect3DVertexDeclaration9* vertex_declaration;
+ ID3DXEffect* magic_fx;
+ BYTE* magic_fx_code;
+ int magic_fx_code_len;
+
+ IDirect3DTexture9* current_texture;
+ int current_blend_state;
+ int scene_active;
+ DWORD render_state[RENDER_STATE_MAX];
+ Material* use_material;
+
+ Material* segment_material;
+ int strategy;
+ int passes;
+
+ ID3DXFont* d3dx_font;
+ char font_name[64];
+ int font_size;
+ bool font_bold;
+ bool font_ital;
+
+ Color ambient;
+ int nlights;
+
+ int first_vert;
+ int num_verts;
+
+ VideoDX9VertexBuffer* screen_vbuf;
+ VideoDX9IndexBuffer* screen_ibuf;
+ VideoDX9ScreenVertex* font_verts;
+ WORD* font_indices;
+ int font_nverts;
+
+ VideoDX9ScreenVertex* screen_line_verts;
+ VideoDX9LineVertex* line_verts;
+};
+
+#endif VideoDX9_h
+
diff --git a/Magic2/l3ds.cpp b/Magic2/l3ds.cpp
index 4f334a5..3cbdcfa 100644
--- a/Magic2/l3ds.cpp
+++ b/Magic2/l3ds.cpp
@@ -1,1793 +1,1793 @@
-// copyright (c) 2001 Lev Povalahev
-
-
-#include "stdafx.h"
-
-#include "l3ds.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-//using namespace std;
-
-//-------------------------------------------------------
-// generic stuff
-//-------------------------------------------------------
-
-typedef unsigned long ulong;
-
-#define SEEK_START 1900
-#define SEEK_CURSOR 1901
-
-// common chunks
-// colors
-#define COLOR_F 0x0010
-#define COLOR_24 0x0011
-#define LIN_COLOR_24 0x0012
-#define LIN_COLOR_F 0x0013
-// percentage
-#define INT_PERCENTAGE 0x0030
-#define FLOAT_PERCENTAGE 0x0031
-// ambient light
-#define AMBIENT_LIGHT 0x2100
-
-
-#define MAIN3DS 0x4D4D
-#define EDIT3DS 0x3D3D // this is the start of the editor config
-
-// keyframer chunk ids
-#define KFDATA 0xB000 // the keyframer section
-#define KFHDR 0xB00A
-#define OBJECT_NODE_TAG 0xB002
-#define NODE_HDR 0xB010
-#define PIVOT 0xB013
-#define POS_TRACK_TAG 0xB020
-#define ROT_TRACK_TAG 0xB021
-#define SCL_TRACK_TAG 0xB022
-
-// material entries
-#define MAT_ENTRY 0xAFFF
-#define MAT_NAME 0xA000
-#define MAT_AMBIENT 0xA010
-#define MAT_DIFFUSE 0xA020
-#define MAT_SPECULAR 0xA030
-#define MAT_SHININESS 0xA040
-#define MAT_SHIN2PCT 0xA041
-#define MAT_TRANSPARENCY 0xA050
-#define MAT_SHADING 0xA100
-#define MAT_TWO_SIDE 0xA081
-#define MAT_ADDITIVE 0xA083
-#define MAT_WIRE 0xA085
-#define MAT_FACEMAP 0xA088
-#define MAT_WIRESIZE 0xA087
-#define MAT_DECAL 0xA082
-#define MAT_TEXMAP 0xA200
-#define MAT_MAPNAME 0xA300
-#define MAT_MAP_TILING 0xA351
-#define MAT_MAP_USCALE 0xA354
-#define MAT_MAP_VSCALE 0xA356
-#define MAT_MAP_UOFFSET 0xA358
-#define MAT_MAP_VOFFSET 0xA35A
-#define MAT_MAP_ANG 0xA35C
-#define MAT_TEX2MAP 0xA33A
-#define MAT_OPACMAP 0xA210
-#define MAT_BUMPMAP 0xA230
-#define MAT_SPECMAP 0xA204
-#define MAT_SHINMAP 0xA33C
-#define MAT_REFLMAP 0xA220
-#define MAT_ACUBIC 0xA310
-
-#define EDIT_OBJECT 0x4000
-#define OBJ_TRIMESH 0x4100
-#define OBJ_LIGHT 0x4600
-#define OBJ_CAMERA 0x4700
-#define LIT_OFF 0x4620
-#define LIT_SPOT 0x4610
-#define TRI_VERTEXLIST 0x4110
-#define TRI_VERTEXOPTIONS 0x4111
-
-#define TRI_FACELIST 0x4120
- #define TRI_MAT_GROUP 0x4130
- #define TRI_SMOOTH_GROUP 0x4150
-
-#define TRI_FACEMAPPING 0x4140
-#define TRI_MATRIX 0x4160
-
-#define SPOTLIGHT 0x4610
-
-//----------------------------------
-
-#define MAX_SHARED_TRIS 100
-
-// the error reporting routine
-
-void ErrorMsg(const char *msg)
-{
-
-}
-
-struct LChunk
-{
- unsigned short id;
- uint start;
- uint end;
-};
-
-struct LTri
-{
- unsigned short a;
- unsigned short b;
- unsigned short c;
- ulong smoothingGroups;
- LVector3 normal;
- LVector3 tangent;
- LVector3 binormal;
- uint materialId;
-};
-
-// globals
-
-LColor3 black = {0, 0, 0};
-
-LVector3 zero3 = {0, 0, 0};
-
-LVector4 zero4 = {0, 0, 0, 0};
-
-LMap emptyMap = {0, "", 1, 1, 0, 0, 0};
-
-LVector3 _4to3(const LVector4 &vec)
-{
- LVector3 t;
- t.x = vec.x;
- t.y = vec.y;
- t.z = vec.z;
- return t;
-}
-
-LVector3 AddVectors(const LVector3 &a, const LVector3 &b)
-{
- LVector3 t;
- t.x = a.x+b.x;
- t.y = a.y+b.y;
- t.z = a.z+b.z;
- return t;
-}
-
-LVector3 SubtractVectors(const LVector3 &a, const LVector3 &b)
-{
- LVector3 t;
- t.x = a.x-b.x;
- t.y = a.y-b.y;
- t.z = a.z-b.z;
- return t;
-}
-
-float VectorLength(const LVector3 &vec)
-{
- return (float)sqrt(vec.x*vec.x + vec.y*vec.y+vec.z*vec.z);
-}
-
-LVector3 NormalizeVector(const LVector3 &vec)
-{
- float a = VectorLength(vec);
- if (a == 0)
- return vec;
- float b = 1/a;
- LVector3 v;
- v.x = vec.x*b;
- v.y = vec.y*b;
- v.z = vec.z*b;
- return v;
-}
-
-LVector3 CrossProduct(const LVector3 &a, const LVector3 &b)
-{
- LVector3 v;
- v.x = a.y*b.z - a.z*b.y;
- v.y = a.z*b.x - a.x*b.z;
- v.z = a.x*b.y - a.y*b.x;
- return v;
-}
-
-void LoadIdentityMatrix(LMatrix4 &m)
-{
- for (int i = 0; i < 4; i++)
- for (int j = 0; j < 4; j++)
- m.m[i][j] = (i==j) ? 1.0f : 0.0f;
-}
-
-LVector4 VectorByMatrix(const LMatrix4 &m, const LVector4 &vec)
-{
- LVector4 res;
-
- res.x = m.m[0][0]*vec.x + m.m[1][0]*vec.y + m.m[2][0]*vec.z + m.m[3][0]*vec.w;
- res.y = m.m[0][1]*vec.x + m.m[1][1]*vec.y + m.m[2][1]*vec.z + m.m[3][1]*vec.w;
- res.z = m.m[0][2]*vec.x + m.m[1][2]*vec.y + m.m[2][2]*vec.z + m.m[3][2]*vec.w;
- res.w = m.m[0][3]*vec.x + m.m[1][3]*vec.y + m.m[2][3]*vec.z + m.m[3][3]*vec.w;
-
- if (res.w != 0) {
- float b = 1/res.w;
- res.x *= b;
- res.y *= b;
- res.z *= b;
- res.w = 1;
- }
- else {
- res.w = 1;
- }
-
- return res;
-}
-
-void QuatToMatrix(const LVector4 &quat, LMatrix4 &m)
-{
-
-}
-
-//-------------------------------------------------------
-// LObject implementation
-//-------------------------------------------------------
-
-LObject::LObject()
-{
- m_name = "";//.clear();
-}
-
-LObject::~LObject()
-{
- // nothing here
-}
-
-void LObject::SetName(const std::string& value)
-{
- m_name = value;
-}
-
-const std::string& LObject::GetName()
-{
- return m_name;
-}
-
-bool LObject::IsObject(const std::string &name)
-{
- return (m_name == name);
-}
-
-
-//-------------------------------------------------------
-// LMaterial implementation
-//-------------------------------------------------------
-
-LMaterial::LMaterial()
-: LObject()
-{
- m_id = 0;
- m_texMap1 = emptyMap;
- m_texMap2 = emptyMap;
- m_opacMap = emptyMap;
- m_bumpMap = emptyMap;
- m_reflMap = emptyMap;
- m_specMap = emptyMap;
- m_ambient = black;
- m_diffuse = black;
- m_specular = black;
- m_shading = sGouraud;
- m_shininess = 0;
- m_transparency = 0;
-}
-
-LMaterial::~LMaterial()
-{
-
-}
-
-uint LMaterial::GetID()
-{
- return m_id;
-}
-
-LMap& LMaterial::GetTextureMap1()
-{
- return m_texMap1;
-}
-
-LMap& LMaterial::GetTextureMap2()
-{
- return m_texMap2;
-}
-
-LMap& LMaterial::GetOpacityMap()
-{
- return m_opacMap;
-}
-
-LMap& LMaterial::GetSpecularMap()
-{
- return m_specMap;
-}
-
-LMap& LMaterial::GetBumpMap()
-{
- return m_bumpMap;
-}
-
-LMap& LMaterial::GetReflectionMap()
-{
- return m_reflMap;
-}
-
-LColor3 LMaterial::GetAmbientColor()
-{
- return m_ambient;
-}
-
-LColor3 LMaterial::GetDiffuseColor()
-{
- return m_diffuse;
-}
-
-LColor3 LMaterial::GetSpecularColor()
-{
- return m_specular;
-}
-
-float LMaterial::GetShininess()
-{
- return m_shininess;
-}
-
-float LMaterial::GetTransparency()
-{
- return m_transparency;
-}
-
-LShading LMaterial::GetShadingType()
-{
- return m_shading;
-}
-
-void LMaterial::SetID(uint value)
-{
- m_id = value;
-}
-
-void LMaterial::SetAmbientColor(const LColor3 &color)
-{
- m_ambient = color;
-}
-
-void LMaterial::SetDiffuseColor(const LColor3 &color)
-{
- m_diffuse = color;
-}
-
-void LMaterial::SetSpecularColor(const LColor3 &color)
-{
- m_specular = color;
-}
-
-void LMaterial::SetShininess(float value)
-{
- m_shininess = value;
- if (m_shininess < 0)
- m_shininess = 0;
- if (m_shininess > 1)
- m_shininess = 1;
-}
-
-void LMaterial::SetTransparency(float value)
-{
- m_transparency = value;
- if (m_transparency < 0)
- m_transparency = 0;
- if (m_transparency > 1)
- m_transparency = 1;
-}
-
-void LMaterial::SetShadingType(LShading shading)
-{
- m_shading = shading;
-}
-
-//-------------------------------------------------------
-// LMesh implementation
-//-------------------------------------------------------
-
-LMesh::LMesh()
-: LObject()
-{
- Clear();
-}
-
-LMesh::~LMesh()
-{
- Clear();
-}
-
-void LMesh::Clear()
-{
- m_vertices.clear();
- m_normals.clear();
- m_uv.clear();
- m_tangents.clear();
- m_binormals.clear();
- m_triangles.clear();
- m_tris.clear();
- m_materials.clear();
- LoadIdentityMatrix(m_matrix);
-}
-
-uint LMesh::GetVertexCount()
-{
- return m_vertices.size();
-}
-
-void LMesh::SetVertexArraySize(uint value)
-{
- m_vertices.resize(value);
- m_normals.resize(value);
- m_uv.resize(value);
- m_tangents.resize(value);
- m_binormals.resize(value);
-}
-
-uint LMesh::GetTriangleCount()
-{
- return m_triangles.size();
-}
-
-void LMesh::SetTriangleArraySize(uint value)
-{
- m_triangles.resize(value);
- m_tris.resize(value);
-}
-
-const LVector4& LMesh::GetVertex(uint index)
-{
- return m_vertices[index];
-}
-
-const LVector3& LMesh::GetNormal(uint index)
-{
- return m_normals[index];
-}
-
-const LVector2& LMesh::GetUV(uint index)
-{
- return m_uv[index];
-}
-
-const LVector3& LMesh::GetTangent(uint index)
-{
- return m_tangents[index];
-}
-
-const LVector3& LMesh::GetBinormal(uint index)
-{
- return m_binormals[index];
-}
-
-void LMesh::SetVertex(const LVector4 &vec, uint index)
-{
- if (index >= m_vertices.size())
- return;
- m_vertices[index] = vec;
-}
-
-void LMesh::SetNormal(const LVector3 &vec, uint index)
-{
- if (index >= m_vertices.size())
- return;
- m_normals[index] = vec;
-}
-
-void LMesh::SetUV(const LVector2 &vec, uint index)
-{
- if (index >= m_vertices.size())
- return;
- m_uv[index] = vec;
-}
-
-void LMesh::SetTangent(const LVector3 &vec, uint index)
-{
- if (index >= m_vertices.size())
- return;
- m_tangents[index] = vec;
-}
-
-void LMesh::SetBinormal(const LVector3 &vec, uint index)
-{
- if (index >= m_vertices.size())
- return;
- m_binormals[index] = vec;
-}
-
-const LTriangle& LMesh::GetTriangle(uint index)
-{
- return m_triangles[index];
-}
-
-LTriangle2 LMesh::GetTriangle2(uint index)
-{
- LTriangle2 f;
- LTriangle t = GetTriangle(index);
- f.vertices[0] = GetVertex(t.a);
- f.vertices[1] = GetVertex(t.b);
- f.vertices[2] = GetVertex(t.c);
-
- f.vertexNormals[0] = GetNormal(t.a);
- f.vertexNormals[1] = GetNormal(t.b);
- f.vertexNormals[2] = GetNormal(t.c);
-
- f.textureCoords[0] = GetUV(t.a);
- f.textureCoords[1] = GetUV(t.b);
- f.textureCoords[2] = GetUV(t.c);
-
- LVector3 a, b;
-
- a = SubtractVectors(_4to3(f.vertices[1]), _4to3(f.vertices[0]));
- b = SubtractVectors(_4to3(f.vertices[1]), _4to3(f.vertices[2]));
-
- f.faceNormal = CrossProduct(b, a);
-
- f.faceNormal = NormalizeVector(f.faceNormal);
-
- f.materialId = m_tris[index].materialId;
-
- return f;
-}
-
-LMatrix4 LMesh::GetMatrix()
-{
- return m_matrix;
-}
-
-void LMesh::SetMatrix(LMatrix4 m)
-{
- m_matrix = m;
-}
-
-void LMesh::TransformVertices()
-{
- for (uint i=0; i<m_vertices.size(); i++)
- m_vertices[i] = VectorByMatrix(m_matrix, m_vertices[i]);
-
- LoadIdentityMatrix(m_matrix);
-}
-
-void LMesh::CalcNormals(bool useSmoothingGroups)
-{
- uint i;
- // first calculate the face normals
- for (i=0; i<m_triangles.size(); i++)
- {
- LVector3 a, b;
- a = SubtractVectors(_4to3(m_vertices[m_tris[i].b]), _4to3(m_vertices[m_tris[i].a]));
- b = SubtractVectors(_4to3(m_vertices[m_tris[i].b]), _4to3(m_vertices[m_tris[i].c]));
- m_tris[i].normal = NormalizeVector(CrossProduct(b, a));
- }
-
- std::vector< std::vector<int> > array;
- array.resize(m_vertices.size());
- for (i=0; i<m_triangles.size(); i++)
- {
- uint k = m_tris[i].a;
- array[k].push_back(i);
-
- k = m_tris[i].b;
- array[k].push_back(i);
-
- k = m_tris[i].c;
- array[k].push_back(i);
- }
-
- LVector3 temp;
-
- if (!useSmoothingGroups)
- {
- // now calculate the normals without using smoothing groups
- for (i=0; i<m_vertices.size(); i++)
- {
- temp = zero3;
- int t = array[i].size();
-
- for (int k=0; k<t; k++)
- {
- temp.x += m_tris[array[i][k]].normal.x;
- temp.y += m_tris[array[i][k]].normal.y;
- temp.z += m_tris[array[i][k]].normal.z;
- }
- m_normals[i] = NormalizeVector(temp);
- }
- }
- else
- {
- // now calculate the normals _USING_ smoothing groups
- // I'm assuming a triangle can only belong to one smoothing group at a time!
- std::vector<ulong> smGroups;
- std::vector< std::vector <uint> > smList;
-
- uint loop_size = m_vertices.size();
-
- for (i=0; i<loop_size; i++)
- {
- int t = array[i].size();
-
- if (t == 0)
- continue;
-
- smGroups.clear();
- smList.clear();
- smGroups.push_back(m_tris[array[i][0]].smoothingGroups);
- smList.resize(smGroups.size());
- smList[smGroups.size()-1].push_back(array[i][0]);
-
- // first build a list of smoothing groups for the vertex
- for (int k=0; k<t; k++)
- {
- bool found = false;
- for (uint j=0; j<smGroups.size(); j++)
- {
- if (m_tris[array[i][k]].smoothingGroups == smGroups[j])
- {
- smList[j].push_back(array[i][k]);
- found = true;
- }
- }
- if (!found)
- {
- smGroups.push_back(m_tris[array[i][k]].smoothingGroups);
- smList.resize(smGroups.size());
- smList[smGroups.size()-1].push_back(array[i][k]);
- }
- }
- // now we have the list of faces for the vertex sorted by smoothing groups
-
-
- // now duplicate the vertices so that there's only one smoothing group "per vertex"
- if (smGroups.size() > 1)
- for (uint j=1; j< smGroups.size(); j++)
- {
- m_vertices.push_back(m_vertices[i]);
- m_normals.push_back(m_normals[i]);
- m_uv.push_back(m_uv[i]);
- m_tangents.push_back(m_tangents[i]);
- m_binormals.push_back(m_binormals[i]);
-
- uint t = m_vertices.size()-1;
- for (uint h=0; h<smList[j].size(); h++)
- {
- if (m_tris[smList[j][h]].a == i)
- m_tris[smList[j][h]].a = t;
- if (m_tris[smList[j][h]].b == i)
- m_tris[smList[j][h]].b = t;
- if (m_tris[smList[j][h]].c == i)
- m_tris[smList[j][h]].c = t;
- }
- }
- }
-
- // now rebuild a face list for each vertex, since the old one is invalidated
- for (i=0; i<array.size(); i++)
- array[i].clear();
- array.clear();
- array.resize(m_vertices.size());
- for (i=0; i<m_triangles.size(); i++)
- {
- uint k = m_tris[i].a;
- array[k].push_back(i);
-
- k = m_tris[i].b;
- array[k].push_back(i);
-
- k = m_tris[i].c;
- array[k].push_back(i);
- }
-
- // now compute the normals
- for (i=0; i<m_vertices.size(); i++)
- {
- temp = zero3;
- int t = array[i].size();
-
- for (int k=0; k<t; k++)
- {
- temp.x += m_tris[array[i][k]].normal.x;
- temp.y += m_tris[array[i][k]].normal.y;
- temp.z += m_tris[array[i][k]].normal.z;
- }
- m_normals[i] = NormalizeVector(temp);
- }
-
- }
-
- // copy m_tris to m_triangles
- for (i=0; i<m_triangles.size(); i++)
- {
- m_triangles[i].a = m_tris[i].a;
- m_triangles[i].b = m_tris[i].b;
- m_triangles[i].c = m_tris[i].c;
- }
-
-}
-
-void LMesh::CalcTextureSpace()
-{
- // a understandable description of how to do that can be found here:
- // http://members.rogers.com/deseric/tangentspace.htm
- // first calculate the tangent for each triangle
- LVector3 x_vec,
- y_vec,
- z_vec;
- LVector3 v1, v2;
- for (uint i=0; i<m_triangles.size(); i++)
- {
- v1.x = m_vertices[m_tris[i].b].x - m_vertices[m_tris[i].a].x;
- v1.y = m_uv[m_tris[i].b].x - m_uv[m_tris[i].a].x;
- v1.z = m_uv[m_tris[i].b].y - m_uv[m_tris[i].a].y;
-
- v2.x = m_vertices[m_tris[i].c].x - m_vertices[m_tris[i].a].x;
- v2.y = m_uv[m_tris[i].c].x - m_uv[m_tris[i].a].x;
- v2.z = m_uv[m_tris[i].c].y - m_uv[m_tris[i].a].y;
-
- x_vec = CrossProduct(v1, v2);
-
- v1.x = m_vertices[m_tris[i].b].y - m_vertices[m_tris[i].a].y;
- v1.y = m_uv[m_tris[i].b].x - m_uv[m_tris[i].a].x;
- v1.z = m_uv[m_tris[i].b].y - m_uv[m_tris[i].a].y;
-
- v2.x = m_vertices[m_tris[i].c].y - m_vertices[m_tris[i].a].y;
- v2.y = m_uv[m_tris[i].c].x - m_uv[m_tris[i].a].x;
- v2.z = m_uv[m_tris[i].c].y - m_uv[m_tris[i].a].y;
-
- y_vec = CrossProduct(v1, v2);
-
- v1.x = m_vertices[m_tris[i].b].z - m_vertices[m_tris[i].a].z;
- v1.y = m_uv[m_tris[i].b].x - m_uv[m_tris[i].a].x;
- v1.z = m_uv[m_tris[i].b].y - m_uv[m_tris[i].a].y;
-
- v2.x = m_vertices[m_tris[i].c].z - m_vertices[m_tris[i].a].z;
- v2.y = m_uv[m_tris[i].c].x - m_uv[m_tris[i].a].x;
- v2.z = m_uv[m_tris[i].c].y - m_uv[m_tris[i].a].y;
-
- z_vec = CrossProduct(v1, v2);
-
- m_tris[i].tangent.x = -(x_vec.y/x_vec.x);
- m_tris[i].tangent.y = -(y_vec.y/y_vec.x);
- m_tris[i].tangent.z = -(z_vec.y/z_vec.x);
-
- m_tris[i].binormal.x = -(x_vec.z/x_vec.x);
- m_tris[i].binormal.y = -(y_vec.z/y_vec.x);
- m_tris[i].binormal.z = -(z_vec.z/z_vec.x);
-
- }
-
- // now for each vertex build a list of face that share this vertex
- std::vector< std::vector<int> > array;
- array.resize(m_vertices.size());
- for (int i=0; i<(int)m_triangles.size(); i++)
- {
- uint k = m_tris[i].a;
- array[k].push_back(i);
-
- k = m_tris[i].b;
- array[k].push_back(i);
-
- k = m_tris[i].c;
- array[k].push_back(i);
- }
-
- // now average the tangents and compute the binormals as (tangent X normal)
- for (int i=0; i<(int)m_vertices.size(); i++)
- {
- v1 = zero3;
- v2 = zero3;
- int t = array[i].size();
-
- for (int k=0; k<t; k++)
- {
- v1.x += m_tris[array[i][k]].tangent.x;
- v1.y += m_tris[array[i][k]].tangent.y;
- v1.z += m_tris[array[i][k]].tangent.z;
-
- v2.x += m_tris[array[i][k]].binormal.x;
- v2.y += m_tris[array[i][k]].binormal.y;
- v2.z += m_tris[array[i][k]].binormal.z;
- }
- m_tangents[i] = NormalizeVector(v1);
- //m_binormals[i] = NormalizeVector(v2);
-
- m_binormals[i] = NormalizeVector(CrossProduct(m_tangents[i], m_normals[i]));
- }
-}
-
-void LMesh::Optimize(LOptimizationLevel value)
-{
- switch (value)
- {
- case oNone:
- TransformVertices();
- break;
- case oSimple:
- TransformVertices();
- CalcNormals(false);
- break;
- case oFull:
- TransformVertices();
- CalcNormals(true);
- CalcTextureSpace();
- break;
- }
-}
-
-void LMesh::SetTri(const LTri &tri, uint index)
-{
- if (index >= m_triangles.size())
- return;
- m_tris[index] = tri;
-}
-
-LTri& LMesh::GetTri(uint index)
-{
- return m_tris[index];
-}
-
-uint LMesh::GetMaterial(uint index)
-{
- return m_materials[index];
-}
-
-uint LMesh::AddMaterial(uint id)
-{
- m_materials.push_back(id);
- return m_materials.size()-1;
-}
-
-uint LMesh::GetMaterialCount()
-{
- return m_materials.size();
-}
-
-//-------------------------------------------------------
-// LLight implementation
-//-------------------------------------------------------
-
-LLight::LLight()
-: LObject()
-{
- Clear();
-}
-
-LLight::~LLight()
-{
-
-}
-
-void LLight::Clear()
-{
- m_pos.x = m_pos.y = m_pos.z = 0.0f;
- m_color.r = m_color.g = m_color.b = 0.0f;
- m_spotlight = false;
-}
-
-void LLight::SetPosition(LVector3 vec)
-{
- m_pos = vec;
-}
-
-LVector3 LLight::GetPosition()
-{
- return m_pos;
-}
-
-void LLight::SetColor(LColor3 color)
-{
- m_color = color;
-}
-
-LColor3 LLight::GetColor()
-{
- return m_color;
-}
-
-void LLight::SetSpotlight(bool value)
-{
- m_spotlight = value;
-}
-
-bool LLight::GetSpotlight()
-{
- return m_spotlight;
-}
-
-void LLight::SetTarget(LVector3 target)
-{
- m_target = target;
-}
-
-LVector3 LLight::GetTarget()
-{
- return m_target;
-}
-
-void LLight::SetHotspot(float value)
-{
- m_hotspot = value;
-}
-
-float LLight::GetHotspot()
-{
- return m_hotspot;
-}
-
-void LLight::SetFalloff(float value)
-{
- m_falloff = value;
-}
-
-float LLight::GetFalloff()
-{
- return m_falloff;
-}
-
-//-------------------------------------------------------
-// LImporter implementation
-//-------------------------------------------------------
-
-LImporter::LImporter()
-{
- Clear();
-}
-
-LImporter::~LImporter()
-{
- Clear();
-}
-
-uint LImporter::GetMeshCount()
-{
- return m_meshes.size();
-}
-
-uint LImporter::GetLightCount()
-{
- return m_lights.size();
-}
-
-uint LImporter::GetMaterialCount()
-{
- return m_materials.size();
-}
-
-LMesh& LImporter::GetMesh(uint index)
-{
- return m_meshes[index];
-}
-
-LLight& LImporter::GetLight(uint index)
-{
- return m_lights[index];
-}
-
-LMaterial& LImporter::GetMaterial(uint index)
-{
- return m_materials[index];
-}
-
-LMaterial* LImporter::FindMaterial(const std::string& name)
-{
- for (uint i=0; i<m_materials.size(); i++)
- if (m_materials[i].IsObject(name))
- return &m_materials[i];
- return 0;
-}
-
-LMesh* LImporter::FindMesh(const std::string& name)
-{
- for (uint i=0; i<m_meshes.size(); i++)
- if (m_meshes[i].IsObject(name))
- return &m_meshes[i];
- return 0;
-}
-
-LLight* LImporter::FindLight(const std::string& name)
-{
- for (uint i=0; i<m_lights.size(); i++)
- if (m_lights[i].IsObject(name))
- return &m_lights[i];
- return 0;
-}
-
-void LImporter::Clear()
-{
- m_meshes.clear();
- m_lights.clear();
- m_materials.clear();
- m_optLevel = oFull;
-}
-
-void LImporter::SetOptimizationLevel(LOptimizationLevel value)
-{
- m_optLevel = value;
-}
-
-LOptimizationLevel LImporter::GetOptimizationLevel()
-{
- return m_optLevel;
-}
-
-//-------------------------------------------------------
-// L3DS implementation
-//-------------------------------------------------------
-
-L3DS::L3DS()
-: LImporter()
-{
- m_buffer = 0;
- m_bufferSize = 0;
- m_pos = 0;
- m_eof = false;
-}
-
-L3DS::L3DS(const char *filename)
-: LImporter()
-{
- m_buffer = 0;
- m_bufferSize = 0;
- m_pos = 0;
- m_eof = false;
- LoadFile(filename);
-}
-
-L3DS::~L3DS()
-{
- if (m_bufferSize > 0)
- free(m_buffer);
-}
-
-bool L3DS::LoadFile(const char *filename)
-{
- FILE *f;
- f = fopen(filename, "rb");
- if (f == 0)
- {
- ErrorMsg("L3DS::LoadFile - cannot open file");
- return false;
- }
- fseek(f, 0, SEEK_END);
- m_bufferSize = ftell(f);
- fseek(f, 0, SEEK_SET);
- m_buffer = (unsigned char*) calloc(m_bufferSize, 1);
- if (m_buffer == 0)
- {
- ErrorMsg("L3DS::LoadFile - not enough memory (malloc failed)");
- return false;
- }
- if (fread(m_buffer, m_bufferSize, 1, f) != 1)
- {
- fclose(f);
- free(m_buffer);
- m_bufferSize = 0;
- ErrorMsg("L3DS::LoadFile - error reading from file");
- return false;
- }
- fclose(f);
- Clear();
- bool res = Read3DS();
- free(m_buffer);
- m_buffer = 0;
- m_bufferSize = 0;
- return res;
-}
-
-short L3DS::ReadShort()
-{
- if ((m_buffer!=0) && (m_bufferSize != 0) && ((m_pos+2)<m_bufferSize))
- {
- short *w = (short*)(m_buffer+m_pos);
- short s = *w;//(short)*(m_buffer+m_pos);
- m_pos += 2;
- return s;
- }
- m_eof = true;
- return 0;
-}
-
-int L3DS::ReadInt()
-{
- if ((m_buffer!=0) && (m_bufferSize != 0) && ((m_pos+4)<m_bufferSize))
- {
- int *w = (int*)(m_buffer+m_pos);
- int s = *w;//(int)*(m_buffer+m_pos);
- m_pos += 4;
- return s;
- }
- m_eof = true;
- return 0;
-}
-
-char L3DS::ReadChar()
-{
- if ((m_buffer!=0) && (m_bufferSize != 0) && ((m_pos+1)<m_bufferSize))
- {
- char s = (char)*(m_buffer+m_pos);
- m_pos += 1;
- return s;
- }
- m_eof = true;
- return 0;
-}
-
-float L3DS::ReadFloat()
-{
- if ((m_buffer!=0) && (m_bufferSize != 0) && ((m_pos+4)<m_bufferSize))
- {
- float *w = (float*)(m_buffer+m_pos);
- float s = *w;//(float)*(m_buffer+m_pos);
- m_pos += 4;
- return s;
- }
- m_eof = true;
- return 0.0;
-}
-
-byte L3DS::ReadByte()
-{
- if ((m_buffer!=0) && (m_bufferSize != 0) && ((m_pos+1)<m_bufferSize))
- {
- byte s = (byte)*(m_buffer+m_pos);
- m_pos += 1;
- return s;
- }
- m_eof = true;
- return 0;
-}
-
-int L3DS::ReadASCIIZ(char *buf, int max_count)
-{
- int count;
- if ((m_buffer==0) || (m_bufferSize == 0) || (m_pos>=m_bufferSize))
- {
- count = 0;
- m_eof = true;
- return count;
- }
- count = 0;
- char c = ReadChar();
- while ((c!=0) && (count<max_count-1))
- {
- buf[count] = c;
- count ++;
- c = ReadChar();
- }
- buf[count] = 0;
- return count;
-}
-
-void L3DS::Seek(int offset, int origin)
-{
- if (origin == SEEK_START)
- m_pos = offset;
- if (origin == SEEK_CURSOR)
- m_pos += offset;
- if (m_pos >= m_bufferSize)
- m_pos = m_bufferSize-1;
- m_eof = false;
-}
-
-uint L3DS::Pos()
-{
- return m_pos;
-}
-
-LChunk L3DS::ReadChunk()
-{
- LChunk chunk;
- chunk.id = ReadShort();
- int a = ReadInt();
- chunk.start = Pos();
- chunk.end = chunk.start+a-6;
- return chunk;
-}
-
-bool L3DS::FindChunk(LChunk &target, const LChunk &parent)
-{
- if (Pos() >= parent.end)
- return false;
- LChunk chunk;
- chunk = ReadChunk();
- while (( chunk.id != target.id) && (chunk.end <= parent.end))
- {
- SkipChunk(chunk);
- if (chunk.end >= parent.end)
- break;
- chunk = ReadChunk();
- }
- if (chunk.id == target.id)
- {
- target.start = chunk.start;
- target.end = chunk.end;
- return true;
- }
- return false;
-}
-
-void L3DS::SkipChunk(const LChunk &chunk)
-{
- Seek(chunk.end, SEEK_START);
-}
-
-void L3DS::GotoChunk(const LChunk &chunk)
-{
- Seek(chunk.start, SEEK_START);
-}
-
-LColor3 L3DS::ReadColor(const LChunk &chunk)
-{
- LColor3 col = black;
- GotoChunk(chunk);
- switch (chunk.id)
- {
- case COLOR_F:
- col.r = ReadFloat();
- col.g = ReadFloat();
- col.b = ReadFloat();
- break;
- case COLOR_24:
- col.r = ReadByte()/255.0f;
- col.g = ReadByte()/255.0f;
- col.b = ReadByte()/255.0f;
- break;
- case LIN_COLOR_F:
- col.r = ReadFloat();
- col.g = ReadFloat();
- col.b = ReadFloat();
- break;
- case LIN_COLOR_24:
- col.r = ReadByte()/255.0f;
- col.g = ReadByte()/255.0f;
- col.b = ReadByte()/255.0f;
- break;
- default:
- ErrorMsg("L3DS::ReadColor - error this is not a color chunk");
- }
- return col;
-}
-
-float L3DS::ReadPercentage(const LChunk &chunk)
-{
- GotoChunk(chunk);
- switch (chunk.id)
- {
- case INT_PERCENTAGE:
- return (ReadShort()/100.0f);
- case FLOAT_PERCENTAGE:
- return ReadFloat();
- }
- ErrorMsg("L3DS::ReadPercentage - error, the chunk is not a percentage chunk");
- return 0;
-}
-
-bool L3DS::Read3DS()
-{
- LChunk mainchunk;
- LChunk edit;
- edit.id = EDIT3DS;
- mainchunk = ReadChunk();
- if (mainchunk.id != MAIN3DS)
- {
- ErrorMsg("L3DS::Read3DS - wrong file format");
- return false;
- }
- if (!FindChunk(edit, mainchunk))
- return false;
- LChunk obj;
- LChunk ml;
-
- GotoChunk(edit);
- obj.id = MAT_ENTRY;
- while (FindChunk(obj, edit))
- {
- ReadMaterial(obj);
- SkipChunk(obj);
- }
- GotoChunk(edit);
-
- obj.id = EDIT_OBJECT;
- {
- while (FindChunk(obj, edit))
- {
- ReadASCIIZ(m_objName, 99);
- ml = ReadChunk();
- if (ml.id == OBJ_TRIMESH)
- ReadMesh(ml);
- if (ml.id == OBJ_LIGHT)
- ReadLight(ml);
- SkipChunk(obj);
- }
- }
-
- // read the keyframer data here to find out correct object orientation
-
- LChunk keyframer;
- keyframer.id = KFDATA;
-
- LChunk objtrack;
- objtrack.id = OBJECT_NODE_TAG;
-
- GotoChunk(mainchunk);
- if (FindChunk(keyframer, mainchunk))
- { // keyframer chunk is present
- GotoChunk(keyframer);
- while (FindChunk(objtrack, keyframer))
- {
- ReadKeyframeData(objtrack);
- SkipChunk(objtrack);
- }
- }
-
- for (uint i=0; i<m_meshes.size(); i++) {
- m_meshes[i].Optimize(m_optLevel);
- }
-
- m_pos = 0;
- strcpy(m_objName, "");
- return true;
-}
-
-void L3DS::ReadLight(const LChunk &parent)
-{
- float t;
- LVector3 v;
- LLight light;
- light.SetName(m_objName);
- GotoChunk(parent);
- LChunk chunk = ReadChunk();
- if (chunk.id == OBJ_LIGHT)
- {
- v.x = ReadFloat();
- v.y = ReadFloat();
- v.z = ReadFloat();
- if (chunk.end < parent.end)
- chunk = ReadChunk();
- while (chunk.end <= parent.end)
- {
- switch (chunk.id)
- {
- case COLOR_24:
- case COLOR_F:
- case LIN_COLOR_F:
- case LIN_COLOR_24:
- light.SetColor(ReadColor(chunk));
- break;
- case SPOTLIGHT:
- v.x = ReadFloat();
- v.y = ReadFloat();
- v.z = ReadFloat();
- light.SetTarget(v);
- t = ReadFloat();
- light.SetHotspot(t);
- t = ReadFloat();
- light.SetFalloff(t);
- break;
- default:
- break;
- }
- SkipChunk(chunk);
- if (chunk.end >= parent.end)
- break;
- chunk = ReadChunk();
-
- }
- }
- m_lights.push_back(light);
-}
-
-void L3DS::ReadMesh(const LChunk &parent)
-{
- unsigned short count, i;
- LVector4 p;
- LMatrix4 m;
- LVector2 t;
- p.w = 1.0f;
- LMesh mesh;
- mesh.SetName(m_objName);
- GotoChunk(parent);
- LChunk chunk = ReadChunk();
- while (chunk.end <= parent.end)
- {
- switch (chunk.id)
- {
- case TRI_VERTEXLIST:
- count = ReadShort();
- mesh.SetVertexArraySize(count);
- for (i=0; i < count; i++)
- {
- p.x = ReadFloat();
- p.y = ReadFloat();
- p.z = ReadFloat();
- mesh.SetVertex(p, i);
- }
- break;
- case TRI_FACEMAPPING:
- count = ReadShort();
- if (mesh.GetVertexCount() == 0)
- mesh.SetVertexArraySize(count);
- for (i=0; i < count; i++)
- {
- t.x = ReadFloat();
- t.y = ReadFloat();
- mesh.SetUV(t, i);
- }
- break;
- case TRI_FACELIST:
- ReadFaceList(chunk, mesh);
- break;
- case TRI_MATRIX:
- {
- for (int i = 0; i < 4; i++)
- for (int j = 0; j < 3; j++)
- m.m[i][j] = ReadFloat();
-
- m.m[0][3] = 0.0f;
- m.m[1][3] = 0.0f;
- m.m[2][3] = 0.0f;
- m.m[3][3] = 1.0f;
-
- mesh.SetMatrix(m);
- }
- break;
- default:
- break;
- }
- SkipChunk(chunk);
- if (chunk.end >= parent.end)
- break;
- chunk = ReadChunk();
- }
- m_meshes.push_back(mesh);
-}
-
-void L3DS::ReadFaceList(const LChunk &chunk, LMesh &mesh)
-{
- // variables
- unsigned short count, t;
- uint i;
- LTri tri;
- LChunk ch;
- char str[20];
- //uint mat;
-
- // consistency checks
- if (chunk.id != TRI_FACELIST)
- {
- ErrorMsg("L3DS::ReadFaceList - internal error: wrong chunk passed as parameter");
- return;
- }
- GotoChunk(chunk);
- tri.smoothingGroups = 1;
- // read the number of faces
- count = ReadShort();
- mesh.SetTriangleArraySize(count);
- for (i=0; i<count; i++)
- {
- tri.a = ReadShort();
- tri.b = ReadShort();
- tri.c = ReadShort();
- ReadShort();
- mesh.SetTri(tri, i);
- }
- // now read the optional chunks
- ch = ReadChunk();
- while (ch.end <= chunk.end)
- {
- switch (ch.id)
- {
- case TRI_MAT_GROUP: {
- ReadASCIIZ(str, 20);
- int mat_id = FindMaterial(str)->GetID();
- mesh.AddMaterial(mat_id);
- count = ReadShort();
- for (i=0; i<count; i++) {
- t = ReadShort();
- mesh.GetTri(t).materialId = mat_id;
- }
- }
- break;
-
- case TRI_SMOOTH_GROUP:
- for (i=0; i<mesh.GetTriangleCount(); i++)
- mesh.GetTri(i).smoothingGroups = (ulong) ReadInt();
- break;
- }
- SkipChunk(ch);
- ch = ReadChunk();
- }
-}
-
-void L3DS::ReadMaterial(const LChunk &parent)
-{
- // variables
- LChunk chunk;
- LChunk child;
- char str[30];
- LMaterial mat;
- short sh;
-
- GotoChunk(parent);
-
- chunk = ReadChunk();
- while (chunk.end <= parent.end)
- {
- switch (chunk.id)
- {
- case MAT_NAME:
- ReadASCIIZ(str, 30);
- mat.SetName(str);
- break;
- case MAT_AMBIENT:
- child = ReadChunk();
- mat.SetAmbientColor(ReadColor(child));
- break;
- case MAT_DIFFUSE:
- child = ReadChunk();
- mat.SetDiffuseColor(ReadColor(child));
- break;
- case MAT_SPECULAR:
- child = ReadChunk();
- mat.SetSpecularColor(ReadColor(child));
- break;
- case MAT_SHININESS:
- child = ReadChunk();
- mat.SetShininess(ReadPercentage(child));
- break;
- case MAT_TRANSPARENCY:
- child = ReadChunk();
- mat.SetTransparency(ReadPercentage(child));
- break;
- case MAT_SHADING:
- sh = ReadShort();
- switch (sh)
- {
- case 0:
- mat.SetShadingType(sWireframe);
- break;
- case 1:
- mat.SetShadingType(sFlat);
- break;
- case 2:
- mat.SetShadingType(sGouraud);
- break;
- case 3:
- mat.SetShadingType(sPhong);
- break;
- case 4:
- mat.SetShadingType(sMetal);
- break;
- }
- break;
- case MAT_WIRE:
- mat.SetShadingType(sWireframe);
- break;
- case MAT_TEXMAP:
- ReadMap(chunk, mat.GetTextureMap1());
- break;
- case MAT_TEX2MAP:
- ReadMap(chunk, mat.GetTextureMap2());
- break;
- case MAT_OPACMAP:
- ReadMap(chunk, mat.GetOpacityMap());
- break;
- case MAT_BUMPMAP:
- ReadMap(chunk, mat.GetBumpMap());
- break;
- case MAT_SPECMAP:
- ReadMap(chunk, mat.GetSpecularMap());
- break;
- case MAT_REFLMAP:
- child = ReadChunk();
- mat.GetReflectionMap().strength = ReadPercentage(child);
- SkipChunk(child);
- child = ReadChunk();
- if (child.id != MAT_MAPNAME)
- {
- ErrorMsg("L3DS::ReadMaterial - error, expected chunk not found");
- return;
- }
- ReadASCIIZ(str, 30);
- if (strcmp(str, "") == 0)
- strcpy(mat.GetReflectionMap().mapName, "auto");
- break;
- }
-
- SkipChunk(chunk);
- chunk = ReadChunk();
- }
- m_materials.push_back(mat);
- m_materials[m_materials.size()-1].SetID(m_materials.size()-1);
-}
-
-void L3DS::ReadMap(const LChunk &chunk, LMap& map)
-{
- LChunk child;
- char str[20];
- GotoChunk(chunk);
- child = ReadChunk();
- while (child.end <= chunk.end)
- {
- switch (child.id)
- {
- case INT_PERCENTAGE:
- map.strength = ReadPercentage(child);
- break;
- case MAT_MAPNAME:
- ReadASCIIZ(str, 20);
- strcpy(map.mapName, str);
- break;
- case MAT_MAP_USCALE:
- map.uScale = ReadFloat();
- break;
- case MAT_MAP_VSCALE:
- map.vScale = ReadFloat();
- break;
- case MAT_MAP_UOFFSET:
- map.uOffset = ReadFloat();
- break;
- case MAT_MAP_VOFFSET:
- map.vOffset = ReadFloat();
- break;
- case MAT_MAP_ANG:
- map.angle = ReadFloat();
- break;
- }
- SkipChunk(child);
- child = ReadChunk();
- }
-}
-
-void L3DS::ReadKeyframeData(const LChunk &parent)
-{
- uint frames = 0;
-
- LChunk node_hdr;
- node_hdr.id = NODE_HDR;
-
- char str[20];
- LMesh *mesh;
-
- GotoChunk(parent);
- if (!FindChunk(node_hdr, parent))
- return;
- GotoChunk(node_hdr);
- ReadASCIIZ(str, 19);
- mesh = FindMesh(str);
- if (mesh == 0)
- return;
- GotoChunk(parent);
-
- // read the pivot
- LVector3 pivot = zero3;
-
- LChunk pivotchunk;
- pivotchunk.id = PIVOT;
- if (FindChunk(pivotchunk, parent))
- {
- GotoChunk(pivotchunk);
- pivot.x = ReadFloat();
- pivot.y = ReadFloat();
- pivot.z = ReadFloat();
- }
- GotoChunk(parent);
-
- // read frame 0 from the position track
- LVector3 pos = zero3;
-
- frames = 0;
-
- LChunk poschunk;
- poschunk.id = POS_TRACK_TAG;
- if (FindChunk(poschunk, parent))
- {
- GotoChunk(poschunk);
- // read the trackheader structure
- ReadShort();
- ReadInt();
- ReadInt();
- frames = ReadInt();
- if (frames > 0)
- {
- ReadKeyheader();
- pos.x = ReadFloat();
- pos.y = ReadFloat();
- pos.z = ReadFloat();
- }
- }
- GotoChunk(parent);
-
- // now read the rotation track
- LVector4 rot = zero4;
-
- LChunk rotchunk;
- rotchunk.id = ROT_TRACK_TAG;
-
- frames = 0;
- if (FindChunk(rotchunk, parent))
- {
- GotoChunk(rotchunk);
- // read the trackheader structure
- ReadShort();
- ReadInt();
- ReadInt();
- frames = ReadInt();
- if (frames > 0)
- {
- ReadKeyheader();
- rot.x = ReadFloat();
- rot.y = ReadFloat();
- rot.z = ReadFloat();
- rot.w = ReadFloat();
- }
- }
- GotoChunk(parent);
-
- // now read the scaling chunk
- LVector3 scale;
- scale.x = 1;
- scale.y = 1;
- scale.z = 1;
-
- LChunk scalechunk;
- scalechunk.id = SCL_TRACK_TAG;
-
- frames = 0;
-
- if (FindChunk(scalechunk, parent))
- {
- GotoChunk(scalechunk);
- // read the trackheader structure
- ReadShort();
- ReadInt();
- ReadInt();
- frames = ReadInt();
- if (frames > 0)
- {
- ReadKeyheader();
- scale.x = ReadFloat();
- scale.y = ReadFloat();
- scale.z = ReadFloat();
- }
- }
- GotoChunk(parent);
-
-
-}
-
-long L3DS::ReadKeyheader()
-{
- long frame;
- frame = ReadInt();
- short opts = ReadShort();
- if (opts & 32768) // 32768 is 1000000000000000 binary
- { // tension is present
- ReadFloat();
- }
- if (opts & 16384) // 16384 is 0100000000000000 binary
- { // continuity is present
- ReadFloat();
- }
- if (opts & 8192)
- { // bias info present
- ReadFloat();
- }
- if (opts & 4096)
- { // "ease to" present
- ReadFloat();
- }
- if (opts & 2048)
- { // "ease from" present
- ReadFloat();
- }
- return frame;
+// copyright (c) 2001 Lev Povalahev
+
+
+#include "stdafx.h"
+
+#include "l3ds.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+//using namespace std;
+
+//-------------------------------------------------------
+// generic stuff
+//-------------------------------------------------------
+
+typedef unsigned long ulong;
+
+#define SEEK_START 1900
+#define SEEK_CURSOR 1901
+
+// common chunks
+// colors
+#define COLOR_F 0x0010
+#define COLOR_24 0x0011
+#define LIN_COLOR_24 0x0012
+#define LIN_COLOR_F 0x0013
+// percentage
+#define INT_PERCENTAGE 0x0030
+#define FLOAT_PERCENTAGE 0x0031
+// ambient light
+#define AMBIENT_LIGHT 0x2100
+
+
+#define MAIN3DS 0x4D4D
+#define EDIT3DS 0x3D3D // this is the start of the editor config
+
+// keyframer chunk ids
+#define KFDATA 0xB000 // the keyframer section
+#define KFHDR 0xB00A
+#define OBJECT_NODE_TAG 0xB002
+#define NODE_HDR 0xB010
+#define PIVOT 0xB013
+#define POS_TRACK_TAG 0xB020
+#define ROT_TRACK_TAG 0xB021
+#define SCL_TRACK_TAG 0xB022
+
+// material entries
+#define MAT_ENTRY 0xAFFF
+#define MAT_NAME 0xA000
+#define MAT_AMBIENT 0xA010
+#define MAT_DIFFUSE 0xA020
+#define MAT_SPECULAR 0xA030
+#define MAT_SHININESS 0xA040
+#define MAT_SHIN2PCT 0xA041
+#define MAT_TRANSPARENCY 0xA050
+#define MAT_SHADING 0xA100
+#define MAT_TWO_SIDE 0xA081
+#define MAT_ADDITIVE 0xA083
+#define MAT_WIRE 0xA085
+#define MAT_FACEMAP 0xA088
+#define MAT_WIRESIZE 0xA087
+#define MAT_DECAL 0xA082
+#define MAT_TEXMAP 0xA200
+#define MAT_MAPNAME 0xA300
+#define MAT_MAP_TILING 0xA351
+#define MAT_MAP_USCALE 0xA354
+#define MAT_MAP_VSCALE 0xA356
+#define MAT_MAP_UOFFSET 0xA358
+#define MAT_MAP_VOFFSET 0xA35A
+#define MAT_MAP_ANG 0xA35C
+#define MAT_TEX2MAP 0xA33A
+#define MAT_OPACMAP 0xA210
+#define MAT_BUMPMAP 0xA230
+#define MAT_SPECMAP 0xA204
+#define MAT_SHINMAP 0xA33C
+#define MAT_REFLMAP 0xA220
+#define MAT_ACUBIC 0xA310
+
+#define EDIT_OBJECT 0x4000
+#define OBJ_TRIMESH 0x4100
+#define OBJ_LIGHT 0x4600
+#define OBJ_CAMERA 0x4700
+#define LIT_OFF 0x4620
+#define LIT_SPOT 0x4610
+#define TRI_VERTEXLIST 0x4110
+#define TRI_VERTEXOPTIONS 0x4111
+
+#define TRI_FACELIST 0x4120
+ #define TRI_MAT_GROUP 0x4130
+ #define TRI_SMOOTH_GROUP 0x4150
+
+#define TRI_FACEMAPPING 0x4140
+#define TRI_MATRIX 0x4160
+
+#define SPOTLIGHT 0x4610
+
+//----------------------------------
+
+#define MAX_SHARED_TRIS 100
+
+// the error reporting routine
+
+void ErrorMsg(const char *msg)
+{
+
+}
+
+struct LChunk
+{
+ unsigned short id;
+ uint start;
+ uint end;
+};
+
+struct LTri
+{
+ unsigned short a;
+ unsigned short b;
+ unsigned short c;
+ ulong smoothingGroups;
+ LVector3 normal;
+ LVector3 tangent;
+ LVector3 binormal;
+ uint materialId;
+};
+
+// globals
+
+LColor3 black = {0, 0, 0};
+
+LVector3 zero3 = {0, 0, 0};
+
+LVector4 zero4 = {0, 0, 0, 0};
+
+LMap emptyMap = {0, "", 1, 1, 0, 0, 0};
+
+LVector3 _4to3(const LVector4 &vec)
+{
+ LVector3 t;
+ t.x = vec.x;
+ t.y = vec.y;
+ t.z = vec.z;
+ return t;
+}
+
+LVector3 AddVectors(const LVector3 &a, const LVector3 &b)
+{
+ LVector3 t;
+ t.x = a.x+b.x;
+ t.y = a.y+b.y;
+ t.z = a.z+b.z;
+ return t;
+}
+
+LVector3 SubtractVectors(const LVector3 &a, const LVector3 &b)
+{
+ LVector3 t;
+ t.x = a.x-b.x;
+ t.y = a.y-b.y;
+ t.z = a.z-b.z;
+ return t;
+}
+
+float VectorLength(const LVector3 &vec)
+{
+ return (float)sqrt(vec.x*vec.x + vec.y*vec.y+vec.z*vec.z);
+}
+
+LVector3 NormalizeVector(const LVector3 &vec)
+{
+ float a = VectorLength(vec);
+ if (a == 0)
+ return vec;
+ float b = 1/a;
+ LVector3 v;
+ v.x = vec.x*b;
+ v.y = vec.y*b;
+ v.z = vec.z*b;
+ return v;
+}
+
+LVector3 CrossProduct(const LVector3 &a, const LVector3 &b)
+{
+ LVector3 v;
+ v.x = a.y*b.z - a.z*b.y;
+ v.y = a.z*b.x - a.x*b.z;
+ v.z = a.x*b.y - a.y*b.x;
+ return v;
+}
+
+void LoadIdentityMatrix(LMatrix4 &m)
+{
+ for (int i = 0; i < 4; i++)
+ for (int j = 0; j < 4; j++)
+ m.m[i][j] = (i==j) ? 1.0f : 0.0f;
+}
+
+LVector4 VectorByMatrix(const LMatrix4 &m, const LVector4 &vec)
+{
+ LVector4 res;
+
+ res.x = m.m[0][0]*vec.x + m.m[1][0]*vec.y + m.m[2][0]*vec.z + m.m[3][0]*vec.w;
+ res.y = m.m[0][1]*vec.x + m.m[1][1]*vec.y + m.m[2][1]*vec.z + m.m[3][1]*vec.w;
+ res.z = m.m[0][2]*vec.x + m.m[1][2]*vec.y + m.m[2][2]*vec.z + m.m[3][2]*vec.w;
+ res.w = m.m[0][3]*vec.x + m.m[1][3]*vec.y + m.m[2][3]*vec.z + m.m[3][3]*vec.w;
+
+ if (res.w != 0) {
+ float b = 1/res.w;
+ res.x *= b;
+ res.y *= b;
+ res.z *= b;
+ res.w = 1;
+ }
+ else {
+ res.w = 1;
+ }
+
+ return res;
+}
+
+void QuatToMatrix(const LVector4 &quat, LMatrix4 &m)
+{
+
+}
+
+//-------------------------------------------------------
+// LObject implementation
+//-------------------------------------------------------
+
+LObject::LObject()
+{
+ m_name = "";//.clear();
+}
+
+LObject::~LObject()
+{
+ // nothing here
+}
+
+void LObject::SetName(const std::string& value)
+{
+ m_name = value;
+}
+
+const std::string& LObject::GetName()
+{
+ return m_name;
+}
+
+bool LObject::IsObject(const std::string &name)
+{
+ return (m_name == name);
+}
+
+
+//-------------------------------------------------------
+// LMaterial implementation
+//-------------------------------------------------------
+
+LMaterial::LMaterial()
+: LObject()
+{
+ m_id = 0;
+ m_texMap1 = emptyMap;
+ m_texMap2 = emptyMap;
+ m_opacMap = emptyMap;
+ m_bumpMap = emptyMap;
+ m_reflMap = emptyMap;
+ m_specMap = emptyMap;
+ m_ambient = black;
+ m_diffuse = black;
+ m_specular = black;
+ m_shading = sGouraud;
+ m_shininess = 0;
+ m_transparency = 0;
+}
+
+LMaterial::~LMaterial()
+{
+
+}
+
+uint LMaterial::GetID()
+{
+ return m_id;
+}
+
+LMap& LMaterial::GetTextureMap1()
+{
+ return m_texMap1;
+}
+
+LMap& LMaterial::GetTextureMap2()
+{
+ return m_texMap2;
+}
+
+LMap& LMaterial::GetOpacityMap()
+{
+ return m_opacMap;
+}
+
+LMap& LMaterial::GetSpecularMap()
+{
+ return m_specMap;
+}
+
+LMap& LMaterial::GetBumpMap()
+{
+ return m_bumpMap;
+}
+
+LMap& LMaterial::GetReflectionMap()
+{
+ return m_reflMap;
+}
+
+LColor3 LMaterial::GetAmbientColor()
+{
+ return m_ambient;
+}
+
+LColor3 LMaterial::GetDiffuseColor()
+{
+ return m_diffuse;
+}
+
+LColor3 LMaterial::GetSpecularColor()
+{
+ return m_specular;
+}
+
+float LMaterial::GetShininess()
+{
+ return m_shininess;
+}
+
+float LMaterial::GetTransparency()
+{
+ return m_transparency;
+}
+
+LShading LMaterial::GetShadingType()
+{
+ return m_shading;
+}
+
+void LMaterial::SetID(uint value)
+{
+ m_id = value;
+}
+
+void LMaterial::SetAmbientColor(const LColor3 &color)
+{
+ m_ambient = color;
+}
+
+void LMaterial::SetDiffuseColor(const LColor3 &color)
+{
+ m_diffuse = color;
+}
+
+void LMaterial::SetSpecularColor(const LColor3 &color)
+{
+ m_specular = color;
+}
+
+void LMaterial::SetShininess(float value)
+{
+ m_shininess = value;
+ if (m_shininess < 0)
+ m_shininess = 0;
+ if (m_shininess > 1)
+ m_shininess = 1;
+}
+
+void LMaterial::SetTransparency(float value)
+{
+ m_transparency = value;
+ if (m_transparency < 0)
+ m_transparency = 0;
+ if (m_transparency > 1)
+ m_transparency = 1;
+}
+
+void LMaterial::SetShadingType(LShading shading)
+{
+ m_shading = shading;
+}
+
+//-------------------------------------------------------
+// LMesh implementation
+//-------------------------------------------------------
+
+LMesh::LMesh()
+: LObject()
+{
+ Clear();
+}
+
+LMesh::~LMesh()
+{
+ Clear();
+}
+
+void LMesh::Clear()
+{
+ m_vertices.clear();
+ m_normals.clear();
+ m_uv.clear();
+ m_tangents.clear();
+ m_binormals.clear();
+ m_triangles.clear();
+ m_tris.clear();
+ m_materials.clear();
+ LoadIdentityMatrix(m_matrix);
+}
+
+uint LMesh::GetVertexCount()
+{
+ return m_vertices.size();
+}
+
+void LMesh::SetVertexArraySize(uint value)
+{
+ m_vertices.resize(value);
+ m_normals.resize(value);
+ m_uv.resize(value);
+ m_tangents.resize(value);
+ m_binormals.resize(value);
+}
+
+uint LMesh::GetTriangleCount()
+{
+ return m_triangles.size();
+}
+
+void LMesh::SetTriangleArraySize(uint value)
+{
+ m_triangles.resize(value);
+ m_tris.resize(value);
+}
+
+const LVector4& LMesh::GetVertex(uint index)
+{
+ return m_vertices[index];
+}
+
+const LVector3& LMesh::GetNormal(uint index)
+{
+ return m_normals[index];
+}
+
+const LVector2& LMesh::GetUV(uint index)
+{
+ return m_uv[index];
+}
+
+const LVector3& LMesh::GetTangent(uint index)
+{
+ return m_tangents[index];
+}
+
+const LVector3& LMesh::GetBinormal(uint index)
+{
+ return m_binormals[index];
+}
+
+void LMesh::SetVertex(const LVector4 &vec, uint index)
+{
+ if (index >= m_vertices.size())
+ return;
+ m_vertices[index] = vec;
+}
+
+void LMesh::SetNormal(const LVector3 &vec, uint index)
+{
+ if (index >= m_vertices.size())
+ return;
+ m_normals[index] = vec;
+}
+
+void LMesh::SetUV(const LVector2 &vec, uint index)
+{
+ if (index >= m_vertices.size())
+ return;
+ m_uv[index] = vec;
+}
+
+void LMesh::SetTangent(const LVector3 &vec, uint index)
+{
+ if (index >= m_vertices.size())
+ return;
+ m_tangents[index] = vec;
+}
+
+void LMesh::SetBinormal(const LVector3 &vec, uint index)
+{
+ if (index >= m_vertices.size())
+ return;
+ m_binormals[index] = vec;
+}
+
+const LTriangle& LMesh::GetTriangle(uint index)
+{
+ return m_triangles[index];
+}
+
+LTriangle2 LMesh::GetTriangle2(uint index)
+{
+ LTriangle2 f;
+ LTriangle t = GetTriangle(index);
+ f.vertices[0] = GetVertex(t.a);
+ f.vertices[1] = GetVertex(t.b);
+ f.vertices[2] = GetVertex(t.c);
+
+ f.vertexNormals[0] = GetNormal(t.a);
+ f.vertexNormals[1] = GetNormal(t.b);
+ f.vertexNormals[2] = GetNormal(t.c);
+
+ f.textureCoords[0] = GetUV(t.a);
+ f.textureCoords[1] = GetUV(t.b);
+ f.textureCoords[2] = GetUV(t.c);
+
+ LVector3 a, b;
+
+ a = SubtractVectors(_4to3(f.vertices[1]), _4to3(f.vertices[0]));
+ b = SubtractVectors(_4to3(f.vertices[1]), _4to3(f.vertices[2]));
+
+ f.faceNormal = CrossProduct(b, a);
+
+ f.faceNormal = NormalizeVector(f.faceNormal);
+
+ f.materialId = m_tris[index].materialId;
+
+ return f;
+}
+
+LMatrix4 LMesh::GetMatrix()
+{
+ return m_matrix;
+}
+
+void LMesh::SetMatrix(LMatrix4 m)
+{
+ m_matrix = m;
+}
+
+void LMesh::TransformVertices()
+{
+ for (uint i=0; i<m_vertices.size(); i++)
+ m_vertices[i] = VectorByMatrix(m_matrix, m_vertices[i]);
+
+ LoadIdentityMatrix(m_matrix);
+}
+
+void LMesh::CalcNormals(bool useSmoothingGroups)
+{
+ uint i;
+ // first calculate the face normals
+ for (i=0; i<m_triangles.size(); i++)
+ {
+ LVector3 a, b;
+ a = SubtractVectors(_4to3(m_vertices[m_tris[i].b]), _4to3(m_vertices[m_tris[i].a]));
+ b = SubtractVectors(_4to3(m_vertices[m_tris[i].b]), _4to3(m_vertices[m_tris[i].c]));
+ m_tris[i].normal = NormalizeVector(CrossProduct(b, a));
+ }
+
+ std::vector< std::vector<int> > array;
+ array.resize(m_vertices.size());
+ for (i=0; i<m_triangles.size(); i++)
+ {
+ uint k = m_tris[i].a;
+ array[k].push_back(i);
+
+ k = m_tris[i].b;
+ array[k].push_back(i);
+
+ k = m_tris[i].c;
+ array[k].push_back(i);
+ }
+
+ LVector3 temp;
+
+ if (!useSmoothingGroups)
+ {
+ // now calculate the normals without using smoothing groups
+ for (i=0; i<m_vertices.size(); i++)
+ {
+ temp = zero3;
+ int t = array[i].size();
+
+ for (int k=0; k<t; k++)
+ {
+ temp.x += m_tris[array[i][k]].normal.x;
+ temp.y += m_tris[array[i][k]].normal.y;
+ temp.z += m_tris[array[i][k]].normal.z;
+ }
+ m_normals[i] = NormalizeVector(temp);
+ }
+ }
+ else
+ {
+ // now calculate the normals _USING_ smoothing groups
+ // I'm assuming a triangle can only belong to one smoothing group at a time!
+ std::vector<ulong> smGroups;
+ std::vector< std::vector <uint> > smList;
+
+ uint loop_size = m_vertices.size();
+
+ for (i=0; i<loop_size; i++)
+ {
+ int t = array[i].size();
+
+ if (t == 0)
+ continue;
+
+ smGroups.clear();
+ smList.clear();
+ smGroups.push_back(m_tris[array[i][0]].smoothingGroups);
+ smList.resize(smGroups.size());
+ smList[smGroups.size()-1].push_back(array[i][0]);
+
+ // first build a list of smoothing groups for the vertex
+ for (int k=0; k<t; k++)
+ {
+ bool found = false;
+ for (uint j=0; j<smGroups.size(); j++)
+ {
+ if (m_tris[array[i][k]].smoothingGroups == smGroups[j])
+ {
+ smList[j].push_back(array[i][k]);
+ found = true;
+ }
+ }
+ if (!found)
+ {
+ smGroups.push_back(m_tris[array[i][k]].smoothingGroups);
+ smList.resize(smGroups.size());
+ smList[smGroups.size()-1].push_back(array[i][k]);
+ }
+ }
+ // now we have the list of faces for the vertex sorted by smoothing groups
+
+
+ // now duplicate the vertices so that there's only one smoothing group "per vertex"
+ if (smGroups.size() > 1)
+ for (uint j=1; j< smGroups.size(); j++)
+ {
+ m_vertices.push_back(m_vertices[i]);
+ m_normals.push_back(m_normals[i]);
+ m_uv.push_back(m_uv[i]);
+ m_tangents.push_back(m_tangents[i]);
+ m_binormals.push_back(m_binormals[i]);
+
+ uint t = m_vertices.size()-1;
+ for (uint h=0; h<smList[j].size(); h++)
+ {
+ if (m_tris[smList[j][h]].a == i)
+ m_tris[smList[j][h]].a = t;
+ if (m_tris[smList[j][h]].b == i)
+ m_tris[smList[j][h]].b = t;
+ if (m_tris[smList[j][h]].c == i)
+ m_tris[smList[j][h]].c = t;
+ }
+ }
+ }
+
+ // now rebuild a face list for each vertex, since the old one is invalidated
+ for (i=0; i<array.size(); i++)
+ array[i].clear();
+ array.clear();
+ array.resize(m_vertices.size());
+ for (i=0; i<m_triangles.size(); i++)
+ {
+ uint k = m_tris[i].a;
+ array[k].push_back(i);
+
+ k = m_tris[i].b;
+ array[k].push_back(i);
+
+ k = m_tris[i].c;
+ array[k].push_back(i);
+ }
+
+ // now compute the normals
+ for (i=0; i<m_vertices.size(); i++)
+ {
+ temp = zero3;
+ int t = array[i].size();
+
+ for (int k=0; k<t; k++)
+ {
+ temp.x += m_tris[array[i][k]].normal.x;
+ temp.y += m_tris[array[i][k]].normal.y;
+ temp.z += m_tris[array[i][k]].normal.z;
+ }
+ m_normals[i] = NormalizeVector(temp);
+ }
+
+ }
+
+ // copy m_tris to m_triangles
+ for (i=0; i<m_triangles.size(); i++)
+ {
+ m_triangles[i].a = m_tris[i].a;
+ m_triangles[i].b = m_tris[i].b;
+ m_triangles[i].c = m_tris[i].c;
+ }
+
+}
+
+void LMesh::CalcTextureSpace()
+{
+ // a understandable description of how to do that can be found here:
+ // http://members.rogers.com/deseric/tangentspace.htm
+ // first calculate the tangent for each triangle
+ LVector3 x_vec,
+ y_vec,
+ z_vec;
+ LVector3 v1, v2;
+ for (uint i=0; i<m_triangles.size(); i++)
+ {
+ v1.x = m_vertices[m_tris[i].b].x - m_vertices[m_tris[i].a].x;
+ v1.y = m_uv[m_tris[i].b].x - m_uv[m_tris[i].a].x;
+ v1.z = m_uv[m_tris[i].b].y - m_uv[m_tris[i].a].y;
+
+ v2.x = m_vertices[m_tris[i].c].x - m_vertices[m_tris[i].a].x;
+ v2.y = m_uv[m_tris[i].c].x - m_uv[m_tris[i].a].x;
+ v2.z = m_uv[m_tris[i].c].y - m_uv[m_tris[i].a].y;
+
+ x_vec = CrossProduct(v1, v2);
+
+ v1.x = m_vertices[m_tris[i].b].y - m_vertices[m_tris[i].a].y;
+ v1.y = m_uv[m_tris[i].b].x - m_uv[m_tris[i].a].x;
+ v1.z = m_uv[m_tris[i].b].y - m_uv[m_tris[i].a].y;
+
+ v2.x = m_vertices[m_tris[i].c].y - m_vertices[m_tris[i].a].y;
+ v2.y = m_uv[m_tris[i].c].x - m_uv[m_tris[i].a].x;
+ v2.z = m_uv[m_tris[i].c].y - m_uv[m_tris[i].a].y;
+
+ y_vec = CrossProduct(v1, v2);
+
+ v1.x = m_vertices[m_tris[i].b].z - m_vertices[m_tris[i].a].z;
+ v1.y = m_uv[m_tris[i].b].x - m_uv[m_tris[i].a].x;
+ v1.z = m_uv[m_tris[i].b].y - m_uv[m_tris[i].a].y;
+
+ v2.x = m_vertices[m_tris[i].c].z - m_vertices[m_tris[i].a].z;
+ v2.y = m_uv[m_tris[i].c].x - m_uv[m_tris[i].a].x;
+ v2.z = m_uv[m_tris[i].c].y - m_uv[m_tris[i].a].y;
+
+ z_vec = CrossProduct(v1, v2);
+
+ m_tris[i].tangent.x = -(x_vec.y/x_vec.x);
+ m_tris[i].tangent.y = -(y_vec.y/y_vec.x);
+ m_tris[i].tangent.z = -(z_vec.y/z_vec.x);
+
+ m_tris[i].binormal.x = -(x_vec.z/x_vec.x);
+ m_tris[i].binormal.y = -(y_vec.z/y_vec.x);
+ m_tris[i].binormal.z = -(z_vec.z/z_vec.x);
+
+ }
+
+ // now for each vertex build a list of face that share this vertex
+ std::vector< std::vector<int> > array;
+ array.resize(m_vertices.size());
+ for (int i=0; i<(int)m_triangles.size(); i++)
+ {
+ uint k = m_tris[i].a;
+ array[k].push_back(i);
+
+ k = m_tris[i].b;
+ array[k].push_back(i);
+
+ k = m_tris[i].c;
+ array[k].push_back(i);
+ }
+
+ // now average the tangents and compute the binormals as (tangent X normal)
+ for (int i=0; i<(int)m_vertices.size(); i++)
+ {
+ v1 = zero3;
+ v2 = zero3;
+ int t = array[i].size();
+
+ for (int k=0; k<t; k++)
+ {
+ v1.x += m_tris[array[i][k]].tangent.x;
+ v1.y += m_tris[array[i][k]].tangent.y;
+ v1.z += m_tris[array[i][k]].tangent.z;
+
+ v2.x += m_tris[array[i][k]].binormal.x;
+ v2.y += m_tris[array[i][k]].binormal.y;
+ v2.z += m_tris[array[i][k]].binormal.z;
+ }
+ m_tangents[i] = NormalizeVector(v1);
+ //m_binormals[i] = NormalizeVector(v2);
+
+ m_binormals[i] = NormalizeVector(CrossProduct(m_tangents[i], m_normals[i]));
+ }
+}
+
+void LMesh::Optimize(LOptimizationLevel value)
+{
+ switch (value)
+ {
+ case oNone:
+ TransformVertices();
+ break;
+ case oSimple:
+ TransformVertices();
+ CalcNormals(false);
+ break;
+ case oFull:
+ TransformVertices();
+ CalcNormals(true);
+ CalcTextureSpace();
+ break;
+ }
+}
+
+void LMesh::SetTri(const LTri &tri, uint index)
+{
+ if (index >= m_triangles.size())
+ return;
+ m_tris[index] = tri;
+}
+
+LTri& LMesh::GetTri(uint index)
+{
+ return m_tris[index];
+}
+
+uint LMesh::GetMaterial(uint index)
+{
+ return m_materials[index];
+}
+
+uint LMesh::AddMaterial(uint id)
+{
+ m_materials.push_back(id);
+ return m_materials.size()-1;
+}
+
+uint LMesh::GetMaterialCount()
+{
+ return m_materials.size();
+}
+
+//-------------------------------------------------------
+// LLight implementation
+//-------------------------------------------------------
+
+LLight::LLight()
+: LObject()
+{
+ Clear();
+}
+
+LLight::~LLight()
+{
+
+}
+
+void LLight::Clear()
+{
+ m_pos.x = m_pos.y = m_pos.z = 0.0f;
+ m_color.r = m_color.g = m_color.b = 0.0f;
+ m_spotlight = false;
+}
+
+void LLight::SetPosition(LVector3 vec)
+{
+ m_pos = vec;
+}
+
+LVector3 LLight::GetPosition()
+{
+ return m_pos;
+}
+
+void LLight::SetColor(LColor3 color)
+{
+ m_color = color;
+}
+
+LColor3 LLight::GetColor()
+{
+ return m_color;
+}
+
+void LLight::SetSpotlight(bool value)
+{
+ m_spotlight = value;
+}
+
+bool LLight::GetSpotlight()
+{
+ return m_spotlight;
+}
+
+void LLight::SetTarget(LVector3 target)
+{
+ m_target = target;
+}
+
+LVector3 LLight::GetTarget()
+{
+ return m_target;
+}
+
+void LLight::SetHotspot(float value)
+{
+ m_hotspot = value;
+}
+
+float LLight::GetHotspot()
+{
+ return m_hotspot;
+}
+
+void LLight::SetFalloff(float value)
+{
+ m_falloff = value;
+}
+
+float LLight::GetFalloff()
+{
+ return m_falloff;
+}
+
+//-------------------------------------------------------
+// LImporter implementation
+//-------------------------------------------------------
+
+LImporter::LImporter()
+{
+ Clear();
+}
+
+LImporter::~LImporter()
+{
+ Clear();
+}
+
+uint LImporter::GetMeshCount()
+{
+ return m_meshes.size();
+}
+
+uint LImporter::GetLightCount()
+{
+ return m_lights.size();
+}
+
+uint LImporter::GetMaterialCount()
+{
+ return m_materials.size();
+}
+
+LMesh& LImporter::GetMesh(uint index)
+{
+ return m_meshes[index];
+}
+
+LLight& LImporter::GetLight(uint index)
+{
+ return m_lights[index];
+}
+
+LMaterial& LImporter::GetMaterial(uint index)
+{
+ return m_materials[index];
+}
+
+LMaterial* LImporter::FindMaterial(const std::string& name)
+{
+ for (uint i=0; i<m_materials.size(); i++)
+ if (m_materials[i].IsObject(name))
+ return &m_materials[i];
+ return 0;
+}
+
+LMesh* LImporter::FindMesh(const std::string& name)
+{
+ for (uint i=0; i<m_meshes.size(); i++)
+ if (m_meshes[i].IsObject(name))
+ return &m_meshes[i];
+ return 0;
+}
+
+LLight* LImporter::FindLight(const std::string& name)
+{
+ for (uint i=0; i<m_lights.size(); i++)
+ if (m_lights[i].IsObject(name))
+ return &m_lights[i];
+ return 0;
+}
+
+void LImporter::Clear()
+{
+ m_meshes.clear();
+ m_lights.clear();
+ m_materials.clear();
+ m_optLevel = oFull;
+}
+
+void LImporter::SetOptimizationLevel(LOptimizationLevel value)
+{
+ m_optLevel = value;
+}
+
+LOptimizationLevel LImporter::GetOptimizationLevel()
+{
+ return m_optLevel;
+}
+
+//-------------------------------------------------------
+// L3DS implementation
+//-------------------------------------------------------
+
+L3DS::L3DS()
+: LImporter()
+{
+ m_buffer = 0;
+ m_bufferSize = 0;
+ m_pos = 0;
+ m_eof = false;
+}
+
+L3DS::L3DS(const char *filename)
+: LImporter()
+{
+ m_buffer = 0;
+ m_bufferSize = 0;
+ m_pos = 0;
+ m_eof = false;
+ LoadFile(filename);
+}
+
+L3DS::~L3DS()
+{
+ if (m_bufferSize > 0)
+ free(m_buffer);
+}
+
+bool L3DS::LoadFile(const char *filename)
+{
+ FILE *f;
+ f = fopen(filename, "rb");
+ if (f == 0)
+ {
+ ErrorMsg("L3DS::LoadFile - cannot open file");
+ return false;
+ }
+ fseek(f, 0, SEEK_END);
+ m_bufferSize = ftell(f);
+ fseek(f, 0, SEEK_SET);
+ m_buffer = (unsigned char*) calloc(m_bufferSize, 1);
+ if (m_buffer == 0)
+ {
+ ErrorMsg("L3DS::LoadFile - not enough memory (malloc failed)");
+ return false;
+ }
+ if (fread(m_buffer, m_bufferSize, 1, f) != 1)
+ {
+ fclose(f);
+ free(m_buffer);
+ m_bufferSize = 0;
+ ErrorMsg("L3DS::LoadFile - error reading from file");
+ return false;
+ }
+ fclose(f);
+ Clear();
+ bool res = Read3DS();
+ free(m_buffer);
+ m_buffer = 0;
+ m_bufferSize = 0;
+ return res;
+}
+
+short L3DS::ReadShort()
+{
+ if ((m_buffer!=0) && (m_bufferSize != 0) && ((m_pos+2)<m_bufferSize))
+ {
+ short *w = (short*)(m_buffer+m_pos);
+ short s = *w;//(short)*(m_buffer+m_pos);
+ m_pos += 2;
+ return s;
+ }
+ m_eof = true;
+ return 0;
+}
+
+int L3DS::ReadInt()
+{
+ if ((m_buffer!=0) && (m_bufferSize != 0) && ((m_pos+4)<m_bufferSize))
+ {
+ int *w = (int*)(m_buffer+m_pos);
+ int s = *w;//(int)*(m_buffer+m_pos);
+ m_pos += 4;
+ return s;
+ }
+ m_eof = true;
+ return 0;
+}
+
+char L3DS::ReadChar()
+{
+ if ((m_buffer!=0) && (m_bufferSize != 0) && ((m_pos+1)<m_bufferSize))
+ {
+ char s = (char)*(m_buffer+m_pos);
+ m_pos += 1;
+ return s;
+ }
+ m_eof = true;
+ return 0;
+}
+
+float L3DS::ReadFloat()
+{
+ if ((m_buffer!=0) && (m_bufferSize != 0) && ((m_pos+4)<m_bufferSize))
+ {
+ float *w = (float*)(m_buffer+m_pos);
+ float s = *w;//(float)*(m_buffer+m_pos);
+ m_pos += 4;
+ return s;
+ }
+ m_eof = true;
+ return 0.0;
+}
+
+byte L3DS::ReadByte()
+{
+ if ((m_buffer!=0) && (m_bufferSize != 0) && ((m_pos+1)<m_bufferSize))
+ {
+ byte s = (byte)*(m_buffer+m_pos);
+ m_pos += 1;
+ return s;
+ }
+ m_eof = true;
+ return 0;
+}
+
+int L3DS::ReadASCIIZ(char *buf, int max_count)
+{
+ int count;
+ if ((m_buffer==0) || (m_bufferSize == 0) || (m_pos>=m_bufferSize))
+ {
+ count = 0;
+ m_eof = true;
+ return count;
+ }
+ count = 0;
+ char c = ReadChar();
+ while ((c!=0) && (count<max_count-1))
+ {
+ buf[count] = c;
+ count ++;
+ c = ReadChar();
+ }
+ buf[count] = 0;
+ return count;
+}
+
+void L3DS::Seek(int offset, int origin)
+{
+ if (origin == SEEK_START)
+ m_pos = offset;
+ if (origin == SEEK_CURSOR)
+ m_pos += offset;
+ if (m_pos >= m_bufferSize)
+ m_pos = m_bufferSize-1;
+ m_eof = false;
+}
+
+uint L3DS::Pos()
+{
+ return m_pos;
+}
+
+LChunk L3DS::ReadChunk()
+{
+ LChunk chunk;
+ chunk.id = ReadShort();
+ int a = ReadInt();
+ chunk.start = Pos();
+ chunk.end = chunk.start+a-6;
+ return chunk;
+}
+
+bool L3DS::FindChunk(LChunk &target, const LChunk &parent)
+{
+ if (Pos() >= parent.end)
+ return false;
+ LChunk chunk;
+ chunk = ReadChunk();
+ while (( chunk.id != target.id) && (chunk.end <= parent.end))
+ {
+ SkipChunk(chunk);
+ if (chunk.end >= parent.end)
+ break;
+ chunk = ReadChunk();
+ }
+ if (chunk.id == target.id)
+ {
+ target.start = chunk.start;
+ target.end = chunk.end;
+ return true;
+ }
+ return false;
+}
+
+void L3DS::SkipChunk(const LChunk &chunk)
+{
+ Seek(chunk.end, SEEK_START);
+}
+
+void L3DS::GotoChunk(const LChunk &chunk)
+{
+ Seek(chunk.start, SEEK_START);
+}
+
+LColor3 L3DS::ReadColor(const LChunk &chunk)
+{
+ LColor3 col = black;
+ GotoChunk(chunk);
+ switch (chunk.id)
+ {
+ case COLOR_F:
+ col.r = ReadFloat();
+ col.g = ReadFloat();
+ col.b = ReadFloat();
+ break;
+ case COLOR_24:
+ col.r = ReadByte()/255.0f;
+ col.g = ReadByte()/255.0f;
+ col.b = ReadByte()/255.0f;
+ break;
+ case LIN_COLOR_F:
+ col.r = ReadFloat();
+ col.g = ReadFloat();
+ col.b = ReadFloat();
+ break;
+ case LIN_COLOR_24:
+ col.r = ReadByte()/255.0f;
+ col.g = ReadByte()/255.0f;
+ col.b = ReadByte()/255.0f;
+ break;
+ default:
+ ErrorMsg("L3DS::ReadColor - error this is not a color chunk");
+ }
+ return col;
+}
+
+float L3DS::ReadPercentage(const LChunk &chunk)
+{
+ GotoChunk(chunk);
+ switch (chunk.id)
+ {
+ case INT_PERCENTAGE:
+ return (ReadShort()/100.0f);
+ case FLOAT_PERCENTAGE:
+ return ReadFloat();
+ }
+ ErrorMsg("L3DS::ReadPercentage - error, the chunk is not a percentage chunk");
+ return 0;
+}
+
+bool L3DS::Read3DS()
+{
+ LChunk mainchunk;
+ LChunk edit;
+ edit.id = EDIT3DS;
+ mainchunk = ReadChunk();
+ if (mainchunk.id != MAIN3DS)
+ {
+ ErrorMsg("L3DS::Read3DS - wrong file format");
+ return false;
+ }
+ if (!FindChunk(edit, mainchunk))
+ return false;
+ LChunk obj;
+ LChunk ml;
+
+ GotoChunk(edit);
+ obj.id = MAT_ENTRY;
+ while (FindChunk(obj, edit))
+ {
+ ReadMaterial(obj);
+ SkipChunk(obj);
+ }
+ GotoChunk(edit);
+
+ obj.id = EDIT_OBJECT;
+ {
+ while (FindChunk(obj, edit))
+ {
+ ReadASCIIZ(m_objName, 99);
+ ml = ReadChunk();
+ if (ml.id == OBJ_TRIMESH)
+ ReadMesh(ml);
+ if (ml.id == OBJ_LIGHT)
+ ReadLight(ml);
+ SkipChunk(obj);
+ }
+ }
+
+ // read the keyframer data here to find out correct object orientation
+
+ LChunk keyframer;
+ keyframer.id = KFDATA;
+
+ LChunk objtrack;
+ objtrack.id = OBJECT_NODE_TAG;
+
+ GotoChunk(mainchunk);
+ if (FindChunk(keyframer, mainchunk))
+ { // keyframer chunk is present
+ GotoChunk(keyframer);
+ while (FindChunk(objtrack, keyframer))
+ {
+ ReadKeyframeData(objtrack);
+ SkipChunk(objtrack);
+ }
+ }
+
+ for (uint i=0; i<m_meshes.size(); i++) {
+ m_meshes[i].Optimize(m_optLevel);
+ }
+
+ m_pos = 0;
+ strcpy(m_objName, "");
+ return true;
+}
+
+void L3DS::ReadLight(const LChunk &parent)
+{
+ float t;
+ LVector3 v;
+ LLight light;
+ light.SetName(m_objName);
+ GotoChunk(parent);
+ LChunk chunk = ReadChunk();
+ if (chunk.id == OBJ_LIGHT)
+ {
+ v.x = ReadFloat();
+ v.y = ReadFloat();
+ v.z = ReadFloat();
+ if (chunk.end < parent.end)
+ chunk = ReadChunk();
+ while (chunk.end <= parent.end)
+ {
+ switch (chunk.id)
+ {
+ case COLOR_24:
+ case COLOR_F:
+ case LIN_COLOR_F:
+ case LIN_COLOR_24:
+ light.SetColor(ReadColor(chunk));
+ break;
+ case SPOTLIGHT:
+ v.x = ReadFloat();
+ v.y = ReadFloat();
+ v.z = ReadFloat();
+ light.SetTarget(v);
+ t = ReadFloat();
+ light.SetHotspot(t);
+ t = ReadFloat();
+ light.SetFalloff(t);
+ break;
+ default:
+ break;
+ }
+ SkipChunk(chunk);
+ if (chunk.end >= parent.end)
+ break;
+ chunk = ReadChunk();
+
+ }
+ }
+ m_lights.push_back(light);
+}
+
+void L3DS::ReadMesh(const LChunk &parent)
+{
+ unsigned short count, i;
+ LVector4 p;
+ LMatrix4 m;
+ LVector2 t;
+ p.w = 1.0f;
+ LMesh mesh;
+ mesh.SetName(m_objName);
+ GotoChunk(parent);
+ LChunk chunk = ReadChunk();
+ while (chunk.end <= parent.end)
+ {
+ switch (chunk.id)
+ {
+ case TRI_VERTEXLIST:
+ count = ReadShort();
+ mesh.SetVertexArraySize(count);
+ for (i=0; i < count; i++)
+ {
+ p.x = ReadFloat();
+ p.y = ReadFloat();
+ p.z = ReadFloat();
+ mesh.SetVertex(p, i);
+ }
+ break;
+ case TRI_FACEMAPPING:
+ count = ReadShort();
+ if (mesh.GetVertexCount() == 0)
+ mesh.SetVertexArraySize(count);
+ for (i=0; i < count; i++)
+ {
+ t.x = ReadFloat();
+ t.y = ReadFloat();
+ mesh.SetUV(t, i);
+ }
+ break;
+ case TRI_FACELIST:
+ ReadFaceList(chunk, mesh);
+ break;
+ case TRI_MATRIX:
+ {
+ for (int i = 0; i < 4; i++)
+ for (int j = 0; j < 3; j++)
+ m.m[i][j] = ReadFloat();
+
+ m.m[0][3] = 0.0f;
+ m.m[1][3] = 0.0f;
+ m.m[2][3] = 0.0f;
+ m.m[3][3] = 1.0f;
+
+ mesh.SetMatrix(m);
+ }
+ break;
+ default:
+ break;
+ }
+ SkipChunk(chunk);
+ if (chunk.end >= parent.end)
+ break;
+ chunk = ReadChunk();
+ }
+ m_meshes.push_back(mesh);
+}
+
+void L3DS::ReadFaceList(const LChunk &chunk, LMesh &mesh)
+{
+ // variables
+ unsigned short count, t;
+ uint i;
+ LTri tri;
+ LChunk ch;
+ char str[20];
+ //uint mat;
+
+ // consistency checks
+ if (chunk.id != TRI_FACELIST)
+ {
+ ErrorMsg("L3DS::ReadFaceList - internal error: wrong chunk passed as parameter");
+ return;
+ }
+ GotoChunk(chunk);
+ tri.smoothingGroups = 1;
+ // read the number of faces
+ count = ReadShort();
+ mesh.SetTriangleArraySize(count);
+ for (i=0; i<count; i++)
+ {
+ tri.a = ReadShort();
+ tri.b = ReadShort();
+ tri.c = ReadShort();
+ ReadShort();
+ mesh.SetTri(tri, i);
+ }
+ // now read the optional chunks
+ ch = ReadChunk();
+ while (ch.end <= chunk.end)
+ {
+ switch (ch.id)
+ {
+ case TRI_MAT_GROUP: {
+ ReadASCIIZ(str, 20);
+ int mat_id = FindMaterial(str)->GetID();
+ mesh.AddMaterial(mat_id);
+ count = ReadShort();
+ for (i=0; i<count; i++) {
+ t = ReadShort();
+ mesh.GetTri(t).materialId = mat_id;
+ }
+ }
+ break;
+
+ case TRI_SMOOTH_GROUP:
+ for (i=0; i<mesh.GetTriangleCount(); i++)
+ mesh.GetTri(i).smoothingGroups = (ulong) ReadInt();
+ break;
+ }
+ SkipChunk(ch);
+ ch = ReadChunk();
+ }
+}
+
+void L3DS::ReadMaterial(const LChunk &parent)
+{
+ // variables
+ LChunk chunk;
+ LChunk child;
+ char str[30];
+ LMaterial mat;
+ short sh;
+
+ GotoChunk(parent);
+
+ chunk = ReadChunk();
+ while (chunk.end <= parent.end)
+ {
+ switch (chunk.id)
+ {
+ case MAT_NAME:
+ ReadASCIIZ(str, 30);
+ mat.SetName(str);
+ break;
+ case MAT_AMBIENT:
+ child = ReadChunk();
+ mat.SetAmbientColor(ReadColor(child));
+ break;
+ case MAT_DIFFUSE:
+ child = ReadChunk();
+ mat.SetDiffuseColor(ReadColor(child));
+ break;
+ case MAT_SPECULAR:
+ child = ReadChunk();
+ mat.SetSpecularColor(ReadColor(child));
+ break;
+ case MAT_SHININESS:
+ child = ReadChunk();
+ mat.SetShininess(ReadPercentage(child));
+ break;
+ case MAT_TRANSPARENCY:
+ child = ReadChunk();
+ mat.SetTransparency(ReadPercentage(child));
+ break;
+ case MAT_SHADING:
+ sh = ReadShort();
+ switch (sh)
+ {
+ case 0:
+ mat.SetShadingType(sWireframe);
+ break;
+ case 1:
+ mat.SetShadingType(sFlat);
+ break;
+ case 2:
+ mat.SetShadingType(sGouraud);
+ break;
+ case 3:
+ mat.SetShadingType(sPhong);
+ break;
+ case 4:
+ mat.SetShadingType(sMetal);
+ break;
+ }
+ break;
+ case MAT_WIRE:
+ mat.SetShadingType(sWireframe);
+ break;
+ case MAT_TEXMAP:
+ ReadMap(chunk, mat.GetTextureMap1());
+ break;
+ case MAT_TEX2MAP:
+ ReadMap(chunk, mat.GetTextureMap2());
+ break;
+ case MAT_OPACMAP:
+ ReadMap(chunk, mat.GetOpacityMap());
+ break;
+ case MAT_BUMPMAP:
+ ReadMap(chunk, mat.GetBumpMap());
+ break;
+ case MAT_SPECMAP:
+ ReadMap(chunk, mat.GetSpecularMap());
+ break;
+ case MAT_REFLMAP:
+ child = ReadChunk();
+ mat.GetReflectionMap().strength = ReadPercentage(child);
+ SkipChunk(child);
+ child = ReadChunk();
+ if (child.id != MAT_MAPNAME)
+ {
+ ErrorMsg("L3DS::ReadMaterial - error, expected chunk not found");
+ return;
+ }
+ ReadASCIIZ(str, 30);
+ if (strcmp(str, "") == 0)
+ strcpy(mat.GetReflectionMap().mapName, "auto");
+ break;
+ }
+
+ SkipChunk(chunk);
+ chunk = ReadChunk();
+ }
+ m_materials.push_back(mat);
+ m_materials[m_materials.size()-1].SetID(m_materials.size()-1);
+}
+
+void L3DS::ReadMap(const LChunk &chunk, LMap& map)
+{
+ LChunk child;
+ char str[20];
+ GotoChunk(chunk);
+ child = ReadChunk();
+ while (child.end <= chunk.end)
+ {
+ switch (child.id)
+ {
+ case INT_PERCENTAGE:
+ map.strength = ReadPercentage(child);
+ break;
+ case MAT_MAPNAME:
+ ReadASCIIZ(str, 20);
+ strcpy(map.mapName, str);
+ break;
+ case MAT_MAP_USCALE:
+ map.uScale = ReadFloat();
+ break;
+ case MAT_MAP_VSCALE:
+ map.vScale = ReadFloat();
+ break;
+ case MAT_MAP_UOFFSET:
+ map.uOffset = ReadFloat();
+ break;
+ case MAT_MAP_VOFFSET:
+ map.vOffset = ReadFloat();
+ break;
+ case MAT_MAP_ANG:
+ map.angle = ReadFloat();
+ break;
+ }
+ SkipChunk(child);
+ child = ReadChunk();
+ }
+}
+
+void L3DS::ReadKeyframeData(const LChunk &parent)
+{
+ uint frames = 0;
+
+ LChunk node_hdr;
+ node_hdr.id = NODE_HDR;
+
+ char str[20];
+ LMesh *mesh;
+
+ GotoChunk(parent);
+ if (!FindChunk(node_hdr, parent))
+ return;
+ GotoChunk(node_hdr);
+ ReadASCIIZ(str, 19);
+ mesh = FindMesh(str);
+ if (mesh == 0)
+ return;
+ GotoChunk(parent);
+
+ // read the pivot
+ LVector3 pivot = zero3;
+
+ LChunk pivotchunk;
+ pivotchunk.id = PIVOT;
+ if (FindChunk(pivotchunk, parent))
+ {
+ GotoChunk(pivotchunk);
+ pivot.x = ReadFloat();
+ pivot.y = ReadFloat();
+ pivot.z = ReadFloat();
+ }
+ GotoChunk(parent);
+
+ // read frame 0 from the position track
+ LVector3 pos = zero3;
+
+ frames = 0;
+
+ LChunk poschunk;
+ poschunk.id = POS_TRACK_TAG;
+ if (FindChunk(poschunk, parent))
+ {
+ GotoChunk(poschunk);
+ // read the trackheader structure
+ ReadShort();
+ ReadInt();
+ ReadInt();
+ frames = ReadInt();
+ if (frames > 0)
+ {
+ ReadKeyheader();
+ pos.x = ReadFloat();
+ pos.y = ReadFloat();
+ pos.z = ReadFloat();
+ }
+ }
+ GotoChunk(parent);
+
+ // now read the rotation track
+ LVector4 rot = zero4;
+
+ LChunk rotchunk;
+ rotchunk.id = ROT_TRACK_TAG;
+
+ frames = 0;
+ if (FindChunk(rotchunk, parent))
+ {
+ GotoChunk(rotchunk);
+ // read the trackheader structure
+ ReadShort();
+ ReadInt();
+ ReadInt();
+ frames = ReadInt();
+ if (frames > 0)
+ {
+ ReadKeyheader();
+ rot.x = ReadFloat();
+ rot.y = ReadFloat();
+ rot.z = ReadFloat();
+ rot.w = ReadFloat();
+ }
+ }
+ GotoChunk(parent);
+
+ // now read the scaling chunk
+ LVector3 scale;
+ scale.x = 1;
+ scale.y = 1;
+ scale.z = 1;
+
+ LChunk scalechunk;
+ scalechunk.id = SCL_TRACK_TAG;
+
+ frames = 0;
+
+ if (FindChunk(scalechunk, parent))
+ {
+ GotoChunk(scalechunk);
+ // read the trackheader structure
+ ReadShort();
+ ReadInt();
+ ReadInt();
+ frames = ReadInt();
+ if (frames > 0)
+ {
+ ReadKeyheader();
+ scale.x = ReadFloat();
+ scale.y = ReadFloat();
+ scale.z = ReadFloat();
+ }
+ }
+ GotoChunk(parent);
+
+
+}
+
+long L3DS::ReadKeyheader()
+{
+ long frame;
+ frame = ReadInt();
+ short opts = ReadShort();
+ if (opts & 32768) // 32768 is 1000000000000000 binary
+ { // tension is present
+ ReadFloat();
+ }
+ if (opts & 16384) // 16384 is 0100000000000000 binary
+ { // continuity is present
+ ReadFloat();
+ }
+ if (opts & 8192)
+ { // bias info present
+ ReadFloat();
+ }
+ if (opts & 4096)
+ { // "ease to" present
+ ReadFloat();
+ }
+ if (opts & 2048)
+ { // "ease from" present
+ ReadFloat();
+ }
+ return frame;
} \ No newline at end of file
diff --git a/Magic2/l3ds.h b/Magic2/l3ds.h
index b38e1e8..16204b5 100644
--- a/Magic2/l3ds.h
+++ b/Magic2/l3ds.h
@@ -1,457 +1,457 @@
-// copyright (c) 2001-2002 Lev Povalahev
-// this is a 3ds importer version 2
-
-#ifndef L3DS_H
-#define L3DS_H
-
-// includes
-#include <vector>
-#include <string>
-
-//---------------------------------------------------------
-
-typedef unsigned int uint;
-typedef unsigned char byte;
-
-enum LShading {sWireframe, sFlat, sGouraud, sPhong, sMetal};
-
-enum LOptimizationLevel {oNone, oSimple, oFull};
-
-// for internal use
-struct LChunk;
-struct LTri;
-
-//------------------------------------------------
-
-struct LVector4
-{
- float x;
- float y;
- float z;
- float w;
-
- int operator==(const LVector4& v) const { return x==v.x && y==v.y && z==v.z && w==v.w; }
-};
-
-struct LVector3
-{
- float x;
- float y;
- float z;
-
- int operator==(const LVector3& v) const { return x==v.x && y==v.y && z==v.z; }
-};
-
-struct LVector2
-{
- float x;
- float y;
-
- int operator==(const LVector2& v) const { return x==v.x && y==v.y; }
-};
-
-struct LColor3
-{
- float r;
- float g;
- float b;
-
- int operator==(const LColor3& v) const { return r==v.r && g==v.g && b==v.b; }
-};
-
-//------------------------------------------------
-
-struct LTriangle
-{
- unsigned short a;
- unsigned short b;
- unsigned short c;
-};
-
-struct LMatrix4
-{
- float m[4][4];
-};
-
-struct LTriangle2
-{
- LVector4 vertices[3];
- LVector3 vertexNormals[3];
- LVector2 textureCoords[3];
- LVector3 faceNormal;
- uint materialId;
-};
-
-// a structure for a texture map
-struct LMap
-{
- // the strength of the texture map
- float strength;
- // the file name of the map. only 8.3 format in 3ds files :(
- char mapName[255];
- float uScale;
- float vScale;
- float uOffset;
- float vOffset;
- float angle;
-};
-
-//------------------------------------------------
-
-class LObject
-{
-public:
- // the default constructor, initilializes the m_name here
- LObject();
- // the destructor frees memory (m_name)
- virtual ~LObject();
- // call this to get the name of the object
- virtual const std::string& GetName();
-
- // this methods should not be used by the "user", they're used internally to fill the class
- // with valid data when reading from file. If you're about to add an importer for another format you'LL
- // have to use these methods
- // call this to set the name of the object
- virtual void SetName(const std::string& value);
- // returns true if the object's name is the name passed as parameter
- bool IsObject(const std::string &name);
-protected:
- // the name of the object
- std::string m_name;
-};
-
-//------------------------------------------------
-
-class LMaterial : public LObject
-{
-public:
- // the default constructor, does the initialization
- LMaterial();
- // the destructor
- virtual ~LMaterial();
- // returns the material ID
- uint GetID();
- // returns the pointer to teh texture map 1
- LMap& GetTextureMap1();
- // returns the pointer to the texture map 2
- LMap& GetTextureMap2();
- // returns the pointer to teh opacity map
- LMap& GetOpacityMap();
- // returns the pointer to the specular (gloss) map
- LMap& GetSpecularMap();
- // returns the pointer to the bump map
- LMap& GetBumpMap();
- // returns the pointer to the reflection map
- LMap& GetReflectionMap();
- // returns the ambient color of the material
- LColor3 GetAmbientColor();
- // returns the diffuse color of the material
- LColor3 GetDiffuseColor();
- // returns the specular color of the material
- LColor3 GetSpecularColor();
- // returns the shininess of the material, ranging from 0(matte) to 1(shiny)
- float GetShininess();
- // returns the transparency of the material, ranging from 1(fully transparent) to 0(opaque)
- float GetTransparency();
- // returns the type of shading, see LShading type
- LShading GetShadingType();
-
- // this methods should not be used by the "user", they're used internally to fill the class
- // with valid data when reading from file. If you're about to add an importer for another format you'LL
- // have to use these methods
- // sets the material ID to "value"
- void SetID(uint value);
- // call this to set the ambient color of the material
- void SetAmbientColor(const LColor3 &color);
- // sets the diffuse color of the material
- void SetDiffuseColor(const LColor3 &color);
- // sets the specular color of the material
- void SetSpecularColor(const LColor3 &color);
- // sets the shininess of the material
- void SetShininess(float value);
- // sets the transparency of the material
- void SetTransparency(float value);
- // sets the shading type
- void SetShadingType(LShading shading);
-protected:
- // the unique material ID
- int m_id;
- // the first texture map
- LMap m_texMap1;
- // the second texture map
- LMap m_texMap2;
- // the opacity map
- LMap m_opacMap;
- // the reflection map
- LMap m_reflMap;
- // the bump map
- LMap m_bumpMap;
- // specular map
- LMap m_specMap;
- // material ambient color
- LColor3 m_ambient;
- // material diffuse color
- LColor3 m_diffuse;
- // material specular color
- LColor3 m_specular;
- // shininess
- float m_shininess;
- // transparency
- float m_transparency;
- // the shading type for the material
- LShading m_shading;
-};
-
-//------------------------------------------------
-
-class LMesh : public LObject
-{
-public:
- // the default constructor
- LMesh();
- // the destructor
- virtual ~LMesh();
- // clears the mesh, deleteing all data
- void Clear();
- // returns the number of vertices in the mesh
- uint GetVertexCount();
- // sets the the size fo the vertex array - for internal use
- void SetVertexArraySize(uint value);
- // returns the number of triangles in the mesh
- uint GetTriangleCount();
- // sets the size of the triangle array - for internal use
- void SetTriangleArraySize(uint value);
- // returns given vertex
- const LVector4& GetVertex(uint index);
- // returns the given normal
- const LVector3& GetNormal(uint index);
- // returns the given texture coordinates vector
- const LVector2& GetUV(uint index);
- // returns the pointer to the array of tangents
- const LVector3& GetTangent(uint index);
- // returns the pointer to the array of binormals
- const LVector3& GetBinormal(uint index);
- // sets the vertex at a given index to "vec" - for internal use
- void SetVertex(const LVector4 &vec, uint index);
- // sets the normal at a given index to "vec" - for internal use
- void SetNormal(const LVector3 &vec, uint index);
- // sets the texture coordinates vector at a given index to "vec" - for internal use
- void SetUV(const LVector2 &vec, uint index);
- // sets the tangent at a given index to "vec" - for internal use
- void SetTangent(const LVector3 &vec, uint index);
- // sets the binormal at a given index to "vec" - for internal use
- void SetBinormal(const LVector3 &vec, uint index);
- // returns the triangle with a given index
- const LTriangle& GetTriangle(uint index);
- // returns the triangle with a given index, see LTriangle2 structure description
- LTriangle2 GetTriangle2(uint index);
- // returns the mesh matrix, should be identity matrix after loading
- LMatrix4 GetMatrix();
- // sets the mesh matrix to a given matrix - for internal use
- void SetMatrix(LMatrix4 m);
- // optimizises the mesh using a given optimization level
- void Optimize(LOptimizationLevel value);
- // sets an internal triangle structure with index "index" - for internal use only
- void SetTri(const LTri &tri, uint index);
- // returns the pointer to the internal triangle structure - for internal use only
- LTri& GetTri(uint index);
- // returns the material id with a given index for the mesh
- uint GetMaterial(uint index);
- // adds a material to the mesh and returns its index - for internal use
- uint AddMaterial(uint id);
- // returns the number of materials used in the mesh
- uint GetMaterialCount();
-protected:
- // the vertices, normals, etc.
- std::vector<LVector4> m_vertices;
- std::vector<LVector3> m_normals;
- std::vector<LVector3> m_binormals;
- std::vector<LVector3> m_tangents;
- std::vector<LVector2> m_uv;
-
- // triangles
- std::vector<LTriangle> m_triangles;
-
- //used internally
- std::vector<LTri> m_tris;
-
- // the transformation matrix.
- LMatrix4 m_matrix;
-
- // the material ID array
- std::vector<uint> m_materials;
-
- // calculates the normals, either using the smoothing groups information or not
- void CalcNormals(bool useSmoothingGroups);
- // calculates the texture(tangent) space for each vertex
- void CalcTextureSpace();
- // transforms the vertices by the mesh matrix
- void TransformVertices();
-};
-
-//------------------------------------------------
-
-class LLight : public LObject
-{
-public:
- // the default constructor
- LLight();
- // the destructor
- virtual ~LLight();
- // clears the data the class holds
- void Clear();
- // sets the position of the light source - for internal use
- void SetPosition(LVector3 vec);
- // returns the position of the light source
- LVector3 GetPosition();
- // sets the color of the light - for internal use
- void SetColor(LColor3 color);
- // returns the color of the light
- LColor3 GetColor();
- // sets whether the light is a spotlight or not - internal use
- void SetSpotlight(bool value);
- // returns true if the light is a spotlight
- bool GetSpotlight();
- // sets the target of the light - internal use
- void SetTarget(LVector3 target);
- // returns the target of the spotlight
- LVector3 GetTarget();
- // sets the hotspot - internal use
- void SetHotspot(float value);
- // returns the hotspot
- float GetHotspot();
- // sets falloff - internal use
- void SetFalloff(float value);
- // returns falloff
- float GetFalloff();
-protected:
- LVector3 m_pos;
- LColor3 m_color;
- bool m_spotlight;
- LVector3 m_target;
- float m_hotspot;
- float m_falloff;
-};
-
-//------------------------------------------------
-
-class LImporter
-{
-public:
- // the default constructor
- LImporter();
- // the destructor
- virtual ~LImporter();
- // reads the model from a file, must be overriden by the child classes
- virtual bool LoadFile(const char *filename) = 0;
- // returns the number of meshes in the scene
- uint GetMeshCount();
- // returns the number of lights in the scene
- uint GetLightCount();
- // returns the number of materials in the scene
- uint GetMaterialCount();
- // returns a pointer to a mesh
- LMesh& GetMesh(uint index);
- // returns a pointer to a light at a given index
- LLight& GetLight(uint index);
- // returns the pointer to the material
- LMaterial& GetMaterial(uint index);
- // returns the pointer to the material with a given name, or NULL if the material was not found
- LMaterial* FindMaterial(const std::string &name);
- // returns the pointer to the mesh with a given name, or NULL if the mesh with such name
- // is not present in the scene
- LMesh* FindMesh(const std::string &name);
- // returns the pointer to the light with a given name, or NULL if not found
- LLight* FindLight(const std::string &name);
- // sets the optimization level to a given value
- void SetOptimizationLevel(LOptimizationLevel value);
- // returns the current optimization level
- LOptimizationLevel GetOptimizationLevel();
-protected:
- // the lights found in the scene
- std::vector<LLight> m_lights;
- // triangular meshes
- std::vector<LMesh> m_meshes;
- // the materials in the scene
- std::vector<LMaterial> m_materials;
- // level of optimization to perform on the meshes
- LOptimizationLevel m_optLevel;
- // clears all data.
- virtual void Clear();
-};
-//------------------------------------------------
-
-class L3DS : public LImporter
-{
-public:
- // the default contructor
- L3DS();
- // constructs the object and loads the file
- L3DS(const char *filename);
- // destructor
- virtual ~L3DS();
- // load 3ds file
- virtual bool LoadFile(const char *filename);
-protected:
- // used internally for reading
- char m_objName[100];
- // true if end of file is reached
- bool m_eof;
- // buffer for loading, used for speedup
- unsigned char *m_buffer;
- // the size of the buffer
- uint m_bufferSize;
- // the current cursor position in the buffer
- uint m_pos;
-
- // reads a short value from the buffer
- short ReadShort();
- // reads an int value from the buffer
- int ReadInt();
- // reads a char from the buffer
- char ReadChar();
- //reada a floatvalue from the buffer
- float ReadFloat();
- //reads an unsigned byte from the buffer
- byte ReadByte();
- //reads an asciiz string
- int ReadASCIIZ(char *buf, int max_count);
- // seek wihtin the buffer
- void Seek(int offset, int origin);
- // returns the position of the cursor
- uint Pos();
-
- // read the chunk and return it.
- LChunk ReadChunk();
- // read until given chunk is found
- bool FindChunk(LChunk &target, const LChunk &parent);
- // skip to the end of chunk "chunk"
- void SkipChunk(const LChunk &chunk);
- // goes to the beginning of the data in teh given chunk
- void GotoChunk(const LChunk &chunk);
-
- // the function read the color chunk (any of the color chunks)
- LColor3 ReadColor(const LChunk &chunk);
- // the function that read the percentage chunk and returns a float from 0 to 1
- float ReadPercentage(const LChunk &chunk);
- // this is where 3ds file is being read
- bool Read3DS();
- // read a light chunk
- void ReadLight(const LChunk &parent);
- // read a trimesh chunk
- void ReadMesh(const LChunk &parent);
- // reads the face list, face materials, smoothing groups... and fill rthe information into the mesh
- void ReadFaceList(const LChunk &chunk, LMesh &mesh);
- // reads the material
- void ReadMaterial(const LChunk &parent);
- // reads the map info and fills the given map with this information
- void ReadMap(const LChunk &chunk, LMap& map);
- // reads keyframer data of the OBJECT_NODE_TAG chunk
- void ReadKeyframeData(const LChunk &parent);
- // reads the keyheader structure from the current offset and returns the frame number
- long ReadKeyheader();
-};
-
-//---------------------------------------------------------
-
+// copyright (c) 2001-2002 Lev Povalahev
+// this is a 3ds importer version 2
+
+#ifndef L3DS_H
+#define L3DS_H
+
+// includes
+#include <vector>
+#include <string>
+
+//---------------------------------------------------------
+
+typedef unsigned int uint;
+typedef unsigned char byte;
+
+enum LShading {sWireframe, sFlat, sGouraud, sPhong, sMetal};
+
+enum LOptimizationLevel {oNone, oSimple, oFull};
+
+// for internal use
+struct LChunk;
+struct LTri;
+
+//------------------------------------------------
+
+struct LVector4
+{
+ float x;
+ float y;
+ float z;
+ float w;
+
+ int operator==(const LVector4& v) const { return x==v.x && y==v.y && z==v.z && w==v.w; }
+};
+
+struct LVector3
+{
+ float x;
+ float y;
+ float z;
+
+ int operator==(const LVector3& v) const { return x==v.x && y==v.y && z==v.z; }
+};
+
+struct LVector2
+{
+ float x;
+ float y;
+
+ int operator==(const LVector2& v) const { return x==v.x && y==v.y; }
+};
+
+struct LColor3
+{
+ float r;
+ float g;
+ float b;
+
+ int operator==(const LColor3& v) const { return r==v.r && g==v.g && b==v.b; }
+};
+
+//------------------------------------------------
+
+struct LTriangle
+{
+ unsigned short a;
+ unsigned short b;
+ unsigned short c;
+};
+
+struct LMatrix4
+{
+ float m[4][4];
+};
+
+struct LTriangle2
+{
+ LVector4 vertices[3];
+ LVector3 vertexNormals[3];
+ LVector2 textureCoords[3];
+ LVector3 faceNormal;
+ uint materialId;
+};
+
+// a structure for a texture map
+struct LMap
+{
+ // the strength of the texture map
+ float strength;
+ // the file name of the map. only 8.3 format in 3ds files :(
+ char mapName[255];
+ float uScale;
+ float vScale;
+ float uOffset;
+ float vOffset;
+ float angle;
+};
+
+//------------------------------------------------
+
+class LObject
+{
+public:
+ // the default constructor, initilializes the m_name here
+ LObject();
+ // the destructor frees memory (m_name)
+ virtual ~LObject();
+ // call this to get the name of the object
+ virtual const std::string& GetName();
+
+ // this methods should not be used by the "user", they're used internally to fill the class
+ // with valid data when reading from file. If you're about to add an importer for another format you'LL
+ // have to use these methods
+ // call this to set the name of the object
+ virtual void SetName(const std::string& value);
+ // returns true if the object's name is the name passed as parameter
+ bool IsObject(const std::string &name);
+protected:
+ // the name of the object
+ std::string m_name;
+};
+
+//------------------------------------------------
+
+class LMaterial : public LObject
+{
+public:
+ // the default constructor, does the initialization
+ LMaterial();
+ // the destructor
+ virtual ~LMaterial();
+ // returns the material ID
+ uint GetID();
+ // returns the pointer to teh texture map 1
+ LMap& GetTextureMap1();
+ // returns the pointer to the texture map 2
+ LMap& GetTextureMap2();
+ // returns the pointer to teh opacity map
+ LMap& GetOpacityMap();
+ // returns the pointer to the specular (gloss) map
+ LMap& GetSpecularMap();
+ // returns the pointer to the bump map
+ LMap& GetBumpMap();
+ // returns the pointer to the reflection map
+ LMap& GetReflectionMap();
+ // returns the ambient color of the material
+ LColor3 GetAmbientColor();
+ // returns the diffuse color of the material
+ LColor3 GetDiffuseColor();
+ // returns the specular color of the material
+ LColor3 GetSpecularColor();
+ // returns the shininess of the material, ranging from 0(matte) to 1(shiny)
+ float GetShininess();
+ // returns the transparency of the material, ranging from 1(fully transparent) to 0(opaque)
+ float GetTransparency();
+ // returns the type of shading, see LShading type
+ LShading GetShadingType();
+
+ // this methods should not be used by the "user", they're used internally to fill the class
+ // with valid data when reading from file. If you're about to add an importer for another format you'LL
+ // have to use these methods
+ // sets the material ID to "value"
+ void SetID(uint value);
+ // call this to set the ambient color of the material
+ void SetAmbientColor(const LColor3 &color);
+ // sets the diffuse color of the material
+ void SetDiffuseColor(const LColor3 &color);
+ // sets the specular color of the material
+ void SetSpecularColor(const LColor3 &color);
+ // sets the shininess of the material
+ void SetShininess(float value);
+ // sets the transparency of the material
+ void SetTransparency(float value);
+ // sets the shading type
+ void SetShadingType(LShading shading);
+protected:
+ // the unique material ID
+ int m_id;
+ // the first texture map
+ LMap m_texMap1;
+ // the second texture map
+ LMap m_texMap2;
+ // the opacity map
+ LMap m_opacMap;
+ // the reflection map
+ LMap m_reflMap;
+ // the bump map
+ LMap m_bumpMap;
+ // specular map
+ LMap m_specMap;
+ // material ambient color
+ LColor3 m_ambient;
+ // material diffuse color
+ LColor3 m_diffuse;
+ // material specular color
+ LColor3 m_specular;
+ // shininess
+ float m_shininess;
+ // transparency
+ float m_transparency;
+ // the shading type for the material
+ LShading m_shading;
+};
+
+//------------------------------------------------
+
+class LMesh : public LObject
+{
+public:
+ // the default constructor
+ LMesh();
+ // the destructor
+ virtual ~LMesh();
+ // clears the mesh, deleteing all data
+ void Clear();
+ // returns the number of vertices in the mesh
+ uint GetVertexCount();
+ // sets the the size fo the vertex array - for internal use
+ void SetVertexArraySize(uint value);
+ // returns the number of triangles in the mesh
+ uint GetTriangleCount();
+ // sets the size of the triangle array - for internal use
+ void SetTriangleArraySize(uint value);
+ // returns given vertex
+ const LVector4& GetVertex(uint index);
+ // returns the given normal
+ const LVector3& GetNormal(uint index);
+ // returns the given texture coordinates vector
+ const LVector2& GetUV(uint index);
+ // returns the pointer to the array of tangents
+ const LVector3& GetTangent(uint index);
+ // returns the pointer to the array of binormals
+ const LVector3& GetBinormal(uint index);
+ // sets the vertex at a given index to "vec" - for internal use
+ void SetVertex(const LVector4 &vec, uint index);
+ // sets the normal at a given index to "vec" - for internal use
+ void SetNormal(const LVector3 &vec, uint index);
+ // sets the texture coordinates vector at a given index to "vec" - for internal use
+ void SetUV(const LVector2 &vec, uint index);
+ // sets the tangent at a given index to "vec" - for internal use
+ void SetTangent(const LVector3 &vec, uint index);
+ // sets the binormal at a given index to "vec" - for internal use
+ void SetBinormal(const LVector3 &vec, uint index);
+ // returns the triangle with a given index
+ const LTriangle& GetTriangle(uint index);
+ // returns the triangle with a given index, see LTriangle2 structure description
+ LTriangle2 GetTriangle2(uint index);
+ // returns the mesh matrix, should be identity matrix after loading
+ LMatrix4 GetMatrix();
+ // sets the mesh matrix to a given matrix - for internal use
+ void SetMatrix(LMatrix4 m);
+ // optimizises the mesh using a given optimization level
+ void Optimize(LOptimizationLevel value);
+ // sets an internal triangle structure with index "index" - for internal use only
+ void SetTri(const LTri &tri, uint index);
+ // returns the pointer to the internal triangle structure - for internal use only
+ LTri& GetTri(uint index);
+ // returns the material id with a given index for the mesh
+ uint GetMaterial(uint index);
+ // adds a material to the mesh and returns its index - for internal use
+ uint AddMaterial(uint id);
+ // returns the number of materials used in the mesh
+ uint GetMaterialCount();
+protected:
+ // the vertices, normals, etc.
+ std::vector<LVector4> m_vertices;
+ std::vector<LVector3> m_normals;
+ std::vector<LVector3> m_binormals;
+ std::vector<LVector3> m_tangents;
+ std::vector<LVector2> m_uv;
+
+ // triangles
+ std::vector<LTriangle> m_triangles;
+
+ //used internally
+ std::vector<LTri> m_tris;
+
+ // the transformation matrix.
+ LMatrix4 m_matrix;
+
+ // the material ID array
+ std::vector<uint> m_materials;
+
+ // calculates the normals, either using the smoothing groups information or not
+ void CalcNormals(bool useSmoothingGroups);
+ // calculates the texture(tangent) space for each vertex
+ void CalcTextureSpace();
+ // transforms the vertices by the mesh matrix
+ void TransformVertices();
+};
+
+//------------------------------------------------
+
+class LLight : public LObject
+{
+public:
+ // the default constructor
+ LLight();
+ // the destructor
+ virtual ~LLight();
+ // clears the data the class holds
+ void Clear();
+ // sets the position of the light source - for internal use
+ void SetPosition(LVector3 vec);
+ // returns the position of the light source
+ LVector3 GetPosition();
+ // sets the color of the light - for internal use
+ void SetColor(LColor3 color);
+ // returns the color of the light
+ LColor3 GetColor();
+ // sets whether the light is a spotlight or not - internal use
+ void SetSpotlight(bool value);
+ // returns true if the light is a spotlight
+ bool GetSpotlight();
+ // sets the target of the light - internal use
+ void SetTarget(LVector3 target);
+ // returns the target of the spotlight
+ LVector3 GetTarget();
+ // sets the hotspot - internal use
+ void SetHotspot(float value);
+ // returns the hotspot
+ float GetHotspot();
+ // sets falloff - internal use
+ void SetFalloff(float value);
+ // returns falloff
+ float GetFalloff();
+protected:
+ LVector3 m_pos;
+ LColor3 m_color;
+ bool m_spotlight;
+ LVector3 m_target;
+ float m_hotspot;
+ float m_falloff;
+};
+
+//------------------------------------------------
+
+class LImporter
+{
+public:
+ // the default constructor
+ LImporter();
+ // the destructor
+ virtual ~LImporter();
+ // reads the model from a file, must be overriden by the child classes
+ virtual bool LoadFile(const char *filename) = 0;
+ // returns the number of meshes in the scene
+ uint GetMeshCount();
+ // returns the number of lights in the scene
+ uint GetLightCount();
+ // returns the number of materials in the scene
+ uint GetMaterialCount();
+ // returns a pointer to a mesh
+ LMesh& GetMesh(uint index);
+ // returns a pointer to a light at a given index
+ LLight& GetLight(uint index);
+ // returns the pointer to the material
+ LMaterial& GetMaterial(uint index);
+ // returns the pointer to the material with a given name, or NULL if the material was not found
+ LMaterial* FindMaterial(const std::string &name);
+ // returns the pointer to the mesh with a given name, or NULL if the mesh with such name
+ // is not present in the scene
+ LMesh* FindMesh(const std::string &name);
+ // returns the pointer to the light with a given name, or NULL if not found
+ LLight* FindLight(const std::string &name);
+ // sets the optimization level to a given value
+ void SetOptimizationLevel(LOptimizationLevel value);
+ // returns the current optimization level
+ LOptimizationLevel GetOptimizationLevel();
+protected:
+ // the lights found in the scene
+ std::vector<LLight> m_lights;
+ // triangular meshes
+ std::vector<LMesh> m_meshes;
+ // the materials in the scene
+ std::vector<LMaterial> m_materials;
+ // level of optimization to perform on the meshes
+ LOptimizationLevel m_optLevel;
+ // clears all data.
+ virtual void Clear();
+};
+//------------------------------------------------
+
+class L3DS : public LImporter
+{
+public:
+ // the default contructor
+ L3DS();
+ // constructs the object and loads the file
+ L3DS(const char *filename);
+ // destructor
+ virtual ~L3DS();
+ // load 3ds file
+ virtual bool LoadFile(const char *filename);
+protected:
+ // used internally for reading
+ char m_objName[100];
+ // true if end of file is reached
+ bool m_eof;
+ // buffer for loading, used for speedup
+ unsigned char *m_buffer;
+ // the size of the buffer
+ uint m_bufferSize;
+ // the current cursor position in the buffer
+ uint m_pos;
+
+ // reads a short value from the buffer
+ short ReadShort();
+ // reads an int value from the buffer
+ int ReadInt();
+ // reads a char from the buffer
+ char ReadChar();
+ //reada a floatvalue from the buffer
+ float ReadFloat();
+ //reads an unsigned byte from the buffer
+ byte ReadByte();
+ //reads an asciiz string
+ int ReadASCIIZ(char *buf, int max_count);
+ // seek wihtin the buffer
+ void Seek(int offset, int origin);
+ // returns the position of the cursor
+ uint Pos();
+
+ // read the chunk and return it.
+ LChunk ReadChunk();
+ // read until given chunk is found
+ bool FindChunk(LChunk &target, const LChunk &parent);
+ // skip to the end of chunk "chunk"
+ void SkipChunk(const LChunk &chunk);
+ // goes to the beginning of the data in teh given chunk
+ void GotoChunk(const LChunk &chunk);
+
+ // the function read the color chunk (any of the color chunks)
+ LColor3 ReadColor(const LChunk &chunk);
+ // the function that read the percentage chunk and returns a float from 0 to 1
+ float ReadPercentage(const LChunk &chunk);
+ // this is where 3ds file is being read
+ bool Read3DS();
+ // read a light chunk
+ void ReadLight(const LChunk &parent);
+ // read a trimesh chunk
+ void ReadMesh(const LChunk &parent);
+ // reads the face list, face materials, smoothing groups... and fill rthe information into the mesh
+ void ReadFaceList(const LChunk &chunk, LMesh &mesh);
+ // reads the material
+ void ReadMaterial(const LChunk &parent);
+ // reads the map info and fills the given map with this information
+ void ReadMap(const LChunk &chunk, LMap& map);
+ // reads keyframer data of the OBJECT_NODE_TAG chunk
+ void ReadKeyframeData(const LChunk &parent);
+ // reads the keyheader structure from the current offset and returns the frame number
+ long ReadKeyheader();
+};
+
+//---------------------------------------------------------
+
#endif \ No newline at end of file
diff --git a/Magic2/resource.h b/Magic2/resource.h
index f183426..84d4573 100644
--- a/Magic2/resource.h
+++ b/Magic2/resource.h
@@ -1,233 +1,233 @@
-//{{NO_DEPENDENCIES}}
-// Microsoft Developer Studio generated include file.
-// Used by Magic.rc
-//
-#define ID_RESET 3
-#define IDC_NEW_MATERIAL 3
-#define ID_BACK_COLOR 4
-#define IDC_DEL_MATERIAL 4
-#define IDC_SELECT_POLYS 5
-#define IDD_ABOUTBOX 100
-#define IDR_MAINFRAME 128
-#define IDR_MAGICTYPE 129
-#define IDD_SURFACE_PROPS 130
-#define IDD_CAMERA_PROPS 131
-#define IDD_MODIFY_SURFACE 135
-#define IDD_VERTS_REDUCE 136
-#define IDD_MODIFY_POLY 137
-#define IDD_CREATE_CUBE 138
-#define IDD_CREATE_CYLINDER 139
-#define IDD_CREATE_SPHERE 140
-#define IDD_MODIFY_TEXTURE 141
-#define IDD_GRIDPROPS 142
-#define IDD_MODIFY_POLYS 143
-#define IDD_CREATE_POLY 144
-#define IDD_EXTRUSION_PROPS 146
-#define IDD_MODIFY_MATERIAL 147
-#define IDC_SURFACE_NAME 1000
-#define IDC_SURFACE_NVERTS 1001
-#define IDC_SURFACE_NPOLYS 1002
-#define IDC_SURFACE_COLOR 1003
-#define IDC_SURFACE_RADIUS 1003
-#define IDC_SURFACE_LENGTH 1004
-#define IDC_SURFACE_WIDTH 1005
-#define IDC_CAMERA_DISTANCE 1006
-#define IDC_SURFACE_HEIGHT 1006
-#define IDC_CAMERA_FOV 1007
-#define IDC_CAMERA_MODE 1008
-#define IDC_SURFACE_LIST 1009
-#define IDC_SURF_NAME 1010
-#define IDC_SURF_POLYS 1011
-#define IDC_SURF_COLOR 1012
-#define IDC_SURF_HIDDEN 1013
-#define IDC_SURF_LOCKED 1014
-#define IDC_SURF_CREATE 1015
-#define IDC_SURF_DISCARD 1016
-#define IDC_SURF_CLONE 1017
-#define IDC_SURF_DELETE 1018
-#define IDC_SURF_ADD_POLYS 1019
-#define IDC_THRESHOLD 1020
-#define IDC_SURF_ID 1020
-#define IDC_FLATTEN 1021
-#define IDC_FLIP_NORM 1022
-#define IDC_DOUBLE_SIDE 1023
-#define IDC_TRIANGULATE 1024
-#define IDC_REMOVE 1025
-#define IDC_POLY_VERTS 1026
-#define IDC_POLY_X 1027
-#define IDC_POLY_Y 1028
-#define IDC_POLY_Z 1029
-#define IDC_POLY_CURVE 1030
-#define IDC_POLY_SURF 1031
-#define IDC_POLY_TEX 1032
-#define IDC_LOC_X 1033
-#define IDC_LOC_Y 1034
-#define IDC_LOC_Z 1035
-#define IDC_SIZE_X 1036
-#define IDC_SIZE_Y 1037
-#define IDC_SIZE_Z 1038
-#define IDC_SECTORS 1039
-#define IDC_RINGS 1040
-#define IDC_GRID_SNAP 1041
-#define IDC_TEXTURE 1041
-#define IDC_MATERIAL 1041
-#define IDC_GRID_SIZE 1042
-#define IDC_MAPPING 1042
-#define IDC_GRID_SHOW 1043
-#define IDC_ALIGN_X 1043
-#define IDC_GRID_LINES 1044
-#define IDC_ALIGN_Y 1044
-#define IDC_GRID_DOTS 1045
-#define IDC_ALIGN_Z 1045
-#define IDC_SCALE_U 1046
-#define IDC_SCALE_V 1047
-#define IDC_TEXTURE_ADD 1048
-#define IDC_TEXTURE_DELETE 1049
-#define IDC_ALIGN_FLIP 1050
-#define IDC_ALIGN_MIRROR 1051
-#define IDC_ALIGN_ROTATE 1052
-#define IDC_TEXTURE_RELOAD 1053
-#define IDC_TEXTURE_PREVIEW 1054
-#define IDC_TEMPLATE 1055
-#define IDC_AMBIENT_COLOR 1055
-#define IDC_FLAG_FLAT 1056
-#define IDC_DIFFUSE_COLOR 1056
-#define IDC_FLAG_LUMINOUS 1057
-#define IDC_NSIDES 1057
-#define IDC_SPECULAR_COLOR 1057
-#define IDC_FLAG_TRANSLUCENT 1058
-#define IDC_EMISSIVE_COLOR 1058
-#define IDC_FLAG_TRANSPARENT 1059
-#define IDC_SECONDARY 1059
-#define IDC_FLAG_SPECULAR 1060
-#define IDC_FLAG_FLAT2 1061
-#define IDC_FLAG_LUMINOUS2 1062
-#define IDC_POLY_INDEX 1062
-#define IDC_FLAG_TRANSLUCENT2 1063
-#define IDC_FLAG_TRANSPARENT2 1064
-#define IDC_FLAG_SPECULAR2 1065
-#define IDC_FLAG_TEXCLAMP 1066
-#define IDC_DISTANCE 1067
-#define IDC_FLAG_SPECULAR22 1067
-#define IDC_FLAG_SPECULAR1 1068
-#define IDC_FLAG_SPECULAR12 1069
-#define IDC_FLAG_TEXCLAMP2 1070
-#define IDC_MATERIAL_LIST 1070
-#define IDC_MATERIAL_NAME 1071
-#define IDC_DIFFUSE_TEXTURE 1072
-#define IDC_SPECULAR_TEXTURE 1073
-#define IDC_EMISSIVE_TEXTURE 1074
-#define IDC_BUMP_TEXTURE 1075
-#define IDC_AMBIENT_VALUE 1076
-#define IDC_DIFFUSE_VALUE 1077
-#define IDC_SPECULAR_VALUE 1078
-#define IDC_EMISSIVE_VALUE 1079
-#define IDC_BUMP_VALUE 1080
-#define IDC_POWER_VALUE 1081
-#define IDC_BRILLIANCE_VALUE 1082
-#define IDC_BLEND_MODE 1083
-#define IDC_MATERIAL_PREVIEW 1084
-#define IDC_FILE_DIFFUSE 1085
-#define IDC_FILE_SPECULAR 1086
-#define IDC_REFERENCE_PLAN 1086
-#define IDC_FILE_EMISSIVE 1087
-#define IDC_REFERENCE_SIDE 1087
-#define IDC_FILE_BUMP 1088
-#define IDC_REFERENCE_FRONT 1088
-#define IDC_SHADOW 1089
-#define IDC_FILE_PLAN 1090
-#define IDC_MATERIAL_SHADER 1090
-#define IDC_FILE_SIDE 1091
-#define IDC_FILE_FRONT 1092
-#define ID_GRID_PROPS 32771
-#define ID_VIEW_ZOOM_IN 32771
-#define ID_VIEW_ZOOM_OUT 32772
-#define ID_VIEW_ZOOM_NORMAL 32773
-#define ID_VIEW_CENTER 32774
-#define ID_SURFACE_CREATE 32779
-#define ID_MODIFY_DRAG_VERTS 32780
-#define ID_CREATE_CUBE 32781
-#define ID_CREATE_TETRA 32782
-#define ID_MODIFY_EXTRUDE 32784
-#define ID_MODIFY_BEVEL 32785
-#define ID_MODIFY_STUD 32786
-#define ID_MODIFY_SUBDIVIDE 32787
-#define ID_PROP_SURFACE 32788
-#define ID_PROP_CAMERA 32789
-#define ID_EDIT_FLIP_NORMAL 32790
-#define ID_EDIT_REMOVE_POLY 32791
-#define ID_EDIT_MERGE_POLY 32792
-#define ID_MODIFY_TEXTURE 32795
-#define ID_OPTIONS_VERTEX_NORMALS 32798
-#define ID_PROP_GRID 32800
-#define ID_EDIT_DELETE 32801
-#define ID_CREATE_POLY 32802
-#define ID_CREATE_VERT 32803
-#define ID_CREATE_CYLINDER 32804
-#define ID_CREATE_SPHERE 32805
-#define ID_FILE_IMPORT 32806
-#define ID_FILE_EXPORT 32807
-#define ID_MODIFY_POLY 32808
-#define ID_MODIFY_VERTS 32809
-#define ID_VERTS_REDUCE 32810
-#define ID_VERTS_SNAP 32811
-#define ID_MODIFY_SCALE_VERTS 32812
-#define ID_MODIFY_ROTATE 32813
-#define ID_CREATE_CONE 32814
-#define ID_FINAL_RENDER 32815
-#define ID_MODIFY_SCALE_X 32817
-#define ID_MODIFY_SCALE_Z 32819
-#define ID_MODIFY_SCALE_Y 32822
-#define ID_MODIFY_SPLIT1 32824
-#define ID_MODIFY_SPLIT2 32825
-#define ID_EDIT_MIRROR 32826
-#define ID_EDIT_SEAL 32827
-#define ID_EDIT_CLONE 32828
-#define ID_GRID_SNAP 32829
-#define ID_MODIFY_FLATTEN_X 32830
-#define ID_MODIFY_FLATTEN_Y 32831
-#define ID_MODIFY_FLATTEN_Z 32832
-#define ID_EDIT_SELECT_NONE 32833
-#define ID_NUDGE_RIGHT 32834
-#define ID_NUDGE_LEFT 32835
-#define ID_NUDGE_UP 32836
-#define ID_NUDGE_DOWN 32837
-#define ID_STEP_LEFT 32838
-#define ID_STEP_RIGHT 32839
-#define ID_STEP_UP 32840
-#define ID_STEP_DOWN 32841
-#define ID_VIEW_RENDER 32842
-#define ID_VIEW_ALL 32843
-#define ID_VIEW_FRONT 32844
-#define ID_VIEW_SIDE 32845
-#define ID_VIEW_TOP 32846
-#define ID_VIEW_PERSPECTIVE 32847
-#define ID_MODIFY_TEXTURE_MAP 32848
-#define ID_MODIFY_MATERIAL 32849
-#define ID_VIEW_MODE_WIREFRAME 32850
-#define ID_VIEW_MODE_SOLID 32851
-#define ID_VIEW_MODE_TEXTURED 32852
-#define ID_GRID_SHOW 32853
-#define ID_VIEW_BACK_COLOR 32854
-#define ID_EDIT_SELECT_INVERSE 32855
-#define ID_MODIFY_UV_MAP 32856
-#define ID_VIEW_SHADOWS 32857
-#define ID_VIEW_ANIMATELIGHT 32858
-#define ID_VIEW_BUMPMAPS 32859
-#define ID_VIEW_VERTEXSHADER 32860
-#define ID_VIEW_PIXELSHADER 32861
-#define ID_VIEW_VISIBLESHADOWS 32862
-#define ID_SURFACE_OPTIMIZE 32863
-#define ID_SURFACE_EXPLODE 32864
-
-// Next default values for new objects
-//
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_3D_CONTROLS 1
-#define _APS_NEXT_RESOURCE_VALUE 148
-#define _APS_NEXT_COMMAND_VALUE 32865
-#define _APS_NEXT_CONTROL_VALUE 1091
-#define _APS_NEXT_SYMED_VALUE 101
-#endif
-#endif
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by Magic.rc
+//
+#define ID_RESET 3
+#define IDC_NEW_MATERIAL 3
+#define ID_BACK_COLOR 4
+#define IDC_DEL_MATERIAL 4
+#define IDC_SELECT_POLYS 5
+#define IDD_ABOUTBOX 100
+#define IDR_MAINFRAME 128
+#define IDR_MAGICTYPE 129
+#define IDD_SURFACE_PROPS 130
+#define IDD_CAMERA_PROPS 131
+#define IDD_MODIFY_SURFACE 135
+#define IDD_VERTS_REDUCE 136
+#define IDD_MODIFY_POLY 137
+#define IDD_CREATE_CUBE 138
+#define IDD_CREATE_CYLINDER 139
+#define IDD_CREATE_SPHERE 140
+#define IDD_MODIFY_TEXTURE 141
+#define IDD_GRIDPROPS 142
+#define IDD_MODIFY_POLYS 143
+#define IDD_CREATE_POLY 144
+#define IDD_EXTRUSION_PROPS 146
+#define IDD_MODIFY_MATERIAL 147
+#define IDC_SURFACE_NAME 1000
+#define IDC_SURFACE_NVERTS 1001
+#define IDC_SURFACE_NPOLYS 1002
+#define IDC_SURFACE_COLOR 1003
+#define IDC_SURFACE_RADIUS 1003
+#define IDC_SURFACE_LENGTH 1004
+#define IDC_SURFACE_WIDTH 1005
+#define IDC_CAMERA_DISTANCE 1006
+#define IDC_SURFACE_HEIGHT 1006
+#define IDC_CAMERA_FOV 1007
+#define IDC_CAMERA_MODE 1008
+#define IDC_SURFACE_LIST 1009
+#define IDC_SURF_NAME 1010
+#define IDC_SURF_POLYS 1011
+#define IDC_SURF_COLOR 1012
+#define IDC_SURF_HIDDEN 1013
+#define IDC_SURF_LOCKED 1014
+#define IDC_SURF_CREATE 1015
+#define IDC_SURF_DISCARD 1016
+#define IDC_SURF_CLONE 1017
+#define IDC_SURF_DELETE 1018
+#define IDC_SURF_ADD_POLYS 1019
+#define IDC_THRESHOLD 1020
+#define IDC_SURF_ID 1020
+#define IDC_FLATTEN 1021
+#define IDC_FLIP_NORM 1022
+#define IDC_DOUBLE_SIDE 1023
+#define IDC_TRIANGULATE 1024
+#define IDC_REMOVE 1025
+#define IDC_POLY_VERTS 1026
+#define IDC_POLY_X 1027
+#define IDC_POLY_Y 1028
+#define IDC_POLY_Z 1029
+#define IDC_POLY_CURVE 1030
+#define IDC_POLY_SURF 1031
+#define IDC_POLY_TEX 1032
+#define IDC_LOC_X 1033
+#define IDC_LOC_Y 1034
+#define IDC_LOC_Z 1035
+#define IDC_SIZE_X 1036
+#define IDC_SIZE_Y 1037
+#define IDC_SIZE_Z 1038
+#define IDC_SECTORS 1039
+#define IDC_RINGS 1040
+#define IDC_GRID_SNAP 1041
+#define IDC_TEXTURE 1041
+#define IDC_MATERIAL 1041
+#define IDC_GRID_SIZE 1042
+#define IDC_MAPPING 1042
+#define IDC_GRID_SHOW 1043
+#define IDC_ALIGN_X 1043
+#define IDC_GRID_LINES 1044
+#define IDC_ALIGN_Y 1044
+#define IDC_GRID_DOTS 1045
+#define IDC_ALIGN_Z 1045
+#define IDC_SCALE_U 1046
+#define IDC_SCALE_V 1047
+#define IDC_TEXTURE_ADD 1048
+#define IDC_TEXTURE_DELETE 1049
+#define IDC_ALIGN_FLIP 1050
+#define IDC_ALIGN_MIRROR 1051
+#define IDC_ALIGN_ROTATE 1052
+#define IDC_TEXTURE_RELOAD 1053
+#define IDC_TEXTURE_PREVIEW 1054
+#define IDC_TEMPLATE 1055
+#define IDC_AMBIENT_COLOR 1055
+#define IDC_FLAG_FLAT 1056
+#define IDC_DIFFUSE_COLOR 1056
+#define IDC_FLAG_LUMINOUS 1057
+#define IDC_NSIDES 1057
+#define IDC_SPECULAR_COLOR 1057
+#define IDC_FLAG_TRANSLUCENT 1058
+#define IDC_EMISSIVE_COLOR 1058
+#define IDC_FLAG_TRANSPARENT 1059
+#define IDC_SECONDARY 1059
+#define IDC_FLAG_SPECULAR 1060
+#define IDC_FLAG_FLAT2 1061
+#define IDC_FLAG_LUMINOUS2 1062
+#define IDC_POLY_INDEX 1062
+#define IDC_FLAG_TRANSLUCENT2 1063
+#define IDC_FLAG_TRANSPARENT2 1064
+#define IDC_FLAG_SPECULAR2 1065
+#define IDC_FLAG_TEXCLAMP 1066
+#define IDC_DISTANCE 1067
+#define IDC_FLAG_SPECULAR22 1067
+#define IDC_FLAG_SPECULAR1 1068
+#define IDC_FLAG_SPECULAR12 1069
+#define IDC_FLAG_TEXCLAMP2 1070
+#define IDC_MATERIAL_LIST 1070
+#define IDC_MATERIAL_NAME 1071
+#define IDC_DIFFUSE_TEXTURE 1072
+#define IDC_SPECULAR_TEXTURE 1073
+#define IDC_EMISSIVE_TEXTURE 1074
+#define IDC_BUMP_TEXTURE 1075
+#define IDC_AMBIENT_VALUE 1076
+#define IDC_DIFFUSE_VALUE 1077
+#define IDC_SPECULAR_VALUE 1078
+#define IDC_EMISSIVE_VALUE 1079
+#define IDC_BUMP_VALUE 1080
+#define IDC_POWER_VALUE 1081
+#define IDC_BRILLIANCE_VALUE 1082
+#define IDC_BLEND_MODE 1083
+#define IDC_MATERIAL_PREVIEW 1084
+#define IDC_FILE_DIFFUSE 1085
+#define IDC_FILE_SPECULAR 1086
+#define IDC_REFERENCE_PLAN 1086
+#define IDC_FILE_EMISSIVE 1087
+#define IDC_REFERENCE_SIDE 1087
+#define IDC_FILE_BUMP 1088
+#define IDC_REFERENCE_FRONT 1088
+#define IDC_SHADOW 1089
+#define IDC_FILE_PLAN 1090
+#define IDC_MATERIAL_SHADER 1090
+#define IDC_FILE_SIDE 1091
+#define IDC_FILE_FRONT 1092
+#define ID_GRID_PROPS 32771
+#define ID_VIEW_ZOOM_IN 32771
+#define ID_VIEW_ZOOM_OUT 32772
+#define ID_VIEW_ZOOM_NORMAL 32773
+#define ID_VIEW_CENTER 32774
+#define ID_SURFACE_CREATE 32779
+#define ID_MODIFY_DRAG_VERTS 32780
+#define ID_CREATE_CUBE 32781
+#define ID_CREATE_TETRA 32782
+#define ID_MODIFY_EXTRUDE 32784
+#define ID_MODIFY_BEVEL 32785
+#define ID_MODIFY_STUD 32786
+#define ID_MODIFY_SUBDIVIDE 32787
+#define ID_PROP_SURFACE 32788
+#define ID_PROP_CAMERA 32789
+#define ID_EDIT_FLIP_NORMAL 32790
+#define ID_EDIT_REMOVE_POLY 32791
+#define ID_EDIT_MERGE_POLY 32792
+#define ID_MODIFY_TEXTURE 32795
+#define ID_OPTIONS_VERTEX_NORMALS 32798
+#define ID_PROP_GRID 32800
+#define ID_EDIT_DELETE 32801
+#define ID_CREATE_POLY 32802
+#define ID_CREATE_VERT 32803
+#define ID_CREATE_CYLINDER 32804
+#define ID_CREATE_SPHERE 32805
+#define ID_FILE_IMPORT 32806
+#define ID_FILE_EXPORT 32807
+#define ID_MODIFY_POLY 32808
+#define ID_MODIFY_VERTS 32809
+#define ID_VERTS_REDUCE 32810
+#define ID_VERTS_SNAP 32811
+#define ID_MODIFY_SCALE_VERTS 32812
+#define ID_MODIFY_ROTATE 32813
+#define ID_CREATE_CONE 32814
+#define ID_FINAL_RENDER 32815
+#define ID_MODIFY_SCALE_X 32817
+#define ID_MODIFY_SCALE_Z 32819
+#define ID_MODIFY_SCALE_Y 32822
+#define ID_MODIFY_SPLIT1 32824
+#define ID_MODIFY_SPLIT2 32825
+#define ID_EDIT_MIRROR 32826
+#define ID_EDIT_SEAL 32827
+#define ID_EDIT_CLONE 32828
+#define ID_GRID_SNAP 32829
+#define ID_MODIFY_FLATTEN_X 32830
+#define ID_MODIFY_FLATTEN_Y 32831
+#define ID_MODIFY_FLATTEN_Z 32832
+#define ID_EDIT_SELECT_NONE 32833
+#define ID_NUDGE_RIGHT 32834
+#define ID_NUDGE_LEFT 32835
+#define ID_NUDGE_UP 32836
+#define ID_NUDGE_DOWN 32837
+#define ID_STEP_LEFT 32838
+#define ID_STEP_RIGHT 32839
+#define ID_STEP_UP 32840
+#define ID_STEP_DOWN 32841
+#define ID_VIEW_RENDER 32842
+#define ID_VIEW_ALL 32843
+#define ID_VIEW_FRONT 32844
+#define ID_VIEW_SIDE 32845
+#define ID_VIEW_TOP 32846
+#define ID_VIEW_PERSPECTIVE 32847
+#define ID_MODIFY_TEXTURE_MAP 32848
+#define ID_MODIFY_MATERIAL 32849
+#define ID_VIEW_MODE_WIREFRAME 32850
+#define ID_VIEW_MODE_SOLID 32851
+#define ID_VIEW_MODE_TEXTURED 32852
+#define ID_GRID_SHOW 32853
+#define ID_VIEW_BACK_COLOR 32854
+#define ID_EDIT_SELECT_INVERSE 32855
+#define ID_MODIFY_UV_MAP 32856
+#define ID_VIEW_SHADOWS 32857
+#define ID_VIEW_ANIMATELIGHT 32858
+#define ID_VIEW_BUMPMAPS 32859
+#define ID_VIEW_VERTEXSHADER 32860
+#define ID_VIEW_PIXELSHADER 32861
+#define ID_VIEW_VISIBLESHADOWS 32862
+#define ID_SURFACE_OPTIMIZE 32863
+#define ID_SURFACE_EXPLODE 32864
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_3D_CONTROLS 1
+#define _APS_NEXT_RESOURCE_VALUE 148
+#define _APS_NEXT_COMMAND_VALUE 32865
+#define _APS_NEXT_CONTROL_VALUE 1091
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif