mirror of https://github.com/OpenTTD/OpenTTD
(svn r15764) [0.7] -Backport from trunk:
- Fix: Number of houses in house variables 0x44, 0x60 and 0x61 were incorrect after 0xFF had been reached and could desync clients joining afterwards (r15755) - Fix: Crash when clicking the small area between the savegame list and the save button in the save game window [FS#2742] (r15753) - Fix: Do not try to (un)draw the cursor when the screen is not ready (r15752) - Fix: The big UFO sometimes landed just outside the map. Instead of landing, just disappear (fly away) in those cases (r15750) - Fix: Crash because submarines would sometimes start far outside of the map [FS#2739] (r15748) - Fix: Road ownership getting lost when removing a road stop [FS#2736] (r15747) - Fix: Update threading code for OS/2, add mutex support, fix compilation (r15746, r15745) - Fix: When town generator failed to create requested number of towns, there were too many cities (r15744)release/0.7
parent
de7a4a4006
commit
9e592b9986
|
@ -566,6 +566,12 @@ static void DisasterTick_Big_Ufo(Vehicle *v)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!IsValidTile(v->dest_tile)) {
|
||||
/* Make sure we don't land outside the map. */
|
||||
delete v;
|
||||
return;
|
||||
}
|
||||
|
||||
z = GetSlopeZ(v->x_pos, v->y_pos);
|
||||
if (z < v->z_pos) {
|
||||
SetDisasterVehiclePos(v, v->x_pos, v->y_pos, v->z_pos - 1);
|
||||
|
@ -885,7 +891,7 @@ static void Disaster_Submarine_Init(DisasterSubType subtype)
|
|||
int x = TileX(r) * TILE_SIZE + TILE_SIZE / 2;
|
||||
|
||||
if (HasBit(r, 31)) {
|
||||
y = MapMaxX() * TILE_SIZE - TILE_SIZE / 2 - 1;
|
||||
y = MapMaxY() * TILE_SIZE - TILE_SIZE / 2 - 1;
|
||||
dir = DIR_NW;
|
||||
} else {
|
||||
y = TILE_SIZE / 2;
|
||||
|
|
|
@ -829,7 +829,7 @@ void ChangeWorkingDirectory(const char *exe)
|
|||
void DetermineBasePaths(const char *exe)
|
||||
{
|
||||
char tmp[MAX_PATH];
|
||||
#if defined(__MORPHOS__) || defined(__AMIGA__) || defined(DOS) || !defined(WITH_PERSONAL_DIR)
|
||||
#if defined(__MORPHOS__) || defined(__AMIGA__) || defined(DOS) || defined(OS2) || !defined(WITH_PERSONAL_DIR)
|
||||
_searchpaths[SP_PERSONAL_DIR] = NULL;
|
||||
#else
|
||||
const char *homedir = getenv("HOME");
|
||||
|
@ -867,7 +867,7 @@ void DetermineBasePaths(const char *exe)
|
|||
AppendPathSeparator(tmp, MAX_PATH);
|
||||
_searchpaths[SP_BINARY_DIR] = strdup(tmp);
|
||||
|
||||
#if defined(__MORPHOS__) || defined(__AMIGA__) || defined(DOS)
|
||||
#if defined(__MORPHOS__) || defined(__AMIGA__) || defined(DOS) || defined(OS2)
|
||||
_searchpaths[SP_INSTALLATION_DIR] = NULL;
|
||||
#else
|
||||
snprintf(tmp, MAX_PATH, "%s", GLOBAL_DATA_DIR);
|
||||
|
|
|
@ -1285,6 +1285,9 @@ void ScreenSizeChanged()
|
|||
|
||||
void UndrawMouseCursor()
|
||||
{
|
||||
/* Don't undraw the mouse cursor if the screen is not ready */
|
||||
if (_screen.dst_ptr == NULL) return;
|
||||
|
||||
if (_cursor.visible) {
|
||||
Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter();
|
||||
_cursor.visible = false;
|
||||
|
@ -1300,6 +1303,9 @@ void DrawMouseCursor()
|
|||
return;
|
||||
#endif
|
||||
|
||||
/* Don't draw the mouse cursor if the screen is not ready */
|
||||
if (_screen.dst_ptr == NULL) return;
|
||||
|
||||
Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter();
|
||||
int x;
|
||||
int y;
|
||||
|
|
|
@ -1361,11 +1361,11 @@ static const Widget _save_dialog_widgets[] = {
|
|||
{ WWT_PUSHTXTBTN, RESIZE_NONE, COLOUR_GREY, 0, 127, 14, 25, STR_SORT_BY_NAME, STR_SORT_ORDER_TIP},
|
||||
{ WWT_PUSHTXTBTN, RESIZE_NONE, COLOUR_GREY, 128, 256, 14, 25, STR_SORT_BY_DATE, STR_SORT_ORDER_TIP},
|
||||
{ WWT_PANEL, RESIZE_RIGHT, COLOUR_GREY, 0, 256, 26, 47, 0x0, STR_NULL},
|
||||
{ WWT_PANEL, RESIZE_RB, COLOUR_GREY, 0, 256, 48, 151, 0x0, STR_NULL},
|
||||
{ WWT_PANEL, RESIZE_RB, COLOUR_GREY, 0, 256, 48, 167, 0x0, STR_NULL},
|
||||
{ WWT_PUSHIMGBTN, RESIZE_LR, COLOUR_GREY, 245, 256, 48, 59, SPR_HOUSE_ICON, STR_SAVELOAD_HOME_BUTTON},
|
||||
{ WWT_INSET, RESIZE_RB, COLOUR_GREY, 2, 243, 50, 150, 0x0, STR_400A_LIST_OF_DRIVES_DIRECTORIES},
|
||||
{ WWT_SCROLLBAR, RESIZE_LRB, COLOUR_GREY, 245, 256, 60, 151, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
|
||||
{ WWT_PANEL, RESIZE_RTB, COLOUR_GREY, 0, 256, 152, 167, 0x0, STR_NULL},
|
||||
{ WWT_PANEL, RESIZE_RTB, COLOUR_GREY, 0, 256, 152, 0, 0x0, STR_NULL},
|
||||
{ WWT_EDITBOX, RESIZE_RTB, COLOUR_GREY, 2, 254, 154, 165, STR_SAVE_OSKTITLE, STR_400B_CURRENTLY_SELECTED_NAME},
|
||||
{ WWT_PUSHTXTBTN, RESIZE_TB, COLOUR_GREY, 0, 127, 168, 179, STR_4003_DELETE, STR_400C_DELETE_THE_CURRENTLY_SELECTED},
|
||||
{ WWT_PUSHTXTBTN, RESIZE_TB, COLOUR_GREY, 128, 244, 168, 179, STR_4002_SAVE, STR_400D_SAVE_THE_CURRENT_GAME_USING},
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "animated_tile_func.h"
|
||||
#include "company_base.h"
|
||||
|
||||
static BuildingCounts _building_counts;
|
||||
static BuildingCounts<uint32> _building_counts;
|
||||
static HouseClassMapping _class_mapping[HOUSE_CLASS_MAX];
|
||||
|
||||
HouseOverrideManager _house_mngr(NEW_HOUSE_OFFSET, HOUSE_MAX, INVALID_HOUSE_ID);
|
||||
|
@ -61,20 +61,13 @@ void IncreaseBuildingCount(Town *t, HouseID house_id)
|
|||
|
||||
if (!_loaded_newgrf_features.has_newhouses) return;
|
||||
|
||||
/* If there are 255 buildings of this type in this town, there are also
|
||||
* at least that many houses of the same class in the town, and
|
||||
* therefore on the map as well. */
|
||||
if (t->building_counts.id_count[house_id] == 255) return;
|
||||
|
||||
t->building_counts.id_count[house_id]++;
|
||||
if (_building_counts.id_count[house_id] < 255) _building_counts.id_count[house_id]++;
|
||||
_building_counts.id_count[house_id]++;
|
||||
|
||||
/* Similarly, if there are 255 houses of this class in this town, there
|
||||
* must be at least that number on the map too. */
|
||||
if (class_id == HOUSE_NO_CLASS || t->building_counts.class_count[class_id] == 255) return;
|
||||
if (class_id == HOUSE_NO_CLASS) return;
|
||||
|
||||
t->building_counts.class_count[class_id]++;
|
||||
if (_building_counts.class_count[class_id] < 255) _building_counts.class_count[class_id]++;
|
||||
_building_counts.class_count[class_id]++;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -121,10 +114,10 @@ static uint32 GetNumHouses(HouseID house_id, const Town *town)
|
|||
uint8 map_id_count, town_id_count, map_class_count, town_class_count;
|
||||
HouseClassID class_id = GetHouseSpecs(house_id)->class_id;
|
||||
|
||||
map_id_count = _building_counts.id_count[house_id];
|
||||
map_class_count = _building_counts.class_count[class_id];
|
||||
town_id_count = town->building_counts.id_count[house_id];
|
||||
town_class_count = town->building_counts.class_count[class_id];
|
||||
map_id_count = ClampU(_building_counts.id_count[house_id], 0, 255);
|
||||
map_class_count = ClampU(_building_counts.class_count[class_id], 0, 255);
|
||||
town_id_count = ClampU(town->building_counts.id_count[house_id], 0, 255);
|
||||
town_class_count = ClampU(town->building_counts.class_count[class_id], 0, 255);
|
||||
|
||||
return map_class_count << 24 | town_class_count << 16 | map_id_count << 8 | town_id_count;
|
||||
}
|
||||
|
|
|
@ -1632,6 +1632,8 @@ CommandCost CmdRemoveRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, ui
|
|||
((GetRoadStopDir(tile) == DIAGDIR_NE) ? ROAD_X : ROAD_Y) :
|
||||
DiagDirToRoadBits(GetRoadStopDir(tile));
|
||||
|
||||
Owner road_owner = GetRoadOwner(tile, ROADTYPE_ROAD);
|
||||
Owner tram_owner = GetRoadOwner(tile, ROADTYPE_TRAM);
|
||||
CommandCost ret = RemoveRoadStop(st, flags, tile);
|
||||
|
||||
/* If the stop was a drive-through stop replace the road */
|
||||
|
@ -1640,7 +1642,7 @@ CommandCost CmdRemoveRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, ui
|
|||
* removed by the owner of the roadstop, _current_company is the
|
||||
* owner of the road stop. */
|
||||
MakeRoadNormal(tile, road_bits, rts, ClosestTownFromTile(tile, UINT_MAX)->index,
|
||||
GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM));
|
||||
road_owner, tram_owner);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -1,66 +1,116 @@
|
|||
/* $Id$ */
|
||||
|
||||
/** @file thread_os2.cpp OS2 implementation of Threads. */
|
||||
/** @file thread_os2.cpp OS/2 implementation of Threads. */
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "thread.h"
|
||||
|
||||
#if 0
|
||||
#include "debug.h"
|
||||
#include "core/alloc_func.hpp"
|
||||
#include <stdlib.h>
|
||||
|
||||
#define INCL_DOS
|
||||
#include <os2.h>
|
||||
#include <process.h>
|
||||
|
||||
struct OTTDThread {
|
||||
TID thread;
|
||||
OTTDThreadFunc func;
|
||||
void *arg;
|
||||
void *ret;
|
||||
/**
|
||||
* OS/2 version for ThreadObject.
|
||||
*/
|
||||
class ThreadObject_OS2 : public ThreadObject {
|
||||
private:
|
||||
TID thread; ///< System thread identifier.
|
||||
OTTDThreadFunc proc; ///< External thread procedure.
|
||||
void *param; ///< Parameter for the external thread procedure.
|
||||
bool self_destruct; ///< Free ourselves when done?
|
||||
|
||||
public:
|
||||
/**
|
||||
* Create a thread and start it, calling proc(param).
|
||||
*/
|
||||
ThreadObject_OS2(OTTDThreadFunc proc, void *param, bool self_destruct) :
|
||||
thread(0),
|
||||
proc(proc),
|
||||
param(param),
|
||||
self_destruct(self_destruct)
|
||||
{
|
||||
thread = _beginthread(stThreadProc, NULL, 32768, this);
|
||||
}
|
||||
|
||||
/* virtual */ bool Exit()
|
||||
{
|
||||
_endthread();
|
||||
return true;
|
||||
}
|
||||
|
||||
/* virtual */ void Join()
|
||||
{
|
||||
DosWaitThread(&this->thread, DCWW_WAIT);
|
||||
this->thread = 0;
|
||||
}
|
||||
private:
|
||||
/**
|
||||
* On thread creation, this function is called, which calls the real startup
|
||||
* function. This to get back into the correct instance again.
|
||||
*/
|
||||
static void stThreadProc(void *thr)
|
||||
{
|
||||
((ThreadObject_OS2 *)thr)->ThreadProc();
|
||||
}
|
||||
|
||||
/**
|
||||
* A new thread is created, and this function is called. Call the custom
|
||||
* function of the creator of the thread.
|
||||
*/
|
||||
void ThreadProc()
|
||||
{
|
||||
/* Call the proc of the creator to continue this thread */
|
||||
try {
|
||||
this->proc(this->param);
|
||||
} catch (OTTDThreadExitSignal e) {
|
||||
} catch (...) {
|
||||
NOT_REACHED();
|
||||
}
|
||||
|
||||
if (self_destruct) {
|
||||
this->Exit();
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static void Proxy(void *arg)
|
||||
/* static */ bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread)
|
||||
{
|
||||
OTTDThread *t = (OTTDThread *)arg;
|
||||
t->ret = t->func(t->arg);
|
||||
ThreadObject *to = new ThreadObject_OS2(proc, param, thread == NULL);
|
||||
if (thread != NULL) *thread = to;
|
||||
return true;
|
||||
}
|
||||
|
||||
OTTDThread *OTTDCreateThread(OTTDThreadFunc function, void *arg)
|
||||
{
|
||||
OTTDThread *t = MallocT<OTTDThread>(1);
|
||||
/**
|
||||
* OS/2 version of ThreadMutex.
|
||||
*/
|
||||
class ThreadMutex_OS2 : public ThreadMutex {
|
||||
private:
|
||||
HMTX mutex;
|
||||
|
||||
t->func = function;
|
||||
t->arg = arg;
|
||||
t->thread = _beginthread(Proxy, NULL, 32768, t);
|
||||
if (t->thread != (TID)-1) {
|
||||
return t;
|
||||
} else {
|
||||
free(t);
|
||||
return NULL;
|
||||
public:
|
||||
ThreadMutex_OS2()
|
||||
{
|
||||
DosCreateMutexSem(NULL, &mutex, 0, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void *OTTDJoinThread(OTTDThread *t)
|
||||
/* virtual */ ~ThreadMutex_OS2()
|
||||
{
|
||||
DosCloseMutexSem(mutex);
|
||||
}
|
||||
|
||||
/* virtual */ void BeginCritical()
|
||||
{
|
||||
DosRequestMutexSem(mutex, (unsigned long) SEM_INDEFINITE_WAIT);
|
||||
}
|
||||
|
||||
/* virtual */ void EndCritical()
|
||||
{
|
||||
DosReleaseMutexSem(mutex);
|
||||
}
|
||||
};
|
||||
|
||||
/* static */ ThreadMutex *ThreadMutex::New()
|
||||
{
|
||||
if (t == NULL) return NULL;
|
||||
|
||||
DosWaitThread(&t->thread, DCWW_WAIT);
|
||||
void *ret = t->ret;
|
||||
free(t);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void OTTDExitThread()
|
||||
{
|
||||
_endthread();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* static */ ThreadObject *ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread)
|
||||
{
|
||||
if (thread != NULL) *thread = NULL;
|
||||
return false;
|
||||
return new ThreadMutex_OS2();
|
||||
}
|
||||
|
|
|
@ -90,9 +90,10 @@ enum HouseExtraFlags {
|
|||
|
||||
DECLARE_ENUM_AS_BIT_SET(HouseExtraFlags)
|
||||
|
||||
template <typename T>
|
||||
struct BuildingCounts {
|
||||
uint8 id_count[HOUSE_MAX];
|
||||
uint8 class_count[HOUSE_CLASS_MAX];
|
||||
T id_count[HOUSE_MAX];
|
||||
T class_count[HOUSE_CLASS_MAX];
|
||||
};
|
||||
|
||||
static const uint CUSTOM_TOWN_NUMBER_DIFFICULTY = 4; ///< value for custom town number in difficulty settings
|
||||
|
@ -176,7 +177,7 @@ struct Town : PoolItem<Town, TownID, &_Town_pool> {
|
|||
uint32 squared_town_zone_radius[HZB_END];
|
||||
|
||||
/* NOSAVE: The number of each type of building in the town. */
|
||||
BuildingCounts building_counts;
|
||||
BuildingCounts<uint16> building_counts;
|
||||
|
||||
/**
|
||||
* Creates a new town
|
||||
|
|
|
@ -1636,19 +1636,18 @@ bool GenerateTowns(TownLayout layout)
|
|||
uint num = 0;
|
||||
uint difficulty = _settings_game.difficulty.number_towns;
|
||||
uint n = (difficulty == (uint)CUSTOM_TOWN_NUMBER_DIFFICULTY) ? _settings_game.game_creation.custom_town_number : ScaleByMapSize(_num_initial_towns[difficulty] + (Random() & 7));
|
||||
uint num_cities = _settings_game.economy.larger_towns == 0 ? 0 : n / _settings_game.economy.larger_towns;
|
||||
|
||||
SetGeneratingWorldProgress(GWP_TOWN, n);
|
||||
|
||||
do {
|
||||
bool city = (_settings_game.economy.larger_towns != 0 && Chance16(1, _settings_game.economy.larger_towns));
|
||||
IncreaseGeneratingWorldProgress(GWP_TOWN);
|
||||
/* try 20 times to create a random-sized town for the first loop. */
|
||||
if (CreateRandomTown(20, TS_RANDOM, num_cities > 0, layout) != NULL) num++;
|
||||
if (num_cities > 0) num_cities--;
|
||||
if (CreateRandomTown(20, TS_RANDOM, city, layout) != NULL) num++;
|
||||
} while (--n);
|
||||
|
||||
/* give it a last try, but now more aggressive */
|
||||
if (num == 0 && CreateRandomTown(10000, TS_RANDOM, false, layout) == NULL) {
|
||||
if (num == 0 && CreateRandomTown(10000, TS_RANDOM, _settings_game.economy.larger_towns != 0, layout) == NULL) {
|
||||
if (GetNumTowns() == 0) {
|
||||
if (_game_mode != GM_EDITOR) {
|
||||
extern StringID _switch_mode_errorstr;
|
||||
|
|
Loading…
Reference in New Issue