src/newgrf.cpp
changeset 6689 dc89785a5bee
parent 6687 d2ef5eda4562
child 6691 e8c27a509894
equal deleted inserted replaced
6688:f5ce3828887c 6689:dc89785a5bee
  2392 
  2392 
  2393 	grfmsg(6, "FeatureMapSpriteGroup: Cargo '%c%c%c%c' mapped to cargo type %d.", GB(cl, 24, 8), GB(cl, 16, 8), GB(cl, 8, 8), GB(cl, 0, 8), ctype);
  2393 	grfmsg(6, "FeatureMapSpriteGroup: Cargo '%c%c%c%c' mapped to cargo type %d.", GB(cl, 24, 8), GB(cl, 16, 8), GB(cl, 8, 8), GB(cl, 0, 8), ctype);
  2394 	return ctype;
  2394 	return ctype;
  2395 }
  2395 }
  2396 
  2396 
       
  2397 
       
  2398 static void VehicleMapSpriteGroup(byte *buf, byte feature, uint8 idcount, uint8 cidcount, bool wagover)
       
  2399 {
       
  2400 	static byte *last_engines;
       
  2401 	static int last_engines_count;
       
  2402 
       
  2403 	if (!wagover) {
       
  2404 		if (last_engines_count != idcount) {
       
  2405 			last_engines = ReallocT(last_engines, idcount);
       
  2406 			last_engines_count = idcount;
       
  2407 		}
       
  2408 	} else {
       
  2409 		if (last_engines_count == 0) {
       
  2410 			grfmsg(0, "FeatureMapSpriteGroup: WagonOverride: No engine to do override with");
       
  2411 			return;
       
  2412 		}
       
  2413 
       
  2414 		grfmsg(6, "FeatureMapSpriteGroup: WagonOverride: %u engines, %u wagons",
       
  2415 				last_engines_count, idcount);
       
  2416 	}
       
  2417 
       
  2418 	for (uint i = 0; i < idcount; i++) {
       
  2419 		uint8 engine_id = buf[3 + i];
       
  2420 		uint8 engine = engine_id + _vehshifts[feature];
       
  2421 		byte *bp = &buf[4 + idcount];
       
  2422 
       
  2423 		if (engine_id > _vehcounts[feature]) {
       
  2424 			grfmsg(0, "Id %u for feature 0x%02X is out of bounds", engine_id, feature);
       
  2425 			return;
       
  2426 		}
       
  2427 
       
  2428 		grfmsg(7, "FeatureMapSpriteGroup: [%d] Engine %d...", i, engine);
       
  2429 
       
  2430 		for (uint c = 0; c < cidcount; c++) {
       
  2431 			uint8 ctype = grf_load_byte(&bp);
       
  2432 			uint16 groupid = grf_load_word(&bp);
       
  2433 
       
  2434 			grfmsg(8, "FeatureMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
       
  2435 
       
  2436 			if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
       
  2437 				grfmsg(1, "FeatureMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping", groupid, _cur_grffile->spritegroups_count);
       
  2438 				continue;
       
  2439 			}
       
  2440 
       
  2441 			ctype = TranslateCargo(feature, ctype);
       
  2442 			if (ctype == CT_INVALID) continue;
       
  2443 
       
  2444 			if (wagover) {
       
  2445 				SetWagonOverrideSprites(engine, ctype, _cur_grffile->spritegroups[groupid], last_engines, last_engines_count);
       
  2446 			} else {
       
  2447 				SetCustomEngineSprites(engine, ctype, _cur_grffile->spritegroups[groupid]);
       
  2448 				last_engines[i] = engine;
       
  2449 			}
       
  2450 		}
       
  2451 	}
       
  2452 
       
  2453 	{
       
  2454 		byte *bp = &buf[4 + idcount + cidcount * 3];
       
  2455 		uint16 groupid = grf_load_word(&bp);
       
  2456 
       
  2457 		grfmsg(8, "-- Default group id 0x%04X", groupid);
       
  2458 
       
  2459 		for (uint i = 0; i < idcount; i++) {
       
  2460 			uint8 engine = buf[3 + i] + _vehshifts[feature];
       
  2461 
       
  2462 			/* Don't tell me you don't love duplicated code! */
       
  2463 			if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
       
  2464 				grfmsg(1, "FeatureMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping",
       
  2465 				       groupid, _cur_grffile->spritegroups_count);
       
  2466 				continue;
       
  2467 			}
       
  2468 
       
  2469 			if (wagover) {
       
  2470 				/* If the ID for this action 3 is the same as the vehicle ID,
       
  2471  * this indicates we have a helicopter rotor override. */
       
  2472 				if (feature == GSF_AIRCRAFT && engine == last_engines[i]) {
       
  2473 					SetRotorOverrideSprites(engine, _cur_grffile->spritegroups[groupid]);
       
  2474 				} else {
       
  2475 					/* TODO: No multiple cargo types per vehicle yet. --pasky */
       
  2476 					SetWagonOverrideSprites(engine, CT_DEFAULT, _cur_grffile->spritegroups[groupid], last_engines, last_engines_count);
       
  2477 				}
       
  2478 			} else {
       
  2479 				SetCustomEngineSprites(engine, CT_DEFAULT, _cur_grffile->spritegroups[groupid]);
       
  2480 				SetEngineGRF(engine, _cur_grffile);
       
  2481 				last_engines[i] = engine;
       
  2482 			}
       
  2483 		}
       
  2484 	}
       
  2485 }
       
  2486 
       
  2487 
       
  2488 static void StationMapSpriteGroup(byte *buf, uint8 idcount, uint8 cidcount)
       
  2489 {
       
  2490 	for (uint i = 0; i < idcount; i++) {
       
  2491 		uint8 stid = buf[3 + i];
       
  2492 		StationSpec *statspec = _cur_grffile->stations[stid];
       
  2493 		byte *bp = &buf[4 + idcount];
       
  2494 
       
  2495 		for (uint c = 0; c < cidcount; c++) {
       
  2496 			uint8 ctype = grf_load_byte(&bp);
       
  2497 			uint16 groupid = grf_load_word(&bp);
       
  2498 
       
  2499 			if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
       
  2500 				grfmsg(1, "FeatureMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping",
       
  2501 				       groupid, _cur_grffile->spritegroups_count);
       
  2502 				continue;
       
  2503 			}
       
  2504 
       
  2505 			ctype = TranslateCargo(GSF_STATION, ctype);
       
  2506 			if (ctype == CT_INVALID) continue;
       
  2507 
       
  2508 			statspec->spritegroup[ctype] = _cur_grffile->spritegroups[groupid];
       
  2509 		}
       
  2510 	}
       
  2511 
       
  2512 	{
       
  2513 		byte *bp = &buf[4 + idcount + cidcount * 3];
       
  2514 		uint16 groupid = grf_load_word(&bp);
       
  2515 
       
  2516 		if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
       
  2517 			grfmsg(1, "FeatureMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping",
       
  2518 			       groupid, _cur_grffile->spritegroups_count);
       
  2519 			return;
       
  2520 		}
       
  2521 
       
  2522 		for (uint i = 0; i < idcount; i++) {
       
  2523 			uint8 stid = buf[3 + i];
       
  2524 			StationSpec *statspec = _cur_grffile->stations[stid];
       
  2525 
       
  2526 			statspec->spritegroup[CT_DEFAULT] = _cur_grffile->spritegroups[groupid];
       
  2527 			statspec->grfid = _cur_grffile->grfid;
       
  2528 			statspec->localidx = stid;
       
  2529 			SetCustomStationSpec(statspec);
       
  2530 		}
       
  2531 	}
       
  2532 }
       
  2533 
       
  2534 
       
  2535 static void TownHouseMapSpriteGroup(byte *buf, uint8 idcount, uint8 cidcount)
       
  2536 {
       
  2537 	byte *bp = &buf[4 + idcount + cidcount * 3];
       
  2538 	uint16 groupid = grf_load_word(&bp);
       
  2539 
       
  2540 	if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
       
  2541 		grfmsg(1, "FeatureMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping.",
       
  2542 		       groupid, _cur_grffile->spritegroups_count);
       
  2543 		return;
       
  2544 	}
       
  2545 
       
  2546 	for (uint i = 0; i < idcount; i++) {
       
  2547 		uint8 hid = buf[3 + i];
       
  2548 		HouseSpec *hs = _cur_grffile->housespec[hid];
       
  2549 
       
  2550 		if (hs == NULL) {
       
  2551 			grfmsg(1, "FeatureMapSpriteGroup: Too many houses defined, skipping");
       
  2552 			return;
       
  2553 		}
       
  2554 
       
  2555 		hs->spritegroup = _cur_grffile->spritegroups[groupid];
       
  2556 	}
       
  2557 }
       
  2558 
  2397 /* Action 0x03 */
  2559 /* Action 0x03 */
  2398 static void FeatureMapSpriteGroup(byte *buf, int len)
  2560 static void FeatureMapSpriteGroup(byte *buf, int len)
  2399 {
  2561 {
  2400 	/* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
  2562 	/* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
  2401 	 * id-list    := [<id>] [id-list]
  2563 	 * id-list    := [<id>] [id-list]
  2408 	 * B num-cid       number of cargo IDs (sprite group IDs) in this definition
  2570 	 * B num-cid       number of cargo IDs (sprite group IDs) in this definition
  2409 	 *                 can be zero, in that case the def-cid is used always
  2571 	 *                 can be zero, in that case the def-cid is used always
  2410 	 * B cargo-type    type of this cargo type (e.g. mail=2, wood=7, see below)
  2572 	 * B cargo-type    type of this cargo type (e.g. mail=2, wood=7, see below)
  2411 	 * W cid           cargo ID (sprite group ID) for this type of cargo
  2573 	 * W cid           cargo ID (sprite group ID) for this type of cargo
  2412 	 * W def-cid       default cargo ID (sprite group ID) */
  2574 	 * W def-cid       default cargo ID (sprite group ID) */
  2413 	/* TODO: Bridges, town houses. */
       
  2414 	/* TODO: Multiple cargo support could be useful even for trains/cars -
       
  2415 	 * cargo id 0xff is used for showing images in the build train list. */
       
  2416 
       
  2417 	static byte *last_engines;
       
  2418 	static int last_engines_count;
       
  2419 
  2575 
  2420 	if (!check_length(len, 6, "FeatureMapSpriteGroup")) return;
  2576 	if (!check_length(len, 6, "FeatureMapSpriteGroup")) return;
  2421 
  2577 
  2422 	uint8 feature = buf[1];
  2578 	uint8 feature = buf[1];
  2423 	uint8 idcount = buf[2] & 0x7F;
  2579 	uint8 idcount = buf[2] & 0x7F;
  2435 	if (!check_length(len, 4 + idcount + cidcount * 3, "FeatureMapSpriteGroup")) return;
  2591 	if (!check_length(len, 4 + idcount + cidcount * 3, "FeatureMapSpriteGroup")) return;
  2436 
  2592 
  2437 	grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids, %d cids, wagon override %d",
  2593 	grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids, %d cids, wagon override %d",
  2438 			feature, idcount, cidcount, wagover);
  2594 			feature, idcount, cidcount, wagover);
  2439 
  2595 
  2440 	if (feature > GSF_STATION && feature != GSF_TOWNHOUSE) {
       
  2441 		grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
       
  2442 		return;
       
  2443 	}
       
  2444 
       
  2445 
       
  2446 	if (feature == GSF_STATION) {
       
  2447 		/* We do things differently for stations. */
       
  2448 
       
  2449 		for (uint i = 0; i < idcount; i++) {
       
  2450 			uint8 stid = buf[3 + i];
       
  2451 			StationSpec *statspec = _cur_grffile->stations[stid];
       
  2452 			byte *bp = &buf[4 + idcount];
       
  2453 
       
  2454 			for (uint c = 0; c < cidcount; c++) {
       
  2455 				uint8 ctype = grf_load_byte(&bp);
       
  2456 				uint16 groupid = grf_load_word(&bp);
       
  2457 
       
  2458 				if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
       
  2459 					grfmsg(1, "FeatureMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping",
       
  2460 					       groupid, _cur_grffile->spritegroups_count);
       
  2461 					return;
       
  2462 				}
       
  2463 
       
  2464 				ctype = TranslateCargo(feature, ctype);
       
  2465 				if (ctype == CT_INVALID) continue;
       
  2466 
       
  2467 				statspec->spritegroup[ctype] = _cur_grffile->spritegroups[groupid];
       
  2468 			}
       
  2469 		}
       
  2470 
       
  2471 		{
       
  2472 			byte *bp = buf + 4 + idcount + cidcount * 3;
       
  2473 			uint16 groupid = grf_load_word(&bp);
       
  2474 
       
  2475 			if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
       
  2476 				grfmsg(1, "FeatureMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping",
       
  2477 				       groupid, _cur_grffile->spritegroups_count);
       
  2478 				return;
       
  2479 			}
       
  2480 
       
  2481 			for (uint i = 0; i < idcount; i++) {
       
  2482 				uint8 stid = buf[3 + i];
       
  2483 				StationSpec *statspec = _cur_grffile->stations[stid];
       
  2484 
       
  2485 				statspec->spritegroup[CT_DEFAULT] = _cur_grffile->spritegroups[groupid];
       
  2486 				statspec->grfid = _cur_grffile->grfid;
       
  2487 				statspec->localidx = stid;
       
  2488 				SetCustomStationSpec(statspec);
       
  2489 			}
       
  2490 		}
       
  2491 		return;
       
  2492 	} else if (feature == GSF_TOWNHOUSE) {
       
  2493 		byte *bp = &buf[4 + idcount + cidcount * 3];
       
  2494 		uint16 groupid = grf_load_word(&bp);
       
  2495 
       
  2496 		if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
       
  2497 			grfmsg(1, "FeatureMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping.",
       
  2498 			       groupid, _cur_grffile->spritegroups_count);
       
  2499 			return;
       
  2500 		}
       
  2501 
       
  2502 		for (uint i = 0; i < idcount; i++) {
       
  2503 			uint8 hid = buf[3 + i];
       
  2504 			HouseSpec *hs = _cur_grffile->housespec[hid];
       
  2505 
       
  2506 			if (hs == NULL) {
       
  2507 				grfmsg(1, "FeatureMapSpriteGroup: Too many houses defined, skipping");
       
  2508 				return;
       
  2509 			}
       
  2510 
       
  2511 			hs->spritegroup = _cur_grffile->spritegroups[groupid];
       
  2512 		}
       
  2513 		return;
       
  2514 	}
       
  2515 
       
  2516 	/* FIXME: Tropicset contains things like:
       
  2517 	 * 03 00 01 19 01 00 00 00 00 - this is missing one 00 at the end,
       
  2518 	 * what should we exactly do with that? --pasky */
       
  2519 
       
  2520 	if (_cur_grffile->spriteset_start == 0 || _cur_grffile->spritegroups == 0) {
  2596 	if (_cur_grffile->spriteset_start == 0 || _cur_grffile->spritegroups == 0) {
  2521 		grfmsg(1, "FeatureMapSpriteGroup: No sprite set to work on! Skipping");
  2597 		grfmsg(1, "FeatureMapSpriteGroup: No sprite set to work on! Skipping");
  2522 		return;
  2598 		return;
  2523 	}
  2599 	}
  2524 
  2600 
  2525 	if (!wagover && last_engines_count != idcount) {
  2601 	switch (feature) {
  2526 		last_engines = ReallocT(last_engines, idcount);
  2602 		case GSF_TRAIN:
  2527 		last_engines_count = idcount;
  2603 		case GSF_ROAD:
  2528 	}
  2604 		case GSF_SHIP:
  2529 
  2605 		case GSF_AIRCRAFT:
  2530 	if (wagover) {
  2606 			VehicleMapSpriteGroup(buf, feature, idcount, cidcount, wagover);
  2531 		if (last_engines_count == 0) {
       
  2532 			grfmsg(0, "FeatureMapSpriteGroup: WagonOverride: No engine to do override with");
       
  2533 			return;
  2607 			return;
  2534 		}
  2608 
  2535 		grfmsg(6, "FeatureMapSpriteGroup: WagonOverride: %u engines, %u wagons",
  2609 		case GSF_STATION:
  2536 				last_engines_count, idcount);
  2610 			StationMapSpriteGroup(buf, idcount, cidcount);
  2537 	}
       
  2538 
       
  2539 
       
  2540 	for (uint i = 0; i < idcount; i++) {
       
  2541 		uint8 engine_id = buf[3 + i];
       
  2542 		uint8 engine = engine_id + _vehshifts[feature];
       
  2543 		byte *bp = &buf[4 + idcount];
       
  2544 
       
  2545 		if (engine_id > _vehcounts[feature]) {
       
  2546 			grfmsg(0, "Id %u for feature 0x%02X is out of bounds", engine_id, feature);
       
  2547 			return;
  2611 			return;
  2548 		}
  2612 
  2549 
  2613 		case GSF_TOWNHOUSE:
  2550 		grfmsg(7, "FeatureMapSpriteGroup: [%d] Engine %d...", i, engine);
  2614 			TownHouseMapSpriteGroup(buf, idcount, cidcount);
  2551 
  2615 			return;
  2552 		for (uint c = 0; c < cidcount; c++) {
  2616 
  2553 			uint8 ctype = grf_load_byte(&bp);
  2617 		default:
  2554 			uint16 groupid = grf_load_word(&bp);
  2618 			grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
  2555 
  2619 			return;
  2556 			grfmsg(8, "FeatureMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
       
  2557 
       
  2558 			if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
       
  2559 				grfmsg(1, "FeatureMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping", groupid, _cur_grffile->spritegroups_count);
       
  2560 				return;
       
  2561 			}
       
  2562 
       
  2563 			ctype = TranslateCargo(feature, ctype);
       
  2564 			if (ctype == CT_INVALID) continue;
       
  2565 
       
  2566 			if (wagover) {
       
  2567 				SetWagonOverrideSprites(engine, ctype, _cur_grffile->spritegroups[groupid], last_engines, last_engines_count);
       
  2568 			} else {
       
  2569 				SetCustomEngineSprites(engine, ctype, _cur_grffile->spritegroups[groupid]);
       
  2570 				last_engines[i] = engine;
       
  2571 			}
       
  2572 		}
       
  2573 	}
       
  2574 
       
  2575 	{
       
  2576 		byte *bp = buf + 4 + idcount + cidcount * 3;
       
  2577 		uint16 groupid = grf_load_word(&bp);
       
  2578 
       
  2579 		grfmsg(8, "-- Default group id 0x%04X", groupid);
       
  2580 
       
  2581 		for (uint i = 0; i < idcount; i++) {
       
  2582 			uint8 engine = buf[3 + i] + _vehshifts[feature];
       
  2583 
       
  2584 			/* Don't tell me you don't love duplicated code! */
       
  2585 			if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
       
  2586 				grfmsg(1, "FeatureMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping", groupid, _cur_grffile->spritegroups_count);
       
  2587 				return;
       
  2588 			}
       
  2589 
       
  2590 			if (wagover) {
       
  2591 				/* If the ID for this action 3 is the same as the vehicle ID,
       
  2592 				 * this indicates we have a helicopter rotor override. */
       
  2593 				if (feature == GSF_AIRCRAFT && engine == last_engines[i]) {
       
  2594 					SetRotorOverrideSprites(engine, _cur_grffile->spritegroups[groupid]);
       
  2595 				} else {
       
  2596 					/* TODO: No multiple cargo types per vehicle yet. --pasky */
       
  2597 					SetWagonOverrideSprites(engine, CT_DEFAULT, _cur_grffile->spritegroups[groupid], last_engines, last_engines_count);
       
  2598 				}
       
  2599 			} else {
       
  2600 				SetCustomEngineSprites(engine, CT_DEFAULT, _cur_grffile->spritegroups[groupid]);
       
  2601 				SetEngineGRF(engine, _cur_grffile);
       
  2602 				last_engines[i] = engine;
       
  2603 			}
       
  2604 		}
       
  2605 	}
  2620 	}
  2606 }
  2621 }
  2607 
  2622 
  2608 /* Action 0x04 */
  2623 /* Action 0x04 */
  2609 static void FeatureNewName(byte *buf, int len)
  2624 static void FeatureNewName(byte *buf, int len)