aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xbmc/karaoke/cdgdata.h7
-rw-r--r--xbmc/karaoke/karaokelyricscdg.cpp129
-rw-r--r--xbmc/karaoke/karaokelyricscdg.h7
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;