#ifndef COMPILE_H
#include "COMPILE.H"
#endif
#ifdef MEDIA551_F20E_F20J_F31E_F31J
unsigned char G4096_PLAY_BUF[32000];
int16_t G4126_;
#ifdef MEDIA670_F31E_F31J
int16_t G4117_;
int16_t G4116_;
int16_t G8204_;
int16_t G2350_;
#endif


void F0060_SOUND_Play_CPSX(
unsigned char*   P0084_puc_SoundData SEPARATOR
unsigned int16_t P0085_i_Period      SEPARATOR /* Number of sound samples for F31E and F31J */
int16_t          P0086_i_SoundVolume FINAL_SEPARATOR
{
        long L6552_i_Frequency;
        int L6553_;/* Channel number 64..71 */
        int L6554_;
        unsigned int L6555_;
        unsigned int16_t L6558_;
        unsigned int16_t L6559_;
        unsigned char L6557_;


#ifdef MEDIA488_F20E_F20J
        L6558_ = *((unsigned int16_t*)P0084_puc_SoundData); /* First word of sound data contains number of sound samples */
        L6558_ = (L6558_ << 8) | (L6558_ >> 8); /* Convert from big endian to little endian */
#endif
#ifdef MEDIA670_F31E_F31J
        L6558_ = P0085_i_Period;
#endif
        if (L6558_ > 31936) { /* Make sure number of sample is small enough to fit in G4096_PLAY_BUF buffer */
                L6558_ = 31936;
        }
        for (L6559_ = 0; L6559_ < L6558_; L6559_++) {
#ifdef MEDIA488_F20E_F20J
                L6557_ = P0084_puc_SoundData[L6559_ + 2];
#endif
#ifdef MEDIA670_F31E_F31J
                L6557_ = P0084_puc_SoundData[L6559_] + 0x80;
#endif
                if (L6557_ & 0x80) {
                        L6557_ ^= 0x7F;
                }
                G4096_PLAY_BUF[32 + L6559_] = L6557_;
        }
        L6552_i_Frequency = 5500; /* 5500 Hertz */
        memcpy(G4096_PLAY_BUF, "ABCDEFGH", 9); /* Sound Name. Writes 9 bytes but there are only 8 bytes for sound name in buffer. Final '\0' is overwritten by Sound ID */
        *(int*)&G4096_PLAY_BUF[8] = 0x55555555; /* Sound ID */
        *(int*)&G4096_PLAY_BUF[12] = L6558_ ; /* Data length */
        *(int*)&G4096_PLAY_BUF[16] = 0; /* Loop point */
        *(int*)&G4096_PLAY_BUF[20] = 0; /* Loop length */
        *(int*)&G4096_PLAY_BUF[24] = L6552_i_Frequency * 98 / 1000; /* Sampling frequency (2 bytes) */
        *(int*)&G4096_PLAY_BUF[26] = 0 ; /* Correction value of the original sound (2 bytes) */
        *(int*)&G4096_PLAY_BUF[28] = 60 ; /* Musical scale of original sound (1 byte) followed by 3 0x00 bytes of reserved area */
        L6554_ = 64;
        L6555_ = P0086_i_SoundVolume;
        /* G4126_ = (int16_t)(G4126_ + 1) % 8; ANOMALY_FMT with modulo. cx, dx registers used instead of ecx, edx, machine code 2 bytes too large */
        _inline(0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90);
        _inline(0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90);
        L6553_ = G4126_ + 64;
        SND_pcm_mode_set(8);
        while (SND_pcm_status(L6553_));
        SND_pcm_play(L6553_, L6554_, L6555_, G4096_PLAY_BUF);
}

#ifdef MEDIA670_F31E_F31J
void F0709_StartSound(
int16_t P2395_i_SoundIndex  SEPARATOR
int16_t P2396_i_SoundVolume FINAL_SEPARATOR
{
        unsigned char* L2928_puc_;
        unsigned int16_t L6577_;


        if ((P2395_i_SoundIndex < 0) || (G0060_as_Graphic562_Sounds[P2395_i_SoundIndex].GraphicIndex >= 0)) {
                L2928_puc_ = G0060_as_Graphic562_Sounds[P2395_i_SoundIndex].Buffer;
                L6577_ = (*L2928_puc_ << 8) | *(L2928_puc_ + 1);
                F0060_SOUND_Play_CPSX(L2928_puc_ + 2, L6577_, P2396_i_SoundVolume);
        }
}
#endif

void F0710_WaitSoundPlayComplete(
void
)
{
#ifdef MEDIA670_F31E_F31J
        int16_t L6551_;


        for (L6551_ = 0; L6551_< 8; L6551_++) {
                while (SND_pcm_status(L6551_ + 64));
        }
#endif
}

#ifdef MEDIA670_F31E_F31J
void F2258_SetVolume(
int16_t P6107_ FINAL_SEPARATOR
{
        if (P6107_ < 0) {
                P6107_ = 0;
        }
        G4116_ = 0;
        G4117_ = P6107_;
        SND_elevol_set(1, P6107_, P6107_);
        SND_elevol_mute(49);
}

void F0814_TRansition_MIDIMusic(
void
)
{
        G4116_ = 1;
}

void F2264_INIT_PCM_SOUND(
void
)
{
        if (SND_init(G4104_SWORK)) {
                exit(0);
        }
        SND_elevol_mute(49);
        F2258_SetVolume(100);
}
#endif

void F2262_TIMER_A_EVENT(
void
)
{
#ifdef MEDIA670_F31E_F31J
        G8204_--;
#endif
        if (++G0317_i_WaitForInputVerticalBlankCount >= G0318_i_WaitForInputMaximumVerticalBlankCount) {
                G0321_B_StopWaitingForPlayerInput = 1;
        }
#ifdef MEDIA670_F31E_F31J
        if (G4116_) {
                if (G4117_ > 0) {
                        G4117_--;
                        SND_elevol_set(1, G4117_, G4117_);
                } else {
                        SND_elevol_mute(1);
                        G4116_ = 0;
                }
        }
#endif
}

void F2263_INIT_TIMER(
void
)
{
        SND_int_timer_a_set(F2262_TIMER_A_EVENT);
        SND_fm_timer_a_set(1, 100);
}

#ifdef MEDIA488_F20E_F20J
void F2264_INIT_PCM_SOUND(
void
)
{
        if (SND_init(G4104_SWORK)) {
                exit(0);
        }
        SND_elevol_set(1, 100, 100);
        SND_elevol_mute(49);
}
#endif

void F2245_INIT_TOWNS(
void
)
{
        F2264_INIT_PCM_SOUND();
        F2263_INIT_TIMER();
        F2259_INIT_TOWNS_SCREEN();
        F2240_INIT_TOWNS_MOUSE();
#ifdef MEDIA488_F20E_F20J
        F2255_SWOOSH_main();
#endif
        F2256_CD_INIT_CPSX();
}

void F2247_RESTORE_TOWNS(
void
)
{
        F2241_RESTORE_TOWNS_MOUSE();
        F2260_RESTORE_TOWNS_SCREEN();
        SND_end();
        SND_elevol_mute(0);
}

#ifdef MEDIA488_F20E_F20J
#include "JAPANESE.C"

void F2249_CLEAR_FRONT_SCREEN(
void
)
{
        int16_t L6511_[4] = { 0, 319, 0, 199 };


        G4103_WRITE_PAGE = 0;
        F0135_VIDEO_FillBox(NULL, L6511_, C00_COLOR_BLACK, 320);
}
#endif

void F2234_ClearBothScreenBuffers(
void
)
{
#ifdef MEDIA488_F20E_F20J
        int16_t L6510_[4] = { 0, 319, 0, 199 };
#endif
#ifdef MEDIA670_F31E_F31J
        int16_t L6510_[4] = { 0, 0, 320, 200 };
#endif


        G4103_WRITE_PAGE = 1;
        F0135_VIDEO_FillBox(NULL, L6510_, C00_COLOR_BLACK, 320);
        G4103_WRITE_PAGE = 0;
        F0135_VIDEO_FillBox(NULL, L6510_, C00_COLOR_BLACK, 320);
}

#ifdef MEDIA670_F31E_F31J
void F2249_CLEAR_FRONT_SCREEN(
void
)
{
        int16_t L6511_[4] = { 0, 0, 320, 200 };


        G4103_WRITE_PAGE = 0;
        F0135_VIDEO_FillBox(NULL, L6511_, C00_COLOR_BLACK, 320);
}

BOOLEAN F0707_ResetSoundBufferAddress(
int16_t P2391_i_ FINAL_SEPARATOR
{
        if ((P2391_i_ < 0) || (G0060_as_Graphic562_Sounds[P2391_i_].GraphicIndex < 0) || G2350_) {
                return C0_FALSE;
        }
        G0060_as_Graphic562_Sounds[P2391_i_].Buffer = NULL;
        return C1_TRUE;
}

#include "JAPANESE.C"
#endif
#endif
