void BitString::setPattern( uint32_t i_sPos, uint32_t i_sLen, CPU_WORD i_pattern, uint32_t i_pLen ) { PRDF_ASSERT(nullptr != getBufAddr()); // must to have a valid address PRDF_ASSERT(0 < i_sLen); // must have at least one bit PRDF_ASSERT(i_sPos + i_sLen <= getBitLen()); // field must be within range PRDF_ASSERT(0 < i_pLen); // must have at least one bit PRDF_ASSERT(i_pLen <= CPU_WORD_BIT_LEN); // i_pLen length must be valid // Get a bit string for the pattern subset (right justified). BitString bso ( i_pLen, &i_pattern, CPU_WORD_BIT_LEN - i_pLen ); // Iterate the range in chunks the size of i_pLen. uint32_t endPos = i_sPos + i_sLen; for ( uint32_t pos = i_sPos; pos < endPos; pos += i_pLen ) { // The true chunk size is either i_pLen or the leftovers at the end. uint32_t len = std::min( i_pLen, endPos - pos ); // Get this chunk's pattern value, truncate (left justified) if needed. CPU_WORD pattern = bso.getField( 0, len ); // Set the pattern in this string. setField( pos, len, pattern ); } }
void drawUploadTransfer() { sceDisplaySetMode(0, SCR_WIDTH, SCR_HEIGHT); sceGuStart(GU_DIRECT, list); sceGuTexFilter(GU_LINEAR, GU_LINEAR); sceGuFinish(); sceGuSync(0, 0); // This time, we only need one buffer. switchBuf(0, GU_PSM_8888); drawTexFlush(2, 2, 16, GU_PSM_T8, imageData, clutAddOne, vertices1); sceDisplayWaitVblank(); // Okay, let's draw a totally different pattern in memory. for (int y = 0; y < 272; ++y) { for (int x = 0; x < 512; ++x) { copybuf[y * 512 + x] = (x & 1) + (y & 1); } } sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(getBufAddr(0), copybuf, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); // Now download should display out pattern. displayBuffer("Pattern"); }
void BitString::setString( const BitString & i_sStr, uint32_t i_sPos, uint32_t i_sLen, uint32_t i_dPos ) { // Ensure the source parameters are valid. PRDF_ASSERT( nullptr != i_sStr.getBufAddr() ); PRDF_ASSERT( 0 < i_sLen ); // at least one bit to copy PRDF_ASSERT( i_sPos + i_sLen <= i_sStr.getBitLen() ); // Ensure the destination has at least one bit available to copy. PRDF_ASSERT( nullptr != getBufAddr() ); PRDF_ASSERT( i_dPos < getBitLen() ); // If the source length is greater than the destination length than the // extra source bits are ignored. uint32_t actLen = std::min( i_sLen, getBitLen() - i_dPos ); // The bit strings may be in overlapping memory spaces. So we need to copy // the data in the correct direction to prevent overlapping. uint32_t sRelOffset = 0, dRelOffset = 0; CPU_WORD * sRelAddr = i_sStr.getRelativePosition( sRelOffset, i_sPos ); CPU_WORD * dRelAddr = getRelativePosition( dRelOffset, i_dPos ); // Copy the data. if ( (dRelAddr == sRelAddr) && (dRelOffset == sRelOffset) ) { // Do nothing. The source and destination are the same. } else if ( (dRelAddr < sRelAddr) || ((dRelAddr == sRelAddr) && (dRelOffset < sRelOffset)) ) { // Copy the data forward. for ( uint32_t pos = 0; pos < actLen; pos += CPU_WORD_BIT_LEN ) { uint32_t len = std::min( actLen - pos, CPU_WORD_BIT_LEN ); CPU_WORD value = i_sStr.getField( i_sPos + pos, len ); setField( i_dPos + pos, len, value ); } } else // Copy the data backwards. { // Get the first position of the last chunk (CPU_WORD aligned). uint32_t lastPos = ((actLen-1) / CPU_WORD_BIT_LEN) * CPU_WORD_BIT_LEN; // Start with the last chunk and work backwards. for ( int32_t pos = lastPos; 0 <= pos; pos -= CPU_WORD_BIT_LEN ) { uint32_t len = std::min( actLen - pos, CPU_WORD_BIT_LEN ); CPU_WORD value = i_sStr.getField( i_sPos + pos, len ); setField( i_dPos + pos, len, value ); } } }
void switchBuf(int i, int fmt) { int off = (i * 512 * 272 * 4); void *p = (void *)off; drawbuf = (u32 *)getBufAddr(i); sceGuStart(GU_DIRECT, list); sceGuDrawBuffer(fmt, p, BUF_WIDTH); sceGuDispBuffer(SCR_WIDTH, SCR_HEIGHT, p, BUF_WIDTH); sceGuFinish(); sceGuSync(0, 0); }
void drawIntraTransfer() { sceDisplaySetMode(0, SCR_WIDTH, SCR_HEIGHT); sceGuStart(GU_DIRECT, list); sceGuTexFilter(GU_LINEAR, GU_LINEAR); sceGuFinish(); sceGuSync(0, 0); // This time, we only need one buffer. switchBuf(0, GU_PSM_8888); drawTexFlush(2, 2, 16, GU_PSM_T8, imageData, clutAddOne, vertices1); sceDisplayWaitVblank(); // Next, let's copy from this buffer to itself. sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(getBufAddr(0), (u8 *)getBufAddr(0) + sizeof(copybuf) / 2, sizeof(copybuf) / 2); sceKernelDcacheWritebackInvalidateAll(); // Now download should display a different buffer. displayBuffer("Spliced buffer"); }
void drawInterTransfer() { sceDisplaySetMode(0, SCR_WIDTH, SCR_HEIGHT); // First draw a texture to buffer 1. We'll use a clut here from memory. switchBuf(0, GU_PSM_8888); drawTexFlush(2, 2, 16, GU_PSM_T8, imageData, clutAddOne, vertices1); // Second, another texture to buffer 2. With a different clut so that they are visibly different. switchBuf(1, GU_PSM_8888); drawTexFlush(2, 2, 16, GU_PSM_T8, imageData, clutAddThree, vertices1); sceDisplayWaitVblank(); // Okay, at this point we have two buffers. Let's display one to make sure download works. displayBuffer("Initial download"); // Next, let's copy between them. sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(getBufAddr(1), getBufAddr(0), sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); // Now download should display the other buffer. displayBuffer("Copied buffer"); }