[56] | 1 | /* |
---|
| 2 | * Abuse - dark 2D side-scrolling platform game |
---|
| 3 | * Copyright (c) 1995 Crack dot Com |
---|
[494] | 4 | * Copyright (c) 2005-2011 Sam Hocevar <sam@hocevar.net> |
---|
[56] | 5 | * |
---|
| 6 | * This software was released into the Public Domain. As with most public |
---|
| 7 | * domain software, no warranty is made or implied by Crack dot Com or |
---|
| 8 | * Jonathan Clark. |
---|
| 9 | */ |
---|
| 10 | |
---|
| 11 | #include "config.h" |
---|
| 12 | |
---|
[524] | 13 | #include "common.h" |
---|
| 14 | |
---|
[481] | 15 | #include "readwav.h" |
---|
| 16 | #include "specs.h" |
---|
| 17 | #include "dprint.h" |
---|
[2] | 18 | |
---|
| 19 | struct wav_chunk |
---|
| 20 | { |
---|
[534] | 21 | char id[4]; |
---|
| 22 | uint32_t size; |
---|
| 23 | char type[4]; |
---|
| 24 | }; |
---|
[2] | 25 | |
---|
| 26 | struct wav_tag |
---|
| 27 | { |
---|
[534] | 28 | char id[4]; |
---|
| 29 | uint32_t size; |
---|
| 30 | }; |
---|
[2] | 31 | |
---|
| 32 | |
---|
| 33 | struct wav_format |
---|
| 34 | { |
---|
[534] | 35 | uint16_t fmt_tag, channels; |
---|
| 36 | uint32_t samplesps, avg_bytesps; |
---|
| 37 | uint16_t align; |
---|
| 38 | }; |
---|
[2] | 39 | |
---|
| 40 | struct pcm_wave |
---|
| 41 | { |
---|
[534] | 42 | wav_format wf; |
---|
| 43 | uint16_t bitsps; |
---|
| 44 | }; |
---|
[2] | 45 | |
---|
[534] | 46 | static void read_chunk(wav_chunk &chunk, bFILE *fp) |
---|
[2] | 47 | { |
---|
[534] | 48 | fp->read(&chunk.id, 4); |
---|
| 49 | chunk.size = fp->read_uint32(); |
---|
| 50 | fp->read(&chunk.type, 4); |
---|
[2] | 51 | } |
---|
| 52 | |
---|
[534] | 53 | static void read_tag(wav_tag &tag, bFILE *fp) |
---|
[2] | 54 | { |
---|
[534] | 55 | fp->read(&tag.id, 4); |
---|
| 56 | tag.size = fp->read_uint32(); |
---|
[2] | 57 | } |
---|
| 58 | |
---|
[534] | 59 | static void read_pcm(pcm_wave &pcm, bFILE *fp) |
---|
[2] | 60 | { |
---|
[534] | 61 | pcm.wf.fmt_tag = fp->read_uint16(); |
---|
| 62 | pcm.wf.channels = fp->read_uint16(); |
---|
| 63 | pcm.wf.samplesps = fp->read_uint32(); |
---|
| 64 | pcm.wf.avg_bytesps = fp->read_uint32(); |
---|
| 65 | pcm.wf.align = fp->read_uint16(); |
---|
| 66 | pcm.bitsps = fp->read_uint16(); |
---|
[2] | 67 | } |
---|
| 68 | |
---|
[534] | 69 | uint8_t *read_wav(char const *filename, int &sample_rate, int &data_size) |
---|
[2] | 70 | { |
---|
[534] | 71 | bFILE *fp = open_file(filename, "rb"); |
---|
| 72 | if (fp->open_failure()) |
---|
| 73 | { |
---|
| 74 | delete fp; |
---|
| 75 | return NULL; |
---|
| 76 | } |
---|
[2] | 77 | |
---|
[534] | 78 | wav_chunk chunk; |
---|
| 79 | read_chunk(chunk, fp); |
---|
| 80 | if (memcmp(chunk.type, "WAVE", 4) != 0) |
---|
| 81 | { |
---|
| 82 | printf("Bad WAV file (chunk) %s\n", filename); |
---|
| 83 | delete fp; |
---|
| 84 | return NULL; |
---|
| 85 | } |
---|
[2] | 86 | |
---|
[534] | 87 | wav_tag tag; |
---|
| 88 | read_tag(tag, fp); |
---|
| 89 | if (memcmp(tag.id, "fmt ", 4) != 0) |
---|
| 90 | { |
---|
| 91 | printf( "fmt tag missing, bad file (%s)\n", filename); |
---|
| 92 | delete fp; |
---|
| 93 | return NULL; |
---|
| 94 | } |
---|
[2] | 95 | |
---|
[534] | 96 | pcm_wave pcm; |
---|
| 97 | read_pcm(pcm, fp); |
---|
[2] | 98 | |
---|
[534] | 99 | fp->seek(tag.size - 16, SEEK_CUR); // seek to offset of sample |
---|
[2] | 100 | |
---|
[534] | 101 | read_tag(tag, fp); |
---|
[2] | 102 | |
---|
[534] | 103 | if (memcmp(tag.id, "data", 4) != 0) |
---|
| 104 | { |
---|
| 105 | printf("Bad Wav file (tag), %s\n", filename); |
---|
| 106 | delete fp; |
---|
| 107 | return NULL; |
---|
| 108 | } |
---|
[124] | 109 | |
---|
[534] | 110 | data_size = tag.size; |
---|
| 111 | uint8_t *ret = (uint8_t *)malloc(tag.size); |
---|
| 112 | ERROR(ret, "Malloc error"); |
---|
[124] | 113 | |
---|
[534] | 114 | sample_rate = pcm.wf.samplesps; |
---|
| 115 | ERROR((unsigned int)fp->read(ret, tag.size) == tag.size, "Premature end of file"); |
---|
| 116 | ERROR(pcm.bitsps == 8, "Only 8-bit samples supported"); |
---|
| 117 | ERROR(pcm.wf.channels == 1, "Only mono samples supported"); |
---|
| 118 | ERROR(pcm.wf.align == 1, "Bad block alignment"); |
---|
[2] | 119 | delete fp; |
---|
[534] | 120 | return ret; |
---|
[2] | 121 | } |
---|
| 122 | |
---|