static inline byte CalcOldVarLen(OldChunkType type) { static const byte type_mem_size[] = {0, 1, 1, 2, 2, 4, 4, 8}; byte length = GB(type, 8, 8); assert(length != 0 && length < lengthof(type_mem_size)); return type_mem_size[length]; }
/** * Change the service interval of a vehicle * @param tile unused * @param flags type of operation * @param p1 vehicle ID that is being service-interval-changed * @param p2 bitmask * - p2 = (bit 0-15) - new service interval * - p2 = (bit 16) - service interval is custom flag * - p2 = (bit 17) - service interval is percentage flag * @param text unused * @return the cost of this operation or an error */ CommandCost CmdChangeServiceInt(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { Vehicle *v = Vehicle::GetIfValid(p1); if (v == NULL || !v->IsPrimaryVehicle()) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; const Company *company = Company::Get(v->owner); bool iscustom = HasBit(p2, 16); bool ispercent = iscustom ? HasBit(p2, 17) : company->settings.vehicle.servint_ispercent; uint16 serv_int; if (iscustom) { serv_int = GB(p2, 0, 16); if (serv_int != GetServiceIntervalClamped(serv_int, ispercent)) return CMD_ERROR; } else { serv_int = CompanyServiceInterval(company, v->type); } if (flags & DC_EXEC) { v->SetServiceInterval(serv_int); v->SetServiceIntervalIsCustom(iscustom); v->SetServiceIntervalIsPercent(ispercent); SetWindowDirty(WC_VEHICLE_DETAILS, v->index); } return CommandCost(); }
void DrawHillyLandTile(const TileInfo *ti) { if (ti->tileh != SLOPE_FLAT) { DrawGroundSprite(SPR_FLAT_ROUGH_LAND + SlopeToSpriteOffset(ti->tileh), PAL_NONE); } else { DrawGroundSprite(_landscape_clear_sprites_rough[GB(TileHash(ti->x, ti->y), 0, 3)], PAL_NONE); } }
/** * Add or remove waiting times from an order. * @param tile Not used. * @param flags Operation to perform. * @param p1 Various bitstuffed elements * - p1 = (bit 0-19) - Vehicle with the orders to change. * - p1 = (bit 20-27) - Order index to modify. * - p1 = (bit 28) - Whether to change the waiting time or the travelling * time. * @param p2 The amount of time to wait. * - p2 = (bit 0-15) - Waiting or travelling time as specified by p1 bit 28 * @param text unused * @return the cost of this operation or an error */ CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { VehicleID veh = GB(p1, 0, 20); Vehicle *v = Vehicle::GetIfValid(veh); if (v == NULL || !v->IsPrimaryVehicle()) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; VehicleOrderID order_number = GB(p1, 20, 8); Order *order = v->GetOrder(order_number); if (order == NULL || order->IsType(OT_IMPLICIT)) return CMD_ERROR; bool is_journey = HasBit(p1, 28); int wait_time = order->wait_time; int travel_time = order->travel_time; if (is_journey) { travel_time = GB(p2, 0, 16); } else { wait_time = GB(p2, 0, 16); } if (wait_time != order->wait_time) { switch (order->GetType()) { case OT_GOTO_STATION: if (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) return_cmd_error(STR_ERROR_TIMETABLE_NOT_STOPPING_HERE); break; case OT_CONDITIONAL: break; default: return_cmd_error(STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS); } } if (travel_time != order->travel_time && order->IsType(OT_CONDITIONAL)) return CMD_ERROR; if (flags & DC_EXEC) { if (wait_time != order->wait_time) ChangeTimetable(v, order_number, wait_time, false); if (travel_time != order->travel_time) ChangeTimetable(v, order_number, travel_time, true); } return CommandCost(); }
/** * Make a random tree tile of the given tile * * Create a new tree-tile for the given tile. The second parameter is used for * randomness like type and number of trees. * * @param tile The tile to make a tree-tile from * @param r The randomness value from a Random() value */ static void PlaceTree(TileIndex tile, uint32 r) { TreeType tree = GetRandomTreeType(tile, GB(r, 24, 8)); if (tree != TREE_INVALID) { PlantTreesOnTile(tile, tree, GB(r, 22, 2), min(GB(r, 16, 3), 6)); /* Rerandomize ground, if neither snow nor shore */ TreeGround ground = GetTreeGround(tile); if (ground != TREE_GROUND_SNOW_DESERT && ground != TREE_GROUND_ROUGH_SNOW && ground != TREE_GROUND_SHORE) { SetTreeGroundDensity(tile, (TreeGround)GB(r, 28, 1), 3); } /* Set the counter to a random start value */ SetTreeCounter(tile, (TreeGround)GB(r, 24, 4)); } }
static void AnimationControl(TileIndex tile, uint16 random_bits) { const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile)); if (HasBit(hs->callback_mask, CBM_HOUSE_ANIMATION_START_STOP)) { uint32 param = (hs->extra_flags & SYNCHRONISED_CALLBACK_1B) ? (GB(Random(), 0, 16) | random_bits << 16) : Random(); HouseAnimationBase::ChangeAnimationFrame(CBID_HOUSE_ANIMATION_START_STOP, hs, Town::GetByTile(tile), tile, param, 0); } }
void CcRoadDepot(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) { if (result.Failed()) return; DiagDirection dir = (DiagDirection)GB(p1, 0, 2); if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_SPLAT_OTHER, tile); if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); ConnectRoadToStructure(tile, dir); }
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) { switch (widget) { case AIC_WIDGET_LIST: this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; size->height = GB(this->GetWidget<NWidgetCore>(widget)->widget_data, MAT_ROW_START, MAT_ROW_BITS) * this->line_height; break; } }
/** * Copy and convert old custom names to UTF-8. * They were all stored in a 512 by 32 (200 by 24 for TTO) long string array * and are now stored with stations, waypoints and other places with names. * @param id the StringID of the custom name to clone. * @return the clones custom name. */ char *CopyFromOldName(StringID id) { /* Is this name an (old) custom name? */ if (GB(id, 11, 5) != 15) return NULL; if (CheckSavegameVersion(37)) { /* Old names were 24/32 characters long, so 128 characters should be * plenty to allow for expansion when converted to UTF-8. */ char tmp[128]; uint offs = _savegame_type == SGT_TTO ? 24 * GB(id, 0, 8) : 32 * GB(id, 0, 9); const char *strfrom = &_old_name_array[offs]; char *strto = tmp; for (; *strfrom != '\0'; strfrom++) { WChar c = (byte)*strfrom; /* Map from non-ISO8859-15 characters to UTF-8. */ switch (c) { case 0xA4: c = 0x20AC; break; // Euro case 0xA6: c = 0x0160; break; // S with caron case 0xA8: c = 0x0161; break; // s with caron case 0xB4: c = 0x017D; break; // Z with caron case 0xB8: c = 0x017E; break; // z with caron case 0xBC: c = 0x0152; break; // OE ligature case 0xBD: c = 0x0153; break; // oe ligature case 0xBE: c = 0x0178; break; // Y with diaresis default: break; } /* Check character will fit into our buffer. */ if (strto + Utf8CharLen(c) > lastof(tmp)) break; strto += Utf8Encode(strto, c); } /* Terminate the new string and copy it back to the name array */ *strto = '\0'; return strdup(tmp); } else { /* Name will already be in UTF-8. */ return strdup(&_old_name_array[32 * GB(id, 0, 9)]); } }
/** * Actually build the object. * @param type The type of object to build. * @param tile The tile to build the northern tile of the object on. * @param owner The owner of the object. * @param town Town the tile is related with. * @param view The view for the object. * @pre All preconditions for building the object at that location * are met, e.g. slope and clearness of tiles are checked. */ void BuildObject(ObjectType type, TileIndex tile, CompanyID owner, Town *town, uint8 view) { const ObjectSpec *spec = ObjectSpec::Get(type); TileArea ta(tile, GB(spec->size, HasBit(view, 0) ? 4 : 0, 4), GB(spec->size, HasBit(view, 0) ? 0 : 4, 4)); Object *o = new Object(); o->type = type; o->location = ta; o->town = town == NULL ? CalcClosestTownFromTile(tile) : town; o->build_date = _date; o->view = view; /* If nothing owns the object, the colour will be random. Otherwise * get the colour from the company's livery settings. */ if (owner == OWNER_NONE) { o->colour = Random(); } else { const Livery *l = Company::Get(owner)->livery; o->colour = l->colour1 + l->colour2 * 16; } /* If the object wants only one colour, then give it that colour. */ if ((spec->flags & OBJECT_FLAG_2CC_COLOUR) == 0) o->colour &= 0xF; if (HasBit(spec->callback_mask, CBM_OBJ_COLOUR)) { uint16 res = GetObjectCallback(CBID_OBJECT_COLOUR, o->colour, 0, spec, o, tile); if (res != CALLBACK_FAILED) { if (res >= 0x100) ErrorUnknownCallbackResult(spec->grf_prop.grffile->grfid, CBID_OBJECT_COLOUR, res); o->colour = GB(res, 0, 8); } } assert(o->town != NULL); TILE_AREA_LOOP(t, ta) { WaterClass wc = (IsWaterTile(t) ? GetWaterClass(t) : WATER_CLASS_INVALID); /* Update company infrastructure counts for objects build on canals owned by nobody. */ if (wc == WATER_CLASS_CANAL && owner != OWNER_NONE && (IsTileOwner(tile, OWNER_NONE) || IsTileOwner(tile, OWNER_WATER))) { Company::Get(owner)->infrastructure.water++; DirtyCompanyInfrastructureWindows(owner); } MakeObject(t, owner, o->index, wc, Random()); MarkTileDirtyByTile(t); }
/** * Copy and convert old custom names to UTF-8. * They were all stored in a 512 by 32 (200 by 24 for TTO) long string array * and are now stored with stations, waypoints and other places with names. * @param id the StringID of the custom name to clone. * @return the clones custom name. */ char *CopyFromOldName(StringID id) { /* Is this name an (old) custom name? */ if (GetStringTab(id) != TEXT_TAB_OLD_CUSTOM) return NULL; if (IsSavegameVersionBefore(SLV_37)) { /* Allow for expansion when converted to UTF-8. */ char tmp[LEN_OLD_STRINGS * MAX_CHAR_LENGTH]; uint offs = _savegame_type == SGT_TTO ? LEN_OLD_STRINGS_TTO * GB(id, 0, 8) : LEN_OLD_STRINGS * GB(id, 0, 9); const char *strfrom = &_old_name_array[offs]; char *strto = tmp; for (; *strfrom != '\0'; strfrom++) { WChar c = (byte)*strfrom; /* Map from non-ISO8859-15 characters to UTF-8. */ switch (c) { case 0xA4: c = 0x20AC; break; // Euro case 0xA6: c = 0x0160; break; // S with caron case 0xA8: c = 0x0161; break; // s with caron case 0xB4: c = 0x017D; break; // Z with caron case 0xB8: c = 0x017E; break; // z with caron case 0xBC: c = 0x0152; break; // OE ligature case 0xBD: c = 0x0153; break; // oe ligature case 0xBE: c = 0x0178; break; // Y with diaresis default: break; } /* Check character will fit into our buffer. */ if (strto + Utf8CharLen(c) > lastof(tmp)) break; strto += Utf8Encode(strto, c); } /* Terminate the new string and copy it back to the name array */ *strto = '\0'; return stredup(tmp); } else { /* Name will already be in UTF-8. */ return stredup(&_old_name_array[LEN_OLD_STRINGS * GB(id, 0, 9)]); } }
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) { if (widget == AIL_WIDGET_LIST) { this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; resize->width = 1; resize->height = this->line_height; size->height = GB(this->GetWidget<NWidgetCore>(widget)->widget_data, MAT_ROW_START, MAT_ROW_BITS) * this->line_height; } }
/** * Ask a goal related question * @param tile unused. * @param flags type of operation * @param p1 various bitstuffed elements * - p1 = (bit 0 - 15) - Unique ID to use for this question. * - p1 = (bit 16 - 23) - Company for which this question is. * @param p2 Buttons of the question. * @param text Text of the question. * @return the cost of this operation or an error */ CommandCost CmdGoalQuestion(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { uint16 uniqueid = (GoalType)GB(p1, 0, 16); CompanyID company = (CompanyID)GB(p1, 16, 8); byte type = GB(p1, 24, 8); if (_current_company != OWNER_DEITY) return CMD_ERROR; if (StrEmpty(text)) return CMD_ERROR; if (company != INVALID_COMPANY && !Company::IsValidID(company)) return CMD_ERROR; if (CountBits(p2) < 1 || CountBits(p2) > 3) return CMD_ERROR; if (p2 >= (1 << GOAL_QUESTION_BUTTON_COUNT)) return CMD_ERROR; if (type >= GOAL_QUESTION_TYPE_COUNT) return CMD_ERROR; if (flags & DC_EXEC) { if ((company != INVALID_COMPANY && company == _local_company) || (company == INVALID_COMPANY && Company::IsValidID(_local_company))) ShowGoalQuestion(uniqueid, type, p2, text); } return CommandCost(); }
/** * Package a 64 bits integer in the packet. * @param data The data to send. */ void Packet::Send_uint64(uint64 data) { assert(this->size < SEND_MTU - sizeof(data)); this->buffer[this->size++] = GB(data, 0, 8); this->buffer[this->size++] = GB(data, 8, 8); this->buffer[this->size++] = GB(data, 16, 8); this->buffer[this->size++] = GB(data, 24, 8); this->buffer[this->size++] = GB(data, 32, 8); this->buffer[this->size++] = GB(data, 40, 8); this->buffer[this->size++] = GB(data, 48, 8); this->buffer[this->size++] = GB(data, 56, 8); }
bool NewHouseTileLoop(TileIndex tile) { const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile)); if (GetHouseProcessingTime(tile) > 0) { DecHouseProcessingTime(tile); return true; } TriggerHouse(tile, HOUSE_TRIGGER_TILE_LOOP); if (hs->building_flags & BUILDING_HAS_1_TILE) TriggerHouse(tile, HOUSE_TRIGGER_TILE_LOOP_TOP); if (HasBit(hs->callback_mask, CBM_HOUSE_ANIMATION_START_STOP)) { /* If this house is marked as having a synchronised callback, all the * tiles will have the callback called at once, rather than when the * tile loop reaches them. This should only be enabled for the northern * tile, or strange things will happen (here, and in TTDPatch). */ if (hs->extra_flags & SYNCHRONISED_CALLBACK_1B) { uint16 random = GB(Random(), 0, 16); if (hs->building_flags & BUILDING_HAS_1_TILE) AnimationControl(tile, random); if (hs->building_flags & BUILDING_2_TILES_Y) AnimationControl(TILE_ADDXY(tile, 0, 1), random); if (hs->building_flags & BUILDING_2_TILES_X) AnimationControl(TILE_ADDXY(tile, 1, 0), random); if (hs->building_flags & BUILDING_HAS_4_TILES) AnimationControl(TILE_ADDXY(tile, 1, 1), random); } else { AnimationControl(tile, 0); } } /* Check callback 21, which determines if a house should be destroyed. */ if (HasBit(hs->callback_mask, CBM_HOUSE_DESTRUCTION)) { uint16 callback_res = GetHouseCallback(CBID_HOUSE_DESTRUCTION, 0, 0, GetHouseType(tile), Town::GetByTile(tile), tile); if (callback_res != CALLBACK_FAILED && GB(callback_res, 0, 8) > 0) { ClearTownHouse(Town::GetByTile(tile), tile); return false; } } SetHouseProcessingTime(tile, hs->processing_time); MarkTileDirtyByTile(tile); return true; }
Sprite *Blitter_32bppSimple::Encode(SpriteLoader::Sprite *sprite, AllocatorProc *allocator) { Blitter_32bppSimple::Pixel *dst; Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + sprite->height * sprite->width * sizeof(*dst)); dest_sprite->height = sprite->height; dest_sprite->width = sprite->width; dest_sprite->x_offs = sprite->x_offs; dest_sprite->y_offs = sprite->y_offs; dst = (Blitter_32bppSimple::Pixel *)dest_sprite->data; SpriteLoader::CommonPixel *src = (SpriteLoader::CommonPixel *)sprite->data; for (int i = 0; i < sprite->height * sprite->width; i++) { if (src->m == 0) { dst[i].r = src->r; dst[i].g = src->g; dst[i].b = src->b; dst[i].a = src->a; dst[i].m = 0; dst[i].v = 0; } else { /* Get brightest value */ uint8 rgb_max = max(src->r, max(src->g, src->b)); /* Black pixel (8bpp or old 32bpp image), so use default value */ if (rgb_max == 0) rgb_max = DEFAULT_BRIGHTNESS; dst[i].v = rgb_max; /* Pre-convert the mapping channel to a RGB value */ uint colour = this->AdjustBrightness(this->LookupColourInPalette(src->m), dst[i].v); dst[i].r = GB(colour, 16, 8); dst[i].g = GB(colour, 8, 8); dst[i].b = GB(colour, 0, 8); dst[i].a = src->a; dst[i].m = src->m; } src++; } return dest_sprite; }
static void AnimationControl(TileIndex tile, uint16 random_bits) { const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile)); if (HasBit(hs->callback_mask, CBM_HOUSE_ANIMATION_START_STOP)) { uint32 param = (hs->extra_flags & SYNCHRONISED_CALLBACK_1B) ? (GB(Random(), 0, 16) | random_bits << 16) : Random(); uint16 callback_res = GetHouseCallback(CBID_HOUSE_ANIMATION_START_STOP, param, 0, GetHouseType(tile), Town::GetByTile(tile), tile); if (callback_res != CALLBACK_FAILED) ChangeHouseAnimationFrame(hs->grffile, tile, callback_res); } }
/** * Copy tile area into clipboard. * * @param tile Northern tile of the area to copy. * @param flags Command flags. * @param p1 Various bits: * \li bits 0..1 [2] - clipboard buffer index * \li bits 2..31 [30] - [ unused ] * @param p2 Various bits: * \li bits 0..5 [6] - width of area to copy * \li bits 6..11 [6] - height of area to copy * \li bits 12..31 [20] - [ unused ] * @param text Unused. * @return The cost of this operation or an error. */ CommandCost CmdCopyToClipboard(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { /* clipboard is available only in a sigle player game and only to the local company */ if (_networking || !IsLocalCompany()) return CMD_ERROR; /* extract and validate clipboard buffer index */ uint index = GB(p1, 0, 2); if (index >= NUM_CLIPBOARD_BUFFERS || index == INSTANT_COPY_PASTE_BUFFER) return CMD_ERROR; /* calculate and validate source area */ TileArea src_area(tile, GB(p2, 0, 6), GB(p2, 6, 6)); CommandCost ret = ValParamCopyPasteArea(src_area); if (ret.Failed()) return ret; /* copy to clipboard only when executing (DC_EXEC) */ if (flags & DC_EXEC) CopyToClipboard(GetClipboardBuffer(index), src_area); /* return the cost */ return CommandCost(INVALID_EXPENSES, 0); }
virtual void SetStringParameters(int widget) const { switch (widget) { case WID_BO_OBJECT_NAME: { const ObjectSpec *spec = ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index); SetDParam(0, spec != NULL ? spec->name : STR_EMPTY); break; } case WID_BO_OBJECT_SIZE: { const ObjectSpec *spec = ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index); int size = spec == NULL ? 0 : spec->size; SetDParam(0, GB(size, HasBit(_selected_object_view, 0) ? 4 : 0, 4)); SetDParam(1, GB(size, HasBit(_selected_object_view, 0) ? 0 : 4, 4)); break; } default: break; } }
static void SetGlyphPtr(FontSize size, WChar key, const GlyphEntry *glyph, bool duplicate = false) { if (_glyph_ptr[size] == NULL) { DEBUG(freetype, 3, "Allocating root glyph cache for size %u", size); _glyph_ptr[size] = CallocT<GlyphEntry*>(256); } if (_glyph_ptr[size][GB(key, 8, 8)] == NULL) { DEBUG(freetype, 3, "Allocating glyph cache for range 0x%02X00, size %u", GB(key, 8, 8), size); _glyph_ptr[size][GB(key, 8, 8)] = CallocT<GlyphEntry>(256); } DEBUG(freetype, 4, "Set glyph for unicode character 0x%04X, size %u", key, size); _glyph_ptr[size][GB(key, 8, 8)][GB(key, 0, 8)].sprite = glyph->sprite; _glyph_ptr[size][GB(key, 8, 8)][GB(key, 0, 8)].width = glyph->width; _glyph_ptr[size][GB(key, 8, 8)][GB(key, 0, 8)].duplicate = duplicate; }
void FreeTypeFontCache::SetGlyphPtr(GlyphID key, const GlyphEntry *glyph, bool duplicate) { if (this->glyph_to_sprite == NULL) { DEBUG(freetype, 3, "Allocating root glyph cache for size %u", this->fs); this->glyph_to_sprite = CallocT<GlyphEntry*>(256); } if (this->glyph_to_sprite[GB(key, 8, 8)] == NULL) { DEBUG(freetype, 3, "Allocating glyph cache for range 0x%02X00, size %u", GB(key, 8, 8), this->fs); this->glyph_to_sprite[GB(key, 8, 8)] = CallocT<GlyphEntry>(256); } DEBUG(freetype, 4, "Set glyph for unicode character 0x%04X, size %u", key, this->fs); this->glyph_to_sprite[GB(key, 8, 8)][GB(key, 0, 8)].sprite = glyph->sprite; this->glyph_to_sprite[GB(key, 8, 8)][GB(key, 0, 8)].width = glyph->width; this->glyph_to_sprite[GB(key, 8, 8)][GB(key, 0, 8)].duplicate = duplicate; }
/** * Create a new subsidy. * @param tile unused. * @param flags type of operation * @param p1 various bitstuffed elements * - p1 = (bit 0 - 7) - SourceType of source. * - p1 = (bit 8 - 23) - SourceID of source. * - p1 = (bit 24 - 31) - CargoID of subsidy. * @param p2 various bitstuffed elements * - p2 = (bit 0 - 7) - SourceType of destination. * - p2 = (bit 8 - 23) - SourceID of destination. * @param text unused. * @return the cost of this operation or an error */ CommandCost CmdCreateSubsidy(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { if (!Subsidy::CanAllocateItem()) return CMD_ERROR; CargoID cid = GB(p1, 24, 8); SourceType src_type = (SourceType)GB(p1, 0, 8); SourceID src = GB(p1, 8, 16); SourceType dst_type = (SourceType)GB(p2, 0, 8); SourceID dst = GB(p2, 8, 16); if (_current_company != OWNER_DEITY) return CMD_ERROR; if (cid >= NUM_CARGO || !::CargoSpec::Get(cid)->IsValid()) return CMD_ERROR; switch (src_type) { case ST_TOWN: if (!Town::IsValidID(src)) return CMD_ERROR; break; case ST_INDUSTRY: if (!Industry::IsValidID(src)) return CMD_ERROR; break; default: return CMD_ERROR; } switch (dst_type) { case ST_TOWN: if (!Town::IsValidID(dst)) return CMD_ERROR; break; case ST_INDUSTRY: if (!Industry::IsValidID(dst)) return CMD_ERROR; break; default: return CMD_ERROR; } if (flags & DC_EXEC) { CreateSubsidy(cid, src_type, src, dst_type, dst); } return CommandCost(); }
/** * Copy a piece of map and instantly paste at given location. * * @param tile Tile where to paste (northern). * @param flags Command flags. * @param p1 Various bits: * \li bits 0..27 [28] - northern tile of the source area * \li bits 28..31 [4] - rail type (RailType) to convert to, ignored if CPM_CONVERT_RAILTYPE mode is off * @param p2 Various bits: * \li bits 0..5 [6] - source area width * \li bits 6..11 [6] - source area height * \li bits 12..15 [4] - additional amount of tile heights to add to each tile (-8..7) * \li bits 16..18 [3] - transformation to perform (DirTransformation) * \li bits 19..27 [9] - mode (CopyPasteMode) * \li bits 28..31 [4] - [ unused ] * @param text Unused. * @return The cost of this operation or an error. */ CommandCost CmdInstantCopyPaste(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { CopyPasteParams copy_paste; /* extract and validate source area */ copy_paste.src_area.tile = GenericTileIndex(TileIndex(GB(p1, 0, 28))); copy_paste.src_area.w = GB(p2, 0, 6); copy_paste.src_area.h = GB(p2, 6, 6); CommandCost ret = ValParamCopyPasteArea(copy_paste.src_area); if (ret.Failed()) return ret; /* calculate and validate destination area */ copy_paste.dst_area = TransformTileArea(copy_paste.src_area, GenericTileIndex(tile), copy_paste.transformation); ret = ValParamCopyPasteArea(copy_paste.dst_area); if (ret.Failed()) return ret; /* extract and validate copy/paste mode */ copy_paste.mode = (CopyPasteMode)GB(p2, 19, 9); if (!ValParamCopyPasteMode(copy_paste.mode)) return CMD_ERROR; /* extract and validate rail type */ copy_paste.railtype = (RailType)GB(p1, 28, 4); if (!ValParamRailtype(copy_paste.railtype)) return CMD_ERROR; /* extract transformation */ copy_paste.transformation = (DirTransformation)GB(p2, 16, 3); /* extract the additional number of height units */ int additional_height_delta = GB(p2, 12, 4); // this is a 4-bit SIGNED integer (-8..7) additional_height_delta |= -(additional_height_delta & (1 << 3)); // propagate the sign bit /* calculate the height */ copy_paste.height_delta = CalcCopyPasteHeightDelta(copy_paste.src_area, copy_paste.dst_area, copy_paste.transformation, additional_height_delta); /* when copy and paste areas are too close each other, firstly * copy to the clipboard and then from the clipboard to the map */ if (CopyPasteAreasMayColide(copy_paste)) { Map *clipboard = GetClipboardBuffer(INSTANT_COPY_PASTE_BUFFER); /* Copy to a buffer, but only in the first stage of the command. * In a single player game and also while we are a server, the first one is non-DC_EXEC * stage (which is fallowed then by a DC_EXEC stage). When we are a client, there is only * one stage which is either a single non-DC_EXEC stage (shift pressed), or a single DC_EXEC * stage (command comming from the network). */ if ((_networking && !_network_server) || !(flags & DC_EXEC)) { CopyToClipboard(clipboard, copy_paste.src_area); } /* paste from the clipboard */ ret = PasteFromClipboard(clipboard, tile, flags, copy_paste.mode, copy_paste.transformation, copy_paste.railtype, additional_height_delta); } else { /* copy/paste directly */ InitializePasting(flags, copy_paste); DoCopyPaste(copy_paste); ret = FinalizePasting(); } return ret; }
static char *RandomPart(char *buf, GRFTownName *t, uint32 seed, byte id, const char *last) { assert(t != NULL); for (int i = 0; i < t->nbparts[id]; i++) { byte count = t->partlist[id][i].bitcount; uint16 maxprob = t->partlist[id][i].maxprob; uint32 r = (GB(seed, t->partlist[id][i].bitstart, count) * maxprob) >> count; for (int j = 0; j < t->partlist[id][i].partcount; j++) { byte prob = t->partlist[id][i].parts[j].prob; maxprob -= GB(prob, 0, 7); if (maxprob > r) continue; if (HasBit(prob, 7)) { buf = RandomPart(buf, t, seed, t->partlist[id][i].parts[j].data.id, last); } else { buf = strecat(buf, t->partlist[id][i].parts[j].data.text, last); } break; } } return buf; }
static void sanitise_mincore(struct syscallrecord *rec) { struct map *map; unsigned long len; map = common_set_mmap_ptr_len(); len = min(GB(1), map->size); len = len + (page_size - 1) / page_size; rec->a3 = (unsigned long) zmalloc(len); // FIXME: LEAK }
/** * Creates a number of tree groups. * The number of trees in each group depends on how many trees are actually placed around the given tile. * * @param num_groups Number of tree groups to place. */ static void PlaceTreeGroups(uint num_groups) { do { TileIndex center_tile = RandomTile(); for (uint i = 0; i < DEFAULT_TREE_STEPS; i++) { uint32 r = Random(); int x = GB(r, 0, 5) - 16; int y = GB(r, 8, 5) - 16; uint dist = abs(x) + abs(y); TileIndex cur_tile = TileAddWrap(center_tile, x, y); IncreaseGeneratingWorldProgress(GWP_TREE); if (cur_tile != INVALID_TILE && dist <= 13 && CanPlantTreesOnTile(cur_tile, true)) { PlaceTree(cur_tile, r); } } } while (--num_groups); }
/* static */ SQInteger AIInfo::DummyConstructor(HSQUIRRELVM vm) { /* Get the AIInfo */ SQUserPointer instance; sq_getinstanceup(vm, 2, &instance, 0); AIInfo *info = (AIInfo *)instance; info->api_version = NULL; SQInteger res = AIFileInfo::Constructor(vm, info); if (res != 0) return res; char buf[8]; seprintf(buf, lastof(buf), "%d.%d", GB(_openttd_newgrf_version, 28, 4), GB(_openttd_newgrf_version, 24, 4)); info->api_version = strdup(buf); /* Remove the link to the real instance, else it might get deleted by RegisterAI() */ sq_setinstanceup(vm, 2, NULL); /* Register the AI to the base system */ info->base->SetDummyAI(info); return 0; }
static bool is_RFC1918(const unsigned char *ipaddr) { return is_ipv4_mapped(ipaddr) && (ipaddr[GB(3)] == 10 || (ipaddr[GB(3)] == 192 && ipaddr[GB(2)] == 168) || (ipaddr[GB(3)] == 172 && (ipaddr[GB(2)] >= 16 && ipaddr[GB(2)] <= 31))); }
void Blitter_32bppAnim::CopyFromBuffer(void *video, const void *src, int width, int height) { assert(!_screen_disable_anim); assert(video >= _screen.dst_ptr && video <= (uint32 *)_screen.dst_ptr + _screen.width + _screen.height * _screen.pitch); Colour *dst = (Colour *)video; const uint32 *usrc = (const uint32 *)src; assert(_screen.pitch == this->anim_buf_pitch); // precondition for translating 'video' into an 'anim_buf' offset below. uint16 *anim_line = ((uint32 *)video - (uint32 *)_screen.dst_ptr) + this->anim_buf; for (; height > 0; height--) { /* We need to keep those for palette animation. */ Colour *dst_pal = dst; uint16 *anim_pal = anim_line; memcpy(dst, usrc, width * sizeof(uint32)); usrc += width; dst += _screen.pitch; /* Copy back the anim-buffer */ memcpy(anim_line, usrc, width * sizeof(uint16)); usrc = (const uint32 *)((const uint16 *)usrc + width); anim_line += this->anim_buf_pitch; /* Okay, it is *very* likely that the image we stored is using * the wrong palette animated colours. There are two things we * can do to fix this. The first is simply reviewing the whole * screen after we copied the buffer, i.e. run PaletteAnimate, * however that forces a full screen redraw which is expensive * for just the cursor. This just copies the implementation of * palette animation, much cheaper though slightly nastier. */ for (int i = 0; i < width; i++) { uint colour = GB(*anim_pal, 0, 8); if (colour >= PALETTE_ANIM_START) { /* Update this pixel */ *dst_pal = this->AdjustBrightness(LookupColourInPalette(colour), GB(*anim_pal, 8, 8)); } dst_pal++; anim_pal++; } } }
/** * Display a story page for all clients that are allowed to * view the story page. * @param tile unused. * @param flags type of operation * @param p1 = (bit 0 - 15) - StoryPageID to show. * @param p2 unused * @param text unused * @return the cost of this operation or an error */ CommandCost CmdShowStoryPage(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; StoryPageID page_id = (StoryPageID)GB(p1, 0, 16); if (!StoryPage::IsValidID(page_id)) return CMD_ERROR; if (flags & DC_EXEC) { StoryPage *g = StoryPage::Get(page_id); if ((g->company != INVALID_COMPANY && g->company == _local_company) || (g->company == INVALID_COMPANY && Company::IsValidID(_local_company))) ShowStoryBook(_local_company, page_id); } return CommandCost(); }