Subversion Repositories Games.Chess Giants

Rev

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

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