📄 processor.cc
字号:
//// Copyright (c) 2003 by Istv醤 V醨adi//// This file is part of dxr3Player, a DVD player written specifically // for the DXR3 (aka Hollywood+) decoder card.// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA//------------------------------------------------------------------------------#include "Processor.h"#include "Instruction.h"#include "TargetPosition.h"#include "util/Log.h"#include "util/Config.h"//------------------------------------------------------------------------------using dvd::vm::Processor;using dvd::vm::Instruction;using dvd::vm::Register;//------------------------------------------------------------------------------bool Processor::evaluateComparison(Instruction::cmpOp_t cmpOp, unsigned value1, unsigned value2){ switch(cmpOp) { case Instruction::BC: return (value1&value2)!=0; case Instruction::EQ: return value1==value2; case Instruction::NE: return value1!=value2; case Instruction::GE: return value1>=value2; case Instruction::GT: return value1>value2; case Instruction::LE: return value1<=value2; case Instruction::LT: return value1<value2; default: Log::error("dvd::vm::Processor::evaluateComparison: invalid comparison operator: %u\n", (unsigned)cmpOp); case Instruction::CMP_NONE: return true; }}//------------------------------------------------------------------------------//------------------------------------------------------------------------------Processor::Processor(DVD* dvd) : state(dvd), scheduler(*this), numberOfBranches(0){}//------------------------------------------------------------------------------unsigned Processor::getAudioStreamNumber(unsigned& logicalStream) const{ unsigned streamNumber = PGC::INVALID_STREAM_NUMBER; const Position& position = getPosition(); logicalStream = 15; const IFO* ifo = position.findIFO(); if (ifo!=0) { PGC pgc = position.getPGC(); unsigned forcedAudioLanguage = Config::get().forcedAudioLanguage; unsigned candidate = PGC::INVALID_STREAM_NUMBER; unsigned streamNo = state.getSPRM().getASTN(); unsigned forcedAudioStream = Config::get().forcedAudioStream; if (forcedAudioStream<8) { streamNo = forcedAudioStream; } if (streamNo<8) { streamNumber = mapAudioStreamNumber(streamNo, forcedAudioLanguage, ifo, pgc, candidate); } if (streamNumber==PGC::INVALID_STREAM_NUMBER) { for(streamNo = 0; streamNumber==PGC::INVALID_STREAM_NUMBER && streamNo<8; ++streamNo) { streamNumber = mapAudioStreamNumber(streamNo, forcedAudioLanguage, ifo, pgc, candidate); if (streamNumber!=PGC::INVALID_STREAM_NUMBER) { logicalStream = streamNo; } } } else { logicalStream = streamNo; } if (streamNumber==PGC::INVALID_STREAM_NUMBER) { streamNumber = candidate; } } return streamNumber;}//------------------------------------------------------------------------------unsigned Processor::getSPUStreamNumber(aspectRatio_t aspectRatio, displayFormat_t displayFormat, bool& forcedOnly) const{ unsigned streamNumber = PGC::INVALID_STREAM_NUMBER; const Position& position = getPosition(); bool isInVTS = !position.isInMenu() && !position.isInVideoManager(); unsigned spstn = state.getSPRM().getSPSTN(); unsigned streamNo = spstn; unsigned forcedSPUStream = Config::get().forcedSPUStream; if (forcedSPUStream<32) { streamNo = 0x40 | forcedSPUStream; } unsigned forcedSPULanguage = Config::get().forcedSPULanguage; if (isInVTS && streamNo==62 && forcedSPULanguage==0xffff) return streamNumber; forcedOnly = (streamNo==62 || (streamNo&0x40)==0) && (forcedSPULanguage==0xffff); const IFO* ifo = position.findIFO(); if (ifo!=0) { PGC pgc = position.getPGC(); unsigned candidate = PGC::INVALID_STREAM_NUMBER; streamNo = isInVTS ? (streamNo & 0x3f) : 0; if (streamNo<32) { streamNumber = mapSPUStreamNumber(streamNo, aspectRatio, displayFormat, forcedSPULanguage, ifo, pgc, candidate); } for(streamNo = 0; streamNumber==PGC::INVALID_STREAM_NUMBER && streamNo<32; ++streamNo) { streamNumber = mapSPUStreamNumber(streamNo, aspectRatio, displayFormat, forcedSPULanguage, ifo, pgc, candidate); } if (streamNumber==PGC::INVALID_STREAM_NUMBER) { streamNumber = candidate; } if (!isInVTS && streamNumber==PGC::INVALID_STREAM_NUMBER) { streamNumber = 0; } } return streamNumber; }//------------------------------------------------------------------------------void Processor::reset(){ state.reset();}//------------------------------------------------------------------------------void Processor::executeFirstPlayPGC(){ scheduler.addFirstPlayPGC(); scheduler.run(); clearBranches();}//------------------------------------------------------------------------------bool Processor::nextCell(unsigned& stillTime){ clearBranches(); const Position& position = getPosition(); stillTime = position.getCellPlaybackInfo().getStillTime(); if (stillTime==PGC::infiniteStillTime) { return false; } if (scheduler.addCellCommand(position)) { scheduler.run(); if (hasBranched()) return true; } TargetPosition targetPosition(position); if (targetPosition.enterNextCell()) { setPosition(targetPosition); return true; } unsigned pgcStillTime = targetPosition.getPGC().getStillTime(); if (pgcStillTime==PGC::infiniteStillTime) { stillTime = pgcStillTime; } else { stillTime += pgcStillTime; } if (stillTime==PGC::infiniteStillTime) { return false; } if (scheduler.addPGCPostCommands(position)) { scheduler.run(); if (hasBranched()) return true; } if (targetPosition.enterNextPGC()) { bool pgcValid = scheduler.addStartPGC(targetPosition); scheduler.run(); clearBranches(); return pgcValid; } else { executeFirstPlayPGC(); return false; }}//------------------------------------------------------------------------------bool Processor::previousCell(){ TargetPosition targetPosition(getPosition()); bool wasPreviousCell = linkPreviousCell(targetPosition); if (wasPreviousCell) { wasPreviousCell = targetPosition.enterLastVOBU(); } if (wasPreviousCell) { scheduler.flush(); scheduler.addSetPosition(targetPosition); scheduler.run(); clearBranches(); } return wasPreviousCell;}//------------------------------------------------------------------------------bool Processor::repeatProgram(){ TargetPosition targetPosition(getPosition()); if (targetPosition.repeatProgram()) { scheduler.flush(); scheduler.addSetPosition(targetPosition); scheduler.run(); clearBranches(); return true; } else { return false; }}//------------------------------------------------------------------------------bool Processor::nextProgram(){ const Position& position = getPosition(); TargetPosition targetPosition(position); if (targetPosition.enterNextProgram()) { setPosition(targetPosition); return true; } if (scheduler.addPGCPostCommands(position)) { scheduler.run(); if (hasBranched()) return true; } if (targetPosition.enterNextPGC()) { bool pgcValid = scheduler.addStartPGC(targetPosition); scheduler.run(); clearBranches(); return pgcValid; } return false;}//------------------------------------------------------------------------------bool Processor::previousProgram(){ TargetPosition targetPosition(getPosition()); bool hasPreviousProgram = targetPosition.enterPreviousProgram(); if (hasPreviousProgram) { scheduler.flush(); scheduler.addSetPosition(targetPosition); scheduler.run(); clearBranches(); } return hasPreviousProgram;}//------------------------------------------------------------------------------bool Processor::enterMenu(unsigned menuID, bool forced){ const Position& position = getPosition(); TargetPosition targetPosition(position); if (targetPosition.enterMenu(menuID, forced)) { if (!position.isInVideoManager() && !position.isInMenu()) { state.save(); } scheduler.addStartPGC(targetPosition); scheduler.run(); clearBranches(); return true; } return false;}//------------------------------------------------------------------------------bool Processor::nextAngle(){ unsigned titleNumber = state.getSPRValue(SPRM::volumeTitleNumber); TitleInfoTable titleInfoTable = state.getDVD()->getVMG()->getTitleInfoTable(); if (titleNumber<1 || titleNumber>titleInfoTable.getNumberOfTitles()) { return false; } TitleInfo titleInfo = titleInfoTable.getTitleInfo(titleNumber); unsigned nextAngle = state.getSPRValue(SPRM::angleNumber); // Here we would subtract 1, to make the angle number 0-based, // then add 1, to get the next angle. So we do nothing nextAngle %= titleInfo.getNumberOfAngles(); nextAngle += 1; Log::debug("dvd::vm::Processor::nextAngle: new angle: %u\n", nextAngle); state.setSPRValue(SPRM::angleNumber, nextAngle); return true;}//------------------------------------------------------------------------------bool Processor::nextAudioStream(bool reversed){ const Position& position = getPosition(); const IFO* ifo = position.findIFO(); Log::debug("dvd::vm::Processor::nextAudioStream: ifo=%p\n", ifo); if (ifo==0) { return false; } unsigned numAudioStreams = ifo->getNumberOfAudioStreams(position.isInMenu()); Log::debug("dvd::vm::Processor::nextAudioStream: numAudioStreams=%u\n", numAudioStreams); if (numAudioStreams==0) { return false; } unsigned audioStreamNumber = getSPRM().getASTN(); if (audioStreamNumber==15) { getAudioStreamNumber(audioStreamNumber); } Log::debug("dvd::vm::Processor::nextAudioStream: audioStreamNumber=%u\n", audioStreamNumber); // if (audioStreamNumber>=numAudioStreams) {// return false;// } if (reversed) { if (audioStreamNumber>0 && audioStreamNumber<numAudioStreams) { --audioStreamNumber; } else { audioStreamNumber = numAudioStreams - 1; } } else { if ((audioStreamNumber+1)<numAudioStreams) { ++audioStreamNumber; } else { audioStreamNumber = 0; } } Log::debug("dvd::vm::Processor::nextAudioStream: new audio stream: %u\n", audioStreamNumber); state.setSPRValue(SPRM::ASTN, audioStreamNumber); return true;}//------------------------------------------------------------------------------bool Processor::nextSPUStream(bool reversed){ const Position& position = getPosition(); const IFO* ifo = position.findIFO(); if (ifo==0) { return false; } unsigned numSPUStreams =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -