newgrf.c
changeset 3633 fd7db14d4491
parent 3630 13278b8ed023
child 3634 6123c07f1bc1
equal deleted inserted replaced
3632:0611603cc41c 3633:fd7db14d4491
  1300 }
  1300 }
  1301 
  1301 
  1302 /* Action 0x02 */
  1302 /* Action 0x02 */
  1303 static void NewSpriteGroup(byte *buf, int len)
  1303 static void NewSpriteGroup(byte *buf, int len)
  1304 {
  1304 {
  1305 	byte *bufend = buf + len;
       
  1306 
       
  1307 	/* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
  1305 	/* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
  1308 	 *
  1306 	 *
  1309 	 * B feature       see action 1
  1307 	 * B feature       see action 1
  1310 	 * B set-id        ID of this particular definition
  1308 	 * B set-id        ID of this particular definition
  1311 	 * B type/num-entries
  1309 	 * B type/num-entries
  1312 	 *                 if 80 or greater, this is a randomized or variational
  1310 	 *                 if 80 or greater, this is a randomized or variational
  1313 	 *                 list definition, see below
  1311 	 *                 list definition, see below
  1314 	 *                 otherwise it specifies a number of entries, the exact
  1312 	 *                 otherwise it specifies a number of entries, the exact
  1315 	 *                 meaning depends on the feature
  1313 	 *                 meaning depends on the feature
  1316 	 * V feature-specific-data (huge mess, don't even look it up --pasky) */
  1314 	 * V feature-specific-data (huge mess, don't even look it up --pasky) */
  1317 	/* TODO: No 0x80-types (ugh). */
       
  1318 	/* TODO: Also, empty sprites aren't handled for now. Need to investigate
       
  1319 	 * the "opacity" rules for these, that is which sprite to fall back to
       
  1320 	 * when. --pasky */
       
  1321 	uint8 feature;
  1315 	uint8 feature;
  1322 	uint8 setid;
  1316 	uint8 setid;
  1323 	/* XXX: For stations, these two are "little cargo" and "lotsa cargo" sets. */
  1317 	uint8 type;
  1324 	uint8 numloaded;
  1318 	SpriteGroup *group = NULL;
  1325 	uint8 numloading;
  1319 	byte *bufend = buf + len;
  1326 	SpriteGroup *group;
       
  1327 	RealSpriteGroup *rg;
       
  1328 	byte *loaded_ptr;
       
  1329 	byte *loading_ptr;
       
  1330 	int i;
       
  1331 
  1320 
  1332 	check_length(len, 5, "NewSpriteGroup");
  1321 	check_length(len, 5, "NewSpriteGroup");
  1333 	feature = buf[1];
  1322 	buf++;
  1334 	setid = buf[2];
  1323 
  1335 	numloaded = buf[3];
  1324 	feature = grf_load_byte(&buf);
  1336 	numloading = buf[4];
  1325 	setid   = grf_load_byte(&buf);
       
  1326 	type    = grf_load_byte(&buf);
  1337 
  1327 
  1338 	if (setid >= _cur_grffile->spritegroups_count) {
  1328 	if (setid >= _cur_grffile->spritegroups_count) {
  1339 		// Allocate memory for new sprite group references.
  1329 		// Allocate memory for new sprite group references.
  1340 		_cur_grffile->spritegroups = realloc(_cur_grffile->spritegroups, (setid + 1) * sizeof(*_cur_grffile->spritegroups));
  1330 		_cur_grffile->spritegroups = realloc(_cur_grffile->spritegroups, (setid + 1) * sizeof(*_cur_grffile->spritegroups));
  1341 		// Initialise new space to NULL
  1331 		// Initialise new space to NULL
  1342 		for (; _cur_grffile->spritegroups_count < (setid + 1); _cur_grffile->spritegroups_count++)
  1332 		for (; _cur_grffile->spritegroups_count < (setid + 1); _cur_grffile->spritegroups_count++)
  1343 			_cur_grffile->spritegroups[_cur_grffile->spritegroups_count] = NULL;
  1333 			_cur_grffile->spritegroups[_cur_grffile->spritegroups_count] = NULL;
  1344 	}
  1334 	}
  1345 
  1335 
  1346 	if (numloaded == 0x81 || numloaded == 0x82) {
  1336 	switch (type) {
  1347 		DeterministicSpriteGroup *dg;
  1337 		/* Deterministic Sprite Group */
  1348 		uint16 groupid;
  1338 		case 0x81: // Self scope, byte
  1349 		int i;
  1339 		case 0x82: // Parent scope, byte
  1350 
  1340 		{
  1351 		// Ok, this is gonna get a little wild, so hold your breath...
  1341 			DeterministicSpriteGroup *dg;
  1352 
  1342 			uint16 groupid;
  1353 		/* This stuff is getting actually evaluated in
  1343 			int i;
  1354 		 * EvalDeterministicSpriteGroup(). */
  1344 
  1355 
  1345 			check_length(bufend - buf, 6, "NewSpriteGroup 0x81/0x82");
  1356 		buf += 4; len -= 4;
  1346 
  1357 		check_length(len, 6, "NewSpriteGroup 0x81/0x82");
  1347 			group = AllocateSpriteGroup();
  1358 
  1348 			group->type = SGT_DETERMINISTIC;
  1359 		group = AllocateSpriteGroup();
  1349 			dg = &group->g.determ;
  1360 		group->type = SGT_DETERMINISTIC;
  1350 
  1361 		dg = &group->g.determ;
  1351 			dg->var_scope = type == 0x82 ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
  1362 
  1352 			dg->variable = grf_load_byte(&buf);
  1363 		/* XXX: We don't free() anything, assuming that if there was
  1353 			/* Variables 0x60 - 0x7F include an extra parameter */
  1364 		 * some action here before, it got associated by action 3.
  1354 			if (IS_BYTE_INSIDE(dg->variable, 0x60, 0x80))
  1365 		 * We should perhaps keep some refcount? --pasky */
  1355 				dg->parameter = grf_load_byte(&buf);
  1366 
  1356 
  1367 		dg->var_scope = numloaded == 0x82 ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
  1357 			dg->shift_num = grf_load_byte(&buf);
  1368 		dg->variable = grf_load_byte(&buf);
  1358 			dg->and_mask = grf_load_byte(&buf);
  1369 		/* Variables 0x60 - 0x7F include an extra parameter */
  1359 			dg->operation = dg->shift_num >> 6; /* w00t */
  1370 		if (IS_BYTE_INSIDE(dg->variable, 0x60, 0x80))
  1360 			dg->shift_num &= 0x3F;
  1371 			dg->parameter = grf_load_byte(&buf);
  1361 			if (dg->operation != DSG_OP_NONE) {
  1372 
  1362 				dg->add_val = grf_load_byte(&buf);
  1373 		dg->shift_num = grf_load_byte(&buf);
  1363 				dg->divmod_val = grf_load_byte(&buf);
  1374 		dg->and_mask = grf_load_byte(&buf);
  1364 			}
  1375 		dg->operation = dg->shift_num >> 6; /* w00t */
  1365 
  1376 		dg->shift_num &= 0x3F;
  1366 			/* (groupid & 0x8000) means this is callback result. */
  1377 		if (dg->operation != DSG_OP_NONE) {
  1367 
  1378 			dg->add_val = grf_load_byte(&buf);
  1368 			dg->num_ranges = grf_load_byte(&buf);
  1379 			dg->divmod_val = grf_load_byte(&buf);
  1369 			dg->ranges = calloc(dg->num_ranges, sizeof(*dg->ranges));
  1380 		}
  1370 			for (i = 0; i < dg->num_ranges; i++) {
  1381 
  1371 				groupid = grf_load_word(&buf);
  1382 		/* (groupid & 0x8000) means this is callback result. */
  1372 				if (HASBIT(groupid, 15)) {
  1383 
  1373 					dg->ranges[i].group = NewCallBackResultSpriteGroup(groupid);
  1384 		dg->num_ranges = grf_load_byte(&buf);
  1374 				} else if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
  1385 		dg->ranges = calloc(dg->num_ranges, sizeof(*dg->ranges));
  1375 					grfmsg(GMS_WARN, "NewSpriteGroup(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty.", setid, type, groupid);
  1386 		for (i = 0; i < dg->num_ranges; i++) {
  1376 					dg->ranges[i].group = NULL;
       
  1377 				} else {
       
  1378 					dg->ranges[i].group = _cur_grffile->spritegroups[groupid];
       
  1379 				}
       
  1380 
       
  1381 				dg->ranges[i].low = grf_load_byte(&buf);
       
  1382 				dg->ranges[i].high = grf_load_byte(&buf);
       
  1383 			}
       
  1384 
  1387 			groupid = grf_load_word(&buf);
  1385 			groupid = grf_load_word(&buf);
  1388 			if (HASBIT(groupid, 15)) {
  1386 			if (HASBIT(groupid, 15)) {
  1389 				dg->ranges[i].group = NewCallBackResultSpriteGroup(groupid);
  1387 				dg->default_group = NewCallBackResultSpriteGroup(groupid);
  1390 			} else if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
  1388 			} else if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
  1391 				grfmsg(GMS_WARN, "NewSpriteGroup(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty.", setid, numloaded, groupid);
  1389 				grfmsg(GMS_WARN, "NewSpriteGroup(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty.", setid, type, groupid);
  1392 				dg->ranges[i].group = NULL;
  1390 				dg->default_group = NULL;
  1393 			} else {
  1391 			} else {
  1394 				dg->ranges[i].group = _cur_grffile->spritegroups[groupid];
  1392 				dg->default_group = _cur_grffile->spritegroups[groupid];
  1395 			}
  1393 			}
  1396 
  1394 
  1397 			dg->ranges[i].low = grf_load_byte(&buf);
  1395 			break;
  1398 			dg->ranges[i].high = grf_load_byte(&buf);
       
  1399 		}
  1396 		}
  1400 
  1397 
  1401 		groupid = grf_load_word(&buf);
  1398 		/* Randomized Sprite Group */
  1402 		if (HASBIT(groupid, 15)) {
  1399 		case 0x80: // Self scope
  1403 			dg->default_group = NewCallBackResultSpriteGroup(groupid);
  1400 		case 0x83: // Parent scope
  1404 		} else if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
  1401 		{
  1405 			grfmsg(GMS_WARN, "NewSpriteGroup(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty.", setid, numloaded, groupid);
  1402 			RandomizedSpriteGroup *rg;
  1406 			dg->default_group = NULL;
  1403 			int i;
  1407 		} else {
  1404 
  1408 			dg->default_group = _cur_grffile->spritegroups[groupid];
  1405 			/* This stuff is getting actually evaluated in
       
  1406 			 * EvalRandomizedSpriteGroup(). */
       
  1407 
       
  1408 			check_length(bufend - buf, 6, "NewSpriteGroup 0x80/0x83");
       
  1409 
       
  1410 			group = AllocateSpriteGroup();
       
  1411 			group->type = SGT_RANDOMIZED;
       
  1412 			rg = &group->g.random;
       
  1413 
       
  1414 			rg->var_scope = type == 0x83 ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
       
  1415 
       
  1416 			rg->triggers = grf_load_byte(&buf);
       
  1417 			rg->cmp_mode = rg->triggers & 0x80;
       
  1418 			rg->triggers &= 0x7F;
       
  1419 
       
  1420 			rg->lowest_randbit = grf_load_byte(&buf);
       
  1421 			rg->num_groups = grf_load_byte(&buf);
       
  1422 
       
  1423 			rg->groups = calloc(rg->num_groups, sizeof(*rg->groups));
       
  1424 			for (i = 0; i < rg->num_groups; i++) {
       
  1425 				uint16 groupid = grf_load_word(&buf);
       
  1426 
       
  1427 				if (HASBIT(groupid, 15)) {
       
  1428 					rg->groups[i] = NewCallBackResultSpriteGroup(groupid);
       
  1429 				} else if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
       
  1430 					grfmsg(GMS_WARN, "NewSpriteGroup(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty.", setid, type, groupid);
       
  1431 					rg->groups[i] = NULL;
       
  1432 				} else {
       
  1433 					rg->groups[i] = _cur_grffile->spritegroups[groupid];
       
  1434 				}
       
  1435 			}
       
  1436 
       
  1437 			break;
  1409 		}
  1438 		}
  1410 
  1439 
  1411 		_cur_grffile->spritegroups[setid] = group;
  1440 		default:
  1412 		return;
  1441 		{
  1413 
  1442 			RealSpriteGroup *rg;
  1414 	} else if (numloaded == 0x80 || numloaded == 0x83) {
  1443 			byte num_loaded  = type;
  1415 		RandomizedSpriteGroup *rg;
  1444 			byte num_loading = grf_load_byte(&buf);
  1416 		int i;
  1445 			uint i;
  1417 
  1446 
  1418 		/* This stuff is getting actually evaluated in
  1447 			if (!_cur_grffile->spriteset_start) {
  1419 		 * EvalRandomizedSpriteGroup(). */
  1448 				grfmsg(GMS_ERROR, "NewSpriteGroup: No sprite set to work on! Skipping.");
  1420 
  1449 				return;
  1421 		buf += 4;
  1450 			}
  1422 		len -= 4;
  1451 
  1423 		check_length(len, 6, "NewSpriteGroup 0x80/0x83");
  1452 			if (_cur_grffile->spriteset_feature != feature) {
  1424 
  1453 				grfmsg(GMS_ERROR, "NewSpriteGroup: Group feature 0x%02X doesn't match set feature 0x%X! Playing it risky and trying to use it anyway.", feature, _cur_grffile->spriteset_feature);
  1425 		group = AllocateSpriteGroup();
  1454 				// return; // XXX: we can't because of MB's newstats.grf --pasky
  1426 		group->type = SGT_RANDOMIZED;
  1455 			}
  1427 		rg = &group->g.random;
  1456 
  1428 
  1457 			if (_cur_grffile->first_spriteset == 0)
  1429 		/* XXX: We don't free() anything, assuming that if there was
  1458 				_cur_grffile->first_spriteset = _cur_grffile->spriteset_start;
  1430 		 * some action here before, it got associated by action 3.
  1459 
  1431 		 * We should perhaps keep some refcount? --pasky */
  1460 			group = AllocateSpriteGroup();
  1432 
  1461 			group->type = SGT_REAL;
  1433 		rg->var_scope = numloaded == 0x83 ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
  1462 			rg = &group->g.real;
  1434 
  1463 
  1435 		rg->triggers = grf_load_byte(&buf);
  1464 			rg->sprites_per_set = _cur_grffile->spriteset_numents;
  1436 		rg->cmp_mode = rg->triggers & 0x80;
  1465 			rg->loaded_count  = num_loaded;
  1437 		rg->triggers &= 0x7F;
  1466 			rg->loading_count = num_loading;
  1438 
  1467 
  1439 		rg->lowest_randbit = grf_load_byte(&buf);
  1468 			rg->loaded  = calloc(rg->loaded_count,  sizeof(*rg->loaded));
  1440 		rg->num_groups = grf_load_byte(&buf);
  1469 			rg->loading = calloc(rg->loading_count, sizeof(*rg->loading));
  1441 
  1470 
  1442 		rg->groups = calloc(rg->num_groups, sizeof(*rg->groups));
  1471 			DEBUG(grf, 6) ("NewSpriteGroup: New SpriteGroup 0x%02hhx, %u views, %u loaded, %u loading, sprites %u - %u",
  1443 		for (i = 0; i < rg->num_groups; i++) {
  1472 					setid, rg->sprites_per_set, rg->loaded_count, rg->loading_count,
  1444 			uint16 groupid = grf_load_word(&buf);
  1473 					_cur_grffile->spriteset_start - _cur_grffile->sprite_offset,
  1445 
  1474 					_cur_grffile->spriteset_start + (_cur_grffile->spriteset_numents * (num_loaded + num_loading)) - _cur_grffile->sprite_offset);
  1446 			if (HASBIT(groupid, 15)) {
  1475 
  1447 				rg->groups[i] = NewCallBackResultSpriteGroup(groupid);
  1476 			for (i = 0; i < num_loaded; i++) {
  1448 			} else if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
  1477 				uint16 spriteset_id = grf_load_word(&buf);
  1449 				grfmsg(GMS_WARN, "NewSpriteGroup(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty.", setid, numloaded, groupid);
  1478 				if (HASBIT(spriteset_id, 15)) {
  1450 				rg->groups[i] = NULL;
  1479 					rg->loaded[i] = NewCallBackResultSpriteGroup(spriteset_id);
  1451 			} else {
  1480 				} else {
  1452 				rg->groups[i] = _cur_grffile->spritegroups[groupid];
  1481 					rg->loaded[i] = NewResultSpriteGroup(_cur_grffile->spriteset_start + spriteset_id * _cur_grffile->spriteset_numents, rg->sprites_per_set);
  1453 			}
  1482 				}
       
  1483 				DEBUG(grf, 8) ("NewSpriteGroup: + rg->loaded[%i]  = %u (subset %u)", i, rg->loaded[i]->g.result.result, spriteset_id);
       
  1484 			}
       
  1485 
       
  1486 			for (i = 0; i < num_loading; i++) {
       
  1487 				uint16 spriteset_id = grf_load_word(&buf);
       
  1488 				if (HASBIT(spriteset_id, 15)) {
       
  1489 					rg->loading[i] = NewCallBackResultSpriteGroup(spriteset_id);
       
  1490 				} else {
       
  1491 					rg->loading[i] = NewResultSpriteGroup(_cur_grffile->spriteset_start + spriteset_id * _cur_grffile->spriteset_numents, rg->sprites_per_set);
       
  1492 				}
       
  1493 				DEBUG(grf, 8) ("NewSpriteGroup: + rg->loading[%i] = %u (subset %u)", i, rg->loading[i]->g.result.result, spriteset_id);
       
  1494 			}
       
  1495 
       
  1496 			break;
  1454 		}
  1497 		}
  1455 
       
  1456 		_cur_grffile->spritegroups[setid] = group;
       
  1457 		return;
       
  1458 	}
       
  1459 
       
  1460 	if (!_cur_grffile->spriteset_start) {
       
  1461 		grfmsg(GMS_ERROR, "NewSpriteGroup: No sprite set to work on! Skipping.");
       
  1462 		return;
       
  1463 	}
       
  1464 
       
  1465 	if (_cur_grffile->spriteset_feature != feature) {
       
  1466 		grfmsg(GMS_ERROR, "NewSpriteGroup: Group feature 0x%02X doesn't match set feature 0x%X! Playing it risky and trying to use it anyway.", feature, _cur_grffile->spriteset_feature);
       
  1467 		// return; // XXX: we can't because of MB's newstats.grf --pasky
       
  1468 	}
       
  1469 
       
  1470 	check_length(bufend - buf, 5, "NewSpriteGroup");
       
  1471 	buf += 5;
       
  1472 	check_length(bufend - buf, 2 * numloaded, "NewSpriteGroup");
       
  1473 	loaded_ptr = buf;
       
  1474 	loading_ptr = buf + 2 * numloaded;
       
  1475 
       
  1476 	if (_cur_grffile->first_spriteset == 0)
       
  1477 		_cur_grffile->first_spriteset = _cur_grffile->spriteset_start;
       
  1478 
       
  1479 	group = AllocateSpriteGroup();
       
  1480 	group->type = SGT_REAL;
       
  1481 	rg = &group->g.real;
       
  1482 
       
  1483 	rg->sprites_per_set = _cur_grffile->spriteset_numents;
       
  1484 	rg->loaded_count  = numloaded;
       
  1485 	rg->loading_count = numloading;
       
  1486 
       
  1487 	rg->loaded  = calloc(rg->loaded_count,  sizeof(*rg->loaded));
       
  1488 	rg->loading = calloc(rg->loading_count, sizeof(*rg->loading));
       
  1489 
       
  1490 	DEBUG(grf, 6) ("NewSpriteGroup: New SpriteGroup 0x%02hhx, %u views, %u loaded, %u loading, sprites %u - %u",
       
  1491 			setid, rg->sprites_per_set, rg->loaded_count, rg->loading_count,
       
  1492 			_cur_grffile->spriteset_start - _cur_grffile->sprite_offset,
       
  1493 			_cur_grffile->spriteset_start + (_cur_grffile->spriteset_numents * (numloaded + numloading)) - _cur_grffile->sprite_offset);
       
  1494 
       
  1495 	for (i = 0; i < numloaded; i++) {
       
  1496 		uint16 spriteset_id = grf_load_word(&loaded_ptr);
       
  1497 		if (HASBIT(spriteset_id, 15)) {
       
  1498 			rg->loaded[i] = NewCallBackResultSpriteGroup(spriteset_id);
       
  1499 		} else {
       
  1500 			rg->loaded[i] = NewResultSpriteGroup(_cur_grffile->spriteset_start + spriteset_id * _cur_grffile->spriteset_numents, rg->sprites_per_set);
       
  1501 		}
       
  1502 		DEBUG(grf, 8) ("NewSpriteGroup: + rg->loaded[%i]  = %u (subset %u)", i, rg->loaded[i]->g.result.result, spriteset_id);
       
  1503 	}
       
  1504 
       
  1505 	for (i = 0; i < numloading; i++) {
       
  1506 		uint16 spriteset_id = grf_load_word(&loading_ptr);
       
  1507 		if (HASBIT(spriteset_id, 15)) {
       
  1508 			rg->loading[i] = NewCallBackResultSpriteGroup(spriteset_id);
       
  1509 		} else {
       
  1510 			rg->loading[i] = NewResultSpriteGroup(_cur_grffile->spriteset_start + spriteset_id * _cur_grffile->spriteset_numents, rg->sprites_per_set);
       
  1511 		}
       
  1512 		DEBUG(grf, 8) ("NewSpriteGroup: + rg->loading[%i] = %u (subset %u)", i, rg->loading[i]->g.result.result, spriteset_id);
       
  1513 	}
  1498 	}
  1514 
  1499 
  1515 	_cur_grffile->spritegroups[setid] = group;
  1500 	_cur_grffile->spritegroups[setid] = group;
  1516 }
  1501 }
  1517 
  1502