1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: dev_Screenshot.cpp
4
5 Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. 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 $Revision: 24950 $
14 *---------------------------------------------------------------------------*/
15
16 #include <nw/dev/dev_Screenshot.h>
17 #include <nn/gx.h>
18 #include <nw/os/os_Memory.h>
19
20 #if defined(NW_DEV_ENABLED) && defined(NW_PLATFORM_CTR)
21
22 namespace nw
23 {
24
25 namespace dev
26 {
27
28 //--------------------------------------------------------------------------
29 Screenshot*
Create(nw::os::IAllocator * allocator,size_t maxLength)30 Screenshot::Create(
31 nw::os::IAllocator* allocator,
32 size_t maxLength)
33 {
34 const int HASH_LENGTH = 20;
35
36 u32* hash = allocator->AllocAndFill(HASH_LENGTH, static_cast<u32>(0));
37 NW_NULL_ASSERT(hash);
38
39 NW_ASSERT(maxLength != 0);
40 u8* copyScreen = allocator->AllocAndFill(maxLength, static_cast<u8>(0));
41 NW_NULL_ASSERT(copyScreen);
42
43 void* memory = allocator->Alloc(sizeof(Screenshot));
44 NW_NULL_ASSERT(memory);
45
46 return new(memory) Screenshot(
47 allocator,
48 copyScreen,
49 maxLength,
50 hash);
51 }
52
53 //--------------------------------------------------------------------------
~Screenshot()54 Screenshot::~Screenshot()
55 {
56 if (this->m_Allocator)
57 {
58 if (this->m_CopyScreen)
59 {
60 (this->m_Allocator)->Free(this->m_CopyScreen);
61 }
62
63 if (this->m_Hash)
64 {
65 (this->m_Allocator)->Free(this->m_Hash);
66 }
67 }
68 }
69
70 //--------------------------------------------------------------------------
71 void
Set(const DisplayDescription & displayDescription,void * srcScreen,int length,int width,int height)72 Screenshot::Set(const DisplayDescription& displayDescription, void* srcScreen, int length, int width, int height)
73 {
74 std::memcpy(m_CopyScreen, srcScreen, length);
75 this->m_DisplayDescription = displayDescription;
76 this->m_Length = length;
77 this->m_Writed = true;
78 this->m_Width = width;
79 this->m_Height = height;
80
81 nn::crypto::CalculateSha1(this->m_Hash, m_CopyScreen, m_Length);
82 }
83
84 //--------------------------------------------------------------------------
85 void
DumpHash() const86 Screenshot::DumpHash() const
87 {
88 const char* DISPLAY_0 = "NN_GX_DISPLAY0 ";
89 const char* DISPLAY_0_EXT = "NN_GX_DISPLAY0EXT";
90 const char* DISPLAY_1 = "NN_GX_DISPLAY1 ";
91
92 const char* display;
93
94 switch (this->m_DisplayDescription.display)
95 {
96 case NN_GX_DISPLAY0:
97 display = DISPLAY_0;
98 break;
99 case NN_GX_DISPLAY0_EXT:
100 display = DISPLAY_0_EXT;
101 break;
102 case NN_GX_DISPLAY1:
103 display = DISPLAY_1;
104 break;
105 default:
106 NW_FATAL_ERROR("Unsupported display type");
107 }
108
109 NW_DEV_LOG("|%s|0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x|\n", display, m_Hash[0], m_Hash[1], m_Hash[2], m_Hash[3], m_Hash[4]);
110 }
111
112 //--------------------------------------------------------------------------
113 ScreenshotManager*
Create(nw::os::IAllocator * allocator,int maxScreenshot,int memorySize)114 ScreenshotManager::Create(
115 nw::os::IAllocator* allocator,
116 int maxScreenshot,
117 int memorySize
118 )
119 {
120 NW_UNUSED_VARIABLE(maxScreenshot);
121
122 void* memory = allocator->Alloc(sizeof(Screenshot));
123 ScreenshotArray screenshots = ScreenshotArray(maxScreenshot, allocator);
124
125 for (int i = 0; i < maxScreenshot; i++)
126 {
127 screenshots.push_back(Screenshot::Create(allocator, memorySize));
128 }
129
130 return new(memory) ScreenshotManager(allocator, screenshots);
131 }
132
133 //--------------------------------------------------------------------------
134 void
Destroy(nw::os::IAllocator * allocator)135 ScreenshotManager::Destroy(nw::os::IAllocator* allocator)
136 {
137 this->~ScreenshotManager();
138 allocator->Free(this);
139 }
140
141 //--------------------------------------------------------------------------
ScreenshotManager(nw::os::IAllocator * allocator,ScreenshotArray screenshots)142 ScreenshotManager::ScreenshotManager(
143 nw::os::IAllocator* allocator,
144 ScreenshotArray screenshots
145 )
146 : m_Allocator(allocator),
147 m_Screenshots(screenshots),
148 m_NextWrited(0)
149 {
150 }
151
152 //--------------------------------------------------------------------------
~ScreenshotManager()153 ScreenshotManager::~ScreenshotManager()
154 {
155 this->ClearScreenshots();
156 }
157
158 //--------------------------------------------------------------------------
159 int
Take(GLenum display,int offsetX,int offsetY)160 ScreenshotManager::Take(
161 GLenum display,
162 int offsetX,
163 int offsetY)
164 {
165 DisplayDescription displayDescription;
166 displayDescription.display = display;
167
168 nngxActiveDisplay(display);
169
170 GLint address;
171 nngxGetDisplaybufferParameteri(NN_GX_DISPLAYBUFFER_ADDRESS, &address);
172 void* srcArea = reinterpret_cast<void*>(address);
173 nngxGetDisplaybufferParameteri(NN_GX_DISPLAYBUFFER_FORMAT, &displayDescription.format);
174 nngxGetDisplaybufferParameteri(NN_GX_DISPLAYBUFFER_WIDTH, &displayDescription.width);
175 nngxGetDisplaybufferParameteri(NN_GX_DISPLAYBUFFER_HEIGHT, &displayDescription.height);
176
177 displayDescription.offsetX = offsetX;
178 displayDescription.offsetY = offsetY;
179
180 if (displayDescription.format == 0 || displayDescription.width == 0 || displayDescription.height == 0)
181 {
182 return -1;
183 }
184
185 int length = CalcMemorySize(displayDescription.format, displayDescription.width, displayDescription.height);
186
187 ScreenshotRange range = this->GetScreenshots();
188
189 if (m_NextWrited < m_Screenshots.size())
190 {
191 Screenshot* screenshot = m_Screenshots[m_NextWrited];
192 screenshot->Set(displayDescription, srcArea, length, displayDescription.width, displayDescription.height);
193 }
194 else
195 {
196 return -1;
197 }
198
199 ++m_NextWrited;
200 if (m_NextWrited >= m_Screenshots.size())
201 {
202 m_NextWrited = 0;
203 }
204
205 return m_NextWrited;
206 }
207
208 //--------------------------------------------------------------------------
209 void
ClearScreenshots()210 ScreenshotManager::ClearScreenshots()
211 {
212 ScreenshotRange range = this->GetScreenshots();
213
214 for (ScreenshotArray::iterator iter = range.first;
215 iter != range.second;
216 ++iter)
217 {
218 Screenshot* screenshot = *iter;
219 if (screenshot != NULL)
220 {
221 screenshot->~Screenshot();
222 m_Allocator->Free(screenshot);
223 }
224 }
225
226 this->m_Screenshots.clear();
227 }
228
229 } // namespace nw::dev
230 } // namespace nw
231
232 #endif // NW_DEV_ENABLED
233