예제 #1
0
파일: RetroTypes.cpp 프로젝트: AxioDL/urde
CAssetId::CAssetId(CInputStream& in) {
  if (g_Main) {
    if (g_Main->GetExpectedIdSize() == sizeof(u32))
      Assign(in.readUint32Big());
    else if (g_Main->GetExpectedIdSize() == sizeof(u64))
      Assign(in.readUint64Big());
    else
      Log.report(logvisor::Fatal, "Unsupported id length %i", g_Main->GetExpectedIdSize());
  } else
    Log.report(logvisor::Fatal, "Input constructor called before runtime Main entered!");
}
예제 #2
0
파일: RetroTypes.cpp 프로젝트: AxioDL/urde
void CAssetId::PutTo(COutputStream& out) {
  if (g_Main) {
    if (g_Main->GetExpectedIdSize() == sizeof(u32))
      out.writeUint32Big(u32(id));
    else if (g_Main->GetExpectedIdSize() == sizeof(u64))
      out.writeUint64Big(id);
    else
      Log.report(logvisor::Fatal, "Unsupported id length %i", g_Main->GetExpectedIdSize());
  } else
    Log.report(logvisor::Fatal, "PutTo called before runtime Main entered!");
}
예제 #3
0
void EmitterElementFactory::read(athena::io::YAMLDocReader& r)
{
    const auto& mapChildren = r.getCurNode()->m_mapChildren;
    if (mapChildren.empty())
    {
        m_elem.reset();
        return;
    }

    const auto& elem = mapChildren[0];
    if (elem.first.size() < 4)
        LogModule.report(logvisor::Fatal, "short FourCC in element '%s'", elem.first.c_str());

    switch (*reinterpret_cast<const uint32_t*>(elem.first.data()))
    {
    case SBIG('SETR'):
        m_elem.reset(new struct EESimpleEmitterTR);
        break;
    case SBIG('SEMR'):
        m_elem.reset(new struct EESimpleEmitter);
        break;
    case SBIG('SPHE'):
        m_elem.reset(new struct VESphere);
        break;
    case SBIG('ASPH'):
        m_elem.reset(new struct VEAngleSphere);
        break;
    default:
        m_elem.reset();
        return;
    }
    r.enterSubRecord(elem.first.c_str());
    m_elem->read(r);
    r.leaveSubRecord();
}
예제 #4
0
void ColorElementFactory::read(athena::io::IStreamReader& r)
{
    uint32_t clsId;
    r.readBytesToBuf(&clsId, 4);
    switch (clsId)
    {
    case SBIG('KEYE'):
    case SBIG('KEYP'):
        m_elem.reset(new struct CEKeyframeEmitter);
        break;
    case SBIG('CNST'):
        m_elem.reset(new struct CEConstant);
        break;
    case SBIG('CHAN'):
        m_elem.reset(new struct CETimeChain);
        break;
    case SBIG('CFDE'):
        m_elem.reset(new struct CEFadeEnd);
        break;
    case SBIG('FADE'):
        m_elem.reset(new struct CEFade);
        break;
    case SBIG('PULS'):
        m_elem.reset(new struct CEPulse);
        break;
    case SBIG('NONE'):
        m_elem.reset();
        return;
    default:
        m_elem.reset();
        LogModule.report(logvisor::Fatal, "Unknown ColorElement class %.4s @%" PRIi64, &clsId, r.position());
        return;
    }
    m_elem->read(r);
}
예제 #5
0
void CGuiWidget::ParseBaseInfo(CGuiFrame* frame, CInputStream& in, const CGuiWidgetParms& parms)
{
    CGuiWidget* parent = frame->FindWidget(parms.x8_parentId);
    bool a = in.readBool();
    if (a)
        xf4_workerId = in.readInt16Big();
    zeus::CVector3f trans;
    trans.readBig(in);
    zeus::CMatrix3f orient;
    orient.readBig(in);
    x80_transform = zeus::CTransform(orient, trans);
    ReapplyXform();
    zeus::CVector3f rotCenter;
    rotCenter.readBig(in);
    SetRotationCenter(rotCenter);
    ParseMessages(in, parms);
    ParseAnimations(in, parms);
    if (a)
        if (!parent->AddWorkerWidget(this))
        {
            Log.report(logvisor::Warning,
            "Warning: Discarding useless worker id. Parent is not a compound widget.");
            xf4_workerId = -1;
        }
    parent->AddChildWidget(this, false, true);
}
예제 #6
0
void EmitterElementFactory::read(athena::io::IStreamReader& r)
{
    uint32_t clsId;
    r.readBytesToBuf(&clsId, 4);
    switch (clsId)
    {
    case SBIG('SETR'):
        m_elem.reset(new struct EESimpleEmitterTR);
        break;
    case SBIG('SEMR'):
        m_elem.reset(new struct EESimpleEmitter);
        break;
    case SBIG('SPHE'):
        m_elem.reset(new struct VESphere);
        break;
    case SBIG('ASPH'):
        m_elem.reset(new struct VEAngleSphere);
        break;
    case SBIG('NONE'):
        m_elem.reset();
        return;
    default:
        m_elem.reset();
        LogModule.report(logvisor::Fatal, "Unknown EmitterElement class %.4s @%" PRIi64, &clsId, r.position());
        return;
    }
    m_elem->read(r);
}
예제 #7
0
void ModVectorElementFactory::read(athena::io::YAMLDocReader& r)
{
    const auto& mapChildren = r.getCurNode()->m_mapChildren;
    if (mapChildren.empty())
    {
        m_elem.reset();
        return;
    }

    const auto& elem = mapChildren[0];
    if (elem.first.size() < 4)
        LogModule.report(logvisor::Fatal, "short FourCC in element '%s'", elem.first.c_str());

    switch (*reinterpret_cast<const uint32_t*>(elem.first.data()))
    {
    case SBIG('IMPL'):
        m_elem.reset(new struct MVEImplosion);
        break;
    case SBIG('EMPL'):
        m_elem.reset(new struct MVEExponentialImplosion);
        break;
    case SBIG('CHAN'):
        m_elem.reset(new struct MVETimeChain);
        break;
    case SBIG('BNCE'):
        m_elem.reset(new struct MVEBounce);
        break;
    case SBIG('CNST'):
        m_elem.reset(new struct MVEConstant);
        break;
    case SBIG('GRAV'):
        m_elem.reset(new struct MVEGravity);
        break;
    case SBIG('EXPL'):
        m_elem.reset(new struct MVEExplode);
        break;
    case SBIG('SPOS'):
        m_elem.reset(new struct MVESetPosition);
        break;
    case SBIG('LMPL'):
        m_elem.reset(new struct MVELinearImplosion);
        break;
    case SBIG('PULS'):
        m_elem.reset(new struct MVEPulse);
        break;
    case SBIG('WIND'):
        m_elem.reset(new struct MVEWind);
        break;
    case SBIG('SWRL'):
        m_elem.reset(new struct MVESwirl);
        break;
    default:
        m_elem.reset();
        return;
    }
    r.enterSubRecord(elem.first.c_str());
    m_elem->read(r);
    r.leaveSubRecord();
}
예제 #8
0
Locale::Locale(const std::string& name, const std::string& fullName,
               const unsigned char* yamlSource, size_t yamlLength)
