1 /*---------------------------------------------------------------------------* 2 Project: Horizon 3 File: FsSecureSaveSample.cpp 4 5 Copyright (C)2009-2012 Nintendo Co., Ltd. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain 8 proprietary information of Nintendo of America Inc. and/or Nintendo 9 Company Ltd., and are protected by Federal copyright law. They may 10 not be disclosed to third parties or copied or duplicated in any form, 11 in whole or in part, without the prior written consent of Nintendo. 12 13 $Rev: 46547 $ 14 *---------------------------------------------------------------------------*/ 15 16 #ifndef NN_SAMPLE_DEMOS_FS_SAMPLE_SECURE_SAVE_H_ 17 #define NN_SAMPLE_DEMOS_FS_SAMPLE_SECURE_SAVE_H_ 18 19 namespace sample { namespace fs { namespace streaming { 20 21 const char SAVE_DATA_ARCHIVE[] = "data:"; 22 const char DATA_FILE_NAME[] = "data:/Data"; 23 24 const int MAX_PATH_LENGTH = 255; 25 26 const char EXT_ARCHIVE[] = "ext:"; 27 const wchar_t MEMO_FILE_NAME[] = L"ext:/Memo"; 28 const bit64 EXT_SAVEDATA_ID = 0xFFFFF; 29 const int MEMO_FILE_NUM_MAX = 64; 30 31 // Size of the region where recording can be done. 32 // 33 // Because the archive that saves streaming in this sample is expanded save data, the guaranteed overhead is 2000 ms when saving, and the write speed is 0.5 mb/s. 34 // 35 // The size of the region that can be saved each frame must be calculated from these values. 36 // 37 // Here, the byte size that must be recorded each second is x[MB/s], the single side buffer size is y[MB], and the time to switch buffers is t[s]. 38 // 39 // Given that: 40 // 2 + x * t / 0.5 < t 41 // x * t = y 42 // conditions need to be satisfied. 43 // Transforming this simultaneous inequality gives: 44 // 2 + y / 0.5 < y / x 45 // Analyzing the above with a buffer size y of 4[MB] gives x < 0.4[MB/s]. 46 // 47 // 48 // From the fact that 1 byte is 8 pixels because 60 frames per second and binary, black/white, are used 49 // The number of pixels per frame is: 50 // 0.4[MB/s] / 60[frame/s] * 8[pixel/B] = 53333[pixel/frame]. 51 // 52 // From the above, the size of the render region is 264 pixels wide by 200 pixels high. 53 const int MEMO_WIDTH = 264; 54 const int MEMO_HEIGHT = 200; 55 const int MEMO_BLANK_WIDTH = NN_GX_DISPLAY1_HEIGHT - MEMO_WIDTH; 56 const int MEMO_BLANK_HEIGHT = NN_GX_DISPLAY1_WIDTH - MEMO_HEIGHT; 57 const int MEMO_X = MEMO_BLANK_WIDTH / 2; 58 const int MEMO_Y = MEMO_BLANK_HEIGHT / 2; 59 60 61 // This constant is used when rendering textures. 62 const int TEXTURE_BLOCK_SIZE = 8; 63 const int MEMO_TEXTURE_WIDTH = 512; 64 const int MEMO_TEXTURE_HEIGHT = 256; 65 66 // With this sample, because textures are rendered directly, both the height and width must be a integer multiple of TEXTURE_BLOCK_SIZE. 67 // 68 NN_STATIC_ASSERT(MEMO_WIDTH % TEXTURE_BLOCK_SIZE == 0); 69 NN_STATIC_ASSERT(MEMO_HEIGHT % TEXTURE_BLOCK_SIZE == 0); 70 71 // The number of bytes for the buffer required for each frame. 72 const int MEMO_BUFFER_SIZE = MEMO_WIDTH * MEMO_HEIGHT / 8; 73 74 // Number of frames stored with the single side buffer. 75 const int BUFFERING_FRAME_NUM = 600; 76 77 // Number of bytes for the buffer for each side. 78 // Each of the front buffer and back buffers are prepared with this size. 79 const int BUFFER_SIZE = MEMO_BUFFER_SIZE * BUFFERING_FRAME_NUM; // Corresponds to y in the equation. 80 81 // Number of longest frames that can be recorded continuously. 3 minutes is specified. 82 // This is used only for determining the size when creating a file for the first time and does not define the length of the temporary buffer for streaming. 83 // 84 const int RECORDABLE_FRAME_NUM_MAX = 3 * 60 * 60; 85 86 // Size of the file where each movie is recorded. 87 const s64 MAX_MEMO_FILE_SIZE = MEMO_BUFFER_SIZE * RECORDABLE_FRAME_NUM_MAX; 88 89 #define RETURN_IF_FAILED_BASE(result, s1) \ 90 do \ 91 { \ 92 ::nn::Result macro_return_if_failure_result = (result); \ 93 if (macro_return_if_failure_result.IsFailure()) \ 94 { \ 95 s1;\ 96 return macro_return_if_failure_result; \ 97 } \ 98 } while(0) 99 100 #define RETURN_IF_FAILED(result) RETURN_IF_FAILED_BASE(result,) 101 #define RETURN_IF_FAILED_1(result, c1) RETURN_IF_FAILED_BASE(result,c1) 102 103 struct Header 104 { 105 s64 size; 106 }; 107 108 struct SaveData 109 { 110 s32 data[1024]; 111 }; 112 113 struct PacketData 114 { 115 private: 116 bit8 *data; 117 s32 size; 118 nn::os::BlockingQueue &returnQueue; 119 120 public: PacketDataPacketData121 PacketData(bit8 *_data, s32 _size, nn::os::BlockingQueue &_returnQueue) : 122 data(_data), size(_size), returnQueue(_returnQueue) 123 {} 124 GetDataPacketData125 bit8 *GetData() { return data; } GetSizePacketData126 s32 GetSize() { return size; } 127 FreePacketData128 void Free() 129 { 130 returnQueue.Enqueue(reinterpret_cast<uptr>(this)); 131 } 132 }; 133 134 enum ENUM_RECORDING_RESULT 135 { 136 RECORDING_RESULT_SUCCESS, 137 RECORDING_RESULT_BUFFER_FULL, 138 RECORDING_RESULT_FILE_FULL 139 }; 140 141 bool LoadMemo(PacketData **pOut); 142 ENUM_RECORDING_RESULT SaveMemo(const bit8 *srcBuffer); 143 nn::Result StartRecording(const wchar_t *fileName); 144 nn::Result StopRecording(); 145 nn::Result StartPlaying(const wchar_t *fileName); 146 nn::Result StopPlaying(); 147 nn::Result FinishPlaying(); 148 nn::Result BgSave(const s32 data); 149 nn::Result BgLoad(s32 &data); 150 151 }}} 152 153 #endif 154