/** * Load a platform sprites block from a RCD file. * @param rcd_file RCD file used for loading. * @param sprites Map of already loaded sprites. * @return Loading was successful. */ bool SpriteManager::LoadPLAT(RcdFileReader *rcd_file, const ImageMap &sprites) { if (rcd_file->version != 2 || rcd_file->size != 2 + 2 + 2 + 2 * 4 + 12 * 4) return false; uint16 width = rcd_file->GetUInt16(); rcd_file->GetUInt16(); /// \todo Remove height from RCD block. uint16 type = rcd_file->GetUInt16(); if (type != 16) return false; // Only accept type 16 'wood'. SpriteStorage *ss = this->GetSpriteStore(width); if (ss == nullptr) return false; Platform *plat = &ss->platform; if (!LoadSpriteFromFile(rcd_file, sprites, &plat->flat[0])) return false; if (!LoadSpriteFromFile(rcd_file, sprites, &plat->flat[1])) return false; for (uint sprnum = 0; sprnum < lengthof(plat->ramp); sprnum++) { if (!LoadSpriteFromFile(rcd_file, sprites, &plat->ramp[sprnum])) return false; } for (uint sprnum = 0; sprnum < lengthof(plat->right_ramp); sprnum++) { if (!LoadSpriteFromFile(rcd_file, sprites, &plat->right_ramp[sprnum])) return false; } for (uint sprnum = 0; sprnum < lengthof(plat->left_ramp); sprnum++) { if (!LoadSpriteFromFile(rcd_file, sprites, &plat->left_ramp[sprnum])) return false; } return true; }
/** * Load slider bar sprite data. * @param rcd_file RCD file being loaded. * @param sprites Sprites loaded from this file. * @return Load was successful. * @todo Move widget_type further to the top in the RCD file block. */ bool GuiSprites::LoadGSLI(RcdFileReader *rcd_file, const ImageMap &sprites) { if (rcd_file->version != 1 || rcd_file->size != 3 * 1 + 2 + WSS_COUNT * 4) return false; uint8 min_length = rcd_file->GetUInt8(); uint8 stepsize = rcd_file->GetUInt8(); uint8 height = rcd_file->GetUInt8(); /* Select sprites to save to. */ uint16 tp = rcd_file->GetUInt16(); // Widget type. SliderSpriteData *sprdata = nullptr; bool shaded = false; switch (tp) { case 128: sprdata = &this->hor_slider; shaded = false; break; case 129: sprdata = &this->hor_slider; shaded = true; break; case 144: sprdata = &this->vert_slider; shaded = false; break; case 145: sprdata = &this->vert_slider; shaded = true; break; default: return false; } sprdata->min_bar_length = min_length; sprdata->stepsize = stepsize; sprdata->height = height; for (uint sprnum = 0; sprnum < WSS_COUNT; sprnum++) { if (shaded) { if (!LoadSpriteFromFile(rcd_file, sprites, &sprdata->shaded[sprnum])) return false; } else { if (!LoadSpriteFromFile(rcd_file, sprites, &sprdata->normal[sprnum])) return false; } } return true; }
/** * Load a track voxel. * @param rcd_file Data file being loaded. * @param length Length of the voxel (according to the file). * @param sprites Already loaded sprite blocks. * @return Loading was successful. */ bool TrackVoxel::Load(RcdFileReader *rcd_file, size_t length, const ImageMap &sprites) { if (length != 4 * 4 + 4 * 4 + 3 + 1) return false; for (uint i = 0; i < 4; i++) { if (!LoadSpriteFromFile(rcd_file, sprites, &this->back[i])) return false; } for (uint i = 0; i < 4; i++) { if (!LoadSpriteFromFile(rcd_file, sprites, &this->front[i])) return false; } this->dxyz.x = rcd_file->GetInt8(); this->dxyz.y = rcd_file->GetInt8(); this->dxyz.z = rcd_file->GetInt8(); this->flags = rcd_file->GetUInt8(); return true; }
/** * Load checkbox and radio button GUI sprites. * @param rcd_file RCD file being loaded. * @param sprites Sprites loaded from this file. * @return Load was successful. * @todo Load width and height from the RCD file too. */ bool GuiSprites::LoadGCHK(RcdFileReader *rcd_file, const ImageMap &sprites) { if (rcd_file->version != 1 || rcd_file->size != 2 + WCS_COUNT * 4) return false; /* Select sprites to save to. */ uint16 tp = rcd_file->GetUInt16(); // Widget type. CheckableWidgetSpriteData *sprdata = nullptr; switch (tp) { case 96: sprdata = &this->checkbox; break; case 112: sprdata = &this->radio_button; break; default: return false; } sprdata->width = 0; sprdata->height = 0; for (uint sprnum = 0; sprnum < WCS_COUNT; sprnum++) { ImageData *spr; if (!LoadSpriteFromFile(rcd_file, sprites, &spr)) return false; sprdata->sprites[sprnum] = spr; if (spr != nullptr) { sprdata->width = std::max(sprdata->width, spr->width); sprdata->height = std::max(sprdata->height, spr->height); } } return true; }
/** * Load the sprites of an animation. * @param rcd_file RCD file used for loading. * @param sprites Map of already loaded sprites. * @return Loading was successful. */ bool AnimationSprites::Load(RcdFileReader *rcd_file, const ImageMap &sprites) { const uint BASE_LENGTH = 2 + 1 + 2 + 2; size_t length = rcd_file->size; if (rcd_file->version != 1 || length < BASE_LENGTH) return false; this->width = rcd_file->GetUInt16(); this->person_type = DecodePersonType(rcd_file->GetUInt8()); if (this->person_type == PERSON_INVALID) return false; uint16 at = rcd_file->GetUInt16(); if (at < ANIM_BEGIN || at > ANIM_LAST) return false; this->anim_type = (AnimationType)at; this->frame_count = rcd_file->GetUInt16(); if (length != BASE_LENGTH + this->frame_count * 4) return false; this->sprites = new ImageData *[this->frame_count]; if (this->sprites == nullptr || this->frame_count == 0) return false; for (uint i = 0; i < this->frame_count; i++) { if (!LoadSpriteFromFile(rcd_file, sprites, &this->sprites[i])) return false; } return true; }
/** * Load a surface game block from a RCD file. * @param rcd_file RCD file used for loading. * @param sprites Map of already loaded sprites. * @return Loading was successful. */ bool SpriteManager::LoadSURF(RcdFileReader *rcd_file, const ImageMap &sprites) { if (rcd_file->version != 4 || rcd_file->size != 2 + 2 + 2 + 4 * NUM_SLOPE_SPRITES) return false; uint16 gt = rcd_file->GetUInt16(); // Ground type bytes. uint8 type = GTP_INVALID; if (gt == 16) type = GTP_GRASS0; if (gt == 17) type = GTP_GRASS1; if (gt == 18) type = GTP_GRASS2; if (gt == 19) type = GTP_GRASS3; if (gt == 32) type = GTP_DESERT; if (gt == 48) type = GTP_CURSOR_TEST; if (type == GTP_INVALID) return false; // Unknown type of ground. uint16 width = rcd_file->GetUInt16(); rcd_file->GetUInt16(); /// \todo Remove height from RCD block. SpriteStorage *ss = this->GetSpriteStore(width); if (ss == nullptr || type >= GTP_COUNT) return false; SurfaceData *sd = &ss->surface[type]; for (uint sprnum = 0; sprnum < NUM_SLOPE_SPRITES; sprnum++) { if (!LoadSpriteFromFile(rcd_file, sprites, &sd->surface[sprnum])) return false; } return true; }
/** * Load sprites of a GUI widget border. * @param rcd_file RCD file being loaded. * @param sprites Sprites loaded from this file. * @return Load was successful. */ bool GuiSprites::LoadGBOR(RcdFileReader *rcd_file, const ImageMap &sprites) { if (rcd_file->version != 1 || rcd_file->size != 2 + 8 * 1 + WBS_COUNT * 4) return false; /* Select sprites to save to. */ uint16 tp = rcd_file->GetUInt16(); // Widget type. BorderSpriteData *sprdata = nullptr; bool pressed = false; switch (tp) { case 32: sprdata = &this->titlebar; pressed = false; break; case 48: sprdata = &this->button; pressed = false; break; case 49: sprdata = &this->button; pressed = true; break; case 52: sprdata = &this->rounded_button; pressed = false; break; case 53: sprdata = &this->rounded_button; pressed = true; break; case 64: sprdata = &this->frame; pressed = false; break; case 68: sprdata = &this->panel; pressed = false; break; case 80: sprdata = &this->inset_frame; pressed = false; break; default: return false; } sprdata->border_top = rcd_file->GetUInt8(); sprdata->border_left = rcd_file->GetUInt8(); sprdata->border_right = rcd_file->GetUInt8(); sprdata->border_bottom = rcd_file->GetUInt8(); sprdata->min_width = rcd_file->GetUInt8(); sprdata->min_height = rcd_file->GetUInt8(); sprdata->hor_stepsize = rcd_file->GetUInt8(); sprdata->vert_stepsize = rcd_file->GetUInt8(); for (uint sprnum = 0; sprnum < WBS_COUNT; sprnum++) { if (pressed) { if (!LoadSpriteFromFile(rcd_file, sprites, &sprdata->pressed[sprnum])) return false; } else { if (!LoadSpriteFromFile(rcd_file, sprites, &sprdata->normal[sprnum])) return false; } } return true; }
/** * Load a displayed object block. * @param rcd_file RCD file used for loading. * @param sprites Map of already loaded sprites. * @return Loading was successful. */ bool SpriteManager::LoadBDIR(RcdFileReader *rcd_file, const ImageMap &sprites) { if (rcd_file->version != 1 || rcd_file->size != 2 + 4 * 4) return false; uint16 width = rcd_file->GetUInt16(); SpriteStorage *ss = this->GetSpriteStore(width); if (ss == nullptr) return false; DisplayedObject *dob = &ss->build_arrows; for (uint sprnum = 0; sprnum < lengthof(dob->sprites); sprnum++) { if (!LoadSpriteFromFile(rcd_file, sprites, &dob->sprites[sprnum])) return false; } return true; }
/** * Load scroll bar sprite data. * @param rcd_file RCD file being loaded. * @param sprites Sprites loaded from this file. * @return Load was successful. * @todo Move widget_type further to the top in the RCD file block. * @todo Add width of the scrollbar in the RCD file block. */ bool GuiSprites::LoadGSCL(RcdFileReader *rcd_file, const ImageMap &sprites) { if (rcd_file->version != 1 || rcd_file->size != 4 * 1 + 2 + WLS_COUNT * 4) return false; uint8 min_length_bar = rcd_file->GetUInt8(); uint8 stepsize_back = rcd_file->GetUInt8(); uint8 min_slider = rcd_file->GetUInt8(); uint8 stepsize_slider = rcd_file->GetUInt8(); /* Select sprites to save to. */ uint16 tp = rcd_file->GetUInt16(); // Widget type. ScrollbarSpriteData *sprdata = nullptr; bool shaded = false; bool vertical = false; switch (tp) { case 160: sprdata = &this->hor_scroll; shaded = false; vertical = false; break; case 161: sprdata = &this->hor_scroll; shaded = true; vertical = false; break; case 176: sprdata = &this->vert_scroll; shaded = false; vertical = true; break; case 177: sprdata = &this->vert_scroll; shaded = true; vertical = true; break; default: return false; } sprdata->min_length_all = min_length_bar; sprdata->stepsize_bar = stepsize_back; sprdata->min_length_slider = min_slider; sprdata->stepsize_slider = stepsize_slider; uint16 max_width = 0; uint16 max_height = 0; for (uint sprnum = 0; sprnum < WLS_COUNT; sprnum++) { ImageData *spr; if (!LoadSpriteFromFile(rcd_file, sprites, &spr)) return false; if (shaded) { sprdata->shaded[sprnum] = spr; } else { sprdata->normal[sprnum] = spr; } if (spr != nullptr) { max_width = std::max(max_width, spr->width); max_height = std::max(max_height, spr->height); } } sprdata->height = (vertical) ? max_width : max_height; return true; }
/** * Load a tile selection block from a RCD file. * @param rcd_file RCD file used for loading. * @param sprites Map of already loaded sprites. * @return Loading was successful. */ bool SpriteManager::LoadTSEL(RcdFileReader *rcd_file, const ImageMap &sprites) { if (rcd_file->version != 2 || rcd_file->size != 2 + 2 + 4 * NUM_SLOPE_SPRITES) return false; uint16 width = rcd_file->GetUInt16(); rcd_file->GetUInt16(); /// \todo Remove height from RCD block. SpriteStorage *ss = this->GetSpriteStore(width); if (ss == nullptr) return false; TileSelection *ts = &ss->tile_select; for (uint sprnum = 0; sprnum < NUM_SLOPE_SPRITES; sprnum++) { if (!LoadSpriteFromFile(rcd_file, sprites, &ts->surface[sprnum])) return false; } return true; }
/** * Load a support sprites block from a RCD file. * @param rcd_file RCD file used for loading. * @param sprites Map of already loaded sprites. * @return Loading was successful. */ bool SpriteManager::LoadSUPP(RcdFileReader *rcd_file, const ImageMap &sprites) { if (rcd_file->version != 1 || rcd_file->size != 2 + 2 + 2 + SSP_COUNT * 4) return false; uint16 type = rcd_file->GetUInt16(); if (type != 16) return false; // Only accept type 16 'wood'. uint16 width = rcd_file->GetUInt16(); rcd_file->GetUInt16(); /// \todo Remove height from RCD block. SpriteStorage *ss = this->GetSpriteStore(width); if (ss == nullptr) return false; Support *supp = &ss->support; for (uint sprnum = 0; sprnum < lengthof(supp->sprites); sprnum++) { if (!LoadSpriteFromFile(rcd_file, sprites, &supp->sprites[sprnum])) return false; } return true; }
/** * Load a path sprites block from a RCD file. * @param rcd_file RCD file used for loading. * @param sprites Map of already loaded sprites. * @return Loading was successful. */ bool SpriteManager::LoadTCOR(RcdFileReader *rcd_file, const ImageMap &sprites) { if (rcd_file->version != 2 || rcd_file->size != 2 + 2 + 4 * VOR_NUM_ORIENT * NUM_SLOPE_SPRITES) return false; uint16 width = rcd_file->GetUInt16(); rcd_file->GetUInt16(); /// \todo Remove height from RCD block. SpriteStorage *ss = this->GetSpriteStore(width); if (ss == nullptr) return false; TileCorners *tc = &ss->tile_corners; for (uint v = 0; v < VOR_NUM_ORIENT; v++) { for (uint sprnum = 0; sprnum < NUM_SLOPE_SPRITES; sprnum++) { if (!LoadSpriteFromFile(rcd_file, sprites, &tc->sprites[v][sprnum])) return false; } } return true; }
/** * Load a path sprites block from a RCD file. * @param rcd_file RCD file used for loading. * @param sprites Map of already loaded sprites. * @return Loading was successful. */ bool SpriteManager::LoadPATH(RcdFileReader *rcd_file, const ImageMap &sprites) { if (rcd_file->version != 1 || rcd_file->size != 2 + 2 + 2 + 4 * PATH_COUNT) return false; uint16 type = rcd_file->GetUInt16(); if (type != 16) return false; // Only 'concrete' paths exist. uint16 width = rcd_file->GetUInt16(); rcd_file->GetUInt16(); /// \todo Remove height from RCD block. SpriteStorage *ss = this->GetSpriteStore(width); if (ss == nullptr) return false; Path *path = &ss->path_sprites; for (uint sprnum = 0; sprnum < PATH_COUNT; sprnum++) { if (!LoadSpriteFromFile(rcd_file, sprites, &path->sprites[sprnum])) return false; } return true; }
/** * Load a path sprites block from a RCD file. * @param rcd_file RCD file used for loading. * @param sprites Map of already loaded sprites. * @return Loading was successful. */ bool SpriteManager::LoadFUND(RcdFileReader *rcd_file, const ImageMap &sprites) { if (rcd_file->version != 1 || rcd_file->size != 2 + 2 + 2 + 4 * 6) return false; uint16 tp = rcd_file->GetUInt16(); uint16 type = FDT_INVALID; if (tp == 16) type = FDT_GROUND; if (tp == 32) type = FDT_WOOD; if (tp == 48) type = FDT_BRICK; if (type == FDT_INVALID) return false; uint16 width = rcd_file->GetUInt16(); rcd_file->GetUInt16(); /// \todo Remove height from RCD block. SpriteStorage *ss = this->GetSpriteStore(width); if (ss == nullptr || type >= FDT_COUNT) return false; Foundation *fn = &ss->foundation[type]; for (uint sprnum = 0; sprnum < lengthof(fn->sprites); sprnum++) { if (!LoadSpriteFromFile(rcd_file, sprites, &fn->sprites[sprnum])) return false; } return true; }
/** * Load GUI slope selection sprites. * @param rcd_file RCD file being loaded. * @param sprites Sprites loaded from this file. * @param texts Texts loaded from this file. * @return Load was successful. */ bool GuiSprites::LoadGSLP(RcdFileReader *rcd_file, const ImageMap &sprites, const TextMap &texts) { const uint8 indices[] = {TSL_STRAIGHT_DOWN, TSL_STEEP_DOWN, TSL_DOWN, TSL_FLAT, TSL_UP, TSL_STEEP_UP, TSL_STRAIGHT_UP}; /* 'indices' entries of slope sprites, bends, banking, 4 triangle arrows, * 4 entries with rotation sprites, 2 button sprites, one entry with a text block. */ if (rcd_file->version != 7 || rcd_file->size != (lengthof(indices) + TBN_COUNT + TPB_COUNT + 4 + 2 + 2 + 1 + TC_END + 1 + WES_COUNT + 4 + 2) * 4 + 4) return false; for (uint i = 0; i < lengthof(indices); i++) { if (!LoadSpriteFromFile(rcd_file, sprites, &this->slope_select[indices[i]])) return false; } for (uint i = 0; i < TBN_COUNT; i++) { if (!LoadSpriteFromFile(rcd_file, sprites, &this->bend_select[i])) return false; } for (uint i = 0; i < TPB_COUNT; i++) { if (!LoadSpriteFromFile(rcd_file, sprites, &this->bank_select[i])) return false; } if (!LoadSpriteFromFile(rcd_file, sprites, &this->triangle_left)) return false; if (!LoadSpriteFromFile(rcd_file, sprites, &this->triangle_right)) return false; if (!LoadSpriteFromFile(rcd_file, sprites, &this->triangle_up)) return false; if (!LoadSpriteFromFile(rcd_file, sprites, &this->triangle_down)) return false; for (uint i = 0; i < 2; i++) { if (!LoadSpriteFromFile(rcd_file, sprites, &this->platform_select[i])) return false; } for (uint i = 0; i < 2; i++) { if (!LoadSpriteFromFile(rcd_file, sprites, &this->power_select[i])) return false; } if (!LoadSpriteFromFile(rcd_file, sprites, &this->disabled)) return false; for (uint i = 0; i < TC_END; i++) { if (!LoadSpriteFromFile(rcd_file, sprites, &this->compass[i])) return false; } if (!LoadSpriteFromFile(rcd_file, sprites, &this->bulldozer)) return false; for (uint i = 0; i < WES_COUNT; i++) { if (!LoadSpriteFromFile(rcd_file, sprites, &this->weather[i])) return false; } if (!LoadSpriteFromFile(rcd_file, sprites, &this->rot_2d_pos)) return false; if (!LoadSpriteFromFile(rcd_file, sprites, &this->rot_2d_neg)) return false; if (!LoadSpriteFromFile(rcd_file, sprites, &this->rot_3d_pos)) return false; if (!LoadSpriteFromFile(rcd_file, sprites, &this->rot_3d_neg)) return false; if (!LoadSpriteFromFile(rcd_file, sprites, &this->close_sprite)) return false; if (!LoadSpriteFromFile(rcd_file, sprites, &this->dot_sprite)) return false; if (!LoadTextFromFile(rcd_file, texts, &this->text)) return false; _language.RegisterStrings(*this->text, _gui_strings_table, STR_GUI_START); return true; }