: m_name(name), m_fullName(fullName)
{
    athena::io::YAMLDocReader reader;
    yaml_parser_set_input_string(reader.getParser(), yamlSource, yamlLength);
    reader.parse();
    m_rootNode = std::move(reader.releaseRootNode());
    if (m_rootNode)
    {
        m_langNode = m_rootNode->findMapChild(name.c_str());
        if (!m_langNode)
            Log.report(logvisor::Fatal, "no root node '%s' found in locale", name.c_str());
    }
    else
        Log.report(logvisor::Warning, "locale empty");
}
예제 #9
0
void ViewResources::init(boo::IGraphicsDataFactory* factory, FontCache* fcache,
                         const IThemeData* theme, float pf)
{
    if (!factory || !fcache || !theme)
        Log.report(logvisor::Fatal, "all arguments of ViewResources::init() must be non-null");
    m_pixelFactor = pf;
    m_factory = factory;
    m_theme = theme;
    m_fcache = fcache;
    unsigned dpi = 72.f * m_pixelFactor;

    m_curveFont = fcache->prepCurvesFont(factory, AllCharFilter, false, 8.f, dpi);

    m_resData = factory->commitTransaction(
    [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
    {
        switch (ctx.platform())
        {
        case boo::IGraphicsDataFactory::Platform::OGL:
            init<boo::GLDataFactory::Context>(static_cast<boo::GLDataFactory::Context&>(ctx), *theme, fcache);
            break;
#if _WIN32
        case boo::IGraphicsDataFactory::Platform::D3D11:
        case boo::IGraphicsDataFactory::Platform::D3D12:
            init<boo::ID3DDataFactory::Context>(static_cast<boo::ID3DDataFactory::Context&>(ctx), *theme, fcache);
            break;
#endif
#if BOO_HAS_METAL
        case boo::IGraphicsDataFactory::Platform::Metal:
            init<boo::MetalDataFactory::Context>(static_cast<boo::MetalDataFactory::Context&>(ctx), *theme, fcache);
            break;
#endif
#if BOO_HAS_VULKAN
        case boo::IGraphicsDataFactory::Platform::Vulkan:
            init<boo::VulkanDataFactory::Context>(static_cast<boo::VulkanDataFactory::Context&>(ctx), *theme, fcache);
            break;
#endif
        default:
            Log.report(logvisor::Fatal, _S("unable to init view system for %s"), ctx.platformName());
        }
        return true;
    });
}
예제 #10
0
파일: main.cpp 프로젝트: KalDragon/urde
    void initialize(boo::IApplication* app)
    {
        zeus::detectCPU();

        const zeus::CPUInfo& cpuInf = zeus::cpuFeatures();
        Log.report(logvisor::Info, "CPU Name: %s", cpuInf.cpuBrand);
        Log.report(logvisor::Info, "CPU Vendor: %s", cpuInf.cpuVendor);
        hecl::SystemString features;
        if (cpuInf.AESNI)
            features += _S("AES-NI");
        if (cpuInf.SSE1)
        {
            if (!features.empty())
                features += _S(", SSE1");
            else
                features += _S("SSE1");
        }
        else
        {
            Log.report(logvisor::Fatal, _S("URDE requires SSE1 minimum"));
            return;
        }
        if (cpuInf.SSE2)
            features += _S(", SSE2");
        else
        {
            Log.report(logvisor::Fatal, _S("URDE requires SSE2 minimum"));
            return;
        }
        if (cpuInf.SSE3)
            features += _S(", SSE3");
        if (cpuInf.SSSE3)
            features += _S(", SSSE3");
        if (cpuInf.SSE4a)
            features += _S(", SSE4a");
        if (cpuInf.SSE41)
            features += _S(", SSE4.1");
        if (cpuInf.SSE42)
            features += _S(", SSE4.2");
        Log.report(logvisor::Info, _S("CPU Features: %s"), features.c_str());
    }
예제 #11
0
파일: icons.cpp 프로젝트: KalDragon/urde
boo::GraphicsDataToken InitializeIcons(specter::ViewResources& viewRes)
{
    athena::io::MemoryReader r(URDE_ICONS, URDE_ICONS_SZ);
    size_t fmt = r.readUint32Big();
    if (fmt != 16)
        Log.report(logvisor::Fatal, "incorrect icon texture format");
    size_t width = r.readUint16Big();
    size_t height = r.readUint16Big();
    size_t mips = r.readUint32Big();
    size_t decompSz = r.readUint32Big();

    std::unique_ptr<uint8_t[]> texels(new uint8_t[decompSz]);
    uLongf destSz = decompSz;
    size_t pos = r.position();
    if (uncompress(texels.get(), &destSz, URDE_ICONS + pos, URDE_ICONS_SZ - pos) != Z_OK)
        Log.report(logvisor::Fatal, "unable to decompress icons");

    g_IconAtlas.initializeAtlas(viewRes.m_factory->newStaticTexture(width, height, mips, boo::TextureFormat::RGBA8,
                                                                    texels.get(), destSz));
    return viewRes.m_factory->commit();
}
예제 #12
0
void ModVectorElementFactory::read(athena::io::IStreamReader& r)
{
    uint32_t clsId;
    r.readBytesToBuf(&clsId, 4);
    switch (clsId)
    {
    case SBIG('IMPL'):
        m_elem.reset(new struct MVEImplosion);
        break;
    case SBIG('EMPL'):
        m_elem.reset(new struct MVEExponentialImplosion);
        break;
    case SBIG('CHAN'):
        m_elem.reset(new struct MVETimeChain);
        break;
    case SBIG('BNCE'):
        m_elem.reset(new struct MVEBounce);
        break;
    case SBIG('CNST'):
        m_elem.reset(new struct MVEConstant);
        break;
    case SBIG('GRAV'):
        m_elem.reset(new struct MVEGravity);
        break;
    case SBIG('EXPL'):
        m_elem.reset(new struct MVEExplode);
        break;
    case SBIG('SPOS'):
        m_elem.reset(new struct MVESetPosition);
        break;
    case SBIG('LMPL'):
        m_elem.reset(new struct MVELinearImplosion);
        break;
    case SBIG('PULS'):
        m_elem.reset(new struct MVEPulse);
        break;
    case SBIG('WIND'):
        m_elem.reset(new struct MVEWind);
        break;
    case SBIG('SWRL'):
        m_elem.reset(new struct MVESwirl);
        break;
    case SBIG('NONE'):
        m_elem.reset();
        return;
    default:
        m_elem.reset();
        LogModule.report(logvisor::Fatal, "Unknown ModVectorElement class %.4s @%" PRIi64, &clsId, r.position());
        return;
    }
    m_elem->read(r);
}
예제 #13
0
void ColorElementFactory::read(athena::io::YAMLDocReader& r)
{
    const auto& mapChildren = r.getCurNode()->m_mapChildren;
    if (mapChildren.empty())
    {
        m_elem.reset();
        return;
    }

    const auto& elem = mapChildren[0];
    if (elem.first.size() < 4)
        LogModule.report(logvisor::Fatal, "short FourCC in element '%s'", elem.first.c_str());

    switch (*reinterpret_cast<const uint32_t*>(elem.first.data()))
    {
    case SBIG('KEYE'):
    case SBIG('KEYP'):
        m_elem.reset(new struct CEKeyframeEmitter);
        break;
    case SBIG('CNST'):
        m_elem.reset(new struct CEConstant);
        break;
    case SBIG('CHAN'):
        m_elem.reset(new struct CETimeChain);
        break;
    case SBIG('CFDE'):
        m_elem.reset(new struct CEFadeEnd);
        break;
    case SBIG('FADE'):
        m_elem.reset(new struct CEFade);
        break;
    case SBIG('PULS'):
        m_elem.reset(new struct CEPulse);
        break;
    default:
        m_elem.reset();
        return;
    }
    r.enterSubRecord(elem.first.c_str());
    m_elem->read(r);
    r.leaveSubRecord();
}
예제 #14
0
void RealElementFactory::read(athena::io::IStreamReader& r)
{
    uint32_t clsId;
    r.readBytesToBuf(&clsId, 4);
    switch (clsId)
    {
    case SBIG('LFTW'):
        m_elem.reset(new struct RELifetimeTween);
        break;
    case SBIG('CNST'):
        m_elem.reset(new struct REConstant);
        break;
    case SBIG('CHAN'):
        m_elem.reset(new struct RETimeChain);
        break;
    case SBIG('ADD_'):
        m_elem.reset(new struct REAdd);
        break;
    case SBIG('CLMP'):
        m_elem.reset(new struct REClamp);
        break;
    case SBIG('KEYE'):
    case SBIG('KEYP'):
        m_elem.reset(new struct REKeyframeEmitter);
        break;
    case SBIG('IRND'):
        m_elem.reset(new struct REInitialRandom);
        break;
    case SBIG('RAND'):
        m_elem.reset(new struct RERandom);
        break;
    case SBIG('MULT'):
        m_elem.reset(new struct REMultiply);
        break;
    case SBIG('PULS'):
        m_elem.reset(new struct REPulse);
        break;
    case SBIG('SCAL'):
        m_elem.reset(new struct RETimeScale);
        break;
    case SBIG('RLPT'):
        m_elem.reset(new struct RELifetimePercent);
        break;
    case SBIG('SINE'):
        m_elem.reset(new struct RESineWave);
        break;
    case SBIG('ISWT'):
        m_elem.reset(new struct REInitialSwitch);
        break;
    case SBIG('CLTN'):
        m_elem.reset(new struct RECompareLessThan);
        break;
    case SBIG('CEQL'):
        m_elem.reset(new struct RECompareEquals);
        break;
    case SBIG('PAP1'):
        m_elem.reset(new struct REParticleAdvanceParam1);
        break;
    case SBIG('PAP2'):
        m_elem.reset(new struct REParticleAdvanceParam2);
        break;
    case SBIG('PAP3'):
        m_elem.reset(new struct REParticleAdvanceParam3);
        break;
    case SBIG('PAP4'):
        m_elem.reset(new struct REParticleAdvanceParam4);
        break;
    case SBIG('PAP5'):
        m_elem.reset(new struct REParticleAdvanceParam5);
        break;
    case SBIG('PAP6'):
        m_elem.reset(new struct REParticleAdvanceParam6);
        break;
    case SBIG('PAP7'):
        m_elem.reset(new struct REParticleAdvanceParam7);
        break;
    case SBIG('PAP8'):
        m_elem.reset(new struct REParticleAdvanceParam8);
        break;
    case SBIG('PSLL'):
        m_elem.reset(new struct REParticleSizeOrLineLength);
        break;
    case SBIG('PRLW'):
        m_elem.reset(new struct REParticleRotationOrLineWidth);
        break;
    case SBIG('SUB_'):
        m_elem.reset(new struct RESubtract);
        break;
    case SBIG('VMAG'):
        m_elem.reset(new struct REVectorMagnitude);
        break;
    case SBIG('VXTR'):
        m_elem.reset(new struct REVectorXToReal);
        break;
    case SBIG('VYTR'):
        m_elem.reset(new struct REVectorYToReal);
        break;
    case SBIG('VZTR'):
        m_elem.reset(new struct REVectorZToReal);
        break;
    case SBIG('CEXT'):
        m_elem.reset(new struct RECEXT);
        break;
    case SBIG('ITRL'):
        m_elem.reset(new struct REIntTimesReal);
        break;
    case SBIG('NONE'):
        m_elem.reset();
        return;
    default:
        m_elem.reset();
        LogModule.report(logvisor::Fatal, "Unknown RealElement class %.4s @%" PRIi64, &clsId, r.position());
        return;
    }
    m_elem->read(r);
}
예제 #15
0
void RealElementFactory::read(athena::io::YAMLDocReader& r)
{
    const auto& mapChildren = r.getCurNode()->m_mapChildren;
    if (mapChildren.empty())
    {
        m_elem.reset();
        return;
    }

    const auto& elem = mapChildren[0];
    if (elem.first.size() < 4)
        LogModule.report(logvisor::Fatal, "short FourCC in element '%s'", elem.first.c_str());

    switch (*reinterpret_cast<const uint32_t*>(elem.first.data()))
    {
    case SBIG('LFTW'):
        m_elem.reset(new struct RELifetimeTween);
        break;
    case SBIG('CNST'):
        m_elem.reset(new struct REConstant);
        break;
    case SBIG('CHAN'):
        m_elem.reset(new struct RETimeChain);
        break;
    case SBIG('ADD_'):
        m_elem.reset(new struct REAdd);
        break;
    case SBIG('CLMP'):
        m_elem.reset(new struct REClamp);
        break;
    case SBIG('KEYE'):
    case SBIG('KEYP'):
        m_elem.reset(new struct REKeyframeEmitter);
        break;
    case SBIG('IRND'):
        m_elem.reset(new struct REInitialRandom);
        break;
    case SBIG('RAND'):
        m_elem.reset(new struct RERandom);
        break;
    case SBIG('MULT'):
        m_elem.reset(new struct REMultiply);
        break;
    case SBIG('PULS'):
        m_elem.reset(new struct REPulse);
        break;
    case SBIG('SCAL'):
        m_elem.reset(new struct RETimeScale);
        break;
    case SBIG('RLPT'):
        m_elem.reset(new struct RELifetimePercent);
        break;
    case SBIG('SINE'):
        m_elem.reset(new struct RESineWave);
        break;
    case SBIG('ISWT'):
        m_elem.reset(new struct REInitialSwitch);
        break;
    case SBIG('CLTN'):
        m_elem.reset(new struct RECompareLessThan);
        break;
    case SBIG('CEQL'):
        m_elem.reset(new struct RECompareEquals);
        break;
    case SBIG('PAP1'):
        m_elem.reset(new struct REParticleAdvanceParam1);
        break;
    case SBIG('PAP2'):
        m_elem.reset(new struct REParticleAdvanceParam2);
        break;
    case SBIG('PAP3'):
        m_elem.reset(new struct REParticleAdvanceParam3);
        break;
    case SBIG('PAP4'):
        m_elem.reset(new struct REParticleAdvanceParam4);
        break;
    case SBIG('PAP5'):
        m_elem.reset(new struct REParticleAdvanceParam5);
        break;
    case SBIG('PAP6'):
        m_elem.reset(new struct REParticleAdvanceParam6);
        break;
    case SBIG('PAP7'):
        m_elem.reset(new struct REParticleAdvanceParam7);
        break;
    case SBIG('PAP8'):
        m_elem.reset(new struct REParticleAdvanceParam8);
        break;
    case SBIG('PSLL'):
        m_elem.reset(new struct REParticleSizeOrLineLength);
        break;
    case SBIG('PRLW'):
        m_elem.reset(new struct REParticleRotationOrLineWidth);
        break;
    case SBIG('SUB_'):
        m_elem.reset(new struct RESubtract);
        break;
    case SBIG('VMAG'):
        m_elem.reset(new struct REVectorMagnitude);
        break;
    case SBIG('VXTR'):
        m_elem.reset(new struct REVectorXToReal);
        break;
    case SBIG('VYTR'):
        m_elem.reset(new struct REVectorYToReal);
        break;
    case SBIG('VZTR'):
        m_elem.reset(new struct REVectorZToReal);
        break;
    case SBIG('CEXT'):
        m_elem.reset(new struct RECEXT);
        break;
    case SBIG('ITRL'):
        m_elem.reset(new struct REIntTimesReal);
        break;
    default:
        m_elem.reset();
        return;
    }
    r.enterSubRecord(elem.first.c_str());
    m_elem->read(r);
    r.leaveSubRecord();
}
예제 #16
0
파일: GLX.cpp 프로젝트: AxioDL/boo
void GLXExtensionCheck() {
  if (!GLXEW_SGI_video_sync)
    Log.report(logvisor::Fatal, "GLX_SGI_video_sync not available");
  if (!GLXEW_EXT_swap_control && !GLXEW_MESA_swap_control && !GLXEW_SGI_swap_control)
    Log.report(logvisor::Fatal, "swap_control not available");
}
예제 #17
0
int main(int argc, const boo::SystemChar** argv)
#endif
{
  logvisor::RegisterConsoleLogger();

  std::vector<boo::SystemString> m_args;
  m_args.reserve(argc);
  double rate = NativeSampleRate;
  int chCount = 2;
  double volume = 1.0;
  for (int i = 1; i < argc; ++i) {
#if _WIN32
    if (!wcsncmp(argv[i], L"-r", 2)) {
      if (argv[i][2])
        rate = wcstod(&argv[i][2], nullptr);
      else if (argc > (i + 1)) {
        rate = wcstod(argv[i + 1], nullptr);
        ++i;
      }
    } else if (!wcsncmp(argv[i], L"-c", 2)) {
      if (argv[i][2])
        chCount = wcstoul(&argv[i][2], nullptr, 0);
      else if (argc > (i + 1)) {
        chCount = wcstoul(argv[i + 1], nullptr, 0);
        ++i;
      }
    } else if (!wcsncmp(argv[i], L"-v", 2)) {
      if (argv[i][2])
        volume = wcstod(&argv[i][2], nullptr);
      else if (argc > (i + 1)) {
        volume = wcstod(argv[i + 1], nullptr);
        ++i;
      }
    } else
      m_args.push_back(argv[i]);
#else
    if (!strncmp(argv[i], "-r", 2)) {
      if (argv[i][2])
        rate = strtod(&argv[i][2], nullptr);
      else if (argc > (i + 1)) {
        rate = strtod(argv[i + 1], nullptr);
        ++i;
      }
    } else if (!strncmp(argv[i], "-c", 2)) {
      if (argv[i][2])
        chCount = strtoul(&argv[i][2], nullptr, 0);
      else if (argc > (i + 1)) {
        chCount = strtoul(argv[i + 1], nullptr, 0);
        ++i;
      }
    } else if (!strncmp(argv[i], "-v", 2)) {
      if (argv[i][2])
        volume = strtod(&argv[i][2], nullptr);
      else if (argc > (i + 1)) {
        volume = strtod(argv[i + 1], nullptr);
        ++i;
      }
    } else
      m_args.push_back(argv[i]);
#endif
  }

  /* Load data */
  if (m_args.size() < 1) {
    Log.report(logvisor::Error,
               "Usage: amuserender <group-file> [<songs-file>] [-r <sample-rate>] [-c <channel-count>] [-v <volume "
               "0.0-1.0>]");
    return 1;
  }

  amuse::ContainerRegistry::Type cType = amuse::ContainerRegistry::DetectContainerType(m_args[0].c_str());
  if (cType == amuse::ContainerRegistry::Type::Invalid) {
    Log.report(logvisor::Error, "invalid/no data at path argument");
    return 1;
  }
  Log.report(logvisor::Info, _SYS_STR("Found '%s' Audio Group data"), amuse::ContainerRegistry::TypeToName(cType));

  std::vector<std::pair<amuse::SystemString, amuse::IntrusiveAudioGroupData>> data =
      amuse::ContainerRegistry::LoadContainer(m_args[0].c_str());
  if (data.empty()) {
    Log.report(logvisor::Error, "invalid/no data at path argument");
    return 1;
  }

  int m_groupId = -1;
  int m_setupId = -1;
  const amuse::SystemString* m_groupName = nullptr;
  const amuse::SystemString* m_songName = nullptr;
  amuse::ContainerRegistry::SongData* m_arrData = nullptr;
  bool m_sfxGroup = false;

  std::list<amuse::AudioGroupProject> m_projs;
  std::map<int, std::pair<std::pair<amuse::SystemString, amuse::IntrusiveAudioGroupData>*,
                          amuse::ObjToken<amuse::SongGroupIndex>>>
      allSongGroups;
  std::map<int, std::pair<std::pair<amuse::SystemString, amuse::IntrusiveAudioGroupData>*,
                          amuse::ObjToken<amuse::SFXGroupIndex>>>
      allSFXGroups;
  size_t totalGroups = 0;

  for (auto& grp : data) {
    /* Load project to assemble group list */
    m_projs.push_back(amuse::AudioGroupProject::CreateAudioGroupProject(grp.second));
    amuse::AudioGroupProject& proj = m_projs.back();
    totalGroups += proj.sfxGroups().size() + proj.songGroups().size();

    for (auto it = proj.songGroups().begin(); it != proj.songGroups().end(); ++it)
      allSongGroups[it->first] = std::make_pair(&grp, it->second);

    for (auto it = proj.sfxGroups().begin(); it != proj.sfxGroups().end(); ++it)
      allSFXGroups[it->first] = std::make_pair(&grp, it->second);
  }

  /* Attempt loading song */
  std::vector<std::pair<amuse::SystemString, amuse::ContainerRegistry::SongData>> songs;
  if (m_args.size() > 1)
    songs = amuse::ContainerRegistry::LoadSongs(m_args[1].c_str());
  else
    songs = amuse::ContainerRegistry::LoadSongs(m_args[0].c_str());

  if (songs.size()) {
    bool play = true;
    if (m_args.size() <= 1) {
      bool prompt = true;
      while (true) {
        if (prompt) {
          printf("Render Song? (Y/N): ");
          prompt = false;
        }
        char userSel;
        if (scanf("%c", &userSel) <= 0 || userSel == '\n')
          continue;
        userSel = tolower(userSel);
        if (userSel == 'n')
          play = false;
        else if (userSel != 'y') {
          prompt = true;
          continue;
        }
        break;
      }
    }

    if (play) {
      /* Get song selection from user */
      if (songs.size() > 1) {
        /* Ask user to specify which song */
        printf("Multiple Songs discovered:\n");
        int idx = 0;
        for (const auto& pair : songs) {
          const amuse::ContainerRegistry::SongData& sngData = pair.second;
          int16_t grpId = sngData.m_groupId;
          int16_t setupId = sngData.m_setupId;
          if (sngData.m_groupId == -1 && sngData.m_setupId != -1) {
            for (const auto& pair : allSongGroups) {
              for (const auto& setup : pair.second.second->m_midiSetups) {
                if (setup.first == sngData.m_setupId) {
                  grpId = pair.first;
                  break;
                }
              }
              if (grpId != -1)
                break;
            }
          }
          amuse::Printf(_SYS_STR("    %d %s (Group %d, Setup %d)\n"), idx++, pair.first.c_str(), grpId, setupId);
        }

        int userSel = 0;
        printf("Enter Song Number: ");
        if (scanf("%d", &userSel) <= 0) {
          Log.report(logvisor::Error, "unable to parse prompt");
          return 1;
        }

        if (userSel < songs.size()) {
          m_arrData = &songs[userSel].second;
          m_groupId = m_arrData->m_groupId;
          m_setupId = m_arrData->m_setupId;
          m_songName = &songs[userSel].first;
        } else {
          Log.report(logvisor::Error, "unable to find Song %d", userSel);
          return 1;
        }
      } else if (songs.size() == 1) {
        m_arrData = &songs[0].second;
        m_groupId = m_arrData->m_groupId;
        m_setupId = m_arrData->m_setupId;
        m_songName = &songs[0].first;
      }
    }
  }

  /* Get group selection via setup search */
  if (m_groupId == -1 && m_setupId != -1) {
    for (const auto& pair : allSongGroups) {
      for (const auto& setup : pair.second.second->m_midiSetups) {
        if (setup.first == m_setupId) {
          m_groupId = pair.first;
          m_groupName = &pair.second.first->first;
          break;
        }
      }
      if (m_groupId != -1)
        break;
    }
  }

  /* Get group selection via user */
  if (m_groupId != -1) {
    auto songSearch = allSongGroups.find(m_groupId);
    auto sfxSearch = allSFXGroups.find(m_groupId);
    if (songSearch != allSongGroups.end()) {
      m_sfxGroup = false;
      m_groupName = &songSearch->second.first->first;
    } else if (sfxSearch != allSFXGroups.end()) {
      m_sfxGroup = true;
      m_groupName = &sfxSearch->second.first->first;
    } else {
      Log.report(logvisor::Error, "unable to find Group %d", m_groupId);
      return 1;
    }
  } else if (totalGroups > 1) {
    /* Ask user to specify which group in project */
    printf("Multiple Audio Groups discovered:\n");
    for (const auto& pair : allSFXGroups) {
      amuse::Printf(_SYS_STR("    %d %s (SFXGroup)  %" PRISize " sfx-entries\n"), pair.first,
                    pair.second.first->first.c_str(), pair.second.second->m_sfxEntries.size());
    }
    for (const auto& pair : allSongGroups) {
      amuse::Printf(_SYS_STR("    %d %s (SongGroup)  %" PRISize " normal-pages, %" PRISize " drum-pages, %" PRISize
                             " MIDI-setups\n"),
                    pair.first, pair.second.first->first.c_str(), pair.second.second->m_normPages.size(),
                    pair.second.second->m_drumPages.size(), pair.second.second->m_midiSetups.size());
    }

    int userSel = 0;
    printf("Enter Group Number: ");
    if (scanf("%d", &userSel) <= 0) {
      Log.report(logvisor::Error, "unable to parse prompt");
      return 1;
    }

    auto songSearch = allSongGroups.find(userSel);
    auto sfxSearch = allSFXGroups.find(userSel);
    if (songSearch != allSongGroups.end()) {
      m_groupId = userSel;
      m_groupName = &songSearch->second.first->first;
      m_sfxGroup = false;
    } else if (sfxSearch != allSFXGroups.end()) {
      m_groupId = userSel;
      m_groupName = &sfxSearch->second.first->first;
      m_sfxGroup = true;
    } else {
      Log.report(logvisor::Error, "unable to find Group %d", userSel);
      return 1;
    }
  } else if (totalGroups == 1) {
    /* Load one and only group */
    if (allSongGroups.size()) {
      const auto& pair = *allSongGroups.cbegin();
      m_groupId = pair.first;
      m_groupName = &pair.second.first->first;
      m_sfxGroup = false;
    } else {
      const auto& pair = *allSFXGroups.cbegin();
      m_groupId = pair.first;
      m_groupName = &pair.second.first->first;
      m_sfxGroup = true;
    }
  } else {
    Log.report(logvisor::Error, "empty project");
    return 1;
  }

  /* Make final group selection */
  amuse::IntrusiveAudioGroupData* selData = nullptr;
  amuse::ObjToken<amuse::SongGroupIndex> songIndex;
  amuse::ObjToken<amuse::SFXGroupIndex> sfxIndex;
  auto songSearch = allSongGroups.find(m_groupId);
  if (songSearch != allSongGroups.end()) {
    selData = &songSearch->second.first->second;
    songIndex = songSearch->second.second;
    std::set<int> sortSetups;
    for (auto& pair : songIndex->m_midiSetups)
      sortSetups.insert(pair.first);
    if (m_setupId == -1) {
      /* Ask user to specify which group in project */
      printf("Multiple MIDI Setups:\n");
      for (int setup : sortSetups)
        printf("    %d\n", setup);
      int userSel = 0;
      printf("Enter Setup Number: ");
      if (scanf("%d", &userSel) <= 0) {
        Log.report(logvisor::Error, "unable to parse prompt");
        return 1;
      }
      m_setupId = userSel;
    }
    if (sortSetups.find(m_setupId) == sortSetups.cend()) {
      Log.report(logvisor::Error, "unable to find setup %d", m_setupId);
      return 1;
    }
  } else {
    auto sfxSearch = allSFXGroups.find(m_groupId);
    if (sfxSearch != allSFXGroups.end()) {
      selData = &sfxSearch->second.first->second;
      sfxIndex = sfxSearch->second.second;
    }
  }

  if (!selData) {
    Log.report(logvisor::Error, "unable to select audio group data");
    return 1;
  }

  if (m_sfxGroup) {
    Log.report(logvisor::Error, "amuserender is currently only able to render SongGroups");
    return 1;
  }

  /* WAV out path */
  amuse::SystemChar pathOut[1024];
  SNPrintf(pathOut, 1024, _SYS_STR("%s-%s.wav"), m_groupName->c_str(), m_songName->c_str());
  Log.report(logvisor::Info, _SYS_STR("Writing to %s"), pathOut);

  /* Build voice engine */
  std::unique_ptr<boo::IAudioVoiceEngine> voxEngine = boo::NewWAVAudioVoiceEngine(pathOut, rate, chCount);
  amuse::BooBackendVoiceAllocator booBackend(*voxEngine);
  amuse::Engine engine(booBackend, amuse::AmplitudeMode::PerSample);
  engine.setVolume(float(amuse::clamp(0.0, volume, 1.0)));

  /* Load group into engine */
  const amuse::AudioGroup* group = engine.addAudioGroup(*selData);
  if (!group) {
    Log.report(logvisor::Error, "unable to add audio group");
    return 1;
  }

  /* Enter playback loop */
  amuse::ObjToken<amuse::Sequencer> seq = engine.seqPlay(m_groupId, m_setupId, m_arrData->m_data.get(), false);
  size_t wroteFrames = 0;
  signal(SIGINT, SIGINTHandler);
  do {
    voxEngine->pumpAndMixVoices();
    wroteFrames += voxEngine->get5MsFrames();
    printf("\rFrame %" PRISize, wroteFrames);
    fflush(stdout);
  } while (!g_BreakLoop && (seq->state() == amuse::SequencerState::Playing || seq->getVoiceCount() != 0));

  printf("\n");
  return 0;
}
예제 #18
0
void VectorElementFactory::read(athena::io::IStreamReader& r)
{
    uint32_t clsId;
    r.readBytesToBuf(&clsId, 4);
    switch (clsId)
    {
    case SBIG('CONE'):
        m_elem.reset(new struct VECone);
        break;
    case SBIG('CHAN'):
        m_elem.reset(new struct VETimeChain);
        break;
    case SBIG('ANGC'):
        m_elem.reset(new struct VEAngleCone);
        break;
    case SBIG('ADD_'):
        m_elem.reset(new struct VEAdd);
        break;
    case SBIG('CCLU'):
        m_elem.reset(new struct VECircleCluster);
        break;
    case SBIG('CNST'):
        m_elem.reset(new struct VEConstant);
        break;
    case SBIG('CIRC'):
        m_elem.reset(new struct VECircle);
        break;
    case SBIG('KEYE'):
    case SBIG('KEYP'):
        m_elem.reset(new struct VEKeyframeEmitter);
        break;
    case SBIG('MULT'):
        m_elem.reset(new struct VEMultiply);
        break;
    case SBIG('RTOV'):
        m_elem.reset(new struct VERealToVector);
        break;
    case SBIG('PULS'):
        m_elem.reset(new struct VEPulse);
        break;
    case SBIG('PVEL'):
        m_elem.reset(new struct VEParticleVelocity);
        break;
    case SBIG('SPOS'):
        m_elem.reset(new struct VESPOS);
        break;
    case SBIG('PLCO'):
        m_elem.reset(new struct VEPLCO);
        break;
    case SBIG('PLOC'):
        m_elem.reset(new struct VEPLOC);
        break;
    case SBIG('PSOR'):
        m_elem.reset(new struct VEPSOR);
        break;
    case SBIG('PSOF'):
        m_elem.reset(new struct VEPSOF);
        break;
    case SBIG('NONE'):
        m_elem.reset();
        return;
    default:
        m_elem.reset();
        LogModule.report(logvisor::Fatal, "Unknown VectorElement class %.4s @%" PRIi64, &clsId, r.position());
        return;
    }
    m_elem->read(r);
}
예제 #19
0
void VectorElementFactory::read(athena::io::YAMLDocReader& r)
{
    const auto& mapChildren = r.getCurNode()->m_mapChildren;
    if (mapChildren.empty())
    {
        m_elem.reset();
        return;
    }

    const auto& elem = mapChildren[0];
    if (elem.first.size() < 4)
        LogModule.report(logvisor::Fatal, "short FourCC in element '%s'", elem.first.c_str());

    switch (*reinterpret_cast<const uint32_t*>(elem.first.data()))
    {
    case SBIG('CONE'):
        m_elem.reset(new struct VECone);
        break;
    case SBIG('CHAN'):
        m_elem.reset(new struct VETimeChain);
        break;
    case SBIG('ANGC'):
        m_elem.reset(new struct VEAngleCone);
        break;
    case SBIG('ADD_'):
        m_elem.reset(new struct VEAdd);
        break;
    case SBIG('CCLU'):
        m_elem.reset(new struct VECircleCluster);
        break;
    case SBIG('CNST'):
        m_elem.reset(new struct VEConstant);
        break;
    case SBIG('CIRC'):
        m_elem.reset(new struct VECircle);
        break;
    case SBIG('KEYE'):
    case SBIG('KEYP'):
        m_elem.reset(new struct VEKeyframeEmitter);
        break;
    case SBIG('MULT'):
        m_elem.reset(new struct VEMultiply);
        break;
    case SBIG('RTOV'):
        m_elem.reset(new struct VERealToVector);
        break;
    case SBIG('PULS'):
        m_elem.reset(new struct VEPulse);
        break;
    case SBIG('PVEL'):
        m_elem.reset(new struct VEParticleVelocity);
        break;
    case SBIG('SPOS'):
        m_elem.reset(new struct VESPOS);
        break;
    case SBIG('PLCO'):
        m_elem.reset(new struct VEPLCO);
        break;
    case SBIG('PLOC'):
        m_elem.reset(new struct VEPLOC);
        break;
    case SBIG('PSOR'):
        m_elem.reset(new struct VEPSOR);
        break;
    case SBIG('PSOF'):
        m_elem.reset(new struct VEPSOF);
        break;
    default:
        m_elem.reset();
        return;
    }
    r.enterSubRecord(elem.first.c_str());
    m_elem->read(r);
    r.leaveSubRecord();
}
예제 #20
0
void IntElementFactory::read(athena::io::IStreamReader& r)
{
    uint32_t clsId;
    r.readBytesToBuf(&clsId, 4);
    switch (clsId)
    {
    case SBIG('KEYE'):
    case SBIG('KEYP'):
        m_elem.reset(new struct IEKeyframeEmitter);
        break;
    case SBIG('DETH'):
        m_elem.reset(new struct IEDeath);
        break;
    case SBIG('CLMP'):
        m_elem.reset(new struct IEClamp);
        break;
    case SBIG('CHAN'):
        m_elem.reset(new struct IETimeChain);
        break;
    case SBIG('ADD_'):
        m_elem.reset(new struct IEAdd);
        break;
    case SBIG('CNST'):
        m_elem.reset(new struct IEConstant);
        break;
    case SBIG('IMPL'):
        m_elem.reset(new struct IEImpulse);
        break;
    case SBIG('ILPT'):
        m_elem.reset(new struct IELifetimePercent);
        break;
    case SBIG('IRND'):
        m_elem.reset(new struct IEInitialRandom);
        break;
    case SBIG('PULS'):
        m_elem.reset(new struct IEPulse);
        break;
    case SBIG('MULT'):
        m_elem.reset(new struct IEMultiply);
        break;
    case SBIG('SPAH'):
        m_elem.reset(new struct IESampleAndHold);
        break;
    case SBIG('RAND'):
        m_elem.reset(new struct IERandom);
        break;
    case SBIG('TSCL'):
        m_elem.reset(new struct IETimeScale);
        break;
    case SBIG('GTCP'):
        m_elem.reset(new struct IEGTCP);
        break;
    case SBIG('MODU'):
        m_elem.reset(new struct IEModulo);
        break;
    case SBIG('SUB_'):
        m_elem.reset(new struct IESubtract);
        break;
    case SBIG('NONE'):
        m_elem.reset();
        return;
    default:
        m_elem.reset();
        LogModule.report(logvisor::Fatal, "Unknown IntElement class %.4s @%" PRIi64, &clsId, r.position());
        return;
    }
    m_elem->read(r);
}
예제 #21
0
void IntElementFactory::read(athena::io::YAMLDocReader& r)
{
    const auto& mapChildren = r.getCurNode()->m_mapChildren;
    if (mapChildren.empty())
    {
        m_elem.reset();
        return;
    }

    const auto& elem = mapChildren[0];
    if (elem.first.size() < 4)
        LogModule.report(logvisor::Fatal, "short FourCC in element '%s'", elem.first.c_str());

    switch (*reinterpret_cast<const uint32_t*>(elem.first.data()))
    {
    case SBIG('KEYE'):
    case SBIG('KEYP'):
        m_elem.reset(new struct IEKeyframeEmitter);
        break;
    case SBIG('DETH'):
        m_elem.reset(new struct IEDeath);
        break;
    case SBIG('CLMP'):
        m_elem.reset(new struct IEClamp);
        break;
    case SBIG('CHAN'):
        m_elem.reset(new struct IETimeChain);
        break;
    case SBIG('ADD_'):
        m_elem.reset(new struct IEAdd);
        break;
    case SBIG('CNST'):
        m_elem.reset(new struct IEConstant);
        break;
    case SBIG('IMPL'):
        m_elem.reset(new struct IEImpulse);
        break;
    case SBIG('ILPT'):
        m_elem.reset(new struct IELifetimePercent);
        break;
    case SBIG('IRND'):
        m_elem.reset(new struct IEInitialRandom);
        break;
    case SBIG('PULS'):
        m_elem.reset(new struct IEPulse);
        break;
    case SBIG('MULT'):
        m_elem.reset(new struct IEMultiply);
        break;
    case SBIG('SPAH'):
        m_elem.reset(new struct IESampleAndHold);
        break;
    case SBIG('RAND'):
        m_elem.reset(new struct IERandom);
        break;
    case SBIG('TSCL'):
        m_elem.reset(new struct IETimeScale);
        break;
    case SBIG('GTCP'):
        m_elem.reset(new struct IEGTCP);
        break;
    case SBIG('MODU'):
        m_elem.reset(new struct IEModulo);
        break;
    case SBIG('SUB_'):
        m_elem.reset(new struct IESubtract);
        break;
    default:
        m_elem.reset();
        return;
    }
    r.enterSubRecord(elem.first.c_str());
    m_elem->read(r);
    r.leaveSubRecord();
}
예제 #22
0
void Translator::setLocale(const Locale* targetLocale)
{
    if (!targetLocale)
        Log.report(logvisor::Fatal, "null locale");
    m_targetLocale = targetLocale;
}