Subversion Repositories Games.Carmageddon

Rev

Rev 11 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include "s3sound.h"
  2. #include "audio.h"
  3. #include "backends/backend.h"
  4. #include "harness/trace.h"
  5. #include "resource.h"
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9.  
  10. #define MAX_PATH_LENGTH 1024
  11. extern void dr_dprintf(char* fmt_string, ...);
  12.  
  13. int gS3_sample_filter_funcs_registered;
  14. long gS3_last_file_length;
  15. tS3_sample_filter* gS3_sample_filter_func;
  16. tS3_sample_filter* gS3_sample_filter_disable_func;
  17.  
  18. int S3LoadSample(tS3_sound_id id) {
  19.     // changed by dethrace for compatibility
  20.     // char filename[80]; // [esp+10h] [ebp-5Ch] BYREF
  21.     char filename[MAX_PATH_LENGTH];
  22.     tS3_descriptor* descriptor;
  23.     tS3_sample* sample;
  24.     char* buf;
  25.     // LPDIRECTSOUNDBUFFER dsound_buffer; // win95 only
  26.  
  27.     if (!gS3_enabled) {
  28.         return 0;
  29.     }
  30.     descriptor = S3GetDescriptorByID(id);
  31.     if (!descriptor) {
  32.         return eS3_error_bad_id;
  33.     }
  34.     if (descriptor->type != eS3_ST_sample) {
  35.         return 0;
  36.     }
  37.     if (descriptor->sound_data) {
  38.         return 0;
  39.     }
  40.     filename[0] = 0;
  41.     strcpy(filename, descriptor->filename);
  42.     sample = S3MemAllocate(sizeof(tS3_sample), kMem_S3_sound_header);
  43.     if (!sample) {
  44.         return eS3_error_memory;
  45.     }
  46.  
  47.     memset(sample, 0, sizeof(tS3_sample));
  48.     buf = S3LoadWavFile_DOS(filename);
  49.     if (buf == NULL) {
  50.         S3MemFree(sample);
  51.         return gS3_last_error;
  52.     }
  53.     sample->freeptr = buf;
  54.     if (memcmp(buf, "RIFF", 4) == 0) {
  55.         wav_header* hdr = (wav_header*)buf;
  56.         sample->dataptr = &buf[sizeof(wav_header)];
  57.         sample->size = hdr->data_bytes;
  58.         sample->rate = hdr->sample_rate;
  59.         sample->resolution = hdr->bit_depth;
  60.         sample->channels = hdr->num_channels;
  61.     } else {
  62.         sample->rate = 16000;
  63.         sample->resolution = 8;
  64.         sample->channels = 1;
  65.         sample->dataptr = buf;
  66.         sample->size = gS3_last_file_length;
  67.     }
  68.  
  69.     // win95
  70.     // descriptor->sound_buffer = S3LoadWavFile(filename, sample);
  71.     // if (!descriptor->sound_buffer) {
  72.     //     S3MemFree(sample);
  73.     //     return gS3_last_error;
  74.     // }
  75.     descriptor->special_fx = 0;
  76.     descriptor->sound_data = (char*)sample;
  77.     return eS3_error_none;
  78. }
  79.  
  80. int S3ReadWavHeader_Win95(char* buf, tWAVEFORMATEX_** pWav_format, char** data_ptr, int* pData_size) {
  81.     int riff_len;
  82.     char* file_eof;         // [esp+10h] [ebp-14h]
  83.     unsigned int chunk_len; // [esp+18h] [ebp-Ch]
  84.     char* chunk_data;       // [esp+1Ch] [ebp-8h]
  85.     // char* chunk_name;       // [esp+20h] [ebp-4h]
  86.     char* chunk_ptr;
  87.  
  88.     if (pWav_format) {
  89.         *pWav_format = 0;
  90.     }
  91.     if (data_ptr) {
  92.         *data_ptr = 0;
  93.     }
  94.     if (pData_size) {
  95.         *pData_size = 0;
  96.     }
  97.     chunk_ptr = buf + 12;
  98.     if (buf[0] != 'R' || buf[1] != 'I' || buf[2] != 'F' || buf[3] != 'F') {
  99.         return 0;
  100.     }
  101.     if (buf[8] != 'W' || buf[9] != 'A' || buf[10] != 'V' || buf[11] != 'E') {
  102.         return 0;
  103.     }
  104.     memcpy(&riff_len, &buf[4], sizeof(riff_len)); // (int32_t)buf[4];
  105. #if BR_ENDIAN_BIG
  106.     riff_len = BrSwap32(riff_len);
  107. #endif
  108.     file_eof = &chunk_ptr[riff_len - 4];
  109.     while (file_eof > chunk_ptr) {
  110.         memcpy(&chunk_len, chunk_ptr + 4, sizeof(chunk_len));
  111. #if BR_ENDIAN_BIG
  112.         chunk_len = BrSwap32(chunk_len);
  113. #endif
  114.         chunk_data = chunk_ptr + 8;
  115.         if (strncmp(chunk_ptr, "fmt ", 4) == 0) {
  116.             if (pWav_format && *pWav_format == NULL) {
  117.                 if (chunk_len < 14) {
  118.                     return 0;
  119.                 }
  120.                 *pWav_format = (tWAVEFORMATEX_*)chunk_data;
  121.                 if ((!data_ptr || *data_ptr) && (!pData_size || *pData_size)) {
  122.                     return 1;
  123.                 }
  124.             }
  125.         } else if (strncmp(chunk_ptr, "data", 4) == 0 && ((data_ptr && !*data_ptr) || (pData_size && !*pData_size))) {
  126.             if (data_ptr) {
  127.                 *data_ptr = chunk_data;
  128.             }
  129.             if (pData_size) {
  130.                 *pData_size = chunk_len;
  131.             }
  132.             if (!pWav_format || *pWav_format) {
  133.                 return 1;
  134.             }
  135.         }
  136.         chunk_ptr = &chunk_data[(chunk_len + 1) & 0xFFFFFFFE];
  137.     }
  138.     return 0;
  139. }
  140.  
  141. void* S3LoadWavFile_DOS(char* pFile_name) {
  142.     FILE* f;
  143.     long file_len;
  144.     size_t bytes_read;
  145.     char* buf;
  146.  
  147.     f = fopen(pFile_name, "rb");
  148.     if (f == NULL) {
  149.         gS3_last_error = eS3_error_readfile;
  150.         return 0;
  151.     }
  152.     fseek(f, 0, SEEK_END);
  153.     file_len = ftell(f);
  154.     fseek(f, 0, SEEK_SET);
  155.  
  156.     buf = S3MemAllocate(file_len + 1, kMem_S3_sample);
  157.  
  158.     if (buf) {
  159.         bytes_read = fread(buf, 1, file_len, f);
  160.         if (bytes_read == file_len) {
  161.             gS3_last_file_length = file_len;
  162.             fclose(f);
  163.             return buf;
  164.         } else {
  165.             gS3_last_error = 4;
  166.         }
  167.     } else {
  168.         fclose(f);
  169.         gS3_last_error = eS3_error_memory;
  170.     }
  171.     return 0;
  172. }
  173.  
  174. void* S3LoadWavFile_Win95(char* pFile_name, tS3_sample* pSample) {
  175.     FILE* f;           // [esp+Ch] [ebp-C8h]
  176.     size_t bytes_read; // [esp+14h] [ebp-C0h] BYREF
  177.     //  unsigned int locked_buffer_data_len; // [esp+18h] [ebp-BCh] BYREF
  178.     //   struct _OFSTRUCT ReOpenBuff;         // [esp+1Ch] [ebp-B8h] BYREF
  179.     char* buf; // [esp+A4h] [ebp-30h]
  180.     // LPDIRECTSOUNDBUFFER ds_buffer;       // [esp+A8h] [ebp-2Ch] BYREF
  181.     // DSBUFFERDESC buffer_desc;   // [esp+ACh] [ebp-28h] BYREF
  182.     int data_size;              // [esp+C0h] [ebp-14h] BYREF
  183.     tWAVEFORMATEX_* wav_format; // [esp+C4h] [ebp-10h] BYREF
  184.     char* data_ptr;             // [esp+C8h] [ebp-Ch] BYREF
  185.     // char* locked_buffer_data;   // [esp+CCh] [ebp-8h] BYREF
  186.     size_t file_len; // [esp+D0h] [ebp-4h]
  187.  
  188.     f = fopen(pFile_name, "rb");
  189.     if (f == NULL) {
  190.         gS3_last_error = eS3_error_readfile;
  191.         return 0;
  192.     }
  193.     fseek(f, 0, SEEK_END);
  194.     file_len = (size_t)ftell(f);
  195.     fseek(f, 0, SEEK_SET);
  196.  
  197.     buf = S3MemAllocate(file_len, kMem_S3_Windows_95_load_WAV_file);
  198.     if (buf == NULL) {
  199.         fclose(f);
  200.         gS3_last_error = eS3_error_memory;
  201.         return 0;
  202.     }
  203.     bytes_read = fread(buf, file_len, 1, f);
  204.     fclose(f);
  205.  
  206.     data_size = 0;
  207.     wav_format = 0;
  208.     data_ptr = 0;
  209.     if (S3ReadWavHeader_Win95(buf, &wav_format, &data_ptr, &data_size) == 0) {
  210.         gS3_last_error = eS3_error_readfile;
  211.         dr_dprintf("ERROR: .WAV file '%s' is crap", pFile_name);
  212.         return 0;
  213.     }
  214.     pSample->freeptr = 0;
  215.     pSample->dataptr = 0;
  216.     pSample->size = data_size;
  217.     pSample->rate = wav_format->nSamplesPerSec;
  218.     pSample->resolution = wav_format->nAvgBytesPerSec;
  219.     pSample->channels = wav_format->nChannels;
  220. #if BR_ENDIAN_BIG
  221.     pSample->rate = BrSwap32(pSample->rate);
  222.     pSample->resolution = BrSwap32(pSample->resolution);
  223.     pSample->channels = BrSwap32(pSample->channels);
  224. #endif
  225.  
  226.     // buffer_desc.dwReserved = 0;
  227.     // buffer_desc.dwSize = 20;
  228.     // buffer_desc.dwFlags = 226;
  229.     // buffer_desc.dwBufferBytes = data_size;
  230.     // buffer_desc.lpwfxFormat = wav_format;
  231.     // if (gS3_direct_sound_ptr->lpVtbl->CreateSoundBuffer(gS3_direct_sound_ptr, &buffer_desc, &ds_buffer, 0)) {
  232.     //     return 0;
  233.     // } else if (ds_buffer->lpVtbl->Lock(
  234.     //                ds_buffer,
  235.     //                0,
  236.     //                data_size,
  237.     //                (LPVOID*)&locked_buffer_data,
  238.     //                &locked_buffer_data_len,
  239.     //                0,
  240.     //                0,
  241.     //                0)) {
  242.     //     return 0;
  243.     // } else {
  244.     //     qmemcpy(locked_buffer_data, data_ptr, locked_buffer_data_len);
  245.     //     S3MemFree(buf);
  246.     //     ds_buffer->lpVtbl->Unlock(ds_buffer, locked_buffer_data, locked_buffer_data_len, 0, 0);
  247.     //     return ds_buffer;
  248.     // }
  249.     return NULL;
  250. }
  251.  
  252. int S3StopSample(tS3_channel* chan) {
  253.     if (chan->tag == 0) {
  254.         return 1;
  255.     }
  256.  
  257.     if (chan->type_struct_sample == NULL) {
  258.         return 0;
  259.     }
  260.  
  261.     AudioBackend_StopSample(chan);
  262.  
  263.     if (chan->active) {
  264.         chan->needs_service = 1;
  265.     }
  266.  
  267.     return 1;
  268. }
  269.  
  270. int S3ExecuteSampleFilterFuncs(tS3_channel* chan) {
  271.     if (((chan->descriptor->special_fx == 0) & gS3_sample_filter_funcs_registered) != 0) {
  272.         gS3_sample_filter_func(1, chan->tag);
  273.         chan->descriptor->special_fx = 1;
  274.     } else if (((gS3_sample_filter_funcs_registered == 0) & chan->descriptor->special_fx) != 0) {
  275.         gS3_sample_filter_disable_func(1, chan->tag);
  276.         chan->descriptor->special_fx = 0;
  277.     }
  278.     return 0;
  279. }
  280.  
  281. int S3PlaySample(tS3_channel* chan) {
  282.  
  283.     if (chan->type_struct_sample == NULL) {
  284.         return 0;
  285.     }
  286.  
  287.     S3SyncSampleVolumeAndPan(chan);
  288.     S3SyncSampleRate(chan);
  289.  
  290.     if (AudioBackend_PlaySample(chan) != eAB_success) {
  291.         return 0;
  292.     }
  293.     // if (chan->descriptor && chan->descriptor->type == chan->type) {
  294.     //     dsound_buffer = chan->descriptor->dsound_buffer;
  295.     //     if (dsound_buffer) {
  296.     //         dsound_buffer->lpVtbl->SetCurrentPosition(dsound_buffer, 0);
  297.     //         play_flags = chan->repetitions == 0; // 1 = DSBPLAY_LOOPING
  298.     //         dsound_buffer->lpVtbl->Play(dsound_buffer, 0, 0, play_flags);
  299.     //         if (!dsound_buffer->lpVtbl->GetStatus(dsound_buffer, (LPDWORD)&status)) {
  300.     //             if ((status & 1) != 0) // DSBSTATUS_PLAYING
  301.     //             {
  302.     //                 dsound_buffer->lpVtbl->SetCurrentPosition(dsound_buffer, 0);
  303.     //             } else {
  304.     //                 dsound_buffer->lpVtbl->Play(dsound_buffer, 0, 0, play_flags);
  305.     //             }
  306.     //         }
  307.     //     }
  308.     //   }
  309.  
  310.     return 1;
  311. }
  312.  
  313. // this function was only called in DOS build
  314. int S3CreateTypeStructs(tS3_channel* chan) {
  315.     void* result;
  316.  
  317.     result = AudioBackend_AllocateSampleTypeStruct();
  318.     if (result == NULL) {
  319.         return 0;
  320.     }
  321.     chan->type_struct_midi = NULL;
  322.     chan->type_struct_cda = NULL;
  323.     chan->type_struct_sample = (char*)result;
  324.     return 1;
  325. }
  326.  
  327. int S3ReleaseTypeStructs(tS3_channel* chan) {
  328.     if (chan->type_struct_sample) {
  329.         S3MemFree(chan->type_struct_sample);
  330.         chan->type_struct_sample = NULL;
  331.     }
  332.     if (chan->type_struct_cda) {
  333.         S3MemFree(chan->type_struct_cda);
  334.         chan->type_struct_cda = NULL;
  335.     }
  336.     return 1;
  337. }
  338.  
  339. int S3SyncSampleVolumeAndPan(tS3_channel* chan) {
  340.  
  341.     float pan_ratio; // [esp+38h] [ebp-8h]
  342.     float total_vol; // [esp+3Ch] [ebp-4h]
  343.  
  344.     int volume_db;
  345.     int pan;
  346.     //float linear_volume; // Pierre-Marie Baty -- unused variable
  347.  
  348.     if (chan->type != eS3_ST_sample) {
  349.         return 1;
  350.     }
  351.     total_vol = (float) (chan->left_volume + chan->right_volume); // Pierre-Marie Baty -- added type cast
  352.     if (total_vol == 0.0f) {
  353.         total_vol = 1.0f;
  354.     }
  355.     if (chan->descriptor && chan->descriptor->type == chan->type) {
  356.         volume_db = (int) (510.0f / total_vol * -5.0f - 350.0f); // Pierre-Marie Baty -- added type cast
  357.         if (volume_db >= 0) {
  358.             volume_db = 0;
  359.         }
  360.  
  361.         if (AudioBackend_SetVolume(chan, volume_db) == eAB_success && chan->spatial_sound) {
  362.  
  363.             if (chan->left_volume != 0 && chan->right_volume > chan->left_volume) {
  364.                 pan_ratio = chan->right_volume / (float)chan->left_volume;
  365.             } else if (chan->right_volume != 0) {
  366.                 pan_ratio = chan->left_volume / (float)chan->right_volume;
  367.             }
  368.             if (chan->left_volume != 0 && chan->right_volume != 0) {
  369.                 pan = (int) ((chan->right_volume - chan->left_volume) * pan_ratio); // Pierre-Marie Baty -- added type cast
  370.                 pan = MAX(pan, -10000);
  371.                 pan = MIN(pan, 10000);
  372.             } else if (chan->left_volume != 0) {
  373.                 pan = -10000;
  374.             } else {
  375.                 pan = 10000;
  376.             }
  377.             AudioBackend_SetPan(chan, pan);
  378.         }
  379.     }
  380.     return 1;
  381. }
  382.  
  383. int S3SyncSampleRate(tS3_channel* chan) {
  384.     if (chan->type != eS3_ST_sample) {
  385.         return 1;
  386.     }
  387.  
  388.     int rate = chan->rate;
  389.     if (rate >= 100000) {
  390.         rate = 100000;
  391.     }
  392.  
  393.     // sound_buffer->lpVtbl->SetFrequency(sound_buffer, rate);
  394.     AudioBackend_SetFrequency(chan, rate);
  395.  
  396.     return 1;
  397. }
  398.  
  399. int S3SetEffects(tS3_sample_filter* filter1, tS3_sample_filter* filter2) {
  400.     STUB_ONCE();
  401.     return 0;
  402. }
  403.