tron@2186: /* $Id$ */ tron@2186: belugas@6527: /** @file misc.cpp */ belugas@6527: truelight@0: #include "stdafx.h" Darkvater@1891: #include "openttd.h" tron@2308: #include "currency.h" tron@2163: #include "functions.h" rubidium@9599: #include "landscape.h" tron@2548: #include "news.h" tron@2191: #include "player.h" tron@1375: #include "string.h" tron@507: #include "table/strings.h" Darkvater@1914: #include "table/sprites.h" tron@679: #include "map.h" truelight@0: #include "vehicle.h" truelight@0: #include "saveload.h" bjarni@842: #include "engine.h" matthijs@1752: #include "vehicle_gui.h" tron@2159: #include "variables.h" truelight@9429: #include "ai/ai.h" truelight@9476: #include "newgrf_house.h" rubidium@4261: #include "date.h" peter1138@6417: #include "cargotype.h" glx@9624: #include "group.h" truelight@0: tron@1328: char _name_array[512][32]; truelight@0: ludde@2073: #ifndef MERSENNE_TWISTER ludde@2073: truelight@543: #ifdef RANDOM_DEBUG rubidium@5720: #include "network/network_data.h" truelight@1120: uint32 DoRandom(int line, const char *file) ludde@2073: #else // RANDOM_DEBUG rubidium@6573: uint32 Random() ludde@2073: #endif // RANDOM_DEBUG truelight@543: { truelight@1121: truelight@1121: uint32 s; truelight@1121: uint32 t; truelight@1121: truelight@543: #ifdef RANDOM_DEBUG truelight@543: if (_networking && (DEREF_CLIENT(0)->status != STATUS_INACTIVE || !_network_server)) truelight@543: printf("Random [%d/%d] %s:%d\n",_frame_counter, _current_player, file, line); truelight@260: #endif truelight@260: truelight@1121: s = _random_seeds[0][0]; truelight@1121: t = _random_seeds[0][1]; pasky@1446: _random_seeds[0][0] = s + ROR(t ^ 0x1234567F, 7) + 1; pasky@1446: return _random_seeds[0][1] = ROR(s, 3) - 1; truelight@0: } ludde@2073: #endif // MERSENNE_TWISTER truelight@0: ludde@2073: #if defined(RANDOM_DEBUG) && !defined(MERSENNE_TWISTER) truelight@1120: uint DoRandomRange(uint max, int line, const char *file) truelight@543: { tron@2484: return GB(DoRandom(line, file), 0, 16) * max >> 16; truelight@543: } truelight@543: #else truelight@0: uint RandomRange(uint max) truelight@0: { tron@2484: return GB(Random(), 0, 16) * max >> 16; truelight@0: } truelight@543: #endif truelight@0: ludde@2073: rubidium@6573: uint32 InteractiveRandom() truelight@0: { signde@206: uint32 t = _random_seeds[1][1]; signde@206: uint32 s = _random_seeds[1][0]; pasky@1446: _random_seeds[1][0] = s + ROR(t ^ 0x1234567F, 7) + 1; pasky@1446: return _random_seeds[1][1] = ROR(s, 3) - 1; signde@206: } signde@206: signde@239: uint InteractiveRandomRange(uint max) signde@239: { tron@2484: return GB(InteractiveRandom(), 0, 16) * max >> 16; signde@239: } signde@239: rubidium@6573: void InitializeVehicles(); rubidium@6573: void InitializeWaypoints(); rubidium@6573: void InitializeDepots(); rubidium@6573: void InitializeEngines(); rubidium@6573: void InitializeOrders(); rubidium@6573: void InitializeClearLand(); rubidium@6573: void InitializeRailGui(); rubidium@6573: void InitializeRoadGui(); rubidium@6573: void InitializeAirportGui(); rubidium@6573: void InitializeDockGui(); rubidium@6573: void InitializeIndustries(); rubidium@6573: void InitializeMainGui(); rubidium@6573: void InitializeTowns(); rubidium@6573: void InitializeTrees(); rubidium@6573: void InitializeSigns(); rubidium@6573: void InitializeStations(); glx@9629: void InitializeCargoPackets(); rubidium@6573: static void InitializeNameMgr(); rubidium@6573: void InitializePlayers(); rubidium@6573: static void InitializeCheats(); rubidium@6573: void InitializeNPF(); truelight@0: truelight@2828: void InitializeGame(int mode, uint size_x, uint size_y) truelight@0: { ludde@2051: AllocateMap(size_x, size_y); ludde@2051: bjarni@842: AddTypeToEngines(); // make sure all engines have a type tron@915: rubidium@6144: SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, 0, WC_MAIN_WINDOW, 0); truelight@0: truelight@6557: _pause_game = 0; truelight@0: _fast_forward = 0; truelight@0: _tick_counter = 0; glx@9629: _realtime_tick = 0; truelight@0: _date_fract = 0; truelight@0: _cur_tileloop_tile = 0; truelight@201: truelight@2828: if ((mode & IG_DATE_RESET) == IG_DATE_RESET) { rubidium@4295: SetDate(ConvertYMDToDate(_patches.starting_year, 0, 1)); truelight@0: } truelight@0: peter1138@2848: InitializeEngines(); truelight@0: InitializeVehicles(); truelight@1542: InitializeWaypoints(); truelight@4347: InitializeDepots(); truelight@1024: InitializeOrders(); glx@9624: InitializeGroup(); truelight@0: truelight@0: InitNewsItemStructs(); ludde@2051: InitializeLandscape(); truelight@0: InitializeClearLand(); truelight@0: InitializeRailGui(); truelight@0: InitializeRoadGui(); truelight@0: InitializeAirportGui(); truelight@0: InitializeDockGui(); truelight@0: InitializeTowns(); truelight@0: InitializeTrees(); truelight@988: InitializeSigns(); truelight@0: InitializeStations(); glx@9629: InitializeCargoPackets(); truelight@0: InitializeIndustries(); truelight@9476: InitializeBuildingCounts(); celestar@3622: InitializeMainGui(); truelight@201: truelight@0: InitializeNameMgr(); darkvater@164: InitializeVehiclesGuiList(); truelight@0: InitializeTrains(); matthijs@1247: InitializeNPF(); truelight@0: truelight@2706: AI_Initialize(); truelight@0: InitializePlayers(); truelight@0: InitializeCheats(); truelight@0: truelight@0: InitTextEffects(); truelight@543: InitTextMessage(); truelight@0: InitializeAnimatedTiles(); truelight@0: truelight@0: InitializeLandscapeVariables(false); truelight@0: truelight@0: ResetObjectToPlace(); truelight@0: } truelight@0: peter1138@4862: bool IsCustomName(StringID id) peter1138@4862: { peter1138@4862: return GB(id, 11, 5) == 15; peter1138@4862: } peter1138@4862: truelight@0: void DeleteName(StringID id) truelight@0: { peter1138@4862: if (IsCustomName(id)) { truelight@0: memset(_name_array[id & 0x1FF], 0, sizeof(_name_array[id & 0x1FF])); truelight@0: } truelight@0: } truelight@0: Darkvater@4912: char *GetName(char *buff, StringID id, const char* last) truelight@0: { Darkvater@4912: return strecpy(buff, _name_array[id & ~0x600], last); truelight@0: } truelight@0: truelight@0: rubidium@6573: static void InitializeCheats() truelight@0: { truelight@201: memset(&_cheats, 0, sizeof(Cheats)); truelight@0: } truelight@0: truelight@0: rubidium@6573: static void InitializeNameMgr() truelight@0: { truelight@0: memset(_name_array, 0, sizeof(_name_array)); truelight@0: } truelight@0: tron@1328: StringID RealAllocateName(const char *name, byte skip, bool check_double) truelight@0: { tron@1375: char (*free_item)[lengthof(*_name_array)] = NULL; tron@1375: char (*i)[lengthof(*_name_array)]; truelight@0: tron@1375: for (i = _name_array; i != endof(_name_array); ++i) { tron@1375: if ((*i)[0] == '\0') { tron@1375: if (free_item == NULL) free_item = i; tron@1375: } else if (check_double && strncmp(*i, name, lengthof(*i) - 1) == 0) { tron@1375: _error_message = STR_0132_CHOSEN_NAME_IN_USE_ALREADY; tron@1375: return 0; truelight@0: } truelight@0: } truelight@0: tron@1375: if (free_item != NULL) { tron@1375: ttd_strlcpy(*free_item, name, lengthof(*free_item)); tron@1375: return (free_item - _name_array) | 0x7800 | (skip << 8); tron@1375: } else { truelight@0: _error_message = STR_0131_TOO_MANY_NAMES_DEFINED; truelight@0: return 0; truelight@0: } truelight@0: } truelight@0: rubidium@6573: void ConvertNameArray() peter1138@5108: { peter1138@5108: uint i; peter1138@5108: peter1138@5108: for (i = 0; i < lengthof(_name_array); i++) { peter1138@5108: const char *strfrom = _name_array[i]; peter1138@5108: char tmp[sizeof(*_name_array)]; peter1138@5108: char *strto = tmp; peter1138@5108: peter1138@5108: for (; *strfrom != '\0'; strfrom++) { peter1138@5108: WChar c = (byte)*strfrom; peter1138@5108: switch (c) { peter1138@5108: case 0xA4: c = 0x20AC; break; // Euro peter1138@5108: case 0xA6: c = 0x0160; break; // S with caron peter1138@5108: case 0xA8: c = 0x0161; break; // s with caron peter1138@5108: case 0xB4: c = 0x017D; break; // Z with caron peter1138@5108: case 0xB8: c = 0x017E; break; // z with caron peter1138@5108: case 0xBC: c = 0x0152; break; // OE ligature peter1138@5108: case 0xBD: c = 0x0153; break; // oe ligature peter1138@5108: case 0xBE: c = 0x0178; break; // Y with diaresis peter1138@5108: default: break; peter1138@5108: } peter1138@5108: if (strto + Utf8CharLen(c) > lastof(tmp)) break; peter1138@5108: strto += Utf8Encode(strto, c); peter1138@5108: } peter1138@5108: peter1138@5108: /* Terminate the new string and copy it back to the name array */ peter1138@5108: *strto = '\0'; peter1138@5108: memcpy(_name_array[i], tmp, sizeof(*_name_array)); peter1138@5108: } peter1138@5108: } peter1138@5108: belugas@6527: /* Calculate constants that depend on the landscape type. */ truelight@0: void InitializeLandscapeVariables(bool only_constants) truelight@0: { peter1138@6417: if (only_constants) return; truelight@201: glx@9505: for (CargoID i = 0; i < NUM_CARGO; i++) { peter1138@6417: _cargo_payment_rates[i] = GetCargo(i)->initial_payment; peter1138@6417: _cargo_payment_rates_frac[i] = 0; truelight@0: } truelight@0: } truelight@0: truelight@0: truelight@0: dominik@116: int FindFirstBit(uint32 value) truelight@0: { belugas@6527: /* The macro FIND_FIRST_BIT is better to use when your value is belugas@6527: not more than 128. */ dominik@116: byte i = 0; maedhros@5914: maedhros@5914: if (value == 0) return 0; maedhros@5914: maedhros@5914: if ((value & 0x0000ffff) == 0) { value >>= 16; i += 16; } maedhros@5914: if ((value & 0x000000ff) == 0) { value >>= 8; i += 8; } maedhros@5914: if ((value & 0x0000000f) == 0) { value >>= 4; i += 4; } maedhros@5914: if ((value & 0x00000003) == 0) { value >>= 2; i += 2; } maedhros@5914: if ((value & 0x00000001) == 0) { i += 1; } maedhros@5914: truelight@0: return i; truelight@0: } truelight@0: rubidium@9628: int CountBitsSet(uint32 value) rubidium@9628: { rubidium@9628: int num; rubidium@9628: rubidium@9628: /* This loop is only called once for every bit set by clearing the lowest rubidium@9628: * bit in each loop. The number of bits is therefore equal to the number of rubidium@9628: * times the loop was called. It was found at the following website: rubidium@9628: * http://graphics.stanford.edu/~seander/bithacks.html */ rubidium@9628: rubidium@9628: for (num = 0; value != 0; num++) { rubidium@9628: value &= value - 1; rubidium@9628: } rubidium@9628: rubidium@9628: return num; rubidium@9628: } truelight@0: rubidium@6573: static void Save_NAME() truelight@0: { truelight@0: int i; truelight@0: tron@1375: for (i = 0; i != lengthof(_name_array); ++i) { tron@1375: if (_name_array[i][0] != '\0') { truelight@0: SlSetArrayIndex(i); truelight@4321: SlArray(_name_array[i], (uint)strlen(_name_array[i]), SLE_UINT8); truelight@201: } truelight@0: } truelight@0: } truelight@0: rubidium@6573: static void Load_NAME() truelight@0: { truelight@0: int index; truelight@201: truelight@0: while ((index = SlIterateArray()) != -1) { rubidium@9601: SlArray(_name_array[index], SlGetFieldLength(), SLE_UINT8); truelight@0: } truelight@0: } truelight@0: truelight@0: static const SaveLoadGlobVarList _date_desc[] = { truelight@4383: SLEG_CONDVAR(_date, SLE_FILE_U16 | SLE_VAR_I32, 0, 30), truelight@4383: SLEG_CONDVAR(_date, SLE_INT32, 31, SL_MAX_VERSION), rubidium@4344: SLEG_VAR(_date_fract, SLE_UINT16), rubidium@4344: SLEG_VAR(_tick_counter, SLE_UINT16), rubidium@4344: SLEG_VAR(_vehicle_id_ctr_day, SLE_UINT16), rubidium@4344: SLEG_VAR(_age_cargo_skip_counter, SLE_UINT8), tron@6222: SLE_CONDNULL(1, 0, 45), rubidium@4344: SLEG_CONDVAR(_cur_tileloop_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5), rubidium@4344: SLEG_CONDVAR(_cur_tileloop_tile, SLE_UINT32, 6, SL_MAX_VERSION), rubidium@4344: SLEG_VAR(_disaster_delay, SLE_UINT16), rubidium@4344: SLEG_VAR(_station_tick_ctr, SLE_UINT16), rubidium@4344: SLEG_VAR(_random_seeds[0][0], SLE_UINT32), rubidium@4344: SLEG_VAR(_random_seeds[0][1], SLE_UINT32), rubidium@4344: SLEG_CONDVAR(_cur_town_ctr, SLE_FILE_U8 | SLE_VAR_U32, 0, 9), rubidium@4344: SLEG_CONDVAR(_cur_town_ctr, SLE_UINT32, 10, SL_MAX_VERSION), rubidium@4344: SLEG_VAR(_cur_player_tick_index, SLE_FILE_U8 | SLE_VAR_U32), rubidium@4344: SLEG_VAR(_next_competitor_start, SLE_FILE_U16 | SLE_VAR_U32), rubidium@4344: SLEG_VAR(_trees_tick_ctr, SLE_UINT8), truelight@6557: SLEG_CONDVAR(_pause_game, SLE_UINT8, 4, SL_MAX_VERSION), rubidium@4344: SLEG_CONDVAR(_cur_town_iter, SLE_UINT32, 11, SL_MAX_VERSION), Darkvater@3046: SLEG_END() truelight@0: }; truelight@0: belugas@6527: /* Save load date related variables as well as persistent tick counters belugas@6527: * XXX: currently some unrelated stuff is just put here */ rubidium@6573: static void SaveLoad_DATE() truelight@0: { truelight@0: SlGlobList(_date_desc); truelight@0: } truelight@0: truelight@0: truelight@0: static const SaveLoadGlobVarList _view_desc[] = { rubidium@4344: SLEG_CONDVAR(_saved_scrollpos_x, SLE_FILE_I16 | SLE_VAR_I32, 0, 5), rubidium@4344: SLEG_CONDVAR(_saved_scrollpos_x, SLE_INT32, 6, SL_MAX_VERSION), rubidium@4344: SLEG_CONDVAR(_saved_scrollpos_y, SLE_FILE_I16 | SLE_VAR_I32, 0, 5), rubidium@4344: SLEG_CONDVAR(_saved_scrollpos_y, SLE_INT32, 6, SL_MAX_VERSION), rubidium@4344: SLEG_VAR(_saved_scrollpos_zoom, SLE_UINT8), Darkvater@3046: SLEG_END() truelight@0: }; truelight@0: rubidium@6573: static void SaveLoad_VIEW() truelight@0: { truelight@0: SlGlobList(_view_desc); truelight@0: } truelight@0: tron@1218: static uint32 _map_dim_x; tron@1218: static uint32 _map_dim_y; tron@1218: tron@1218: static const SaveLoadGlobVarList _map_dimensions[] = { Darkvater@3046: SLEG_CONDVAR(_map_dim_x, SLE_UINT32, 6, SL_MAX_VERSION), Darkvater@3046: SLEG_CONDVAR(_map_dim_y, SLE_UINT32, 6, SL_MAX_VERSION), Darkvater@3046: SLEG_END() tron@1218: }; tron@1218: rubidium@6573: static void Save_MAPS() tron@1218: { tron@1219: _map_dim_x = MapSizeX(); tron@1219: _map_dim_y = MapSizeY(); tron@1218: SlGlobList(_map_dimensions); tron@1218: } tron@1218: rubidium@6573: static void Load_MAPS() tron@1218: { tron@1218: SlGlobList(_map_dimensions); ludde@2051: AllocateMap(_map_dim_x, _map_dim_y); tron@1218: } tron@1218: rubidium@6573: static void Load_MAPT() ludde@2050: { tron@2295: uint size = MapSize(); tron@2295: uint i; tron@2295: tron@2295: for (i = 0; i != size;) { tron@2295: byte buf[4096]; tron@2295: uint j; tron@2295: tron@2295: SlArray(buf, lengthof(buf), SLE_UINT8); tron@2295: for (j = 0; j != lengthof(buf); j++) _m[i++].type_height = buf[j]; truelight@817: } truelight@0: } truelight@0: rubidium@6573: static void Save_MAPT() tron@1093: { tron@2295: uint size = MapSize(); tron@2295: uint i; tron@2295: tron@2295: SlSetLength(size); tron@2295: for (i = 0; i != size;) { tron@2295: byte buf[4096]; tron@2295: uint j; tron@2295: tron@2295: for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].type_height; tron@2295: SlArray(buf, lengthof(buf), SLE_UINT8); tron@2295: } truelight@0: } truelight@0: rubidium@6573: static void Load_MAP1() tron@1093: { tron@2295: uint size = MapSize(); tron@2295: uint i; tron@2295: tron@2295: for (i = 0; i != size;) { tron@2295: byte buf[4096]; tron@2295: uint j; tron@2295: tron@2295: SlArray(buf, lengthof(buf), SLE_UINT8); tron@2360: for (j = 0; j != lengthof(buf); j++) _m[i++].m1 = buf[j]; tron@2295: } tron@2295: } tron@2295: rubidium@6573: static void Save_MAP1() tron@2295: { tron@2295: uint size = MapSize(); tron@2295: uint i; tron@2295: tron@2295: SlSetLength(size); tron@2295: for (i = 0; i != size;) { tron@2295: byte buf[4096]; tron@2295: uint j; tron@2295: tron@2360: for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m1; tron@2295: SlArray(buf, lengthof(buf), SLE_UINT8); tron@2295: } truelight@0: } truelight@0: rubidium@6573: static void Load_MAP2() tron@1093: { tron@2049: uint size = MapSize(); tron@2049: uint i; tron@2049: tron@2049: for (i = 0; i != size;) { tron@2049: uint16 buf[4096]; tron@2049: uint j; tron@2049: tron@2049: SlArray(buf, lengthof(buf), tron@2049: /* In those versions the m2 was 8 bits */ truelight@2685: CheckSavegameVersion(5) ? SLE_FILE_U8 | SLE_VAR_U16 : SLE_UINT16 tron@2049: ); tron@2049: for (j = 0; j != lengthof(buf); j++) _m[i++].m2 = buf[j]; tron@2049: } tron@2049: } tron@2049: rubidium@6573: static void Save_MAP2() tron@2049: { tron@2049: uint size = MapSize(); tron@2049: uint i; tron@2049: tron@2049: SlSetLength(size * sizeof(_m[0].m2)); tron@2049: for (i = 0; i != size;) { tron@2049: uint16 buf[4096]; tron@2049: uint j; tron@2049: tron@2049: for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m2; tron@2049: SlArray(buf, lengthof(buf), SLE_UINT16); tron@2049: } tron@2049: } tron@2049: rubidium@6573: static void Load_MAP3() tron@2049: { tron@2295: uint size = MapSize(); tron@2295: uint i; tron@2295: tron@2295: for (i = 0; i != size;) { tron@2295: byte buf[4096]; tron@2295: uint j; tron@2295: tron@2295: SlArray(buf, lengthof(buf), SLE_UINT8); tron@2295: for (j = 0; j != lengthof(buf); j++) _m[i++].m3 = buf[j]; tron@2295: } tron@2049: } tron@2049: rubidium@6573: static void Save_MAP3() tron@2049: { tron@2295: uint size = MapSize(); tron@2295: uint i; tron@2295: tron@2295: SlSetLength(size); tron@2295: for (i = 0; i != size;) { tron@2295: byte buf[4096]; tron@2295: uint j; tron@2295: tron@2295: for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m3; tron@2295: SlArray(buf, lengthof(buf), SLE_UINT8); tron@2295: } tron@2049: } tron@2049: rubidium@6573: static void Load_MAP4() tron@2049: { tron@2295: uint size = MapSize(); tron@2295: uint i; tron@2295: tron@2295: for (i = 0; i != size;) { tron@2295: byte buf[4096]; tron@2295: uint j; tron@2295: tron@2295: SlArray(buf, lengthof(buf), SLE_UINT8); tron@2295: for (j = 0; j != lengthof(buf); j++) _m[i++].m4 = buf[j]; tron@2295: } tron@2295: } tron@2295: rubidium@6573: static void Save_MAP4() tron@2295: { tron@2295: uint size = MapSize(); tron@2295: uint i; tron@2295: tron@2295: SlSetLength(size); tron@2295: for (i = 0; i != size;) { tron@2295: byte buf[4096]; tron@2295: uint j; tron@2295: tron@2295: for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m4; tron@2295: SlArray(buf, lengthof(buf), SLE_UINT8); tron@2295: } tron@2295: } tron@2295: rubidium@6573: static void Load_MAP5() tron@2295: { tron@2295: uint size = MapSize(); tron@2295: uint i; tron@2295: tron@2295: for (i = 0; i != size;) { tron@2295: byte buf[4096]; tron@2295: uint j; tron@2295: tron@2295: SlArray(buf, lengthof(buf), SLE_UINT8); tron@2295: for (j = 0; j != lengthof(buf); j++) _m[i++].m5 = buf[j]; tron@2295: } tron@2295: } tron@2295: rubidium@6573: static void Save_MAP5() tron@2295: { tron@2295: uint size = MapSize(); tron@2295: uint i; tron@2295: tron@2295: SlSetLength(size); tron@2295: for (i = 0; i != size;) { tron@2295: byte buf[4096]; tron@2295: uint j; tron@2295: tron@2295: for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m5; tron@2295: SlArray(buf, lengthof(buf), SLE_UINT8); tron@2295: } tron@2049: } tron@2049: rubidium@6573: static void Load_MAP6() tron@2049: { belugas@5847: /* Still available for loading old games */ tron@2049: uint size = MapSize(); tron@2049: uint i; tron@2049: celestar@5573: if (CheckSavegameVersion(42)) { celestar@5573: for (i = 0; i != size;) { celestar@5573: uint8 buf[1024]; celestar@5573: uint j; tron@2049: celestar@5573: SlArray(buf, lengthof(buf), SLE_UINT8); celestar@5573: for (j = 0; j != lengthof(buf); j++) { belugas@5847: _m[i++].m6 = GB(buf[j], 0, 2); belugas@5847: _m[i++].m6 = GB(buf[j], 2, 2); belugas@5847: _m[i++].m6 = GB(buf[j], 4, 2); belugas@5847: _m[i++].m6 = GB(buf[j], 6, 2); celestar@5573: } celestar@5573: } celestar@5573: } else { celestar@5573: for (i = 0; i != size;) { celestar@5573: byte buf[4096]; celestar@5573: uint j; celestar@5573: celestar@5573: SlArray(buf, lengthof(buf), SLE_UINT8); belugas@5847: for (j = 0; j != lengthof(buf); j++) _m[i++].m6 = buf[j]; tron@2049: } tron@2049: } tron@2049: } tron@2049: rubidium@6573: static void Save_MAP6() tron@2049: { tron@2049: uint size = MapSize(); tron@2049: uint i; tron@2049: celestar@5573: SlSetLength(size); tron@2049: for (i = 0; i != size;) { celestar@5573: uint8 buf[4096]; tron@2049: uint j; tron@2049: belugas@5847: for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m6; tron@2049: SlArray(buf, lengthof(buf), SLE_UINT8); tron@2049: } truelight@0: } truelight@0: truelight@9476: static void Load_MAP7() truelight@9476: { truelight@9476: uint size = MapSize(); truelight@9476: uint i; truelight@9476: truelight@9476: for (i = 0; i != size;) { truelight@9476: uint8 buf[4096]; truelight@9476: uint j; truelight@9476: truelight@9476: SlArray(buf, lengthof(buf), SLE_UINT8); truelight@9476: for (j = 0; j != lengthof(buf); j++) _me[i++].m7 = buf[j]; truelight@9476: } truelight@9476: } truelight@9476: truelight@9476: static void Save_MAP7() truelight@9476: { truelight@9476: uint size = MapSize(); truelight@9476: uint i; truelight@9476: truelight@9476: SlSetLength(size); truelight@9476: for (i = 0; i != size;) { truelight@9476: uint8 buf[4096]; truelight@9476: uint j; truelight@9476: truelight@9476: for (j = 0; j != lengthof(buf); j++) buf[j] = _me[i++].m7; truelight@9476: SlArray(buf, lengthof(buf), SLE_UINT8); truelight@9476: } truelight@9476: } truelight@0: rubidium@6573: static void Save_CHTS() truelight@0: { truelight@0: byte count = sizeof(_cheats)/sizeof(Cheat); truelight@0: Cheat* cht = (Cheat*) &_cheats; truelight@0: Cheat* cht_last = &cht[count]; truelight@0: tron@2951: SlSetLength(count * 2); tron@2951: for (; cht != cht_last; cht++) { truelight@0: SlWriteByte(cht->been_used); truelight@0: SlWriteByte(cht->value); truelight@0: } truelight@0: } truelight@0: rubidium@6573: static void Load_CHTS() truelight@0: { tron@2989: Cheat* cht = (Cheat*)&_cheats; tron@2989: uint count = SlGetFieldLength() / 2; tron@2989: uint i; truelight@0: tron@2989: for (i = 0; i < count; i++) { rubidium@5838: cht[i].been_used = (SlReadByte() != 0); rubidium@5838: cht[i].value = (SlReadByte() != 0); truelight@0: } truelight@0: } truelight@0: truelight@0: rubidium@5838: extern const ChunkHandler _misc_chunk_handlers[] = { rubidium@4344: { 'MAPS', Save_MAPS, Load_MAPS, CH_RIFF }, rubidium@4344: { 'MAPT', Save_MAPT, Load_MAPT, CH_RIFF }, rubidium@4344: { 'MAPO', Save_MAP1, Load_MAP1, CH_RIFF }, rubidium@4344: { 'MAP2', Save_MAP2, Load_MAP2, CH_RIFF }, rubidium@4344: { 'M3LO', Save_MAP3, Load_MAP3, CH_RIFF }, rubidium@4344: { 'M3HI', Save_MAP4, Load_MAP4, CH_RIFF }, rubidium@4344: { 'MAP5', Save_MAP5, Load_MAP5, CH_RIFF }, belugas@5847: { 'MAPE', Save_MAP6, Load_MAP6, CH_RIFF }, truelight@9476: { 'MAP7', Save_MAP7, Load_MAP7, CH_RIFF }, truelight@0: rubidium@4344: { 'NAME', Save_NAME, Load_NAME, CH_ARRAY}, truelight@0: { 'DATE', SaveLoad_DATE, SaveLoad_DATE, CH_RIFF}, truelight@0: { 'VIEW', SaveLoad_VIEW, SaveLoad_VIEW, CH_RIFF}, rubidium@4344: { 'CHTS', Save_CHTS, Load_CHTS, CH_RIFF | CH_LAST} truelight@0: };