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