X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=source%2Fmupen64plus-video-arachnoid%2Fsrc%2FDisplayListParser.cpp;fp=source%2Fmupen64plus-video-arachnoid%2Fsrc%2FDisplayListParser.cpp;h=90aec28838eeabf8bb470d0789c3a1d04780079f;hb=22726e4d55be26faa48b57b22689cbedde27ae44;hp=0000000000000000000000000000000000000000;hpb=fc5d46b49a19d41f9f2da5a9336daec452900475;p=mupen64plus-pandora.git diff --git a/source/mupen64plus-video-arachnoid/src/DisplayListParser.cpp b/source/mupen64plus-video-arachnoid/src/DisplayListParser.cpp new file mode 100755 index 0000000..90aec28 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/DisplayListParser.cpp @@ -0,0 +1,219 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +#include "DisplayListParser.h" +#include "Memory.h" +#include "GBI.h" +#include "RSP.h" +#include "RDP.h" +#include "OpenGLRenderer.h" +#include "GBIDefs.h" + +//----------------------------------------------------------------------------- +//* Task +//! Definition of tasks that needs to be performed by the RSP +//! Used to process the dlist by the RSP (Reality Signal Processor) +//! Placed in DMEM at adress 0x04000fc0 +//----------------------------------------------------------------------------- +typedef struct +{ + unsigned int type; + unsigned int flags; + unsigned int ucode_boot; + unsigned int ucode_boot_size; + unsigned int ucode; + unsigned int ucode_size; + unsigned int ucode_data; + unsigned int ucode_data_size; + unsigned int dram_stack; + unsigned int dram_stack_size; + unsigned int output_buff; + unsigned int output_buff_size; + unsigned int data_ptr; + unsigned int data_size; + unsigned int yield_data_ptr; + unsigned int yield_data_size; +} Task_t; + +typedef union { + Task_t t; + unsigned long long force_structure_alignment; +} Task; + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +DisplayListParser::DisplayListParser() +{ +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +DisplayListParser::~DisplayListParser() +{ +} + +//----------------------------------------------------------------------------- +//! Initialize +//----------------------------------------------------------------------------- +bool DisplayListParser::initialize(RSP* rsp, RDP* rdp, GBI* gbi, Memory* memory) +{ + //Save pointers + m_rsp = rsp; + m_rdp = rdp; + m_gbi = gbi; + m_memory = memory; + + //Reset display list + m_DListStackPointer = 0; + for (int i=0; igetDMEM(TASK_ADDRESS_RELATIVE_DMEM)); + + + //Select UCode + m_gbi->selectUCode(task->t.ucode, task->t.ucode_data, task->t.ucode_size, task->t.ucode_data_size); + + //Parse DList + m_DListStackPointer = 0; + m_DlistStack[m_DListStackPointer].pc = (unsigned int)task->t.data_ptr; + m_DlistStack[m_DListStackPointer].countdown = MAX_DL_COUNT; + + // The main loop + while( m_DListStackPointer >= 0 ) + { + //Cast memory pointer + //uint32* RDRAMu32 = (unsigned int*)graphicsInfo.RDRAM; + unsigned int* RDRAMu32 = m_memory->getRDRAMint32(); + + //Get ucode argument from memory (vertices, textures, matrices...) + MicrocodeArgument* ucodeArg = (MicrocodeArgument*)&RDRAMu32[(m_DlistStack[m_DListStackPointer].pc>>2)]; + + //Increment program counter + m_DlistStack[m_DListStackPointer].pc += 8; + + //Call function to execute command + m_gbi->m_cmds[(ucodeArg->cmd)](ucodeArg); + + //Get next command + MicrocodeArgument* ucodeNext = (MicrocodeArgument*)&RDRAMu32[(m_DlistStack[m_DListStackPointer].pc>>2)]; + + //If this was a rendering command + if ( ucodeArg->cmd == GBI::G_TRI1 || + ucodeArg->cmd == GBI::G_TRI2 || + ucodeArg->cmd == GBI::G_TRI4 || + ucodeArg->cmd == GBI::G_QUAD || + ucodeArg->cmd == GBI::G_DMA_TRI ) + { + //If next is not a rendering command + if ( ucodeNext->cmd != GBI::G_TRI1 && + ucodeNext->cmd != GBI::G_TRI2 && + ucodeNext->cmd != GBI::G_TRI4 && + ucodeNext->cmd != GBI::G_QUAD && + ucodeNext->cmd != GBI::G_DMA_TRI ) + { + OpenGLRenderer::getSingleton().render(); + } + } + + //?? + if ( m_DListStackPointer >= 0 && --m_DlistStack[m_DListStackPointer].countdown < 0 ) + { + m_DListStackPointer--; + } + } + + //Trigger interupts + m_rdp->triggerInterrupt(); + m_rsp->triggerInterrupt(); +} + +//----------------------------------------------------------------------------- +//! Get next word +//----------------------------------------------------------------------------- +unsigned int DisplayListParser::getNextWord() +{ + unsigned int word = *(unsigned int*)m_memory->getRDRAM( this->getPC() + 4 ); + this->increasePC(8); + return word; +} + +//----------------------------------------------------------------------------- +//!< @param segmentAddress Used to retrive RDRAM address witch is used to set program counter +//----------------------------------------------------------------------------- +void DisplayListParser::displayList(unsigned int segmentAddress) +{ + unsigned int address = m_memory->getRDRAMAddress(segmentAddress); + + if ( (address + 8) > m_memory->getRDRAMSize() ) { + return; + } + + if ( m_DListStackPointer < (MAX_DL_STACK_SIZE - 1)) + { + m_DListStackPointer++; + m_DlistStack[m_DListStackPointer].pc = address; + m_DlistStack[m_DListStackPointer].countdown = MAX_DL_COUNT; + } +} + +//----------------------------------------------------------------------------- +//! Branch Display List +//----------------------------------------------------------------------------- +void DisplayListParser::branchDisplayList(unsigned int dl) +{ + unsigned int address = m_memory->getRDRAMAddress( dl ); + + if ( (address + 8) > m_memory->getRDRAMSize() ) { + return; + } + + m_DlistStack[m_DListStackPointer].pc = address; + m_DlistStack[m_DListStackPointer].countdown = MAX_DL_COUNT; +} + +//----------------------------------------------------------------------------- +//! DMA Display List +//----------------------------------------------------------------------------- +void DisplayListParser::DMADisplayList( unsigned int w0, unsigned int w1 ) +{ + //unsigned int dwAddr = (w1);//RSPSegmentAddr((gfx->words.w1)); + unsigned int dwAddr = m_memory->getRDRAMAddress(w1);//RSPSegmentAddr((gfx->words.w1)); + + { + m_DListStackPointer++; + m_DlistStack[m_DListStackPointer].pc = dwAddr; + m_DlistStack[m_DListStackPointer].countdown = (((w0)>>16)&0xFF); + } +}