0001: /* low end viewer for triangulation files

0002:  * a short description of the <<.vtf>> files see function definition GraphicsDataInterpretation()

0003:  */
0004: #define UNICODE
0005: #include <windows.h>
0006: #include <stdio.h>
0007: #include <stdarg.h>
0008: #include <stdlib.h>
0009: #include <wchar.h>
0010: #include <GL/gl.h>
0011: #include <GL/glu.h>
0012: #include <sys/stat.h>
0013: #include <math.h>
0014: #include <process.h>
0015: #include <errno.h>
0016: #include "esperanto.h"
0017: #include "s_text.c"
0018: #include "dlg_utils.c"
0019: extern int errno;
0020: 
0021: #define L_Version_string L"0.0"
0022: 
0023: #define INTERNAL_LANG_ESPERANTO        0
0024: #define INTERNAL_LANG_ESPERANTO_XCODED 1
0025: #define INTERNAL_LANG_GERMAN           2
0026: #define INTERNAL_LANG_ENGLISH          3
0027: #define STARTUP_DEFAULT_LANG INTERNAL_LANG_ESPERANTO
0028: 
0029: #define NO_DUMP_MAT
0030: #define NO_CUBE
0031: #define NO_FADEN_1
0032: #define NO_FADEN_2
0033: #define NO_DUMP_VIEW_DATA
0034: #define NE_KUN_STATISTIKO
0035: #define NO_DUMP_MODEL_SELECT_RECORDS
0036: #ifdef FADEN_1
0037: #define FADEN_INIT
0038: #endif

0039: #ifdef FADEN_2
0040: #define FADEN_INIT
0041: #endif

0042: 
0043: #ifdef DUMP_MAT
0044: FILE *trail = NULL;
0045: #endif

0046: 
0047: #define        MdlDispClassName    L"RTD_Models"
0048: #define        AboutClassName      L"RTD_About"
0049: #define ThisClassName       L"RigardiloTriangularajDosieroj"
0050: #define ThisWindowName      L"Rigardilo por triangularaj dosieroj"
0051: #define ThisWindowNameGer   L"Triangulationsdateienbetrachter"
0052: #define ThisWindowNameEng   L"Triangulation File Viewer"
0053: #define RegistryBaseDir     L"Software\\Arnold.WENDL-Fuerth\\rtd"
0054: #define RegistryDir RegistryBaseDir L"\\" L_Version_string
0055: wchar_t *RevHistory[] = { L"0.0pre", L"0.0", NULL };
0056: wchar_t *KeywordHistory[] = { L"malantauxo rugxona", L"malantauxo verdona",
0057:                               L"malantauxo bluona", L"openGl listoj",
0058:                               L"malantauxa edro" L"montri centro", L"dimensio", L"X kodo", L"lingvo",
0059:                               L"simplaj coloroj", L"helaj korpoj", L"anstatauxaj prog", L"muso", NULL };
0060: 
0061: #define SLP_STL_ASCII_HEAD "solid "
0062: #define VTF_ASCII_HEAD "triangulara dosiero (.vtf)\r\n\32"
0063: 
0064: #define Title1en L"LOW END"
0065: #define Title2en L"TRIANGULATION FILE"
0066: #define Title3en L"VIEWER"
0067: #define Title1eo L"KAPABLETA"
0068: #define Title2eo L"RIGARDILO POR"
0069: #define Title3eo L"TRIANGULARAJ DOSIEROJ"
0070: #define Versn_en L"Version " L_Version_string
0071: #define Versn_eo L"Versio " L_Version_string
0072: #define VSW 0.70F
0073: #define VSC 3.45F
0074: 
0075: #define MN_FILE_OPEN 201
0076: #define MN_FILE_SAVE 202
0077: #define MN_FILE_QUIT 203
0078: #define MN_VIEW_LEFT   210
0079: #define MN_VIEW_FRONT  211
0080: #define MN_VIEW_RIGHT  212
0081: #define MN_VIEW_BACK   213
0082: #define MN_VIEW_TOP    214
0083: #define MN_VIEW_BOTTOM 215
0084: #define MN_VIEW_ISO    216
0085: #define MN_VIEW_DI     217
0086: #define MN_VIEW_TRI    218
0087: #define MN_ZOOM_PLUS   220
0088: #define MN_ZOOM_MINUS  221
0089: #define MN_ZOOM_FIT    222
0090: #define MN_PART_DISP   230
0091: #define MN_MOUSE_L_INV 231
0092: #define MN_MOUSE_M_INV 232
0093: #define MN_MOUSE_R_INV 233
0094: #define MN_REPAINT     239    /* invisible */
0095: #define MN_SET_BACKGRND  240
0096: #define MN_SET_LIGHTY    241
0097: #define MN_SET_SIMPLCOL  242
0098: #define MN_SET_LISTS     243
0099: #define MN_SET_WIREFRAME 244
0100: #define MN_SET_CULL      245
0101: #define MN_SET_CS        246
0102: #define MN_SET_EXTEND    247
0103: #define MN_SET_CALLEXIT  248
0104: #define RT_SET_LANG      249  /* object dialog window */
0105: #define MN_SET_LANG_EO   350
0106: #define MN_SET_LANG_EOX  351
0107: #define MN_SET_LANG_GER  352
0108: #define MN_SET_LANG_ENG  353
0109: #define MN_INFO          299
0110: #define RT_CLEAR_CHECKBOXES 170
0111: #define RT_BUILD_CHECKBOXES 171
0112: #define MN_OBJECT_ZERO   300
0113: 
0114: #define PROJ_LAST   0
0115: #define PROJ_FRONT  1
0116: #define PROJ_LEFT   2
0117: #define PROJ_TOP    3
0118: #define PROJ_BOTTOM 4
0119: #define PROJ_RIGHT  5
0120: #define PROJ_BACK   6
0121: #define PROJ_ISO    7
0122: #define PROJ_DI     8
0123: #define PROJ_TRI    9
0124: 
0125: int Argc;
0126: wchar_t **Argv;
0127: int CmdLineFileRead = 0, CmdLineFirstFileBasenameStart = 0,
0128:                          CmdLineFirstFileExtensionStart = 0;
0129: HICON MyIcon, MySmallIcon;
0130: HINSTANCE hThisInstance;
0131: 
0132: struct ES_DIALOG_DATA {
0133:   int record_size;
0134:   int prompt_launching;
0135:   struct PER_FILETYPE {
0136:     int enabled;
0137:     wchar_t Program[MAX_PATH], ProgramBasename[MAX_PATH];
0138:     int with_optional_param;
0139:     wchar_t OptionalParam[MAX_PATH];
0140:   } VtfSlpStl[3];
0141: } ES_Settings;
0142: 
0143: void Clear_ES_Settings(void)
0144: { memset(&ES_Settings, 0, sizeof(struct ES_DIALOG_DATA));
0145:   ES_Settings.record_size = sizeof(struct ES_DIALOG_DATA);
0146:   ES_Settings.prompt_launching = 1;
0147: }
0148: 
0149: int compact_ES_Data(wchar_t *z, struct ES_DIALOG_DATA *dd)
0150: { int erg, i;
0151:   erg = 0;
0152:   z[erg] = dd->record_size;      erg++;
0153:   z[erg] = dd->prompt_launching; erg++;
0154:   for (i = 0; i < 3; i++) {
0155:     z[erg] = dd->VtfSlpStl[i].enabled; erg++;
0156:     wcsncpy(&(z[erg]), dd->VtfSlpStl[i].Program,         MAX_PATH); z[erg + MAX_PATH - 1] = 0;
0157:      erg += wcslen(&(z[erg])) + 1;
0158:     wcsncpy(&(z[erg]), dd->VtfSlpStl[i].ProgramBasename, MAX_PATH); z[erg + MAX_PATH - 1] = 0;
0159:      erg += wcslen(&(z[erg])) + 1;
0160:     z[erg] = dd->VtfSlpStl[i].with_optional_param; erg++;
0161:     wcsncpy(&(z[erg]), dd->VtfSlpStl[i].OptionalParam,   MAX_PATH); z[erg + MAX_PATH - 1] = 0;
0162:      erg += wcslen(&(z[erg])) + 1;
0163:   }
0164:   return erg;
0165: }
0166: 
0167: int uncompact_ES_Data(struct ES_DIALOG_DATA *dd, wchar_t *z)
0168: { int pos, i;
0169:   pos = 0;
0170:   if (z[0] != sizeof(struct ES_DIALOG_DATA)) return 0;
0171:   memset(dd, 0, sizeof(struct ES_DIALOG_DATA));
0172:   dd->record_size = z[0]; 
0173:   dd->prompt_launching = z[1]; pos = 2;
0174:   for (i = 0; i < 3; i++) {
0175:     dd->VtfSlpStl[i].enabled = z[pos]; pos++;
0176:     wcsncpy(dd->VtfSlpStl[i].Program,         &(z[pos]), MAX_PATH); pos += wcslen(&(z[pos])) + 1;
0177:     wcsncpy(dd->VtfSlpStl[i].ProgramBasename, &(z[pos]), MAX_PATH); pos += wcslen(&(z[pos])) + 1;
0178:     dd->VtfSlpStl[i].with_optional_param = z[pos]; pos++;
0179:     wcsncpy(dd->VtfSlpStl[i].OptionalParam,   &(z[pos]), MAX_PATH); pos += wcslen(&(z[pos])) + 1;
0180:   }
0181:   return 1;
0182: }
0183: 
0184: #ifdef FADEN_INIT
0185: void cPrintfI(char *fmt, int i)
0186: { char Zeile[300]; wchar_t WZ[300];
0187:   int erg;
0188:   sprintf(Zeile, fmt, i); wsprintf(WZ, L"%S", Zeile);
0189:   WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), WZ, strlen(Zeile), &erg, NULL); 
0190: }
0191: 
0192: void cPrintfF(char *fmt, float i)
0193: { char Zeile[300]; wchar_t WZ[300];
0194:   int erg;
0195:   sprintf(Zeile, fmt, i); wsprintf(WZ, L"%S", Zeile);
0196:   WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), WZ, strlen(Zeile), &erg, NULL); 
0197: }
0198: #else

0199: #define cPrintfI(a, b) 
0200: #define cPrintfF(a, b) 
0201: #undef DUMP_VIEW_DATA
0202: #endif

0203: 
0204: /* if not UNICODE font prefere this set to TRUE: */
0205: X_CODING = STARTUP_DEFAULT_LANG;
0206: 
0207: /* simple color */
0208: simple_color = 0;
0209: 
0210: /* more lighty colors */
0211: lighty_models = 0;
0212: 
0213: /* opposite mouse actions */
0214: mouse_inversion = 0;
0215: 
0216: /* Startup projection */
0217: int Projection = PROJ_TRI;
0218: 
0219: /* Background color */
0220: #define BG_R 0
0221: #define BG_G 0
0222: #define BG_B 64
0223: DWORD SBG_R = BG_R, SBG_G = BG_G, SBG_B = BG_B;
0224: GLclampf bg_r = BG_R / 255.0F, bg_g = BG_G / 255.0F, bg_b = BG_B / 255.0F;
0225: COLORREF Farbfeld[16] = {
0226:     RGB(BG_R, BG_G, BG_B), RGB(BG_R, BG_G, BG_B),
0227:     RGB(BG_R, BG_G, BG_B), RGB(BG_R, BG_G, BG_B),
0228:     RGB(BG_R, BG_G, BG_B), RGB(BG_R, BG_G, BG_B),
0229:     RGB(BG_R, BG_G, BG_B), RGB(BG_R, BG_G, BG_B),
0230:     RGB(BG_R, BG_G, BG_B), RGB(BG_R, BG_G, BG_B),
0231:     RGB(BG_R, BG_G, BG_B), RGB(BG_R, BG_G, BG_B),
0232:     RGB(BG_R, BG_G, BG_B), RGB(BG_R, BG_G, BG_B),
0233:     RGB(BG_R, BG_G, BG_B), RGB(BG_R, BG_G, BG_B) };
0234: 
0235: /* Options modified */
0236: int options_altered = 0;
0237: 
0238: /* Show CS at startup */
0239: int Disp_CS = 1;
0240: 
0241: /* Show Extend at startup */
0242: int Disp_Extend = 0;
0243: 
0244: /* Off course, no WIREFRAME display at startup */
0245: int Wireframe = 0;
0246: 
0247: /* Cullface at startup */
0248: int CullFace = 0;
0249: 
0250: /* Use openGL lists */
0251: int UseLists = 0, RebuildLists = 1;
0252: 
0253: /* Keep Border? */
0254: #define RANDFAKTOR 1.05
0255: 
0256: /* GL lightning parameters */
0257: GLfloat specular  [] = { 1.0F, 1.0F, 1.0F, 1.0F };
0258: GLfloat shininess [] = { 70.0F };
0259: GLfloat position  [] = { 0.0F, 0.0F, 50.0F, 0.0F };
0260: GLfloat position0 [] = {-10.0F, 15.0F, 50.0F, 0.0F };
0261: GLfloat ambient   [] = { 0.15F, 0.15F, 0.15F, 1.0F };
0262: GLfloat diffuse   [] = { 0.35F, 0.35F, 0.35F, 1.0F };
0263: 
0264: HWND hwndApplication, hwndObjectDisplayDialog = NULL;
0265: HGLRC hglrc;
0266: HMENU optionsmenu, filemenu, viewmenu, mousemenu, langmenu = NULL;
0267: 
0268: #ifdef CUBE
0269: #define VersX 10.0
0270: #define VersY 20.0
0271: #define VersZ 70.0
0272: #define a_halb 1.5
0273: #endif

0274: 
0275: 
0276: int short_in_mapping, long_in_mapping, float_in_mapping, double_in_mapping;
0277: 
0278: int SWAPING[8][8] = {
0279:   { 0, 1, 2, 3, 4, 5, 6, 7 },
0280:   { 1, 0, 3, 2, 5, 4, 7, 6 },
0281:   { 2, 3, 0, 1, 6, 7, 4, 5 },
0282:   { 3, 2, 1, 0, 7, 6, 5, 4 },
0283:   { 4, 5, 6, 7, 0, 1, 2, 3 },
0284:   { 5, 4, 7, 6, 1, 0, 3, 2 },
0285:   { 6, 7, 4, 5, 2, 3, 0, 1 },
0286:   { 7, 6, 5, 4, 3, 2, 1, 0 } };
0287: 
0288: union SWAP2 {
0289:   unsigned short us;
0290:   short          s;
0291:   unsigned char  c[2];
0292: };
0293: 
0294: union SWAP4 {
0295:   unsigned long ul;
0296:   long          l;
0297:   float         f;
0298:   unsigned char c[4];
0299: };
0300: 
0301: union SWAP8 {
0302:   unsigned __int64 uxl;
0303:   __int64          xl;
0304:   double           d;
0305:   unsigned char    c[8];
0306: };
0307: 
0308: /* Extend of the model */
0309: GLdouble xmin, xmax,  ymin, ymax,  zmin, zmax;
0310: unsigned long total_facet_count;
0311: /* center, diagonal and required scaling to fit into the screen */
0312: GLdouble xc, yc, zc, scale, halfdiagonal;
0313: double view_scale = 1.0, view_x = 0.0, view_y = 0.0;
0314: #define DefaultZoomFaktor sqrt(sqrt(8.0))
0315: #define MaxZoomFaktor 512.0
0316: 
0317: /* screen size info */
0318: float screen_center_x, screen_center_y, screen_size;
0319: 
0320: /* Saved Model Matrix (rotation only) */
0321: GLdouble MVMat[16];
0322: 
0323: wchar_t *StrByLang(int lang, ...)
0324: { int ct;
0325:   wchar_t *erg, *next;
0326:   va_list ap;
0327: 
0328:   erg = NULL;
0329:   va_start(ap, lang);
0330:   for (ct = 0;; ct++) {
0331:     next = va_arg(ap, wchar_t *);
0332:     if (next == NULL) { va_end(ap); return erg; }
0333:     if (wcscmp(next, L"\xffff")) erg = next;
0334:     if (ct == lang) { va_end(ap); return erg; }
0335:   }
0336:   /* va_end(ap); return erg; */
0337: }
0338: 
0339: float TFloatByLang(int lang, ...)
0340: { int ct;
0341:   long erg, next;
0342:   va_list ap;
0343: 
0344:   erg = 0L;
0345:   va_start(ap, lang);
0346:   for (ct = 0;; ct++) {
0347:     next = va_arg(ap, long);
0348:     if (next == 0L) { va_end(ap); return((float) erg / 1000.0F); }
0349:     erg = next;
0350:     if (ct == lang) { va_end(ap); return((float) erg / 1000.0F); }
0351:   }
0352:   /* va_end(ap); return erg; */
0353: }
0354: 
0355: #define LangWindowName StrByLang(X_CODING, ThisWindowName, L"\xffff", ThisWindowNameGer, ThisWindowNameEng, NULL)
0356: 
0357: #ifdef DUMP_MAT
0358: void dump_Mat(void)
0359: { int z, s;
0360:   if (trail == NULL) return;
0361:   fprintf(trail, "\n");
0362:   for (z = 0; z < 4; z++) {
0363:     for (s = 0; s < 16; s += 4)
0364:       fprintf(trail, "%8.4lf  ", (double) MVMat[s + z]);
0365:     fprintf(trail, "\n");
0366:   }
0367:   fflush(trail);
0368: }
0369: #else

0370: #define dump_Mat()
0371: #endif

0372: 
0373: float scol_r, scol_g, scol_b;
0374: 
0375: void SimpleColorSave(float r, float g, float b)
0376: { scol_r = r; scol_g = g; scol_b = b;
0377: }
0378: 
0379: void SimpleColorSetNormal(double nx, double ny, double nz)
0380: { double px, py, pz;
0381:   float dir;
0382:   px = MVMat[0] * nx + MVMat[4] * ny + MVMat[ 8] * nz;
0383:   py = MVMat[1] * nx + MVMat[5] * ny + MVMat[ 9] * nz;
0384:   pz = MVMat[2] * nx + MVMat[6] * ny + MVMat[10] * nz;
0385:   dir = (float) pow(pz * pz / ( px * px + py * py + pz * pz), 0.4);
0386:   if (lighty_models) glColor3f(dir * (0.5F + 0.5F * scol_r),
0387:                                dir * (0.5F + 0.5F * scol_g),
0388:                                dir * (0.5F + 0.5F * scol_b));
0389:    else glColor3f(dir * scol_r, dir * scol_g, dir * scol_b);
0390: }
0391: 
0392: struct Nomo {
0393:   unsigned long size_n_flags;
0394:   wchar_t ObjectName[0];
0395: }; /* 1/2 * 8 bytes + x */
0396: 
0397: struct Dauxrigo {
0398:   unsigned long size_n_flags;
0399:   void * There;
0400: }; /* 1 * 8 bytes */
0401: 
0402: struct Triangulo {
0403:   unsigned long size_n_flags;
0404:   unsigned long repeated;
0405:   double        coordinates[0];
0406: }; /* 1 * 8 bytes + n * 8 bytes */
0407: 
0408: struct Trianguleto {
0409:   unsigned long size_n_flags;
0410:   unsigned long repeated;
0411:   float         coordinates[0];
0412: }; /* 1 * 8 bytes + n / 2 * 8 bytes */
0413: 
0414: struct Triangulatoro {
0415:   unsigned long size_n_flags;
0416:   unsigned long repeated;
0417:   unsigned long index[0];
0418: }; /* 1 * 8 bytes + n / 2 * 8 bytes */
0419: 
0420: struct Coloro {
0421:   unsigned long size_n_flags;
0422:   float r, g, b;
0423: }; /* 16 bytes = 2 * 8 bytes */
0424: 
0425: union Unu {
0426:   struct Coloro        coloro;
0427:   struct Triangulo     triangulo;
0428:   struct Trianguleto   trianguleto;
0429:   struct Triangulatoro triangulatoro;
0430:   struct Dauxrigo      dauxrigo;
0431:   struct Nomo          nomo;
0432:   unsigned __int64     Data[1];
0433: };
0434: 
0435: struct Memorilo {
0436:   struct Memorilo *next_block;
0437:   unsigned long capacity;
0438:   unsigned long next_free;
0439:   void *        next_free_p;
0440:   unsigned __int64 Data[0];
0441: } *TDate = NULL, *TDate_Current = NULL;
0442: 
0443: void swap2(void *dta, int mode)
0444: { union SWAP2 erg;
0445:   int ct;
0446:   for (ct = 0; ct < 2; ct++) erg.c[SWAPING[mode][ct]] = ((union SWAP2 *) dta)->c[ct];
0447:   ((union SWAP2 *) dta)->us = erg.us;
0448: }
0449: 
0450: void swap4(void *dta, int mode)
0451: { union SWAP4 erg;
0452:   int ct;
0453:   for (ct = 0; ct < 4; ct++) erg.c[SWAPING[mode][ct]] = ((union SWAP4 *) dta)->c[ct];
0454:   ((union SWAP4 *) dta)->ul = erg.ul;
0455: }
0456: 
0457: void swap8(void *dta, int mode)
0458: { union SWAP8 erg;
0459:   int ct;
0460:   for (ct = 0; ct < 8; ct++) erg.c[SWAPING[mode][ct]] = ((union SWAP8 *) dta)->c[ct];
0461:   ((union SWAP8 *) dta)->uxl = erg.uxl;
0462: }
0463: 
0464: struct HEAD {
0465:   unsigned char t[30];
0466:   wchar_t       us;
0467:   unsigned long ul;
0468:   float         f;
0469:   double        d;
0470: };
0471: 
0472: /* How many valid models */
0473: int VALID_MODELS = 0, IN_FILE_DIALOG = 0;
0474: int ObjectsShowAll = 1, stored_model_references = 0;
0475: 
0476: struct MODEL_SELECT {
0477:   union Unu *Start;
0478:   wchar_t *Name;
0479:   union Unu *ValidCoords;
0480:   int ValidCoordType;
0481:   int Number, Display;
0482:   HWND Checkbox;
0483:   struct MODEL_SELECT *next;
0484: } *model_select_chain = NULL, *model_select_chain_last;
0485: 
0486: #ifdef DUMP_MODEL_SELECT_RECORDS
0487: void DumpModelSelectRecord(void)
0488: { struct MODEL_SELECT *ms;
0489:   wchar_t T[3000];
0490:   int ct = 0;
0491:   wcscpy(T, L"model_select_chain:");
0492:   for (ms = model_select_chain; ms != NULL; ms = ms->next) {
0493:     wsprintf(&(T[wcslen(T)]), L"\n%d: \"%s\" CA(%d)-<%.8lx> @%.8lx Disp=%d",
0494:       ms->Number,
0495:       (ms->Name == NULL) ? L"<null>" : ms->Name,
0496:       ms->ValidCoordType, (unsigned long) (ms->ValidCoords), (unsigned long) ms->Start,
0497:       ms->Display);
0498:     ct++;
0499:   }
0500:   wsprintf(&(T[wcslen(T)]), L"\n< %d >\nstored_model_references = %d\nVALID_MODLES = %d ",
0501:     ct, stored_model_references, VALID_MODELS);
0502:   MessageBox(NULL, T, L"msc", MB_ICONINFORMATION | MB_OK);
0503: }
0504: #endif

0505: 
0506: int AddModelSelectRecord(void)
0507: { struct MODEL_SELECT *neu;
0508:   if ((neu = malloc(sizeof(struct MODEL_SELECT))) == NULL) return 0;
0509:   neu->Start = NULL; neu->Name = NULL; neu->Number = 0; neu->Display = -1;
0510:   neu->ValidCoords = NULL; neu->ValidCoordType = -1;
0511:   neu->Checkbox = NULL; neu->next = NULL;
0512:   if (model_select_chain == NULL) model_select_chain = neu;
0513:   else
0514:   if (model_select_chain_last != NULL) model_select_chain_last->next = neu;
0515:   model_select_chain_last = neu;
0516:   return 1;
0517: }
0518: 
0519: void AddModelReference(union Unu *Strt, wchar_t *Nm, union Unu *VC, int VCT)
0520: { struct MODEL_SELECT *ms;
0521:   for (ms = model_select_chain; ms != NULL; ms = ms->next) {
0522:     if (ms->Name == NULL) goto add_there;
0523:   }
0524:   if (!AddModelSelectRecord()) return;
0525:   ms = model_select_chain_last;
0526:   add_there:
0527:   if (ms == NULL) return;
0528:   ms->Number = ++stored_model_references;
0529:   ms->Name = Nm; ms->Start = Strt;
0530:   ms->ValidCoords = VC; ms->ValidCoordType = VCT;
0531:   // { wchar_t T[9]; wsprintf(T, L"%d", __LINE__); MessageBox(NULL, T, L"Trail", MB_ICONINFORMATION | MB_OK); }

0532:   /*

0533:   { wchar_t T[300];

0534:     wsprintf(T, L"Solid '%s'", Nm);

0535:     MessageBox(NULL, T, L"Addig Model Reference (Start Pointer)", MB_ICONINFORMATION | MB_OK);

0536:   }

0537:   */
0538: }
0539: 
0540: void UnlinkModelSelectItems(void)
0541: { struct MODEL_SELECT *sm;
0542:   if (hwndObjectDisplayDialog == NULL) return;
0543:   for (sm = model_select_chain; sm != NULL; sm = sm->next) {
0544:     if (sm->Checkbox != NULL) {
0545:       ShowWindow(sm->Checkbox, SW_HIDE);
0546:       sm->Display = -1;
0547:     }
0548:   }
0549: }
0550: 
0551: void ClearModelSelectItems(void)
0552: { struct MODEL_SELECT *sm;
0553:   for (sm = model_select_chain; sm != NULL; sm = sm->next) {
0554:     sm->Name = NULL; sm->Start = NULL;
0555:     sm->Number = 0;
0556:     sm->ValidCoords = NULL; sm->ValidCoordType = -1;
0557:   }
0558:   stored_model_references = 0;
0559: }
0560: 
0561: 
0562: void Initialize_Local_Parameters(void)
0563: { wchar_t *T;
0564:   Clear_ES_Settings();
0565:   if ((T = _wgetenv(L"mylang")) == NULL) T = _wgetenv(L"LANG");
0566:   if (T != NULL) {
0567:     if (!wcscmp(T, L"esperanto")) X_CODING = 0;
0568:     else
0569:     if (!wcscmp(T, L"esperanto-x")) X_CODING = 1;
0570:     else
0571:     if (!wcscmp(T, L"german")) X_CODING = 2;
0572:     else
0573:     if (!wcscmp(T, L"english")) X_CODING = 3;
0574:   }
0575: }
0576: 
0577: void try_launching(int typeno, wchar_t *datei)
0578: { int erg; wchar_t T[100 + 2 * MAX_PATH];
0579:   if (ES_Settings.prompt_launching) {
0580:     wsprintf(T, StrByLang(X_CODING,
0581:                 US_CX L"u apertas dosiero \273%s\253 kun programon \273%s\253?",
0582:                 L"Cxu apertas dosiero \273%s\253 kun programon \273%s\253?",
0583:                 L"Datei '%s' mit Programm '%s' öffnen?",
0584:                 L"To open file '%s' launch program '%s' now?", NULL),
0585:                 datei, ES_Settings.VtfSlpStl[typeno].Program);
0586:     if (MessageBox(hwndApplication, T, StrByLang(X_CODING,
0587:                                                  L"nekonata enhavo en tiu " US_cx L"i dosiero!",
0588:                                                  L"nekonata enhavo en tiu cxi dosiero!",
0589:                                                  L"unbekanntes Dateiformat in dieser Datei!",
0590:                                                  L"this file is an unknown file format!",
0591:                                                  NULL),
0592:                    MB_ICONQUESTION | MB_YESNOCANCEL) != IDYES) return;
0593:   }
0594:   if (ES_Settings.VtfSlpStl[typeno].with_optional_param)
0595:     erg = _wexecl(ES_Settings.VtfSlpStl[typeno].Program,
0596:                   ES_Settings.VtfSlpStl[typeno].ProgramBasename,
0597:                   ES_Settings.VtfSlpStl[typeno].OptionalParam,
0598:                   datei, NULL);
0599:    else
0600:     erg = _wexecl(ES_Settings.VtfSlpStl[typeno].Program,
0601:                   ES_Settings.VtfSlpStl[typeno].ProgramBasename,
0602:                   datei, NULL);
0603:   if (erg) {
0604:     switch (errno) {
0605:       case EACCES:  wsprintf(T, L"(%d) \"%s\"", errno, StrByLang(X_CODING,
0606:                              L"alira eraro", L"\xffff",
0607:                              L"Zugriff verweigert",
0608:                              L"No access", NULL));
0609:                     break;
0610:       case EMFILE:  wsprintf(T, L"(%d) \"%s\"", errno, StrByLang(X_CODING,
0611:                              L"tro multe da malfermaj dosieroj", L"\xffff",
0612:                              L"Zu viele offene Dateien",
0613:                              L"Too many open files", NULL));
0614:                     break;
0615:       case ENOENT:  wsprintf(T, L"(%d) \"%s\"", errno, StrByLang(X_CODING,
0616:                              L"ne trovas dosieron a" US_ux L" ser" US_cx L"vojo",
0617:                              L"ne trovas dosieron aux sercxvojo",
0618:                              L"Pfad oder Dateiname nicht gefunden",
0619:                              L"Path of file name not found", NULL));
0620:                     break;
0621:       case ENOEXEC: wsprintf(T, L"(%d) \"%s\"", errno, StrByLang(X_CODING,
0622:                              L"eraro da pretigo de \273EXEC\253", L"\xffff",
0623:                              L"Falsches EXEC-Dateiformat",
0624:                              L"Exec format error", NULL));
0625:                     break;
0626:       case ENOMEM:  wsprintf(T, L"(%d) \"%s\"", errno, StrByLang(X_CODING,
0627:                              L"tro malmulte da storo", L"\xffff",
0628:                              L"Zu wenig freier Speicher",
0629:                              L"Not enough memory", NULL));
0630:                     break;
0631:       default:      wsprintf(T, L"%s %d", StrByLang(X_CODING,
0632:                              L"Eraro No.", L"\xffff",
0633:                              L"Fehler Nummer ",
0634:                              L"Error number ", NULL), errno);
0635:                     break;
0636:     }
0637:     MessageBox(hwndApplication, T, StrByLang(X_CODING,
0638:                                              L"eraro da starto de aplika programo", L"\xffff",
0639:                                              L"Applikationsstartfehler:",
0640:                                              L"Launching Error:", NULL),
0641:                MB_OK | MB_ICONINFORMATION);
0642:   }
0643: }
0644: 
0645: int ItsVTFtype(FILE *ein, int *short_in_mapping, int *long_in_mapping,
0646:                 int *float_in_mapping, int *double_in_mapping)
0647: { int test, gl, p;
0648:   union SWAP2 /* us, s, c[2]      */ s2, S2;
0649:   union SWAP4 /* ul, l, f, c[4]   */ s4, S4;
0650:   union SWAP8 /* uxl, xl, d, c[8] */ s8, S8;
0651:   struct HEAD head;
0652:   head.t[29] = 1;
0653:   fread(&head, 1, sizeof(struct HEAD), ein); fseek(ein, 0L, SEEK_SET);
0654:   if (head.t[29]) return 0;
0655:   if (strcmp(head.t, VTF_ASCII_HEAD)) return 0;
0656:   /* the lower byte of the short word must be greater */
0657:   s2.us = head.us; S2.us = 1;
0658:   if (s2.c[0] == s2.c[1]) return 0;
0659:   if (s2.c[0] > s2.c[1]) { s2.c[0] = 1; s2.c[1] = 0; } else { s2.c[0] = 0; s2.c[1] = 1; }
0660:   *short_in_mapping = -1;
0661:   for (test = 0; test < 2; test++) {
0662:     gl = 1;
0663:     for (p = 0; p < 2; p++) {
0664:       if (s2.c[SWAPING[test][p]] != S2.c[p]) gl = 0;
0665:     }
0666:     if (gl) { *short_in_mapping = test; test = 9; }
0667:   }
0668:   if (*short_in_mapping < 0) return 0;
0669:   /* the bytes of the long word must match exactly */
0670:   s4.ul = head.ul; S4.ul = 987654321L;
0671:   *long_in_mapping = -1;
0672:   for (test = 0; test < 4; test++) {
0673:     gl = 1;
0674:     for (p = 0; p < 4; p++) {
0675:       if (s4.c[SWAPING[test][p]] != S4.c[p]) gl = 0;
0676:     }
0677:     if (gl) { *long_in_mapping = test; test = 9; }
0678:   }
0679:   if (*long_in_mapping < 0) return 0;
0680:   /* the bytes of the float must match exactly */
0681:   s4.f = head.f; S4.f = 7654321.0F;
0682:   *float_in_mapping = -1;
0683:   for (test = 0; test < 4; test++) {
0684:     gl = 1;
0685:     for (p = 0; p < 4; p++) {
0686:       if (s4.c[SWAPING[test][p]] != S4.c[p]) gl = 0;
0687:     }
0688:     if (gl) { *float_in_mapping = test; test = 9; }
0689:   }
0690:   if (*float_in_mapping < 0) return 0;
0691:   /* the bytes of the double must match exactly */
0692:   s8.d = head.d; S8.d = 9876543210123456.0;
0693:   *double_in_mapping = -1;
0694:   for (test = 0; test < 8; test++) {
0695:     gl = 1;
0696:     for (p = 0; p < 8; p++) {
0697:       if (s8.c[SWAPING[test][p]] != S8.c[p]) gl = 0;
0698:     }
0699:     if (gl) { *double_in_mapping = test; test = 9; }
0700:   }
0701:   if (*double_in_mapping < 0) return 0;
0702:   /* success */
0703:   return 1;
0704: }
0705: 
0706: void clear_triangulation(void)
0707: { struct Memorilo *This, *Next;
0708:   for (This = TDate; This != NULL; This = Next) {
0709:     Next = This->next_block;
0710:     free(This);
0711:   }
0712:   TDate = NULL; TDate_Current = NULL;
0713: }
0714: 
0715: void alloc_memory_block(unsigned long how_much)
0716: { unsigned long words_to_align, bytes_to_align;
0717:   struct Memorilo *neu;
0718:   words_to_align = (how_much < 20L) ? 65536L : how_much;
0719:   bytes_to_align = 8L * words_to_align + sizeof(struct Memorilo);
0720:   if ((neu = malloc(bytes_to_align)) == NULL) {
0721:     return;
0722:   }
0723:   neu->next_block = NULL;
0724:   neu->capacity = words_to_align;
0725:   neu->next_free = 0;
0726:   neu->next_free_p = &(neu->Data[0]);
0727:   if (TDate_Current != NULL) {
0728:     TDate_Current->next_block = neu;
0729:     ((struct Dauxrigo *) (TDate_Current->next_free_p))->size_n_flags = 0xc0000001L;
0730:     ((struct Dauxrigo *) (TDate_Current->next_free_p))->There = neu->next_free_p;
0731:     (TDate_Current->next_free)++;
0732:     TDate_Current->next_free_p = &(TDate_Current->Data[TDate_Current->next_free]);
0733:   }
0734:   TDate_Current = neu;
0735:   if (TDate == NULL) TDate = neu;
0736: }
0737: 
0738: void store_end(void)
0739: { if (TDate_Current == NULL) return;
0740:   ((struct Dauxrigo *) (TDate_Current->next_free_p))->size_n_flags = 0xf0000001;
0741: }
0742: 
0743: void store_endsolid(void)
0744: { unsigned long QWords_to_store;
0745:   QWords_to_store = 1;
0746:   if ((TDate_Current == NULL)
0747:    || (TDate_Current->capacity < TDate_Current->next_free + QWords_to_store + 5UL))
0748:     alloc_memory_block(0UL);
0749:   if (TDate_Current == NULL) return;
0750:   ((struct Dauxrigo *) (TDate_Current->next_free_p))->size_n_flags = 0x90000001;
0751:   ((struct Dauxrigo *) (TDate_Current->next_free_p))->There = NULL;
0752:   TDate_Current->next_free += QWords_to_store;
0753:   TDate_Current->next_free_p = &(TDate_Current->Data[TDate_Current->next_free]);
0754:   store_end();
0755: }
0756: 
0757: void store_beginsolid(char *Name)
0758: { unsigned long QWords_to_store;
0759:   unsigned int Strlg;
0760:   Strlg = strlen(Name) + 3;
0761:   while (Strlg & 3) Strlg++;
0762:   QWords_to_store = Strlg / 4;
0763:   if ((TDate_Current == NULL)
0764:    || (TDate_Current->capacity < TDate_Current->next_free + QWords_to_store + 5UL))
0765:     alloc_memory_block(0UL);
0766:   if (TDate_Current == NULL) return;
0767:   ((union Unu *) (TDate_Current->next_free_p))->Data[QWords_to_store - 1] = 0;
0768:   ((struct Nomo *) (TDate_Current->next_free_p))->size_n_flags = 0x80000000 + QWords_to_store;
0769:   for (Strlg = 0; Name[Strlg]; Strlg++)
0770:     ((struct Nomo *) (TDate_Current->next_free_p))->ObjectName[Strlg]
0771:       = (wchar_t) ((unsigned char) Name[Strlg]);
0772:   AddModelReference((union Unu *)(TDate_Current->next_free_p),
0773:                     ((struct Nomo *)(TDate_Current->next_free_p))->ObjectName,
0774:                     NULL, -1);
0775:     /* VTF-Dateien haben andere 2. und 3. Parameter! */
0776:   // DumpModelSelectRecord();

0777:   TDate_Current->next_free += QWords_to_store;
0778:   TDate_Current->next_free_p = &(TDate_Current->Data[TDate_Current->next_free]);
0779:   store_end();
0780: }
0781: 
0782: void store_set_color(float r, float g, float b)
0783: { unsigned long QWords_to_store;
0784:   QWords_to_store = 2;
0785:   if ((TDate_Current == NULL)
0786:    || (TDate_Current->capacity < TDate_Current->next_free + QWords_to_store + 5UL))
0787:     alloc_memory_block(0UL);
0788:   if (TDate_Current == NULL) return;
0789:   ((struct Coloro *) (TDate_Current->next_free_p))->size_n_flags = 0x40000000L + QWords_to_store;
0790:   ((struct Coloro *) (TDate_Current->next_free_p))->r = r;
0791:   ((struct Coloro *) (TDate_Current->next_free_p))->g = g;
0792:   ((struct Coloro *) (TDate_Current->next_free_p))->b = b;
0793:   TDate_Current->next_free += QWords_to_store;
0794:   TDate_Current->next_free_p = &(TDate_Current->Data[TDate_Current->next_free]);
0795:   store_end();
0796: }
0797: 
0798: void store_facet_short(float Nx, float Ny, float Nz, float *vx, float *vy, float *vz)
0799: { unsigned long QWords_to_store;
0800:   int ct;
0801:   QWords_to_store = 7;
0802:   if ((TDate_Current == NULL)
0803:    || (TDate_Current->capacity < TDate_Current->next_free + QWords_to_store + 5UL))
0804:     alloc_memory_block(0UL);
0805:   if (TDate_Current == NULL) return;
0806:   if (!total_facet_count) {
0807:     xmin = xmax = vx[0]; ymin = ymax = vy[0]; zmin = zmax = vz[0];
0808:   }
0809:   for (ct = 0; ct < 3; ct++) {
0810:     if (vx[ct] < xmin) xmin = vx[ct]; else if (vx[ct] > xmax) xmax = vx[ct];
0811:     if (vy[ct] < ymin) ymin = vy[ct]; else if (vy[ct] > ymax) ymax = vy[ct];
0812:     if (vz[ct] < zmin) zmin = vz[ct]; else if (vz[ct] > zmax) zmax = vz[ct];
0813:   }
0814:   ((struct Trianguleto *) (TDate_Current->next_free_p))->size_n_flags = 0x20000000L + QWords_to_store;
0815:   ((struct Trianguleto *) (TDate_Current->next_free_p))->repeated = 1;
0816:   ((struct Trianguleto *) (TDate_Current->next_free_p))->coordinates[0] = Nx;
0817:   ((struct Trianguleto *) (TDate_Current->next_free_p))->coordinates[1] = Ny;
0818:   ((struct Trianguleto *) (TDate_Current->next_free_p))->coordinates[2] = Nz;
0819:   ((struct Trianguleto *) (TDate_Current->next_free_p))->coordinates[ 3] = vx[0];
0820:   ((struct Trianguleto *) (TDate_Current->next_free_p))->coordinates[ 4] = vy[0];
0821:   ((struct Trianguleto *) (TDate_Current->next_free_p))->coordinates[ 5] = vz[0];
0822:   ((struct Trianguleto *) (TDate_Current->next_free_p))->coordinates[ 6] = vx[1];
0823:   ((struct Trianguleto *) (TDate_Current->next_free_p))->coordinates[ 7] = vy[1];
0824:   ((struct Trianguleto *) (TDate_Current->next_free_p))->coordinates[ 8] = vz[1];
0825:   ((struct Trianguleto *) (TDate_Current->next_free_p))->coordinates[ 9] = vx[2];
0826:   ((struct Trianguleto *) (TDate_Current->next_free_p))->coordinates[10] = vy[2];
0827:   ((struct Trianguleto *) (TDate_Current->next_free_p))->coordinates[11] = vz[2];
0828:   TDate_Current->next_free += QWords_to_store;
0829:   TDate_Current->next_free_p = &(TDate_Current->Data[TDate_Current->next_free]);
0830:   store_end();
0831:   total_facet_count++;
0832: }
0833: 
0834: void store_facet(double Nx, double Ny, double Nz, double *vx, double *vy, double *vz)
0835: { unsigned long QWords_to_store;
0836:   int ct;
0837:   QWords_to_store = 13;
0838:   if ((TDate_Current == NULL)
0839:    || (TDate_Current->capacity < TDate_Current->next_free + QWords_to_store + 5UL))
0840:     alloc_memory_block(0UL);
0841:   if (TDate_Current == NULL) return;
0842:   if (!total_facet_count) {
0843:     xmin = xmax = vx[0]; ymin = ymax = vy[0]; zmin = zmax = vz[0];
0844:   }
0845:   for (ct = 0; ct < 3; ct++) {
0846:     if (vx[ct] < xmin) xmin = vx[ct]; else if (vx[ct] > xmax) xmax = vx[ct];
0847:     if (vy[ct] < ymin) ymin = vy[ct]; else if (vy[ct] > ymax) ymax = vy[ct];
0848:     if (vz[ct] < zmin) zmin = vz[ct]; else if (vz[ct] > zmax) zmax = vz[ct];
0849:   }
0850:   ((struct Triangulo *) (TDate_Current->next_free_p))->size_n_flags = 0x30000000L + QWords_to_store;
0851:   ((struct Triangulo *) (TDate_Current->next_free_p))->repeated = 1;
0852:   ((struct Triangulo *) (TDate_Current->next_free_p))->coordinates[0] = Nx;
0853:   ((struct Triangulo *) (TDate_Current->next_free_p))->coordinates[1] = Ny;
0854:   ((struct Triangulo *) (TDate_Current->next_free_p))->coordinates[2] = Nz;
0855:   ((struct Triangulo *) (TDate_Current->next_free_p))->coordinates[ 3] = vx[0];
0856:   ((struct Triangulo *) (TDate_Current->next_free_p))->coordinates[ 4] = vy[0];
0857:   ((struct Triangulo *) (TDate_Current->next_free_p))->coordinates[ 5] = vz[0];
0858:   ((struct Triangulo *) (TDate_Current->next_free_p))->coordinates[ 6] = vx[1];
0859:   ((struct Triangulo *) (TDate_Current->next_free_p))->coordinates[ 7] = vy[1];
0860:   ((struct Triangulo *) (TDate_Current->next_free_p))->coordinates[ 8] = vz[1];
0861:   ((struct Triangulo *) (TDate_Current->next_free_p))->coordinates[ 9] = vx[2];
0862:   ((struct Triangulo *) (TDate_Current->next_free_p))->coordinates[10] = vy[2];
0863:   ((struct Triangulo *) (TDate_Current->next_free_p))->coordinates[11] = vz[2];
0864:   TDate_Current->next_free += QWords_to_store;
0865:   TDate_Current->next_free_p = &(TDate_Current->Data[TDate_Current->next_free]);
0866:   store_end();
0867:   total_facet_count++;
0868: }
0869: 
0870: int AdjustInputVTF(void *start, unsigned long total_length)
0871: { unsigned long pos, cnt, j;
0872:   int stp, models_added = 0;
0873:   unsigned long typ, sz, i, coords_type;
0874:   union Unu *Ptr, *coords;
0875:   double px, py, pz;
0876:   pos = coords_type = stp = 0;
0877:   coords = NULL;
0878:   while (pos < total_length) {
0879:     wchar_t TT[300]; int c, stp_neu;
0880:     Ptr = (union Unu *) &(((union Unu *)start)->Data[pos]);
0881:     if (long_in_mapping) swap4(&(Ptr->dauxrigo.size_n_flags), long_in_mapping);
0882:     sz = Ptr->dauxrigo.size_n_flags & 0x0fffffffL;
0883:     typ = (Ptr->dauxrigo.size_n_flags >> 28) & 0x0fL;
0884:     switch (typ) {
0885:       case 8: /* Begin Solid */
0886:         cPrintfI("Begin solid ...\n", 0);
0887:         if (short_in_mapping) for (i = 0; i + 2 < 4 * sz; i++)
0888:           swap2(&(Ptr->nomo.ObjectName[i]), short_in_mapping);
0889:         AddModelReference(Ptr, Ptr->nomo.ObjectName, coords, coords_type);
0890:         models_added++;
0891:         Ptr = (union Unu *) &(Ptr->Data[sz]);
0892:       break;
0893:       case 0: /* indexed color */
0894:         if (float_in_mapping)
0895:           swap4(&(Ptr->triangulatoro.repeated), long_in_mapping);
0896:         Ptr = (union Unu *) &(Ptr->Data[sz]);
0897:       break;
0898:       case 4: /* color */
0899:         if (float_in_mapping) {
0900:           swap4(&(Ptr->coloro.r), float_in_mapping);
0901:           swap4(&(Ptr->coloro.g), float_in_mapping);
0902:           swap4(&(Ptr->coloro.b), float_in_mapping);
0903:         }
0904:         Ptr = (union Unu *) &(Ptr->Data[sz]);
0905:       break;
0906:       case 7:
0907:         if (long_in_mapping) swap4(&(Ptr->triangulo.repeated), long_in_mapping);
0908:         if (double_in_mapping) for (cnt = 0; cnt < 3 * Ptr->triangulo.repeated; cnt++)
0909:           swap8(&(Ptr->triangulo.coordinates[cnt]), double_in_mapping);
0910:         coords = Ptr;
0911:         coords_type = 7;
0912:         Ptr = (union Unu *) &(Ptr->Data[sz]);
0913:       break;
0914:       case 6:
0915:         if (long_in_mapping) swap4(&(Ptr->trianguleto.repeated), long_in_mapping);
0916:         if (float_in_mapping) for (cnt = 0; cnt < 3 * Ptr->trianguleto.repeated; cnt++)
0917:           swap4(&(Ptr->trianguleto.coordinates[cnt]), float_in_mapping);
0918:         coords = Ptr;
0919:         coords_type = 6;
0920:         Ptr = (union Unu *) &(Ptr->Data[sz]);
0921:       break;
0922:       case 1: /* triangulatoro */
0923:         if (long_in_mapping) swap4(&(Ptr->triangulatoro.repeated), long_in_mapping);
0924:         for (cnt = 0; cnt < 4 * Ptr->triangulatoro.repeated; cnt += 4) {
0925:           if (long_in_mapping) for (j = 0; j < 4; j++)
0926:             swap4(&(Ptr->triangulatoro.index[cnt + j]), long_in_mapping);
0927:           if (!total_facet_count) {
0928:             switch (coords_type) {
0929:               case 7:
0930:                 xmin = xmax = coords->triangulo.coordinates[Ptr->triangulatoro.index[cnt + 1]];
0931:                 ymin = ymax = coords->triangulo.coordinates[Ptr->triangulatoro.index[cnt + 1] + 1];
0932:                 zmin = zmax = coords->triangulo.coordinates[Ptr->triangulatoro.index[cnt + 1] + 2];
0933:               break;
0934:               case 6:
0935:                 xmin = xmax = coords->trianguleto.coordinates[Ptr->triangulatoro.index[cnt + 1]];
0936:                 ymin = ymax = coords->trianguleto.coordinates[Ptr->triangulatoro.index[cnt + 1] + 1];
0937:                 zmin = zmax = coords->trianguleto.coordinates[Ptr->triangulatoro.index[cnt + 1] + 2];
0938:               break;
0939:             }
0940:           }
0941:           for (j = 1; j < 4; j++) {
0942:             switch (coords_type) {
0943:               case 7:
0944:                 px = coords->triangulo.coordinates[Ptr->triangulatoro.index[cnt + j]];
0945:                 py = coords->triangulo.coordinates[Ptr->triangulatoro.index[cnt + j] + 1];
0946:                 pz = coords->triangulo.coordinates[Ptr->triangulatoro.index[cnt + j] + 2];
0947:               break;
0948:               case 6:
0949:                 px = coords->trianguleto.coordinates[Ptr->triangulatoro.index[cnt + j]];
0950:                 py = coords->trianguleto.coordinates[Ptr->triangulatoro.index[cnt + j] + 1];
0951:                 pz = coords->trianguleto.coordinates[Ptr->triangulatoro.index[cnt + j] + 2];
0952:               break;
0953:             }
0954:             if (xmin > px) xmin = px; else if (xmax < px) xmax = px;
0955:             if (ymin > py) ymin = py; else if (ymax < py) ymax = py;
0956:             if (zmin > pz) zmin = pz; else if (zmax < pz) zmax = pz;
0957:           }
0958:           total_facet_count++;
0959:         }
0960:         Ptr = (union Unu *) &(Ptr->Data[sz]);
0961:       break;
0962:       case 3: /* triangulo */
0963:         if (long_in_mapping) swap4(&(Ptr->triangulo.repeated), long_in_mapping);
0964:         for (cnt = 0; cnt < 12 * Ptr->triangulo.repeated; cnt += 12) {
0965:           if (double_in_mapping) for (j = 0; j < 12; j++)
0966:             swap8(&(Ptr->triangulo.coordinates[cnt + j]), double_in_mapping);
0967:           if (!total_facet_count) {
0968:             xmin = xmax = Ptr->triangulo.coordinates[cnt + 3];
0969:             ymin = ymax = Ptr->triangulo.coordinates[cnt + 4];
0970:             zmin = zmax = Ptr->triangulo.coordinates[cnt + 5];
0971:           }
0972:           for (j = 3; j < 12; j += 3) {
0973:             if (xmin > Ptr->triangulo.coordinates[cnt + j])
0974:               xmin = Ptr->triangulo.coordinates[cnt + j];
0975:              else if (xmax < Ptr->triangulo.coordinates[cnt + j])
0976:               xmax = Ptr->triangulo.coordinates[cnt + j];
0977:             if (ymin > Ptr->triangulo.coordinates[cnt + j + 1])
0978:               ymin = Ptr->triangulo.coordinates[cnt + j + 1];
0979:              else if (ymax < Ptr->triangulo.coordinates[cnt + j + 1])
0980:               ymax = Ptr->triangulo.coordinates[cnt + j + 1];
0981:             if (zmin > Ptr->triangulo.coordinates[cnt + j + 2])
0982:               zmin = Ptr->triangulo.coordinates[cnt + j + 2];
0983:              else if (zmax < Ptr->triangulo.coordinates[cnt + j + 2])
0984:               zmax = Ptr->triangulo.coordinates[cnt + j + 2];
0985:           }
0986:           total_facet_count++;
0987:         }
0988:         Ptr = (union Unu *) &(Ptr->Data[sz]);
0989:       break;
0990:       case 2: /* trianguleto */
0991:         if (long_in_mapping) swap4(&(Ptr->trianguleto.repeated), long_in_mapping);
0992:         for (cnt = 0; cnt < 12 * Ptr->trianguleto.repeated; cnt += 12) {
0993:           if (float_in_mapping) for (j = 0; j < 12; j++)
0994:             swap4(&(Ptr->trianguleto.coordinates[cnt + j]), float_in_mapping);
0995:           if (!total_facet_count) {
0996:             xmin = xmax = Ptr->trianguleto.coordinates[cnt + 3];
0997:             ymin = ymax = Ptr->trianguleto.coordinates[cnt + 4];
0998:             zmin = zmax = Ptr->trianguleto.coordinates[cnt + 5];
0999:           }
1000:           for (j = 3; j < 12; j += 3) {
1001:             if (xmin > Ptr->trianguleto.coordinates[cnt + j])
1002:               xmin = Ptr->trianguleto.coordinates[cnt + j];
1003:              else if (xmax < Ptr->trianguleto.coordinates[cnt + j])
1004:               xmax = Ptr->trianguleto.coordinates[cnt + j];
1005:             if (ymin > Ptr->trianguleto.coordinates[cnt + j + 1])
1006:               ymin = Ptr->trianguleto.coordinates[cnt + j + 1];
1007:              else if (ymax < Ptr->trianguleto.coordinates[cnt + j + 1])
1008:               ymax = Ptr->trianguleto.coordinates[cnt + j + 1];
1009:             if (zmin > Ptr->trianguleto.coordinates[cnt + j + 2])
1010:               zmin = Ptr->trianguleto.coordinates[cnt + j + 2];
1011:              else if (zmax < Ptr->trianguleto.coordinates[cnt + j + 2])
1012:               zmax = Ptr->trianguleto.coordinates[cnt + j + 2];
1013:           }
1014:           total_facet_count++;
1015:         }
1016:         Ptr = (union Unu *) &(Ptr->Data[sz]);
1017:       break;
1018:       default:
1019:         Ptr = (union Unu *) &(Ptr->Data[sz]);
1020:     }
1021:     pos += sz;
1022:     stp_neu = (int) floor((25.0 * pos) / ((double) total_length) + 25.0);
1023:     if (stp_neu != stp) {
1024:       stp = stp_neu;
1025:       wsprintf(TT, L"%s ", LangWindowName);
1026:       for (c = 0; c < stp; c++) wcscat(TT, L".");
1027:       wcscat (TT, L"|");
1028:       for (c = stp; c < 49; c++) wcscat(TT, L".");
1029:       SetWindowText(hwndApplication, TT);
1030:     }
1031:   }
1032:   return models_added;
1033: }
1034: 
1035: int ReadFileVTF(FILE *ein)
1036: { unsigned long QWords_to_store, start_index, load_index, to_load;
1037:   int stp, models_added = 0;
1038:   struct stat sb;
1039:   sb.st_size = 0L; stp = 0;
1040:   fstat(fileno(ein), &sb);
1041:   if (sb.st_size <= 48) return 0;
1042:   QWords_to_store = (sb.st_size / 8L) - 6L;
1043:   if ((TDate_Current == NULL)
1044:    || (TDate_Current->capacity < TDate_Current->next_free + QWords_to_store + 5UL))
1045:     alloc_memory_block(QWords_to_store + 5UL);
1046:   if (TDate_Current == NULL) return 0;
1047:   load_index = start_index = TDate_Current->next_free;
1048:   to_load = QWords_to_store;
1049:   fseek(ein, 48L, SEEK_SET);
1050:   while (to_load > 4096) {
1051:     wchar_t TT[300]; int c, stp_neu;
1052:     fread(&(TDate_Current->Data[load_index]), 8, 4096, ein);
1053:     load_index += 4096; to_load -= 4096;
1054:     stp_neu = (int) floor((25.0 * (double) ftell(ein)) / ((double) sb.st_size));
1055:     if (stp_neu != stp) {
1056:       stp = stp_neu;
1057:       wsprintf(TT, L"%s ", LangWindowName);
1058:       for (c = 0; c < stp; c++) wcscat(TT, L".");
1059:       wcscat (TT, L"|");
1060:       for (c = stp; c < 49; c++) wcscat(TT, L".");
1061:       SetWindowText(hwndApplication, TT);
1062:     }
1063:   }
1064:   if (to_load) {
1065:     fread(&(TDate_Current->Data[load_index]), 8, to_load, ein);
1066:     load_index += to_load; to_load = 0;
1067:   }
1068:   models_added = AdjustInputVTF(TDate_Current->next_free_p, QWords_to_store);
1069:   TDate_Current->next_free += QWords_to_store;
1070:   TDate_Current->next_free_p = &(TDate_Current->Data[TDate_Current->next_free]);
1071:   store_end();
1072:   if (total_facet_count) VALID_MODELS += models_added;
1073:   if (TDate_Current == NULL) VALID_MODELS = 0;
1074:   return 1;
1075: }
1076: 
1077: int ReadFileSTL(FILE *ein)
1078: { char Z1[81];
1079:   int stp, models_added = 0;
1080:   unsigned long fcnt, ct;
1081:   float vx[5], vy[5], vz[5];
1082:   struct vv {
1083:     float V[12];
1084:     unsigned short us;
1085:   } VV;
1086:   struct stat sb;
1087:   sb.st_size = 1000000L; stp = 0;
1088:   fstat(fileno(ein), &sb);
1089:   if (fread(Z1, 1, 80, ein) < 80) return 0;
1090:   store_beginsolid(&(Z1[6])); models_added = 1;
1091:   Z1[80] = '\0';
1092:   if (strncmp(Z1, "solid ", 6)) return 0;
1093:   fcnt = 0;
1094:   fread(&fcnt, 4, 1, ein);
1095:   cPrintfI("%u Facetten ...\n", (int) fcnt);
1096:   for (ct = 0; ct < fcnt; ct++) {
1097:     if (!(ct & 0x3f)) {
1098:       wchar_t TT[300]; int c, stp_neu;
1099:       cPrintfI("Facette %u:\n", (int) ct);
1100:       stp_neu = (int) floor((50.0 * (double) ftell(ein)) / ((double) sb.st_size));
1101:       if (stp_neu != stp) {
1102:         stp = stp_neu;
1103:         wsprintf(TT, L"%s ", LangWindowName);
1104:         for (c = 0; c < stp; c++) wcscat(TT, L".");
1105:         wcscat (TT, L"|");
1106:         for (c = stp; c < 49; c++) wcscat(TT, L".");
1107:         SetWindowText(hwndApplication, TT);
1108:       }
1109:     }
1110:     if (fread(&VV, 50, 1, ein) >= 1) {
1111:       /*

1112:       if (!(ct & 0x3f)) {

1113:         cPrintfF("%6.3f ", VV.V[0]); cPrintfF("%6.3f ", VV.V[1]); cPrintfF("%6.3f\n", VV.V[2]);

1114:         cPrintfF("%6.3f ", VV.V[3]); cPrintfF("%6.3f ", VV.V[4]); cPrintfF("%6.3f\n", VV.V[5]);

1115:         cPrintfF("%6.3f ", VV.V[6]); cPrintfF("%6.3f ", VV.V[7]); cPrintfF("%6.3f\n", VV.V[8]);

1116:         cPrintfF("%6.3f ", VV.V[9]); cPrintfF("%6.3f ", VV.V[10]); cPrintfF("%6.3f\n", VV.V[11]);

1117:         cPrintfI("< %u >\n", (int) VV.us);

1118:       }

1119:       */
1120:       vx[0] = VV.V[ 3]; vy[0] = VV.V[ 4]; vz[0] = VV.V[ 5];
1121:       vx[1] = VV.V[ 6]; vy[1] = VV.V[ 7]; vz[1] = VV.V[ 8];
1122:       vx[2] = VV.V[ 9]; vy[2] = VV.V[10]; vz[2] = VV.V[11];
1123:       store_facet_short(VV.V[0], VV.V[1], VV.V[2], vx, vy, vz);
1124:     } /* else cPrintfI("Datensatz %u nicht gelesen!\n", ct); */
1125:   }
1126:   store_endsolid();
1127:   SetWindowText(hwndApplication, LangWindowName);
1128:   if (total_facet_count) VALID_MODELS += models_added;
1129:   if (TDate_Current == NULL) VALID_MODELS = 0;
1130:   return 1;
1131: }
1132: 
1133: int ReadFileSLP(FILE *ein)
1134: { char Zeile[MAX_PATH + 50], Kennwort[MAX_PATH + 50], Kennwort2[MAX_PATH + 50];
1135:   unsigned long ZNR;
1136:   int sw, stp = -1, STATE = -1, cv, cn;
1137:   double d1, d2, d3, nx[3], ny[3], nz[3], vx[6], vy[6], vz[6], Nx, Ny, Nz, NNx, NNy, NNz, NL;
1138:   int ct_solid;
1139: #ifdef KUN_STATISTIKO
1140:   int ct_unknown = 0, ct_endsolid = 0, ct_color = 0,
1141:       ct_facet = 0, ct_endfacet = 0, ct_outer_loop = 0, ct_endloop = 0,
1142:       ct_normal = 0, ct_vertex = 0, ct_rechts = 0, ct_links = 0;
1143: #endif

1144:   struct stat sb;
1145: #ifdef KUN_STATISTIKO
1146:   wchar_t Meldung[500];
1147:   char Meldung2[300];
1148: #endif

1149:   ZNR = 0; sb.st_size = 1000000L;
1150:   ct_solid = 0;
1151:   fstat(fileno(ein), &sb);
1152:   while (fgets(Zeile, MAX_PATH + 50, ein) != NULL) {
1153:     /* Anzeige des Ladefortschritts in der Titelleiste! */
1154:     if (!(ZNR & 0x3f)) {
1155:       wchar_t TT[300]; int c, stp_neu;
1156:       stp_neu = (int) floor((50.0 * (double) ftell(ein)) / ((double) sb.st_size));
1157:       if (stp_neu != stp) {
1158:         stp = stp_neu;
1159:         wsprintf(TT, L"%s ", LangWindowName);
1160:         for (c = 0; c < stp; c++) wcscat(TT, L".");
1161:         wcscat (TT, L"|");
1162:         for (c = stp; c < 49; c++) wcscat(TT, L".");
1163:         /* if (stp >= 32) stp = 0; */
1164:         SetWindowText(hwndApplication, TT);
1165:       }
1166:     }
1167:     Kennwort[0] = '\0'; ZNR++;
1168:     sw = sscanf(Zeile, "%s %lf %lf %lf", Kennwort, &d1, &d2, &d3);
1169:     if (!stricmp(Kennwort, "solid")) {
1170:       STATE = 1;
1171:       Kennwort2[0] = '\0';
1172:       sscanf(Zeile, "%s %s", Kennwort, Kennwort2);
1173:       store_beginsolid(Kennwort2);
1174:       ct_solid++;
1175:     } else
1176:     if (!stricmp(Kennwort, "endsolid")) {
1177:       STATE = 0;
1178:       store_endsolid();
1179: #ifdef KUN_STATISTIKO
1180:       ct_endsolid++;
1181: #endif

1182:     } else
1183:     if (!stricmp(Kennwort, "color")) {
1184:       if ((STATE == 1) && (sw == 4))
1185:         store_set_color((float) d1, (float) d2, (float) d3);
1186: #ifdef KUN_STATISTIKO
1187:       ct_color++;
1188: #endif

1189:     } else
1190:     if (!stricmp(Kennwort, "facet")) {
1191:       if (STATE == 1) {
1192:         cn = cv = 0;
1193:         STATE = 2;
1194:         sw = sscanf(Zeile, "%s %s %lf %lf %lf", Kennwort, Kennwort2, &d1, &d2, &d3);
1195:         if ((sw == 5) && !stricmp(Kennwort2, "normal") && (cn < 3)) {
1196:           nx[cn] = d1; ny[cn] = d2; nz[cn] = d3; cn++;
1197: #ifdef KUN_STATISTIKO
1198:           ct_normal++;
1199: #endif

1200:         }
1201:       }
1202: #ifdef KUN_STATISTIKO
1203:       ct_facet++;
1204: #endif

1205:     } else
1206:     if (!stricmp(Kennwort, "endfacet")) {
1207:       if (STATE > 1) {
1208:         if ((cv == 3) && (cn > 0)) {
1209:           NNx = nx[0]; NNy = ny[0]; NNz = nz[0];
1210:           for (sw = 1; sw < cn; sw++) {
1211:             NNx += nx[sw]; NNy += ny[sw]; NNz += nz[sw];
1212:           }
1213:           vx[3] = vx[1] - vx[0]; vx[4] = vx[2] - vx[1]; vx[5] = vx[0] - vx[2];
1214:           vy[3] = vy[1] - vy[0]; vy[4] = vy[2] - vy[1]; vy[5] = vy[0] - vy[2];
1215:           vz[3] = vz[1] - vz[0]; vz[4] = vz[2] - vz[1]; vz[5] = vz[0] - vz[2];
1216:           Nx = (vy[3] * vz[4] - vz[3] * vy[4]) + (vy[4] * vz[5] - vz[4] * vy[5]) + (vy[5] * vz[3] - vz[5] * vy[3]);
1217:           Ny = (vz[3] * vx[4] - vx[3] * vz[4]) + (vz[4] * vx[5] - vx[4] * vz[5]) + (vz[5] * vx[3] - vx[5] * vz[3]);
1218:           Nz = (vx[3] * vy[4] - vy[3] * vx[4]) + (vx[4] * vy[5] - vy[4] * vx[5]) + (vx[5] * vy[3] - vy[5] * vx[3]);
1219:           NL = sqrt(Nx*Nx + Ny*Ny + Nz*Nz);
1220:           if (NL >= 1.0e-100L) {
1221:             if ((d1 = Nx * NNx + Ny * NNy + Nz * NNz) > 0.0) {
1222: #ifdef KUN_STATISTIKO
1223:               ct_rechts++;
1224: #endif

1225:             } else if (d1 < 0.0) {
1226:               /*

1227:               sprintf(Meldung2, "Normal:\n"

1228:                 "%9.3lf %9.3lf %9.3lf\n%9.3lf %9.3lf %9.3lf\n%9.3lf %9.3lf %9.3lf\n"

1229:                 "Vertizes:\n"

1230:                 "%9.3lf %9.3lf %9.3lf\n%9.3lf %9.3lf %9.3lf\n%9.3lf %9.3lf %9.3lf\n",

1231:                   nx[0], ny[0], nz[0], nx[1], ny[1], nz[1], nx[2], ny[2], nz[2],

1232:                   vx[0], vy[0], vz[0], vx[1], vy[1], vz[1], vx[2], vy[2], vz[2]);

1233:               wsprintf(Meldung, L"%S", Meldung2);

1234:               MessageBox(hwndApplication, Meldung, L"maldekstra triangolo:", MB_OK | MB_ICONINFORMATION);

1235:               */
1236:               NL *= -1.0;
1237: #ifdef KUN_STATISTIKO
1238:               ct_links++;
1239: #endif

1240:               vx[4] = vx[1]; vx[1] = vx[2]; vx[2] = vx[4];
1241:               vy[4] = vy[1]; vy[1] = vy[2]; vy[2] = vy[4];
1242:               vz[4] = vz[1]; vz[1] = vz[2]; vz[2] = vz[4];
1243:             }
1244:             Nx /= NL; Ny /= NL; Nz /= NL;
1245:           }
1246:           /*

1247:           { sprintf(Meldung2, "Normal:\n"

1248:                 "%9.3lf %9.3lf %9.3lf\n%9.3lf %9.3lf %9.3lf\n%9.3lf %9.3lf %9.3lf\n"

1249:                 "nova Normal:\n"

1250:                 "%9.3lf %9.3lf %9.3lf\n(%9.3lf)\n"

1251:                 "Vertizes:\n"

1252:                 "%9.3lf %9.3lf %9.3lf\n%9.3lf %9.3lf %9.3lf\n%9.3lf %9.3lf %9.3lf\n",

1253:                   nx[0], ny[0], nz[0], nx[1], ny[1], nz[1], nx[2], ny[2], nz[2],

1254:                   Nx, Ny, Nz, NL,

1255:                   vx[0], vy[0], vz[0], vx[1], vy[1], vz[1], vx[2], vy[2], vz[2]);

1256:               wsprintf(Meldung, L"%S", Meldung2);

1257:               MessageBox(hwndApplication, Meldung, L"maldekstra triangolo:", MB_OK | MB_ICONINFORMATION);

1258:           }

1259:           */
1260:           store_facet(Nx, Ny, Nz, vx, vy, vz);
1261:         }
1262:         STATE = 1;
1263:       }
1264: #ifdef KUN_STATISTIKO
1265:       ct_endfacet++;
1266: #endif

1267:     } else
1268:     if (!stricmp(Kennwort, "outer")) {
1269:       if (STATE == 2) STATE = 3;
1270: #ifdef KUN_STATISTIKO
1271:       ct_outer_loop++;
1272: #endif

1273:     } else
1274:     if (!stricmp(Kennwort, "endloop")) {
1275:       if (STATE == 3) STATE = 2;
1276: #ifdef KUN_STATISTIKO
1277:       ct_endloop++;
1278: #endif

1279:     } else
1280:     if (!stricmp(Kennwort, "normal")) {
1281:       if ((STATE == 2) && (sw == 4) && (cn < 3)) {
1282:         nx[cn] = d1; ny[cn] = d2; nz[cn] = d3; cn++;
1283:       }
1284: #ifdef KUN_STATISTIKO
1285:       ct_normal++;
1286: #endif

1287:     } else
1288:     if (!stricmp(Kennwort, "vertex")) {
1289:       if ((STATE == 3) && (sw == 4) && (cv < 3)) {
1290:         vx[cv] = d1; vy[cv] = d2; vz[cv] = d3; cv++;
1291:       }
1292: #ifdef KUN_STATISTIKO
1293:       ct_vertex++;
1294: #endif

1295:     } else {
1296: #ifdef KUN_STATISTIKO
1297:       ct_unknown++;
1298: #endif

1299:     }
1300:   }
1301:   SetWindowText(hwndApplication, LangWindowName);
1302: #ifdef KUN_STATISTIKO
1303:   if (ct_vertex)
1304:     sprintf(Meldung2, "\n\n[ %5.3lf..%5.3lf ; %5.3lf..%5.3lf ; %5.3lf..%5.3lf ]",
1305:       xmin, xmax, ymin, ymax, zmin, zmax);
1306:    else Meldung2[0] = '\0';
1307:   wsprintf(Meldung,
1308:            StrByLang(X_CODING,
1309:            /*   0*/  L"%d\tsolid\n%d\tendsolid\n%d\tcolor\n"
1310:                      L"%d\tfacet\n%d\tendfacet\n%d\touter loop\n%d\tendloop\n"
1311:                      L"\t%d\tdekstra\n\t%d\tmaldekstra\n"
1312:                      L"%d\tnormal\n%d\tvertex\n%d\tnekonata\n---------------\n%d\tlinioj%S", L"\xffff",
1313:            /* EOL */ NULL),
1314:                     ct_solid, ct_endsolid, ct_color,
1315:                     ct_facet, ct_endfacet, ct_outer_loop, ct_endloop,
1316:                     ct_rechts, ct_links,
1317:                     ct_normal, ct_vertex, ct_unknown, ZNR, Meldung2);
1318:   MessageBox(hwndApplication, Meldung,
1319:              StrByLang(X_CODING, L"statistiko:", L"\xffff", NULL),
1320:              MB_OK | MB_ICONINFORMATION);
1321: #endif

1322:   if (total_facet_count) VALID_MODELS += ct_solid;
1323:   if (TDate_Current == NULL) VALID_MODELS = 0;
1324:   return 1;
1325: }
1326: 
1327: int which_eoln(FILE *ein)
1328: { unsigned char C;
1329:   unsigned long CP;
1330:   CP = ftell(ein);
1331:   while (fread(&C, 1, 1, ein) > 0) {
1332:     switch(C) {
1333:       case '\n': case '\r': 
1334:         fseek(ein, CP, SEEK_SET);
1335:         return 1;
1336:       case '\0':
1337:         fseek(ein, CP, SEEK_SET);
1338:         return 2;
1339:     }
1340:   }
1341:   fseek(ein, CP, SEEK_SET);
1342:   return -1;
1343: }
1344: 
1345: void ReadFileIn(wchar_t *datei, wchar_t *basename, int ext_start, int append)
1346: /* append = -1 : Zu lesende Datei im Dialog ausgewählt

1347:  * append =  0 : erste Datei aus Kommandozeile

1348:  * append >= 1 : Folgedatei aus Kommandozeile            */
1349: { FILE *ein;
1350:   wchar_t Fehler[MAX_PATH + 100];
1351:   char Kopf[8];
1352:   if ((ein = _wfopen(datei, L"rb")) == NULL) {
1353:     wsprintf(Fehler,
1354:              StrByLang(X_CODING,
1355:                        L"Ne konas legi dosieron '%s'!", L"\xffff",
1356:                        L"Kann Datei '%s' nicht lesen!",
1357:                        L"File \"%s\" cannot be read!",
1358:                        NULL),
1359:              datei);
1360:     MessageBox(hwndApplication, Fehler,
1361:                StrByLang(X_CODING,
1362:                          L"apertas triangularan dosieron", L"\xffff",
1363:                          L"Öffnen einer Triangulationsdatei",
1364:                          L"Opening a triangulation file",
1365:                          NULL),
1366:                MB_OK | MB_ICONEXCLAMATION);
1367:     return;
1368:   }
1369:   Kopf[0] = '\0';
1370:   fread(Kopf, 1, strlen(SLP_STL_ASCII_HEAD), ein); fseek(ein, 0, SEEK_SET);
1371:   Kopf[strlen(SLP_STL_ASCII_HEAD)] = '\0';
1372:   IN_FILE_DIALOG = 1; RebuildLists = 1;
1373:   if (append <= 0) {
1374:     clear_triangulation(); total_facet_count = 0; VALID_MODELS = 0;
1375:     if (hwndObjectDisplayDialog != NULL) SendMessage(hwndObjectDisplayDialog, WM_COMMAND, RT_CLEAR_CHECKBOXES, 0L);
1376:     ClearModelSelectItems();
1377:   }
1378:   if (!stricmp(Kopf, SLP_STL_ASCII_HEAD)) {
1379:     switch(which_eoln(ein)) {
1380:       case 1:
1381:         ReadFileSLP(ein);
1382:       break;
1383:       case 2:
1384:         ReadFileSTL(ein);
1385:       break;
1386:       default:
1387:         goto reading_unknown_type;
1388:     }
1389:     if (hwndObjectDisplayDialog != NULL) SendMessage(hwndObjectDisplayDialog, WM_COMMAND, RT_BUILD_CHECKBOXES, 0L);
1390:   } else 
1391:   if (ItsVTFtype(ein, &short_in_mapping, &long_in_mapping,
1392:                       &float_in_mapping, &double_in_mapping)) {
1393:     ReadFileVTF(ein);
1394:     if (hwndObjectDisplayDialog != NULL) SendMessage(hwndObjectDisplayDialog, WM_COMMAND, RT_BUILD_CHECKBOXES, 0L);
1395:     /*

1396:     wsprintf(Fehler, L"Mappings:\nshort = %d\nlong = %d\nfloat = %d\ndouble = %d",

1397:              short_in_mapping, long_in_mapping, float_in_mapping, double_in_mapping);

1398:     MessageBox(hwndApplication, Fehler, L"tipo:", MB_OK | MB_ICONINFORMATION);

1399:     */
1400:   } else {
1401:     reading_unknown_type:
1402:     if (append == 0) {
1403:       // wchar_t M[500];

1404:       // wsprintf(M, L"ReadFileIn(\"%s\",\n           \"%s\",\n           %d, %d)\n\"%s\"\nnokonata enhavo!",

1405:       //  datei, basename, ext_start, append, &(datei[ext_start]));

1406:       // MessageBox(hwndApplication, M, L"launching problem", MB_OK | MB_ICONEXCLAMATION);

1407:       if (ES_Settings.VtfSlpStl[0].enabled && !wcsicmp(&(datei[ext_start]), L".vtf")) {
1408:         fclose(ein);
1409:         // MessageBox(hwndApplication, L"VTF-Application", L"should launch by", MB_OK | MB_ICONEXCLAMATION);

1410:         try_launching(0, datei);
1411:         goto this_routine_exit_code;
1412:       }
1413:       if (ES_Settings.VtfSlpStl[1].enabled && !wcsicmp(&(datei[ext_start]), L".slp")) {
1414:         fclose(ein);
1415:         // MessageBox(hwndApplication, L"SLP-Application", L"should launch by", MB_OK | MB_ICONEXCLAMATION);

1416:         try_launching(1, datei);
1417:         goto this_routine_exit_code;
1418:       }
1419:       if (ES_Settings.VtfSlpStl[2].enabled && !wcsicmp(&(datei[ext_start]), L".stl")) {
1420:         fclose(ein);
1421:         // MessageBox(hwndApplication, L"STL-Application", L"should launch by", MB_OK | MB_ICONEXCLAMATION);

1422:         try_launching(2, datei);
1423:         goto this_routine_exit_code;
1424:       }
1425:     }
1426:     MessageBox(hwndApplication,
1427:                StrByLang(X_CODING, 
1428:                          L"nekonata enhavo en tiu " US_cx L"i dosiero!",
1429:                          L"nekonata enhavo en tiu cxi dosiero!",
1430:                          L"unbekanntes Dateiformat in dieser Datei!",
1431:                          L"this file is an unknown file format!",
1432:                          NULL),
1433:                StrByLang(X_CODING, L"lega manko", L"\xffff",
1434:                                    L"Lesefehler",
1435:                                    L"Error while reading",
1436:                                    NULL),
1437:                MB_OK | MB_ICONEXCLAMATION);
1438:     if (append <= 0) total_facet_count = 0;
1439:   }
1440:   fclose(ein);
1441:   this_routine_exit_code:
1442:   if ((TDate_Current == NULL) || (total_facet_count == 0)) {
1443:     clear_triangulation(); VALID_MODELS = 0;
1444:   }
1445:   IN_FILE_DIALOG = 0;
1446:   EnableMenuItem(filemenu, MN_FILE_SAVE, MF_BYCOMMAND | (VALID_MODELS ? MF_ENABLED : MF_GRAYED));
1447:   EnableMenuItem(viewmenu, MN_PART_DISP, MF_BYCOMMAND | ((VALID_MODELS > 1) ? MF_ENABLED : MF_GRAYED));
1448:   if (VALID_MODELS && (append <= 0)) {
1449:     wsprintf(Fehler, L"%s - %s", LangWindowName, basename);
1450:     SetWindowText(hwndApplication, Fehler);
1451:   }
1452:   Projection = PROJ_TRI;
1453: }
1454: 
1455: void UnlinkAllMyRegistryKeys(void)
1456: { wchar_t RegName[MAX_PATH];
1457:   int ct, i;
1458:   for (ct = 0; RevHistory[ct] != NULL; ct++) {
1459:     for (i = 0; KeywordHistory[i] != NULL; i++) {
1460:       wsprintf(RegName, L"%s\\%s\\%s", RegistryBaseDir, RevHistory[ct], KeywordHistory[i]);
1461:       /* MessageBox(NULL, RegName, L"Registry entry to delete", MB_OK | MB_ICONINFORMATION);

1462:       if ( */ RegDeleteKey(HKEY_CURRENT_USER, RegName) /* == FALSE)

1463:         MessageBox(NULL, RegName, L"Registry deletion failed", MB_OK | MB_ICONEXCLAMATION) */;
1464:     }
1465:     wsprintf(RegName, L"%s\\%s", RegistryBaseDir, RevHistory[ct]);
1466:     /* MessageBox(NULL, RegName, L"Registry entry to delete", MB_OK | MB_ICONINFORMATION);

1467:     if ( */ RegDeleteKey(HKEY_CURRENT_USER, RegName) /* == FALSE)

1468:       MessageBox(NULL, RegName, L"Registry deletion failed", MB_OK | MB_ICONEXCLAMATION) */;
1469:   }
1470:   /* MessageBox(NULL, RegistryBaseDir, L"Registry entry to delete", MB_OK | MB_ICONINFORMATION);

1471:   if ( */ RegDeleteKey(HKEY_CURRENT_USER, RegistryBaseDir) /* == FALSE)

1472:     MessageBox(NULL, RegistryBaseDir, L"Registry deletion failed", MB_OK | MB_ICONEXCLAMATION) */;
1473: }
1474: 
1475: void SaveParametersInRegistry(void)
1476: { HKEY regkey;
1477:   DWORD disposition;
1478:   wchar_t ES_Packed[sizeof(struct ES_DIALOG_DATA) / 2];
1479:   int lg;
1480:   if (!options_altered) return;
1481:   if (RegCreateKeyEx(HKEY_CURRENT_USER, RegistryDir, 0, L"",
1482:       REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
1483:       &regkey, &disposition) != ERROR_SUCCESS)
1484:         return;
1485:   RegSetValueEx(regkey, L"malantauxo rugxona", 0, REG_DWORD,  (void *) &SBG_R,           4);
1486:   RegSetValueEx(regkey, L"malantauxo verdona", 0, REG_DWORD,  (void *) &SBG_G,           4);
1487:   RegSetValueEx(regkey, L"malantauxo bluona",  0, REG_DWORD,  (void *) &SBG_B,           4);
1488:   RegSetValueEx(regkey, L"openGl listoj",      0, REG_DWORD,  (void *) &UseLists,        4);
1489:   RegSetValueEx(regkey, L"malantauxa edro",    0, REG_DWORD,  (void *) &CullFace,        4);
1490:   RegSetValueEx(regkey, L"montri centro",      0, REG_DWORD,  (void *) &Disp_CS,         4);
1491:   RegSetValueEx(regkey, L"dimensio",           0, REG_DWORD,  (void *) &Disp_Extend,     4);
1492:   RegSetValueEx(regkey, L"lingvo",             0, REG_DWORD,  (void *) &X_CODING,        4);
1493:   RegSetValueEx(regkey, L"simplaj coloroj",    0, REG_DWORD,  (void *) &simple_color,    4);
1494:   RegSetValueEx(regkey, L"helaj korpoj",       0, REG_DWORD,  (void *) &lighty_models,   4);
1495:   RegSetValueEx(regkey, L"muso",               0, REG_DWORD,  (void *) &mouse_inversion, 4);
1496:   if ((lg = 2 * compact_ES_Data(ES_Packed, &ES_Settings)) != 0);
1497:     RegSetValueEx(regkey, L"anstatauxaj prog",   0, REG_BINARY, (void *) ES_Packed,   lg);
1498:   RegCloseKey(regkey);
1499:   options_altered = 0;
1500: }
1501: 
1502: void LoadParametersFromRegistry(void)
1503: { HKEY regkey;
1504:   int erg, ct;
1505:   DWORD sz, buffertype;
1506:   wchar_t ES_Packed[sizeof(struct ES_DIALOG_DATA) / 2];
1507:   erg = 0;
1508:   if (RegOpenKeyEx(HKEY_CURRENT_USER, RegistryDir, 0,
1509:       KEY_SET_VALUE | KEY_QUERY_VALUE, &regkey) != ERROR_SUCCESS)
1510:         return;
1511:   sz = 4; buffertype = REG_DWORD;
1512:   if (RegQueryValueEx(regkey, L"malantauxo rugxona", 0, &buffertype, (void *) &SBG_R,   &sz)
1513:       == ERROR_SUCCESS) erg++;
1514:   sz = 4; buffertype = REG_DWORD;
1515:   if (RegQueryValueEx(regkey, L"malantauxo verdona", 0, &buffertype, (void *) &SBG_G,   &sz)
1516:       == ERROR_SUCCESS) erg++;
1517:   sz = 4; buffertype = REG_DWORD;
1518:   if (RegQueryValueEx(regkey, L"malantauxo bluona",  0, &buffertype, (void *) &SBG_B,   &sz)
1519:       == ERROR_SUCCESS) erg++;
1520:   sz = 4; buffertype = REG_DWORD;
1521:   RegQueryValueEx(regkey, L"openGl listoj",   0, &buffertype, (void *) &UseLists,        &sz);
1522:   sz = 4; buffertype = REG_DWORD;
1523:   RegQueryValueEx(regkey, L"malantauxa edro", 0, &buffertype, (void *) &CullFace,        &sz);
1524:   sz = 4; buffertype = REG_DWORD;
1525:   RegQueryValueEx(regkey, L"montri centro",   0, &buffertype, (void *) &Disp_CS,         &sz);
1526:   sz = 4; buffertype = REG_DWORD;
1527:   RegQueryValueEx(regkey, L"dimensio",        0, &buffertype, (void *) &Disp_Extend,     &sz);
1528:   sz = 4; buffertype = REG_DWORD;
1529:   RegQueryValueEx(regkey, L"lingvo",          0, &buffertype, (void *) &X_CODING,        &sz);
1530:   sz = 4; buffertype = REG_DWORD;
1531:   RegQueryValueEx(regkey, L"simplaj coloroj", 0, &buffertype, (void *) &simple_color,    &sz);
1532:   sz = 4; buffertype = REG_DWORD;
1533:   RegQueryValueEx(regkey, L"helaj korpoj",    0, &buffertype, (void *) &lighty_models,   &sz);
1534:   sz = 4; buffertype = REG_DWORD;
1535:   RegQueryValueEx(regkey, L"muso",            0, &buffertype, (void *) &mouse_inversion, &sz);
1536:   sz = ES_Settings.record_size; buffertype = REG_BINARY;
1537:   RegQueryValueEx(regkey, L"anstatauxaj prog",0, &buffertype, (void *) ES_Packed,      &sz);
1538:   uncompact_ES_Data(&ES_Settings, ES_Packed);
1539:   RegCloseKey(regkey);
1540:   if (erg >= 3) {
1541:     bg_r = SBG_R / 255.0F; bg_g = SBG_G / 255.0F; bg_b = SBG_B / 255.0F;
1542:     for (ct = 1; ct < 16; ct += 2) Farbfeld[ct] = RGB(SBG_R, SBG_G, SBG_B);
1543:   }
1544: }
1545: 
1546: wchar_t FT_IE[] = L"invalid enum",
1547:         FT_IV[] = L"invalid value",
1548:         FT_IO[] = L"invalid operation",
1549:         FT_SO[] = L"stack overflow",
1550:         FT_SU[] = L"stack underflow",
1551:         FT_OM[] = L"out of memory";
1552: 
1553: void report_glerror(int zeile)
1554: { GLenum fehler;
1555:   wchar_t *FText, Unbekant[80], Kopf[80];
1556:   switch (fehler = glGetError()) {
1557:     case GL_NO_ERROR: return;
1558:     case GL_INVALID_ENUM:      FText = FT_IE; break;
1559:     case GL_INVALID_VALUE:     FText = FT_IV; break;
1560:     case GL_INVALID_OPERATION: FText = FT_IO; break;
1561:     case GL_STACK_OVERFLOW:    FText = FT_SO; break;
1562:     case GL_STACK_UNDERFLOW:   FText = FT_SU; break;
1563:     case GL_OUT_OF_MEMORY:     FText = FT_OM; break;
1564:     default:                   FText = Unbekant; break;
1565:       wsprintf(Unbekant,
1566:                StrByLang(X_CODING, L"neniu teksto por eraro No. %u", L"\xffff",
1567:                                    L"Kein Beschreibungstext für Fehlermeldung Nr. %u",
1568:                                    L"No description available for error number %u",
1569:                                    NULL),
1570:                (unsigned int) fehler);
1571:            
1572:   }
1573:   wsprintf(Kopf,
1574:            StrByLang(X_CODING, L"eraro de openGL en lineo de codo No. %d", L"\xffff",
1575:                                L"openGL-Fehler in Programmzeile %d",
1576:                                L"openGL error in line %d",
1577:                                NULL),
1578:            zeile);
1579:   MessageBox(NULL, FText, Kopf, MB_OK | MB_ICONEXCLAMATION);
1580: }
1581: 
1582: 
1583: void Rotate0(GLdouble rot, GLdouble x, GLdouble y, GLdouble z)
1584: { GLdouble CurrMat[16], ax, ay, az;
1585: 
1586:   glGetDoublev(GL_MODELVIEW_MATRIX, CurrMat); report_glerror(__LINE__); dump_Mat();
1587:   ax = x * (CurrMat[ 5] * CurrMat[10] - CurrMat[ 6] * CurrMat[ 9])
1588:      + y * (CurrMat[ 6] * CurrMat[ 8] - CurrMat[ 4] * CurrMat[10])
1589:      + z * (CurrMat[ 4] * CurrMat[10] - CurrMat[ 6] * CurrMat[ 8]);
1590:   ay = x * (CurrMat[ 2] * CurrMat[ 9] - CurrMat[ 1] * CurrMat[10])
1591:      + y * (CurrMat[ 0] * CurrMat[10] - CurrMat[ 2] * CurrMat[ 8])
1592:      + z * (CurrMat[ 2] * CurrMat[ 8] - CurrMat[ 0] * CurrMat[10]);
1593:   az = x * (CurrMat[ 1] * CurrMat[ 6] - CurrMat[ 2] * CurrMat[ 5])
1594:      + y * (CurrMat[ 2] * CurrMat[ 4] - CurrMat[ 0] * CurrMat[ 6])
1595:      + z * (CurrMat[ 0] * CurrMat[ 5] - CurrMat[ 1] * CurrMat[ 4]);
1596:   glRotated(rot, ax, ay, az);
1597: }
1598: 
1599: void show_center_box(void)
1600: { GLdouble RSize;
1601:   RSize = 11.0 / screen_size / view_scale;
1602:   glPushMatrix();
1603:   glLoadIdentity();
1604:   glLineWidth(1.0);
1605:   glShadeModel(GL_FLAT); report_glerror(__LINE__);
1606:   glDisable(GL_LIGHTING); report_glerror(__LINE__);
1607:   glDisable(GL_DEPTH_TEST); report_glerror(__LINE__);
1608:   glClear(GL_DEPTH_BUFFER_BIT); report_glerror(__LINE__);
1609:   glColor3f(1.0, 1.0, 1.0);
1610:   glBegin(GL_LINE_LOOP);
1611:   glVertex3d(view_x + RSize, view_y + RSize, 0.0);
1612:   glVertex3d(view_x + RSize, view_y - RSize, 0.0);
1613:   glVertex3d(view_x - RSize, view_y - RSize, 0.0);
1614:   glVertex3d(view_x - RSize, view_y + RSize, 0.0);
1615:   glEnd();
1616:   glColor3f(0.0, 0.0, 0.0);
1617:   glBegin(GL_LINES);
1618:   glVertex3d(view_x + RSize, view_y + 0.5 * RSize, 0.0);
1619:   glVertex3d(view_x + RSize, view_y - 0.5 * RSize, 0.0);
1620:   glVertex3d(view_x - RSize, view_y - 0.5 * RSize, 0.0);
1621:   glVertex3d(view_x - RSize, view_y + 0.5 * RSize, 0.0);
1622:   glVertex3d(view_x - 0.5 * RSize, view_y + RSize, 0.0);
1623:   glVertex3d(view_x + 0.5 * RSize, view_y + RSize, 0.0);
1624:   glVertex3d(view_x + 0.5 * RSize, view_y - RSize, 0.0);
1625:   glVertex3d(view_x - 0.5 * RSize, view_y - RSize, 0.0);
1626:   glEnd();
1627:   glPopMatrix();
1628: }
1629: 
1630: void CoordinateSystem(void)
1631: {
1632:   double CSSZ, CSZ;
1633:   CSSZ = 0.175 * halfdiagonal / view_scale;
1634:   CSZ = 0.045 * halfdiagonal / view_scale;
1635:   glLineWidth(5.0); report_glerror(__LINE__);
1636:   glDisable(GL_LIGHTING); report_glerror(__LINE__);
1637:   glDisable(GL_DEPTH_TEST); report_glerror(__LINE__);
1638:   glColor3f(0.0, 0.0, 0.0); report_glerror(__LINE__);
1639:   /* X, Y, Z directions in the center of extend */
1640:   glBegin(GL_LINES);
1641:   glVertex3d(xc, yc, zc); glVertex3d(CSSZ + xc, yc, zc);
1642:   glVertex3d(xc, yc, zc); glVertex3d(xc, CSSZ + yc, zc);
1643:   glVertex3d(xc, yc, zc); glVertex3d(xc, yc, CSSZ + zc);
1644:   glEnd();
1645:   /* Origin */
1646:   glLineWidth(3.0);
1647:   glBegin(GL_LINES);
1648:   glVertex3d(-CSZ, 0.0, 0.0); glVertex3d(CSZ, 0.0, 0.0);
1649:   glVertex3d(0.0, -CSZ, 0.0); glVertex3d(0.0, CSZ, 0.0);
1650:   glVertex3d(0.0, 0.0, -CSZ); glVertex3d(0.0, 0.0, CSZ);
1651:   glEnd();
1652:   show_center_box();
1653:   glEnable(GL_DEPTH_TEST); report_glerror(__LINE__);
1654:   glLineWidth(3.0); report_glerror(__LINE__);
1655:   glClear(GL_DEPTH_BUFFER_BIT); report_glerror(__LINE__);
1656:   glShadeModel(GL_FLAT); report_glerror(__LINE__);
1657:   /* X, Y, Z directions in the center of extend */
1658:   glBegin(GL_LINES);
1659:   glColor3f(1.0, 0.0, 0.0); glVertex3d(xc, yc, zc); glVertex3d(CSSZ + xc, yc, zc);
1660:   glColor3f(0.0, 1.0, 0.0); glVertex3d(xc, yc, zc); glVertex3d(xc, CSSZ + yc, zc);
1661:   glColor3f(0.0, 0.0, 1.0); glVertex3d(xc, yc, zc); glVertex3d(xc, yc, CSSZ + zc);
1662:   glEnd();
1663:   /* Origin */
1664:   glLineWidth(1.0);
1665:   glBegin(GL_LINES);
1666:   glColor3f(1.0, 0.0, 0.0); glVertex3d(-CSZ, 0.0, 0.0); glVertex3d(CSZ, 0.0, 0.0);
1667:   glColor3f(0.0, 1.0, 0.0); glVertex3d(0.0, -CSZ, 0.0); glVertex3d(0.0, CSZ, 0.0);
1668:   glColor3f(0.0, 0.0, 1.0); glVertex3d(0.0, 0.0, -CSZ); glVertex3d(0.0, 0.0, CSZ);
1669:   glEnd();
1670:   glLineWidth(1.0);
1671: }
1672: 
1673: void GraphicsDataInterpretation(union Unu *Startpunkt, int rs_coord,
1674:                                 union Unu *ValidCoords, int ValidCoordType, int stop_at_endsolid)
1675: /* Record Types: 

1676:  *     The 4 most significant bits of the 32 bit integer leading a data record are the record type.

1677:  *     The 28 least significant bits indicate the size of this record - counted in 8 byte blocks.

1678:  *     The records within a <<.vtf>> file is preceded by this header:

1679:  *       Zero terminated ANSI string "triangluara doriero (.vtf)\r\n\32"

1680:  *       16 bit integer, where the least significant byte is greater then the most significant

1681:  *       32 bit integer, value 987654321

1682:  *       32 bit float, value 7654321.0

1683:  *       64 bit double, value 9876543210123456.0

1684:  * 0000 =  0 = 0x0 : Set Color, indexed (next unsigned long = index to Coordinate_Array) ** size = 1 only

1685:  * 0001 =  1 = 0x1 : Surface Triangles, indexed (next unsigned long = count of 4-long-index_to_Coordiante_Array-group)

1686:  * 0010 =  2 = 0x2 : Surface Triangles, float (next unsigned long = count of 12-float-groups [normal, 3 corners])

1687:  * 0011 =  3 = 0x3 : Surface Triangles, double (next unsigned long = count of 12-double-groups [normal, 3 corners])

1688:  * 0100 =  4 = 0x4 : Set Color (next 3 floats: red, green, blue) ** size = 2 only

1689:  * 0101 =  5 = 0x5 : *** reserved ***

1690:  * 0110 =  6 = 0x6 : Coordiante Array (next unsigned long = count of 3-float-groups)

1691:  * 0111 =  7 = 0x7 : Coordinate Array (next unsigned long = count of 3-double-groups)

1692:  * 1000 =  8 = 0x8 : Begin Solid (next is name in UNICODE, zero terminated and filled with zero until the next 8 byte boundary is reached)

1693:  * 1001 =  9 = 0x9 : End Solid ** size = 1 only

1694:  * 1010 = 10 = 0xA : *** reserved ***

1695:  * 1011 = 11 = 0xB : *** reserved ***

1696:  * 1100 = 12 = 0xC : Jump to next memory location - only used within the viewer ** size = 1 only

1697:  * 1101 = 13 = 0xD : *** reserved ***

1698:  * 1110 = 14 = 0xE : *** reserved ***

1699:  * 1111 = 15 = 0xF : End of Data - only used within the viewer ** size = 1 only

1700:  */
1701: { union Unu *dta;
1702:   static union Unu *coords;
1703:   unsigned long typ, sz, rep, offs, start_solid_count;
1704:   static int coords_type;
1705:   if (rs_coord) { coords = NULL; coords_type = 0; }
1706:   if (ValidCoords != NULL) {
1707:     coords = ValidCoords; coords_type = ValidCoordType;
1708:   }
1709:   start_solid_count = 0;
1710:   for (dta = Startpunkt;
1711:        ((dta->dauxrigo.size_n_flags >> 28) & 0x0fL) != 0x0fL;
1712:        ) {
1713:     sz = dta->dauxrigo.size_n_flags & 0x0fffffffL;
1714:     typ = (dta->dauxrigo.size_n_flags >> 28) & 0x0fL;
1715:     switch (typ) {
1716:       case 12: /* Jump to next memory segment */
1717: #ifdef DUMP_VIEW_DATA
1718:         cPrintfI("Jump to new Segment ...\n", 0);
1719: #endif

1720:         dta = (union Unu *) dta->dauxrigo.There;
1721:       break;
1722:       case 8: /* Begin Solid */
1723: #ifdef DUMP_VIEW_DATA
1724:         cPrintfI("Begin solid ...\n", 0);
1725:         { unsigned int i;
1726:           for (i = 0; i + 2 < 4 * sz; i++)
1727:             cPrintfI(" %.4x", dta->nomo.ObjectName[i]);
1728:         } cPrintfI("\n", 0);
1729: #endif

1730:         if (stop_at_endsolid && (start_solid_count++)) return;
1731:         glColor4f(1.0, 1.0, 1.0, 1.0);
1732:         dta = (union Unu *) &(dta->Data[sz]);
1733:       break;
1734:       case 0: /* indexed color */
1735:         if (simple_color && !Wireframe) {
1736:           switch (coords_type) {
1737:             case 7:
1738:               SimpleColorSave((float) coords->triangulo.coordinates[dta->triangulatoro.repeated],
1739:                               (float) coords->triangulo.coordinates[dta->triangulatoro.repeated + 1],
1740:                               (float) coords->triangulo.coordinates[dta->triangulatoro.repeated + 2]);
1741:             break;
1742:             case 6:
1743:               SimpleColorSave((float) coords->trianguleto.coordinates[dta->triangulatoro.repeated],
1744:                               (float) coords->trianguleto.coordinates[dta->triangulatoro.repeated + 1],
1745:                               (float) coords->trianguleto.coordinates[dta->triangulatoro.repeated + 2]);
1746:             break;
1747:           }
1748:         } else {
1749:           switch (coords_type) {
1750:             case 7:
1751:               if (lighty_models)
1752:                 glColor4f(0.5F + 0.5F * (float) coords->triangulo.coordinates[dta->triangulatoro.repeated],
1753:                           0.5F + 0.5F * (float) coords->triangulo.coordinates[dta->triangulatoro.repeated + 1],
1754:                           0.5F + 0.5F * (float) coords->triangulo.coordinates[dta->triangulatoro.repeated + 2],
1755:                           1.0);
1756:               else
1757:                 glColor4f((float) coords->triangulo.coordinates[dta->triangulatoro.repeated],
1758:                           (float) coords->triangulo.coordinates[dta->triangulatoro.repeated + 1],
1759:                           (float) coords->triangulo.coordinates[dta->triangulatoro.repeated + 2],
1760:                           1.0);
1761:             break;
1762:             case 6:
1763:               if (lighty_models)
1764:                 glColor4f(0.5F + 0.5F * (float) coords->trianguleto.coordinates[dta->triangulatoro.repeated],
1765:                           0.5F + 0.5F * (float) coords->trianguleto.coordinates[dta->triangulatoro.repeated + 1],
1766:                           0.5F + 0.5F * (float) coords->trianguleto.coordinates[dta->triangulatoro.repeated + 2],
1767:                           1.0);
1768:               else
1769:                 glColor4f((float) coords->trianguleto.coordinates[dta->triangulatoro.repeated],
1770:                           (float) coords->trianguleto.coordinates[dta->triangulatoro.repeated + 1],
1771:                           (float) coords->trianguleto.coordinates[dta->triangulatoro.repeated + 2],
1772:                           1.0);
1773:             break;
1774:           }
1775:         }
1776:         dta = (union Unu *) &(dta->Data[sz]);
1777:       break;
1778:       case 4: /* set color */
1779: #ifdef DUMP_VIEW_DATA
1780:         cPrintfI("color ...\n", 0);
1781:         cPrintfF(" %5.3f", dta->coloro.r);
1782:         cPrintfF(" %5.3f", dta->coloro.g);
1783:         cPrintfF(" %5.3f\n", dta->coloro.b);
1784: #endif

1785:         if (simple_color && !Wireframe) 
1786:          SimpleColorSave(dta->coloro.r, dta->coloro.g, dta->coloro.b);
1787:           else {
1788: #ifdef FADEN_1
1789:            float colors[4];
1790:            colors[0] = dta->coloro.r;
1791:            colors[1] = dta->coloro.g;
1792:            colors[2] = dta->coloro.b;
1793:            colors[3] = 1.0;
1794:            if (maxr < dta->coloro.r) maxr = dta->coloro.r;
1795:              else if (minr > dta->coloro.r) minr = dta->coloro.r;
1796:            if (maxg < dta->coloro.g) maxg = dta->coloro.g;
1797:              else if (ming > dta->coloro.g) ming = dta->coloro.g;
1798:            if (maxb < dta->coloro.b) maxb = dta->coloro.b;
1799:              else if (minb > dta->coloro.b) minb = dta->coloro.b;
1800:            // glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);

1801:            // glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);

1802: #endif

1803:          if (lighty_models)
1804:            glColor4f(0.5F + 0.5F * dta->coloro.r, 0.5F + 0.5F * dta->coloro.g, 0.5F + 0.5F * dta->coloro.b, 1.0);
1805:           else
1806:            glColor4f(dta->coloro.r, dta->coloro.g, dta->coloro.b, 1.0);
1807:         }
1808: #ifdef DUMP_MAT
1809:         fprintf(trail, "Color: %5.3f %5.3f %5.3f\n",
1810:           dta->coloro.r, dta->coloro.g, dta->coloro.b);
1811:         fflush(trail);
1812: #endif

1813:         dta = (union Unu *) &(dta->Data[sz]);
1814:       break;
1815:       case 7:
1816:         coords = dta;
1817:         coords_type = 7;
1818:         dta = (union Unu *) &(dta->Data[sz]);
1819:       break;
1820:       case 6:
1821:         coords = dta;
1822:         coords_type = 6;
1823:         dta = (union Unu *) &(dta->Data[sz]);
1824:       break;
1825:       case 1:
1826: #ifdef DUMP_VIEW_DATA
1827:         cPrintfI("%d triangles by index ", dta->triangulatoro.repeated);
1828:         cPrintfI("[%d] ...\n", sz);
1829: #endif

1830:         for (rep = offs = 0; rep < dta->triangulatoro.repeated; rep++) {
1831:           if (Wireframe) glBegin(GL_LINE_LOOP);
1832:           if (simple_color && !Wireframe) switch (coords_type) {
1833:             case 7:
1834:               SimpleColorSetNormal(coords->triangulo.coordinates[dta->triangulatoro.index[offs]],
1835:                                    coords->triangulo.coordinates[dta->triangulatoro.index[offs] + 1],
1836:                                    coords->triangulo.coordinates[dta->triangulatoro.index[offs] + 2]);
1837:             break;
1838:             case 6:
1839:               SimpleColorSetNormal(coords->trianguleto.coordinates[dta->triangulatoro.index[offs]],
1840:                                    coords->trianguleto.coordinates[dta->triangulatoro.index[offs] + 1],
1841:                                    coords->trianguleto.coordinates[dta->triangulatoro.index[offs] + 2]);
1842:             break;
1843:           }
1844:           switch (coords_type) {
1845:             case 7:
1846:               glNormal3d(coords->triangulo.coordinates[dta->triangulatoro.index[offs]],
1847:                          coords->triangulo.coordinates[dta->triangulatoro.index[offs] + 1],
1848:                          coords->triangulo.coordinates[dta->triangulatoro.index[offs] + 2]);
1849:               glVertex3d(coords->triangulo.coordinates[dta->triangulatoro.index[offs + 1]],
1850:                          coords->triangulo.coordinates[dta->triangulatoro.index[offs + 1] + 1],
1851:                          coords->triangulo.coordinates[dta->triangulatoro.index[offs + 1] + 2]);
1852:               glVertex3d(coords->triangulo.coordinates[dta->triangulatoro.index[offs + 2]],
1853:                          coords->triangulo.coordinates[dta->triangulatoro.index[offs + 2] + 1],
1854:                          coords->triangulo.coordinates[dta->triangulatoro.index[offs + 2] + 2]);
1855:               glVertex3d(coords->triangulo.coordinates[dta->triangulatoro.index[offs + 3]],
1856:                          coords->triangulo.coordinates[dta->triangulatoro.index[offs + 3] + 1],
1857:                          coords->triangulo.coordinates[dta->triangulatoro.index[offs + 3] + 2]);
1858:             break;
1859:             case 6:
1860:               glNormal3f(coords->trianguleto.coordinates[dta->triangulatoro.index[offs]],
1861:                          coords->trianguleto.coordinates[dta->triangulatoro.index[offs] + 1],
1862:                          coords->trianguleto.coordinates[dta->triangulatoro.index[offs] + 2]);
1863:               glVertex3f(coords->trianguleto.coordinates[dta->triangulatoro.index[offs + 1]],
1864:                          coords->trianguleto.coordinates[dta->triangulatoro.index[offs + 1] + 1],
1865:                          coords->trianguleto.coordinates[dta->triangulatoro.index[offs + 1] + 2]);
1866:               glVertex3f(coords->trianguleto.coordinates[dta->triangulatoro.index[offs + 2]],
1867:                          coords->trianguleto.coordinates[dta->triangulatoro.index[offs + 2] + 1],
1868:                          coords->trianguleto.coordinates[dta->triangulatoro.index[offs + 2] + 2]);
1869:               glVertex3d(coords->trianguleto.coordinates[dta->triangulatoro.index[offs + 3]],
1870:                          coords->trianguleto.coordinates[dta->triangulatoro.index[offs + 3] + 1],
1871:                          coords->trianguleto.coordinates[dta->triangulatoro.index[offs + 3] + 2]);
1872:             break;
1873:           }
1874:           if (Wireframe) glEnd();
1875:           offs += 4;
1876:         }
1877:         dta = (union Unu *) &(dta->Data[sz]);
1878:       break;
1879:       case 3:
1880: #ifdef DUMP_VIEW_DATA
1881:         cPrintfI("%d triangles ", dta->triangulo.repeated);
1882:         cPrintfI("[%d] ...\n", sz);
1883: #endif

1884:         for (rep = offs = 0; rep < dta->triangulo.repeated; rep++) {
1885: #ifdef DUMP_VIEW_DATA
1886:           cPrintfF(" n %8.3f", (float) dta->triangulo.coordinates[offs]);
1887:           cPrintfF(" %8.3f", (float) dta->triangulo.coordinates[offs + 1]);
1888:           cPrintfF(" %8.3f\n", (float) dta->triangulo.coordinates[offs + 2]);
1889:           cPrintfF("   %8.3f", (float) dta->triangulo.coordinates[offs + 3]);
1890:           cPrintfF(" %8.3f", (float) dta->triangulo.coordinates[offs + 4]);
1891:           cPrintfF(" %8.3f\n", (float) dta->triangulo.coordinates[offs + 5]);
1892:           cPrintfF("   %8.3f", (float) dta->triangulo.coordinates[offs + 6]);
1893:           cPrintfF(" %8.3f", (float) dta->triangulo.coordinates[offs + 7]);
1894:           cPrintfF(" %8.3f\n", (float) dta->triangulo.coordinates[offs + 8]);
1895:           cPrintfF("   %8.3f", (float) dta->triangulo.coordinates[offs + 9]);
1896:           cPrintfF(" %8.3f", (float) dta->triangulo.coordinates[offs + 10]);
1897:           cPrintfF(" %8.3f\n", (float) dta->triangulo.coordinates[offs + 11]);
1898: #endif

1899:           if (Wireframe) glBegin(GL_LINE_LOOP);
1900:           if (simple_color && !Wireframe)
1901:           SimpleColorSetNormal(dta->triangulo.coordinates[offs     ],
1902:                                dta->triangulo.coordinates[offs +  1],
1903:                                dta->triangulo.coordinates[offs +  2]);
1904: #ifdef FADEN_1
1905:           NLG = dta->triangulo.coordinates[offs    ] * dta->triangulo.coordinates[offs    ]
1906:               + dta->triangulo.coordinates[offs + 1] * dta->triangulo.coordinates[offs + 1]
1907:               + dta->triangulo.coordinates[offs + 2] * dta->triangulo.coordinates[offs + 2];
1908:           if (NLGmin > NLG) NLGmin = NLG;
1909:           if (NLGmax < NLG) NLGmax = NLG;
1910: #endif

1911:           glNormal3d(dta->triangulo.coordinates[offs     ],
1912:                      dta->triangulo.coordinates[offs +  1],
1913:                      dta->triangulo.coordinates[offs +  2]);
1914:           glVertex3d(dta->triangulo.coordinates[offs +  3],
1915:                      dta->triangulo.coordinates[offs +  4],
1916:                      dta->triangulo.coordinates[offs +  5]);
1917:           glVertex3d(dta->triangulo.coordinates[offs +  6],
1918:                      dta->triangulo.coordinates[offs +  7],
1919:                      dta->triangulo.coordinates[offs +  8]);
1920:           glVertex3d(dta->triangulo.coordinates[offs +  9],
1921:                      dta->triangulo.coordinates[offs + 10],
1922:                      dta->triangulo.coordinates[offs + 11]);
1923: #ifdef FADEN_1
1924:           ndmin = ndmax = dta->triangulo.coordinates[offs     ] * dta->triangulo.coordinates[offs +  3]
1925:                         + dta->triangulo.coordinates[offs +  1] * dta->triangulo.coordinates[offs +  4]
1926:                         + dta->triangulo.coordinates[offs +  2] * dta->triangulo.coordinates[offs +  5];
1927:           nd = dta->triangulo.coordinates[offs     ] * dta->triangulo.coordinates[offs +  6]
1928:              + dta->triangulo.coordinates[offs +  1] * dta->triangulo.coordinates[offs +  7]
1929:              + dta->triangulo.coordinates[offs +  2] * dta->triangulo.coordinates[offs +  8];
1930:           if (nd > ndmax) ndmax = nd; if (nd < ndmin) ndmin = nd;
1931:           nd = dta->triangulo.coordinates[offs     ] * dta->triangulo.coordinates[offs +  9]
1932:              + dta->triangulo.coordinates[offs +  1] * dta->triangulo.coordinates[offs + 10]
1933:              + dta->triangulo.coordinates[offs +  2] * dta->triangulo.coordinates[offs + 11];
1934:           if (nd > ndmax) ndmax = nd; if (nd < ndmin) ndmin = nd;
1935:           if (nddiff < ndmax - ndmin) nddiff = ndmax - ndmin;
1936: #endif

1937: #ifdef DUMP_MAT
1938:           fprintf(trail, "Normal:\n%9.3lf %9.3lf %9.3lf\n"
1939:                          "Vertex:\n%9.3lf %9.3lf %9.3lf\n%9.3lf %9.3lf %9.3lf\n%9.3lf %9.3lf %9.3lf\n",
1940:                      dta->triangulo.coordinates[offs     ],
1941:                      dta->triangulo.coordinates[offs +  1],
1942:                      dta->triangulo.coordinates[offs +  2],
1943:                      dta->triangulo.coordinates[offs +  3],
1944:                      dta->triangulo.coordinates[offs +  4],
1945:                      dta->triangulo.coordinates[offs +  5],
1946:                      dta->triangulo.coordinates[offs +  6],
1947:                      dta->triangulo.coordinates[offs +  7],
1948:                      dta->triangulo.coordinates[offs +  8],
1949:                      dta->triangulo.coordinates[offs +  9],
1950:                      dta->triangulo.coordinates[offs + 10],
1951:                      dta->triangulo.coordinates[offs + 11]);
1952:           fflush(trail);
1953: #endif

1954:           if (Wireframe) glEnd();
1955:           offs += 12;
1956:         }
1957:         dta = (union Unu *) &(dta->Data[sz]);
1958:       break;
1959:       case 2:
1960: #ifdef DUMP_VIEW_DATA
1961:         cPrintfI("%d small triangles ", dta->trianguleto.repeated);
1962:         cPrintfI("[%d] ...\n", sz);
1963: #endif

1964:         for (rep = offs = 0; rep < dta->trianguleto.repeated; rep++) {
1965: #ifdef DUMP_VIEW_DATA
1966:           cPrintfF(" n %8.3f", dta->trianguleto.coordinates[offs]);
1967:           cPrintfF(" %8.3f", dta->trianguleto.coordinates[offs + 1]);
1968:           cPrintfF(" %8.3f\n", dta->trianguleto.coordinates[offs + 2]);
1969:           cPrintfF("   %8.3f", dta->trianguleto.coordinates[offs + 3]);
1970:           cPrintfF(" %8.3f", dta->trianguleto.coordinates[offs + 4]);
1971:           cPrintfF(" %8.3f\n", dta->trianguleto.coordinates[offs + 5]);
1972:           cPrintfF("   %8.3f", dta->trianguleto.coordinates[offs + 6]);
1973:           cPrintfF(" %8.3f", dta->trianguleto.coordinates[offs + 7]);
1974:           cPrintfF(" %8.3f\n", dta->trianguleto.coordinates[offs + 8]);
1975:           cPrintfF("   %8.3f", dta->trianguleto.coordinates[offs + 9]);
1976:           cPrintfF(" %8.3f", dta->trianguleto.coordinates[offs + 10]);
1977:           cPrintfF(" %8.3f\n", dta->trianguleto.coordinates[offs + 11]);
1978: #endif

1979:           if (Wireframe) glBegin(GL_LINE_LOOP);
1980:           if (simple_color && !Wireframe)
1981:           SimpleColorSetNormal((double) dta->trianguleto.coordinates[offs     ],
1982:                                (double) dta->trianguleto.coordinates[offs +  1],
1983:                                (double) dta->trianguleto.coordinates[offs +  2]);
1984:           glNormal3f(dta->trianguleto.coordinates[offs     ],
1985:                      dta->trianguleto.coordinates[offs +  1],
1986:                      dta->trianguleto.coordinates[offs +  2]);
1987:           glVertex3f(dta->trianguleto.coordinates[offs +  3],
1988:                      dta->trianguleto.coordinates[offs +  4],
1989:                      dta->trianguleto.coordinates[offs +  5]);
1990:           glVertex3f(dta->trianguleto.coordinates[offs +  6],
1991:                      dta->trianguleto.coordinates[offs +  7],
1992:                      dta->trianguleto.coordinates[offs +  8]);
1993:           glVertex3f(dta->trianguleto.coordinates[offs +  9],
1994:                      dta->trianguleto.coordinates[offs + 10],
1995:                      dta->trianguleto.coordinates[offs + 11]);
1996:           if (Wireframe) glEnd();
1997:           offs += 12;
1998:         }
1999:         dta = (union Unu *) &(dta->Data[sz]);
2000:       break;
2001:       case 9:
2002:         if (stop_at_endsolid) return;
2003:       default: /* perhaps 9= EndSolid */
2004: #ifdef DUMP_VIEW_DATA
2005:         cPrintfI("Unknown %lx ", typ);
2006:         cPrintfI("[%ld] ...\n", sz);
2007: #endif

2008:         dta = (union Unu *) &(dta->Data[sz]);
2009:       break;
2010:     }
2011:   }
2012: }
2013: 
2014: void DisplayModelFromMemory(void)
2015: { struct MODEL_SELECT *vmod;
2016: #ifdef FADEN_1
2017:   float maxr, maxg, maxb, minr, ming, minb;
2018:   double NLGmin, NLGmax, NLG, nd, ndmin, ndmax, nddiff;
2019:   maxr = maxg = maxb = 0.0; minr = ming = minb = 0.0;
2020:   NLGmin = 1.0; NLGmax = 0.0, nddiff = 0.0;
2021: #endif

2022:   // glColor3f(0.2, 0.2, 0.2);

2023:   if (TDate == NULL) return;
2024:   if (simple_color && !Wireframe) {
2025:     glShadeModel(GL_FLAT); report_glerror(__LINE__);
2026:     glDisable(GL_LIGHTING); report_glerror(__LINE__);
2027:     glDisable(GL_LIGHT0); report_glerror(__LINE__);
2028:   }
2029:   if (UseLists) {
2030:     if (!RebuildLists) {
2031:       /* Änderung von Wireframe setzt RebuildLists auf 1 */
2032:       for (vmod = model_select_chain; vmod != NULL; vmod = vmod->next)
2033:        if ((vmod->Name != NULL)
2034:         && (vmod->Start != NULL)
2035:         && (ObjectsShowAll || (vmod->Display == 1)))
2036:          glCallList(vmod->Number);
2037:       return;
2038:     }
2039:     /* RebuildLists */
2040: #ifdef FADEN_2
2041:     cPrintfI("VALID_MODES = %d\n", VALID_MODELS);
2042: #endif

2043: #ifdef DUMP_MODEL_SELECT_RECORDS
2044:     DumpModelSelectRecord();
2045: #endif

2046: #ifdef FADEN_2
2047:     cPrintfI("VALID_MODES = %d\n", VALID_MODELS);
2048: #endif

2049:     for (vmod = model_select_chain; vmod != NULL; vmod = vmod->next)
2050:      if ((vmod->Name != NULL)
2051:       && (vmod->Start != NULL)) {
2052:       glNewList(vmod->Number, (ObjectsShowAll || (vmod->Display == 1)) ? GL_COMPILE_AND_EXECUTE : GL_COMPILE);
2053:       if (!Wireframe) glBegin(GL_TRIANGLES);
2054:       GraphicsDataInterpretation(             vmod->Start,
2055:         /* Reset Coord Array Pointer       */ 1,
2056:         /* Coord Pointer and Type at Start */ vmod->ValidCoords, vmod->ValidCoordType,
2057:         /* Stop at Endsolid                */ 1);
2058:       if (!Wireframe) glEnd();
2059:       glEndList();
2060:     }
2061:     RebuildLists = 0;
2062:   } else { /* e.g. simple_color, or "no option" */
2063:     if (!Wireframe) glBegin(GL_TRIANGLES);
2064:     if (!ObjectsShowAll) {
2065:       for (vmod = model_select_chain; vmod != NULL; vmod = vmod->next)
2066:        if ((vmod->Name != NULL)
2067:         && (vmod->Start != NULL)
2068:         && (vmod->Display == 1))
2069:         GraphicsDataInterpretation(             vmod->Start,
2070:           /* Reset Coord Array Pointer       */ 1,
2071:           /* Coord Pointer and Type at Start */ vmod->ValidCoords, vmod->ValidCoordType,
2072:           /* Stop at Endsolid                */ 1);
2073:     } else {
2074:       GraphicsDataInterpretation((union Unu *) &(TDate->Data[0]),
2075:         /* Reset Coord Array Pointer       */  1,
2076:         /* Coord Pointer and Type at Start */  NULL, 0,
2077:         /* Stop at Endsolid                */  0);
2078:     }
2079:     if (!Wireframe) glEnd();
2080:   }
2081: #ifdef FADEN_1
2082:   cPrintfI("Farbwerte:\n", 0);
2083:   cPrintfF("R = %f ..", minr); cPrintfF(" %f\n", maxr);
2084:   cPrintfF("G = %f ..", ming); cPrintfF(" %f\n", maxg);
2085:   cPrintfF("B = %f ..", minb); cPrintfF(" %f\n", maxb);
2086:   cPrintfI("\nModellgröße:\n", 0);
2087:   cPrintfF("[ %6.3f ..", (float) xmin); cPrintfF(" %6.3f ", (float) xmax);
2088:   cPrintfF("| %6.3f ..", (float) ymin); cPrintfF(" %6.3f ", (float) ymax);
2089:   cPrintfF("| %6.3f ..", (float) zmin); cPrintfF(" %6.3f ]\n", (float) zmax);
2090:   cPrintfI("\nNormalenlängen zum Quadrat:\n", 0);
2091:   cPrintfF("  %6.3f ..", (float) NLGmin); cPrintfF(" %.3f\n", (float) NLGmax);
2092:   cPrintfF("Endpunkthöhendifferenz: %6.4f\n\n", (float) nddiff);
2093: #endif

2094: }
2095: 
2096: 
2097: void NoModelDefaultModel(void)
2098: {
2099:   if (lighty_models) glColor3f(1.0F, 0.5F, 0.5F); else glColor3f(1.0F, 0.0F, 0.0F);
2100:   S_FONT_stroketext(1.0, 1.0, - 0.5F * S_FONT_stringwidth(1.0, 1.0, Title1eo), 4.0, 3.0, Title1eo, !Wireframe);
2101:   S_FONT_stroketext(1.0, 1.0, - 0.5F * S_FONT_stringwidth(1.0, 1.0, Title2eo), 2.0, 3.0, Title2eo, !Wireframe);
2102:   S_FONT_stroketext(1.0, 1.0, - 0.5F * S_FONT_stringwidth(1.0, 1.0, Title3eo), 0.0, 3.0, Title3eo, !Wireframe);
2103:   if (lighty_models) glColor3f(0.5F, 0.5F, 1.0F); else glColor3f(0.0F, 0.0F, 1.0F);
2104:   S_FONT_stroketext(VSC, VSW, - 0.5F * S_FONT_stringwidth(VSC, VSW, Versn_eo), 2.5 - 0.5 * VSC, 0.5, Versn_eo, !Wireframe);
2105: 
2106:   glPushMatrix();
2107:   glRotated(180.0, 0.0, 1.0, 0.0);
2108: 
2109:   if (lighty_models) glColor3f(0.9F, 1.0F, 0.5F); else glColor3f(0.8F, 1.0F, 0.0F);
2110:   S_FONT_stroketext(1.0, 1.0, - 0.5F * S_FONT_stringwidth(1.0, 1.0, Title1en), 4.0, 3.0, Title1en, !Wireframe);
2111:   S_FONT_stroketext(1.0, 1.0, - 0.5F * S_FONT_stringwidth(1.0, 1.0, Title2en), 2.0, 3.0, Title2en, !Wireframe);
2112:   S_FONT_stroketext(1.0, 1.0, - 0.5F * S_FONT_stringwidth(1.0, 1.0, Title3en), 0.0, 3.0, Title3en, !Wireframe);
2113:   if (lighty_models) glColor3f(0.5F, 0.5F, 1.0F); else glColor3f(0.0F, 0.0F, 1.0F);
2114:   S_FONT_stroketext(VSC, VSW, - 0.5F * S_FONT_stringwidth(VSC, VSW, Versn_en), 2.5F - 0.5F * VSC, 0.5F, Versn_en, !Wireframe);
2115: 
2116:   glPopMatrix();
2117: }
2118: 
2119: void NoModelExtent(void)
2120: { float sz;
2121:   xmax = 0.5 * S_FONT_stringwidth(1.0, 1.0, Title1en);
2122:   sz = 0.5F * S_FONT_stringwidth(1.0, 1.0, Title2en); if (sz > xmax) xmax = sz;
2123:   sz = 0.5F * S_FONT_stringwidth(1.0, 1.0, Title3en); if (sz > xmax) xmax = sz;
2124:   sz = 0.5F * S_FONT_stringwidth(1.0, 1.0, Title1eo); if (sz > xmax) xmax = sz;
2125:   sz = 0.5F * S_FONT_stringwidth(1.0, 1.0, Title2eo); if (sz > xmax) xmax = sz;
2126:   sz = 0.5F * S_FONT_stringwidth(1.0, 1.0, Title3eo); if (sz > xmax) xmax = sz;
2127:   sz = 0.5F * S_FONT_stringwidth(VSC, VSW, Versn_en); if (sz > xmax) xmax = sz;
2128:   sz = 0.5F * S_FONT_stringwidth(VSC, VSW, Versn_eo); if (sz > xmax) xmax = sz;
2129:   xmin = - xmax;
2130:   ymin = 0.0; ymax = 5.0;
2131:   zmin = -3.0; zmax = 3.0;
2132: }
2133: 
2134: 
2135: void view_pan_limit(void)
2136: { double Limitation;
2137:   Limitation = 1.0 - 1.0 / view_scale;
2138:   if (view_x < - Limitation) view_x = - Limitation;
2139:   if (view_x >   Limitation) view_x =   Limitation;
2140:   if (view_y < - Limitation) view_y = - Limitation;
2141:   if (view_y >   Limitation) view_y =   Limitation;
2142: }
2143: 
2144: void view_pan(WORD x, WORD y)
2145: { double dx, dy;
2146:   dx = (x - screen_center_x) * 2.0 / screen_size / view_scale;
2147:   dy = (y - screen_center_y) * 2.0 / screen_size / view_scale;
2148:   if (mouse_inversion & 4) {
2149:     view_x += dx; view_y -= dy;
2150:   } else {
2151:     view_x -= dx; view_y += dy;
2152:   }
2153: }
2154: 
2155: void view_zoom(WORD y)
2156: { double dy, veraenderung;
2157:   dy = (screen_center_y - y) * 2.0 / screen_size;
2158:   // f = pow((double) sqrt(8.0), dy);

2159:   veraenderung = exp((mouse_inversion & 2) ? -dy : dy);
2160:   view_scale *= veraenderung;
2161:   if (view_scale > MaxZoomFaktor) view_scale = MaxZoomFaktor;
2162:   if (view_scale < 1.0) view_scale = 1.0;
2163: }
2164: 
2165: 
2166: #define DRAW_ADD_ROT 1
2167: 
2168: void DrawExtend(HDC hdc, RECT clientRect)
2169: { char Zl[100];
2170:   wchar_t wZl[100];
2171:   TEXTMETRIC tm;
2172:   GetTextMetrics(hdc, &tm);
2173:   SetBkMode(hdc, TRANSPARENT);
2174:   SetTextColor(hdc, (39 * SBG_R + 44 * SBG_G + 17 * SBG_B < 12800) ? RGB(255, 255, 255) : RGB(0, 0, 0));
2175:   sprintf(Zl, "X: %+9lE ... %+9lE", xmin, xmax);
2176:   wsprintf(wZl, L"%S", Zl);
2177:   TextOut(hdc, 3, clientRect.bottom - (tm.tmHeight + tm.tmInternalLeading) * 3, wZl, wcslen(wZl));
2178:   sprintf(Zl, "Y: %+9lE ... %+9lE", ymin, ymax);
2179:   wsprintf(wZl, L"%S", Zl);
2180:   TextOut(hdc, 3, clientRect.bottom - (tm.tmHeight + tm.tmInternalLeading) * 2, wZl, wcslen(wZl));
2181:   sprintf(Zl, "Z: %+9lE ... %+9lE", zmin, zmax);
2182:   wsprintf(wZl, L"%S", Zl);
2183:   TextOut(hdc, 3, clientRect.bottom - (tm.tmHeight + tm.tmInternalLeading) * 1, wZl, wcslen(wZl));
2184: }
2185: 
2186: void Draw3D(HDC hDC, RECT clientRect, int addition, WORD x, WORD y)
2187: {
2188:     GLdouble li, re, ob, ut, dx, dy, dw;
2189: 
2190:     if (!VALID_MODELS && !IN_FILE_DIALOG) NoModelExtent();
2191: 
2192:     xc = xmax - xmin;
2193:     yc = ymax - ymin;
2194:     zc = zmax - zmin;
2195:     halfdiagonal = sqrt(xc * xc + yc * yc + zc * zc) * 0.5;
2196:     scale = 1.0 / halfdiagonal / RANDFAKTOR;
2197:     xc = (xmax + xmin) * 0.5F;
2198:     yc = (ymax + ymin) * 0.5F;
2199:     zc = (zmax + zmin) * 0.5F;
2200: 
2201:     screen_center_x = 0.5F * clientRect.right;
2202:     screen_center_y = 0.5F * clientRect.bottom;
2203: 
2204:     if (clientRect.right > clientRect.bottom) {
2205:       ob = 1.0; ut = -1.0;
2206:       re = ((double) clientRect.right) / ((double) clientRect.bottom);
2207:       li = -re;
2208:       screen_size = (float) clientRect.bottom;
2209:     } else {
2210:       li = -1.0; re = 1.0;
2211:       ob = ((double) clientRect.bottom) / ((double) clientRect.right);
2212:       ut = -ob;
2213:       screen_size = (float) clientRect.right;
2214:     }
2215:     if (screen_size <= 0.0) screen_size = 1.0;
2216: 
2217:     view_pan_limit();
2218:     li = li / view_scale + view_x;
2219:     re = re / view_scale + view_x;
2220:     ob = ob / view_scale + view_y;
2221:     ut = ut / view_scale + view_y;
2222: 
2223:     SetCursor(NULL);
2224: 
2225:     wglMakeCurrent(hDC, hglrc);
2226:     glMatrixMode(GL_PROJECTION); report_glerror(__LINE__);
2227:     glLoadIdentity(); report_glerror(__LINE__);
2228:     glViewport(0, 0, clientRect.right, clientRect.bottom); report_glerror(__LINE__);
2229:     glOrtho(li, re, ut, ob, -1.0, 1.0); report_glerror(__LINE__);
2230: 
2231:     glMatrixMode(GL_MODELVIEW); report_glerror(__LINE__);
2232:     glLoadIdentity(); report_glerror(__LINE__);
2233: 
2234:     if (Wireframe) {
2235:       glShadeModel(GL_FLAT); report_glerror(__LINE__);
2236:     } else {
2237:       glShadeModel(GL_SMOOTH); report_glerror(__LINE__);
2238:     }
2239:     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); report_glerror(__LINE__);
2240:     // glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR,  specular); report_glerror(__LINE__);

