Subversion Repositories Games.Chess Giants

Rev

Rev 11 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 1
// main.cpp
2
 
3
#include "common.h"
4
 
5
 
6
bool Themes_Init (void)
7
{
8
   // this function (re)builds the themes array and loads all the themes' data
9
 
10
   wchar_t search_pattern[256];
11
   WIN32_FIND_DATA wfd;
12
   HANDLE hFind;
13
   int selectedtheme_index;
14
 
15
   // start by resetting the themes array
16
   themes = NULL;
17
   theme_count = 0;
18
 
19
   // the selected them isn't known yet
20
   selectedtheme_index = -1;
21
 
11 pmbaty 22
   // build the search pattern string out of the path and initiate the search from that point
1 pmbaty 23
   swprintf_s (search_pattern, WCHAR_SIZEOF (search_pattern), L"%s\\themes\\*.*", app_path);
24
   hFind = FindFirstFile (search_pattern, &wfd);
25
   if (hFind != INVALID_HANDLE_VALUE)
26
   {
27
      // start doing this...
28
      do
29
      {
30
         // is it this directory or the parent directory ?
31
         if ((wcscmp (wfd.cFileName, L".") == 0) || (wcscmp (wfd.cFileName, L"..") == 0))
32
            continue; // skip that entry
33
 
34
         // is it a directory ?
35
         if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
36
         {
37
            // reallocate space for one theme more (zero out the allocated space) and copy it in place
38
            themes = (theme_t *) SAFE_realloc (themes, theme_count, theme_count + 1, sizeof (theme_t), true);
39
            wcscpy_s (themes[theme_count].name, WCHAR_SIZEOF (themes[theme_count].name), wfd.cFileName);
40
            theme_count++; // we know now one theme more
41
 
42
            // is it the selected theme ?
43
            if (_wcsicmp (wfd.cFileName, wantedtheme_name) == 0)
44
            {
45
               Theme_Load (&themes[theme_count - 1], true); // load ALL the theme data from this directory
46
               selectedtheme_index = theme_count - 1; // remember the selected theme is this one
47
            }
48
         }
49
      } while (FindNextFile (hFind, &wfd)); // ...and don't stop as long as there are files to go
50
 
51
      FindClose (hFind); // close the search handle
52
   }
53
 
11 pmbaty 54
   // consistency check: we need at least one theme
1 pmbaty 55
   if (theme_count == 0)
56
   {
11 pmbaty 57
      MessageBox (NULL, LOCALIZE (L"Error_UnableToLoadThemes"), LOCALIZE (L"FatalError"), MB_ICONERROR | MB_OK);
1 pmbaty 58
      return (false); // if none of these extensions match, bomb out
59
   }
60
 
61
   // have we found the selected theme ?
62
   if (selectedtheme_index != -1)
63
      theme = &themes[selectedtheme_index]; // found it, so link it
64
   else
65
   {
66
      Theme_Load (&themes[0], true); // not found, so load the first available theme
67
      theme = &themes[0]; // and link selected theme to it
68
   }
69
 
70
   // if we have a custom background specified, load it too
71
   if (custombackground_pathname[0] != 0)
72
      Background_LoadImage (&custombg, custombackground_pathname);
73
 
74
   return (true); // at least one theme has been loaded successfully, return TRUE
75
}
76
 
77
 
78
void Themes_Shutdown (void)
79
{
80
   // helper function to release the themes structures array
81
 
82
   int theme_index;
83
 
84
   // before freeing the themes array, backup our theme's name
85
   wcscpy_s (wantedtheme_name, WCHAR_SIZEOF (wantedtheme_name), theme->name);
86
 
87
   // for each theme, free its mallocated data
88
   for (theme_index = 0; theme_index < theme_count; theme_index++)
89
   {
90
      SAFE_free ((void **) &theme->description); // free its description
91
 
92
      SAFE_free ((void **) &themes[theme_index].illum.lights); // free the lights array
93
      themes[theme_index].illum.light_count = 0;
94
   }
95
 
96
   // free the themes array
97
   SAFE_free ((void **) &themes);
98
   theme_count = 0;
99
 
100
   return; // nothing to do
101
}
102
 
