engine.c
changeset 445 0e3fa3da3899
parent 433 00c1c7a58672
child 485 453c096beb1b
equal deleted inserted replaced
444:b4589ccaff3a 445:0e3fa3da3899
   241 	 * to prevent leaks. But first we need to refcount the SpriteGroup.
   241 	 * to prevent leaks. But first we need to refcount the SpriteGroup.
   242 	 * --pasky */
   242 	 * --pasky */
   243 	_engine_custom_sprites[engine][cargo] = *group;
   243 	_engine_custom_sprites[engine][cargo] = *group;
   244 }
   244 }
   245 
   245 
       
   246 typedef struct RealSpriteGroup *(*resolve_callback)(struct SpriteGroup *spritegroup,
       
   247                                                     struct Vehicle *veh,
       
   248                                                     void *callback); /* XXX data pointer used as function pointer */
       
   249 
   246 static struct RealSpriteGroup *
   250 static struct RealSpriteGroup *
   247 ResolveVehicleSpriteGroup(struct SpriteGroup *spritegroup, struct Vehicle *veh)
   251 ResolveVehicleSpriteGroup(struct SpriteGroup *spritegroup, struct Vehicle *veh,
   248 {
   252 			  resolve_callback callback)
       
   253 {
       
   254 	//debug("spgt %d", spritegroup->type);
   249 	switch (spritegroup->type) {
   255 	switch (spritegroup->type) {
   250 		case SGT_REAL:
   256 		case SGT_REAL:
   251 			return &spritegroup->g.real;
   257 			return &spritegroup->g.real;
   252 
   258 
   253 		case SGT_DETERMINISTIC: {
   259 		case SGT_DETERMINISTIC: {
   272 					if (dsg->num_ranges > 0) {
   278 					if (dsg->num_ranges > 0) {
   273 						target = &dsg->ranges[0].group;
   279 						target = &dsg->ranges[0].group;
   274 					} else {
   280 					} else {
   275 						target = dsg->default_group;
   281 						target = dsg->default_group;
   276 					}
   282 					}
   277 					return ResolveVehicleSpriteGroup(target, NULL);
   283 					return callback(target, NULL, callback);
   278 				}
   284 				}
   279 
   285 
   280 				if (dsg->var_scope == VSG_SCOPE_PARENT) {
   286 				if (dsg->var_scope == VSG_SCOPE_PARENT) {
   281 					/* First engine in the vehicle chain */
   287 					/* First engine in the vehicle chain */
   282 					if (veh->type == VEH_Train)
   288 					if (veh->type == VEH_Train)
   391 					}
   397 					}
   392 				}
   398 				}
   393 			}
   399 			}
   394 
   400 
   395 			target = value != -1 ? EvalDeterministicSpriteGroup(dsg, value) : dsg->default_group;
   401 			target = value != -1 ? EvalDeterministicSpriteGroup(dsg, value) : dsg->default_group;
   396 			//debug("Resolved variable %x: %d", dsg->variable, value);
   402 			//debug("Resolved variable %x: %d, %p", dsg->variable, value, callback);
   397 			return ResolveVehicleSpriteGroup(target, veh);
   403 			return callback(target, veh, callback);
   398 		}
   404 		}
   399 
   405 
       
   406 		case SGT_RANDOMIZED: {
       
   407 			struct RandomizedSpriteGroup *rsg = &spritegroup->g.random;
       
   408 
       
   409 			if (veh == NULL) {
       
   410 				/* Purchase list of something. Show the first one. */
       
   411 				assert(rsg->num_groups > 0);
       
   412 				//debug("going for %p: %d", rsg->groups[0], rsg->groups[0].type);
       
   413 				return callback(&rsg->groups[0], NULL, callback);
       
   414 			}
       
   415 
       
   416 			if (rsg->var_scope == VSG_SCOPE_PARENT) {
       
   417 				/* First engine in the vehicle chain */
       
   418 				if (veh->type == VEH_Train)
       
   419 					veh = GetFirstVehicleInChain(veh);
       
   420 			}
       
   421 
       
   422 			return callback(EvalRandomizedSpriteGroup(rsg, veh->random_bits), veh, callback);
       
   423 		}
       
   424 
   400 		default:
   425 		default:
   401 		case SGT_RANDOM:
   426 			error("I don't know how to handle such a spritegroup %d!", spritegroup->type);
   402 			error("I don't know how to handle random spritegroups yet!");
       
   403 			return NULL;
   427 			return NULL;
   404 	}
   428 	}
   405 }
   429 }
   406 
   430 
   407 int GetCustomEngineSprite(byte engine, Vehicle *v, byte direction)
   431 static struct SpriteGroup *GetVehicleSpriteGroup(byte engine, Vehicle *v)
   408 {
   432 {
   409 	struct SpriteGroup *group;
   433 	struct SpriteGroup *group;
   410 	struct RealSpriteGroup *rsg;
       
   411 	uint16 overriding_engine = -1;
   434 	uint16 overriding_engine = -1;
   412 	byte cargo = CID_PURCHASE;
   435 	byte cargo = CID_PURCHASE;
   413 	byte loaded = 0;
       
   414 	byte in_motion = 0;
       
   415 	int totalsets, spriteset;
       
   416 	int r;
       
   417 
   436 
   418 	if (v != NULL) {
   437 	if (v != NULL) {
   419 		overriding_engine = v->type == VEH_Train ? v->u.rail.first_engine : -1;
   438 		overriding_engine = v->type == VEH_Train ? v->u.rail.first_engine : -1;
   420 		cargo = _global_cargo_id[_opt.landscape][v->cargo_type];
   439 		cargo = _global_cargo_id[_opt.landscape][v->cargo_type];
   421 		loaded = ((v->cargo_count + 1) * 100) / (v->cargo_cap + 1);
       
   422 		in_motion = !!v->cur_speed;
       
   423 	}
   440 	}
   424 
   441 
   425 	group = &_engine_custom_sprites[engine][cargo];
   442 	group = &_engine_custom_sprites[engine][cargo];
   426 
   443 
   427 	if (overriding_engine != 0xffff) {
   444 	if (overriding_engine != 0xffff) {
   429 
   446 
   430 		overset = GetWagonOverrideSpriteSet(engine, overriding_engine);
   447 		overset = GetWagonOverrideSpriteSet(engine, overriding_engine);
   431 		if (overset) group = overset;
   448 		if (overset) group = overset;
   432 	}
   449 	}
   433 
   450 
   434 	rsg = ResolveVehicleSpriteGroup(group, v);
   451 	return group;
       
   452 }
       
   453 
       
   454 int GetCustomEngineSprite(byte engine, Vehicle *v, byte direction)
       
   455 {
       
   456 	struct SpriteGroup *group;
       
   457 	struct RealSpriteGroup *rsg;
       
   458 	byte cargo = CID_PURCHASE;
       
   459 	byte loaded = 0;
       
   460 	bool in_motion = 0;
       
   461 	int totalsets, spriteset;
       
   462 	int r;
       
   463 
       
   464 	if (v != NULL) {
       
   465 		int capacity = v->cargo_cap;
       
   466 
       
   467 		cargo = _global_cargo_id[_opt.landscape][v->cargo_type];
       
   468 		if (capacity == 0) capacity = 1;
       
   469 		loaded = (v->cargo_count * 100) / capacity;
       
   470 		in_motion = (v->cur_speed != 0);
       
   471 	}
       
   472 
       
   473 	group = GetVehicleSpriteGroup(engine, v);
       
   474 	rsg = ResolveVehicleSpriteGroup(group, v, (resolve_callback) ResolveVehicleSpriteGroup);
   435 
   475 
   436 	if (rsg->sprites_per_set == 0 && cargo != 29) { /* XXX magic number */
   476 	if (rsg->sprites_per_set == 0 && cargo != 29) { /* XXX magic number */
   437 		// This group is empty but perhaps there'll be a default one.
   477 		// This group is empty but perhaps there'll be a default one.
   438 		rsg = ResolveVehicleSpriteGroup(&_engine_custom_sprites[engine][29], v);
   478 		rsg = ResolveVehicleSpriteGroup(&_engine_custom_sprites[engine][29], v,
       
   479 		                                (resolve_callback) ResolveVehicleSpriteGroup);
   439 	}
   480 	}
   440 
   481 
   441 	if (!rsg->sprites_per_set) {
   482 	if (!rsg->sprites_per_set) {
   442 		// This group is empty. This function users should therefore
   483 		// This group is empty. This function users should therefore
   443 		// look up the sprite number in _engine_original_sprites.
   484 		// look up the sprite number in _engine_original_sprites.
   465 			spriteset--;
   506 			spriteset--;
   466 	}
   507 	}
   467 
   508 
   468 	r = (in_motion ? rsg->loaded[spriteset] : rsg->loading[spriteset]) + direction;
   509 	r = (in_motion ? rsg->loaded[spriteset] : rsg->loading[spriteset]) + direction;
   469 	return r;
   510 	return r;
       
   511 }
       
   512 
       
   513 
       
   514 // Global variables are evil, yes, but we would end up with horribly overblown
       
   515 // calling convention otherwise and this should be 100% reentrant.
       
   516 static byte _vsg_random_triggers;
       
   517 static byte _vsg_bits_to_reseed;
       
   518 
       
   519 extern int _custom_sprites_base;
       
   520 
       
   521 static struct RealSpriteGroup *
       
   522 TriggerVehicleSpriteGroup(struct SpriteGroup *spritegroup, struct Vehicle *veh,
       
   523 			  resolve_callback callback)
       
   524 {
       
   525 	if (spritegroup->type == SGT_RANDOMIZED)
       
   526 		_vsg_bits_to_reseed |= RandomizedSpriteGroupTriggeredBits(&spritegroup->g.random,
       
   527 		                                                         _vsg_random_triggers,
       
   528 		                                                         &veh->waiting_triggers);
       
   529 
       
   530 	return ResolveVehicleSpriteGroup(spritegroup, veh, callback);
       
   531 }
       
   532 
       
   533 static void DoTriggerVehicle(Vehicle *veh, enum VehicleTrigger trigger, byte base_random_bits, bool first)
       
   534 {
       
   535 	struct RealSpriteGroup *rsg;
       
   536 	byte new_random_bits;
       
   537 
       
   538 	_vsg_random_triggers = trigger;
       
   539 	_vsg_bits_to_reseed = 0;
       
   540 	rsg = TriggerVehicleSpriteGroup(GetVehicleSpriteGroup(veh->engine_type, veh), veh,
       
   541 	                                (resolve_callback) TriggerVehicleSpriteGroup);
       
   542 	if (rsg->sprites_per_set == 0 && veh->cargo_type != 29) { /* XXX magic number */
       
   543 		// This group turned out to be empty but perhaps there'll be a default one.
       
   544 		rsg = TriggerVehicleSpriteGroup(&_engine_custom_sprites[veh->engine_type][29], veh,
       
   545 						(resolve_callback) TriggerVehicleSpriteGroup);
       
   546 	}
       
   547 	veh->random_bits &= ~_vsg_bits_to_reseed;
       
   548 	veh->random_bits |= (first ? (new_random_bits = Random()) : base_random_bits) & _vsg_bits_to_reseed;
       
   549 
       
   550 	switch (trigger) {
       
   551 		case VEHICLE_TRIGGER_NEW_CARGO:
       
   552 			/* All vehicles in chain get ANY_NEW_CARGO trigger now.
       
   553 			 * So we call it for the first one and they will recurse. */
       
   554 			/* Indexing part of vehicle random bits needs to be
       
   555 			 * same for all triggered vehicles in the chain (to get
       
   556 			 * all the random-cargo wagons carry the same cargo,
       
   557 			 * i.e.), so we give them all the NEW_CARGO triggered
       
   558 			 * vehicle's portion of random bits. */
       
   559 			assert(first);
       
   560 			DoTriggerVehicle(GetFirstVehicleInChain(veh), VEHICLE_TRIGGER_ANY_NEW_CARGO, new_random_bits, false);
       
   561 			break;
       
   562 		case VEHICLE_TRIGGER_DEPOT:
       
   563 			/* We now trigger the next vehicle in chain recursively.
       
   564 			 * The random bits portions may be different for each
       
   565 			 * vehicle in chain. */
       
   566 			if (veh->next != NULL)
       
   567 				DoTriggerVehicle(veh->next, trigger, 0, true);
       
   568 			break;
       
   569 		case VEHICLE_TRIGGER_EMPTY:
       
   570 			/* We now trigger the next vehicle in chain
       
   571 			 * recursively.  The random bits portions must be same
       
   572 			 * for each vehicle in chain, so we give them all
       
   573 			 * first chained vehicle's portion of random bits. */
       
   574 			if (veh->next != NULL)
       
   575 				DoTriggerVehicle(veh->next, trigger, first ? new_random_bits : base_random_bits, false);
       
   576 			break;
       
   577 		case VEHICLE_TRIGGER_ANY_NEW_CARGO:
       
   578 			/* Now pass the trigger recursively to the next vehicle
       
   579 			 * in chain. */
       
   580 			assert(!first);
       
   581 			if (veh->next != NULL)
       
   582 				DoTriggerVehicle(veh->next, VEHICLE_TRIGGER_ANY_NEW_CARGO, base_random_bits, false);
       
   583 			break;
       
   584 	}
       
   585 }
       
   586 
       
   587 void TriggerVehicle(Vehicle *veh, enum VehicleTrigger trigger)
       
   588 {
       
   589 	DoTriggerVehicle(veh, trigger, 0, true);
   470 }
   590 }
   471 
   591 
   472 
   592 
   473 static char *_engine_custom_names[256];
   593 static char *_engine_custom_names[256];
   474 
   594