Subversion Repositories pentevo

Rev

Rev 796 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

  1. #include "std.h"
  2.  
  3. #include <io.h>
  4. #include <fcntl.h>
  5. #include <sys/stat.h>
  6.  
  7. #include "emul.h"
  8. #include "vars.h"
  9. #include "bass.h"
  10. #include "snd_bass.h"
  11. #include "gshle.h"
  12. #include "gs.h"
  13. #include "init.h"
  14. #include "util.h"
  15.  
  16. #ifdef MOD_GSBASS
  17. void GSHLE::reportError(const char *err, bool fatal)
  18. {
  19.    color(CONSCLR_ERROR);
  20.    printf("BASS library reports error in %s\n", err);
  21.    color(CONSCLR_ERRCODE);
  22.    printf("error code is 0x%04X\n", BASS::ErrorGetCode());
  23.    if(fatal)
  24.    {
  25.        exit();
  26.    }
  27. }
  28.  
  29. void GSHLE::runBASS()
  30. {
  31.    if(BASS::Initialized)
  32.        return;
  33.  
  34.    if (BASS::Init(-1, conf.sound.fq, BASS_DEVICE_LATENCY, wnd, nullptr))
  35.    {
  36.       DWORD len = BASS::GetConfig(BASS_CONFIG_UPDATEPERIOD);
  37.       BASS_INFO info;
  38.       BASS::GetInfo(&info);
  39.       BASS::SetConfig(BASS_CONFIG_BUFFER, len + info.minbuf);
  40.       color(CONSCLR_HARDITEM);
  41.       printf("BASS device latency is ");
  42.       color(CONSCLR_HARDINFO);
  43.       printf("%lums\n", len + info.minbuf);
  44.    }
  45.    else
  46.    {
  47.       color(CONSCLR_WARNING);
  48.       reportError("warning: can't use default BASS device, trying silence\n", false);
  49.       if (!BASS::Init(-2, 11025, 0, wnd, nullptr))
  50.           errexit("can't init BASS");
  51.    }
  52.  
  53.    BASS::Initialized = true;
  54.    hmod = 0;
  55.    for (int ch = 0; ch < 4; ch++)
  56.        chan[ch].bass_ch = 0;
  57.  
  58.    DebugCh.bass_ch = 0;
  59. }
  60.  
  61. void GSHLE::reset_sound()
  62. {
  63.   // runBASS();
  64.   // BASS_Stop(); // todo: move to silent state?
  65. }
  66.  
  67.  
  68. DWORD CALLBACK gs_render(HSTREAM handle, void *buffer, DWORD length, void *user);
  69.  
  70. void GSHLE::initChannels()
  71. {
  72.    if (chan[0].bass_ch)
  73.        return;
  74.    for (int ch = 0; ch < 4; ch++)
  75.    {
  76.       chan[ch].bass_ch = BASS::StreamCreate(conf.sound.fq, 1, BASS_SAMPLE_8BITS, gs_render, &chan[ch]);
  77.       if (!chan[ch].bass_ch)
  78.           reportError("BASS_StreamCreate()");
  79.    }
  80.  
  81.    DebugCh.bass_ch = BASS::StreamCreate(conf.sound.fq, 1, BASS_SAMPLE_8BITS, gs_render, &DebugCh);
  82.    if(!DebugCh.bass_ch)
  83.        reportError("BASS_StreamCreate()");
  84. }
  85.  
  86. void GSHLE::setmodvol(unsigned vol)
  87. {
  88.    if (!hmod)
  89.        return;
  90.    runBASS();
  91.    float v = (int(vol) * conf.sound.bass_vol) / float(8192 * 64);
  92.    assert(v <= 1.0f);
  93.    if (!BASS::ChannelSetAttribute(hmod, BASS_ATTRIB_VOL, v))
  94.        reportError("BASS_ChannelSetAttribute() [music volume]");
  95. }
  96.  
  97. void GSHLE::SetModSpeed()
  98. {
  99. // ╘єэъЎш  эх юЄырцхэр, эхшчтхёЄэю т ъръшї яЁюуЁрььрї фрээр  ъюьрэфр шёяюы№чєхЄё 
  100.     if(!hmod)
  101.         return;
  102.     runBASS();
  103.  
  104.     // printf("%s, speed=%u\n", __FUNCTION__, speed);
  105.  
  106.     if(!BASS::ChannelSetAttribute(hmod, BASS_ATTRIB_MUSIC_SPEED, speed))
  107.         reportError("BASS_ChannelSetAttribute() [music speed]");
  108. }
  109.  
  110.  
  111. void GSHLE::init_mod()
  112. {
  113.    runBASS();
  114.    if (hmod)
  115.        BASS::MusicFree(hmod);
  116.    hmod = 0;
  117.    hmod = BASS::MusicLoad(1, mod, 0, modsize, BASS_MUSIC_LOOP | BASS_MUSIC_POSRESET | BASS_MUSIC_RAMP, 0);
  118.    if (!hmod)
  119.        reportError("BASS_MusicLoad()", false);
  120.  
  121.    setmodvol(modvol); // ╙ёЄрэютър эрўры№эющ уЁюьъюёЄш
  122. }
  123.  
  124. void GSHLE::restart_mod(unsigned order, unsigned row)
  125. {
  126.    if (!hmod)
  127.        return;
  128.    SetModSpeed();
  129.    if (!BASS::ChannelSetPosition(hmod, QWORD(MAKELONG(order,row)), BASS_POS_MUSIC_ORDER))
  130.        reportError("BASS_ChannelSetPosition() [music]");
  131.    if (!BASS::ChannelFlags(hmod, BASS_MUSIC_LOOP | BASS_MUSIC_POSRESET | BASS_MUSIC_RAMP, -1U))
  132.        reportError("BASS_ChannelFlags() [music]");
  133.    BASS::Start();
  134.    if (!BASS::ChannelPlay(hmod, FALSE/*TRUE*/))
  135.        reportError("BASS_ChannelPlay() [music]"); //molodcov_alex 0.36.2
  136.  
  137.    mod_playing = 1;
  138. }
  139.  
  140. void GSHLE::resetmod()
  141. {
  142.    if (hmod)
  143.        BASS::MusicFree(hmod);
  144.    hmod = 0;
  145. }
  146.  
  147. void GSHLE::resetfx()
  148. {
  149.    runBASS();
  150.    for (int i = 0; i < 4; i++)
  151.    {
  152.        if (chan[i].bass_ch)
  153.        {
  154.          BASS::StreamFree(chan[i].bass_ch);
  155.          chan[i].bass_ch = 0;
  156.        }
  157.    }
  158. }
  159.  
  160. DWORD GSHLE::modgetpos()
  161. {
  162.    runBASS();
  163.    return (DWORD)BASS::ChannelGetPosition(hmod, BASS_POS_MUSIC_ORDER);
  164. //   return BASS_MusicGetOrderPosition(hmod);
  165. }
  166.  
  167. void GSHLE::stop_mod()
  168. {
  169.    runBASS();
  170.    if (!hmod)
  171.        return;
  172.    if(BASS::ChannelIsActive(hmod) != BASS_ACTIVE_PLAYING)
  173.        return;
  174.    if (!BASS::ChannelPause(hmod))
  175.        reportError("BASS_ChannelPause() [music]");
  176. }
  177.  
  178. void GSHLE::cont_mod()
  179. {
  180.    runBASS();
  181.    if (!hmod)
  182.        return;
  183.    if (!BASS::ChannelPlay(hmod, TRUE))
  184.        reportError("BASS_ChannelPlay() [music]");
  185. }
  186.  
  187. void GSHLE::startfx(CHANNEL *ch, float pan)
  188. {
  189.    initChannels();
  190.  
  191.    float vol = (int(ch->volume) * conf.sound.gs_vol) / float(8192*64);
  192.    assert(vol <= 1.0f);
  193.  
  194.    if(BASS::ChannelIsActive(ch->bass_ch) == BASS_ACTIVE_PLAYING)
  195.    {
  196.        if(!BASS::ChannelStop(ch->bass_ch))
  197.            reportError("BASS_ChannelStop()");
  198.    }
  199.  
  200.    if (!BASS::ChannelSetAttribute(ch->bass_ch, BASS_ATTRIB_VOL, vol))
  201.        reportError("BASS_ChannelSetAttribute() [vol]");
  202.    if (!BASS::ChannelSetAttribute(ch->bass_ch, BASS_ATTRIB_FREQ, ch->freq))
  203.        reportError("BASS_ChannelSetAttribute() [freq]");
  204.    if (!BASS::ChannelSetAttribute(ch->bass_ch, BASS_ATTRIB_PAN, pan))
  205.        reportError("BASS_ChannelSetAttribute() [pan]");
  206.  
  207.    {
  208.        DWORD len = BASS::GetConfig(BASS_CONFIG_UPDATEPERIOD);
  209.        BASS_INFO info;
  210.        BASS::GetInfo(&info);
  211.        BASS::SetConfig(BASS_CONFIG_BUFFER, len + info.minbuf);
  212.    }
  213.    if (!BASS::ChannelPlay(ch->bass_ch, FALSE))
  214.        reportError("BASS_ChannelPlay()");
  215. }
  216.  
  217. void GSHLE::flush_gs_frame()
  218. {
  219.    unsigned lvl;
  220.    if (!hmod || (lvl = BASS::ChannelGetLevel(hmod)) == -1U) lvl = 0;
  221.  
  222.    gsleds[0].level = LOWORD(lvl) >> (15-4);
  223.    gsleds[0].attrib = 0x0D;
  224.    gsleds[1].level = HIWORD(lvl) >> (15-4);
  225.    gsleds[1].attrib = 0x0D;
  226.  
  227.    for (int ch = 0; ch < 4; ch++)
  228.    {
  229.       if (chan[ch].bass_ch && (lvl = BASS::ChannelGetLevel(chan[ch].bass_ch)) != -1U)
  230.       {
  231.          lvl = max(HIWORD(lvl), LOWORD(lvl));
  232.          lvl >>= (15-4);
  233.       }
  234.       else
  235.          lvl = 0;
  236.       gsleds[ch+2].level = lvl;
  237.       gsleds[ch+2].attrib = 0x0F;
  238.    }
  239. }
  240.  
  241. void GSHLE::debug_note(unsigned i)
  242. {
  243.     if(BASS::ChannelIsActive(DebugCh.bass_ch) == BASS_ACTIVE_PLAYING)
  244.     {
  245.         if(!BASS::ChannelStop(DebugCh.bass_ch))
  246.         {
  247.             reportError("BASS_ChannelStop()");
  248.         }
  249.     }
  250.  
  251.     DebugCh.volume = sample[i].volume;
  252.     DebugCh.ptr = 0;
  253.     DebugCh.start = sample[i].start;
  254.     DebugCh.loop = sample[i].loop;
  255.     DebugCh.end = sample[i].end;
  256.     unsigned note = sample[i].note;
  257.     DebugCh.freq = note2rate[note];
  258.  
  259.     startfx(&DebugCh, 0);
  260. }
  261.  
  262. void GSHLE::debug_save_note(unsigned i, const char *FileName)
  263. {
  264.     int f = open(FileName, O_CREAT | O_TRUNC | O_BINARY | O_WRONLY, S_IREAD | S_IWRITE);
  265.     if(f >= 0)
  266.     {
  267.         write(f, sample[i].start, sample[i].end);
  268.         close(f);
  269.     }
  270. }
  271.  
  272. void GSHLE::debug_save_mod(const char *FileName)
  273. {
  274.     int f = open(FileName, O_CREAT | O_TRUNC | O_BINARY | O_WRONLY, S_IREAD | S_IWRITE);
  275.     if(f >= 0)
  276.     {
  277.         write(f, mod, modsize);
  278.         close(f);
  279.     }
  280. }
  281. #endif
  282.