// File: /workspace/github_c_makefile_star2_O1/jonof[P]jfaudiolib/src/driver_sdl.c
// Function: SDLDrv_PCM_Init
int SDLDrv_PCM_Init(int * mixrate, int * numchannels, int * samplebits, void * initdata)
{
    Uint32 inited;
    int err = 0;
    SDL_AudioSpec spec, actual;

    (void)initdata;

    if (Initialised) {
        SDLDrv_PCM_Shutdown();
    }

    inited = SDL_WasInit(SDL_INIT_EVERYTHING);

    if (inited == 0) {
        // nothing was initialised
        err = SDL_Init(SDL_INIT_AUDIO);
        StartedSDLInit |= 0x80000000 + SDL_INIT_AUDIO;
    } else if (!(inited & SDL_INIT_AUDIO)) {
        err = SDL_InitSubSystem(SDL_INIT_AUDIO);
        StartedSDLInit |= SDL_INIT_AUDIO;
    }

    if (err < 0) {
        ErrorCode = SDLErr_InitSubSystem;
        return SDLErr_Error;
    }

    StartedSDL |= SDL_INIT_AUDIO;

    #if (SDL_MAJOR_VERSION == 1)
    {
        char drivername[256] = "(error)";
        SDL_AudioDriverName(drivername, sizeof(drivername));
        ASS_Message("SDLDrv: audio driver: %s\n", drivername);
    }
    #else
    {
        const char * drivername = SDL_GetCurrentAudioDriver();
        ASS_Message("SDLDrv: audio driver: %s\n", drivername ? drivername : "(error)");
    }
    #endif

    memset(&spec, 0, sizeof(spec));
    spec.freq = *mixrate;
    spec.format = (*samplebits == 8) ? AUDIO_U8 : AUDIO_S16SYS;
    spec.channels = *numchannels;
    spec.callback = fillData;
    spec.userdata = 0;

    // Mix buffer to be a power of 2, min 512 samples, and 4096 samples at 48kHz.
    spec.samples = 512;
    while (spec.samples < (4096 * *mixrate / 48000))
        spec.samples += spec.samples;

    memset(&actual, 0, sizeof(actual));

    err = SDL_OpenAudio(&spec, &actual);
    if (err < 0) {
        ErrorCode = SDLErr_OpenAudio;
        return SDLErr_Error;
    }

    if (actual.freq == 0 || actual.channels == 0) {
        // hack for when SDL said it opened the audio, but clearly didn't
        SDL_CloseAudio();
        ErrorCode = SDLErr_OpenAudio;
        return SDLErr_Error;
    }

    err = 0;

    *mixrate = actual.freq;
    if (actual.format == AUDIO_U8 || actual.format == AUDIO_S16SYS) {
        *samplebits = actual.format & 0xff;
    } else {
        const char *format;
        switch (actual.format) {
            case AUDIO_U8: format = "AUDIO_U8"; break;
            case AUDIO_S8: format = "AUDIO_S8"; break;
            case AUDIO_U16LSB: format = "AUDIO_U16LSB"; break;
            case AUDIO_S16LSB: format = "AUDIO_S16LSB"; break;
            case AUDIO_U16MSB: format = "AUDIO_U16MSB"; break;
            case AUDIO_S16MSB: format = "AUDIO_S16MSB"; break;
            default: format = "?!"; break;
        }
        ASS_Message("SDLDrv: audio format: %s\n", format);
        ErrorCode = SDLErr_OpenAudio;
        err = 1;
    }
    if (actual.channels == 1 || actual.channels == 2) {
        *numchannels = actual.channels;
    } else {
        ASS_Message("SDLDrv: audio channels: %d\n", actual.channels);
        ErrorCode = SDLErr_OpenAudio;
        err = 1;
    }
    // ASS_Message("SDLDrv: actual samples = %d vs spec samples = %d\n", actual.samples, spec.samples);

    if (err) {
        SDL_CloseAudio();
        return SDLErr_Error;
    } else {
        Initialised = 1;
        return SDLErr_Ok;
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x48, %rsp
movq %rdx, %r14
movq %rsi, %rbx
movq %rdi, %r15
cmpb $0x1, 0x10b68(%rip)     # 0x19754
jne 0x8bf3
callq 0x8def
movl $0xf231, %edi           # imm = 0xF231
callq 0x2120
testl %eax, %eax
je 0x8c16
testb $0x10, %al
jne 0x8c33
movl $0x10, %ebp
movl $0x10, %edi
callq 0x21a0
jmp 0x8c25
movl $0x10, %edi
callq 0x2190
movl $0x80000010, %ebp       # imm = 0x80000010
orl %ebp, 0x10b2d(%rip)     # 0x19758
testl %eax, %eax
js 0x8d1d
orb $0x10, 0x10b22(%rip)    # 0x1975c
callq 0x2080
testq %rax, %rax
leaq 0x236d(%rip), %rsi      # 0xafb6
cmovneq %rax, %rsi
leaq 0x2348(%rip), %rdi      # 0xaf9c
xorl %eax, %eax
callq 0x8aa8
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
movaps %xmm0, (%rsp)
movl (%r15), %eax
movl %eax, (%rsp)
movl (%r14), %ecx
cmpl $0x8, %ecx
movl $0x8010, %edx           # imm = 0x8010
cmovel %ecx, %edx
movw %dx, 0x4(%rsp)
movb (%rbx), %cl
movb %cl, 0x6(%rsp)
leaq 0x1ab(%rip), %rcx       # 0x8e38
movq %rcx, 0x10(%rsp)
movq $0x0, 0x18(%rsp)
shll $0xc, %eax
cltq
imulq $0x57619f1, %rax, %rax  # imm = 0x57619F1
movq %rax, %rcx
shrq $0x3f, %rcx
sarq $0x2a, %rax
addl %ecx, %eax
movw $0x200, %dx             # imm = 0x200
movl %edx, %ecx
movzwl %dx, %esi
leal (%rcx,%rcx), %edx
cmpl %esi, %eax
jg 0x8cb8
movq %rsp, %rdi
movw %cx, 0x8(%rdi)
xorps %xmm0, %xmm0
leaq 0x20(%rsp), %rsi
movaps %xmm0, (%rsi)
movaps %xmm0, 0x10(%rsi)
callq 0x2350
testl %eax, %eax
js 0x8d31
movl 0x20(%rsp), %eax
testl %eax, %eax
je 0x8d2c
cmpb $0x0, 0x26(%rsp)
je 0x8d2c
movl %eax, (%r15)
movzwl 0x24(%rsp), %ebp
cmpl $0x8007, %ebp           # imm = 0x8007
jg 0x8d40
cmpl $0x8, %ebp
je 0x8d58
cmpl $0x10, %ebp
je 0x8d74
cmpl $0x1010, %ebp           # imm = 0x1010
jne 0x8d6b
leaq 0x22b9(%rip), %rsi      # 0xafd4
jmp 0x8d84
movl $0x2, 0x10a29(%rip)     # 0x19750
jmp 0x8ddf
callq 0x2110
movl $0x3, 0x10a15(%rip)     # 0x19750
jmp 0x8ddf
cmpl $0x8008, %ebp           # imm = 0x8008
je 0x8d62
cmpl $0x9010, %ebp           # imm = 0x9010
je 0x8d7d
cmpl $0x8010, %ebp           # imm = 0x8010
jne 0x8d6b
movl %ebp, %eax
andl $0x18, %eax
movl %eax, (%r14)
jmp 0x8d9c
leaq 0x2255(%rip), %rsi      # 0xafbe
jmp 0x8d84
leaq 0x227c(%rip), %rsi      # 0xafee
jmp 0x8d84
leaq 0x224c(%rip), %rsi      # 0xafc7
jmp 0x8d84
leaq 0x225d(%rip), %rsi      # 0xafe1
leaq 0x2266(%rip), %rdi      # 0xaff1
xorl %eax, %eax
callq 0x8aa8
movl $0x3, 0x109b4(%rip)     # 0x19750
movzbl 0x26(%rsp), %esi
leal -0x1(%rsi), %eax
cmpb $0x1, %al
ja 0x8dc2
movl %esi, (%rbx)
cmpl $0x8, %ebp
je 0x8db7
cmpl $0x8010, %ebp           # imm = 0x8010
jne 0x8dda
movb $0x1, 0x10996(%rip)     # 0x19754
xorl %eax, %eax
jmp 0x8de4
leaq 0x2242(%rip), %rdi      # 0xb00b
xorl %eax, %eax
callq 0x8aa8
movl $0x3, 0x10976(%rip)     # 0x19750
callq 0x2110
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
addq $0x48, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq