/*---------------------------------------------------------------------------* Project: TwlSDK - tcl - demos.TWL - tcl-2 File: main.c Copyright 2008-2009 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Date:: 2009-06-04#$ $Rev: 10698 $ $Author: okubata_ryoma $ *---------------------------------------------------------------------------*/ #include #include #include #include #include "DEMO.h" #include "screen.h" /*---------------------------------------------------------------------------* Constant Definitions *---------------------------------------------------------------------------*/ #define BMP_HEADER_SIZE 54 // Header size for Windows bitmap (BMP) file /*---------------------------------------------------------------------------* Internal Functions and Definitions *---------------------------------------------------------------------------*/ void VBlankIntr(void); void Print(void); void BMPToRGB( const u8* p_bmp, u16* p_rgb ); /*---------------------------------------------------------------------------* Internal Variable Definitions *---------------------------------------------------------------------------*/ int state = 0; int num_pict = 0; int rest_pict = 0; /*---------------------------------------------------------------------------* Name: VBlankIntr Description: V-Blank interrupt handler. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ void VBlankIntr(void) { OS_SetIrqCheckFlag( OS_IE_V_BLANK ); } /*---------------------------------------------------------------------------* Name: Print Description: Renders debug information. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ void Print(void) { ClearScreen(); PutScreen(0, 0, 0xff, "TCL-2 Write Picture Demo"); PutScreen(2, 4, 0xff, "Num Pictures : %d", num_pict ); PutScreen(2, 3, 0xff, "Rest Num Pictures : %d", rest_pict ); switch( state ) { case 0: PutScreen( 1, 8, 0xff, "A Button > Write Picture" ); break; case 1: PutScreen( 1, 8, 0xff, "Now Writing..." ); break; case 2: PutScreen( 1, 8, 0xff, "Finish!" ); break; case 3: PutScreen( 1, 8, 0xff, "Not enable Write Picture" ); break; } } /*---------------------------------------------------------------------------* Name: BMPToRGB Description: Converts 24-bit BMP to RGB555 format. Arguments: p_bmp: Original bitmap image p_rgb: New RGB image Returns: None. *---------------------------------------------------------------------------*/ void BMPToRGB( const u8* p_bmp, u16* p_rgb ) { int h, w; int b, g, r; for ( h = 0; h < TCL_JPEG_HEIGHT; ++h ) { for ( w = 0; w < TCL_JPEG_WIDTH; ++w ) { b = ( p_bmp[ 3 * ( h * TCL_JPEG_WIDTH + w ) + 0 ] >> 3 ) & 0x1f; g = ( p_bmp[ 3 * ( h * TCL_JPEG_WIDTH + w ) + 1 ] >> 3 ) & 0x1f; r = ( p_bmp[ 3 * ( h * TCL_JPEG_WIDTH + w ) + 2 ] >> 3 ) & 0x1f; p_rgb[ ( TCL_JPEG_HEIGHT - h - 1 ) * TCL_JPEG_WIDTH + w ] = (u16)( 0x8000 | ( b << GX_RGBA_B_SHIFT ) | ( g << GX_RGBA_G_SHIFT ) | ( r << GX_RGBA_R_SHIFT ) ); } } } /*---------------------------------------------------------------------------* Name: TwlMain Description: Main. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ void TwlMain(void) { OSHeapHandle handle; void* nstart; void* pTableBuf; void* pWorkBuf; FSResult fs_result; TCLResult result; // TCL accessor TCLAccessor accessor; // Search condition object TCLSearchObject search_obj; BOOL write_enable = TRUE; int count; // Initialization process DEMOInitCommon(); DEMOInitVRAM(); OS_InitTick(); OS_InitAlarm(); RTC_Init(); FS_Init( FS_DMA_NOT_USE ); InitScreen(); ClearScreen(); // GX-related settings GX_SetBankForBG( GX_VRAM_BG_128_A ); GX_SetGraphicsMode( GX_DISPMODE_GRAPHICS, GX_BGMODE_3, GX_BG0_AS_2D ); GX_SetVisiblePlane( GX_PLANEMASK_BG3 ); G2_SetBG3Priority( 0 ); G2_BG3Mosaic( FALSE ); G2_SetBG3ControlDCBmp( GX_BG_SCRSIZE_DCBMP_256x256, GX_BG_AREAOVER_XLU, GX_BG_BMPSCRBASE_0x00000 ); // Create heap nstart = OS_InitAlloc( OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1 ); OS_SetMainArenaLo( nstart ); handle = OS_CreateHeap( OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi() ); if (handle < 0) { OS_Panic("ARM9: Fail to create heap..."); } handle = OS_SetCurrentHeap( OS_ARENA_MAIN, handle ); // TCL initialization // 32-byte alignment necessary pTableBuf = OS_Alloc( TCL_GetTableBufferSize() ); pWorkBuf = OS_Alloc( TCL_GetWorkBufferSize() ); if( pTableBuf == NULL || pWorkBuf == NULL ) { OS_Panic("Cannot allocate memory!"); } result = TCL_LoadTable( &accessor, pTableBuf, TCL_GetTableBufferSize(), pWorkBuf, TCL_GetWorkBufferSize(), &fs_result ); #if 1 // End the following processes when loading of the management file fails if ( result != TCL_RESULT_SUCCESS ) { // For other errors, prompt Nintendo DSi camera startup and end the process //OS_TPrintf ("appropriate text here") OS_Panic("failed TCL_LoadTable : %d\n", result ); } #else // Try recovering if loading of the management file failed switch( result ) { case TCL_RESULT_SUCCESS: break; // Success case TCL_RESULT_ERROR_EXIST_OTHER_FILE: case TCL_RESULT_ERROR_ALREADY_MANAGED: OS_TPrintf("failed TCL_LoadTable : %d\n", result ); // Recalculate the next save location because no write-out processing can be carried out result = TCL_RepairTable( &accessor, &fs_result ); if( result != TCL_RESULT_SUCCESS ) { OS_TPrintf("failed TCL_RepairTable : %d\n", result ); // Recreate the management file because the state does not allow image write-outs result = TCL_CreateTable( &accessor, pTableBuf, TCL_GetTableBufferSize(), pWorkBuf, TCL_GetWorkBufferSize(), &fs_result ); switch( result ) { case TCL_RESULT_SUCCESS: // Table successfully created break; case TCL_RESULT_ERROR_OVER_NUM_PICTURES: // More than 500 photos present, but table successfully created OS_TPrintf("failed TCL_CreateTable : %d", result ); break; case TCL_RESULT_ERROR_NO_NEXT_INDEX: // Error indicates no save possible, but continuation possible write_enable = FALSE; OS_TPrintf("failed TCL_CreateTable : %d", result ); break; default: // Continuation impossible error OS_Panic("failed TCL_CreateTable : %d", result ); break; } } break; default: OS_TPrintf("failed TCL_LoadTable : %d\n", result ); // The management file is recreated because read processing cannot be carried out result = TCL_CreateTable( &accessor, pTableBuf, TCL_GetTableBufferSize(), pWorkBuf, TCL_GetWorkBufferSize(), &fs_result ); switch( result ) { case TCL_RESULT_SUCCESS: break; case TCL_RESULT_ERROR_OVER_NUM_PICTURES: OS_TPrintf("failed TCL_CreateTable : %d", result ); break; case TCL_RESULT_ERROR_NO_NEXT_INDEX: write_enable = FALSE; OS_TPrintf("failed TCL_CreateTable : %d", result ); break; default: OS_Panic("failed TCL_CreateTable : %d", result ); break; } break; } #endif // How many more photos can be saved? rest_pict = TCL_CalcNumEnableToTakePictures( &accessor ); // Initialize SearchObject TCL_InitSearchObject( &search_obj, TCL_SEARCH_CONDITION_PICTURE ); // How many photos in all? num_pict = TCL_GetNumPictures( &accessor, &search_obj ); Print(); DEMOStartDisplay(); // Updates text display UpdateScreen(); while (1) { // Reading pad information and controls DEMOReadKey(); if( DEMO_IS_TRIG( PAD_BUTTON_A ) ) { if( rest_pict == 0 || !write_enable ) { // Cannot save more than this count = 0; state = 3; Print(); } else if( state == 0 ) { count = 0; ++state; Print(); } } else if( state == 1 ) { // Buffer storing JPEG images u8* pJpegBuf = NULL; u8* pData = NULL; u8* pTmpBuf = NULL; u16* pRGBBuf = NULL; u32 length; FSFile file; const u32 option = SSP_JPEG_THUMBNAIL | SSP_JPEG_RGB555; // Get BMP image FS_InitFile( &file ); if( !FS_OpenFileEx( &file, "rom:/demo.bmp", FS_FILEMODE_R ) ) { OS_Panic("failed FS_OpenFileEx : %d ", FS_GetResultCode( &file ) ); } length = FS_GetFileLength( &file ); pData = OS_Alloc( length ); if( pData == NULL ) { OS_Panic("Cannot allocate memory ... pData!"); } if( FS_ReadFile( &file, pData, (s32)length ) == -1 ) { OS_Panic("failed FS_ReadFile"); } ( void ) FS_CloseFile( &file ); pData += BMP_HEADER_SIZE; // Convert BMP image to RGB555 format pRGBBuf = OS_Alloc( TCL_JPEG_WIDTH * TCL_JPEG_HEIGHT * sizeof(u16) ); if( pRGBBuf == NULL ) { OS_Panic("Cannot allocate memory ... pRGBBuf!"); } BMPToRGB( pData, pRGBBuf ); pData -= BMP_HEADER_SIZE; OS_Free( pData ); // JPEG encoding length = TCL_GetJpegEncoderBufferSize( option ); pTmpBuf = OS_Alloc( length ); if( pTmpBuf == NULL ) { OS_Panic("Cannot allocate memory ... pTmpBuf!"); } OS_TPrintf("SSP_GetJpegEncoderBufferSize() = %d\n", length ); pJpegBuf = OS_Alloc( TCL_MAX_JPEG_SIZE ); if( pJpegBuf == NULL ) { OS_Panic("Cannot allocate memory ... pJpegBuf!"); } // Encode + Write result = TCL_EncodeAndWritePicture( &accessor, pRGBBuf , pJpegBuf, TCL_MAX_JPEG_SIZE , pTmpBuf , TCL_JPEG_DEFAULT_QUALITY , option , &fs_result ); if( result != TCL_RESULT_SUCCESS ) { OS_TPrintf("failed TCL_WritePicture : %d\n", result ); // Cannot save more than this if( result == TCL_RESULT_ERROR_NO_NEXT_INDEX ) write_enable = FALSE; } else { OS_TPrintf("success TCL_WritePicture! %s\n" , TCL_GetLastWrittenPicturePath() ); } OS_Free( pJpegBuf ); OS_Free( pTmpBuf ); OS_Free( pRGBBuf ); // How many more photos can be saved? rest_pict = TCL_CalcNumEnableToTakePictures( &accessor ); // How many photos in all? num_pict = TCL_GetNumPictures( &accessor, &search_obj ); ++state; Print(); } else if( state == 2 || state == 3 ) { ++count; if( count > 180 ) { state = 0; Print(); } } OS_WaitVBlankIntr(); // Updates text display UpdateScreen(); } OS_Free( pWorkBuf ); OS_Free( pTableBuf ); OS_Terminate(); }