newgrf.c
changeset 3561 2f67415d44aa
parent 3557 1e9867319bce
child 3566 21db83574baf
equal deleted inserted replaced
3560:b2fcf1898eec 3561:2f67415d44aa
    36 
    36 
    37 static GRFFile *_cur_grffile;
    37 static GRFFile *_cur_grffile;
    38 GRFFile *_first_grffile;
    38 GRFFile *_first_grffile;
    39 static int _cur_spriteid;
    39 static int _cur_spriteid;
    40 static int _cur_stage;
    40 static int _cur_stage;
    41 static int _nfo_line;
    41 static uint32 _nfo_line;
    42 
    42 
    43 /* 32 * 8 = 256 flags. Apparently TTDPatch uses this many.. */
    43 /* 32 * 8 = 256 flags. Apparently TTDPatch uses this many.. */
    44 static uint32 _ttdpatch_flags[8];
    44 static uint32 _ttdpatch_flags[8];
    45 
    45 
    46 
    46 
  1847 	uint8 condtype;
  1847 	uint8 condtype;
  1848 	uint8 numsprites;
  1848 	uint8 numsprites;
  1849 	uint32 param_val = 0;
  1849 	uint32 param_val = 0;
  1850 	uint32 cond_val = 0;
  1850 	uint32 cond_val = 0;
  1851 	bool result;
  1851 	bool result;
       
  1852 	GRFLabel *label;
       
  1853 	GRFLabel *choice = NULL;
  1852 
  1854 
  1853 	check_length(len, 6, "SkipIf");
  1855 	check_length(len, 6, "SkipIf");
  1854 	param = buf[1];
  1856 	param = buf[1];
  1855 	paramsize = buf[2];
  1857 	paramsize = buf[2];
  1856 	condtype = buf[3];
  1858 	condtype = buf[3];
  1945 		grfmsg(GMS_NOTICE, "Not skipping sprites, test was false.");
  1947 		grfmsg(GMS_NOTICE, "Not skipping sprites, test was false.");
  1946 		return;
  1948 		return;
  1947 	}
  1949 	}
  1948 
  1950 
  1949 	numsprites = grf_load_byte(&buf);
  1951 	numsprites = grf_load_byte(&buf);
       
  1952 
       
  1953 	/* numsprites can be a GOTO label if it has been defined in the GRF
       
  1954 	 * file. The jump will always be the first matching label that follows
       
  1955 	 * the current nfo_line. If no matching label is found, the first matching
       
  1956 	 * label in the file is used. */
       
  1957 	for (label = _cur_grffile->label; label != NULL; label = label->next) {
       
  1958 		if (label->label != numsprites) continue;
       
  1959 
       
  1960 		/* Remember a goto before the current line */
       
  1961 		if (choice == NULL) choice = label;
       
  1962 		/* If we find a label here, this is definitely good */
       
  1963 		if (label->nfo_line > _nfo_line) {
       
  1964 			choice = label;
       
  1965 			break;
       
  1966 		}
       
  1967 	}
       
  1968 
       
  1969 	if (choice != NULL) {
       
  1970 		grfmsg(GMS_NOTICE, "Jumping to label 0x%0X at line %d, test was true.", choice->label, choice->nfo_line);
       
  1971 		FioSeekTo(choice->pos, SEEK_SET);
       
  1972 		_nfo_line = choice->nfo_line;
       
  1973 		return;
       
  1974 	}
       
  1975 
  1950 	grfmsg(GMS_NOTICE, "Skipping %d sprites, test was true.", numsprites);
  1976 	grfmsg(GMS_NOTICE, "Skipping %d sprites, test was true.", numsprites);
  1951 	_skip_sprites = numsprites;
  1977 	_skip_sprites = numsprites;
  1952 	if (_skip_sprites == 0) {
  1978 	if (_skip_sprites == 0) {
  1953 		/* Zero means there are no sprites to skip, so
  1979 		/* Zero means there are no sprites to skip, so
  1954 		 * we use -1 to indicate that all further
  1980 		 * we use -1 to indicate that all further
  2063 static void GRFComment(byte *buf, int len)
  2089 static void GRFComment(byte *buf, int len)
  2064 {
  2090 {
  2065 	/* <0C> [<ignored...>]
  2091 	/* <0C> [<ignored...>]
  2066 	 *
  2092 	 *
  2067 	 * V ignored       Anything following the 0C is ignored */
  2093 	 * V ignored       Anything following the 0C is ignored */
       
  2094 
       
  2095 	static char comment[256];
       
  2096 	if (len == 1) return;
       
  2097 
       
  2098 	ttd_strlcpy(comment, buf + 1, minu(sizeof(comment), len));
       
  2099 	grfmsg(GMS_NOTICE, "GRFComment: %s", comment);
  2068 }
  2100 }
  2069 
  2101 
  2070 /* Action 0x0D */
  2102 /* Action 0x0D */
  2071 static void ParamSet(byte *buf, int len)
  2103 static void ParamSet(byte *buf, int len)
  2072 {
  2104 {
  2276 			file->flags &= 0xFFFE;
  2308 			file->flags &= 0xFFFE;
  2277 		}
  2309 		}
  2278 	}
  2310 	}
  2279 }
  2311 }
  2280 
  2312 
       
  2313 static void DefineGotoLabel(byte *buf, int len)
       
  2314 {
       
  2315 	/* <10> <label> [<comment>]
       
  2316 	 *
       
  2317 	 * B label      The label to define
       
  2318 	 * V comment    Optional comment - ignored */
       
  2319 
       
  2320 	GRFLabel *label;
       
  2321 
       
  2322 	check_length(len, 1, "GRFLabel");
       
  2323 	buf++; len--;
       
  2324 
       
  2325 	label = malloc(sizeof(*label));
       
  2326 	label->label    = grf_load_byte(&buf);
       
  2327 	label->nfo_line = _nfo_line;
       
  2328 	label->pos      = FioGetPos();
       
  2329 	label->next     = NULL;
       
  2330 
       
  2331 	/* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
       
  2332 	if (_cur_grffile->label == NULL) {
       
  2333 		_cur_grffile->label = label;
       
  2334 	} else {
       
  2335 		/* Attach the label to the end of the list */
       
  2336 		GRFLabel *l;
       
  2337 		for (l = _cur_grffile->label; l->next != NULL; l = l->next);
       
  2338 		l->next = label;
       
  2339 	}
       
  2340 
       
  2341 	grfmsg(GMS_NOTICE, "DefineGotoLabel: GOTO target with label 0x%X", label->label);
       
  2342 }
  2281 
  2343 
  2282 static void InitializeGRFSpecial(void)
  2344 static void InitializeGRFSpecial(void)
  2283 {
  2345 {
  2284 	/* FIXME: We should rather reflect reality in _ttdpatch_flags[]. */
  2346 	/* FIXME: We should rather reflect reality in _ttdpatch_flags[]. */
  2285 
  2347 
  2408 
  2470 
  2409 	// Add engine type to engine data. This is needed for the refit precalculation.
  2471 	// Add engine type to engine data. This is needed for the refit precalculation.
  2410 	AddTypeToEngines();
  2472 	AddTypeToEngines();
  2411 }
  2473 }
  2412 
  2474 
       
  2475 /** Reset all NewGRFData that was used only while processing data */
       
  2476 static void ClearTemporaryNewGRFData(void)
       
  2477 {
       
  2478 	/* Clear the GOTO labels used for GRF processing */
       
  2479 	GRFLabel *l;
       
  2480 	for (l = _cur_grffile->label; l != NULL;) {
       
  2481 		GRFLabel *l2 = l->next;
       
  2482 		free(l);
       
  2483 		l = l2;
       
  2484 	}
       
  2485 	_cur_grffile->label = NULL;
       
  2486 }
       
  2487 
  2413 static void InitNewGRFFile(const char* filename, int sprite_offset)
  2488 static void InitNewGRFFile(const char* filename, int sprite_offset)
  2414 {
  2489 {
  2415 	GRFFile *newfile;
  2490 	GRFFile *newfile;
  2416 
  2491 
  2417 	newfile = GetFileByFilename(filename);
  2492 	newfile = GetFileByFilename(filename);
  2480  * better make this more robust in the future. */
  2555  * better make this more robust in the future. */
  2481 static void DecodeSpecialSprite(uint num, uint stage)
  2556 static void DecodeSpecialSprite(uint num, uint stage)
  2482 {
  2557 {
  2483 	/* XXX: There is a difference between staged loading in TTDPatch and
  2558 	/* XXX: There is a difference between staged loading in TTDPatch and
  2484 	 * here.  In TTDPatch, for some reason actions 1 and 2 are carried out
  2559 	 * here.  In TTDPatch, for some reason actions 1 and 2 are carried out
  2485 	 * during stage 0, whilst action 3 is carried out during stage 1 (to
  2560 	 * during stage 1, whilst action 3 is carried out during stage 2 (to
  2486 	 * "resolve" cargo IDs... wtf). This is a little problem, because cargo
  2561 	 * "resolve" cargo IDs... wtf). This is a little problem, because cargo
  2487 	 * IDs are valid only within a given set (action 1) block, and may be
  2562 	 * IDs are valid only within a given set (action 1) block, and may be
  2488 	 * overwritten after action 3 associates them. But overwriting happens
  2563 	 * overwritten after action 3 associates them. But overwriting happens
  2489 	 * in an earlier stage than associating, so...  We just process actions
  2564 	 * in an earlier stage than associating, so...  We just process actions
  2490 	 * 1 and 2 in stage 1 now, let's hope that won't get us into problems.
  2565 	 * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
  2491 	 * --pasky */
  2566 	 * --pasky */
  2492 	uint32 action_mask = (stage == 0) ? 0x0001FB40 : 0x0001FFBF;
  2567 	/* We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
       
  2568 	 * is not in memory and scanning the file every time would be too expensive.
       
  2569 	 * In other stages we skip action 0x10 since it's already dealt with. */
       
  2570 	static const uint32 action_mask[] = {0x10000, 0x0000FB40, 0x0000FFBF};
       
  2571 
  2493 	static const SpecialSpriteHandler handlers[] = {
  2572 	static const SpecialSpriteHandler handlers[] = {
  2494 		/* 0x00 */ VehicleChangeInfo,
  2573 		/* 0x00 */ VehicleChangeInfo,
  2495 		/* 0x01 */ NewSpriteSet,
  2574 		/* 0x01 */ NewSpriteSet,
  2496 		/* 0x02 */ NewSpriteGroup,
  2575 		/* 0x02 */ NewSpriteGroup,
  2497 		/* 0x03 */ NewVehicle_SpriteGroupMapping,
  2576 		/* 0x03 */ NewVehicle_SpriteGroupMapping,
  2505 		/* 0x0B */ GRFError,
  2584 		/* 0x0B */ GRFError,
  2506 		/* 0x0C */ GRFComment,
  2585 		/* 0x0C */ GRFComment,
  2507 		/* 0x0D */ ParamSet,
  2586 		/* 0x0D */ ParamSet,
  2508 		/* 0x0E */ GRFInhibit,
  2587 		/* 0x0E */ GRFInhibit,
  2509 		/* 0x0F */ NULL, // TODO implement
  2588 		/* 0x0F */ NULL, // TODO implement
  2510 		/* 0x10 */ NULL  // TODO implement
  2589 		/* 0x10 */ DefineGotoLabel,
  2511 	};
  2590 	};
  2512 
  2591 
  2513 	byte* buf = malloc(num);
  2592 	byte* buf = malloc(num);
  2514 	byte action;
  2593 	byte action;
  2515 
  2594 
  2518 	FioReadBlock(buf, num);
  2597 	FioReadBlock(buf, num);
  2519 	action = buf[0];
  2598 	action = buf[0];
  2520 
  2599 
  2521 	if (action >= lengthof(handlers)) {
  2600 	if (action >= lengthof(handlers)) {
  2522 		DEBUG(grf, 7) ("Skipping unknown action 0x%02X", action);
  2601 		DEBUG(grf, 7) ("Skipping unknown action 0x%02X", action);
  2523 	} else if (!HASBIT(action_mask, action)) {
  2602 	} else if (!HASBIT(action_mask[stage], action)) {
  2524 		DEBUG(grf, 7) ("Skipping action 0x%02X in stage %d", action, stage);
  2603 		DEBUG(grf, 7) ("Skipping action 0x%02X in stage %d", action, stage);
  2525 	} else if (handlers[action] == NULL) {
  2604 	} else if (handlers[action] == NULL) {
  2526 		DEBUG(grf, 7) ("Skipping unsupported Action 0x%02X", action);
  2605 		DEBUG(grf, 7) ("Skipping unsupported Action 0x%02X", action);
  2527 	} else {
  2606 	} else {
  2528 		DEBUG(grf, 7) ("Handling action 0x%02X in stage %d", action, stage);
  2607 		DEBUG(grf, 7) ("Handling action 0x%02X in stage %d", action, stage);
  2546 	 * carried out.  All others are ignored, because they only need to be
  2625 	 * carried out.  All others are ignored, because they only need to be
  2547 	 * processed once at initialization.  */
  2626 	 * processed once at initialization.  */
  2548 	if (stage != 0) {
  2627 	if (stage != 0) {
  2549 		_cur_grffile = GetFileByFilename(filename);
  2628 		_cur_grffile = GetFileByFilename(filename);
  2550 		if (_cur_grffile == NULL) error("File ``%s'' lost in cache.\n", filename);
  2629 		if (_cur_grffile == NULL) error("File ``%s'' lost in cache.\n", filename);
  2551 		if (!(_cur_grffile->flags & 0x0001)) return;
  2630 		if (stage > 1 && !(_cur_grffile->flags & 0x0001)) return;
  2552 	}
  2631 	}
  2553 
  2632 
  2554 	FioOpenFile(file_index, filename);
  2633 	FioOpenFile(file_index, filename);
  2555 	_file_index = file_index; // XXX
  2634 	_file_index = file_index; // XXX
  2556 
  2635 
  2622 
  2701 
  2623 	/* Load newgrf sprites
  2702 	/* Load newgrf sprites
  2624 	 * in each loading stage, (try to) open each file specified in the config
  2703 	 * in each loading stage, (try to) open each file specified in the config
  2625 	 * and load information from it. */
  2704 	 * and load information from it. */
  2626 	_custom_sprites_base = load_index;
  2705 	_custom_sprites_base = load_index;
  2627 	for (stage = 0; stage < 2; stage++) {
  2706 	for (stage = 0; stage <= 2; stage++) {
  2628 		uint slot = file_index;
  2707 		uint slot = file_index;
  2629 		uint j;
  2708 		uint j;
  2630 
  2709 
  2631 		_cur_stage = stage;
  2710 		_cur_stage = stage;
  2632 		_cur_spriteid = load_index;
  2711 		_cur_spriteid = load_index;
  2635 				// TODO: usrerror()
  2714 				// TODO: usrerror()
  2636 				error("NewGRF file missing: %s", _newgrf_files[j]);
  2715 				error("NewGRF file missing: %s", _newgrf_files[j]);
  2637 			}
  2716 			}
  2638 			if (stage == 0) InitNewGRFFile(_newgrf_files[j], _cur_spriteid);
  2717 			if (stage == 0) InitNewGRFFile(_newgrf_files[j], _cur_spriteid);
  2639 			LoadNewGRFFile(_newgrf_files[j], slot++, stage);
  2718 			LoadNewGRFFile(_newgrf_files[j], slot++, stage);
       
  2719 			if (stage == 2) ClearTemporaryNewGRFData();
  2640 			DEBUG(spritecache, 2) ("Currently %i sprites are loaded", load_index);
  2720 			DEBUG(spritecache, 2) ("Currently %i sprites are loaded", load_index);
  2641 		}
  2721 		}
  2642 	}
  2722 	}
  2643 
  2723 
  2644 	// Pre-calculate all refit masks after loading GRF files
  2724 	// Pre-calculate all refit masks after loading GRF files