/*---------------------------------------------------------------------------* Project: Horizon File: FsSecureSaveSample.cpp Copyright (C)2009-2012 Nintendo Co., Ltd. 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. $Rev: 46547 $ *---------------------------------------------------------------------------*/ #ifndef NN_SAMPLE_DEMOS_FS_SAMPLE_SECURE_SAVE_H_ #define NN_SAMPLE_DEMOS_FS_SAMPLE_SECURE_SAVE_H_ namespace sample { namespace fs { namespace streaming { const char SAVE_DATA_ARCHIVE[] = "data:"; const char DATA_FILE_NAME[] = "data:/Data"; const int MAX_PATH_LENGTH = 255; const char EXT_ARCHIVE[] = "ext:"; const wchar_t MEMO_FILE_NAME[] = L"ext:/Memo"; const bit64 EXT_SAVEDATA_ID = 0xFFFFF; const int MEMO_FILE_NUM_MAX = 64; // Size of the region where recording can be done. // // 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. // // The size of the region that can be saved each frame must be calculated from these values. // // 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]. // // Given that: // 2 + x * t / 0.5 < t // x * t = y // conditions need to be satisfied. // Transforming this simultaneous inequality gives: // 2 + y / 0.5 < y / x // Analyzing the above with a buffer size y of 4[MB] gives x < 0.4[MB/s]. // // // From the fact that 1 byte is 8 pixels because 60 frames per second and binary, black/white, are used // The number of pixels per frame is: // 0.4[MB/s] / 60[frame/s] * 8[pixel/B] = 53333[pixel/frame]. // // From the above, the size of the render region is 264 pixels wide by 200 pixels high. const int MEMO_WIDTH = 264; const int MEMO_HEIGHT = 200; const int MEMO_BLANK_WIDTH = NN_GX_DISPLAY1_HEIGHT - MEMO_WIDTH; const int MEMO_BLANK_HEIGHT = NN_GX_DISPLAY1_WIDTH - MEMO_HEIGHT; const int MEMO_X = MEMO_BLANK_WIDTH / 2; const int MEMO_Y = MEMO_BLANK_HEIGHT / 2; // This constant is used when rendering textures. const int TEXTURE_BLOCK_SIZE = 8; const int MEMO_TEXTURE_WIDTH = 512; const int MEMO_TEXTURE_HEIGHT = 256; // With this sample, because textures are rendered directly, both the height and width must be a integer multiple of TEXTURE_BLOCK_SIZE. // NN_STATIC_ASSERT(MEMO_WIDTH % TEXTURE_BLOCK_SIZE == 0); NN_STATIC_ASSERT(MEMO_HEIGHT % TEXTURE_BLOCK_SIZE == 0); // The number of bytes for the buffer required for each frame. const int MEMO_BUFFER_SIZE = MEMO_WIDTH * MEMO_HEIGHT / 8; // Number of frames stored with the single side buffer. const int BUFFERING_FRAME_NUM = 600; // Number of bytes for the buffer for each side. // Each of the front buffer and back buffers are prepared with this size. const int BUFFER_SIZE = MEMO_BUFFER_SIZE * BUFFERING_FRAME_NUM; // Corresponds to y in the equation. // Number of longest frames that can be recorded continuously. 3 minutes is specified. // 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. // const int RECORDABLE_FRAME_NUM_MAX = 3 * 60 * 60; // Size of the file where each movie is recorded. const s64 MAX_MEMO_FILE_SIZE = MEMO_BUFFER_SIZE * RECORDABLE_FRAME_NUM_MAX; #define RETURN_IF_FAILED_BASE(result, s1) \ do \ { \ ::nn::Result macro_return_if_failure_result = (result); \ if (macro_return_if_failure_result.IsFailure()) \ { \ s1;\ return macro_return_if_failure_result; \ } \ } while(0) #define RETURN_IF_FAILED(result) RETURN_IF_FAILED_BASE(result,) #define RETURN_IF_FAILED_1(result, c1) RETURN_IF_FAILED_BASE(result,c1) struct Header { s64 size; }; struct SaveData { s32 data[1024]; }; struct PacketData { private: bit8 *data; s32 size; nn::os::BlockingQueue &returnQueue; public: PacketData(bit8 *_data, s32 _size, nn::os::BlockingQueue &_returnQueue) : data(_data), size(_size), returnQueue(_returnQueue) {} bit8 *GetData() { return data; } s32 GetSize() { return size; } void Free() { returnQueue.Enqueue(reinterpret_cast(this)); } }; enum ENUM_RECORDING_RESULT { RECORDING_RESULT_SUCCESS, RECORDING_RESULT_BUFFER_FULL, RECORDING_RESULT_FILE_FULL }; bool LoadMemo(PacketData **pOut); ENUM_RECORDING_RESULT SaveMemo(const bit8 *srcBuffer); nn::Result StartRecording(const wchar_t *fileName); nn::Result StopRecording(); nn::Result StartPlaying(const wchar_t *fileName); nn::Result StopPlaying(); nn::Result FinishPlaying(); nn::Result BgSave(const s32 data); nn::Result BgLoad(s32 &data); }}} #endif