src/newgrf_station.cpp
changeset 5587 167d9a91ef02
parent 5584 1111b4d36e35
child 5609 dc6a58930ba4
equal deleted inserted replaced
5586:2d4126d81ebb 5587:167d9a91ef02
    15 #include "newgrf.h"
    15 #include "newgrf.h"
    16 #include "newgrf_callbacks.h"
    16 #include "newgrf_callbacks.h"
    17 #include "newgrf_station.h"
    17 #include "newgrf_station.h"
    18 #include "newgrf_spritegroup.h"
    18 #include "newgrf_spritegroup.h"
    19 #include "date.h"
    19 #include "date.h"
       
    20 #include "helpers.hpp"
    20 
    21 
    21 static StationClass station_classes[STAT_CLASS_MAX];
    22 static StationClass station_classes[STAT_CLASS_MAX];
    22 
    23 
    23 enum {
    24 enum {
    24 	MAX_SPECLIST = 255,
    25 	MAX_SPECLIST = 255,
    29  * This includes initialising the Default and Waypoint classes with an empty
    30  * This includes initialising the Default and Waypoint classes with an empty
    30  * entry, for standard stations and waypoints.
    31  * entry, for standard stations and waypoints.
    31  */
    32  */
    32 void ResetStationClasses(void)
    33 void ResetStationClasses(void)
    33 {
    34 {
    34 	StationClassID i;
    35 	for (StationClassID i = STAT_CLASS_BEGIN; i < STAT_CLASS_MAX; i++) {
    35 	for (i = 0; i < STAT_CLASS_MAX; i++) {
       
    36 		station_classes[i].id = 0;
    36 		station_classes[i].id = 0;
    37 		station_classes[i].name = STR_EMPTY;
    37 		station_classes[i].name = STR_EMPTY;
    38 		station_classes[i].stations = 0;
    38 		station_classes[i].stations = 0;
    39 
    39 
    40 		free(station_classes[i].spec);
    40 		free(station_classes[i].spec);
    43 
    43 
    44 	// Set up initial data
    44 	// Set up initial data
    45 	station_classes[0].id = 'DFLT';
    45 	station_classes[0].id = 'DFLT';
    46 	station_classes[0].name = STR_STAT_CLASS_DFLT;
    46 	station_classes[0].name = STR_STAT_CLASS_DFLT;
    47 	station_classes[0].stations = 1;
    47 	station_classes[0].stations = 1;
    48 	station_classes[0].spec = malloc(sizeof(*station_classes[0].spec));
    48 	MallocT(&station_classes[0].spec, 1);
    49 	station_classes[0].spec[0] = NULL;
    49 	station_classes[0].spec[0] = NULL;
    50 
    50 
    51 	station_classes[1].id = 'WAYP';
    51 	station_classes[1].id = 'WAYP';
    52 	station_classes[1].name = STR_STAT_CLASS_WAYP;
    52 	station_classes[1].name = STR_STAT_CLASS_WAYP;
    53 	station_classes[1].stations = 1;
    53 	station_classes[1].stations = 1;
    54 	station_classes[1].spec = malloc(sizeof(*station_classes[1].spec));
    54 	MallocT(&station_classes[1].spec, 1);
    55 	station_classes[1].spec[0] = NULL;
    55 	station_classes[1].spec[0] = NULL;
    56 }
    56 }
    57 
    57 
    58 /**
    58 /**
    59  * Allocate a station class for the given class id.
    59  * Allocate a station class for the given class id.
    60  * @param classid A 32 bit value identifying the class.
    60  * @param classid A 32 bit value identifying the class.
    61  * @return Index into station_classes of allocated class.
    61  * @return Index into station_classes of allocated class.
    62  */
    62  */
    63 StationClassID AllocateStationClass(uint32 class)
    63 StationClassID AllocateStationClass(uint32 cls)
    64 {
    64 {
    65 	StationClassID i;
    65 	for (StationClassID i = STAT_CLASS_BEGIN; i < STAT_CLASS_MAX; i++) {
    66 
    66 		if (station_classes[i].id == cls) {
    67 	for (i = 0; i < STAT_CLASS_MAX; i++) {
       
    68 		if (station_classes[i].id == class) {
       
    69 			// ClassID is already allocated, so reuse it.
    67 			// ClassID is already allocated, so reuse it.
    70 			return i;
    68 			return i;
    71 		} else if (station_classes[i].id == 0) {
    69 		} else if (station_classes[i].id == 0) {
    72 			// This class is empty, so allocate it to the ClassID.
    70 			// This class is empty, so allocate it to the ClassID.
    73 			station_classes[i].id = class;
    71 			station_classes[i].id = cls;
    74 			return i;
    72 			return i;
    75 		}
    73 		}
    76 	}
    74 	}
    77 
    75 
    78 	grfmsg(2, "StationClassAllocate: already allocated %d classes, using default", STAT_CLASS_MAX);
    76 	grfmsg(2, "StationClassAllocate: already allocated %d classes, using default", STAT_CLASS_MAX);
   148 
   146 
   149 	assert(statspec->sclass < STAT_CLASS_MAX);
   147 	assert(statspec->sclass < STAT_CLASS_MAX);
   150 	station_class = &station_classes[statspec->sclass];
   148 	station_class = &station_classes[statspec->sclass];
   151 
   149 
   152 	i = station_class->stations++;
   150 	i = station_class->stations++;
   153 	station_class->spec = realloc(station_class->spec, station_class->stations * sizeof(*station_class->spec));
   151 	ReallocT(&station_class->spec, station_class->stations);
   154 
   152 
   155 	station_class->spec[i] = statspec;
   153 	station_class->spec[i] = statspec;
   156 	statspec->allocated = true;
   154 	statspec->allocated = true;
   157 }
   155 }
   158 
   156 
   174 }
   172 }
   175 
   173 
   176 
   174 
   177 const StationSpec *GetCustomStationSpecByGrf(uint32 grfid, byte localidx)
   175 const StationSpec *GetCustomStationSpecByGrf(uint32 grfid, byte localidx)
   178 {
   176 {
   179 	StationClassID i;
       
   180 	uint j;
   177 	uint j;
   181 
   178 
   182 	for (i = STAT_CLASS_DFLT; i < STAT_CLASS_MAX; i++) {
   179 	for (StationClassID i = STAT_CLASS_BEGIN; i < STAT_CLASS_MAX; i++) {
   183 		for (j = 0; j < station_classes[i].stations; j++) {
   180 		for (j = 0; j < station_classes[i].stations; j++) {
   184 			const StationSpec *statspec = station_classes[i].spec[j];
   181 			const StationSpec *statspec = station_classes[i].spec[j];
   185 			if (statspec == NULL) continue;
   182 			if (statspec == NULL) continue;
   186 			if (statspec->grfid == grfid && statspec->localidx == localidx) return statspec;
   183 			if (statspec->grfid == grfid && statspec->localidx == localidx) return statspec;
   187 		}
   184 		}
   362 			case 0x44: return 2;               /* PBS status */
   359 			case 0x44: return 2;               /* PBS status */
   363 			case 0xFA: return max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0); /* Build date */
   360 			case 0xFA: return max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0); /* Build date */
   364 		}
   361 		}
   365 
   362 
   366 		*available = false;
   363 		*available = false;
   367 		return -1;
   364 		return UINT_MAX;
   368 	}
   365 	}
   369 
   366 
   370 	switch (variable) {
   367 	switch (variable) {
   371 		/* Calculated station variables */
   368 		/* Calculated station variables */
   372 		case 0x40: return GetPlatformInfoHelper(tile, false, false, false);
   369 		case 0x40: return GetPlatformInfoHelper(tile, false, false, false);
   428 	}
   425 	}
   429 
   426 
   430 	DEBUG(grf, 1, "Unhandled station property 0x%X", variable);
   427 	DEBUG(grf, 1, "Unhandled station property 0x%X", variable);
   431 
   428 
   432 	*available = false;
   429 	*available = false;
   433 	return -1;
   430 	return UINT_MAX;
   434 }
   431 }
   435 
   432 
   436 
   433 
   437 static const SpriteGroup *StationResolveReal(const ResolverObject *object, const SpriteGroup *group)
   434 static const SpriteGroup *StationResolveReal(const ResolverObject *object, const SpriteGroup *group)
   438 {
   435 {
   608 	if (i == MAX_SPECLIST) return -1;
   605 	if (i == MAX_SPECLIST) return -1;
   609 
   606 
   610 	if (exec) {
   607 	if (exec) {
   611 		if (i >= st->num_specs) {
   608 		if (i >= st->num_specs) {
   612 			st->num_specs = i + 1;
   609 			st->num_specs = i + 1;
   613 			st->speclist = realloc(st->speclist, st->num_specs * sizeof(*st->speclist));
   610 			ReallocT(&st->speclist, st->num_specs);
   614 
   611 
   615 			if (st->num_specs == 2) {
   612 			if (st->num_specs == 2) {
   616 				/* Initial allocation */
   613 				/* Initial allocation */
   617 				st->speclist[0].spec     = NULL;
   614 				st->speclist[0].spec     = NULL;
   618 				st->speclist[0].grfid    = 0;
   615 				st->speclist[0].grfid    = 0;
   654 	/* If this was the highest spec index, reallocate */
   651 	/* If this was the highest spec index, reallocate */
   655 	if (specindex == st->num_specs - 1) {
   652 	if (specindex == st->num_specs - 1) {
   656 		for (; st->speclist[st->num_specs - 1].grfid == 0 && st->num_specs > 1; st->num_specs--);
   653 		for (; st->speclist[st->num_specs - 1].grfid == 0 && st->num_specs > 1; st->num_specs--);
   657 
   654 
   658 		if (st->num_specs > 1) {
   655 		if (st->num_specs > 1) {
   659 			st->speclist = realloc(st->speclist, st->num_specs * sizeof(*st->speclist));
   656 			ReallocT(&st->speclist, st->num_specs);
   660 		} else {
   657 		} else {
   661 			free(st->speclist);
   658 			free(st->speclist);
   662 			st->num_specs = 0;
   659 			st->num_specs = 0;
   663 			st->speclist  = NULL;
   660 			st->speclist  = NULL;
   664 		}
   661 		}
   694 	}
   691 	}
   695 
   692 
   696 	if (statspec->renderdata == NULL) {
   693 	if (statspec->renderdata == NULL) {
   697 		sprites = GetStationTileLayout(tile + axis);
   694 		sprites = GetStationTileLayout(tile + axis);
   698 	} else {
   695 	} else {
   699 		sprites = &statspec->renderdata[(tile < statspec->tiles) ? tile + axis : axis];
   696 		sprites = &statspec->renderdata[(tile < statspec->tiles) ? tile + axis : (uint)axis];
   700 	}
   697 	}
   701 
   698 
   702 	image = sprites->ground_sprite;
   699 	image = sprites->ground_sprite;
   703 	if (HASBIT(image, 31)) {
   700 	if (HASBIT(image, 31)) {
   704 		CLRBIT(image, 31);
   701 		CLRBIT(image, 31);