103
 
104
void Theme_Load (theme_t *theme, bool want_all)
105
{
106
   // this function loads a particular theme out of a theme subdirectory's files
107
 
11 pmbaty 108
   #define THEME_LOAD_STEP(id) if ((theme->load_index == (id)) || (want_all && (theme->load_index < ((id) + 1))))
109
   #define THEME_LOAD_TEXTURE(varname,texture_name) \
110
   { \
111
      theme->varname = Render_LoadTexture (L"%s/themes/%s/" texture_name L".*", app_path, theme->name); \
112
      if (theme->varname == -1) \
113
         MessageBox (NULL, LOCALIZE (L"Error_UnableToAddTextureD3DXCreateTextureFromFileFailed"), LOCALIZE (L"FatalError"), MB_ICONERROR | MB_OK); \
114
   }
10 pmbaty 115
   #define THEME_LOAD_MESH(varname,mesh_name) \
116
   { \
11 pmbaty 117
      theme->varname = Render_LoadMesh (L"%s/themes/%s/" mesh_name L".*", app_path, theme->name); \
10 pmbaty 118
      if (theme->varname == -1) \
119
         MessageBox (NULL, LOCALIZE (L"Error_UnableToAddMeshD3DXLoadMeshFromXFailed"), LOCALIZE (L"FatalError"), MB_ICONERROR | MB_OK); \
120
   }
11 pmbaty 121
   #define THEME_LOAD_SPRITE(varname,sprite_name) \
122
   { \
123
      theme->varname = Render_LoadSprite (L"%s/themes/%s/" sprite_name L".*", app_path, theme->name); \
124
      if (theme->varname == -1) \
125
         MessageBox (NULL, LOCALIZE (L"Error_UnableToAddSpriteD3DXCreateSpriteFailed"), LOCALIZE (L"FatalError"), MB_ICONERROR | MB_OK); \
126
   }
10 pmbaty 127
   #define THEME_LOAD_PART(part_id,part_name) \
128
   { \
129
      theme->part_meshes[part_id] = -1; \
130
      if (options.want_hiquality) \
11 pmbaty 131
         theme->part_meshes[part_id] = Render_LoadMesh (L"%s/themes/%s/" part_name L"-hidef.*", app_path, theme->name); \
10 pmbaty 132
      if (theme->part_meshes[part_id] == -1) \
11 pmbaty 133
         theme->part_meshes[part_id] = Render_LoadMesh (L"%s/themes/%s/" part_name L".*", app_path, theme->name); \
10 pmbaty 134
      if (theme->part_meshes[part_id] == -1) \
135
         MessageBox (NULL, LOCALIZE (L"Error_UnableToAddMeshD3DXLoadMeshFromXFailed"), LOCALIZE (L"FatalError"), MB_ICONERROR | MB_OK); \
136
   }
137
 
81 pmbaty 138
   unsigned long file_size;
1 pmbaty 139
   char *desc_buffer;
140
   wchar_t filename[256];
141
   wchar_t section_name[32];
142
   wchar_t value[128];
143
   light_t light;
144
   void *inifile;
145
   int light_index;
146
   int light_count;
81 pmbaty 147
   int length;
148
   int pos;
1 pmbaty 149
   int red;
150
   int green;
151
   int blue;
152
   FILE *fp;
153
 
154
   // allocate space for and load its description
11 pmbaty 155
   swprintf_s (filename, WCHAR_SIZEOF (filename), L"%s/themes/%s/readme.txt", app_path, theme->name);
81 pmbaty 156
   _wfopen_s (&fp, filename, L"rb");
157
   if (fp != NULL)
1 pmbaty 158
   {
81 pmbaty 159
      fseek (fp, 0, SEEK_END); // seek at end of file
160
      file_size = ftell (fp); // get file size
161
      fseek (fp, 0, SEEK_SET); // and rewind
162
      if (file_size > 0)
163
      {
164
         desc_buffer = (char *) SAFE_malloc (file_size, sizeof (char), false);
165
         fread (desc_buffer, file_size, 1, fp); // read file in whole in ASCII form
166
         fclose (fp); // close it and then convert it to wide char
167
         theme->description = (wchar_t *) SAFE_malloc (file_size, sizeof (wchar_t), false);
168
         ConvertToWideChar (theme->description, file_size, desc_buffer);
169
         SAFE_free ((void **) &desc_buffer); // we no longer need the ASCII buffer
170
      }
171
      else
172
         theme->description = NULL; // this theme has no description
173
      fclose (fp);
1 pmbaty 174
   }
175
 
176
   // load its background image
11 pmbaty 177
   THEME_LOAD_STEP (0) Background_LoadImage (&theme->bg, L"%s/themes/%s/background/background.*", app_path, theme->name);
1 pmbaty 178
 
179
   // load board meshes
11 pmbaty 180
   THEME_LOAD_STEP (1) THEME_LOAD_MESH (board_meshindex, L"models/board");
181
   THEME_LOAD_STEP (2) THEME_LOAD_MESH (table_meshindex, L"models/table");
182
   THEME_LOAD_STEP (3) THEME_LOAD_MESH (trim_meshindex, L"models/trim");
183
   THEME_LOAD_STEP (4) THEME_LOAD_MESH (tile_meshindex, L"models/tile");
1 pmbaty 184
 
185
   // load part meshes
11 pmbaty 186
   THEME_LOAD_STEP (5) THEME_LOAD_PART (PART_KING, L"models/king");
187
   THEME_LOAD_STEP (6) THEME_LOAD_PART (PART_QUEEN, L"models/queen");
188
   THEME_LOAD_STEP (7) THEME_LOAD_PART (PART_BISHOP, L"models/bishop");
189
   THEME_LOAD_STEP (8) THEME_LOAD_PART (PART_KNIGHT, L"models/knight");
190
   THEME_LOAD_STEP (9) THEME_LOAD_PART (PART_ROOK, L"models/rook");
191
   THEME_LOAD_STEP (10) THEME_LOAD_PART (PART_PAWN, L"models/pawn");
1 pmbaty 192
 
193
   // load part textures
11 pmbaty 194
   THEME_LOAD_STEP (11) THEME_LOAD_TEXTURE (part_colors[COLOR_BLACK].texture, L"models/part-black");
195
   THEME_LOAD_STEP (12) THEME_LOAD_TEXTURE (part_colors[COLOR_WHITE].texture, L"models/part-white");
1 pmbaty 196
 
197
   // load board, table, grid and trim textures
11 pmbaty 198
   THEME_LOAD_STEP (13) THEME_LOAD_TEXTURE (board_texture, L"models/board");
199
   THEME_LOAD_STEP (14) THEME_LOAD_TEXTURE (table_texture, L"models/table");
200
   THEME_LOAD_STEP (15) THEME_LOAD_TEXTURE (trim_texture, L"models/trim");
201
   THEME_LOAD_STEP (16) THEME_LOAD_TEXTURE (grid_texture, L"models/grid");
1 pmbaty 202
 
203
   // load overlay textures
11 pmbaty 204
   THEME_LOAD_STEP (17) THEME_LOAD_TEXTURE (shadow_textureindex, L"shadow");
205
   THEME_LOAD_STEP (18) THEME_LOAD_TEXTURE (hovered_textureindex, L"hovered");
206
   THEME_LOAD_STEP (19) THEME_LOAD_TEXTURE (check_textureindex, L"check");
207
   THEME_LOAD_STEP (20) THEME_LOAD_TEXTURE (threat_textureindex, L"takeable");
208
   THEME_LOAD_STEP (21) THEME_LOAD_TEXTURE (lastmovesource_textureindex, L"lastmovesource");
209
   THEME_LOAD_STEP (22) THEME_LOAD_TEXTURE (lastmovetarget_textureindex, L"lastmovetarget");
210
   THEME_LOAD_STEP (23) THEME_LOAD_TEXTURE (selected_textureindex, L"selected");
211
   THEME_LOAD_STEP (24) THEME_LOAD_TEXTURE (possiblemove_textureindex, L"possiblemove");
212
   THEME_LOAD_STEP (25) THEME_LOAD_TEXTURE (takeable_textureindex, L"takeable");
1 pmbaty 213
 
214
   // load sprites
11 pmbaty 215
   THEME_LOAD_STEP (26) THEME_LOAD_SPRITE (flatsprites[COLOR_WHITE][PART_PAWN], L"parts/pawn-white");
216
   THEME_LOAD_STEP (27) THEME_LOAD_SPRITE (flatsprites[COLOR_WHITE][PART_ROOK], L"parts/rook-white");
217
   THEME_LOAD_STEP (28) THEME_LOAD_SPRITE (flatsprites[COLOR_WHITE][PART_KNIGHT], L"parts/knight-white");
218
   THEME_LOAD_STEP (29) THEME_LOAD_SPRITE (flatsprites[COLOR_WHITE][PART_BISHOP], L"parts/bishop-white");
219
   THEME_LOAD_STEP (30) THEME_LOAD_SPRITE (flatsprites[COLOR_WHITE][PART_QUEEN], L"parts/queen-white");
220
   THEME_LOAD_STEP (31) THEME_LOAD_SPRITE (flatsprites[COLOR_WHITE][PART_KING], L"parts/king-white");
221
   THEME_LOAD_STEP (32) THEME_LOAD_SPRITE (flatsprites[COLOR_BLACK][PART_PAWN], L"parts/pawn-black");
222
   THEME_LOAD_STEP (33) THEME_LOAD_SPRITE (flatsprites[COLOR_BLACK][PART_ROOK], L"parts/rook-black");
223
   THEME_LOAD_STEP (34) THEME_LOAD_SPRITE (flatsprites[COLOR_BLACK][PART_KNIGHT], L"parts/knight-black");
224
   THEME_LOAD_STEP (35) THEME_LOAD_SPRITE (flatsprites[COLOR_BLACK][PART_BISHOP], L"parts/bishop-black");
225
   THEME_LOAD_STEP (36) THEME_LOAD_SPRITE (flatsprites[COLOR_BLACK][PART_QUEEN], L"parts/queen-black");
226
   THEME_LOAD_STEP (37) THEME_LOAD_SPRITE (flatsprites[COLOR_BLACK][PART_KING], L"parts/king-black");
227
   THEME_LOAD_STEP (38) THEME_LOAD_SPRITE (lastmovesource_spriteindex, L"lastmovesource");
228
   THEME_LOAD_STEP (39) THEME_LOAD_SPRITE (lastmovetarget_spriteindex, L"lastmovetarget");
1 pmbaty 229
 
230
   // load the flat pieces textures
11 pmbaty 231
   THEME_LOAD_STEP (40) THEME_LOAD_TEXTURE (flattextures[COLOR_WHITE][PART_PAWN], L"parts/pawn-white");
232
   THEME_LOAD_STEP (41) THEME_LOAD_TEXTURE (flattextures[COLOR_WHITE][PART_ROOK], L"parts/rook-white");
233
   THEME_LOAD_STEP (42) THEME_LOAD_TEXTURE (flattextures[COLOR_WHITE][PART_KNIGHT], L"parts/knight-white");
234
   THEME_LOAD_STEP (43) THEME_LOAD_TEXTURE (flattextures[COLOR_WHITE][PART_BISHOP], L"parts/bishop-white");
235
   THEME_LOAD_STEP (44) THEME_LOAD_TEXTURE (flattextures[COLOR_WHITE][PART_QUEEN], L"parts/queen-white");
236
   THEME_LOAD_STEP (45) THEME_LOAD_TEXTURE (flattextures[COLOR_WHITE][PART_KING], L"parts/king-white");
237
   THEME_LOAD_STEP (46) THEME_LOAD_TEXTURE (flattextures[COLOR_BLACK][PART_PAWN], L"parts/pawn-black");
238
   THEME_LOAD_STEP (47) THEME_LOAD_TEXTURE (flattextures[COLOR_BLACK][PART_ROOK], L"parts/rook-black");
239
   THEME_LOAD_STEP (48) THEME_LOAD_TEXTURE (flattextures[COLOR_BLACK][PART_KNIGHT], L"parts/knight-black");
240
   THEME_LOAD_STEP (49) THEME_LOAD_TEXTURE (flattextures[COLOR_BLACK][PART_BISHOP], L"parts/bishop-black");
241
   THEME_LOAD_STEP (50) THEME_LOAD_TEXTURE (flattextures[COLOR_BLACK][PART_QUEEN], L"parts/queen-black");
242
   THEME_LOAD_STEP (51) THEME_LOAD_TEXTURE (flattextures[COLOR_BLACK][PART_KING], L"parts/king-black");
1 pmbaty 243
 
244
   //////////////////////////////
245
   // read scene lights from file
246
 
11 pmbaty 247
   THEME_LOAD_STEP (52)
1 pmbaty 248
   {
249
      theme->illum.lights = NULL; // no lights for the scene so far
250
      theme->illum.light_count = 0; // reset the known lights count
251
 
252
      // open the INI file
11 pmbaty 253
      swprintf_s (filename, WCHAR_SIZEOF (filename), L"%s/themes/%s/lights.ini", app_path, theme->name);
1 pmbaty 254
      inifile = INIFile_LoadINIFile (filename);
255
 
256
      // read the global light values and the parts illumination values
257
      swscanf_s (INIFile_ReadEntryAsString (inifile, L"global", L"ambient light", L"50, 50, 50"), L"%d , %d , %d", &red, &green, &blue);
258
      theme->illum.ambient_light = RGB_TO_RGBACOLOR (red, green, blue);
259
      theme->board_material = Render_MaterialIndexOf (INIFile_ReadEntryAsString (inifile, L"global", L"board material", L"default"));
260
      theme->table_material = Render_MaterialIndexOf (INIFile_ReadEntryAsString (inifile, L"global", L"table material", L"default"));
261
      theme->trim_material = -1; // TODO: make customizable
262
      theme->reflection_alpha = (unsigned char) INIFile_ReadEntryAsLong (inifile, L"global", L"table reflection alpha", 50);
263
      theme->part_colors[COLOR_BLACK].material = Render_MaterialIndexOf (INIFile_ReadEntryAsString (inifile, L"global", L"black material", L"default"));
264
      theme->part_colors[COLOR_WHITE].material = Render_MaterialIndexOf (INIFile_ReadEntryAsString (inifile, L"global", L"white material", L"default"));
265
 
266
      // figure out the number of lights in this file
267
      light_count = INIFile_GetNumberOfSections (inifile) - 1; // deduce the [global] section
268
 
269
      // for each light section...
270
      for (light_index = 0; light_index < light_count; light_index++)
271
      {
272
         swprintf_s (section_name, WCHAR_SIZEOF (section_name), L"light %d", light_index + 1); // build section name
273
         memset (&light, 0, sizeof (light)); // wipe out temporary light structure
274
 
275
         // get this light parameters
276
         wcscpy_s (value, WCHAR_SIZEOF (value), INIFile_ReadEntryAsString (inifile, section_name, L"type", L""));
277
         if (_wcsicmp (value, L"directional") == 0)
278
            light.type = LIGHT_DIRECTIONAL;
279
         else if (_wcsicmp (value, L"point") == 0)
280
            light.type = LIGHT_POINT;
281
         else if (_wcsicmp (value, L"spot") == 0)
282
            light.type = LIGHT_SPOT;
283
         else
284
            continue; // on invalid data, skip this section
285
         swscanf_s (INIFile_ReadEntryAsString (inifile, section_name, L"color", L"0, 0, 0"), L"%d , %d , %d", &red, &green, &blue);
286
         light.color = RGB_TO_RGBACOLOR (red, green, blue);
287
         swscanf_s (INIFile_ReadEntryAsString (inifile, section_name, L"source", L"0.0, 0.0, 0.0"), L"%f , %f , %f", &light.pos_x, &light.pos_y, &light.pos_z);
288
         swscanf_s (INIFile_ReadEntryAsString (inifile, section_name, L"direction", L"0.0, 0.0, 0.0"), L"%f , %f , %f", &light.direction_x, &light.direction_y, &light.direction_z);
289
         light.range = (float) INIFile_ReadEntryAsDouble (inifile, section_name, L"range", 0.0);
290
         swscanf_s (INIFile_ReadEntryAsString (inifile, section_name, L"attenuation", L"0.0, 0.0, 0.0"), L"%f , %f , %f", &light.attenuation_constant, &light.attenuation_proportional, &light.attenuation_square);
291
         swscanf_s (INIFile_ReadEntryAsString (inifile, section_name, L"cone", L"0.0, 0.0"), L"%f , %f", &light.cone_inner, &light.cone_outer);
292
 
293
         // reallocate the lights array to hold one light more
294
         theme->illum.lights = (light_t *) SAFE_realloc (theme->illum.lights, theme->illum.light_count, theme->illum.light_count + 1, sizeof (light_t), false);
295
         memcpy (&theme->illum.lights[theme->illum.light_count], &light, sizeof (light_t)); // copy light in place
296
         theme->illum.light_count++; // we know now one light more
297
      }
298
 
299
      // close the INI file
300
      INIFile_FreeINIFile (inifile);
301
   }
302
 
303
   theme->load_index++; // this bit has been loaded
304
   if (theme->load_index == 53)
305
      theme->is_loaded = true; // when everything has been loaded, remember this theme is now usable
306
 
307
   return; // finished, theme data is loaded a bit more
10 pmbaty 308
 
309
   #undef THEME_LOAD_PART
11 pmbaty 310
   #undef THEME_LOAD_SPRITE
10 pmbaty 311
   #undef THEME_LOAD_MESH
11 pmbaty 312
   #undef THEME_LOAD_TEXTURE
313
   #undef THEME_LOAD_STEP
1 pmbaty 314
}
315
 
