@@ -1006,26 +1006,25 @@ static bool CheckSubsidyDuplicate(Subsid
static void SubsidyMonthlyHandler(void)
{
Subsidy *s;
Pair pair;
Station *st;
uint n;
FoundRoute fr;
bool modified = false;
for(s=_subsidies; s != endof(_subsidies); s++) {
if (s->cargo_type == CT_INVALID)
continue;
if (s->cargo_type == CT_INVALID) continue;
if (s->age == 12-1) {
pair = SetupSubsidyDecodeParam(s, 1);
AddNewsItem(STR_202E_OFFER_OF_SUBSIDY_EXPIRED, NEWS_FLAGS(NM_NORMAL, NF_TILE, NT_SUBSIDIES, 0), pair.a, pair.b);
s->cargo_type = CT_INVALID;
modified = true;
} else if (s->age == 2*12-1) {
st = GetStation(s->to);
if (st->owner == _local_player) {
AddNewsItem(STR_202F_SUBSIDY_WITHDRAWN_SERVICE, NEWS_FLAGS(NM_NORMAL, NF_TILE, NT_SUBSIDIES, 0), pair.a, pair.b);
}
@@ -214,26 +214,25 @@ void GenerateWorld(int mode, uint size_x
GenerateUnmovables();
// These are probably pointless when inside the scenario editor.
StartupPlayers();
StartupEngines();
StartupDisasters();
_generating_world = false;
// No need to run the tile loop in the scenario editor.
if (mode != GW_EMPTY) {
for(i=0x500; i!=0; i--)
RunTileLoop();
for (i = 0x500; i != 0; i--) RunTileLoop();
ResetObjectToPlace();
void DeleteName(StringID id)
if ((id & 0xF800) == 0x7800) {
memset(_name_array[id & 0x1FF], 0, sizeof(_name_array[id & 0x1FF]));
@@ -1367,26 +1367,27 @@ static void SaveLoadDlgWndProc(Window *w
UpdateTextBufferSize(&WP(w, querystr_d).text);
} else if (HASBIT(w->click_state, 12)) { /* Save button clicked */
_switch_mode = SM_SAVE;
FiosMakeSavegameName(_file_to_saveload.name, WP(w,querystr_d).text.buf);
/* In the editor set up the vehicle engines correctly (date might have changed) */
if (_game_mode == GM_EDITOR) StartupEngines();
break;
case WE_DESTROY:
// pause is only used in single-player, non-editor mode, non menu mode
if(!_networking && (_game_mode != GM_EDITOR) && (_game_mode != GM_MENU))
if (!_networking && _game_mode != GM_EDITOR && _game_mode != GM_MENU) {
DoCommandP(0, 0, 0, NULL, CMD_PAUSE);
FiosFreeSavegameList();
CLRBIT(_no_scroll, SCROLL_SAVE);
case WE_RESIZE: {
/* Widget 2 and 3 have to go with halve speed, make it so obiwan */
uint diff = e->sizing.diff.x / 2;
w->widget[2].right += diff;
w->widget[3].left += diff;
w->widget[3].right += e->sizing.diff.x;
/* Same for widget 11 and 12 in save-dialog */
if (_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO) {
@@ -367,26 +367,25 @@ bad_town_name:;
static const byte _color_sort[16] = {2, 2, 3, 2, 3, 2, 3, 2, 3, 2, 2, 2, 3, 1, 1, 1};
static const byte _color_similar_1[16] = {8, 6, 255, 12, 255, 0, 1, 1, 0, 13, 11, 10, 3, 9, 15, 14};
static const byte _color_similar_2[16] = {5, 7, 255, 255, 255, 8, 7, 6, 5, 12, 255, 255, 9, 255, 255, 255};
static byte GeneratePlayerColor(void)
byte colors[16], pcolor, t2;
int i,j,n;
uint32 r;
Player *p;
// Initialize array
for(i=0; i!=16; i++)
colors[i] = i;
for (i = 0; i != 16; i++) colors[i] = i;
// And randomize it
n = 100;
do {
r = Random();
COLOR_SWAP(GB(r, 0, 4), GB(r, 4, 4));
} while (--n);
// Bubble sort it according to the values in table 1
i = 16;
for(j=0; j!=15; j++) {
@@ -1244,25 +1243,26 @@ static const SaveLoad _player_ai_build_r
SLE_CONDVAR(AiBuildRec,use_tile, SLE_UINT32, 6, 255),
SLE_VAR(AiBuildRec,rand_rng, SLE_UINT8),
SLE_VAR(AiBuildRec,cur_building_rule,SLE_UINT8),
SLE_VAR(AiBuildRec,unk6, SLE_UINT8),
SLE_VAR(AiBuildRec,unk7, SLE_UINT8),
SLE_VAR(AiBuildRec,buildcmd_a, SLE_UINT8),
SLE_VAR(AiBuildRec,buildcmd_b, SLE_UINT8),
SLE_VAR(AiBuildRec,direction, SLE_UINT8),
SLE_VAR(AiBuildRec,cargo, SLE_UINT8),
SLE_END()
};
static void SaveLoad_PLYR(Player *p) {
static void SaveLoad_PLYR(Player* p)
int i;
SlObject(p, _player_desc);
// Write AI?
if (!IS_HUMAN_PLAYER(p->index)) {
SlObject(&p->ai, _player_ai_desc);
for(i=0; i!=p->ai.num_build_rec; i++)
SlObject(&p->ai.src + i, _player_ai_build_rec_desc);
// Write economy
@@ -769,29 +769,27 @@ static void SlSaveChunks(void)
/** Find the ChunkHandler that will be used for processing the found
* chunk in the savegame or in memory
* @param id the chunk in question
* @return returns the appropiate chunkhandler
*/
static const ChunkHandler *SlFindChunkHandler(uint32 id)
const ChunkHandler *ch;
const ChunkHandler *const *chsc;
for (chsc = _sl.chs; (ch=*chsc++) != NULL;) {
while(true) {
if (ch->id == id)
return ch;
if (ch->flags & CH_LAST)
for (;;) {
if (ch->id == id) return ch;
if (ch->flags & CH_LAST) break;
ch++;
return NULL;
/** Load all chunks */
static void SlLoadChunks(void)
uint32 id;
@@ -421,24 +421,25 @@ static bool load_intlist(const char *str
default:
NOT_REACHED();
return true;
static void make_intlist(char *buf, void *array, int nelems, int type)
int i, v = 0;
byte *p = (byte*)array;
for(i=0; i!=nelems; i++) {
switch(type) {
case SDT_INT8 >> 4: v = *(int8*)p; p += 1; break;
case SDT_UINT8 >> 4:v = *(byte*)p; p += 1; break;
case SDT_INT16 >> 4:v = *(int16*)p; p += 2; break;
case SDT_UINT16 >> 4:v = *(uint16*)p; p += 2; break;
case SDT_INT32 >> 4:v = *(int32*)p; p += 4; break;
case SDT_UINT32 >> 4:v = *(uint32*)p; p += 4; break;
default: NOT_REACHED();
buf += sprintf(buf, i ? ",%d" : "%d", v);
@@ -295,26 +295,25 @@ char *ParseWord(char **buf)
*buf = s;
return r;
// Forward declaration
static int TranslateArgumentIdx(int arg);
static void EmitWordList(char **words, int nw)
int i,j;
PutByte(nw);
for(i=0; i<nw; i++)
PutByte(strlen(words[i]));
for (i = 0; i < nw; i++) PutByte(strlen(words[i]));
for(i=0; i<nw; i++) {
for(j=0; words[i][j]; j++)
PutByte(words[i][j]);
static void EmitPlural(char *buf, int value)
int argidx = _cur_argidx;
char *words[5];
int nw = 0;
@@ -356,26 +355,25 @@ static void EmitPlural(char *buf, int va
static void EmitGender(char *buf, int value)
char *words[8];
int nw;
if (buf[0] == '=') {
buf++;
// This is a {G=DER} command
for(nw=0; ;nw++) {
if (nw >= 8)
Fatal("G argument '%s' invalid", buf);
if (nw >= 8) Fatal("G argument '%s' invalid", buf);
if (!strcmp(buf, _genders[nw]))
// now nw contains the gender index
PutByte(0x87);
} else {
// This is a {G 0 foo bar two} command.
// If no relative number exists, default to +0
if (!ParseRelNum(&buf, &argidx)) {}
@@ -457,24 +457,25 @@ static int DeterminePluralForm(int32 n)
// Used in:
// Slovenian
case 8:
return n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;
static const char *ParseStringChoice(const char *b, uint form, char *dst, int *dstlen)
//<NUM> {Length of each string} {each string}
uint n = (byte)*b++;
uint pos,i, mylen=0,mypos=0;
for(i=pos=0; i!=n; i++) {
uint len = (byte)*b++;
if (i == form) {
mypos = pos;
mylen = len;
pos += len;
*dstlen = mylen;
memcpy(dst, b + mypos, mylen);
return b + pos;
@@ -1164,26 +1164,25 @@ static bool CheckFree2x2Area(Town *t1, T
static const TileIndexDiffC _tile_add[] = {
{0 , 0 },
{0 - 0, 1 - 0},
{1 - 0, 0 - 1},
{1 - 1, 1 - 0}
for(i=0; i!=4; i++) {
tile += ToTileIndexDiff(_tile_add[i]);
if (GetTileSlope(tile, NULL))
return false;
if (GetTileSlope(tile, NULL)) return false;
if (CmdFailed(DoCommandByTile(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER | DC_FORCETEST, CMD_LANDSCAPE_CLEAR)))
static void DoBuildTownHouse(Town *t, TileIndex tile)
uint bitmask;
@@ -2205,25 +2205,25 @@ static bool CheckReverseTrain(Vehicle *v
ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, last->tile, trackdir_rev, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.railtype);
if (ftd.best_bird_dist != 0) {
/* We didn't find anything, just keep on going straight ahead */
reverse_best = false;
if (NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE))
reverse_best = true;
else
fd.best_bird_dist = (uint)-1;
fd.best_track_dist = (uint)-1;
NewTrainPathfind(v->tile, v->dest_tile, reverse ^ i, (NTPEnumProc*)NtpCallbFindStation, &fd);
if (best_track != -1) {
if (best_bird_dist != 0) {
if (fd.best_bird_dist != 0) {
/* neither reached the destination, pick the one with the smallest bird dist */
if (fd.best_bird_dist > best_bird_dist) goto bad;
if (fd.best_bird_dist < best_bird_dist) goto good;
@@ -999,26 +999,32 @@ static void DrawBridgePillars(const Tile
if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
p = _tileh_bits[(image & 1) * 2 + (ti->map5&0x01)];
front_height = ti->z + ((ti->tileh & p[0])?8:0);
back_height = ti->z + ((ti->tileh & p[1])?8:0);
if (IsSteepTileh(ti->tileh)) {
if (!(ti->tileh & p[2])) front_height += 8;
if (!(ti->tileh & p[3])) back_height += 8;
for(; z>=front_height || z>=back_height; z=z-8) {
if (z>=front_height) AddSortableSpriteToDraw(image, x,y, p[4], p[5], 0x28, z); // front facing pillar
if (z>=back_height && z<i-8) AddSortableSpriteToDraw(image, x - p[6], y - p[7], p[4], p[5], 0x28, z); // back facing pillar
if (z >= front_height) {
// front facing pillar
AddSortableSpriteToDraw(image, x,y, p[4], p[5], 0x28, z);
if (z >= back_height && z < i - 8) {
// back facing pillar
AddSortableSpriteToDraw(image, x - p[6], y - p[7], p[4], p[5], 0x28, z);
uint GetBridgeFoundation(uint tileh, byte direction)
// normal level sloped building (7, 11, 13, 14)
if (BRIDGE_FULL_LEVELED_FOUNDATION & (1 << tileh))
return tileh;
// inclined sloped building
@@ -1936,26 +1936,25 @@ byte GetDirectionTowards(const Vehicle *
dir = v->direction;
dirdiff = _new_direction_table[i] - dir;
if (dirdiff == 0)
return dir;
return (dir+((dirdiff&7)<5?1:-1)) & 7;
Trackdir GetVehicleTrackdir(const Vehicle* v)
if (v->vehstatus & VS_CRASHED) return 0xFF;
switch(v->type)
switch (v->type) {
case VEH_Train:
if (v->u.rail.track == 0x80) /* We'll assume the train is facing outwards */
return DiagdirToDiagTrackdir(GetDepotDirection(v->tile, TRANSPORT_RAIL)); /* Train in depot */
if (v->u.rail.track == 0x40) /* train in tunnel, so just use his direction and assume a diagonal track */
return DiagdirToDiagTrackdir((v->direction >> 1) & 3);
return TrackDirectionToTrackdir(FIND_FIRST_BIT(v->u.rail.track),v->direction);
case VEH_Ship:
if (v->u.ship.state == 0x80) /* Inside a depot? */
/* We'll assume the ship is facing outwards */
@@ -700,25 +700,25 @@ static void CheckPaletteAnim(void)
if (_pal_last_dirty == -1)
return;
InvalidateRect(_wnd.main_wnd, NULL, FALSE);
static void Win32GdiMainLoop(void)
MSG mesg;
uint32 next_tick = GetTickCount() + 30, cur_ticks;
_wnd.running = true;
while (PeekMessage(&mesg, NULL, 0, 0, PM_REMOVE)) {
InteractiveRandom(); // randomness
TranslateMessage(&mesg);
DispatchMessage(&mesg);
if (_exit_game) return;
#if defined(_DEBUG)
if (_wnd.has_focus && GetAsyncKeyState(VK_SHIFT) < 0) {
if (
#else
if (_wnd.has_focus && GetAsyncKeyState(VK_TAB) < 0) {
@@ -132,25 +132,25 @@ static void GetFileInfo(DebugFileInfo *d
HANDLE file;
byte buffer[1024];
DWORD numread;
uint32 filesize = 0;
FILETIME write_time;
uint32 crc = (uint32)-1;
file = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, 0);
if (file != INVALID_HANDLE_VALUE) {
if (ReadFile(file, buffer, sizeof(buffer), &numread, NULL) == 0 ||
numread == 0)
filesize += numread;
crc = CalcCRC(buffer, numread, crc);
dfi->size = filesize;
dfi->crc32 = crc ^ (uint32)-1;
if (GetFileTime(file, NULL, NULL, &write_time)) {
FileTimeToSystemTime(&write_time, &dfi->file_time);
Status change: