⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 processor.cc

📁 Linux下比较早的基于命令行的DVD播放器
💻 CC
📖 第 1 页 / 共 3 页
字号:
        ifo->getNumberOfSPUStreams(position.isInMenu());    if (numSPUStreams==0) {        return false;    }    unsigned spuStreamNumber = getSPRM().getSPSTN();    bool display = (spuStreamNumber&0x40)==0x40 || spuStreamNumber==62 || spuStreamNumber==63;    spuStreamNumber &= 0x3f;    if (reversed) {        if (spuStreamNumber>31) {            spuStreamNumber = numSPUStreams - 1;        } else if (spuStreamNumber>0) {            --spuStreamNumber;        } else {            spuStreamNumber = display ? 63 : 62;        }    } else {        if (spuStreamNumber>31) {            spuStreamNumber = 0;        } else if ((spuStreamNumber+1)<numSPUStreams) {            ++spuStreamNumber;        } else {            spuStreamNumber = display ? 63 : 62;        }    }    if (spuStreamNumber<=31 && display) {        spuStreamNumber |= 0x40;    }    Log::debug("dvd::vm::Processor::nextSPUStream: new SPU stream: %u\n",                spuStreamNumber);    state.setSPRValue(SPRM::SPSTN, spuStreamNumber);    return true;}//------------------------------------------------------------------------------void Processor::execute(const Instruction* instruction, size_t length){    scheduler.addInstructionSet(instruction, length);    scheduler.run();}//------------------------------------------------------------------------------void Processor::clearBranches(){    numberOfBranches = 0;}//------------------------------------------------------------------------------bool Processor::hasBranched(){    bool branched = numberOfBranches>0;    clearBranches();    return branched;}//------------------------------------------------------------------------------unsigned Processor::mapAudioStreamNumber(unsigned streamNo, unsigned languageCode,                     const IFO* ifo, PGC pgc, unsigned& candidate) const{    unsigned streamNumber = pgc.getAudioStreamNumber(streamNo);    if (streamNumber!=PGC::INVALID_STREAM_NUMBER) {        if (candidate==PGC::INVALID_STREAM_NUMBER) {            candidate = streamNumber;        }                if (languageCode!=0xffff) {            bool inMenu = getPosition().isInMenu();            if (streamNumber<ifo->getNumberOfAudioStreams(inMenu)) {                AudioStreamAttributes audioStreamAttributes =                     ifo->getAudioStreamAttributes(inMenu, streamNumber);                if (audioStreamAttributes.getLanguageCode()!=languageCode) {                    streamNumber = PGC::INVALID_STREAM_NUMBER;                }            } else {                streamNumber = PGC::INVALID_STREAM_NUMBER;            }        }    }    return streamNumber;}//------------------------------------------------------------------------------unsigned Processor::mapSPUStreamNumber(unsigned streamNo,                                        aspectRatio_t aspectRatio,                                       displayFormat_t displayFormat,                                       unsigned languageCode,                                       const IFO* ifo, PGC pgc,                                       unsigned& candidate) const{    unsigned streamNumber =         pgc.getSPUStreamNumber(streamNo, aspectRatio, displayFormat);    if (streamNumber!=PGC::INVALID_STREAM_NUMBER) {        if (candidate==PGC::INVALID_STREAM_NUMBER) {            candidate = streamNumber;        }                if (languageCode!=0xffff) {            bool inMenu = getPosition().isInMenu();            if (streamNumber<ifo->getNumberOfSPUStreams(inMenu)) {                SPUStreamAttributes spuStreamAttributes =                     ifo->getSPUStreamAttributes(inMenu, streamNumber);                if (spuStreamAttributes.getLanguageCode()!=languageCode) {                    streamNumber = PGC::INVALID_STREAM_NUMBER;                }            } else {                streamNumber = PGC::INVALID_STREAM_NUMBER;            }        }    }    return streamNumber;}//------------------------------------------------------------------------------void Processor::setPosition(const Position& position){    state.setPosition(position);}//------------------------------------------------------------------------------void Processor::process(const Instruction* instruction){    switch(instruction->getType()) {      case Instruction::SPECIAL:        executeSpecial(instruction);        break;      case Instruction::BRANCH:        executeBranch(instruction);        break;      case Instruction::SETSYSREG:        executeSetSysReg(instruction);        break;      case Instruction::SET:        executeSet(instruction);        break;      case Instruction::SETCLNK:        executeSetCLnk(instruction);        break;      case Instruction::CSETCLNK:        executeCSetCLnk(instruction);        break;      case Instruction::CMPSETLNK:        executeCmpSetLnk(instruction);        break;      default:        Log::error("dvd::vm::Processor::process: invalid instruction type: %u\n",                     (unsigned)instruction->getType());        scheduler.addStep();        break;    }}//------------------------------------------------------------------------------void Processor::executeSpecial(const Instruction* instruction){    if (!evaluateSpecialCondition(instruction)) {        scheduler.addStep();        return;    }    switch(instruction->getSpecCmd()) {      case Instruction::BREAK:        scheduler.addBreak();        break;      case Instruction::SETTMPPLVL:        /// FIXME: we should ask for password based in the parental level        /// for now, it just succeeds (we trust ourselves and our children)        state.setSPRValue(SPRM::PLT, instruction->operand3.getLVL());        // We should goto after successfully setting the parental level      case Instruction::GOTO:        scheduler.addGoto(instruction->operand3.getLineNumber());        break;      default:        Log::error("dvd::vm::Processor::executeSpecial: invalid special command: %u\n",                    (unsigned)instruction->getSpecCmd());                scheduler.addFirstPlayPGC();        break;      case Instruction::NOP:        scheduler.addStep();        break;    }}//------------------------------------------------------------------------------void Processor::executeBranch(const Instruction* instruction){    if (instruction->isDirect()) {        executeJumpCall(instruction);    } else {        executeLink(instruction);    }}//------------------------------------------------------------------------------void Processor::executeLink(const Instruction* instruction){    if (evaluateLinkCondition(instruction)) {        executeLinkUnconditionally(instruction);    } else {        scheduler.addStep();    }}    //------------------------------------------------------------------------------void Processor::executeLinkUnconditionally(const Instruction* instruction){    TargetPosition targetPosition(state.getPosition());    ++numberOfBranches;    switch(instruction->getLinkCmd()) {      case Instruction::LINKSUBSET:        executeLinkSubset(instruction);        break;      case Instruction::LINKPGCN:        if (targetPosition.enterPGC(instruction->operand3.getPGCN())) {            scheduler.addStartPGC(targetPosition);        } else {            scheduler.addFirstPlayPGC();        }        break;      case Instruction::LINKPTTN:        if (targetPosition.enterPTT(state.getSPRValue(SPRM::vtsTitleNumber), // FIXME: use a more scientific approach here                                    instruction->operand3.getPTTN()))        {            unsigned buttonNumber = instruction->operand3.getHLBN();            if (buttonNumber>0) {                state.setHighlightedButtonNumber(buttonNumber);            }            scheduler.flush();            scheduler.addSetPosition(targetPosition);        } else {            scheduler.addFirstPlayPGC();        }        break;      case Instruction::LINKPGN:        // FIXME: the same as above        if (targetPosition.enterProgram(instruction->operand3.getPGN())) {            unsigned buttonNumber = instruction->operand3.getHLBN();            if (buttonNumber>0) {                state.setHighlightedButtonNumber(buttonNumber);            }            scheduler.flush();            scheduler.addSetPosition(targetPosition);        } else {            scheduler.addFirstPlayPGC();        }        break;      case Instruction::LINKCN:        // FIXME: the same as above        if (targetPosition.enterCell(instruction->operand3.getCN())) {            unsigned buttonNumber = instruction->operand3.getHLBN();            if (buttonNumber>0) {                state.setHighlightedButtonNumber(buttonNumber);            }            scheduler.flush();            scheduler.addSetPosition(targetPosition);        } else {            scheduler.addFirstPlayPGC();        }        break;      default:        Log::error("dvd::vm::Processor::executeLinkUnconditionally: invalid link command: %u\n",                    (unsigned)instruction->getLinkCmd());        scheduler.addFirstPlayPGC();        break;      case Instruction::LINK_NOP:        --numberOfBranches;        scheduler.addStep();        break;    }}//------------------------------------------------------------------------------bool Processor::linkPreviousCell(TargetPosition& targetPosition){    if (!targetPosition.enterPreviousCell()) {        do {            if (!targetPosition.enterPreviousPGC()) {                return false;            }        } while(!targetPosition.enterLastCell());    }        return true;}//------------------------------------------------------------------------------void Processor::executeLinkSubset(const Instruction* instruction){    TargetPosition targetPosition(state.getPosition());    switch(instruction->operand3.getLinkType()) {      case Operand3::TOPCELL:        targetPosition.repeatCell();        scheduler.flush();        scheduler.addSetPosition(targetPosition);        break;      case Operand3::NEXTCELL:        if (targetPosition.enterNextCell()) {            scheduler.flush();            scheduler.addSetPosition(targetPosition);        } else {            if (targetPosition.enterNextPGC()) {                scheduler.addStartPGC(targetPosition);            } else {                scheduler.addFirstPlayPGC();            }            scheduler.addPGCPostCommands(state.getPosition());        }        break;      case Operand3::PREVCELL:        if (linkPreviousCell(targetPosition)) {            scheduler.flush();            scheduler.addSetPosition(targetPosition);        } else {            scheduler.addFirstPlayPGC();        }        break;      case Operand3::TOPPG:        targetPosition.repeatProgram();        scheduler.flush();        scheduler.addSetPosition(targetPosition);        break;      case Operand3::NEXTPG:        if (targetPosition.enterNextProgram()) {            scheduler.flush();            scheduler.addSetPosition(targetPosition);        } else {            if (targetPosition.enterNextPGC()) {                scheduler.addStartPGC(targetPosition);            } else {                scheduler.addFirstPlayPGC();            }            scheduler.addPGCPostCommands(state.getPosition());            // FIXME: same as for NEXTCELL        }        break;      case Operand3::PREVPG:        if (targetPosition.enterPreviousProgram()) {            scheduler.flush();            scheduler.addSetPosition(targetPosition);        } else {            if (targetPosition.enterPreviousPGC()) {                targetPosition.enterLastProgram();                scheduler.flush();                scheduler.addSetPosition(targetPosition);            } else {                scheduler.addFirstPlayPGC();            }            // FIXME: almost the same as PREVCELL        }      case Operand3::TOPPGC:        // FIXME: this is almost the same as for LINKPGCN        if (targetPosition.enterProgram(1)) {            scheduler.addStartPGC(targetPosition);        } else {            scheduler.addFirstPlayPGC();        }        break;      case Operand3::NEXTPGC:        // FIXME: this is almost the same as for LINKPGCN        if (targetPosition.enterNextPGC()) {            scheduler.addStartPGC(targetPosition);        } else {            scheduler.addFirstPlayPGC();        }        break;      case Operand3::PREVPGC:        // FIXME: this is almost the same as for LINKPGCN        if (targetPosition.enterPreviousPGC()) {            scheduler.addStartPGC(targetPosition);        } else {            scheduler.addFirstPlayPGC();        }        break;      case Operand3::GOUPPGC:        // FIXME: this is almost the same as for LINKPGCN        if (targetPosition.enterGoUpPGC()) {            scheduler.addStartPGC(targetPosition);        } else {            scheduler.addFirstPlayPGC();        }        break;      case Operand3::TAILPGC:        scheduler.addFirstPlayPGC(); // FIXME: Fallback, if the POST commands                                     // would not jump        scheduler.addPGCPostCommands(state.getPosition());        break;      case Operand3::RSM:        if (!state.resume()) {            scheduler.addFirstPlayPGC();        }        break;      default:        Log::error("dvd::vm::Processor::executeLinkSubset: Invalid link subset type: %u\n",                   (unsigned)instruction->operand3.getLinkType());        scheduler.addFirstPlayPGC();        return;      case Operand3::LINK_NOP:        --numberOfBranches;        scheduler.addStep();        return;    }    unsigned buttonNumber = instruction->operand3.getHLBN();    if (buttonNumber>0) {        state.setHighlightedButtonNumber(buttonNumber);    }}//------------------------------------------------------------------------------void Processor::executeJumpCall(const Instruction* instruction){    if (!evaluateJumpCallCondition(instruction)) {        scheduler.addStep();        return;    }        TargetPosition targetPosition(state.getPosition());    ++numberOfBranches;    switch(instruction->getJumpCallCmd()) {      case Instruction::EXIT:        Log::debug("dvd::vm::Processor::executeJumpCall: EXIT instruction hit\n");        if (Config::get().quitOnExit) {            scheduler.flush();                        targetPosition.exit();            scheduler.addSetPosition(targetPosition);        } else {            scheduler.addFirstPlayPGC();        }        break;      case Instruction::JUMPTT:        if (targetPosition.enterTT(instruction->operand2.getTTN())) {            scheduler.addStartPGC(targetPosition);        } else {            scheduler.addFirstPlayPGC();        }        break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -