23 #include "vehicle.h" |
23 #include "vehicle.h" |
24 #include "newgrf_text.h" |
24 #include "newgrf_text.h" |
25 #include "table/sprites.h" |
25 #include "table/sprites.h" |
26 #include "date.h" |
26 #include "date.h" |
27 #include "currency.h" |
27 #include "currency.h" |
|
28 #include "sound.h" |
|
29 #include "newgrf_sound.h" |
28 #include "newgrf_spritegroup.h" |
30 #include "newgrf_spritegroup.h" |
29 |
31 |
30 /* TTDPatch extended GRF format codec |
32 /* TTDPatch extended GRF format codec |
31 * (c) Petr Baudis 2004 (GPL'd) |
33 * (c) Petr Baudis 2004 (GPL'd) |
32 * Changes by Florian octo Forster are (c) by the OpenTTD development team. |
34 * Changes by Florian octo Forster are (c) by the OpenTTD development team. |
54 /* 32 * 8 = 256 flags. Apparently TTDPatch uses this many.. */ |
56 /* 32 * 8 = 256 flags. Apparently TTDPatch uses this many.. */ |
55 static uint32 _ttdpatch_flags[8]; |
57 static uint32 _ttdpatch_flags[8]; |
56 |
58 |
57 /* Used by Action 0x06 to preload a pseudo sprite and modify its content */ |
59 /* Used by Action 0x06 to preload a pseudo sprite and modify its content */ |
58 static byte *_preload_sprite = NULL; |
60 static byte *_preload_sprite = NULL; |
|
61 |
|
62 |
|
63 typedef enum GrfDataType { |
|
64 GDT_SOUND, |
|
65 } GrfDataType; |
|
66 |
|
67 static byte _grf_data_blocks; |
|
68 static GrfDataType _grf_data_type; |
59 |
69 |
60 |
70 |
61 typedef enum grfspec_feature { |
71 typedef enum grfspec_feature { |
62 GSF_TRAIN, |
72 GSF_TRAIN, |
63 GSF_ROAD, |
73 GSF_ROAD, |
1180 |
1190 |
1181 *bufp = buf; |
1191 *bufp = buf; |
1182 return ret; |
1192 return ret; |
1183 } |
1193 } |
1184 |
1194 |
|
1195 static bool SoundEffectChangeInfo(uint sid, int numinfo, int prop, byte **bufp, int len) |
|
1196 { |
|
1197 byte *buf = *bufp; |
|
1198 int i; |
|
1199 bool ret = false; |
|
1200 |
|
1201 if (_cur_grffile->sound_offset == 0) { |
|
1202 grfmsg(GMS_WARN, "SoundEffectChangeInfo: No effects defined, skipping."); |
|
1203 return false; |
|
1204 } |
|
1205 |
|
1206 switch (prop) { |
|
1207 case 0x08: /* Relative volume */ |
|
1208 FOR_EACH_OBJECT { |
|
1209 uint sound = sid + i + _cur_grffile->sound_offset - GetNumOriginalSounds(); |
|
1210 |
|
1211 if (sound >= GetNumSounds()) { |
|
1212 grfmsg(GMS_WARN, "SoundEffectChangeInfo: Sound %d not defined (max %d)", sound, GetNumSounds()); |
|
1213 } else { |
|
1214 GetSound(sound)->volume = grf_load_byte(&buf); |
|
1215 } |
|
1216 } |
|
1217 break; |
|
1218 |
|
1219 case 0x09: /* Priority */ |
|
1220 FOR_EACH_OBJECT { |
|
1221 uint sound = sid + i + _cur_grffile->sound_offset - GetNumOriginalSounds(); |
|
1222 |
|
1223 if (sound >= GetNumSounds()) { |
|
1224 grfmsg(GMS_WARN, "SoundEffectChangeInfo: Sound %d not defined (max %d)", sound, GetNumSounds()); |
|
1225 } else { |
|
1226 GetSound(sound)->priority = grf_load_byte(&buf); |
|
1227 } |
|
1228 } |
|
1229 break; |
|
1230 |
|
1231 case 0x0A: /* Override old sound */ |
|
1232 FOR_EACH_OBJECT { |
|
1233 uint sound = sid + i + _cur_grffile->sound_offset - GetNumOriginalSounds(); |
|
1234 uint orig_sound = grf_load_byte(&buf); |
|
1235 |
|
1236 if (sound >= GetNumSounds() || orig_sound >= GetNumSounds()) { |
|
1237 grfmsg(GMS_WARN, "SoundEffectChangeInfo: Sound %d or %d not defined (max %d)", sound, orig_sound, GetNumSounds()); |
|
1238 } else { |
|
1239 FileEntry *newfe = GetSound(sound); |
|
1240 FileEntry *oldfe = GetSound(orig_sound); |
|
1241 |
|
1242 /* Literally copy the data of the new sound over the original */ |
|
1243 memcpy(oldfe, newfe, sizeof(*oldfe)); |
|
1244 } |
|
1245 } |
|
1246 break; |
|
1247 |
|
1248 default: |
|
1249 ret = true; |
|
1250 } |
|
1251 |
|
1252 *bufp = buf; |
|
1253 return ret; |
|
1254 } |
|
1255 |
1185 /* Action 0x00 */ |
1256 /* Action 0x00 */ |
1186 static void FeatureChangeInfo(byte *buf, int len) |
1257 static void FeatureChangeInfo(byte *buf, int len) |
1187 { |
1258 { |
1188 byte *bufend = buf + len; |
1259 byte *bufend = buf + len; |
1189 int i; |
1260 int i; |
1212 /* GSF_TOWNHOUSE */ NULL, |
1283 /* GSF_TOWNHOUSE */ NULL, |
1213 /* GSF_GLOBALVAR */ GlobalVarChangeInfo, |
1284 /* GSF_GLOBALVAR */ GlobalVarChangeInfo, |
1214 /* GSF_INDUSTRYTILES */NULL, |
1285 /* GSF_INDUSTRYTILES */NULL, |
1215 /* GSF_INDUSTRIES */ NULL, |
1286 /* GSF_INDUSTRIES */ NULL, |
1216 /* GSF_CARGOS */ NULL, |
1287 /* GSF_CARGOS */ NULL, |
1217 /* GSF_SOUNDFX */ NULL, |
1288 /* GSF_SOUNDFX */ SoundEffectChangeInfo, |
1218 }; |
1289 }; |
1219 |
1290 |
1220 uint8 feature; |
1291 uint8 feature; |
1221 uint8 numprops; |
1292 uint8 numprops; |
1222 uint8 numinfo; |
1293 uint8 numinfo; |
2704 for (l = _cur_grffile->label; l->next != NULL; l = l->next); |
2775 for (l = _cur_grffile->label; l->next != NULL; l = l->next); |
2705 l->next = label; |
2776 l->next = label; |
2706 } |
2777 } |
2707 |
2778 |
2708 grfmsg(GMS_NOTICE, "DefineGotoLabel: GOTO target with label 0x%02X", label->label); |
2779 grfmsg(GMS_NOTICE, "DefineGotoLabel: GOTO target with label 0x%02X", label->label); |
|
2780 } |
|
2781 |
|
2782 /* Action 0x11 */ |
|
2783 static void GRFSound(byte *buf, int len) |
|
2784 { |
|
2785 /* <11> <num> |
|
2786 * |
|
2787 * W num Number of sound files that follow */ |
|
2788 |
|
2789 uint16 num; |
|
2790 |
|
2791 check_length(len, 1, "GRFSound"); |
|
2792 buf++; |
|
2793 num = grf_load_word(&buf); |
|
2794 |
|
2795 _grf_data_blocks = num; |
|
2796 _grf_data_type = GDT_SOUND; |
|
2797 |
|
2798 if (_cur_grffile->sound_offset == 0) _cur_grffile->sound_offset = GetNumSounds(); |
|
2799 } |
|
2800 |
|
2801 static void LoadGRFSound(byte *buf, int len) |
|
2802 { |
|
2803 byte *buf_start = buf; |
|
2804 FileEntry *se; |
|
2805 |
|
2806 /* Allocate a sound entry. This is done even if the data is not loaded |
|
2807 * so that the indices used elsewhere are still correct. */ |
|
2808 se = AllocateFileEntry(); |
|
2809 |
|
2810 if (grf_load_dword(&buf) != 'FFIR') { |
|
2811 grfmsg(GMS_WARN, "LoadGRFSound: Missing RIFF header"); |
|
2812 return; |
|
2813 } |
|
2814 |
|
2815 /* Size of file -- we ignore this */ |
|
2816 grf_load_dword(&buf); |
|
2817 |
|
2818 if (grf_load_dword(&buf) != 'EVAW') { |
|
2819 grfmsg(GMS_WARN, "LoadGRFSound: Invalid RIFF type"); |
|
2820 return; |
|
2821 } |
|
2822 |
|
2823 for (;;) { |
|
2824 uint32 tag = grf_load_dword(&buf); |
|
2825 uint32 size = grf_load_dword(&buf); |
|
2826 |
|
2827 switch (tag) { |
|
2828 case ' tmf': /* 'fmt ' */ |
|
2829 /* Audio format, must be 1 (PCM) */ |
|
2830 if (grf_load_word(&buf) != 1) { |
|
2831 grfmsg(GMS_WARN, "LoadGRFSound: Invalid audio format"); |
|
2832 return; |
|
2833 } |
|
2834 se->channels = grf_load_word(&buf); |
|
2835 se->rate = grf_load_dword(&buf); |
|
2836 grf_load_dword(&buf); |
|
2837 grf_load_word(&buf); |
|
2838 se->bits_per_sample = grf_load_word(&buf); |
|
2839 |
|
2840 /* Consume any extra bytes */ |
|
2841 for (; size > 16; size--) grf_load_byte(&buf); |
|
2842 break; |
|
2843 |
|
2844 case 'atad': /* 'data' */ |
|
2845 se->file_size = size; |
|
2846 se->file_offset = FioGetPos() - (len - (buf - buf_start)) + 1; |
|
2847 se->file_offset |= _file_index << 24; |
|
2848 |
|
2849 /* Set default volume and priority */ |
|
2850 se->volume = 0x80; |
|
2851 se->priority = 0; |
|
2852 |
|
2853 grfmsg(GMS_NOTICE, "LoadGRFSound: channels %u, sample rate %u, bits per sample %u, length %u", se->channels, se->rate, se->bits_per_sample, size); |
|
2854 return; |
|
2855 |
|
2856 default: |
|
2857 se->file_size = 0; |
|
2858 return; |
|
2859 } |
|
2860 } |
|
2861 } |
|
2862 |
|
2863 /* 'Action 0xFF' */ |
|
2864 static void GRFDataBlock(byte *buf, int len) |
|
2865 { |
|
2866 byte name_len; |
|
2867 const char *name; |
|
2868 |
|
2869 if (_grf_data_blocks == 0) { |
|
2870 grfmsg(GMS_WARN, "GRFDataBlock: unexpected data block, skipping."); |
|
2871 return; |
|
2872 } |
|
2873 |
|
2874 buf++; |
|
2875 name_len = grf_load_byte(&buf); |
|
2876 name = (const char *)buf; |
|
2877 buf += name_len + 1; |
|
2878 |
|
2879 grfmsg(GMS_NOTICE, "GRFDataBlock: block name '%s'...", name); |
|
2880 |
|
2881 _grf_data_blocks--; |
|
2882 |
|
2883 switch (_grf_data_type) { |
|
2884 case GDT_SOUND: LoadGRFSound(buf, len - name_len - 2); break; |
|
2885 default: NOT_REACHED(); break; |
|
2886 } |
2709 } |
2887 } |
2710 |
2888 |
2711 static void InitializeGRFSpecial(void) |
2889 static void InitializeGRFSpecial(void) |
2712 { |
2890 { |
2713 _ttdpatch_flags[0] = ((_patches.always_small_airport ? 1 : 0) << 0x0C) // keepsmallairport |
2891 _ttdpatch_flags[0] = ((_patches.always_small_airport ? 1 : 0) << 0x0C) // keepsmallairport |
2876 /* Reset misc GRF features and train list display variables */ |
3054 /* Reset misc GRF features and train list display variables */ |
2877 _misc_grf_features = 0; |
3055 _misc_grf_features = 0; |
2878 _traininfo_vehicle_pitch = 0; |
3056 _traininfo_vehicle_pitch = 0; |
2879 _traininfo_vehicle_width = 29; |
3057 _traininfo_vehicle_width = 29; |
2880 |
3058 |
|
3059 InitializeSoundPool(); |
2881 InitializeSpriteGroupPool(); |
3060 InitializeSpriteGroupPool(); |
2882 } |
3061 } |
2883 |
3062 |
2884 /** Reset all NewGRFData that was used only while processing data */ |
3063 /** Reset all NewGRFData that was used only while processing data */ |
2885 static void ClearTemporaryNewGRFData(void) |
3064 static void ClearTemporaryNewGRFData(void) |
2984 * 1 and 2 in stage 2 now, let's hope that won't get us into problems. |
3163 * 1 and 2 in stage 2 now, let's hope that won't get us into problems. |
2985 * --pasky */ |
3164 * --pasky */ |
2986 /* We need a pre-stage to set up GOTO labels of Action 0x10 because the grf |
3165 /* We need a pre-stage to set up GOTO labels of Action 0x10 because the grf |
2987 * is not in memory and scanning the file every time would be too expensive. |
3166 * is not in memory and scanning the file every time would be too expensive. |
2988 * In other stages we skip action 0x10 since it's already dealt with. */ |
3167 * In other stages we skip action 0x10 since it's already dealt with. */ |
2989 static const uint32 action_mask[] = {0x10000, 0x0000FB40, 0x0000FFFF}; |
3168 static const uint32 action_mask[] = {0x10000, 0x0002FB40, 0x0000FFFF}; |
2990 |
3169 |
2991 static const SpecialSpriteHandler handlers[] = { |
3170 static const SpecialSpriteHandler handlers[] = { |
2992 /* 0x00 */ FeatureChangeInfo, |
3171 /* 0x00 */ FeatureChangeInfo, |
2993 /* 0x01 */ NewSpriteSet, |
3172 /* 0x01 */ NewSpriteSet, |
2994 /* 0x02 */ NewSpriteGroup, |
3173 /* 0x02 */ NewSpriteGroup, |
3004 /* 0x0C */ GRFComment, |
3183 /* 0x0C */ GRFComment, |
3005 /* 0x0D */ ParamSet, |
3184 /* 0x0D */ ParamSet, |
3006 /* 0x0E */ GRFInhibit, |
3185 /* 0x0E */ GRFInhibit, |
3007 /* 0x0F */ NULL, // TODO implement |
3186 /* 0x0F */ NULL, // TODO implement |
3008 /* 0x10 */ DefineGotoLabel, |
3187 /* 0x10 */ DefineGotoLabel, |
|
3188 /* 0x11 */ GRFSound, |
3009 }; |
3189 }; |
3010 |
3190 |
3011 byte* buf; |
3191 byte* buf; |
3012 byte action; |
3192 byte action; |
3013 |
3193 |
3027 FioSeekTo(num, SEEK_CUR); |
3207 FioSeekTo(num, SEEK_CUR); |
3028 } |
3208 } |
3029 |
3209 |
3030 action = buf[0]; |
3210 action = buf[0]; |
3031 |
3211 |
3032 if (action >= lengthof(handlers)) { |
3212 if (action == 0xFF) { |
|
3213 DEBUG(grf, 7) ("Handling data block in stage %d", stage); |
|
3214 GRFDataBlock(buf, num); |
|
3215 } else if (action >= lengthof(handlers)) { |
3033 DEBUG(grf, 7) ("Skipping unknown action 0x%02X", action); |
3216 DEBUG(grf, 7) ("Skipping unknown action 0x%02X", action); |
3034 } else if (!HASBIT(action_mask[stage], action)) { |
3217 } else if (!HASBIT(action_mask[stage], action)) { |
3035 DEBUG(grf, 7) ("Skipping action 0x%02X in stage %d", action, stage); |
3218 DEBUG(grf, 7) ("Skipping action 0x%02X in stage %d", action, stage); |
3036 } else if (handlers[action] == NULL) { |
3219 } else if (handlers[action] == NULL) { |
3037 DEBUG(grf, 7) ("Skipping unsupported Action 0x%02X", action); |
3220 DEBUG(grf, 7) ("Skipping unsupported Action 0x%02X", action); |