2241:     // glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shininess); report_glerror(__LINE__);

2242:     // glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT,   ambient); report_glerror(__LINE__);

2243:     // glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,   diffuse); report_glerror(__LINE__);

2244:     glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); report_glerror(__LINE__);
2245:     glEnable(GL_COLOR_MATERIAL); report_glerror(__LINE__);
2246:     // glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);

2247:     glLightfv(GL_LIGHT0, GL_POSITION, position0); report_glerror(__LINE__);
2248:     // glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); report_glerror(__LINE__);

2249:     // glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); report_glerror(__LINE__);

2250:     if (Wireframe) {
2251:       glDisable(GL_LIGHTING); report_glerror(__LINE__);
2252:     } else {
2253:       glEnable(GL_LIGHTING); report_glerror(__LINE__);
2254:     }
2255:     glEnable(GL_LIGHT0); report_glerror(__LINE__);
2256:     glEnable(GL_DEPTH_TEST); report_glerror(__LINE__);
2257: 
2258:     if (CullFace) {
2259:       glCullFace(GL_BACK); report_glerror(__LINE__);
2260:       glEnable(GL_CULL_FACE); report_glerror(__LINE__);
2261:     } else {
2262:       glDisable(GL_CULL_FACE); report_glerror(__LINE__);
2263:     }
2264: 
2265:     glColor4f(1.0, 1.0, 1.0, 1.0); report_glerror(__LINE__);
2266:     if (simple_color && !Wireframe) SimpleColorSave(1.0, 1.0, 1.0);
2267: 
2268:     glClearColor(bg_r, bg_g, bg_b, 0.0); report_glerror(__LINE__);
2269:     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); report_glerror(__LINE__);
2270: 
2271:         if (!IN_FILE_DIALOG) {
2272:     switch(Projection) {
2273:       case PROJ_LAST:
2274:         glLoadMatrixd(MVMat); report_glerror(__LINE__);
2275:       break;
2276:       /* case PROJ_FRONT: break; */
2277:       case PROJ_LEFT:
2278:         Rotate0(90.0, 0.0, 1.0, 0.0);
2279:       break;
2280:       case PROJ_RIGHT:
2281:         Rotate0(-90.0, 0.0, 1.0, 0.0);
2282:       break;
2283:       case PROJ_BACK:
2284:         Rotate0(180.0, 0.0, 1.0, 0.0);
2285:       break;
2286:       case PROJ_TOP:
2287:         Rotate0(90.0, 1.0, 0.0, 0.0);
2288:       break;
2289:       case PROJ_BOTTOM:
2290:         Rotate0(-90.0, 1.0, 0.0, 0.0);
2291:       break;
2292:       case PROJ_ISO:
2293:         Rotate0(-45.0, 0.0, 1.0, 0.0);
2294:         Rotate0(35.26439, 1.0, 0.0, 0.0);
2295:       break;
2296:       case PROJ_DI:
2297:         Rotate0(-20.705, 0.0, 1.0, 0.0);
2298:         Rotate0(19.471, 1.0, 0.0, 0.0);
2299:       break;
2300:       case PROJ_TRI:
2301:         Rotate0(-37.761, 0.0, 1.0, 0.0);
2302:         Rotate0(14.763, 1.0, 0.0, 0.0);
2303:       break;
2304:     }
2305:     if (Projection != PROJ_LAST) glScaled(scale, scale, scale);
2306:     switch(addition) {
2307:       case DRAW_ADD_ROT:
2308:         if (mouse_inversion & 1) {
2309:           dx = screen_center_x - x;
2310:           dy = screen_center_y - y;
2311:         } else {
2312:           dx = x - screen_center_x;
2313:           dy = y - screen_center_y;
2314:         }
2315:         dw = sqrt(dx * dx + dy * dy) / screen_size * 180.0 / view_scale;
2316:         Rotate0(dw, dy, dx, 0.0);
2317:         Projection = PROJ_LAST;
2318:       break;
2319:     }
2320:     glGetDoublev(GL_MODELVIEW_MATRIX, MVMat); report_glerror(__LINE__); dump_Mat();
2321:     glTranslated(-xc, -yc, -zc);
2322:     /* I scaled the model to match a viewing port size of -1.0 .. 1.0, and on large

2323:      * Models the colors were too light. Normalizing of the normal vectors did help

2324:      * correcting the colors.

2325:      */
2326:     glEnable(GL_NORMALIZE);
2327: 
2328:     /* Display Model */
2329:     if (VALID_MODELS) DisplayModelFromMemory(); else NoModelDefaultModel();
2330: 
2331:     /* Display Coordinate System, when requested */
2332:     if (Disp_CS) CoordinateSystem();
2333:     }
2334: 
2335:     glFlush(); report_glerror(__LINE__);
2336:     wglMakeCurrent(NULL, NULL);
2337:     SetCursor(LoadCursor(NULL, IDC_CROSS));
2338: }
2339: 
2340: 
2341: void DrawScene(HWND hwnd, int addition, WORD x, WORD y)
2342: {
2343:     HDC hDC;
2344:     PAINTSTRUCT paintStruct;
2345:     RECT clientRect;
2346: 
2347:     InvalidateRect(hwnd, NULL, FALSE);
2348: 
2349:     hDC = BeginPaint(hwnd, &paintStruct);
2350:     if (hDC != NULL) {
2351:       GetClientRect(hwnd, &clientRect);
2352:       Draw3D(hDC, clientRect, addition, x, y);
2353:       if (Disp_Extend) DrawExtend(hDC, clientRect);
2354:       EndPaint(hwnd, &paintStruct);
2355:     }
2356: }
2357: 
2358: BOOL InsertSubmenuString(HMENU hMenu, UINT Pos, BOOL byPos, HMENU submenu, WCHAR *Text)
2359: { MENUITEMINFO mii;
2360:   // char Name[100];

2361:   mii.cbSize = sizeof(MENUITEMINFO);
2362:   mii.fMask = MIIM_SUBMENU | MIIM_TYPE;
2363:   mii.fType = MFT_STRING;
2364:   mii.fState = MFS_DEFAULT;
2365:   mii.wID = 0;
2366:   mii.hSubMenu = submenu;
2367:   mii.hbmpChecked = NULL;
2368:   mii.hbmpUnchecked = NULL;
2369:   mii.dwItemData = 0;
2370:   mii.dwTypeData = Text;
2371:   mii.cch = wcslen(Text);
2372:   return InsertMenuItem(hMenu, Pos, byPos, &mii);
2373: }
2374: 
2375: void BuildMenue(HWND hwnd)
2376: { HMENU newmenu, oldmenu;
2377: 
2378:   langmenu = CreateMenu();
2379:   AppendMenu(langmenu, MF_STRING, MN_SET_LANG_EO,  L"Esperant&o");
2380:   AppendMenu(langmenu, MF_STRING, MN_SET_LANG_EOX, L"Esperanto &X kodo");
2381:   AppendMenu(langmenu, MF_STRING, MN_SET_LANG_GER, L"&Deutsch");
2382:   AppendMenu(langmenu, MF_STRING, MN_SET_LANG_ENG, L"&English");
2383: 
2384:   newmenu = CreateMenu();
2385: 
2386:   filemenu = CreateMenu();
2387:   AppendMenu(filemenu, MF_STRING, MN_FILE_OPEN,
2388:              StrByLang(X_CODING, L"&aperti", L"\xffff",
2389:                        L"ö&ffnen",
2390:                        L"&open",
2391:                        NULL));
2392:   AppendMenu(filemenu, MF_STRING, MN_FILE_SAVE,
2393:              StrByLang(X_CODING, L"&sekurigi", L"\xffff",
2394:                        L"&speichern",
2395:                        L"&save",
2396:                        NULL));
2397:   AppendMenu(filemenu, MF_SEPARATOR, 0, NULL);
2398:   AppendMenu(filemenu, MF_STRING, MN_FILE_QUIT,
2399:              StrByLang(X_CODING, US_cx L"&esu\tQ", L"cx&esu\tQ",
2400:                        L"&beenden\tQ",
2401:                        L"&quit\tQ",
2402:                        NULL));
2403:   InsertSubmenuString(newmenu, -1, TRUE, filemenu,
2404:                       StrByLang(X_CODING, L"&Dosiero", L"\xffff",
2405:                       L"&Datei",
2406:                       L"&File",
2407:                       NULL));
2408: 
2409:   viewmenu = CreateMenu();
2410:   AppendMenu(viewmenu, MF_STRING, MN_VIEW_FRONT,
2411:              StrByLang(X_CODING, L"anta" US_ux L"a\tJ", L"antauxa\tJ",
2412:                        L"Aufriss\tJ",
2413:                        L"front\tJ",
2414:                        NULL));
2415:   AppendMenu(viewmenu, MF_STRING, MN_VIEW_LEFT,
2416:              StrByLang(X_CODING, L"maldekstra\tK", L"\xffff",
2417:                        L"Seitenriss v. links\tK",
2418:                        L"left\tK",
2419:                        NULL));
2420:   AppendMenu(viewmenu, MF_STRING, MN_VIEW_TOP,
2421:              StrByLang(X_CODING, L"supra\tM", L"\xffff",
2422:                        L"Grundriss\tM",
2423:                        L"top\tM",
2424:                        NULL));
2425:   AppendMenu(viewmenu, MF_STRING, MN_VIEW_RIGHT,
2426:              StrByLang(X_CODING, L"dekstra\tH", L"\xffff",
2427:                        L"Seitenriss v. rechts\tH",
2428:                        L"right\tH",
2429:                        NULL));
2430:   AppendMenu(viewmenu, MF_STRING, MN_VIEW_BACK,
2431:              StrByLang(X_CODING, L"malanta" US_ux L"a\tL", L"malantauxa\tL",
2432:                        L"von hinten\tL",
2433:                        L"back\tL",
2434:                        NULL));
2435:   AppendMenu(viewmenu, MF_STRING, MN_VIEW_BOTTOM,
2436:              StrByLang(X_CODING, L"malsupra\tU", L"\xffff",
2437:                        L"von unten\tU",
2438:                        L"bottom\tU",
2439:                        NULL));
2440:   AppendMenu(viewmenu, MF_STRING, MN_VIEW_ISO,
2441:              StrByLang(X_CODING, L"&IZO (1:1:1)\tI", L"\xffff",
2442:                        L"&Isometrie (1:1:1)\tI",
2443:                        L"&isometric (1/1/1)\tI",
2444:                        NULL));
2445:   AppendMenu(viewmenu, MF_STRING, MN_VIEW_DI,
2446:              StrByLang(X_CODING, L"&DI (2:2:1)\tD", L"\xffff",
2447:                        L"&Dimetrie (2:2:1)\tD",
2448:                        L"&dimetric (2/2/1)\tD",
2449:                        NULL));
2450:   AppendMenu(viewmenu, MF_STRING, MN_VIEW_TRI,
2451:              StrByLang(X_CODING, L"&TRI (6:5:4)\tT", L"\xffff",
2452:                        L"&Trimetire (6:5:4)\tT",
2453:                        L"&trimetric (6/5/4)\tT",
2454:                        NULL));
2455:   AppendMenu(viewmenu, MF_SEPARATOR, 0, NULL);
2456:   AppendMenu(viewmenu, MF_STRING, MN_ZOOM_PLUS,
2457:              StrByLang(X_CODING, L"&pligrani\t+", L"\xffff",
2458:                        L"ver&größern\t+",
2459:                        L"en&large\t+",
2460:                        NULL));
2461:   AppendMenu(viewmenu, MF_STRING, MN_ZOOM_MINUS,
2462:              StrByLang(X_CODING, L"&malgrani\t-", L"\xffff",
2463:                        L"ver&kleinern\t-",
2464:                        L"scale &down\t-",
2465:                        NULL));
2466:   AppendMenu(viewmenu, MF_STRING, MN_ZOOM_FIT,
2467:              StrByLang(X_CODING, L"&akomodi\t#", L"\xffff",
2468:                        L"ein&passen\t#",
2469:                        L"&fit in\t#",
2470:                        NULL));
2471:   AppendMenu(viewmenu, MF_SEPARATOR, 0, NULL);
2472:   AppendMenu(viewmenu, MF_STRING, MN_PART_DISP,
2473:              StrByLang(X_CODING, L"&videblaj objektoj", L"\xffff",
2474:                        L"&Objektdarstellung",
2475:                        L"&object display status",
2476:                        NULL));
2477:   InsertSubmenuString(newmenu, -1, TRUE, viewmenu,
2478:                       StrByLang(X_CODING, L"&Vida" US_jx L"oj", L"&Vidajxoj",
2479:                                 L"&Ansichten",
2480:                                 L"&Viewing",
2481:                                 NULL));
2482: 
2483:   mousemenu = CreateMenu();
2484:   AppendMenu(mousemenu, MF_STRING, MN_MOUSE_L_INV,
2485:              StrByLang(X_CODING, L"inversigi ago de mald&ekstra musa butono (rotacio)", L"\xffff",
2486:                                  L"Rotationsrichtung (&linke Maustaste) umkehren",
2487:                                  L"invert &left mouse button click rotation direction",
2488:                                  NULL));
2489:   AppendMenu(mousemenu, MF_STRING, MN_MOUSE_M_INV,
2490:              StrByLang(X_CODING, L"inversigi ago de &dekstra musa butono (zumo)", L"\xffff",
2491:                                  L"Skalierungsrichtung (&mittlere Maustaste) umkehren",
2492:                                  L"invert &middle mouse button click scaling direction",
2493:                                  NULL));
2494:   AppendMenu(mousemenu, MF_STRING, MN_MOUSE_R_INV,
2495:              StrByLang(X_CODING, L"inversigi ago de &meza musa butono (for" US_sx L"ovo)",
2496:                                  L"inversigi ago de &meza musa butono (forsxovo)",
2497:                                  L"Verschieberichtung (&rechte Maustaste) umkehren",
2498:                                  L"invert &right mouse button click movement direction",
2499:                                  NULL));
2500:   InsertSubmenuString(newmenu, -1, TRUE, mousemenu,
2501:                       StrByLang(X_CODING, L"&Movoj", L"\xffff",
2502:                                 L"&Bewegungen",
2503:                                 L"&Movements",
2504:                                 NULL));
2505: 
2506:   optionsmenu = CreateMenu();
2507:   AppendMenu(optionsmenu, MF_STRING, MN_SET_BACKGRND,
2508:              StrByLang(X_CODING, L"malanta" US_ux L"a &koloro", L"malantauxa &koloro",
2509:                        L"&Hintergrundfarbe",
2510:                        L"&background color",
2511:                        NULL));
2512:   AppendMenu(optionsmenu, MF_STRING, MN_SET_LIGHTY,
2513:              StrByLang(X_CODING, L"&helaj korpoj", L"\xffff",
2514:                        L"helle &Körper",
2515:                        L"light &model colors",
2516:                        NULL));
2517:   AppendMenu(optionsmenu, MF_STRING, MN_SET_SIMPLCOL,
2518:              StrByLang(X_CODING, L"&simplaj coloroj", L"\xffff",
2519:                        L"einfache &Farben",
2520:                        L"&simplified colors",
2521:                        NULL));
2522:   AppendMenu(optionsmenu, MF_STRING, MN_SET_LISTS,
2523:              StrByLang(X_CODING, L"openGL &listoj", L"\xffff",
2524:                        L"openGL-&Listen",
2525:                        L"openGL &lists",
2526:                        NULL));
2527:   AppendMenu(optionsmenu, MF_STRING, MN_SET_WIREFRAME,
2528:              StrByLang(X_CODING, L"drata &montri", L"\xffff",
2529:                        L"&Drahtmodell",
2530:                        L"&wireframe",
2531:                        NULL));
2532:   AppendMenu(optionsmenu, MF_STRING, MN_SET_CULL,
2533:              StrByLang(X_CODING, L"malanta" US_ux L"a edro", L"malantauxa &edro",
2534:                        L"Flächen&rückseiten",
2535:                        L"back &faces",
2536:                        NULL));
2537:   AppendMenu(optionsmenu, MF_STRING, MN_SET_CS,
2538:              StrByLang(X_CODING, L"montri &centron\tC", L"\xffff",
2539:                        L"&Mittelpunkte u.s.w.\tC",
2540:                        L"&center, koordinates\tC",
2541:                        NULL));
2542:   AppendMenu(optionsmenu, MF_STRING, MN_SET_EXTEND,
2543:              StrByLang(X_CODING, L"&dimensio\tX", L"\xffff",
2544:                        L"&Abmessungen\tX",
2545:                        L"over all &dimension\tX",
2546:                        NULL));
2547:   AppendMenu(optionsmenu, MF_STRING, MN_SET_CALLEXIT,
2548:              StrByLang(X_CODING, L"&anstata" US_ux L"aj programoj",
2549:                                  L"&anstatauxaj programoj",
2550:                                  L"andere &Programme",
2551:                                  L"&other applications",
2552:                                  NULL));
2553:   InsertSubmenuString(optionsmenu, -1, TRUE, langmenu,
2554:                       StrByLang(X_CODING, L"lingv&oj", L"\xffff",
2555:                                 L"&Sprachen",
2556:                                 L"languag&es",
2557:                                 NULL));
2558:   InsertSubmenuString(newmenu, -1, TRUE, optionsmenu,
2559:                       StrByLang(X_CODING, L"&Kazoj", L"\xffff",
2560:                                 L"&Einstellungen",
2561:                                 L"&Settings",
2562:                                 NULL));
2563:   AppendMenu(newmenu, MF_STRING, MN_INFO, L"&?");
2564:   /*

2565:    * dosiero         vidajxoj           movoj   kazoj                       ?

2566:    * - aperti        - antauxa     J            - malantauxa koloro

2567:    * - sekurigi      - maldekstra  K            - helaj korpoj

2568:    * ------------    - supra       M            - simplaj coloroj

2569:    * - cxesu    Q    - dekstra     H            - openGL listoj

2570:    *                 - malantauxa  L            - drata montri

2571:    *                 - malsupra    U            - malantauxa edro

2572:    *                 - IZO (1:1:1) I            - montri centron     C

2573:    *                 - DI (2:2:1)  D            - dimensio           X

2574:    *                 - TRI (6:5:4) T            - anstatauxaj programoj

2575:    *                 ---------------            - lingvo -> Esperanto

2576:    *                 - pligrandi   +                        Esperanto X kodo

2577:    *                 - malgrandi   -                        Deutsch

2578:    *                 - akomodi     #                        English

2579:    *                 ---------------

2580:    *                 - 

2581:    *********************************************************************

2582:    * Datei           Ansichten                    Bewegungen   Einstellungen              ?

2583:    * - öffnen        - Aufriss              J                  - Hintergrundfarbe

2584:    * - speichern     - Seitenriss v. links  K                  - helle Körper

2585:    * -----------     - Grundriss            M                  - einfache Farben

2586:    * - Beenden  Q    - Seitenriss v. rechts H                  - openGL-Listen

2587:    *                 - von hinten           L                  - Drahtmodell

2588:    *                 - von unten            U                  - Flächenrückseiten

2589:    *                 - Isometrie (1:1:1)    I                  - Mittelpunkte u.s.w.  C

2590:    *                 - Dimetrie (2:2:1)     D                  - Abmessungen          X

2591:    *                 - Trimetrie (6:5:4)    T                  - andere Programme

2592:    *                 ------------------------                  - Sprachen -> Esperanto

2593:    *                 - vergrößern           +                                Esperanto X kodo

2594:    *                 - verkleinern          -                                Deutsch

2595:    *                 - einpassen            #                                English

2596:    *                 ------------------------

2597:    *                 - Objektdarstellung

2598:    *******************************************************************************

2599:    * File            Viewing                      Movements   Settings

2600:    * - open          - front                J                 - background color

2601:    * - save          - left                 K                 - light model colors

2602:    * ----------      - top                  M                 - simplified colors

2603:    * - quit   Q      - right                H                 - openGL lists

2604:    *                 - back                 L                 - wireframe

2605:    *                 - bottom               U                 - back faces

2606:    *                 - isometric (1/1/1)    I                 - center, koordinates  C

2607:    *                 - dimetric (2/2/1)     D                 - over all dimension   X

2608:    *                 - trimetric (6/5/4)    T                 - other applications

2609:    *                 ------------------------                 - languages -> Esperanto

2610:    *                 - enlarge              +                                Esperanto X kodo

2611:    *                 - scale down           -                                Deutsch

2612:    *                 - fit in               #                                English

2613:    *                 ------------------------

2614:    *                 - object display status

2615:    */
2616:   oldmenu = GetMenu(hwnd);
2617:   SetMenu(hwnd, newmenu);
2618:   DestroyMenu(oldmenu);
2619:   DrawMenuBar(hwnd);
2620:   CheckMenuItem(optionsmenu, MN_SET_CS, MF_BYCOMMAND | (Disp_CS ? MF_CHECKED : MF_UNCHECKED));
2621:   CheckMenuItem(optionsmenu, MN_SET_EXTEND, MF_BYCOMMAND | (Disp_Extend ? MF_CHECKED : MF_UNCHECKED));
2622:   CheckMenuItem(langmenu, MN_SET_LANG_EO,  MF_BYCOMMAND | (X_CODING == 0) ? MF_CHECKED : MF_UNCHECKED);
2623:   CheckMenuItem(langmenu, MN_SET_LANG_EOX, MF_BYCOMMAND | (X_CODING == 1) ? MF_CHECKED : MF_UNCHECKED);
2624:   CheckMenuItem(langmenu, MN_SET_LANG_GER, MF_BYCOMMAND | (X_CODING == 2) ? MF_CHECKED : MF_UNCHECKED);
2625:   CheckMenuItem(langmenu, MN_SET_LANG_ENG, MF_BYCOMMAND | (X_CODING == 3) ? MF_CHECKED : MF_UNCHECKED);
2626:   CheckMenuItem(optionsmenu, MN_SET_WIREFRAME, MF_BYCOMMAND | (Wireframe ? MF_CHECKED : MF_UNCHECKED));
2627:   CheckMenuItem(optionsmenu, MN_SET_LISTS, MF_BYCOMMAND | (UseLists ? MF_CHECKED : MF_UNCHECKED));
2628:   CheckMenuItem(optionsmenu, MN_SET_LIGHTY, MF_BYCOMMAND | (lighty_models ? MF_CHECKED : MF_UNCHECKED));
2629:   CheckMenuItem(optionsmenu, MN_SET_SIMPLCOL, MF_BYCOMMAND | (simple_color ? MF_CHECKED : MF_UNCHECKED));
2630:   CheckMenuItem(optionsmenu, MN_SET_CULL, MF_BYCOMMAND | ((!CullFace) ? MF_CHECKED : MF_UNCHECKED));
2631:   CheckMenuItem(mousemenu, MN_MOUSE_L_INV, MF_BYCOMMAND | ((mouse_inversion & 1) ? MF_CHECKED : MF_UNCHECKED));
2632:   CheckMenuItem(mousemenu, MN_MOUSE_M_INV, MF_BYCOMMAND | ((mouse_inversion & 2) ? MF_CHECKED : MF_UNCHECKED));
2633:   CheckMenuItem(mousemenu, MN_MOUSE_R_INV, MF_BYCOMMAND | ((mouse_inversion & 4) ? MF_CHECKED : MF_UNCHECKED));
2634:   EnableMenuItem(filemenu, MN_FILE_SAVE, MF_BYCOMMAND | (VALID_MODELS ? MF_ENABLED : MF_GRAYED));
2635:   EnableMenuItem(viewmenu, MN_PART_DISP, MF_BYCOMMAND | ((VALID_MODELS > 1) ? MF_ENABLED : MF_GRAYED));
2636:   if (hwndObjectDisplayDialog != NULL) SendMessage(hwndObjectDisplayDialog, WM_COMMAND, RT_SET_LANG, 0L);
2637: }
2638: 
2639: BOOL ChooseBackgroundColor(HWND hwnd)
2640: { BOOL erg;
2641:   CHOOSECOLOR farbe;
2642:   /* int ct; */
2643:   farbe.lStructSize = sizeof(CHOOSECOLOR);
2644:   farbe.hwndOwner = hwnd;
2645:   farbe.hInstance = NULL;
2646:   farbe.rgbResult = RGB(((int) floor(255.0 * bg_r + 0.5)),
2647:                         ((int) floor(255.0 * bg_g + 0.5)),
2648:                         ((int) floor(255.0 * bg_b + 0.5)));
2649:   farbe.lpCustColors = Farbfeld;
2650:   farbe.Flags = CC_RGBINIT /* | CC_PREVENTFULLOPEN */;
2651:   farbe.lCustData = 0;
2652:   farbe.lpfnHook = NULL;
2653:   farbe.lpTemplateName = NULL; // X_CODING ? L"malantauxa koloro" : L"malanta" US_ux L"a koloro";

2654:   if ((erg = ChooseColor(&farbe)) != 0) {
2655:     bg_r = (SBG_R = GetRValue(farbe.rgbResult)) / 255.0F;
2656:     bg_g = (SBG_G = GetGValue(farbe.rgbResult)) / 255.0F;
2657:     bg_b = (SBG_B = GetBValue(farbe.rgbResult)) / 255.0F;
2658:   }
2659:   return erg;
2660: }
2661: 
2662: int SaveVtf(wchar_t *FileName)
2663: { FILE *ausgabe;
2664:   union Unu *dta;
2665:   wchar_t Meldung[MAX_PATH + 40];
2666:   unsigned long typ, sz;
2667:   struct HEAD head;
2668:   if (TDate == NULL) return -1;
2669:   if ((ausgabe = _wfopen(FileName, L"wb")) == NULL) {
2670:     wsprintf(Meldung,
2671:              StrByLang(X_CODING, L"Ne konas skribi dosieron '%s'!", L"\xffff",
2672:                                  L"Kann nicht in Datei '%s' schreiben!",
2673:                                  L"Cannot write file '%s'!",
2674:                                  NULL),
2675:              FileName);
2676:     MessageBox(hwndApplication, Meldung,
2677:                StrByLang(X_CODING, L"eraro - sekurigi dosieron", L"\xffff",
2678:                                    L"Fehler beim Abspeichern",
2679:                                    L"Error while saving",
2680:                                    NULL),
2681:                MB_OK | MB_ICONINFORMATION);
2682:     return -2;
2683:   }
2684:   strcpy(head.t, VTF_ASCII_HEAD);
2685:   head.us = 1;
2686:   head.ul = 987654321L;
2687:   head.f = 7654321.0F;
2688:   head.d = 9876543210123456.0;
2689:   fwrite(&head, 1, sizeof(struct HEAD), ausgabe);
2690:   for (dta = (union Unu *) &(TDate->Data[0]);
2691:        ((dta->dauxrigo.size_n_flags >> 28) & 0x0fL) != 0x0fL;
2692:        ) {
2693:     sz = dta->dauxrigo.size_n_flags & 0x0fffffffL;
2694:     typ = (dta->dauxrigo.size_n_flags >> 28) & 0x0fL;
2695:     switch (typ) {
2696:       case 12: /* Jump to next memory segment */
2697:         dta = (union Unu *) dta->dauxrigo.There;
2698:       break;
2699:       default:
2700:         fwrite(dta, 8, sz, ausgabe);
2701:         dta = (union Unu *) &(dta->Data[sz]);
2702:       break;
2703:     }
2704:   }
2705:   fclose(ausgabe);
2706:   return 0;
2707: }
2708: 
2709: BOOL SelectAndSaveFile(HWND hwnd)
2710: { BOOL erg;
2711:   OPENFILENAME ofn;
2712:   wchar_t FileName[MAX_PATH], BaseName[MAX_PATH];
2713:   FileName[0] = BaseName[0] = 0;
2714:   ofn.lStructSize = sizeof(OPENFILENAME);
2715:   ofn.hwndOwner = hwnd;
2716:   ofn.hInstance = NULL;
2717:   ofn.lpstrFilter = StrByLang(X_CODING,
2718:                               L"duuma rigardiga dosieroj (*.vtf)\0*.vtf\0" US_cx L"iuj dosieroj (*.*)\0*.*\0",
2719:                               L"duuma rigardiga dosieroj (*.vtf)\0*.vtf\0cxiuj dosieroj (*.*)\0*.*\0",
2720:                               L"binäre Triangulationsdatei (*.vtf)\0*.vtf\0alle Dateien (*.*)\0*.*\0",
2721:                               L"binary viewable triangulation file (*.vtf)\0*.vtf\0all files (*.*)\0*.*\0",
2722:                               NULL);
2723:   ofn.lpstrCustomFilter = NULL;
2724:   ofn.nMaxCustFilter = 0;
2725:   ofn.nFilterIndex = 1;
2726:   ofn.lpstrFile = FileName;
2727:   ofn.nMaxFile = MAX_PATH;
2728:   ofn.lpstrFileTitle = BaseName;
2729:   ofn.nMaxFileTitle = MAX_PATH;
2730:   ofn.lpstrInitialDir = NULL;
2731:   ofn.lpstrTitle = StrByLang(X_CODING, L"sekurigi triangularan dosieron", L"\xffff",
2732:                                        L"Triangulatinsdatei abspeichern",
2733:                                        L"save the triangulation file",
2734:                                        NULL);
2735:   ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | /* OFN_PATHMUSTEXIST | */ OFN_OVERWRITEPROMPT;
2736:   ofn.nFileOffset = 0;
2737:   ofn.nFileExtension = 0;
2738:   ofn.lpstrDefExt = L"slp";
2739:   ofn.lCustData = 0;
2740:   ofn.lpfnHook = NULL;
2741:   ofn.lpTemplateName = NULL;
2742:   if ((erg = GetSaveFileName(&ofn)) != 0) {
2743:     /*

2744:     wchar_t Meldung[700];

2745:     wsprintf(Meldung, L"FileName = '%s'\nBaseName = '%s'\nExt. = '%s'",

2746:       FileName, BaseName, &(FileName[ofn.nFileExtension]));

2747:     MessageBox(NULL, Meldung, L"SelectAndSaveFile()", MB_OK | MB_ICONINFORMATION);

2748:     */
2749:     SaveVtf(FileName);
2750:   }
2751:   return erg;
2752: }
2753: 
2754: BOOL SelectAndOpenFile(HWND hwnd)
2755: { BOOL erg;
2756:   OPENFILENAME ofn;
2757:   wchar_t FileName[MAX_PATH], BaseName[MAX_PATH];
2758:   FileName[0] = BaseName[0] = 0;
2759:   ofn.lStructSize = sizeof(OPENFILENAME);
2760:   ofn.hwndOwner = hwnd;
2761:   ofn.hInstance = NULL;
2762:   ofn.lpstrFilter = StrByLang(X_CODING,
2763:                     /*   0 */ L"triangularaj dosieroj (*.slp;*.stl;*.vtf)\0*.slp;*.stl;*.vtf\0"
2764:                               L"rigardiga dosieroj (*.slp)\0*.slp\0"
2765:                               L"litografiaj dosieroj (*.stl)\0*.stl\0"
2766:                               L"duuma rigardiga dosieroj (*.vtf)\0*.vtf\0"
2767:                               US_cx L"iuj dosieroj (*.*)\0*.*\0",
2768:                     /*   1 */ L"triangularaj dosieroj (*.slp;*.stl;*.vtf)\0*.slp;*.stl;*.vtf\0"
2769:                               L"rigardiga dosieroj (*.slp)\0*.slp\0"
2770:                               L"litografiaj dosieroj (*.stl)\0*.stl\0"
2771:                               L"duuma rigardiga dosieroj (*.vtf)\0*.vtf\0"
2772:                               L"cxiuj dosieroj (*.*)\0*.*\0",
2773:                     /*   2 */ L"Triangulationsdateien (*.slp;*.stl;*.vtf)\0*.slp;*.stl;*.vtf\0"
2774:                               L"Rendering-Datei (*.slp)\0*.slp\0"
2775:                               L"Stereolithographidatei (*.stl)\0*.stl\0"
2776:                               L"binäre Triangulationsdatei (*.vtf)\0*.vtf\0"
2777:                               L"alle Dateien (*.*)\0*.*\0",
2778:                     /*   3 */ L"triangulation files (*.slp;*.stl;*.vtf)\0*.slp;*.stl;*.vtf\0"
2779:                               L"render file (*.slp)\0*.slp\0"
2780:                               L"stereolithographic file (*.stl)\0*.stl\0"
2781:                               L"binary viewable triangulation file (*.vtf)\0*.vtf\0"
2782:                               L"all files (*.*)\0*.*\0",
2783:                     /* EOL */ NULL);
2784:   ofn.lpstrCustomFilter = NULL;
2785:   ofn.nMaxCustFilter = 0;
2786:   ofn.nFilterIndex = 1;
2787:   ofn.lpstrFile = FileName;
2788:   ofn.nMaxFile = MAX_PATH;
2789:   ofn.lpstrFileTitle = BaseName;
2790:   ofn.nMaxFileTitle = MAX_PATH;
2791:   ofn.lpstrInitialDir = NULL;
2792:   ofn.lpstrTitle = StrByLang(X_CODING, L"aperti triangularan dosieron", L"\xffff",
2793:                                        L"Triangulationsdatei öffnen",
2794:                                        L"open a triangulation file",
2795:                                        NULL);
2796:   ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
2797:   ofn.nFileOffset = 0;
2798:   ofn.nFileExtension = 0;
2799:   ofn.lpstrDefExt = L"slp";
2800:   ofn.lCustData = 0;
2801:   ofn.lpfnHook = NULL;
2802:   ofn.lpTemplateName = NULL;
2803:   if ((erg = GetOpenFileName(&ofn)) != 0) {
2804:     /*

2805:     wchar_t Meldung[700];

2806:     wsprintf(Meldung, L"FileName = '%s'\nBaseName = '%s'\nExt. = '%s'",

2807:       FileName, BaseName, &(FileName[ofn.nFileExtension]));

2808:     MessageBox(NULL, Meldung, L"SelectAndOpenFile()", MB_OK | MB_ICONINFORMATION);

2809:     */
2810:     ReadFileIn(FileName, BaseName, ofn.nFileExtension, -1);
2811:   }
2812:   return erg;
2813: }
2814: 
2815: CmdLineReadFile(wchar_t *FileName, int append)
2816: { int ct;
2817:   int bn, ex;
2818:   bn = ex = 0;
2819:   for (ct = wcslen(FileName); ct >= 0; ct--) {
2820:     if (!ex && (FileName[ct] == L'.')) ex = ct;
2821:     if (!bn && (ct > 0)
2822:         && ((FileName[ct - 1] == L'\\')
2823:          || (FileName[ct - 1] == L'/')
2824:          || (FileName[ct - 1] == L':'))) bn = ct;
2825:   }
2826:   ReadFileIn(FileName, &(FileName[bn]), ex, append);
2827:   if (!append) {
2828:     CmdLineFirstFileBasenameStart = bn;
2829:     CmdLineFirstFileExtensionStart = ex;
2830:   }
2831: }
2832: 
2833: int ES_Dialog_DatasetValid(struct ES_DIALOG_DATA *DD, int tc)
2834: { if (!DD->VtfSlpStl[tc].enabled) return 1;
2835:   if (!DD->VtfSlpStl[tc].Program[0]) return 0;
2836:   if (!DD->VtfSlpStl[tc].ProgramBasename[0]) return 0;
2837:   if (!DD->VtfSlpStl[tc].with_optional_param) return 1;
2838:   if (!DD->VtfSlpStl[tc].OptionalParam[0]) return 0;
2839:   return 1;
2840: }
2841: 
2842: BOOL ES_Dialog_ExecFileSelection(HWND hwnd, struct ES_DIALOG_DATA *DD, int tc)
2843: { BOOL erg;
2844:   OPENFILENAME ofn;
2845:   wchar_t FileName[MAX_PATH], BaseName[MAX_PATH];
2846:   FileName[0] = BaseName[0] = 0;
2847:   ofn.lStructSize = sizeof(OPENFILENAME);
2848:   ofn.hwndOwner = hwnd;
2849:   ofn.hInstance = NULL;
2850:   ofn.lpstrFilter = L"*.exe\0*.exe\0"
2851:                     L"*.bat\0*.bat\0"
2852:                     L"*.cmd\0*.cmd\0"
2853:                     L"*.exe + *.bat + *.cmd\0*.exe;*.bat;*.cmd\0"
2854:                     L"*.*\0*.*\0";
2855:   ofn.lpstrCustomFilter = NULL;
2856:   ofn.nMaxCustFilter = 0;
2857:   ofn.nFilterIndex = 1;
2858:   ofn.lpstrFile = FileName;
2859:   ofn.nMaxFile = MAX_PATH;
2860:   ofn.lpstrFileTitle = BaseName;
2861:   ofn.nMaxFileTitle = MAX_PATH;
2862:   ofn.lpstrInitialDir = NULL;
2863:   ofn.lpstrTitle = StrByLang(tc,
2864:                              StrByLang(X_CODING,
2865:                                        L"anstata" US_ux L"a programo por aperti 'VTF' dosieron",
2866:                                        L"anstatauxa programo por aperti 'VTF' dosieron",
2867:                                        L"Alternatives Programm, welches 'andere' VTF-Dateien öffnet",
2868:                                        L"program to open 'other' VTF files",
2869:                                        NULL),
2870:                              StrByLang(X_CODING,
2871:                                        L"anstata" US_ux L"a programo por aperti 'SLP' dosieron",
2872:                                        L"anstatauxa programo por aperti 'SLP' dosieron",
2873:                                        L"Alternatives Programm, welches 'andere' SLP-Dateien öffnet",
2874:                                        L"program to open 'other' SLP files",
2875:                                        NULL),
2876:                              StrByLang(X_CODING,
2877:                                        L"anstata" US_ux L"a programo por aperti 'STL' dosieron",
2878:                                        L"anstatauxa programo por aperti 'STL' dosieron",
2879:                                        L"Alternatives Programm, welches 'andere' STL-Dateien öffnet",
2880:                                        L"program to open 'other' STL-files",
2881:                                        NULL),
2882:                              NULL);
2883:   ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
2884:   ofn.nFileOffset = 0;
2885:   ofn.nFileExtension = 0;
2886:   ofn.lpstrDefExt = L"exe";
2887:   ofn.lCustData = 0;
2888:   ofn.lpfnHook = NULL;
2889:   ofn.lpTemplateName = NULL;
2890:   if ((erg = GetOpenFileName(&ofn)) != 0) {
2891:     wcscpy(DD->VtfSlpStl[tc].Program, FileName);
2892:     wcscpy(DD->VtfSlpStl[tc].ProgramBasename, BaseName);
2893:   }
2894:   return erg;
2895: }
2896: 
2897: BOOL CALLBACK ES_DialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
2898: { int ct, grp;
2899:   static struct ES_DIALOG_DATA *DD = NULL;
2900:   switch (msg) {
2901:     case WM_INITDIALOG:
2902:       DD = (struct ES_DIALOG_DATA *) lParam;
2903:       CheckDlgButton(hwnd, 40, DD->prompt_launching ? BST_CHECKED : BST_UNCHECKED);
2904:       CheckDlgButton(hwnd, 11, DD->VtfSlpStl[0].enabled ? BST_CHECKED : BST_UNCHECKED);
2905:       CheckDlgButton(hwnd, 21, DD->VtfSlpStl[1].enabled ? BST_CHECKED : BST_UNCHECKED);
2906:       CheckDlgButton(hwnd, 31, DD->VtfSlpStl[2].enabled ? BST_CHECKED : BST_UNCHECKED);
2907:       CheckDlgButton(hwnd, 14, DD->VtfSlpStl[0].with_optional_param ? BST_CHECKED : BST_UNCHECKED);
2908:       CheckDlgButton(hwnd, 24, DD->VtfSlpStl[1].with_optional_param ? BST_CHECKED : BST_UNCHECKED);
2909:       CheckDlgButton(hwnd, 34, DD->VtfSlpStl[2].with_optional_param ? BST_CHECKED : BST_UNCHECKED);
2910:       if (IsDlgButtonChecked(hwnd, 11) == BST_CHECKED) {
2911:         for (ct = 12; ct <= 14; ct++) EnableWindow(GetDlgItem(hwnd, ct), TRUE);
2912:         EnableWindow(GetDlgItem(hwnd, 15), (IsDlgButtonChecked(hwnd, 14) == BST_CHECKED) ? TRUE : FALSE);
2913:       } else {
2914:         for (ct = 12; ct <= 15; ct++) EnableWindow(GetDlgItem(hwnd, ct), FALSE);
2915:       }
2916:       ShowWindow(GetDlgItem(hwnd, 16), SW_HIDE); /* Saved values should be ok, do not SW_SHOW error marker */
2917:       if (IsDlgButtonChecked(hwnd, 21) == BST_CHECKED) {
2918:         for (ct = 22; ct <= 23; ct++) EnableWindow(GetDlgItem(hwnd, ct), TRUE);
2919:         EnableWindow(GetDlgItem(hwnd, 25), (IsDlgButtonChecked(hwnd, 24) == BST_CHECKED) ? TRUE : FALSE);
2920:       } else {
2921:         for (ct = 22; ct <= 25; ct++) EnableWindow(GetDlgItem(hwnd, ct), FALSE);
2922:       }
2923:       ShowWindow(GetDlgItem(hwnd, 26), SW_HIDE);
2924:       if (IsDlgButtonChecked(hwnd, 31) == BST_CHECKED) {
2925:         for (ct = 32; ct <= 33; ct++) EnableWindow(GetDlgItem(hwnd, ct), TRUE);
2926:         EnableWindow(GetDlgItem(hwnd, 35), (IsDlgButtonChecked(hwnd, 34) == BST_CHECKED) ? TRUE : FALSE);
2927:       } else {
2928:         for (ct = 32; ct <= 35; ct++) EnableWindow(GetDlgItem(hwnd, ct), FALSE);
2929:       }
2930:       ShowWindow(GetDlgItem(hwnd, 36), SW_HIDE);
2931:       return TRUE;
2932:     case WM_COMMAND:
2933:       grp = (LOWORD(wParam) / 10) - 1;
2934:       // { wchar_t M[100]; wsprintf(M, L"grp = %d\nDD = %lx", grp, DD); MessageBox(NULL, M, L"Gruppenkode:", MB_OK | MB_ICONINFORMATION); }

2935:       switch (LOWORD(wParam)) {
2936:         case 11: case 21: case 31:
2937:           if (DD == NULL) return FALSE;
2938:           DD->VtfSlpStl[grp].enabled = !DD->VtfSlpStl[grp].enabled;
2939:           CheckDlgButton(hwnd, 11 + 10 * grp, DD->VtfSlpStl[grp].enabled ? BST_CHECKED : BST_UNCHECKED);
2940:           if (DD->VtfSlpStl[grp].enabled) {
2941:             for (ct = 12; ct <= 14; ct++) EnableWindow(GetDlgItem(hwnd, ct + 10 * grp), TRUE);
2942:             EnableWindow(GetDlgItem(hwnd, 15 + 10 * grp), DD->VtfSlpStl[grp].with_optional_param ? TRUE : FALSE);
2943:             ShowWindow(GetDlgItem(hwnd, 16 + 10 * grp), ES_Dialog_DatasetValid(DD, grp) ? SW_HIDE : SW_SHOW);
2944:           } else {
2945:             for (ct = 12; ct <= 15; ct++) EnableWindow(GetDlgItem(hwnd, ct + 10 * grp), FALSE);
2946:             ShowWindow(GetDlgItem(hwnd, 16 + 10 * grp), SW_HIDE);
2947:           }
2948:           EnableWindow(GetDlgItem(hwnd, 99),
2949:                        (ES_Dialog_DatasetValid(DD, 0) && ES_Dialog_DatasetValid(DD, 1) && ES_Dialog_DatasetValid(DD, 2))
2950:                        ? TRUE : FALSE);
2951:           return TRUE;
2952:         case 12: case 22: case 32:
2953:           if (DD == NULL) return FALSE;
2954:           if (ES_Dialog_ExecFileSelection(hwnd, DD, grp)) {
2955:             SetDlgItemText(hwnd, 13 + 10 * grp, DD->VtfSlpStl[grp].Program);
2956:             ShowWindow(GetDlgItem(hwnd, 16 + 10 * grp), ES_Dialog_DatasetValid(DD, grp) ? SW_HIDE : SW_SHOW);
2957:             EnableWindow(GetDlgItem(hwnd, 99),
2958:                          (ES_Dialog_DatasetValid(DD, 0) && ES_Dialog_DatasetValid(DD, 1) && ES_Dialog_DatasetValid(DD, 2))
2959:                            ? TRUE : FALSE);
2960:           }
2961:           return TRUE;
2962:         case 14: case 24: case 34:
2963:           if (DD == NULL) return FALSE;
2964:           DD->VtfSlpStl[grp].with_optional_param = !(DD->VtfSlpStl[grp].with_optional_param);
2965:           CheckDlgButton(hwnd, 14 + 10 * grp, DD->VtfSlpStl[grp].with_optional_param ? BST_CHECKED : BST_UNCHECKED);
2966:           EnableWindow(GetDlgItem(hwnd, 15 + 10 * grp), DD->VtfSlpStl[grp].with_optional_param ? TRUE : FALSE);
2967:           ShowWindow(GetDlgItem(hwnd, 16 + 10 * grp), ES_Dialog_DatasetValid(DD, grp) ? SW_HIDE : SW_SHOW);
2968:           EnableWindow(GetDlgItem(hwnd, 99),
2969:                        (ES_Dialog_DatasetValid(DD, 0) && ES_Dialog_DatasetValid(DD, 1) && ES_Dialog_DatasetValid(DD, 2))
2970:                        ? TRUE : FALSE);
2971:           return TRUE;
2972:         case 15: case 25: case 35:
2973:           if (DD == NULL) return FALSE;
2974:           switch (HIWORD(wParam)) {
2975:             case EN_CHANGE: case EN_KILLFOCUS:
2976:               GetWindowText((HWND) lParam, DD->VtfSlpStl[grp].OptionalParam, MAX_PATH);
2977:               DD->VtfSlpStl[grp].OptionalParam[MAX_PATH - 1] = 0;
2978:       // { wchar_t M[100]; wsprintf(M, L"grp = %d\nDD = %lx", grp, DD); MessageBox(NULL, M, L"Gruppenkode Direkt:", MB_OK | MB_ICONINFORMATION); wsprintf(M, L"OptionalParam = \"%s\"", DD->VtfSlpStl[grp].OptionalParam); MessageBox(NULL, M, L"OptionalParam:", MB_OK | MB_ICONINFORMATION); }

2979:               ShowWindow(GetDlgItem(hwnd, 16 + 10 * grp), ES_Dialog_DatasetValid(DD, grp) ? SW_HIDE : SW_SHOW);
2980:               EnableWindow(GetDlgItem(hwnd, 99),
2981:                            (ES_Dialog_DatasetValid(DD, 0) && ES_Dialog_DatasetValid(DD, 1) && ES_Dialog_DatasetValid(DD, 2))
2982:                            ? TRUE : FALSE);
2983:             return TRUE;
2984:           }
2985:           break;
2986:         case 40:
2987:           if (DD == NULL) return FALSE;
2988:           DD->prompt_launching = !DD->prompt_launching;
2989:           CheckDlgButton(hwnd, 40, DD->prompt_launching ? BST_CHECKED : BST_UNCHECKED);
2990:           return TRUE;
2991:         case 98:
2992:           DD = NULL;
2993:           EndDialog(hwnd, 0);
2994:           return TRUE;
2995:         case 99:
2996:           DD = NULL;
2997:           EndDialog(hwnd, 1);
2998:           return TRUE;
2999:       }
3000:     break;
3001:   }
3002:   return FALSE;
3003: }
3004: 
3005: #ifdef DLG_DEBUG
3006: 
3007: void DlgDataList(DynDlgTemplate *ddt)
3008: { int ct, p, lg; unsigned short *Daten;
3009: #define INFO_LG 5000
3010:   wchar_t Info[INFO_LG];
3011:   if (ddt == NULL) return;
3012:   lg = ddt->bytes_filled / 2;
3013:   Daten = (void *) ddt->dlg;
3014:   wsprintf(Info, L"%d Words:\n", lg);
3015:   p = wcslen(Info);
3016:   for (ct = 0; ct < lg; ct++) {
3017:     if (p + 15 < INFO_LG) {
3018:       if (((Daten[ct] >= 0x20) && (Daten[ct] < 0x007f))
3019:        || ((Daten[ct] >= 0xa1) && (Daten[ct] <= 0x017f)))
3020:          wsprintf(&(Info[p]), L"0x%.4x '%c' ", Daten[ct], Daten[ct]);
3021:         else
3022:          wsprintf(&(Info[p]), L"0x%.4x     ", Daten[ct]);
3023:       if ((ct % 10) == 9) wcscat(Info, L"\n");
3024:       p = wcslen(Info);
3025:     }
3026:   }
3027:   MessageBox(NULL, Info, L"Dialog Template Data", MB_OK | MB_ICONINFORMATION);
3028: }
3029: #endif

