src/newgrf_spritegroup.cpp
branchNewGRF_ports
changeset 6870 ca3fd1fbe311
parent 6800 6c09e1e86fcb
child 6871 5a9dc001e1ad
equal deleted inserted replaced
6869:76282d3b748d 6870:ca3fd1fbe311
    74 	_SpriteGroup_pool.CleanPool();
    74 	_SpriteGroup_pool.CleanPool();
    75 
    75 
    76 	_spritegroup_count = 0;
    76 	_spritegroup_count = 0;
    77 }
    77 }
    78 
    78 
    79 uint32 _temp_store[0x110];
    79 TemporaryStorageArray<uint32, 0x110> _temp_store;
    80 
    80 
    81 
    81 
    82 static inline uint32 GetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
    82 static inline uint32 GetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
    83 {
    83 {
    84 	/* Return common variables */
    84 	/* Return common variables */
    96 		case 0x1A: return UINT_MAX;
    96 		case 0x1A: return UINT_MAX;
    97 		case 0x1B: return GB(_display_opt, 0, 6);
    97 		case 0x1B: return GB(_display_opt, 0, 6);
    98 		case 0x1C: return object->last_value;
    98 		case 0x1C: return object->last_value;
    99 		case 0x20: return _opt.landscape == LT_ARCTIC ? GetSnowLine() : 0xFF;
    99 		case 0x20: return _opt.landscape == LT_ARCTIC ? GetSnowLine() : 0xFF;
   100 
   100 
   101 		case 0x7D: return _temp_store[parameter];
   101 		case 0x7D: return _temp_store.Get(parameter);
   102 
   102 
   103 		/* Not a common variable, so evalute the feature specific variables */
   103 		/* Not a common variable, so evalute the feature specific variables */
   104 		default: return object->GetVariable(object, variable, parameter, available);
   104 		default: return object->GetVariable(object, variable, parameter, available);
   105 	}
   105 	}
       
   106 }
       
   107 
       
   108 
       
   109 /**
       
   110  * Rotate val rot times to the right
       
   111  * @param val the value to rotate
       
   112  * @param rot the amount of times to rotate
       
   113  * @return the rotated value
       
   114  */
       
   115 static uint32 RotateRight(uint32 val, uint32 rot)
       
   116 {
       
   117 	/* Do not rotate more than necessary */
       
   118 	rot %= 32;
       
   119 
       
   120 	return (val >> rot) | (val << (32 - rot));
   106 }
   121 }
   107 
   122 
   108 
   123 
   109 /* Evaluate an adjustment for a variable of the given size.
   124 /* Evaluate an adjustment for a variable of the given size.
   110 * U is the unsigned type and S is the signed type to use. */
   125 * U is the unsigned type and S is the signed type to use. */
   111 template <typename U, typename S>
   126 template <typename U, typename S>
   112 static U EvalAdjustT(const DeterministicSpriteGroupAdjust *adjust, U last_value, uint32 value)
   127 static U EvalAdjustT(const DeterministicSpriteGroupAdjust *adjust, ResolverObject *object, U last_value, uint32 value)
   113 {
   128 {
   114 	value >>= adjust->shift_num;
   129 	value >>= adjust->shift_num;
   115 	value  &= adjust->and_mask;
   130 	value  &= adjust->and_mask;
   116 
   131 
   117 	if (adjust->type != DSGA_TYPE_NONE) value += (S)adjust->add_val;
   132 	if (adjust->type != DSGA_TYPE_NONE) value += (S)adjust->add_val;
   135 		case DSGA_OP_UMOD: return value == 0 ? (U)last_value : (U)last_value % (U)value;
   150 		case DSGA_OP_UMOD: return value == 0 ? (U)last_value : (U)last_value % (U)value;
   136 		case DSGA_OP_MUL:  return last_value * value;
   151 		case DSGA_OP_MUL:  return last_value * value;
   137 		case DSGA_OP_AND:  return last_value & value;
   152 		case DSGA_OP_AND:  return last_value & value;
   138 		case DSGA_OP_OR:   return last_value | value;
   153 		case DSGA_OP_OR:   return last_value | value;
   139 		case DSGA_OP_XOR:  return last_value ^ value;
   154 		case DSGA_OP_XOR:  return last_value ^ value;
   140 		case DSGA_OP_STO:
   155 		case DSGA_OP_STO:  _temp_store.Store(value, last_value); return last_value;
   141 			if (value < lengthof(_temp_store)) _temp_store[value] = last_value;
       
   142 			return last_value;
       
   143 		case DSGA_OP_RST:  return value;
   156 		case DSGA_OP_RST:  return value;
       
   157 		case DSGA_OP_STOP: if (object->psa != NULL) object->psa->Store(value, last_value); return last_value;
       
   158 		case DSGA_OP_ROR:  return RotateRight(last_value, value);
       
   159 		case DSGA_OP_SCMP: return ((S)last_value == (S)value) ? 1 : ((S)last_value < (S)value ? 0 : 2);
       
   160 		case DSGA_OP_UCMP: return ((U)last_value == (U)value) ? 1 : ((U)last_value < (U)value ? 0 : 2);
   144 		default:           return value;
   161 		default:           return value;
   145 	}
   162 	}
   146 }
   163 }
   147 
   164 
   148 
   165 
   177 			 * the group from the first range or the default group. */
   194 			 * the group from the first range or the default group. */
   178 			return Resolve(group->g.determ.num_ranges > 0 ? group->g.determ.ranges[0].group : group->g.determ.default_group, object);
   195 			return Resolve(group->g.determ.num_ranges > 0 ? group->g.determ.ranges[0].group : group->g.determ.default_group, object);
   179 		}
   196 		}
   180 
   197 
   181 		switch (group->g.determ.size) {
   198 		switch (group->g.determ.size) {
   182 			case DSG_SIZE_BYTE:  value = EvalAdjustT<uint8, int8>(adjust, last_value, value); break;
   199 			case DSG_SIZE_BYTE:  value = EvalAdjustT<uint8,  int8> (adjust, object, last_value, value); break;
   183 			case DSG_SIZE_WORD:  value = EvalAdjustT<uint16, int16>(adjust, last_value, value); break;
   200 			case DSG_SIZE_WORD:  value = EvalAdjustT<uint16, int16>(adjust, object, last_value, value); break;
   184 			case DSG_SIZE_DWORD: value = EvalAdjustT<uint32, int32>(adjust, last_value, value); break;
   201 			case DSG_SIZE_DWORD: value = EvalAdjustT<uint32, int32>(adjust, object, last_value, value); break;
   185 			default: NOT_REACHED(); break;
   202 			default: NOT_REACHED(); break;
   186 		}
   203 		}
   187 		last_value = value;
   204 		last_value = value;
   188 	}
   205 	}
   189 
   206 
   190 	object->last_value = last_value;
   207 	object->last_value = last_value;
   191 
   208 
   192 	if (group->g.determ.num_ranges == 0) {
   209 	if (group->g.determ.num_ranges == 0) {
   193 		/* nvar == 0 is a special case -- we turn our value into a callback result */
   210 		/* nvar == 0 is a special case -- we turn our value into a callback result */
   194 		nvarzero.type = SGT_CALLBACK;
   211 		nvarzero.type = SGT_CALLBACK;
   195 		nvarzero.g.callback.result = GB(value, 0, 15);
   212 		switch (object->callback) {
       
   213 			/* All these functions are 15 bit callbacks */
       
   214 			case CBID_VEHICLE_REFIT_CAPACITY:
       
   215 			case CBID_HOUSE_COLOUR:
       
   216 			case CBID_HOUSE_CARGO_ACCEPTANCE:
       
   217 			case CBID_INDUSTRY_LOCATION:
       
   218 			case CBID_INDTILE_CARGO_ACCEPTANCE:
       
   219 			case CBID_VEHICLE_COLOUR_MAPPING:
       
   220 			case CBID_HOUSE_PRODUCE_CARGO:
       
   221 			case CBID_VEHICLE_SOUND_EFFECT:
       
   222 			case CBID_SOUNDS_AMBIENT_EFFECT:
       
   223 				nvarzero.g.callback.result = GB(value, 0, 15);
       
   224 				break;
       
   225 
       
   226 			/* The rest is a 8 bit callback, which should be truncated properly */
       
   227 			default:
       
   228 				nvarzero.g.callback.result = GB(value, 0, 8);
       
   229 				break;
       
   230 		}
   196 		return &nvarzero;
   231 		return &nvarzero;
   197 	}
   232 	}
   198 
   233 
   199 	for (i = 0; i < group->g.determ.num_ranges; i++) {
   234 	for (i = 0; i < group->g.determ.num_ranges; i++) {
   200 		if (group->g.determ.ranges[i].low <= value && value <= group->g.determ.ranges[i].high) {
   235 		if (group->g.determ.ranges[i].low <= value && value <= group->g.determ.ranges[i].high) {