316
 
11 pmbaty 317
void Background_LoadImage (backgroundsprite_t *bg, const wchar_t *fmt, ...)
1 pmbaty 318
{
319
   // this function loads the specified background image for the specified theme
320
 
11 pmbaty 321
   static wchar_t bgimage_pathname[MAX_PATH];
322
   va_list argptr;
1 pmbaty 323
   int width;
324
   int height;
325
 
11 pmbaty 326
   // concatenate all the arguments in one string
327
   va_start (argptr, fmt);
328
   wvsprintf (bgimage_pathname, fmt, argptr);
329
   va_end (argptr);
330
 
1 pmbaty 331
   // does the background file look like an image we can comprehend ? try to get its width and height
11 pmbaty 332
   if (GetImageSize (bgimage_pathname, &width, &height))
1 pmbaty 333
   {
334
      // yes it is, so load it as our background and round its size to the highest multiple of two
335
      bg->sprite_width = 2;
336
      while (bg->sprite_width < width)
337
         bg->sprite_width *= 2; // save them rounded to the next power of two
338
      bg->sprite_height = 2;
339
      while (bg->sprite_height < height)
340
         bg->sprite_height *= 2; // save them rounded to the next power of two
341
 
11 pmbaty 342
      bg->sprite_index = Render_LoadSprite (bgimage_pathname); // load texture as sprite
1 pmbaty 343
   }
344
   else
345
   {
346
      // no it's not, so load a default texture
11 pmbaty 347
      bg->sprite_index = Render_LoadSprite (L"%s/data/notexture.png", app_path);
1 pmbaty 348
      bg->sprite_width = 2;
349
      bg->sprite_height = 2;
350
   }
351
 
352
   return; // finished, theme background image is loaded
353
}