From: Holger Schemel Date: Mon, 20 May 2002 13:15:15 +0000 (+0200) Subject: rnd-20020520-2-src X-Git-Tag: 2.1.0^2~16 X-Git-Url: https://git.artsoft.org/?a=commitdiff_plain;h=cb5fe20318d9b2c18cb82bc1f7197150cfba7bc0;p=rocksndiamonds.git rnd-20020520-2-src --- diff --git a/CHANGES b/CHANGES index b998ba6c..6fc46cd6 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,7 @@ Release Version 2.1.0 [XX XXX XXXX] - new structured setup menu (with sob-menues for graphics and sounds) - graphics, sounds and music now fully configurable - added support for TrueColor PCX graphics files + - added support for 16 bit WAV sound files - added "quick save" and "quick load" functions with shortcut key - changed default slipping behaviour of gems back to 2.0.0 style; this is now an element property for gems in the level editor, diff --git a/src/files.c b/src/files.c index 46636003..76831030 100644 --- a/src/files.c +++ b/src/files.c @@ -152,8 +152,8 @@ static int LoadLevel_HEAD(FILE *file, int chunk_size, struct LevelInfo *level) lev_fieldx = level->fieldx = fgetc(file); lev_fieldy = level->fieldy = fgetc(file); - level->time = getFile16BitInteger(file, BYTE_ORDER_BIG_ENDIAN); - level->gems_needed = getFile16BitInteger(file, BYTE_ORDER_BIG_ENDIAN); + level->time = getFile16BitBE(file); + level->gems_needed = getFile16BitBE(file); for(i=0; iname[i] = fgetc(file); @@ -229,8 +229,7 @@ static int LoadLevel_CONT(FILE *file, int chunk_size, struct LevelInfo *level) for(x=0; x<3; x++) level->yam_content[i][x][y] = checkLevelElement(level->encoding_16bit_field ? - getFile16BitInteger(file, BYTE_ORDER_BIG_ENDIAN) : - fgetc(file)); + getFile16BitBE(file) : fgetc(file)); return chunk_size; } @@ -257,8 +256,7 @@ static int LoadLevel_BODY(FILE *file, int chunk_size, struct LevelInfo *level) for(x=0; xfieldx; x++) Feld[x][y] = Ur[x][y] = checkLevelElement(level->encoding_16bit_field ? - getFile16BitInteger(file, BYTE_ORDER_BIG_ENDIAN) : - fgetc(file)); + getFile16BitBE(file) : fgetc(file)); return chunk_size; } @@ -269,7 +267,7 @@ static int LoadLevel_CNT2(FILE *file, int chunk_size, struct LevelInfo *level) int num_contents, content_xsize, content_ysize; int content_array[MAX_ELEMENT_CONTENTS][3][3]; - element = checkLevelElement(getFile16BitInteger(file,BYTE_ORDER_BIG_ENDIAN)); + element = checkLevelElement(getFile16BitBE(file)); num_contents = fgetc(file); content_xsize = fgetc(file); content_ysize = fgetc(file); @@ -278,8 +276,7 @@ static int LoadLevel_CNT2(FILE *file, int chunk_size, struct LevelInfo *level) for(i=0; i MAX_ELEMENT_CONTENTS) @@ -323,12 +320,12 @@ void LoadLevel(int level_nr) return; } - getFileChunk(file, chunk_name, NULL, BYTE_ORDER_BIG_ENDIAN); + getFileChunkBE(file, chunk_name, NULL); if (strcmp(chunk_name, "RND1") == 0) { - getFile32BitInteger(file, BYTE_ORDER_BIG_ENDIAN); /* not used */ + getFile32BitBE(file); /* not used */ - getFileChunk(file, chunk_name, NULL, BYTE_ORDER_BIG_ENDIAN); + getFileChunkBE(file, chunk_name, NULL); if (strcmp(chunk_name, "CAVE") != 0) { Error(ERR_WARN, "unknown format of level file '%s'", filename); @@ -386,7 +383,7 @@ void LoadLevel(int level_nr) { NULL, 0, NULL } }; - while (getFileChunk(file, chunk_name, &chunk_size, BYTE_ORDER_BIG_ENDIAN)) + while (getFileChunkBE(file, chunk_name, &chunk_size)) { int i = 0; @@ -481,8 +478,8 @@ static void SaveLevel_HEAD(FILE *file, struct LevelInfo *level) fputc(level->fieldx, file); fputc(level->fieldy, file); - putFile16BitInteger(file, level->time, BYTE_ORDER_BIG_ENDIAN); - putFile16BitInteger(file, level->gems_needed, BYTE_ORDER_BIG_ENDIAN); + putFile16BitBE(file, level->time); + putFile16BitBE(file, level->gems_needed); for(i=0; iname[i], file); @@ -531,8 +528,7 @@ static void SaveLevel_CONT(FILE *file, struct LevelInfo *level) for(y=0; y<3; y++) for(x=0; x<3; x++) if (level->encoding_16bit_field) - putFile16BitInteger(file, level->yam_content[i][x][y], - BYTE_ORDER_BIG_ENDIAN); + putFile16BitBE(file, level->yam_content[i][x][y]); else fputc(level->yam_content[i][x][y], file); } @@ -545,7 +541,7 @@ static void SaveLevel_BODY(FILE *file, struct LevelInfo *level) for(y=0; yfieldy; y++) for(x=0; xfieldx; x++) if (level->encoding_16bit_field) - putFile16BitInteger(file, Ur[x][y], BYTE_ORDER_BIG_ENDIAN); + putFile16BitBE(file, Ur[x][y]); else fputc(Ur[x][y], file); } @@ -588,7 +584,7 @@ static void SaveLevel_CNT2(FILE *file, struct LevelInfo *level, int element) return; } - putFile16BitInteger(file, element, BYTE_ORDER_BIG_ENDIAN); + putFile16BitBE(file, element); fputc(num_contents, file); fputc(content_xsize, file); fputc(content_ysize, file); @@ -598,8 +594,7 @@ static void SaveLevel_CNT2(FILE *file, struct LevelInfo *level, int element) for(i=0; irandom_seed = getFile32BitInteger(file, BYTE_ORDER_BIG_ENDIAN); - tape->date = getFile32BitInteger(file, BYTE_ORDER_BIG_ENDIAN); - tape->length = getFile32BitInteger(file, BYTE_ORDER_BIG_ENDIAN); + tape->random_seed = getFile32BitBE(file); + tape->date = getFile32BitBE(file); + tape->length = getFile32BitBE(file); /* read header fields that are new since version 1.2 */ if (tape->file_version >= FILE_VERSION_1_2) @@ -840,12 +835,12 @@ void LoadTape(int level_nr) if (!(file = fopen(filename, MODE_READ))) return; - getFileChunk(file, chunk_name, NULL, BYTE_ORDER_BIG_ENDIAN); + getFileChunkBE(file, chunk_name, NULL); if (strcmp(chunk_name, "RND1") == 0) { - getFile32BitInteger(file, BYTE_ORDER_BIG_ENDIAN); /* not used */ + getFile32BitBE(file); /* not used */ - getFileChunk(file, chunk_name, NULL, BYTE_ORDER_BIG_ENDIAN); + getFileChunkBE(file, chunk_name, NULL); if (strcmp(chunk_name, "TAPE") != 0) { Error(ERR_WARN, "unknown format of tape file '%s'", filename); @@ -900,7 +895,7 @@ void LoadTape(int level_nr) { NULL, 0, NULL } }; - while (getFileChunk(file, chunk_name, &chunk_size, BYTE_ORDER_BIG_ENDIAN)) + while (getFileChunkBE(file, chunk_name, &chunk_size)) { int i = 0; @@ -954,9 +949,9 @@ static void SaveTape_HEAD(FILE *file, struct TapeInfo *tape) if (tape->player_participates[i]) store_participating_players |= (1 << i); - putFile32BitInteger(file, tape->random_seed, BYTE_ORDER_BIG_ENDIAN); - putFile32BitInteger(file, tape->date, BYTE_ORDER_BIG_ENDIAN); - putFile32BitInteger(file, tape->length, BYTE_ORDER_BIG_ENDIAN); + putFile32BitBE(file, tape->random_seed); + putFile32BitBE(file, tape->date); + putFile32BitBE(file, tape->length); fputc(store_participating_players, file); @@ -1009,16 +1004,16 @@ void SaveTape(int level_nr) body_chunk_size = (num_participating_players + 1) * tape.length; - putFileChunk(file, "RND1", CHUNK_SIZE_UNDEFINED, BYTE_ORDER_BIG_ENDIAN); - putFileChunk(file, "TAPE", CHUNK_SIZE_NONE, BYTE_ORDER_BIG_ENDIAN); + putFileChunkBE(file, "RND1", CHUNK_SIZE_UNDEFINED); + putFileChunkBE(file, "TAPE", CHUNK_SIZE_NONE); - putFileChunk(file, "VERS", FILE_VERS_CHUNK_SIZE, BYTE_ORDER_BIG_ENDIAN); + putFileChunkBE(file, "VERS", FILE_VERS_CHUNK_SIZE); WriteChunk_VERS(file, FILE_VERSION_ACTUAL, GAME_VERSION_ACTUAL); - putFileChunk(file, "HEAD", TAPE_HEADER_SIZE, BYTE_ORDER_BIG_ENDIAN); + putFileChunkBE(file, "HEAD", TAPE_HEADER_SIZE); SaveTape_HEAD(file, &tape); - putFileChunk(file, "BODY", body_chunk_size, BYTE_ORDER_BIG_ENDIAN); + putFileChunkBE(file, "BODY", body_chunk_size); SaveTape_BODY(file, &tape); fclose(file); diff --git a/src/libgame/misc.h b/src/libgame/misc.h index 84a3f1b2..3dd380b1 100644 --- a/src/libgame/misc.h +++ b/src/libgame/misc.h @@ -92,6 +92,19 @@ void putFileChunk(FILE *, char *, int, int); void ReadUnusedBytesFromFile(FILE *, unsigned long); void WriteUnusedBytesToFile(FILE *, unsigned long); +#define getFile16BitBE(f) getFile16BitInteger(f,BYTE_ORDER_BIG_ENDIAN) +#define getFile16BitLE(f) getFile16BitInteger(f,BYTE_ORDER_LITTLE_ENDIAN) +#define putFile16BitBE(f,x) putFile16BitInteger(f,x,BYTE_ORDER_BIG_ENDIAN) +#define putFile16BitLE(f,x) putFile16BitInteger(f,x,BYTE_ORDER_LITTLE_ENDIAN) +#define getFile32BitBE(f) getFile32BitInteger(f,BYTE_ORDER_BIG_ENDIAN) +#define getFile32BitLE(f) getFile32BitInteger(f,BYTE_ORDER_LITTLE_ENDIAN) +#define putFile32BitBE(f,x) putFile32BitInteger(f,x,BYTE_ORDER_BIG_ENDIAN) +#define putFile32BitLE(f,x) putFile32BitInteger(f,x,BYTE_ORDER_LITTLE_ENDIAN) +#define getFileChunkBE(f,s,x) getFileChunk(f,s,x,BYTE_ORDER_BIG_ENDIAN) +#define getFileChunkLE(f,s,x) getFileChunk(f,s,x,BYTE_ORDER_LITTLE_ENDIAN) +#define putFileChunkBE(f,s,x) putFileChunk(f,s,x,BYTE_ORDER_BIG_ENDIAN) +#define putFileChunkLE(f,s,x) putFileChunk(f,s,x,BYTE_ORDER_LITTLE_ENDIAN) + char *getKeyNameFromKey(Key); char *getX11KeyNameFromKey(Key); Key getKeyFromKeyName(char *); diff --git a/src/libgame/sound.c b/src/libgame/sound.c index f659b031..b29d5dd6 100644 --- a/src/libgame/sound.c +++ b/src/libgame/sound.c @@ -91,6 +91,18 @@ struct SoundHeader_8SVX }; #endif +#if defined(AUDIO_UNIX_NATIVE) +struct SoundHeader_WAV +{ + unsigned short compression_code; + unsigned short num_channels; + unsigned long sample_rate; + unsigned long bytes_per_second; + unsigned short block_align; + unsigned short bits_per_sample; +}; +#endif + struct AudioFormatInfo { boolean stereo; /* availability of stereo sound */ @@ -106,8 +118,8 @@ struct SampleInfo int type; int format; - long data_len; - void *data_ptr; + void *data_ptr; /* pointer to first sample (8 or 16 bit) */ + long data_len; /* number of samples, NOT number of bytes */ }; typedef struct SampleInfo SoundInfo; typedef struct SampleInfo MusicInfo; @@ -127,8 +139,8 @@ struct SoundControl int type; int format; - long data_len; - void *data_ptr; + void *data_ptr; /* pointer to first sample (8 or 16 bit) */ + long data_len; /* number of samples, NOT number of bytes */ #if defined(TARGET_ALLEGRO) int voice; @@ -1487,11 +1499,14 @@ static SoundInfo *Load_WAV(char *filename) { SoundInfo *snd_info; #if defined(AUDIO_UNIX_NATIVE) + struct SoundHeader_WAV header; +#if 0 byte sound_header_buffer[WAV_HEADER_SIZE]; + int i; +#endif char chunk_name[CHUNK_ID_LEN + 1]; int chunk_size; FILE *file; - int i; #endif if (!audio.sound_available) @@ -1535,7 +1550,7 @@ static SoundInfo *Load_WAV(char *filename) } /* read chunk id "RIFF" */ - getFileChunk(file, chunk_name, &chunk_size, BYTE_ORDER_LITTLE_ENDIAN); + getFileChunkLE(file, chunk_name, &chunk_size); if (strcmp(chunk_name, "RIFF") != 0) { Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename); @@ -1545,7 +1560,7 @@ static SoundInfo *Load_WAV(char *filename) } /* read "RIFF" type id "WAVE" */ - getFileChunk(file, chunk_name, NULL, BYTE_ORDER_LITTLE_ENDIAN); + getFileChunkLE(file, chunk_name, NULL); if (strcmp(chunk_name, "WAVE") != 0) { Error(ERR_WARN, "missing 'WAVE' type ID of sound file '%s'", filename); @@ -1554,16 +1569,69 @@ static SoundInfo *Load_WAV(char *filename) return NULL; } - while (getFileChunk(file, chunk_name, &chunk_size, BYTE_ORDER_LITTLE_ENDIAN)) + while (getFileChunkLE(file, chunk_name, &chunk_size)) { if (strcmp(chunk_name, "fmt ") == 0) { - /* read header information */ - for (i=0; i < MIN(chunk_size, WAV_HEADER_SIZE); i++) - sound_header_buffer[i] = fgetc(file); + if (chunk_size < WAV_HEADER_SIZE) + { + Error(ERR_WARN, "sound file '%s': chunk 'fmt ' too short", filename); + fclose(file); + free(snd_info); + return NULL; + } + + header.compression_code = getFile16BitLE(file); + header.num_channels = getFile16BitLE(file); + header.sample_rate = getFile32BitLE(file); + header.bytes_per_second = getFile32BitLE(file); + header.block_align = getFile16BitLE(file); + header.bits_per_sample = getFile16BitLE(file); if (chunk_size > WAV_HEADER_SIZE) ReadUnusedBytesFromFile(file, chunk_size - WAV_HEADER_SIZE); + + if (header.compression_code != 1) + { + Error(ERR_WARN, "sound file '%s': compression code %d not supported", + filename, header.compression_code); + fclose(file); + free(snd_info); + return NULL; + } + + if (header.num_channels != 1) + { + Error(ERR_WARN, "sound file '%s': number of %d channels not supported", + filename, header.num_channels); + fclose(file); + free(snd_info); + return NULL; + } + + if (header.bits_per_sample != 8 && header.bits_per_sample != 16) + { + Error(ERR_WARN, "sound file '%s': %d bits per sample not supported", + filename, header.bits_per_sample); + fclose(file); + free(snd_info); + return NULL; + } + + /* warn, but accept wrong sample rate (may be only slightly different) */ + if (header.sample_rate != DEFAULT_AUDIO_SAMPLE_RATE) + Error(ERR_WARN, "sound file '%s': wrong sample rate %d instead of %d", + filename, header.sample_rate, DEFAULT_AUDIO_SAMPLE_RATE); + +#if 0 + printf("WAV file: '%s'\n", filename); + printf(" Compression code: %d'\n", header.compression_code); + printf(" Number of channels: %d'\n", header.num_channels); + printf(" Sample rate: %ld'\n", header.sample_rate); + printf(" Average bytes per second: %ld'\n", header.bytes_per_second); + printf(" Block align: %d'\n", header.block_align); + printf(" Significant bits per sample: %d'\n", header.bits_per_sample); +#endif } else if (strcmp(chunk_name, "data") == 0) { @@ -1598,7 +1666,13 @@ static SoundInfo *Load_WAV(char *filename) return NULL; } - snd_info->format = AUDIO_FORMAT_U8; + if (header.bits_per_sample == 8) + snd_info->format = AUDIO_FORMAT_U8; + else /* header.bits_per_sample == 16 */ + { + snd_info->format = AUDIO_FORMAT_S16; + snd_info->data_len /= 2; /* correct number of samples */ + } #endif /* AUDIO_UNIX_NATIVE */ diff --git a/src/timestamp.h b/src/timestamp.h index 78e001e5..b740e595 100644 --- a/src/timestamp.h +++ b/src/timestamp.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "[2002-05-19 22:16]" +#define COMPILE_DATE_STRING "[2002-05-20 14:07]"