- #include "s3sound.h" 
- #include "audio.h" 
- #include "backends/backend.h" 
- #include "harness/hooks.h" 
- #include "harness/trace.h" 
- #include "resource.h" 
- #include <stdio.h> 
- #include <stdlib.h> 
- #include <string.h> 
-   
- #define MAX_PATH_LENGTH 1024 
- extern void dr_dprintf(char* fmt_string, ...); 
-   
- int gS3_sample_filter_funcs_registered; 
- long gS3_last_file_length; 
- tS3_sample_filter* gS3_sample_filter_func; 
- tS3_sample_filter* gS3_sample_filter_disable_func; 
-   
- int S3LoadSample(tS3_sound_id id) { 
-     // changed by dethrace for compatibility 
-     // char filename[80]; // [esp+10h] [ebp-5Ch] BYREF 
-     char filename[MAX_PATH_LENGTH]; 
-     tS3_descriptor* descriptor; 
-     tS3_sample* sample; 
-     char* buf; 
-     // LPDIRECTSOUNDBUFFER dsound_buffer; // win95 only 
-   
-     if (!gS3_enabled) { 
-         return 0; 
-     } 
-     descriptor = S3GetDescriptorByID(id); 
-     if (!descriptor) { 
-         return eS3_error_bad_id; 
-     } 
-     if (descriptor->type != eS3_ST_sample) { 
-         return 0; 
-     } 
-     if (descriptor->sound_data) { 
-         return 0; 
-     } 
-     filename[0] = 0; 
-     strcpy(- filename ,-  descriptor ->- filename );
 
-     sample = S3MemAllocate(sizeof(tS3_sample), kMem_S3_sound_header); 
-     if (!sample) { 
-         return eS3_error_memory; 
-     } 
-   
-     memset(- sample , 0, sizeof(- tS3_sample ));
 
-     buf = S3LoadWavFile_DOS(filename); 
-     if (buf == NULL) { 
-         S3MemFree(sample); 
-         return gS3_last_error; 
-     } 
-     sample->freeptr = buf; 
-     if (memcmp(- buf , "RIFF", 4) == 0) {
 
-         wav_header* hdr = (wav_header*)buf; 
-         sample->dataptr = &buf[sizeof(wav_header)]; 
-         sample->size = hdr->data_bytes; 
-         sample->rate = hdr->sample_rate; 
-         sample->resolution = hdr->bit_depth; 
-         sample->channels = hdr->num_channels; 
-     } else { 
-         sample->rate = 16000; 
-         sample->resolution = 8; 
-         sample->channels = 1; 
-         sample->dataptr = buf; 
-         sample->size = gS3_last_file_length; 
-     } 
-   
-     // win95 
-     // descriptor->sound_buffer = S3LoadWavFile(filename, sample); 
-     // if (!descriptor->sound_buffer) { 
-     //     S3MemFree(sample); 
-     //     return gS3_last_error; 
-     // } 
-     descriptor->special_fx = 0; 
-     descriptor->sound_data = (char*)sample; 
-     return eS3_error_none; 
- } 
-   
- int S3ReadWavHeader_Win95(char* buf, tWAVEFORMATEX_** pWav_format, char** data_ptr, int* pData_size) { 
-     int riff_len; 
-     char* file_eof;         // [esp+10h] [ebp-14h] 
-     unsigned int chunk_len; // [esp+18h] [ebp-Ch] 
-     char* chunk_data;       // [esp+1Ch] [ebp-8h] 
-     // char* chunk_name;       // [esp+20h] [ebp-4h] 
-     char* chunk_ptr; 
-   
-     if (pWav_format) { 
-         *pWav_format = 0; 
-     } 
-     if (data_ptr) { 
-         *data_ptr = 0; 
-     } 
-     if (pData_size) { 
-         *pData_size = 0; 
-     } 
-     chunk_ptr = buf + 12; 
-     if (buf[0] != 'R' || buf[1] != 'I' || buf[2] != 'F' || buf[3] != 'F') { 
-         return 0; 
-     } 
-     if (buf[8] != 'W' || buf[9] != 'A' || buf[10] != 'V' || buf[11] != 'E') { 
-         return 0; 
-     } 
-     memcpy(&- riff_len , &- buf [4], sizeof(- riff_len )); // (int32_t)buf[4];
 
- #if BR_ENDIAN_BIG 
-     riff_len = BrSwap32(riff_len); 
- #endif 
-     file_eof = &chunk_ptr[riff_len - 4]; 
-     while (file_eof > chunk_ptr) { 
-         memcpy(&- chunk_len ,-  chunk_ptr  + 4, sizeof(- chunk_len ));
 
- #if BR_ENDIAN_BIG 
-         chunk_len = BrSwap32(chunk_len); 
- #endif 
-         chunk_data = chunk_ptr + 8; 
-         if (strncmp(- chunk_ptr , "fmt ", 4) == 0) {
 
-             if (pWav_format && *pWav_format == NULL) { 
-                 if (chunk_len < 14) { 
-                     return 0; 
-                 } 
-                 *pWav_format = (tWAVEFORMATEX_*)chunk_data; 
-                 if ((!data_ptr || *data_ptr) && (!pData_size || *pData_size)) { 
-                     return 1; 
-                 } 
-             } 
-         } else if (strncmp(- chunk_ptr , "data", 4) == 0 && ((- data_ptr  && !*- data_ptr ) || (- pData_size  && !*- pData_size ))) {
 
-             if (data_ptr) { 
-                 *data_ptr = chunk_data; 
-             } 
-             if (pData_size) { 
-                 *pData_size = chunk_len; 
-             } 
-             if (!pWav_format || *pWav_format) { 
-                 return 1; 
-             } 
-         } 
-         chunk_ptr = &chunk_data[(chunk_len + 1) & 0xFFFFFFFE]; 
-     } 
-     return 0; 
- } 
-   
- void* S3LoadWavFile_DOS(char* pFile_name) { 
-     FILE* f; 
-     long file_len; 
-     size_t bytes_read; 
-     char* buf; 
-   
-     f = Harness_Hook_fopen (pFile_name, "rb"); 
-     if (f == NULL) { 
-         gS3_last_error = eS3_error_readfile; 
-         return 0; 
-     } 
-   
-     buf = S3MemAllocate(file_len + 1, kMem_S3_sample); 
-   
-     if (buf) { 
-         bytes_read  = fread(- buf , 1,-  file_len ,-  f );
-         if (bytes_read == file_len) { 
-             gS3_last_file_length = file_len; 
-             return buf; 
-         } else { 
-             gS3_last_error = 4; 
-         } 
-     } else { 
-         gS3_last_error = eS3_error_memory; 
-     } 
-     return 0; 
- } 
-   
- void* S3LoadWavFile_Win95(char* pFile_name, tS3_sample* pSample) { 
-     FILE* f;           // [esp+Ch] [ebp-C8h] 
-     size_t bytes_read; // [esp+14h] [ebp-C0h] BYREF 
-     //  unsigned int locked_buffer_data_len; // [esp+18h] [ebp-BCh] BYREF 
-     //   struct _OFSTRUCT ReOpenBuff;         // [esp+1Ch] [ebp-B8h] BYREF 
-     char* buf; // [esp+A4h] [ebp-30h] 
-     // LPDIRECTSOUNDBUFFER ds_buffer;       // [esp+A8h] [ebp-2Ch] BYREF 
-     // DSBUFFERDESC buffer_desc;   // [esp+ACh] [ebp-28h] BYREF 
-     int data_size;              // [esp+C0h] [ebp-14h] BYREF 
-     tWAVEFORMATEX_* wav_format; // [esp+C4h] [ebp-10h] BYREF 
-     char* data_ptr;             // [esp+C8h] [ebp-Ch] BYREF 
-     // char* locked_buffer_data;   // [esp+CCh] [ebp-8h] BYREF 
-     size_t file_len; // [esp+D0h] [ebp-4h] 
-   
-     f = Harness_Hook_fopen (pFile_name, "rb"); 
-     if (f == NULL) { 
-         gS3_last_error = eS3_error_readfile; 
-         return 0; 
-     } 
-     file_len  = (size_t)ftell(- f );
-   
-     buf = S3MemAllocate(file_len, kMem_S3_Windows_95_load_WAV_file); 
-     if (buf == NULL) { 
-         gS3_last_error = eS3_error_memory; 
-         return 0; 
-     } 
-     bytes_read  = fread(- buf ,-  file_len , 1,-  f );
-   
-     data_size = 0; 
-     wav_format = 0; 
-     data_ptr = 0; 
-     if (S3ReadWavHeader_Win95(buf, &wav_format, &data_ptr, &data_size) == 0) { 
-         gS3_last_error = eS3_error_readfile; 
-         dr_dprintf("ERROR: .WAV file '%s' is crap", pFile_name); 
-         return 0; 
-     } 
-     pSample->freeptr = 0; 
-     pSample->dataptr = 0; 
-     pSample->size = data_size; 
-     pSample->rate = wav_format->nSamplesPerSec; 
-     pSample->resolution = wav_format->nAvgBytesPerSec; 
-     pSample->channels = wav_format->nChannels; 
- #if BR_ENDIAN_BIG 
-     pSample->rate = BrSwap32(pSample->rate); 
-     pSample->resolution = BrSwap32(pSample->resolution); 
-     pSample->channels = BrSwap32(pSample->channels); 
- #endif 
-   
-     // buffer_desc.dwReserved = 0; 
-     // buffer_desc.dwSize = 20; 
-     // buffer_desc.dwFlags = 226; 
-     // buffer_desc.dwBufferBytes = data_size; 
-     // buffer_desc.lpwfxFormat = wav_format; 
-     // if (gS3_direct_sound_ptr->lpVtbl->CreateSoundBuffer(gS3_direct_sound_ptr, &buffer_desc, &ds_buffer, 0)) { 
-     //     return 0; 
-     // } else if (ds_buffer->lpVtbl->Lock( 
-     //                ds_buffer, 
-     //                0, 
-     //                data_size, 
-     //                (LPVOID*)&locked_buffer_data, 
-     //                &locked_buffer_data_len, 
-     //                0, 
-     //                0, 
-     //                0)) { 
-     //     return 0; 
-     // } else { 
-     //     qmemcpy(locked_buffer_data, data_ptr, locked_buffer_data_len); 
-     //     S3MemFree(buf); 
-     //     ds_buffer->lpVtbl->Unlock(ds_buffer, locked_buffer_data, locked_buffer_data_len, 0, 0); 
-     //     return ds_buffer; 
-     // } 
-     return NULL; 
- } 
-   
- int S3StopSample(tS3_channel* chan) { 
-     if (chan->tag == 0) { 
-         return 1; 
-     } 
-   
-     if (chan->type_struct_sample == NULL) { 
-         return 0; 
-     } 
-   
-     AudioBackend_StopSample(chan); 
-   
-     if (chan->active) { 
-         chan->needs_service = 1; 
-     } 
-   
-     return 1; 
- } 
-   
- int S3ExecuteSampleFilterFuncs(tS3_channel* chan) { 
-     if (((chan->descriptor->special_fx == 0) & gS3_sample_filter_funcs_registered) != 0) { 
-         gS3_sample_filter_func(1, chan->tag); 
-         chan->descriptor->special_fx = 1; 
-     } else if (((gS3_sample_filter_funcs_registered == 0) & chan->descriptor->special_fx) != 0) { 
-         gS3_sample_filter_disable_func(1, chan->tag); 
-         chan->descriptor->special_fx = 0; 
-     } 
-     return 0; 
- } 
-   
- int S3PlaySample(tS3_channel* chan) { 
-   
-     if (chan->type_struct_sample == NULL) { 
-         return 0; 
-     } 
-   
-     S3SyncSampleVolumeAndPan(chan); 
-     S3SyncSampleRate(chan); 
-   
-     if (AudioBackend_PlaySample(chan) != eAB_success) { 
-         return 0; 
-     } 
-     // if (chan->descriptor && chan->descriptor->type == chan->type) { 
-     //     dsound_buffer = chan->descriptor->dsound_buffer; 
-     //     if (dsound_buffer) { 
-     //         dsound_buffer->lpVtbl->SetCurrentPosition(dsound_buffer, 0); 
-     //         play_flags = chan->repetitions == 0; // 1 = DSBPLAY_LOOPING 
-     //         dsound_buffer->lpVtbl->Play(dsound_buffer, 0, 0, play_flags); 
-     //         if (!dsound_buffer->lpVtbl->GetStatus(dsound_buffer, (LPDWORD)&status)) { 
-     //             if ((status & 1) != 0) // DSBSTATUS_PLAYING 
-     //             { 
-     //                 dsound_buffer->lpVtbl->SetCurrentPosition(dsound_buffer, 0); 
-     //             } else { 
-     //                 dsound_buffer->lpVtbl->Play(dsound_buffer, 0, 0, play_flags); 
-     //             } 
-     //         } 
-     //     } 
-     //   } 
-   
-     return 1; 
- } 
-   
- // this function was only called in DOS build 
- int S3CreateTypeStructs(tS3_channel* chan) { 
-     void* result; 
-   
-     result = AudioBackend_AllocateSampleTypeStruct(); 
-     if (result == NULL) { 
-         return 0; 
-     } 
-     chan->type_struct_midi = NULL; 
-     chan->type_struct_cda = NULL; 
-     chan->type_struct_sample = (char*)result; 
-     return 1; 
- } 
-   
- int S3ReleaseTypeStructs(tS3_channel* chan) { 
-     if (chan->type_struct_sample) { 
-         S3MemFree(chan->type_struct_sample); 
-         chan->type_struct_sample = NULL; 
-     } 
-     if (chan->type_struct_cda) { 
-         S3MemFree(chan->type_struct_cda); 
-         chan->type_struct_cda = NULL; 
-     } 
-     return 1; 
- } 
-   
- int S3SyncSampleVolumeAndPan(tS3_channel* chan) { 
-   
-     float pan_ratio; // [esp+38h] [ebp-8h] 
-     float total_vol; // [esp+3Ch] [ebp-4h] 
-   
-     int volume_db; 
-     int pan; 
-     //float linear_volume; // Pierre-Marie Baty -- unused variable 
-   
-     if (chan->type != eS3_ST_sample) { 
-         return 1; 
-     } 
-     total_vol = (float) (chan->left_volume + chan->right_volume); // Pierre-Marie Baty -- added type cast 
-     if (total_vol == 0.0f) { 
-         total_vol = 1.0f; 
-     } 
-     if (chan->descriptor && chan->descriptor->type == chan->type) { 
-         volume_db = (int) (510.0f / total_vol * -5.0f - 350.0f); // Pierre-Marie Baty -- added type cast 
-         if (volume_db >= 0) { 
-             volume_db = 0; 
-         } 
-   
-         if (AudioBackend_SetVolume(chan, volume_db) == eAB_success && chan->spatial_sound) { 
-   
-             if (chan->left_volume != 0 && chan->right_volume > chan->left_volume) { 
-                 pan_ratio = chan->right_volume / (float)chan->left_volume; 
-             } else if (chan->right_volume != 0) { 
-                 pan_ratio = chan->left_volume / (float)chan->right_volume; 
-             } 
-             if (chan->left_volume != 0 && chan->right_volume != 0) { 
-                 pan = (int) ((chan->right_volume - chan->left_volume) * pan_ratio); // Pierre-Marie Baty -- added type cast 
-                 pan = MAX(pan, -10000); 
-                 pan = MIN(pan, 10000); 
-             } else if (chan->left_volume != 0) { 
-                 pan = -10000; 
-             } else { 
-                 pan = 10000; 
-             } 
-             AudioBackend_SetPan(chan, pan); 
-         } 
-     } 
-     return 1; 
- } 
-   
- int S3SyncSampleRate(tS3_channel* chan) { 
-     if (chan->type != eS3_ST_sample) { 
-         return 1; 
-     } 
-   
-     int rate = chan->rate; 
-     if (rate >= 100000) { 
-         rate = 100000; 
-     } 
-   
-     // sound_buffer->lpVtbl->SetFrequency(sound_buffer, rate); 
-     AudioBackend_SetFrequency(chan, rate); 
-   
-     return 1; 
- } 
-   
- int S3SetEffects(tS3_sample_filter* filter1, tS3_sample_filter* filter2) { 
-     STUB_ONCE(); 
-     return 0; 
- } 
-