3030: 
3031: #define DlgW    175
3032: #define BtnG      5
3033: #define BtnH     18
3034: #define WarnW    55
3035: #define WarnH     8
3036: #define WarnG     2
3037: #define SelBtnW  30
3038: #define SelBtnH  12
3039: #define ParaCbW  80
3040: #define ParaCbH  SelBtnH
3041: #define TxtW     (DlgW - 5 * BtnG - SelBtnW)
3042: #define ParaTxtW (DlgW - 5 * BtnG - ParaCbW)
3043: #define ErgBtnW  ((DlgW - 3 * BtnG) / 2)
3044: #define BoxH     (WarnH + SelBtnH + ParaCbH + 2 * BtnG + 2 * WarnG)
3045: #define DlgH     (3 * BoxH + BtnH + SelBtnH + 7 * BtnG)
3046: void CallExitSettings(HWND hwnd)
3047: { struct ES_DIALOG_DATA ES_Dialog_Data;
3048:   DynDlgTemplate ES_Dialog = DynDlgTemplateNULL;
3049:   int erg, cxChar, cyChar;
3050:   RECT FatherWindowExt;
3051:   /* get old values */
3052:   memcpy( &ES_Dialog_Data, &ES_Settings, sizeof(struct ES_DIALOG_DATA));
3053:   /*

3054:   ES_Dialog_Data.prompt_launching = 1;

3055:   ES_Dialog_Data.VtfSlpStl[0].enabled = 1;

3056:   ES_Dialog_Data.VtfSlpStl[0].with_optional_param = 0;

3057:   wcscpy(ES_Dialog_Data.VtfSlpStl[0].Program, L"E:\\a\\b\\c\\d\\e\\f\\g\\h\\i\\j\\k\\l\\m\\n\\o\\p\\q\\r\\s\\t\\u\\v\\w\\x\\y\\z.exe");

3058:   wcscpy(ES_Dialog_Data.VtfSlpStl[0].ProgramBasename, L"z.exe");

3059:   ES_Dialog_Data.VtfSlpStl[1].enabled = 1;

3060:   wcscpy(ES_Dialog_Data.VtfSlpStl[0].OptionalParam, L"-abcdefghijklmnopqrstuvwxyz0123456789");

3061:   wcscpy(ES_Dialog_Data.VtfSlpStl[1].Program, L"E:\\a\\b\\c\\d\\e\\f\\g\\h\\i\\j\\k\\l\\m\\n\\o\\p\\q\\r\\s\\t\\u\\v\\w\\x\\y\\z.exe");

3062:   wcscpy(ES_Dialog_Data.VtfSlpStl[1].ProgramBasename, L"z.exe");

3063:   ES_Dialog_Data.VtfSlpStl[1].with_optional_param = 1;

3064:   wcscpy(ES_Dialog_Data.VtfSlpStl[1].OptionalParam, L"-abcdefghijklmnopqrstuvwxyz0123456789");

3065:   ES_Dialog_Data.VtfSlpStl[2].enabled = 0;

3066:   wcscpy(ES_Dialog_Data.VtfSlpStl[2].Program, L"E:\\a\\b\\c\\d\\e\\f\\g\\h\\i\\j\\k\\l\\m\\n\\o\\p\\q\\r\\s\\t\\u\\v\\w\\x\\y\\z.exe");

3067:   wcscpy(ES_Dialog_Data.VtfSlpStl[2].ProgramBasename, L"z.exe");

3068:   ES_Dialog_Data.VtfSlpStl[2].with_optional_param = 1;

3069:   wcscpy(ES_Dialog_Data.VtfSlpStl[2].OptionalParam, L"-abcdefghijklmnopqrstuvwxyz0123456789");

3070:   */
3071:   /* build dialog mask */
3072:   GetClientRect(hwnd, &FatherWindowExt);
3073:   cxChar = LOWORD(GetDialogBaseUnits());
3074:   cyChar = HIWORD(GetDialogBaseUnits());
3075:   if (DynDlgSetHead(&ES_Dialog, WS_VISIBLE | DS_MODALFRAME | WS_POPUP | WS_CAPTION, 0,
3076:                     (FatherWindowExt.right  * 4 > DlgW * cxChar) ? (FatherWindowExt.right  * 4 / cxChar - DlgW) / 2 : 0,
3077:                     (FatherWindowExt.bottom * 8 > DlgH * cyChar) ? (FatherWindowExt.bottom * 8 / cyChar - DlgH) / 2 : 0,
3078:                     DlgW, DlgH,
3079:                     NULL, -1,
3080:                     NULL, -1,
3081:                     StrByLang(X_CODING,
3082:                               L"rtd - anstata" US_ux L"aj programoj por aperti deviaj dosieroj",
3083:                               L"rtd - anstatauxaj programoj por aperti deviaj dosieroj",
3084:                               L"rtd - alternative Programme, um nicht-RTD-Dateien zu öffnen",
3085:                               L"rtd - other applications to open non-RTD files",
3086:                               NULL),
3087:                     NULL, 0, 0, 0)) return;
3088:   // MessageBox(NULL, L"Step 1", L"Dialog Build", MB_OK | MB_ICONINFORMATION);

3089:   // DlgDataList(&ES_Dialog);

3090:   if (DynDlgAddItem(&ES_Dialog, WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP, 0,
3091:                    BtnG,                      DlgH - BtnG - BtnH,
3092:                    ErgBtnW,                   BtnH,                99,
3093:                    NULL, DlgButton,
3094:                    StrByLang(X_CODING, L"en ordo", L"\xffff",
3095:                                        L"OK", L"OK", NULL), 0,
3096:                    0, NULL, 0)) return;
3097:   // MessageBox(NULL, L"Step 2", L"Dialog Build", MB_OK | MB_ICONINFORMATION);

3098:   // DlgDataList(&ES_Dialog);

3099:   if (DynDlgAddItem(&ES_Dialog, WS_CHILD | WS_VISIBLE, 0,
3100:                    DlgW - BtnG - ErgBtnW,     DlgH - BtnG - BtnH,
3101:                    ErgBtnW,                   BtnH,                98,
3102:                    L"button", 0,
3103:                    StrByLang(X_CODING, L"nuligi", L"\xffff",
3104:                                        L"Abbruch", L"Abort", NULL), 0,
3105:                    0, NULL, 0)) return;
3106:   for (erg = 0; erg < 3; erg++) {
3107:     if (DynDlgAddItem(&ES_Dialog, WS_CHILD | WS_VISIBLE | SS_BLACKFRAME, 0,
3108:                      BtnG, BtnG + erg * (BtnG + BoxH),
3109:                      DlgW - 2 * BtnG, BoxH, 10 + 10 * erg,
3110:                      L"static", 0,
3111:                      L"", 0,
3112:                      0, NULL, 0)) return;
3113:     if (DynDlgAddItem(&ES_Dialog, WS_CHILD | WS_VISIBLE | BS_CHECKBOX | WS_GROUP | WS_TABSTOP, 0,
3114:                      BtnG + WarnG, BtnG + WarnG + erg * (BtnG + BoxH),
3115:                      DlgW - 4 * BtnG - WarnG - WarnW, WarnH, 11 + 10 * erg,
3116:                      L"button", 0,
3117:                      StrByLang(erg,
3118:                         StrByLang(X_CODING, L"por \"&VTF\"aj dosieroj", L"\xffff",
3119:                                               L"für &VTF-Dateien",
3120:                                             L"for &VTF files", NULL),
3121:                         StrByLang(X_CODING, L"por \"&SLP\"aj dosieroj", L"\xffff",
3122:                                               L"für &SLP-Dateien",
3123:                                             L"for &SLP files", NULL),
3124:                         StrByLang(X_CODING, L"por \"S&TL\"aj dosieroj", L"\xffff",
3125:                                               L"für S&TL-Dateien",
3126:                                             L"for S&TL files", NULL),
3127:                         NULL), 0,
3128:                      0, NULL, 0)) return;
3129:     if (DynDlgAddItem(&ES_Dialog, WS_CHILD | WS_VISIBLE | WS_TABSTOP, 0,
3130:                      2 * BtnG, BtnG + 2 * WarnG + WarnH + erg * (BtnG + BoxH),
3131:                      SelBtnW, SelBtnH, 12 + 10 * erg,
3132:                      L"button", 0,
3133:                      StrByLang(X_CODING, L"elekti", L"\xffff",
3134:                                          L"Auswahl", L"select", NULL), 0,
3135:                      0, NULL, 0)) return;
3136:     if (DynDlgAddItem(&ES_Dialog, WS_CHILD | WS_VISIBLE | ES_LEFT | ES_AUTOHSCROLL | WS_BORDER | ES_READONLY, 0,
3137:                      3 * BtnG + SelBtnW, BtnG + 2 * WarnG + WarnH + erg * (BtnG + BoxH),
3138:                      TxtW, SelBtnH, 13 + 10 * erg,
3139:                      L"edit", 0,
3140:                      ES_Dialog_Data.VtfSlpStl[erg].Program, 0,
3141:                      0, NULL, 0)) return;
3142:     if (DynDlgAddItem(&ES_Dialog, WS_CHILD | WS_VISIBLE | BS_CHECKBOX | WS_TABSTOP, 0,
3143:                      2 * BtnG, BtnG + 3 * WarnG + WarnH + SelBtnH + erg * (BtnG + BoxH),
3144:                      ParaCbW, ParaCbH, 14 + 10 * erg,
3145:                      L"button", 0,
3146:                      StrByLang(X_CODING, L"libervola parametro", L"\xffff",
3147:                                          L"optionaler Parameter",
3148:                                          L"optional parameter", NULL), 0,
3149:                      0, NULL, 0)) return;
3150:     if (DynDlgAddItem(&ES_Dialog, WS_CHILD | WS_VISIBLE | ES_LEFT | ES_AUTOHSCROLL | WS_BORDER, 0,
3151:                      3 * BtnG + ParaCbW, BtnG + 3 * WarnG + WarnH + SelBtnH + erg * (BtnG + BoxH),
3152:                      ParaTxtW, ParaCbH, 15 + 10 * erg,
3153:                      L"edit", 0,
3154:                      ES_Dialog_Data.VtfSlpStl[erg].OptionalParam, 0,
3155:                      0, NULL, 0)) return;
3156:     if (DynDlgAddItem(&ES_Dialog, WS_CHILD | WS_VISIBLE | ES_RIGHT, 0,
3157:                      DlgW - 2 * BtnG - WarnW, BtnG + WarnG + erg * (BtnG + BoxH),
3158:                      WarnW, WarnH, 16 + 10 * erg,
3159:                      L"static", 0,
3160:                      StrByLang(X_CODING, L"*** nevalida ***", L"\xffff",
3161:                                          L"*** ungültig ***",
3162:                                          L"*** invalid ***", NULL), 0,
3163:                      0, NULL, 0)) return;
3164:   }
3165:   if (DynDlgAddItem(&ES_Dialog, WS_CHILD | WS_VISIBLE | BS_CHECKBOX | WS_GROUP | WS_TABSTOP, 0,
3166:                    BtnG, BtnG + 2 * WarnG + 3 * (BtnG + BoxH),
3167:                    DlgW - 2 * BtnG, SelBtnH, 40,
3168:                    L"button", 0,
3169:                    StrByLang(X_CODING, L"demandi anta" US_ux L" la starto",
3170:                                        L"demandi antaux la starto",
3171:                                          L"Rückfrage vor dem Start",
3172:                                        L"prompt before launching", NULL), 0,
3173:                    0, NULL, 0)) return;
3174:   // MessageBox(NULL, L"Step 3", L"Dialog Build", MB_OK | MB_ICONINFORMATION);

3175:   // DlgDataList(&ES_Dialog);

3176:   erg = DialogBoxIndirectParam(hThisInstance, ES_Dialog.dlg, hwnd, ES_DialogProc, (LPARAM) &ES_Dialog_Data);
3177:   // { wchar_t RESULT[150];

3178:   //   wsprintf(RESULT, L"DialogBoxIndirect() = %d", erg);

3179:   //   MessageBox(NULL, RESULT, L"Dialog Result", MB_OK | MB_ICONINFORMATION);

3180:   // }

3181:   if (erg) { /* Save the result */
3182:     memcpy(&ES_Settings, &ES_Dialog_Data, sizeof(struct ES_DIALOG_DATA));
3183:   }
3184:   DynDlgTemplateFree(&ES_Dialog);
3185: }
3186: 
3187: void InfoBox(void)
3188: { int cxChar, cyChar, Breite, Hoehe;
3189:   HWND fenster;
3190:   cxChar = LOWORD(GetDialogBaseUnits());
3191:   cyChar = HIWORD(GetDialogBaseUnits());
3192:   Breite = (int) floor(TFloatByLang(X_CODING, 79000L, 79000L, 55000L, 53000L, 0L) * cxChar)
3193:          + 64 + 3 * cyChar + 2 * GetSystemMetrics(SM_CXBORDER);
3194:   Hoehe = (int) floor(TFloatByLang(X_CODING, 20500L, 20500L, 15000L, 15000L, 0L) * cyChar)
3195:         + 2 * GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYCAPTION);
3196:   if (Breite > GetSystemMetrics(SM_CXSCREEN)) Breite = GetSystemMetrics(SM_CXSCREEN);
3197:    else if (Breite < GetSystemMetrics(SM_CXMIN)) Breite = GetSystemMetrics(SM_CXMIN);
3198:   if (Hoehe > GetSystemMetrics(SM_CYSCREEN)) Hoehe = GetSystemMetrics(SM_CYSCREEN);
3199:    else if (Hoehe < GetSystemMetrics(SM_CYMIN)) Hoehe = GetSystemMetrics(SM_CYMIN);
3200:   fenster = CreateWindow(AboutClassName,
3201:                          StrByLang(X_CODING,
3202:                                    L"kapableta rigardilo por triangularaj dosieroj", L"\xffff",
3203:                                    L"grundfunktionaler Betrachter für Triangulationsdateien",
3204:                                    L"low end triangulation file viewer",
3205:                                    NULL),
3206:                          WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_EX_TOPMOST,
3207:                          CW_USEDEFAULT, CW_USEDEFAULT, Breite, Hoehe,
3208:                          hwndApplication, NULL, hThisInstance, NULL);
3209: }
3210: 
3211: void MenuHit(HWND hwnd, WPARAM key)
3212: {
3213:   switch (key) {
3214:     case MN_FILE_OPEN:
3215:           if (SelectAndOpenFile(hwnd)) {
3216:                 Projection = PROJ_TRI;
3217:                 DrawScene(hwnd, 0, 0, 0);
3218:           }
3219:     break;
3220:     case MN_FILE_SAVE:
3221:           SelectAndSaveFile(hwnd);
3222:     break;
3223:     case MN_VIEW_ISO:
3224:       Projection = PROJ_ISO;
3225:       DrawScene(hwnd, 0, 0, 0);
3226:     break;
3227:     case MN_VIEW_DI:
3228:       Projection = PROJ_DI;
3229:       DrawScene(hwnd, 0, 0, 0);
3230:     break;
3231:     case MN_VIEW_TRI:
3232:       Projection = PROJ_TRI;
3233:       DrawScene(hwnd, 0, 0, 0);
3234:     break;
3235:     case MN_VIEW_RIGHT:
3236:       Projection = PROJ_RIGHT;
3237:       DrawScene(hwnd, 0, 0, 0);
3238:     break;
3239:     case MN_VIEW_FRONT:
3240:       Projection = PROJ_FRONT;
3241:       DrawScene(hwnd, 0, 0, 0);
3242:     break;
3243:     case MN_VIEW_LEFT:
3244:       Projection = PROJ_LEFT;
3245:       DrawScene(hwnd, 0, 0, 0);
3246:     break;
3247:     case MN_VIEW_BACK:
3248:       Projection = PROJ_BACK;
3249:       DrawScene(hwnd, 0, 0, 0);
3250:     break;
3251:     case MN_VIEW_TOP:
3252:       Projection = PROJ_TOP;
3253:       DrawScene(hwnd, 0, 0, 0);
3254:     break;
3255:     case MN_VIEW_BOTTOM:
3256:       Projection = PROJ_BOTTOM;
3257:       DrawScene(hwnd, 0, 0, 0);
3258:     break;
3259:     case MN_SET_CS:
3260:       Disp_CS = !Disp_CS;
3261:       CheckMenuItem(optionsmenu, MN_SET_CS, MF_BYCOMMAND | (Disp_CS ? MF_CHECKED : MF_UNCHECKED));
3262:       options_altered = 1;
3263:       DrawScene(hwnd, 0, 0, 0);
3264:     break;
3265:     case MN_SET_EXTEND:
3266:       Disp_Extend = !Disp_Extend;
3267:       CheckMenuItem(optionsmenu, MN_SET_EXTEND, MF_BYCOMMAND | (Disp_Extend ? MF_CHECKED : MF_UNCHECKED));
3268:       options_altered = 1;
3269:       DrawScene(hwnd, 0, 0, 0);
3270:     break;
3271:     case MN_SET_WIREFRAME:
3272:       Wireframe = !Wireframe;
3273:       RebuildLists = 1;
3274:       CheckMenuItem(optionsmenu, MN_SET_WIREFRAME, MF_BYCOMMAND | (Wireframe ? MF_CHECKED : MF_UNCHECKED));
3275:       options_altered = 1;
3276:       DrawScene(hwnd, 0, 0, 0);
3277:     break;
3278:     case MN_SET_CULL:
3279:       CullFace = !CullFace;
3280:       CheckMenuItem(optionsmenu, MN_SET_CULL, MF_BYCOMMAND | ((!CullFace) ? MF_CHECKED : MF_UNCHECKED));
3281:       options_altered = 1;
3282:       DrawScene(hwnd, 0, 0, 0);
3283:     break;
3284:     case MN_SET_SIMPLCOL:
3285:       simple_color = !simple_color;
3286:       if (!simple_color) UseLists = 0;
3287:       CheckMenuItem(optionsmenu, MN_SET_SIMPLCOL, MF_BYCOMMAND | (simple_color ? MF_CHECKED : MF_UNCHECKED));
3288:       CheckMenuItem(optionsmenu, MN_SET_LISTS, MF_BYCOMMAND | (UseLists ? MF_CHECKED : MF_UNCHECKED));
3289:       options_altered = 1;
3290:       DrawScene(hwnd, 0, 0, 0);
3291:     break;
3292:     case MN_SET_LIGHTY:
3293:       lighty_models = !lighty_models;
3294:       RebuildLists = 1;
3295:       CheckMenuItem(optionsmenu, MN_SET_LIGHTY, MF_BYCOMMAND | (lighty_models ? MF_CHECKED : MF_UNCHECKED));
3296:       options_altered = 1;
3297:       DrawScene(hwnd, 0, 0, 0);
3298:     break;
3299:     case MN_SET_LISTS:
3300:       // MessageBox(NULL, L"ne ebla", L"openGL listoj", MB_OK | MB_ICONSTOP);

3301:       UseLists = !UseLists;
3302:       if (UseLists) simple_color = 0;
3303:       RebuildLists = 1;
3304:       CheckMenuItem(optionsmenu, MN_SET_LISTS, MF_BYCOMMAND | (UseLists ? MF_CHECKED : MF_UNCHECKED));
3305:       CheckMenuItem(optionsmenu, MN_SET_SIMPLCOL, MF_BYCOMMAND | (simple_color ? MF_CHECKED : MF_UNCHECKED));
3306:       options_altered = 1;
3307:       DrawScene(hwnd, 0, 0, 0);
3308:     break;
3309:     case MN_SET_BACKGRND:
3310:       if (ChooseBackgroundColor(hwnd)) {
3311:         options_altered = 1;
3312:         DrawScene(hwnd, 0, 0, 0);
3313:       }
3314:     break;
3315:     case MN_SET_LANG_EO:
3316:       X_CODING = 0;
3317:       BuildMenue(hwnd); /* CheckMenuItem() is done by BuildMenue() */
3318:       options_altered = 1;
3319:     break;
3320:     case MN_SET_LANG_EOX:
3321:       X_CODING = 1;
3322:       BuildMenue(hwnd); /* CheckMenuItem() is done by BuildMenue() */
3323:       options_altered = 1;
3324:     break;
3325:     case MN_SET_LANG_GER:
3326:       X_CODING = 2;
3327:       BuildMenue(hwnd); /* CheckMenuItem() is done by BuildMenue() */
3328:       options_altered = 1;
3329:     break;
3330:     case MN_SET_LANG_ENG:
3331:       X_CODING = 3;
3332:       BuildMenue(hwnd); /* CheckMenuItem() is done by BuildMenue() */
3333:       options_altered = 1;
3334:     break;
3335:     case MN_MOUSE_L_INV:
3336:       mouse_inversion = (mouse_inversion & 1) ? mouse_inversion & 6 : mouse_inversion | 1;
3337:       CheckMenuItem(mousemenu, MN_MOUSE_L_INV, MF_BYCOMMAND | ((mouse_inversion & 1) ? MF_CHECKED : MF_UNCHECKED));
3338:     break;
3339:     case MN_MOUSE_M_INV:
3340:       mouse_inversion = (mouse_inversion & 2) ? mouse_inversion & 5 : mouse_inversion | 2;
3341:       CheckMenuItem(mousemenu, MN_MOUSE_M_INV, MF_BYCOMMAND | ((mouse_inversion & 2) ? MF_CHECKED : MF_UNCHECKED));
3342:     break;
3343:     case MN_MOUSE_R_INV:
3344:       mouse_inversion = (mouse_inversion & 4) ? mouse_inversion & 3 : mouse_inversion | 4;
3345:       CheckMenuItem(mousemenu, MN_MOUSE_R_INV, MF_BYCOMMAND | ((mouse_inversion & 4) ? MF_CHECKED : MF_UNCHECKED));
3346:     break;
3347:     case MN_SET_CALLEXIT:
3348:       CallExitSettings(hwnd);
3349:       options_altered = 1;
3350:     break;
3351:     case MN_ZOOM_PLUS:
3352:       view_scale *= DefaultZoomFaktor;
3353:       if (view_scale > MaxZoomFaktor) view_scale = MaxZoomFaktor;
3354:       DrawScene(hwnd, 0, 0, 0);
3355:     break;
3356:     case MN_ZOOM_MINUS:
3357:       view_scale /= DefaultZoomFaktor;
3358:       if (view_scale < 1.0) view_scale = 1.0;
3359:       DrawScene(hwnd, 0, 0, 0);
3360:     break;
3361:     case MN_ZOOM_FIT:
3362:       view_scale = 1.0;
3363:       DrawScene(hwnd, 0, 0, 0);
3364:     break;
3365:     case MN_PART_DISP:
3366:       if (VALID_MODELS > 1) {
3367:         /* wchar_t T[50];

3368:            wsprintf(T, L"%d objektoj", VALID_MODELS); */
3369:         if (hwndObjectDisplayDialog == NULL) {
3370:           /* MessageBox(NULL, L"Start ObjectDisplayDialog", T, MB_ICONINFORMATION | MB_OK); */
3371:           hwndObjectDisplayDialog = CreateWindow(MdlDispClassName,
3372:                                                  StrByLang(X_CODING,
3373:                                                  L"objektoj de kapableta rigardilo por triangularaj dosieroj", L"\xffff",
3374:                                                  L"Objekte des grundfunktionalen Betrachters für Triangulationsdateien",
3375:                                                  L"object in the low end triangulation file viewer",
3376:                                                  NULL),
3377:                                                  WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3378:                                                  CW_USEDEFAULT, CW_USEDEFAULT,
3379:                                                  30 * LOWORD(GetDialogBaseUnits()),
3380:                                                  (2 * GetSystemMetrics(SM_CYFULLSCREEN)) / 3,
3381:                                                  hwndApplication, NULL, hThisInstance, NULL);
3382:         }
3383:         ShowWindow(hwndObjectDisplayDialog, SW_SHOWNORMAL);
3384:       }
3385:     break;
3386:     case MN_REPAINT:
3387:       DrawScene(hwnd, 0, 0, 0);
3388:     break;
3389:     case MN_INFO:
3390:       InfoBox();
3391:     break;
3392:     case MN_FILE_QUIT:
3393:       SaveParametersInRegistry();
3394:       PostQuitMessage(0);
3395:     break;
3396:   }
3397: }
3398: 
3399: void KbdHit(HWND hwnd, WPARAM key)
3400: {
3401:   switch (key) {
3402:     case 033: case 'Q': case 'q':
3403: #ifdef DUMP_MAT
3404:       if (trail != NULL) fclose(trail);
3405: #endif

3406:       SaveParametersInRegistry();
3407:       PostQuitMessage(0);
3408:     break;
3409:     case 'i': case 'I':
3410:       MenuHit(hwnd, MN_VIEW_ISO);
3411:     break;
3412:     case 'd': case 'D':
3413:       MenuHit(hwnd, MN_VIEW_DI);
3414:     break;
3415:     case 't': case 'T':
3416:       MenuHit(hwnd, MN_VIEW_TRI);
3417:     break;
3418:     case 'h': case 'H':
3419:       MenuHit(hwnd, MN_VIEW_RIGHT);
3420:     break;
3421:     case 'j': case 'J':
3422:       MenuHit(hwnd, MN_VIEW_FRONT);
3423:     break;
3424:     case 'k': case 'K':
3425:       MenuHit(hwnd, MN_VIEW_LEFT);
3426:     break;
3427:     case 'l': case 'L':
3428:       MenuHit(hwnd, MN_VIEW_BACK);
3429:     break;
3430:     case 'm': case 'M':
3431:       MenuHit(hwnd, MN_VIEW_TOP);
3432:     break;
3433:     case 'u': case 'U':
3434:       MenuHit(hwnd, MN_VIEW_BOTTOM);
3435:     break;
3436:     case 'c': case 'C':
3437:       MenuHit(hwnd, MN_SET_CS);
3438:     break;
3439:     case 'x': case 'X':
3440:       MenuHit(hwnd, MN_SET_EXTEND);
3441:     break;
3442:     case '+':
3443:       MenuHit(hwnd, MN_ZOOM_PLUS);
3444:     break;
3445:     case '-':
3446:       MenuHit(hwnd, MN_ZOOM_MINUS);
3447:     break;
3448:     case '#':
3449:       MenuHit(hwnd, MN_ZOOM_FIT);
3450:     break;
3451:   }
3452: }
3453: 
3454: void MdlDispCheckboxPositionAdjust(int cxChar, int cyChar, int CheckBoxesStartY, int CBHight, int CheckBoxWidth,
3455:                                    int FirstCheckBox, int CheckBoxesVisibleCount)
3456: { int ct;
3457:   struct MODEL_SELECT *vm;
3458:   ct = 0;
3459:   for (vm = model_select_chain; vm != NULL; vm = vm->next)
3460:     if ((vm->Name != NULL) && (vm->Checkbox != NULL)) {
3461:       ++ct;
3462:       if ((ct > FirstCheckBox) && (ct <= FirstCheckBox + CheckBoxesVisibleCount)) {
3463:         MoveWindow(vm->Checkbox, cxChar, CheckBoxesStartY + (vm->Number - 1 - FirstCheckBox) * CBHight,
3464:                    CheckBoxWidth, CBHight, TRUE);
3465:       } else {
3466:         MoveWindow(vm->Checkbox, 0, 0, 0, 0, FALSE);
3467:       }
3468:   }
3469: }
3470: 
3471: LRESULT CALLBACK MdlDispWndProc(HWND hwnd, UINT uMsg,
3472:                                 WPARAM wParam, LPARAM lParam)
3473: {
3474:     static HWND wndAll, wndRP, wndSC;
3475:     static int topmost = 0, gezeigt = 1;
3476:     static int cxChar, cyChar, CBHight, HightBut, CheckBoxWidth, CheckBoxesStartY, CheckBoxesEndY,
3477:                CheckBoxesVisibleCount = 1, FirstCheckBox = 0;
3478:     int Notification;
3479:     struct MODEL_SELECT *vm;
3480:     wchar_t ZL[100];
3481:     SCROLLINFO si;
3482: 
3483:     switch(uMsg) {
3484:       case WM_CREATE:
3485:         cxChar = LOWORD(GetDialogBaseUnits());
3486:         cyChar = HIWORD(GetDialogBaseUnits());
3487:         CBHight = cyChar + 4;
3488:         wndRP = CreateWindow(L"button",
3489:                              StrByLang(X_CODING, L"prezenti", L"\xffff",
3490:                                        L"zeigen", L"repaint", NULL),
3491:                              WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
3492:                              0, 0, 0, 0,
3493:                              hwnd, (HMENU) 0, hThisInstance, NULL);
3494:         wndAll = CreateWindow(L"button",
3495:                              StrByLang(X_CODING, L"prezenti " US_cx L"iuj objektojn",
3496:                                                  L"prozenti cxiuj objektojn",
3497:                                                  L"alle Objekte zeigen",
3498:                                                  L"show all objects", NULL),
3499:                              WS_CHILD | WS_VISIBLE | BS_CHECKBOX,
3500:                              0, 0, 0, 0,
3501:                              hwnd, (HMENU) 1, hThisInstance, NULL);
3502:         SendMessage(wndAll, BM_SETCHECK, ObjectsShowAll ? BST_CHECKED : BST_UNCHECKED, 0L);
3503:         wndSC = CreateWindow(L"scrollbar", NULL,
3504:                              WS_CHILD | WS_VISIBLE | SBS_VERT,
3505:                              0, 0, 0, 0,
3506:                              hwnd, (HMENU) 2, hThisInstance, NULL);
3507: #ifdef DUMP_MODEL_SELECT_RECORDS
3508:         DumpModelSelectRecord();
3509: #endif

3510:         for (vm = model_select_chain; vm != NULL; vm = vm->next)
3511:           if (vm->Name != NULL) {
3512:             _snwprintf(ZL, 100, L"%d.: %s", vm->Number, vm->Name); ZL[99] = 0;
3513:             vm->Checkbox = CreateWindow(L"button", ZL,
3514:                                         WS_CHILD | WS_VISIBLE | BS_CHECKBOX,
3515:                                         0, 0, 0, 0,
3516:                                         hwnd, (HMENU) (MN_OBJECT_ZERO + vm->Number), hThisInstance, NULL);
3517:             if (vm->Checkbox == NULL) {
3518:               vm->Display = -1;
3519:             } else {
3520:               vm->Display = 1;
3521:               SendMessage(vm->Checkbox, BM_SETCHECK, vm->Display ? BST_CHECKED : BST_UNCHECKED, 0L);
3522:               EnableWindow(vm->Checkbox, ObjectsShowAll ? FALSE : TRUE);
3523:             }
3524:         }
3525:       break;
3526:       case WM_VSCROLL:
3527:         // { wchar_t Zl[100]; int min, max;

3528:           // wsprintf(Zl, L"wParam = %.4lx\nlParam = %.8lx", (unsigned long) wParam, lParam);

3529:           // GetScrollRange(wndSC, SB_CTL, &min, &max);

3530:           // wsprintf(Zl, L"VERT range: %d .. %d", min, max);

3531:           // MessageBox(NULL, Zl, L"Scroll:", MB_ICONINFORMATION | MB_OK);

3532:         // }

3533:         switch (LOWORD(wParam)) {
3534:           case SB_LINEUP:
3535:             // MessageBox(NULL, L"LineUp", L"Scroll:", MB_ICONINFORMATION | MB_OK);

3536:             if (--FirstCheckBox < 0) FirstCheckBox = 0;
3537:           break;
3538:           case SB_LINEDOWN:
3539:             // MessageBox(NULL, L"LineDown", L"Scroll:", MB_ICONINFORMATION | MB_OK);

3540:             FirstCheckBox++;
3541:             /***???  VALID_MODELS oder stored_model_references verwenden? ***/
3542:             if (stored_model_references < FirstCheckBox + CheckBoxesVisibleCount)
3543:               FirstCheckBox = stored_model_references - CheckBoxesVisibleCount;
3544:             if (FirstCheckBox < 0) FirstCheckBox = 0;
3545:           break;
3546:           case SB_PAGEUP:
3547:             // MessageBox(NULL, L"PageUp", L"Scroll:", MB_ICONINFORMATION | MB_OK);

3548:             FirstCheckBox -= CheckBoxesVisibleCount;
3549:             if (FirstCheckBox < 0) FirstCheckBox = 0;
3550:           break;
3551:           case SB_PAGEDOWN:
3552:             // MessageBox(NULL, L"PageDown", L"Scroll:", MB_ICONINFORMATION | MB_OK);

3553:             FirstCheckBox += CheckBoxesVisibleCount;
3554:             if (stored_model_references < FirstCheckBox + CheckBoxesVisibleCount)
3555:               FirstCheckBox = stored_model_references - CheckBoxesVisibleCount;
3556:             if (FirstCheckBox < 0) FirstCheckBox = 0;
3557:           break;
3558:           case SB_THUMBTRACK:
3559:           case SB_THUMBPOSITION:
3560:             si.cbSize = sizeof(si);
3561:             si.fMask = SIF_ALL;
3562:             GetScrollInfo(wndSC, SB_CTL, &si);
3563:             FirstCheckBox = si.nTrackPos;
3564:             if (stored_model_references < FirstCheckBox + CheckBoxesVisibleCount)
3565:               FirstCheckBox = stored_model_references - CheckBoxesVisibleCount;
3566:             if (FirstCheckBox < 0) FirstCheckBox = 0;
3567:             if (LOWORD(wParam) == SB_THUMBTRACK) {
3568:               MdlDispCheckboxPositionAdjust(cxChar, cyChar, CheckBoxesStartY, CBHight, CheckBoxWidth,
3569:                                             FirstCheckBox, CheckBoxesVisibleCount);
3570:               return 0;
3571:             }
3572:           break;
3573:         }
3574:         si.cbSize = sizeof(si);
3575:         si.fMask = SIF_POS;
3576:         si.nPos = FirstCheckBox;
3577:         SetScrollInfo(wndSC, SB_CTL, &si, TRUE);
3578:         MdlDispCheckboxPositionAdjust(cxChar, cyChar, CheckBoxesStartY, CBHight, CheckBoxWidth,
3579:                                       FirstCheckBox, CheckBoxesVisibleCount);
3580:       break;
3581:       case WM_COMMAND:
3582:         Notification = HIWORD(wParam);
3583:         switch (LOWORD(wParam)) {
3584:           case 0: if (IN_FILE_DIALOG) break;
3585:                   SendMessage(hwndApplication, WM_COMMAND, MN_REPAINT, 0L);
3586:                   gezeigt = 1;
3587:                   SetWindowText(wndRP, StrByLang(X_CODING, L"prezenti", L"\xffff",
3588:                                                            L"zeigen", L"repaint", NULL));
3589:         // { wchar_t Zl[100]; int min, max;

3590:           // wsprintf(Zl, L"wParam = %.4lx\nlParam = %.8lx", (unsigned long) wParam, lParam);

3591:           /* GetScrollRange(wndSC, SB_VERT, &min, &max);

3592:           wsprintf(Zl, L"VERT range: %d .. %d\n", min, max); */
3593:           // GetScrollRange(wndSC, SB_CTL, &min, &max);

3594:           // wsprintf(/* &(*/ Zl /*[wcslen(Zl)])*/, L"CTL  range: %d .. %d", min, max);

3595:           // MessageBox(NULL, Zl, L"Scroll:", MB_ICONINFORMATION | MB_OK);

3596:         // }

3597:           break;
3598:           case 1:
3599:             ObjectsShowAll = !ObjectsShowAll;
3600:             SendMessage(wndAll, BM_SETCHECK, ObjectsShowAll ? BST_CHECKED : BST_UNCHECKED, 0L);
3601:             for (vm = model_select_chain; vm != NULL; vm = vm->next)
3602:               if ((vm->Name != NULL) && (vm->Checkbox != NULL)) {
3603:                 EnableWindow(vm->Checkbox, ObjectsShowAll ? FALSE : TRUE);
3604:                 if (!(vm->Display)) gezeigt = 0;
3605:             }
3606:             if (!gezeigt) SetWindowText(wndRP, StrByLang(X_CODING, L"prezenti!", L"\xffff",
3607:                                                                    L"zeigen!", L"repaint!", NULL));
3608:           break;
3609:           case RT_BUILD_CHECKBOXES:
3610:             for (vm = model_select_chain; vm != NULL; vm = vm->next)
3611:               if (vm->Name != NULL) {
3612:                 _snwprintf(ZL, 100, L"%d.: %s", vm->Number, vm->Name); ZL[99] = 0;
3613:                 if (vm->Checkbox == NULL) {
3614:                   vm->Checkbox = CreateWindow(L"button", ZL,
3615:                                               WS_CHILD | WS_VISIBLE | BS_CHECKBOX,
3616:                                               0, 0, 0, 0,
3617:                                               hwnd, (HMENU) (MN_OBJECT_ZERO + vm->Number), hThisInstance, NULL);
3618:                 } else
3619:                   SetWindowText(vm->Checkbox, ZL);
3620:                 if (vm->Checkbox == NULL) {
3621:                   vm->Display = -1;
3622:                 } else {
3623:                   ShowWindow(vm->Checkbox, SW_SHOW);
3624:                   vm->Display = 1;
3625:                   SendMessage(vm->Checkbox, BM_SETCHECK, vm->Display ? BST_CHECKED : BST_UNCHECKED, 0L);
3626:                   EnableWindow(vm->Checkbox, ObjectsShowAll ? FALSE : TRUE);
3627:                 }
3628:             }
3629:             si.cbSize = sizeof(si);
3630:             si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
3631:             si.nPage = CheckBoxesVisibleCount; si.nMin = 0; si.nMax = stored_model_references - 1;
3632:             si.nPos = FirstCheckBox;
3633:             SetScrollInfo(wndSC, SB_CTL, &si, TRUE);
3634:             MdlDispCheckboxPositionAdjust(cxChar, cyChar, CheckBoxesStartY, CBHight, CheckBoxWidth,
3635:                                           FirstCheckBox, CheckBoxesVisibleCount);
3636:           break;
3637:           case RT_CLEAR_CHECKBOXES:
3638:             for (vm = model_select_chain; vm != NULL; vm = vm->next)
3639:             if (vm->Checkbox != NULL) {
3640:               EnableWindow(vm->Checkbox, FALSE);
3641:               ShowWindow(vm->Checkbox, SW_HIDE);
3642:             }
3643:           break;
3644:           case RT_SET_LANG:
3645:             SetWindowText(wndRP, StrByLang(X_CODING, L"prezenti", L"\xffff",
3646:                                            L"zeigen", L"repaint", NULL));
3647:             SetWindowText(wndAll, StrByLang(X_CODING, L"prezenti " US_cx L"iuj objektojn",
3648:                                                       L"prozenti cxiuj objektojn",
3649:                                                       L"alle Objekte zeigen",
3650:                                                       L"show all objects", NULL));
3651:             SetWindowText(hwnd, StrByLang(X_CODING,
3652:                                           L"objektoj de kapableta rigardilo por triangularaj dosieroj", L"\xffff",
3653:                                           L"Objekte des grundfunktionalen Betrachters für Triangulationsdateien",
3654:                                           L"object in the low end triangulation file viewer",
3655:                                           NULL));
3656:           break;
3657:           default:
3658:             if (LOWORD(wParam) > MN_OBJECT_ZERO) {
3659:               for (vm = model_select_chain; vm != NULL; vm = vm->next)
3660:                 if ((vm->Name != NULL) && (vm->Checkbox != NULL)) {
3661:                   if (LOWORD(wParam) == vm->Number + MN_OBJECT_ZERO) {
3662:                     vm->Display = !(vm->Display);
3663:                     SendMessage(vm->Checkbox, BM_SETCHECK, vm->Display ? BST_CHECKED : BST_UNCHECKED, 0L);
3664:                     gezeigt = 0;
3665:                     SetWindowText(wndRP, StrByLang(X_CODING, L"prezenti!", L"\xffff",
3666:                                                              L"zeigen!", L"repaint!", NULL));
3667:                   }
3668:               }
3669:             }
3670:         }
3671:       break;
3672:       case WM_SIZE:
3673:         cxChar = LOWORD(GetDialogBaseUnits());
3674:         cyChar = HIWORD(GetDialogBaseUnits());
3675:         HightBut = (3 * cyChar) / 2 + 2 * (GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYEDGE));
3676:         CheckBoxesStartY = 2 * cxChar + CBHight;
3677:         CheckBoxesEndY = (int) HIWORD(lParam) - 2 * cxChar - HightBut;
3678:         CheckBoxWidth = (int) LOWORD(lParam) - 2 * cxChar - GetSystemMetrics(SM_CXVSCROLL);
3679:         CheckBoxesVisibleCount = (CheckBoxesEndY - CheckBoxesStartY) / CBHight;
3680:         if (CheckBoxesVisibleCount <= 0) CheckBoxesVisibleCount = 1;
3681:         if (stored_model_references < FirstCheckBox + CheckBoxesVisibleCount)
3682:           FirstCheckBox = stored_model_references - CheckBoxesVisibleCount;
3683:         if (FirstCheckBox < 0) FirstCheckBox = 0;
3684:         MoveWindow(wndAll, cxChar,                             cxChar,
3685:                            (int) LOWORD(lParam) - 2 * cxChar,  CBHight,
3686:                            TRUE);
3687:         MoveWindow(wndSC,  cxChar + CheckBoxWidth,             CheckBoxesStartY,
3688:                            GetSystemMetrics(SM_CXVSCROLL),     CheckBoxesEndY - CheckBoxesStartY,
3689:                            TRUE);
3690:         si.cbSize = sizeof(si); si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
3691:         GetScrollInfo(wndSC, SB_CTL, &si);
3692:         si.nPage = CheckBoxesVisibleCount; si.nMin = 0; si.nMax = stored_model_references - 1;
3693:         SetScrollInfo(wndSC, SB_CTL, &si, TRUE);
3694:         MdlDispCheckboxPositionAdjust(cxChar, cyChar, CheckBoxesStartY, CBHight, CheckBoxWidth,
3695:                                       FirstCheckBox, CheckBoxesVisibleCount);
3696:         MoveWindow(wndRP,  cxChar,                             (int) HIWORD(lParam) - cxChar - HightBut,
3697:                            (int) LOWORD(lParam) - 2 * cxChar,  HightBut,
3698:                            TRUE);
3699:       break;
3700:       case WM_CHAR:
3701:         if (hwndApplication != NULL) switch (wParam) {
3702:           case 'q': case 'Q': case '\033': break;
3703:           default: KbdHit(hwndApplication, wParam);
3704:         }
3705:       break;
3706:       case WM_DESTROY:
3707:         hwndObjectDisplayDialog = NULL;
3708:         ObjectsShowAll = 1;
3709:         UnlinkModelSelectItems();
3710:       default:
3711:         return DefWindowProc(hwnd, uMsg, wParam, lParam);
3712:     }
3713:     return 0;
3714: }
3715: 
3716: LRESULT CALLBACK AboutWndProc(HWND hwnd, UINT uMsg,
3717:                               WPARAM wParam, LPARAM lParam)
3718: {
3719:     HWND wndTx, wndOK;
3720:     int cxChar, cyChar, HightBut;
3721:     SCROLLINFO si;
3722:     HDC hdc;
3723:     PAINTSTRUCT ps;
3724: 
3725:     switch(uMsg) {
3726:       case WM_CREATE:
3727:         cxChar = LOWORD(GetDialogBaseUnits());
3728:         cyChar = HIWORD(GetDialogBaseUnits());
3729:         wndOK = CreateWindow(L"button",
3730:                              StrByLang(X_CODING, L"en ordo", L"\xffff",
3731:                                        L"OK", L"OK", NULL),
3732:                              WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
3733:                              0, 0, 0, 0,
3734:                              hwnd, (HMENU) 0, hThisInstance, NULL);
3735:         wndTx = CreateWindow(L"edit",
3736:                              StrByLang(X_CODING,
3737:                     /*    0 */ L"Programiga ekzerco kun \273openGL\253 kaj \273UNICODE\253\r\n"
3738:                                L"Versio " L_Version_string L" [kompilis: " TEXT(__DATE__)
3739:                                 L"--" TEXT(__TIME__) L"]\r\n"
3740:                                L"\r\n\251 copyright Arnold WENDL, Fürth, Germanio, anno Domini 2002, 2003\r\n\r\n"
3741:                                L"Uzo de \273Windows registry\253:\r\n"
3742:                                L"\"HKEY_CURRENT_USER\\" RegistryDir L"\"\r\n\r\n"
3743:                                L"Vortaroj:\r\n"
3744:                                L"Angla-Esteranto Komputila Vortaro,"
3745:                                 L" http://www.cilea.it/~bottoni/doc/eo-note/komputila-vortaro.htm, 1999\r\n"
3746:                                L"Taschenwörterbuch Deutsch Esperanto,"
3747:                                 L" VEB Verlag Enzyklopädie Leipzig, 1989\r\n"
3748:                                L"J. C. Wells: Teach Yourself Esperanto Dictionary,"
3749:                                 L" Hodder and Stoughton Ltd, 1985\r\n\r\n"
3750:                                L"Senpaga uzo, neniu garantio!\r\n"
3751:                                L"Free to use, no warrenty at all!\r\n"
3752:                                L"Benutzung lizenzfrei, keinerlei Garantie!",
3753:                                L"\xffff",
3754:                     /*    2 */ L"Programmierübung zu \"openGL\" und \"UNICODE\"\r\n"
3755:                                L"Version " L_Version_string L" [übersetzt: " TEXT(__DATE__)
3756:                                 L"--" TEXT(__TIME__) L"]\r\n"
3757:                                L"\r\n\251 copyright Arnold WENDL, Fürth, Deutschland, anno Domini 2002, 2003\r\n\r\n"
3758:                                L"Benutzter Bereich der \"Windows registry\":\r\n"
3759:                                L"\"HKEY_CURRENT_USER\\" RegistryDir L"\"\r\n\r\n"
3760:                                L"Senpaga uzo, neniu garantio!\r\n"
3761:                                L"Free to use, no warrenty at all!\r\n"
3762:                                L"Benutzung lizenzfrei, keinerlei Garantie!",
3763:                     /*    3 */ L"Programing exercise of \"openGL\" and \"UNICODE\" usage\r\n"
3764:                                L"Version " L_Version_string L" [compiled: " TEXT(__DATE__)
3765:                                 L"--" TEXT(__TIME__) L"]\r\n"
3766:                                L"\r\n\251 copyright Arnold WENDL, Fürth, Germany, anno Domini 2002, 2003\r\n\r\n"
3767:                                L"\"Windows registry\" usage:\r\n"
3768:                                L"\"HKEY_CURRENT_USER\\" RegistryDir L"\"\r\n\r\n"
3769:                                L"Senpaga uzo, neniu garantio!\r\n"
3770:                                L"Free to use, no warrenty at all!\r\n"
3771:                                L"Benutzung lizenzfrei, keinerlei Garantie!",
3772:                              NULL),
3773:                              WS_CHILD | WS_VISIBLE | WS_VSCROLL |
3774:                              ES_LEFT | ES_READONLY | ES_MULTILINE,
3775:                              0, 0, 0, 0,
3776:                              hwnd, (HMENU) 1, hThisInstance, NULL);
3777:         SetWindowLong(hwnd, 0, (long) wndTx);
3778:         SetWindowLong(hwnd, sizeof(long), (long) wndOK);
3779:       break;
3780:       case WM_COMMAND:
3781:         if (LOWORD(wParam) == 0) DestroyWindow(hwnd);
3782:       break;
3783:       case WM_SIZE:
3784:         cxChar = LOWORD(GetDialogBaseUnits());
3785:         cyChar = HIWORD(GetDialogBaseUnits());
3786:         wndTx = (HWND) GetWindowLong(hwnd, 0);
3787:         wndOK = (HWND) GetWindowLong(hwnd, sizeof(long));
3788:         HightBut = (3 * cyChar) / 2 + 2 * (GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYEDGE));
3789:         MoveWindow(wndOK,  32 + 2 * cxChar,                         (int) HIWORD(lParam) - cxChar - HightBut,
3790:                            (int) LOWORD(lParam) - 32 - 3 * cxChar,  HightBut,
3791:                            TRUE);
3792:         ShowScrollBar(wndTx, SB_VERT, TRUE);
3793:         MoveWindow(wndTx,  32 + 2 * cxChar,                         cxChar,
3794:                            (int) LOWORD(lParam) - 32 - 3 * cxChar,  (int) HIWORD(lParam) - 3 * cxChar - HightBut,
3795:                            TRUE);
3796:         si.cbSize = sizeof(SCROLLINFO);
3797:         si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
3798:         GetScrollInfo(wndTx, SB_VERT, &si);
3799:         if ((long) si.nPage > (long) si.nMax - (long) si.nMin)
3800:           ShowScrollBar(wndTx, SB_VERT, FALSE);
3801:          else
3802:           ShowScrollBar(wndTx, SB_VERT, TRUE);
3803:       break;
3804:       case WM_PAINT:
3805:         cxChar = LOWORD(GetDialogBaseUnits());
3806:         hdc = BeginPaint(hwnd, &ps);
3807:         DrawIcon(hdc, cxChar, cxChar, MyIcon);
3808:         EndPaint(hwnd, &ps);
3809:       default:
3810:         return DefWindowProc(hwnd, uMsg, wParam, lParam);
3811:     }
3812:     return 0;
3813: }
3814: 
3815: LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg,
3816:                          WPARAM wParam, LPARAM lParam)
3817: {
3818:     switch(uMsg)
3819:     {
3820:         case WM_PAINT:
3821:             DrawScene(hwnd, 0, 0, 0);
3822:             break;
3823:         case WM_DESTROY:
3824: #ifdef DUMP_MAT
3825:             if (trail != NULL) fclose(trail);
3826: #endif

3827:             SaveParametersInRegistry();
3828:             PostQuitMessage(0);
3829:             break;
3830:         case WM_LBUTTONDOWN:
3831:             switch(wParam & (MK_CONTROL | MK_SHIFT)) {
3832:               case 0:
3833:                 DrawScene(hwnd, DRAW_ADD_ROT, LOWORD(lParam), HIWORD(lParam));
3834:               break;
3835:               case MK_SHIFT:
3836:                 view_pan(LOWORD(lParam), HIWORD(lParam));
3837:                 DrawScene(hwnd, 0, 0, 0);
3838:               break;
3839:               case MK_CONTROL:
3840:                 view_zoom(HIWORD(lParam));
3841:                 DrawScene(hwnd, 0, 0, 0);
3842:               break;
3843:               default:
3844:                 return DefWindowProc(hwnd, uMsg, wParam, lParam);
3845:               break;
3846:             }
3847:             break;
3848:         case WM_RBUTTONDOWN:
3849:             switch(wParam & (MK_CONTROL | MK_SHIFT)) {
3850:               case 0:
3851:                 view_pan(LOWORD(lParam), HIWORD(lParam));
3852:                 DrawScene(hwnd, 0, 0, 0);
3853:               break;
3854:               default:
3855:                 return DefWindowProc(hwnd, uMsg, wParam, lParam);
3856:               break;
3857:             }
3858:             break;
3859:         case WM_MBUTTONDOWN:
3860:             switch(wParam & (MK_CONTROL | MK_SHIFT)) {
3861:               case 0:
3862:                 view_zoom(HIWORD(lParam));
3863:                 DrawScene(hwnd, 0, 0, 0);
3864:               break;
3865:               default:
3866:                 return DefWindowProc(hwnd, uMsg, wParam, lParam);
3867:               break;
3868:             }
3869:             break;
3870:         case WM_COMMAND:
3871:             MenuHit(hwnd, wParam);
3872:             break;
3873:         case WM_CHAR:
3874:             KbdHit(hwnd, wParam);
3875:             break;
3876:         default:
3877:             return DefWindowProc(hwnd, uMsg, wParam, lParam);
3878:     }
3879:     return 0;
3880: }
3881: 
3882: void OptionsScan(int first)
3883: { int ct, do_save;
3884:   wchar_t Titel[MAX_PATH + 100];
3885:   do_save = 0;
3886:   for (ct = 1; ct < Argc; ct++) {
3887:     if (Argv[ct][0] == L'-') {
3888:       if (!wcscmp(Argv[ct], L"-ClearReg")) {
3889:         if (first) UnlinkAllMyRegistryKeys();
3890:       } else
3891:       if (!wcscmp(Argv[ct], L"-Save")) {
3892:         if (!first) do_save = 1;
3893:       }
3894:     } else if (!first) {
3895:       CmdLineReadFile(Argv[ct], CmdLineFileRead);
3896:       if (!CmdLineFileRead && total_facet_count) CmdLineFileRead = ct;
3897:     }
3898:   }
3899:   if (CmdLineFileRead) DrawScene(hwndApplication, 0, 0, 0);
3900:   if (VALID_MODELS) {
3901:     wsprintf(Titel, L"%s - %s", LangWindowName,
3902:              &(Argv[CmdLineFileRead][CmdLineFirstFileBasenameStart]));
3903:     SetWindowText(hwndApplication, Titel);
3904:   }
3905: }
3906: 
3907: 
3908: long ICON_AND[32] = { 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,
3909:                       0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,
3910:                       0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,
3911:                       0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L };
3912: unsigned char ICON_XOR[128] = { 0xff, 0xff, 0xff, 0xff,
3913:          /* Spitze */           0xff, 0xfe, 0xff, 0xff,
3914:                                 0xff, 0xfe, 0x7f, 0xff,
3915:                                 0xff, 0xfd, 0x7f, 0xff,
3916:                                 0xff, 0xfd, 0xbf, 0xff,
3917:                                 0xff, 0xf9, 0xdf, 0xff,
3918:                                 0xff, 0xf9, 0x6f, 0xff,
3919:                                 0xff, 0xf3, 0xcf, 0xff,
3920:                                 0xff, 0xf2, 0xf7, 0xff,
3921:                                 0xff, 0xe3, 0xbb, 0xff,
3922:                                 0xff, 0xe9, 0xed, 0xff,
3923:                                 0xff, 0xd7, 0x79, 0xff,
3924:                                 0xff, 0xc3, 0xde, 0xff,
3925:                                 0xff, 0x96, 0xf7, 0x7f,
3926:                                 0xff, 0xa7, 0xbd, 0xbf,
3927:          /* Mitte des */        0xff, 0x4d, 0xef, 0x3f,
3928:          /* Bildes    */        0xff, 0x2f, 0x7b, 0xdf,
3929:                                 0xfe, 0x4b, 0xde, 0xef,
3930:                                 0xfe, 0xae, 0xf7, 0xb7,
3931:                                 0xfd, 0x57, 0xbd, 0xe7,
3932:                                 0xfc, 0x9d, 0xef, 0x7b,
3933:          /* mittl. Horiz. */    0xf9, 0x00, 0x00, 0x01,
3934:                                 0xfa, 0xaf, 0xff, 0xfb,
3935:                                 0xf5, 0x73, 0xff, 0xf7,
3936:                                 0xf2, 0xfd, 0xff, 0xef,
3937:                                 0xe5, 0xfe, 0xff, 0xdf,
3938:                                 0xeb, 0xff, 0x7f, 0xbf,
3939:                                 0xd7, 0xff, 0xbf, 0x7f,
3940:                                 0xcf, 0xff, 0xce, 0xff,
3941:                                 0x9f, 0xff, 0xf5, 0xff,
3942:          /* untere Horiz. */    0x80, 0x00, 0x03, 0xff,
3943:                                 0xff, 0xff, 0xff, 0xff };
3944: 
3945: short SICON_AND[16] = { 0, 0, 0, 0, 0, 0, 0, 0,
3946:                         0, 0, 0, 0, 0, 0, 0, 0 };
3947: unsigned char SICON_XOR[32] = { 0xff, 0xff,  0xfe, 0xff,  0xfe, 0x7f,  0xfc, 0xbf,
3948:                                 0xfd, 0xbf,  0xf9, 0xdf,  0xf9, 0xef,  0xf5, 0xf7,
3949:                                 0xf3, 0xf7,  0xeb, 0xfb,  0xe8, 0x01,  0xd5, 0xfb,
3950:                                 0xce, 0x77,  0x9f, 0xaf,  0x80, 0x1f,  0xff, 0xff };
3951: 
3952: int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
3953:                                         LPSTR d3, int nCmdShow)
3954: {
3955:     MSG msg;
3956:     WNDCLASSEX wndClass;
3957:     HDC hDC;
3958:     PIXELFORMATDESCRIPTOR pfd;
3959:     int iPixelFormat;
3960: 
3961:     Initialize_Local_Parameters();
3962:     hThisInstance = hInstance;
3963: #ifdef DUMP_MAT
3964:     trail = fopen("cube.trail", "a");
3965: #endif

3966: 
3967:     Argv = CommandLineToArgvW(GetCommandLine(), &Argc);
3968:     OptionsScan(1);
3969:     LoadParametersFromRegistry();
3970: 
3971: 
3972:     if (hPrevInstance == NULL)
3973:     {
3974:         MyIcon = CreateIcon(NULL, 32, 32, 1, 1,
3975:                             (void *) &(ICON_AND[0]),
3976:                             (void *) &(ICON_XOR[0]));
3977:         MySmallIcon = CreateIcon(NULL, 16, 16, 1, 1,
3978:                             (void *) &(SICON_AND[0]),
3979:                             (void *) &(SICON_XOR[0]));
3980:         
3981:         memset(&wndClass, 0, sizeof(wndClass));
3982:         wndClass.cbSize = sizeof(wndClass);
3983:         wndClass.style = CS_HREDRAW | CS_VREDRAW;
3984:         wndClass.lpfnWndProc = WndProc;
3985:         wndClass.hInstance = hInstance;
3986:         wndClass.hIcon = MyIcon;
3987:         wndClass.hIconSm = MySmallIcon;
3988:         wndClass.hCursor = LoadCursor(NULL, IDC_CROSS);
3989:         wndClass.lpszClassName = ThisClassName;
3990:         if (!RegisterClassEx(&wndClass)) {
3991:           MessageBox(NULL,
3992:                      StrByLang(X_CODING, L"\273RegisterClassExW()\253 malsukcesis!\nSubtenon de \273UNICODE\253?",
3993:                                          L"\xffff",
3994:                                          L"'RegisterClassExW()' schlug fehl!\nUngenügende UNICODE-Unterstützung?",
3995:                                          L"\"RegisterClassEsW()\" failed!\nInsufficent UNICODE support?",
3996:                                          NULL),
3997:                      StrByLang(X_CODING, L"precipa eraro", L"\xffff",
3998:                                          L"Grundsätzlicher Fehler",
3999:                                          L"general error",
4000:                                          NULL),
4001:                      MB_ICONSTOP | MB_OK);
4002:           return FALSE;
4003:         }
4004: 
4005:         wndClass.style = CS_HREDRAW | CS_VREDRAW;
4006:         wndClass.lpfnWndProc = AboutWndProc;
4007:         wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
4008:         wndClass.lpszClassName = AboutClassName;
4009:         wndClass.hbrBackground = (struct HBRUSH__ *) (COLOR_MENU + 1);
4010:         wndClass.cbWndExtra = 2 * sizeof(long);
4011:         if (!RegisterClassEx(&wndClass)) {
4012:           MessageBox(NULL,
4013:                      StrByLang(X_CODING, L"\273RegisterClassExW()\253 malsukcesis!\nSubtenon de \273UNICODE\253?",
4014:                                          L"\xffff",
4015:                                          L"'RegisterClassExW()' schlug fehl!\nUngenügende UNICODE-Unterstützung?",
4016:                                          L"\"RegisterClassEsW()\" failed!\nInsufficent UNICODE support?",
4017:                                          NULL),
4018:                      StrByLang(X_CODING, L"precipa eraro", L"\xffff",
4019:                                          L"Grundsätzlicher Fehler",
4020:                                          L"general error",
4021:                                          NULL),
4022:                      MB_ICONSTOP | MB_OK);
4023:           return FALSE;
4024:         }
4025: 
4026:         wndClass.style = CS_HREDRAW | CS_VREDRAW;
4027:         wndClass.lpfnWndProc = MdlDispWndProc;
4028:         wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
4029:         wndClass.lpszClassName = MdlDispClassName;
4030:         wndClass.hbrBackground = (struct HBRUSH__ *) (COLOR_MENU + 1);
4031:         wndClass.cbWndExtra = 0;
4032:         if (!RegisterClassEx(&wndClass)) {
4033:           MessageBox(NULL,
4034:                      StrByLang(X_CODING, L"\273RegisterClassExW()\253 malsukcesis!\nSubtenon de \273UNICODE\253?",
4035:                                          L"\xffff",
4036:                                          L"'RegisterClassExW()' schlug fehl!\nUngenügende UNICODE-Unterstützung?",
4037:                                          L"\"RegisterClassEsW()\" failed!\nInsufficent UNICODE support?",
4038:                                          NULL),
4039:                      StrByLang(X_CODING, L"precipa eraro", L"\xffff",
4040:                                          L"Grundsätzlicher Fehler",
4041:                                          L"general error",
4042:                                          NULL),
4043:                      MB_ICONSTOP | MB_OK);
4044:           return FALSE;
4045:         }
4046:     }
4047:     hwndApplication = CreateWindow(ThisClassName, LangWindowName,
4048:                         WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
4049:                         CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
4050:                         NULL, NULL, hInstance, NULL);
4051:     BuildMenue(hwndApplication);
4052:     hDC = GetDC(hwndApplication);
4053:     memset(&pfd, 0, sizeof(pfd));
4054:     pfd.nSize = sizeof(pfd);
4055:     pfd.nVersion = 1;
4056:     pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
4057:     pfd.iPixelType = PFD_TYPE_RGBA;
4058:     pfd.iLayerType = PFD_MAIN_PLANE;
4059:     pfd.cDepthBits = 32;
4060:     iPixelFormat = ChoosePixelFormat(hDC, &pfd);
4061:     SetPixelFormat(hDC, iPixelFormat, &pfd);
4062:     hglrc = wglCreateContext(hDC);
4063:     ReleaseDC(hwndApplication, hDC);
4064:     ShowWindow(hwndApplication, nCmdShow);
4065:     UpdateWindow(hwndApplication);
4066: #ifdef FADEN_INIT
4067:     AllocConsole();
4068: #endif

4069:     OptionsScan(0);
4070:     while (GetMessage(&msg, NULL, 0, 0)) {
4071:         TranslateMessage(&msg);
4072:         DispatchMessage(&msg);
4073:     }
4074:     wglMakeCurrent(NULL, NULL);
4075:     wglDeleteContext(hglrc);
4076:     DeleteObject(MyIcon); DeleteObject(MySmallIcon);
4077:     return msg.wParam;
4078: }
4079: