diff options
-rw-r--r-- | xbmc/karaoke/cdgdata.h | 7 | ||||
-rw-r--r-- | xbmc/karaoke/karaokelyricscdg.cpp | 129 | ||||
-rw-r--r-- | xbmc/karaoke/karaokelyricscdg.h | 7 |
3 files changed, 132 insertions, 11 deletions
diff --git a/xbmc/karaoke/cdgdata.h b/xbmc/karaoke/cdgdata.h index 64bea70dd9..30d8255631 100644 --- a/xbmc/karaoke/cdgdata.h +++ b/xbmc/karaoke/cdgdata.h @@ -62,5 +62,12 @@ typedef struct char colorSpec[16]; // AND with 0x3F3F to clear P and Q channel } CDG_LoadColorTable; +typedef struct +{ + char color; // Only lower 4 bits are used, mask with 0x0F + char hScroll; // Only lower 6 bits are used, mask with 0x3F + char vScroll; // Only lower 6 bits are used, mask with 0x3F +} +CDG_Scroll; #endif // CDG_H diff --git a/xbmc/karaoke/karaokelyricscdg.cpp b/xbmc/karaoke/karaokelyricscdg.cpp index 6a3f34478e..f64fb64b32 100644 --- a/xbmc/karaoke/karaokelyricscdg.cpp +++ b/xbmc/karaoke/karaokelyricscdg.cpp @@ -379,6 +379,16 @@ bool CKaraokeLyricsCDG::UpdateBuffer( unsigned int packets_due ) screen_changed = true; break; + case CDG_INST_SCROLL_PRESET: + cmdScroll( sc.data, false ); + screen_changed = true; + break; + + case CDG_INST_SCROLL_COPY: + cmdScroll( sc.data, true ); + screen_changed = true; + break; + default: // this shouldn't happen as we validated the stream in Load() break; } @@ -445,21 +455,14 @@ bool CKaraokeLyricsCDG::Load() case CDG_INST_TILE_BLOCK_XOR: case CDG_INST_TILE_BLOCK: case CDG_INST_DEF_TRANSP_COL: + case CDG_INST_SCROLL_PRESET: + case CDG_INST_SCROLL_COPY: memcpy( &packet.subcode, sc, sizeof(SubCode) ); packet.packetnum = offset / sizeof( SubCode ); m_cdgStream.push_back( packet ); break; - - // We do not support those commands since I have never seen a CD+G file which has them. - case CDG_INST_SCROLL_PRESET: - case CDG_INST_SCROLL_COPY: - CLog::Log( LOGERROR, "CDG loader: Unsupported CD+G instruction %d found in file %s, " - "please report to oldnemesis together with the file!", - sc->instruction & CDG_MASK, m_cdgFile.c_str() ); - m_cdgStream.clear(); - return false; - - default: + + default: buggy_commands++; break; } @@ -484,3 +487,107 @@ bool CKaraokeLyricsCDG::Load() return true; } + +void CKaraokeLyricsCDG::cmdScroll( const char * data, bool isloop ) +{ + CDG_Scroll * scroll = (CDG_Scroll*) & data; + scroll->color &= 0x0F; + int color = isloop ? -1 : scroll->color; + + BYTE hSCmd = (scroll->hScroll & 0x30) >> 4; + BYTE vSCmd = (scroll->vScroll & 0x30) >> 4; + + switch (hSCmd) + { + case 1: + scrollRight( color ); + break; + + case 2: + scrollLeft( color ); + break; + } + + switch (vSCmd) + { + case 1: + scrollDown( color ); + break; + + case 2: + scrollUp( color); + break; + } +} + +void CKaraokeLyricsCDG::scrollLeft( int color ) +{ + BYTE PixelTemp[CDG_FULL_HEIGHT][CDG_BORDER_WIDTH]; + UINT i, j; + + for (i = 0;i < CDG_BORDER_WIDTH;i++) + for (j = 0;j < CDG_FULL_HEIGHT;j++) + PixelTemp[j][i] = (color == -1 ? getPixel( j, i ) : color); + + for (i = 0;i < CDG_FULL_WIDTH - CDG_BORDER_WIDTH;i++) //Fill scrolled area + for (j = 0;j < CDG_FULL_HEIGHT;j++) + setPixel( j, i, getPixel( j, i + CDG_BORDER_WIDTH ) ); + + for (i = CDG_FULL_WIDTH - CDG_BORDER_WIDTH;i < CDG_FULL_WIDTH;i++) //Fill uncovered area + for (j = 0;j < CDG_FULL_HEIGHT;j++) + setPixel( j, i, PixelTemp[j][i + CDG_BORDER_WIDTH - CDG_FULL_WIDTH] ); +} + +void CKaraokeLyricsCDG::scrollRight( int color ) +{ + BYTE PixelTemp[CDG_FULL_HEIGHT][CDG_BORDER_WIDTH]; + UINT i, j; + + for (i = CDG_FULL_WIDTH - CDG_BORDER_WIDTH;i < CDG_FULL_WIDTH;i++) + for (j = 0;j < CDG_FULL_HEIGHT;j++) + PixelTemp[j][CDG_BORDER_WIDTH - CDG_FULL_WIDTH + i] = (color == -1 ? getPixel( j, i ) : color); + + for (i = CDG_BORDER_WIDTH ; i < CDG_FULL_WIDTH ; i++) //Fill scrolled area + for (j = 0;j < CDG_FULL_HEIGHT;j++) + setPixel( j, i, getPixel( j, i - CDG_BORDER_WIDTH ) ); + + for (i = 0;i < CDG_BORDER_WIDTH;i++) //Fill uncovered area + for (j = 0;j < CDG_FULL_HEIGHT;j++) + setPixel( j, i, PixelTemp[j][i] ); +} + +void CKaraokeLyricsCDG::scrollUp( int color ) +{ + BYTE PixelTemp[CDG_BORDER_HEIGHT][CDG_FULL_WIDTH]; + UINT i, j; + + for (i = 0;i < CDG_FULL_WIDTH;i++) + for (j = 0 ; j < CDG_BORDER_HEIGHT ;j++) + PixelTemp[j][i] = (color == -1 ? getPixel( j, i ) : color ); + + for (i = 0;i < CDG_FULL_WIDTH;i++) //Fill scrolled area + for (j = 0;j < CDG_FULL_HEIGHT - CDG_BORDER_HEIGHT;j++) + setPixel( j, i, getPixel( j + CDG_BORDER_HEIGHT, i ) ); + + for (i = 0;i < CDG_FULL_WIDTH;i++) //Fill uncovered area + for (j = CDG_FULL_HEIGHT - CDG_BORDER_HEIGHT;j < CDG_FULL_HEIGHT;j++) + setPixel( j, i, PixelTemp[CDG_BORDER_HEIGHT - CDG_FULL_HEIGHT + j][i] ); +} + +void CKaraokeLyricsCDG::scrollDown( int color ) +{ + BYTE PixelTemp[CDG_BORDER_HEIGHT][CDG_FULL_WIDTH]; + UINT i, j; + + for (i = 0;i < CDG_FULL_WIDTH;i++) + for (j = CDG_FULL_HEIGHT - CDG_BORDER_HEIGHT;j < CDG_FULL_HEIGHT;j++) + PixelTemp[CDG_BORDER_HEIGHT - CDG_FULL_HEIGHT + j][i] = (color == -1 ? getPixel( j, i ) : color ); + + for (i = 0;i < CDG_FULL_WIDTH;i++) //Fill scrolled area + for (j = CDG_BORDER_HEIGHT;j < CDG_FULL_HEIGHT;j++) + setPixel( j, i, getPixel( j - CDG_BORDER_HEIGHT, i ) ); + + for (i = 0;i < CDG_FULL_WIDTH;i++) //Fill uncovered area + for (j = 0;j < CDG_BORDER_HEIGHT;j++) + setPixel( j, i, PixelTemp[j][i] ); +} diff --git a/xbmc/karaoke/karaokelyricscdg.h b/xbmc/karaoke/karaokelyricscdg.h index 925be10e94..fc1b7328ec 100644 --- a/xbmc/karaoke/karaokelyricscdg.h +++ b/xbmc/karaoke/karaokelyricscdg.h @@ -68,6 +68,13 @@ class CKaraokeLyricsCDG : public CKaraokeLyrics void cmdTileBlock( const char * data ); void cmdTileBlockXor( const char * data ); void cmdTransparentColor( const char * data ); + + void cmdScroll( const char * data, bool loop ); + void scrollLeft( int color ); + void scrollRight( int color ); + void scrollUp( int color ); + void scrollDown( int color ); + bool UpdateBuffer( unsigned int packets_due ); void RenderIntoBuffer( unsigned char *pixels, unsigned int width, unsigned int height, unsigned int pitch ) const; |