mirror of
https://github.com/rvtr/ctr_Repair.git
synced 2025-10-31 13:51:08 -04:00
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@669 385bec56-5757-e545-9c3a-d8741f4650f1
254 lines
8.5 KiB
C++
254 lines
8.5 KiB
C++
/*---------------------------------------------------------------------------*
|
|
Project: Horizon
|
|
File: QrImage.cpp
|
|
|
|
Copyright 2009-2011 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.
|
|
|
|
$Rev$
|
|
*---------------------------------------------------------------------------*/
|
|
|
|
#include "QrImage.h"
|
|
#include "HeapManager.h"
|
|
#include "Util.h"
|
|
#include <cstring>
|
|
#include <string>
|
|
#include "ResFont.h"
|
|
|
|
#include <qre.h>
|
|
|
|
namespace
|
|
{
|
|
char s_DeviceIdStr[32];
|
|
char s_SerialNumberStr[32];
|
|
}
|
|
|
|
namespace common
|
|
{
|
|
|
|
QrImage::QrImage()
|
|
{
|
|
// TODO 自動生成されたコンストラクター・スタブ
|
|
|
|
}
|
|
|
|
QrImage::~QrImage()
|
|
{
|
|
// TODO Auto-generated destructor stub
|
|
}
|
|
|
|
void DrawDeviceId()
|
|
{
|
|
GetTextWriter()->Printf("DeviceId = %s", s_DeviceIdStr);
|
|
}
|
|
|
|
void DrawSerialNumber()
|
|
{
|
|
GetTextWriter()->Printf("SerialNo. = %s", s_SerialNumberStr);
|
|
}
|
|
|
|
void QrImage::Draw(demo::RenderSystemDrawing& renderSystem, bit64 deviceId, u8* serialNo, bool flip)
|
|
{
|
|
char deviceIdStr[32];
|
|
nn::nstd::TSNPrintf(deviceIdStr, sizeof(deviceIdStr), "%llu", deviceId);
|
|
|
|
std::string deviceIdString(deviceIdStr);
|
|
Util::SplitDeviceidWithSpace(deviceIdString);
|
|
std::strlcpy(s_DeviceIdStr, deviceIdString.c_str(), sizeof(s_DeviceIdStr));
|
|
std::strlcpy(s_SerialNumberStr, reinterpret_cast<char*>(serialNo), sizeof(s_SerialNumberStr));
|
|
|
|
renderSystem.SetRenderTarget(Util::GetRenderTarget(NN_GX_DISPLAY0, flip));
|
|
renderSystem.Clear();
|
|
GetTextWriter()->SetTextColor(nn::util::Color8(255, 255, 255, 255));
|
|
SetDrawTextHandler(DrawDeviceId);
|
|
DrawResFont(Util::GetRenderTarget(NN_GX_DISPLAY0, flip));
|
|
DrawStringinQr(renderSystem, reinterpret_cast<u8*>(deviceIdStr), Util::GetRenderTarget(NN_GX_DISPLAY0, flip));
|
|
renderSystem.SwapBuffers();
|
|
|
|
renderSystem.SetRenderTarget(Util::GetRenderTarget(NN_GX_DISPLAY1, flip));
|
|
renderSystem.Clear();
|
|
GetTextWriter()->SetTextColor(nn::util::Color8(255, 255, 255, 255));
|
|
SetDrawTextHandler(DrawSerialNumber);
|
|
DrawResFont(Util::GetRenderTarget(NN_GX_DISPLAY1, flip));
|
|
DrawStringinQr(renderSystem, serialNo, Util::GetRenderTarget(NN_GX_DISPLAY1, flip));
|
|
renderSystem.SwapBuffers();
|
|
}
|
|
|
|
void QrImage::DrawStringinQr(demo::RenderSystemDrawing& renderSystem, u8* str, u32 target)
|
|
{
|
|
using namespace mw::qre;
|
|
|
|
QREncoder *encoder = new QREncoder;
|
|
u32 dataSize = std::strlen(reinterpret_cast<char*>(str));
|
|
u32 requiredMemorySize = QREncoder::GetEncodeBufferSize(dataSize, 3, 1);
|
|
common::HeapManager heap(requiredMemorySize);
|
|
if(!heap.GetAddr())
|
|
{
|
|
NN_LOG("not enough memory\n");
|
|
return;
|
|
}
|
|
encoder->InitMemory(heap.GetAddr(), requiredMemorySize);
|
|
|
|
/* 作成するQRコードの情報を設定 */
|
|
EncodeData info;
|
|
// バージョン2で数字34文字OK
|
|
info.version = 10;
|
|
/* 誤り訂正レベルH */
|
|
info.ecc_level = ECC_LEVEL_H;
|
|
/* コンテンツ文字列の情報 */
|
|
info.size = dataSize;
|
|
info.data = str;
|
|
/*
|
|
* コンテンツサイズに合わせて分割、
|
|
* このサンプルでは分割するほど大きなデータを入力することは想定していない
|
|
*/
|
|
info.total = 1;
|
|
/* セルのサイズ設定 */
|
|
info.cell_size = 3;
|
|
|
|
/* エンコード実行 */
|
|
if (!encoder->Encode(&info))
|
|
{
|
|
/* エンコードに失敗 */
|
|
NN_LOG("QR encode failed...\n");
|
|
}
|
|
|
|
int qr_size = encoder->GetQRSize(0, false);
|
|
ImageInfo QRImage;
|
|
QRImage.rgb888Data = reinterpret_cast<u8*>(common::ForceAllocate(qr_size));
|
|
if (!QRImage.rgb888Data) {
|
|
NN_LOG("Memory allocation failed...\n");
|
|
return;
|
|
}
|
|
if(!encoder->GetQRData(&QRImage, 0))
|
|
{
|
|
NN_LOG("Get QRData Failed\n");
|
|
return;
|
|
}
|
|
delete encoder;
|
|
|
|
DrawImage(renderSystem, QRImage.rgb888Data, QRImage.width, QRImage.height, target);
|
|
common::ForceFree(QRImage.rgb888Data);
|
|
}
|
|
|
|
void QrImage::DrawImage(demo::RenderSystemDrawing& renderSystem, u8* textureDataPtr, u32 width, u32 height, u32 renderTarget)
|
|
{
|
|
static GLuint textureId = 0;
|
|
if (textureId != 0)
|
|
{
|
|
renderSystem.DeleteTexture(textureId);
|
|
}
|
|
GLenum target = GL_TEXTURE_2D;
|
|
GLenum internalFormat = GL_RGB_NATIVE_DMP;
|
|
GLenum format = GL_RGB_NATIVE_DMP;
|
|
GLenum type = GL_UNSIGNED_BYTE;
|
|
u32 textureWidth = width;
|
|
u32 textureHeight = height;
|
|
u8* textureDataBuffer = GetTextureDataFromRawData(width, height,
|
|
textureDataPtr,
|
|
textureWidth,
|
|
textureHeight);
|
|
renderSystem.GenerateTexture(target, internalFormat, textureWidth, textureHeight,
|
|
format, type, textureDataBuffer, textureId);
|
|
common::ForceFree(textureDataBuffer);
|
|
|
|
f32 windowPositionX = 0.0f;
|
|
f32 windowPositionY = 0.0f;
|
|
if (renderTarget == NN_GX_DISPLAY0)
|
|
{
|
|
windowPositionX = (nn::gx::DISPLAY0_HEIGHT / 2) - (width / 2);
|
|
if (height < nn::gx::DISPLAY0_WIDTH)
|
|
{
|
|
windowPositionY = (nn::gx::DISPLAY0_WIDTH / 2) - (height / 2);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
windowPositionX = (nn::gx::DISPLAY1_HEIGHT / 2) - (width / 2);
|
|
if (height < nn::gx::DISPLAY1_WIDTH)
|
|
{
|
|
windowPositionY = (nn::gx::DISPLAY1_WIDTH / 2) - (height / 2);
|
|
}
|
|
}
|
|
|
|
f32 rectangleWidth = static_cast<f32>(width);
|
|
f32 rectangleHeight = static_cast<f32>(height);
|
|
renderSystem.FillTexturedRectangle(textureId,
|
|
windowPositionX, windowPositionY,
|
|
rectangleWidth, rectangleHeight,
|
|
static_cast<f32>(width),
|
|
static_cast<f32>(height),
|
|
static_cast<f32>(textureWidth),
|
|
static_cast<f32>(textureHeight));
|
|
}
|
|
|
|
u8* QrImage::GetTextureDataFromRawData(const u32& width,
|
|
const u32& height,
|
|
u8* rawDataBuffer,
|
|
u32& textureWidth,
|
|
u32& textureHeight)
|
|
{
|
|
textureWidth = GetTextureLength(width);
|
|
textureHeight = GetTextureLength(height);
|
|
u32 textureSize = textureWidth * textureHeight * 3;
|
|
u8* textureGLDataBuffer = reinterpret_cast<u8*>(common::ForceAllocate(textureSize));
|
|
u8* dstPtr = textureGLDataBuffer;
|
|
|
|
u32 y = 0;
|
|
for (; y < height; y++) {
|
|
// FLIP対応
|
|
// ConvertGLTextureToNative()にてFLIPしている。
|
|
u8* srcPtr = rawDataBuffer + width * (height - y - 1) * 3;
|
|
u32 x = 0;
|
|
for (; x < width; x++) {
|
|
dstPtr[0] = srcPtr[2];
|
|
dstPtr[1] = srcPtr[1];
|
|
dstPtr[2] = srcPtr[0];
|
|
dstPtr += 3;
|
|
srcPtr += 3;
|
|
}
|
|
for (; x < textureWidth; x++) {
|
|
dstPtr[0] = dstPtr[1] = dstPtr[2] = 0x00;
|
|
dstPtr += 3;
|
|
}
|
|
}
|
|
for (; y < textureHeight; y++) {
|
|
for (u32 x = 0; x < textureWidth; x++) {
|
|
dstPtr[0] = dstPtr[1] = dstPtr[2] = 0x00;
|
|
dstPtr += 3;
|
|
}
|
|
}
|
|
|
|
u8* textureDataBuffer = reinterpret_cast<u8*>(common::ForceAllocate(textureSize));
|
|
GLenum format = GL_RGB_NATIVE_DMP;
|
|
bool result = demo::ConvertGLTextureToNative(format, textureWidth, textureHeight,
|
|
textureGLDataBuffer, textureDataBuffer);
|
|
if (!result) {
|
|
NN_LOG(" Convert to GL_RGB_NATIVE_DMP failed.\n");
|
|
NN_ASSERT(0);
|
|
}
|
|
common::ForceFree(textureGLDataBuffer);
|
|
|
|
return textureDataBuffer;
|
|
}
|
|
|
|
u32 QrImage::GetTextureLength(const u32& imageLength)
|
|
{
|
|
u32 textureLength = 8;
|
|
// 8, 16, 32, 64, 128, 256, 512, 1024
|
|
for (u32 i = 0; i < 7; i++) {
|
|
if (imageLength < textureLength)
|
|
return textureLength;
|
|
|
|
textureLength *= 2;
|
|
}
|
|
return 1024;
|
|
}
|
|
|
|
} /* namespace common */
|