607 * when. --pasky */ |
607 * when. --pasky */ |
608 uint8 feature; |
608 uint8 feature; |
609 uint8 setid; |
609 uint8 setid; |
610 uint8 numloaded; |
610 uint8 numloaded; |
611 uint8 numloading; |
611 uint8 numloading; |
612 struct SpriteSuperSet *superset; |
612 struct SpriteGroup *group; |
613 int i; |
613 int i; |
614 |
614 |
615 check_length(len, 5, "SpriteNewSuperset"); |
615 check_length(len, 5, "SpriteNewGroup"); |
616 feature = buf[1]; |
616 feature = buf[1]; |
617 setid = buf[2]; |
617 setid = buf[2]; |
618 numloaded = buf[3]; |
618 numloaded = buf[3]; |
619 numloading = buf[4]; |
619 numloading = buf[4]; |
620 |
620 |
621 if (feature == 4) { |
621 if (feature == 4) { |
622 grfmsg(GMS_WARN, "SpriteNewSuperset: Stations unsupported, skipping."); |
622 grfmsg(GMS_WARN, "SpriteNewGroup: Stations unsupported, skipping."); |
623 return; |
623 return; |
624 } |
624 } |
625 |
625 |
626 if (numloaded == 0x81) { |
626 if (numloaded == 0x81) { |
627 // XXX: This is _VERY_ ad hoc just to handle Dm3. And that is |
627 // XXX: This is _VERY_ ad hoc just to handle Dm3. And that is |
628 // a semi-futile ask because the great Patchman himself says |
628 // a semi-futile ask because the great Patchman himself says |
629 // this is just buggy. It dereferences last (first) byte of |
629 // this is just buggy. It dereferences last (first) byte of |
630 // a schedule list pointer of the vehicle and if it's 0xff |
630 // a schedule list pointer of the vehicle and if it's 0xff |
631 // it uses superset 01, otherwise it uses superset 00. Now |
631 // it uses group 01, otherwise it uses group 00. Now |
632 // if _you_ understand _that_... We just assume it is never |
632 // if _you_ understand _that_... We just assume it is never |
633 // 0xff and therefore go for superset 00. --pasky |
633 // 0xff and therefore go for group 00. --pasky |
634 uint8 var = buf[4]; |
634 uint8 var = buf[4]; |
635 //uint8 shiftnum = buf[5]; |
635 //uint8 shiftnum = buf[5]; |
636 //uint8 andmask = buf[6]; |
636 //uint8 andmask = buf[6]; |
637 uint8 nvar = buf[7]; |
637 uint8 nvar = buf[7]; |
638 //uint32 val; |
638 //uint32 val; |
639 uint16 def; |
639 uint16 def; |
640 |
640 |
641 grfmsg(GMS_WARN, "SpriteNewSuperset(0x81): Unsupported variable %x. Using default cid.", var); |
641 grfmsg(GMS_WARN, "SpriteNewGroup(0x81): Unsupported variable %x. Using default cid.", var); |
642 |
642 |
643 //val = (0xff << shiftnum) & andmask; |
643 //val = (0xff << shiftnum) & andmask; |
644 |
644 |
645 //Go for the default. |
645 //Go for the default. |
646 if (setid >= _spritesset_count) { |
646 if (setid >= _spritesset_count) { |
647 _spritesset_count = setid + 1; |
647 _spritesset_count = setid + 1; |
648 _spritesset = realloc(_spritesset, _spritesset_count * sizeof(struct SpriteSuperSet)); |
648 _spritesset = realloc(_spritesset, _spritesset_count * sizeof(struct SpriteGroup)); |
649 } |
649 } |
650 buf += 8 + nvar * 4; |
650 buf += 8 + nvar * 4; |
651 def = grf_load_word(&buf); |
651 def = grf_load_word(&buf); |
652 _spritesset[setid] = _spritesset[def]; |
652 _spritesset[setid] = _spritesset[def]; |
653 return; |
653 return; |
654 |
654 |
655 } else if (numloaded & 0x80) { |
655 } else if (numloaded & 0x80) { |
656 grfmsg(GMS_WARN, "SpriteNewSuperset(0x%x): Unsupported special superset.", numloaded); |
656 grfmsg(GMS_WARN, "SpriteNewGroup(0x%x): Unsupported special group.", numloaded); |
657 return; |
657 return; |
658 } |
658 } |
659 |
659 |
660 if (!_spriteset_start) { |
660 if (!_spriteset_start) { |
661 grfmsg(GMS_WARN, "SpriteNewSuperset: No sprite set to work on! Skipping."); |
661 grfmsg(GMS_WARN, "SpriteNewGroup: No sprite set to work on! Skipping."); |
662 return; |
662 return; |
663 } |
663 } |
664 |
664 |
665 if (_spriteset_feature != feature) { |
665 if (_spriteset_feature != feature) { |
666 grfmsg(GMS_WARN, "SpriteNewSuperset: Superset feature %x doesn't match set feature %x! Skipping.", feature, _spriteset_feature); |
666 grfmsg(GMS_WARN, "SpriteNewGroup: Group feature %x doesn't match set feature %x! Skipping.", feature, _spriteset_feature); |
667 return; |
667 return; |
668 } |
668 } |
669 |
669 |
670 if (setid >= _spritesset_count) { |
670 if (setid >= _spritesset_count) { |
671 _spritesset_count = setid + 1; |
671 _spritesset_count = setid + 1; |
672 _spritesset = realloc(_spritesset, _spritesset_count * sizeof(struct SpriteSuperSet)); |
672 _spritesset = realloc(_spritesset, _spritesset_count * sizeof(struct SpriteGroup)); |
673 } |
673 } |
674 superset = &_spritesset[setid]; |
674 group = &_spritesset[setid]; |
675 memset(superset, 0, sizeof(struct SpriteSuperSet)); |
675 memset(group, 0, sizeof(struct SpriteGroup)); |
676 superset->sprites_per_set = _spriteset_numents; |
676 group->sprites_per_set = _spriteset_numents; |
677 |
677 |
678 buf += 5; |
678 buf += 5; |
679 |
679 |
680 for (i = 0; buf < bufend && i < numloaded; i++) { |
680 for (i = 0; buf < bufend && i < numloaded; i++) { |
681 uint16 spriteset_id = grf_load_word(&buf); |
681 uint16 spriteset_id = grf_load_word(&buf); |
682 |
682 |
683 if (_spritesset[setid].loaded_count > 16) { |
683 if (_spritesset[setid].loaded_count > 16) { |
684 grfmsg(GMS_WARN, "SpriteNewSuperset: More than 16 sprites in superset %x, skipping.", setid); |
684 grfmsg(GMS_WARN, "SpriteNewGroup: More than 16 sprites in group %x, skipping.", setid); |
685 return; |
685 return; |
686 } |
686 } |
687 superset->loaded[superset->loaded_count++] |
687 group->loaded[group->loaded_count++] |
688 = _spriteset_start + spriteset_id * _spriteset_numents; |
688 = _spriteset_start + spriteset_id * _spriteset_numents; |
689 } |
689 } |
690 |
690 |
691 for (i = 0; buf < bufend && i < numloading; i++) { |
691 for (i = 0; buf < bufend && i < numloading; i++) { |
692 uint16 spriteset_id = grf_load_word(&buf); |
692 uint16 spriteset_id = grf_load_word(&buf); |
693 |
693 |
694 if (_spritesset[setid].loading_count > 16) { |
694 if (_spritesset[setid].loading_count > 16) { |
695 grfmsg(GMS_WARN, "SpriteNewSuperset: More than 16 sprites in superset %x, skipping.", setid); |
695 grfmsg(GMS_WARN, "SpriteNewGroup: More than 16 sprites in group %x, skipping.", setid); |
696 return; |
696 return; |
697 } |
697 } |
698 superset->loading[superset->loading_count++] = _spriteset_start + spriteset_id * _spriteset_numents; |
698 group->loading[group->loading_count++] = _spriteset_start + spriteset_id * _spriteset_numents; |
699 } |
699 } |
700 } |
700 } |
701 |
701 |
702 /* Action 0x03 */ |
702 /* Action 0x03 */ |
703 static void VehicleMapSpriteSuperset(byte *buf, int len) |
703 static void NewVehicle_SpriteGroupMapping(byte *buf, int len) |
704 { |
704 { |
705 /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid> |
705 /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid> |
706 * id-list := [<id>] [id-list] |
706 * id-list := [<id>] [id-list] |
707 * cargo-list := <cargo-type> <cid> [cargo-list] |
707 * cargo-list := <cargo-type> <cid> [cargo-list] |
708 * |
708 * |
709 * B feature see action 0 |
709 * B feature see action 0 |
710 * B n-id bits 0-6: how many IDs this definition applies to |
710 * B n-id bits 0-6: how many IDs this definition applies to |
711 * bit 7: if set, this is a wagon override definition (see below) |
711 * bit 7: if set, this is a wagon override definition (see below) |
712 * B ids the IDs for which this definition applies |
712 * B ids the IDs for which this definition applies |
713 * B num-cid number of cargo IDs in this definition |
713 * B num-cid number of cargo IDs (sprite group IDs) in this definition |
714 * can be zero, in that case the def-cid is used always |
714 * can be zero, in that case the def-cid is used always |
715 * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below) |
715 * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below) |
716 * W cid cargo ID for this type of cargo |
716 * W cid cargo ID (sprite group ID) for this type of cargo |
717 * W def-cid default cargo ID */ |
717 * W def-cid default cargo ID (sprite group ID) */ |
718 /* TODO: Only trains supported now. */ |
718 /* TODO: Only trains supported now. */ |
719 /* TODO: Multiple cargo support could be useful even for trains/cars - |
719 /* TODO: Multiple cargo support could be useful even for trains/cars - |
720 * cargo id 0xff is used for showing images in the build train list. */ |
720 * cargo id 0xff is used for showing images in the build train list. */ |
721 |
721 |
722 static byte *last_engines; |
722 static byte *last_engines; |
756 uint8 engine = buf[3 + i] + _vehshifts[feature]; |
756 uint8 engine = buf[3 + i] + _vehshifts[feature]; |
757 byte *bp = &buf[4 + idcount]; |
757 byte *bp = &buf[4 + idcount]; |
758 |
758 |
759 for (c = 0; c < cidcount; c++) { |
759 for (c = 0; c < cidcount; c++) { |
760 uint8 ctype = grf_load_byte(&bp); |
760 uint8 ctype = grf_load_byte(&bp); |
761 uint16 supersetid = grf_load_word(&bp); |
761 uint16 groupid = grf_load_word(&bp); |
762 |
762 |
763 if (supersetid >= _spritesset_count) { |
763 if (groupid >= _spritesset_count) { |
764 grfmsg(GMS_WARN, "VehicleMapSpriteSuperset: Spriteset %x out of range %x, skipping.", supersetid, _spritesset_count); |
764 grfmsg(GMS_WARN, "VehicleMapSpriteGroup: Spriteset %x out of range %x, skipping.", groupid, _spritesset_count); |
765 return; |
765 return; |
766 } |
766 } |
767 |
767 |
768 if (ctype == 0xFF) |
768 if (ctype == 0xFF) |
769 ctype = CID_PURCHASE; |
769 ctype = CID_PURCHASE; |
770 |
770 |
771 if (wagover) { |
771 if (wagover) { |
772 // TODO: No multiple cargo types per vehicle yet. --pasky |
772 // TODO: No multiple cargo types per vehicle yet. --pasky |
773 SetWagonOverrideSprites(engine, &_spritesset[supersetid], last_engines, last_engines_count); |
773 SetWagonOverrideSprites(engine, &_spritesset[groupid], last_engines, last_engines_count); |
774 } else { |
774 } else { |
775 SetCustomEngineSprites(engine, ctype, &_spritesset[supersetid]); |
775 SetCustomEngineSprites(engine, ctype, &_spritesset[groupid]); |
776 last_engines[i] = engine; |
776 last_engines[i] = engine; |
777 } |
777 } |
778 } |
778 } |
779 } |
779 } |
780 |
780 |
781 { |
781 { |
782 byte *bp = buf + 4 + idcount + cidcount * 3; |
782 byte *bp = buf + 4 + idcount + cidcount * 3; |
783 uint16 supersetid = grf_load_word(&bp); |
783 uint16 groupid = grf_load_word(&bp); |
784 |
784 |
785 for (i = 0; i < idcount; i++) { |
785 for (i = 0; i < idcount; i++) { |
786 uint8 engine = buf[3 + i] + _vehshifts[feature]; |
786 uint8 engine = buf[3 + i] + _vehshifts[feature]; |
787 |
787 |
788 // Don't tell me you don't love duplicated code! |
788 // Don't tell me you don't love duplicated code! |
789 if (supersetid >= _spritesset_count) { |
789 if (groupid >= _spritesset_count) { |
790 grfmsg(GMS_WARN, "VehicleMapSpriteSuperset: Spriteset %x out of range %x, skipping.", supersetid, _spritesset_count); |
790 grfmsg(GMS_WARN, "VehicleMapSpriteGroup: Spriteset %x out of range %x, skipping.", groupid, _spritesset_count); |
791 return; |
791 return; |
792 } |
792 } |
793 |
793 |
794 if (wagover) { |
794 if (wagover) { |
795 // TODO: No multiple cargo types per vehicle yet. --pasky |
795 // TODO: No multiple cargo types per vehicle yet. --pasky |
796 SetWagonOverrideSprites(engine, &_spritesset[supersetid], last_engines, last_engines_count); |
796 SetWagonOverrideSprites(engine, &_spritesset[groupid], last_engines, last_engines_count); |
797 } else { |
797 } else { |
798 SetCustomEngineSprites(engine, CID_DEFAULT, &_spritesset[supersetid]); |
798 SetCustomEngineSprites(engine, CID_DEFAULT, &_spritesset[groupid]); |
799 last_engines[i] = engine; |
799 last_engines[i] = engine; |
800 } |
800 } |
801 } |
801 } |
802 } |
802 } |
803 } |
803 } |