From c7732de9aa10d75b9135f1256055e203a4d387b6 Mon Sep 17 00:00:00 2001 From: frntc <48584231+frntc@users.noreply.github.com> Date: Fri, 23 Dec 2022 18:28:03 +0100 Subject: [PATCH] modifications for slide shows --- Source/Firmware/helpers.cpp | 7 +- Source/Firmware/helpers.h | 10 +- Source/Firmware/kernel_ef.cpp | 238 ++++++++++++++++++++++++++++++ Source/Firmware/kernel_launch.cpp | 65 +++++++- Source/Firmware/kernel_menu.cpp | 2 +- Source/Firmware/tft_st7789.cpp | 173 +++++++++++++++------- Source/Firmware/tft_st7789.h | 10 +- 7 files changed, 442 insertions(+), 63 deletions(-) diff --git a/Source/Firmware/helpers.cpp b/Source/Firmware/helpers.cpp index a9bc5253..4fe80ad8 100644 --- a/Source/Firmware/helpers.cpp +++ b/Source/Firmware/helpers.cpp @@ -29,10 +29,12 @@ #include "helpers.h" // file reading -int readFile( CLogger *logger, const char *DRIVE, const char *FILENAME, u8 *data, u32 *size ) +int readFile( CLogger *logger, const char *DRIVE, const char *FILENAME, u8 *data, u32 *size, u32 maxSize ) { FATFS m_FileSystem; + *size = 0; + // mount file system if ( f_mount( &m_FileSystem, DRIVE, 1 ) != FR_OK ) logger->Write( "RaspiMenu", LogPanic, "Cannot mount drive: %s", DRIVE ); @@ -55,6 +57,9 @@ int readFile( CLogger *logger, const char *DRIVE, const char *FILENAME, u8 *data return 0; } + if ( filesize > maxSize ) + filesize = maxSize; + *size = filesize; // read data in one big chunk diff --git a/Source/Firmware/helpers.h b/Source/Firmware/helpers.h index c5236c40..0cda940f 100644 --- a/Source/Firmware/helpers.h +++ b/Source/Firmware/helpers.h @@ -33,7 +33,7 @@ #include #include -extern int readFile( CLogger *logger, const char *DRIVE, const char *FILENAME, u8 *data, u32 *size ); +extern int readFile( CLogger *logger, const char *DRIVE, const char *FILENAME, u8 *data, u32 *size, u32 maxSize = 0x7fffffff ); extern int getFileSize( CLogger *logger, const char *DRIVE, const char *FILENAME, u32 *size ); extern int writeFile( CLogger *logger, const char *DRIVE, const char *FILENAME, u8 *data, u32 size ); @@ -261,4 +261,12 @@ C64IsRunning: \ #define min(a,b) (((a)<(b))?(a):(b)) #define max(a,b) (((a)>(b))?(a):(b)) +__attribute__( ( always_inline ) ) inline u8 flipByte( u8 x ) +{ + u32 t; + asm volatile( "rbit %w0, %w1" : "=r" ( t ) : "r" ( x ) ); // flip all bits in 32-bit-DWORD + asm volatile( "rev %w0, %w1" : "=r" ( t ) : "r" ( t ) ); // reverse 4 bytes in 32-bit-DWORD + return *(u8*)&t; +} + #endif diff --git a/Source/Firmware/kernel_ef.cpp b/Source/Firmware/kernel_ef.cpp index fc9a9411..a34791ec 100644 --- a/Source/Firmware/kernel_ef.cpp +++ b/Source/Firmware/kernel_ef.cpp @@ -459,6 +459,7 @@ static void KernelEFFIQHandler_Dinamic( void *pParam ); static void KernelEFFIQHandler_SimonsBasic( void *pParam ); static void KernelEFFIQHandler_Comal80( void *pParam ); static void KernelEFFIQHandler_EpyxFL( void *pParam ); +static void KernelMDOnlyFIQHandler( void *pParam ); #define LRU_CACHE_ENTRIES 16 @@ -502,6 +503,13 @@ static void checkForEyeOfTheBeholder() } } +static u8 showSlideShow = 0; +static u8 curSlideShowImage = 0; +static u16 curPixelRow = 0; +static u16 curCopyRow = 0; +static u32 pauseSlideShow = 0; +static u8 timeSlideShow[ 32 ]; + static void KernelEFFIQHandler( void *pParam ); void KernelEFRun( CGPIOPinFIQ m_InputPin, CKernelMenu *kernelMenu, const char *FILENAME, const char *menuItemStr, const char *FILENAME_KERNAL = NULL ) #else @@ -555,6 +563,9 @@ void CKernelEF::Run( void ) checkForEyeOfTheBeholder(); + showSlideShow = 0; + tftSlideShowNImages = 0; + #ifdef COMPILE_MENU if ( screenType == 0 ) { @@ -568,9 +579,11 @@ void CKernelEF::Run( void ) } else if ( screenType == 1 ) { + char fn[ 1024 ]; // attention: this assumes that the filename ending is always ".crt"! memset( fn, 0, 1024 ); + strncpy( fn, FILENAME, strlen( FILENAME ) - 4 ); strcat( fn, ".tga" ); @@ -664,6 +677,25 @@ void CKernelEF::Run( void ) tftCopyBackground2Framebuffer(); } + memset( fn, 0, 1024 ); + strncpy( fn, FILENAME, strlen( FILENAME ) - 4 ); + strcat( fn, "-slideshow.tga" ); + + if ( tftLoadSlideShowTGA( DRIVE, fn ) && tftSlideShowNImages > 0 ) + { + showSlideShow = 1; + curSlideShowImage = tftSlideShowNImages - 1; + curCopyRow = curPixelRow = 0; + pauseSlideShow = 0; + + fn[ strlen( fn ) - 3 ] = 0; + strcat( fn, "time" ); + u32 size = 0; + for ( u32 i = 0; i < 32; i++ ) + timeSlideShow[ i ] = 10; + readFile( logger, DRIVE, fn, timeSlideShow, &size, 32 ); + } + tftInitImm(); tftSendFramebuffer16BitImm( tftFrameBuffer ); } @@ -708,6 +740,10 @@ void CKernelEF::Run( void ) myHandler = KernelEFFIQHandler_EpyxFL; if ( ef.bankswitchType == BS_SIMONSBASIC ) myHandler = KernelEFFIQHandler_SimonsBasic; + + + if ( ef.bankswitchType == BS_MAGICDESK ) + myHandler = KernelMDOnlyFIQHandler; #endif if ( !isEyeOfTheBeholder ) @@ -2199,3 +2235,205 @@ void efPollingHandler() OUTPUT_LATCH_AND_FINISH_BUS_HANDLING } } + + + + + + + + + + + + + + + + +static void KernelMDOnlyFIQHandler( void *pParam ) +{ + register u32 D, addr; + register u8 *flashBankR = ef.flashBank; + + // after this call we have some time (until signals are valid, multiplexers have switched, the RPi can/should read again) + START_AND_READ_ADDR0to7_RW_RESET_CS + + // we got the A0..A7 part of the address which we will access + addr = GET_ADDRESS0to7 << 5; + + CACHE_PRELOADL2STRM( &flashBankR[ addr * 2 ] ); + UPDATE_COUNTERS_MIN( ef.c64CycleCount, ef.resetCounter2 ) + + // + // + // + if ( ef.reg2 != 4 && VIC_HALF_CYCLE ) + { + WAIT_AND_READ_ADDR8to12_ROMLH_IO12_BA +// READ_ADDR0to7_RW_RESET_CS_AND_MULTIPLEX +// WAIT_AND_READ_ADDR8to12_ROMLH_IO12_BA_VIC2 + + addr |= GET_ADDRESS8to12; + + if ( ROML_OR_ROMH_ACCESS ) + { + // get both ROML and ROMH with one read + D = *(u32*)&flashBankR[ addr * 2 ]; + if ( ROMH_ACCESS ) D >>= 8; + WRITE_D0to7_TO_BUS_VIC( D ) + setLatchFIQ( LED_ROM_ACCESS ); + } else + if ( IO2_ACCESS && ( ef.bankswitchType == BS_EASYFLASH ) ) + { + WRITE_D0to7_TO_BUS_VIC( ef.ram[ GET_IO12_ADDRESS ] ); + setLatchFIQ( LED_IO2 ); + } else + if ( IO1_ACCESS && ( ef.bankswitchType == BS_EASYFLASH ) ) + { + WRITE_D0to7_TO_BUS_VIC( easyflash_IO1_Read( GET_IO12_ADDRESS ) ); + setLatchFIQ( LED_IO1 ); + } + + FINISH_BUS_HANDLING + return; + } + + ef.mainloopCount = 0; + + // read the rest of the signals + WAIT_AND_READ_ADDR8to12_ROMLH_IO12_BA + + // make our address complete + addr |= GET_ADDRESS8to12; + + // VIC2 read during badline? + if ( ef.reg2 != 4 && VIC_BADLINE ) + { + if ( !ef.LONGBOARD ) + READ_ADDR8to12_ROMLH_IO12_BA + + if ( ROMH_ACCESS ) + { + if ( ef.bankswitchType == BS_MAGICDESK ) + D = *(u32*)&flashBankR[ addr ]; else + D = *(u8*)&flashBankR[ addr * 2 + 1 ]; + WRITE_D0to7_TO_BUS_BADLINE( D ) + } + FINISH_BUS_HANDLING + return; + } + + // + // starting from here: CPU communication + // + if ( ef.reg2 != 4 && CPU_READS_FROM_BUS ) + { + if ( ( ~g3 & ef.ROM_LH ) ) + { + D = *(u32*)&flashBankR[ addr ]; + + WRITE_D0to7_TO_BUS( D ) + setLatchFIQ( LED_ROM_ACCESS ); + goto cleanup; + } + } + + if ( ef.reg2 != 4 && CPU_WRITES_TO_BUS && IO1_ACCESS ) + { + READ_D0to7_FROM_BUS( D ) + + if( GET_IO12_ADDRESS == 0 ) + { + if ( !( D & 128 ) ) + { + if ( ef.nBanks <= 64 ) + ef.reg0 = (u8)( D & 63 ); else + ef.reg0 = (u8)( D & 127 ); + ef.reg2 = 128 + 4 + 2; + } else + ef.reg2 = 4 + 0; + } + + ef.flashBank = &ef.flash_cacheoptimized[ ef.reg0 * 8192 ]; + + // if the EF-ROM does not fit into the RPi's cache: stall the CPU with a DMA and prefetch the data + if ( !ef.flashFitsInCache ) + { + WAIT_UP_TO_CYCLE( WAIT_TRIGGER_DMA ); + CLR_GPIO( bDMA ); + ef.releaseDMA = NUM_DMA_CYCLES; + prefetchHeuristic(); + } + + setGAMEEXROM(); + + setLatchFIQ( LED_IO1 ); + goto cleanup; + } + + // reset handling + if ( !( g2 & bRESET ) ) { ef.resetCounter ++; } else { ef.resetCounter = 0; } + + if ( ef.resetCounter > 3 && ef.resetCounter < 0x8000000 ) + { + ef.resetCounter = 0x8000000; + initEF(); + SET_GPIO( bDMA ); + FINISH_BUS_HANDLING + return; + } + +cleanup: + + if ( ef.releaseDMA > 0 && --ef.releaseDMA == 0 ) + { + WAIT_UP_TO_CYCLE( WAIT_RELEASE_DMA ); + SET_GPIO( bDMA ); + } + + if ( ef.reg2 == 4 ) // cartridge disabled (like this because of my mapping of MD to EF) + { + if ( showSlideShow ) + { + if ( pauseSlideShow ) + { + pauseSlideShow --; + } else + if ( bufferEmptyI2C() ) + { + extern void setMultiplePixels( u32 x, u32 y, u32 nx, u32 ny, u16 *c ); + setMultiplePixels( curCopyRow, 0, 0, 239, (u16 *)&tftSlideShow[ (curSlideShowImage * 240 + curCopyRow ) * 240 * 2 ] ); + + do { + curPixelRow ++; + if ( curPixelRow > 255 ) + { + curPixelRow = 0; + pauseSlideShow = (u32)timeSlideShow[ tftSlideShowNImages - 1 - curSlideShowImage ] * 500000 * 2; + curSlideShowImage = ( curSlideShowImage + tftSlideShowNImages - 1 ) % tftSlideShowNImages; + } + curCopyRow = flipByte( curPixelRow ); + } while ( curCopyRow >= 240 ); + } + } + + prepareOutputLatch4Bit(); + } + +/* if ( bufferEmptyI2C() ) + { + if ( mode & 1 ) + setLatchFIQ( LATCH_LED0 ); + if (!( mode & 1 )) + setLatchFIQ( LATCH_LED1 ); + }*/ + + + //CLEAR_LEDS_EVERY_8K_CYCLES + static u32 cycleCount = 0; + if ( !((++cycleCount)&8191) ) + clrLatchFIQ( LED_CLEAR ); + + OUTPUT_LATCH_AND_FINISH_BUS_HANDLING +} diff --git a/Source/Firmware/kernel_launch.cpp b/Source/Firmware/kernel_launch.cpp index 6e47c750..2852ea53 100644 --- a/Source/Firmware/kernel_launch.cpp +++ b/Source/Firmware/kernel_launch.cpp @@ -36,7 +36,7 @@ static const char FILENAME[] = "SD:C64/test.prg"; // .PRG to start static const bool c128PRG = false; #endif static const char FILENAME_CBM80[] = "SD:C64/launch.cbm80"; // launch code (CBM80 8k cart) -static const char FILENAME_CBM80_NOINIT[] = "SD:C64/launch_noinit.cbm80"; // launch code (CBM80 8k cart) +static const char FILENAME_CBM80_NOINIT[] = "SD:C64/launch_noinit.cbm80"; // launch code (CBM80 8k cart) static const char FILENAME_CBM128[] = "SD:C64/launch128.cbm80"; // launch code (C128 cart) static const char FILENAME_SPLASH_RGB[] = "SD:SPLASH/sk64_launch.tga"; @@ -99,6 +99,14 @@ void prepareOnReset( bool refresh = false ) static u32 nBytesRead, stage; +static u8 showSlideShow = 0; +static u8 curSlideShowImage = 0; +static u16 curPixelRow = 0; +static u16 curCopyRow = 0; +static u32 pauseSlideShow = 0; +static u8 timeSlideShow[ 32 ]; + + #ifdef COMPILE_MENU void KernelLaunchRun( CGPIOPinFIQ m_InputPin, CKernelMenu *kernelMenu, const char *FILENAME, bool hasData = false, u8 *prgDataExt = NULL, u32 prgSizeExt = 0, u32 c128PRG = 0, u32 playingPSID = 0, u8 noInitStartup = 0 ) #else @@ -129,15 +137,19 @@ void CKernelLaunch::Run( void ) #ifdef COMPILE_MENU _playingPSID = playingPSID; + showSlideShow = 0; + tftSlideShowNImages = 0; + if ( screenType == 0 ) { splashScreen( sidekick_launch_oled ); } else if ( screenType == 1 ) { - char fn[ 1024 ]; + char fn[ 1024 ];//, fnslide[ 1024*2 ]; // attention: this assumes that the filename ending is always ".crt"! memset( fn, 0, 1024 ); + strncpy( fn, FILENAME, strlen( FILENAME ) - 4 ); strcat( fn, ".tga" ); @@ -162,6 +174,25 @@ void CKernelLaunch::Run( void ) tftCopyBackground2Framebuffer(); } + memset( fn, 0, 1024 ); + strncpy( fn, FILENAME, strlen( FILENAME ) - 4 ); + strcat( fn, "-slideshow.tga" ); + + if ( tftLoadSlideShowTGA( DRIVE, fn ) && tftSlideShowNImages > 0 ) + { + showSlideShow = 1; + curSlideShowImage = tftSlideShowNImages - 1; + curCopyRow = curPixelRow = 0; + pauseSlideShow = 0; + + fn[ strlen( fn ) - 3 ] = 0; + strcat( fn, "time" ); + u32 size = 0; + for ( u32 i = 0; i < 32; i++ ) + timeSlideShow[ i ] = 10; + readFile( logger, DRIVE, fn, timeSlideShow, &size, 32 ); + } + tftInitImm(); tftSendFramebuffer16BitImm( tftFrameBuffer ); } @@ -326,6 +357,36 @@ void CKernelLaunch::FIQHandler (void *pParam) } OUTPUT_LATCH_AND_FINISH_BUS_HANDLING return; + } else + { + if ( showSlideShow ) + { + if ( pauseSlideShow ) + { + pauseSlideShow --; + } else + if ( bufferEmptyI2C() ) + { + extern void setMultiplePixels( u32 x, u32 y, u32 nx, u32 ny, u16 *c ); + setMultiplePixels( curCopyRow, 0, 0, 239, (u16 *)&tftSlideShow[ (curSlideShowImage * 240 + curCopyRow ) * 240 * 2 ] ); + + do { + curPixelRow ++; + if ( curPixelRow > 255 ) + { + curPixelRow = 0; + pauseSlideShow = (u32)timeSlideShow[ tftSlideShowNImages - 1 - curSlideShowImage ] * 500000; + curSlideShowImage = ( curSlideShowImage + tftSlideShowNImages - 1 ) % tftSlideShowNImages; + } + curCopyRow = flipByte( curPixelRow ); + } while ( curCopyRow >= 240 ); + } + } + + prepareOutputLatch4Bit(); + outputLatch(); + OUTPUT_LATCH_AND_FINISH_BUS_HANDLING + return; } } diff --git a/Source/Firmware/kernel_menu.cpp b/Source/Firmware/kernel_menu.cpp index 8fabd8b3..f2e5611f 100644 --- a/Source/Firmware/kernel_menu.cpp +++ b/Source/Firmware/kernel_menu.cpp @@ -2050,7 +2050,7 @@ int main( void ) }*/ /* for debugging purposes only*/ - /*if ( launchKernel == 255 ) +/* if ( launchKernel == 255 ) { reboot (); } else*/ diff --git a/Source/Firmware/tft_st7789.cpp b/Source/Firmware/tft_st7789.cpp index c087bb8c..acc52fce 100644 --- a/Source/Firmware/tft_st7789.cpp +++ b/Source/Firmware/tft_st7789.cpp @@ -225,15 +225,15 @@ void tftInitDisplay() flush4BitBuffer( true ); delay( 100 ); } -void tftSetPartial( u8 s, u8 e ) -{ - tftCommandImm( 0x12 ); - tftCommandImm( 0x30 ); - tftSendDataImm( 0 ); - tftSendDataImm( s ); - tftSendDataImm( 0 ); - tftSendDataImm( e ); -} +void tftSetPartial( u8 s, u8 e ) +{ + tftCommandImm( 0x12 ); + tftCommandImm( 0x30 ); + tftSendDataImm( 0 ); + tftSendDataImm( s ); + tftSendDataImm( 0 ); + tftSendDataImm( e ); +} void tftInitDisplayImm() { @@ -280,51 +280,51 @@ void tftInitDisplayImm() delay( 100 ); } -void tftReInitDisplayImm() -{ - TFTimm_SDA_LOW - TFT_SDA_LOW - lastBit = 0; - TFTimm_SCK_HIGH - TFTimm_DC_HIGH - - tftCommandImm( 0x34 ); // tearing off - delay( 500 ); - - tftCommandImm( 0x38 ); // idle mode off - delay( 500 ); - tftCommandImm( 0x13 ); // partial off - delay( 500 ); - tftCommandImm( 0x11 ); // quit sleep mode - delay( 500 ); - - tftCommandImm( 0x3A, 0x05 ); // 16-bit color mode - tftCommandImm( 0x20 + invert ); // invert - tftCommandImm( 0x36, rotate << 5 ); // orientation - - tftCommandImm( 0x26, 0 ); - - tftCommandImm( 0xe0 ); - for ( int i = 0; i < 14; i++ ) - tftSendDataImm( posGamma[ i ] ); - - tftCommandImm( 0xe1 ); - for ( int i = 0; i < 14; i++ ) - tftSendDataImm( negGamma[ i ] ); - - tftCommandImm( 0xba, 4 ); - - tftCommandImm( 0xe2 ); // red gamma lut - for ( int i = 0; i < 64; i++ ) - tftSendDataImm( i * 4 ); - - tftCommandImm( 0xe3 ); // blue gamma lut - for ( int i = 0; i < 64; i++ ) - tftSendDataImm( i * 4 ); - - tftCommandImm( 0x29 ); // display on - delay( 100 ); -} +void tftReInitDisplayImm() +{ + TFTimm_SDA_LOW + TFT_SDA_LOW + lastBit = 0; + TFTimm_SCK_HIGH + TFTimm_DC_HIGH + + tftCommandImm( 0x34 ); // tearing off + delay( 500 ); + + tftCommandImm( 0x38 ); // idle mode off + delay( 500 ); + tftCommandImm( 0x13 ); // partial off + delay( 500 ); + tftCommandImm( 0x11 ); // quit sleep mode + delay( 500 ); + + tftCommandImm( 0x3A, 0x05 ); // 16-bit color mode + tftCommandImm( 0x20 + invert ); // invert + tftCommandImm( 0x36, rotate << 5 ); // orientation + + tftCommandImm( 0x26, 0 ); + + tftCommandImm( 0xe0 ); + for ( int i = 0; i < 14; i++ ) + tftSendDataImm( posGamma[ i ] ); + + tftCommandImm( 0xe1 ); + for ( int i = 0; i < 14; i++ ) + tftSendDataImm( negGamma[ i ] ); + + tftCommandImm( 0xba, 4 ); + + tftCommandImm( 0xe2 ); // red gamma lut + for ( int i = 0; i < 64; i++ ) + tftSendDataImm( i * 4 ); + + tftCommandImm( 0xe3 ); // blue gamma lut + for ( int i = 0; i < 64; i++ ) + tftSendDataImm( i * 4 ); + + tftCommandImm( 0x29 ); // display on + delay( 100 ); +} void tftUse12BitColor() { @@ -591,7 +591,10 @@ unsigned char rgbChars[ 256 * 16 * 16 ]; unsigned char tftBackground[ 240 * 240 * 2 ]; unsigned char tftFrameBuffer[ 240 * 240 * 2 ]; unsigned char tftFrameBuffer12Bit[ 240 * 240 * 3 / 2 ]; -unsigned char tempTGA[ 256 * 256 * 4 ]; +unsigned char tempTGA[ 256 * 256 * 4 ]; + +u8 tftSlideShowNImages = 0; +unsigned char tftSlideShow[ 240 * 240 * 2 * 32 ]; #define DIRTY_SIZE 4 unsigned char tftDirty[ (240/DIRTY_SIZE) * (240/DIRTY_SIZE) ]; @@ -804,6 +807,66 @@ int tftLoadBackgroundTGA( const char *drive, const char *name, int dither ) } +// loads a 24/32-bit, uncompressed Targa file +// height expected to be a multiple of 240 +int tftLoadSlideShowTGA( const char *drive, const char *name, int dither ) +{ + tftSlideShowNImages = 0; + + int imgWidth, imgHeight; + + memset( tftSlideShow, 0, 240 * 240 * 32 * 2 ); + + u8 tga[ 256 * 256 * 4 * 32 ]; + u32 size; + extern CLogger *logger; + if ( readFile( logger, (char*)drive, name, tga, &size ) ) + { + unsigned char *type = &tga[ 0 ]; + if ( type[ 1 ] != 0 || ( type[ 2 ] != 2 && type[ 2 ] != 3 ) ) + return 0; + + unsigned char *info = &tga[ 12 ]; + imgWidth = info[ 0 ] + info[ 1 ] * 256; + imgHeight = info[ 2 ] + info[ 3 ] * 256; + int imgBits = info[ 4 ]; + + tftSlideShowNImages = imgHeight / 240; + + if ( ( imgBits != 32 && imgBits != 24 ) || tftSlideShowNImages == 0 || imgWidth != 240 || (imgHeight % 240) != 0 ) + return -1; + + int bytesPerPixel = imgBits / 8; + + size = imgWidth * imgHeight; + + u32 yp = 0; + u32 ofs = 0; + for ( int j = 0; j < imgHeight; j++ ) + { + u32 xp = 0; + for ( int i = 0; i < min( 240, imgWidth ) * bytesPerPixel; i += bytesPerPixel ) + { + unsigned char *p = &tga[ i + 0 + 18 + j * imgWidth * bytesPerPixel ]; + + /*if ( dither ) + for ( int c = 0; c < 3; c++ ) + p[ c ] = ditherColor( p[ c ], i, j, dither );*/ + + u32 t = yp % 240; + u32 ny = yp - t + ( 239 - t); + ofs = ( xp + ny * 240 ) * 2; + *(unsigned short*)&tftSlideShow[ ofs ] = rgb24to16( p[2], p[1], p[0] ); + xp ++; + } + yp ++; + } + return 1; + } + return 0; +} + + void tftLoadCharset( const char *drive, const char *name ) { u32 size; diff --git a/Source/Firmware/tft_st7789.h b/Source/Firmware/tft_st7789.h index 4c44617e..ed3adb8a 100644 --- a/Source/Firmware/tft_st7789.h +++ b/Source/Firmware/tft_st7789.h @@ -40,14 +40,17 @@ #include "latch.h" #include "helpers.h" +extern u8 tftSlideShowNImages; +extern unsigned char tftSlideShow[ 240 * 240 * 2 * 32 ]; + extern u32 rgb( u32 r, u32 g, u32 b ); extern void tftSendFramebuffer16BitImm(); extern void tftUse12BitColor(); extern void tftUse16BitColor(); extern void setDoubleWPixel12( u32 x, u32 y, u32 c ); -extern void tftCommandImm( u8 c ); -extern void tftCommandImm( u8 c, u8 d ); +extern void tftCommandImm( u8 c ); +extern void tftCommandImm( u8 c, u8 d ); extern void tftSplashScreen( const u8 *fb ); extern int tftSplashScreenFile( const char *drive, const char *fn ); @@ -58,13 +61,14 @@ extern unsigned char tftFrameBuffer12Bit[ 240 * 240 * 3 / 2 ]; extern void tftSendFramebuffer16BitImm( const u8 *raw ); extern void tftSendFramebuffer12BitImm( const u8 *raw ); -extern void tftSetPartial( u8 s, u8 e ); +extern void tftSetPartial( u8 s, u8 e ); extern void tftInit( int rot = -1 ); extern void tftInitImm( int rot = -1 ); extern u32 rgb24to16( u32 r, u32 g, u32 b ); extern int tftLoadTGA( const char *drive, const char *name, unsigned char *dst, int *imgWidth, int *imgHeight, int wantAlpha ); extern int tftLoadBackgroundTGA( const char *drive, const char *name, int dither = 0 ); +extern int tftLoadSlideShowTGA( const char *drive, const char *name, int dither = 0 ); extern void tftConvertFrameBuffer12Bit(); extern void tftBlendRGBA( unsigned char *rgba, unsigned char *dst, int dither = 0 ); extern void tftBlendRGBA( u32 r_, u32 g_, u32 b_, u32 a, unsigned char *dst, int dither );