ctr_Repair/trunk/ConsoleDataMigration/sources/common/QrImage.cpp
N2614 634c9575ed チェックデジット無しのシリアルNo.を下画面に表示するように
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@667 385bec56-5757-e545-9c3a-d8741f4650f1
2012-03-16 04:44:47 +00:00

225 lines
7.7 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 <qre.h>
namespace common
{
QrImage::QrImage()
{
// TODO 自動生成されたコンストラクター・スタブ
}
QrImage::~QrImage()
{
// TODO Auto-generated destructor stub
}
void QrImage::Draw(demo::RenderSystemDrawing& renderSystem, bit64 deviceId, u8* serialNo, bool flip)
{
char deviceIdStr[32];
nn::nstd::TSNPrintf(deviceIdStr, sizeof(deviceIdStr), "%llu", deviceId);
renderSystem.SetRenderTarget(Util::GetRenderTarget(NN_GX_DISPLAY0, flip));
renderSystem.Clear();
renderSystem.DrawText(0, 0, "DeviceId");
DrawStringinQr(renderSystem, reinterpret_cast<u8*>(deviceIdStr), Util::GetRenderTarget(NN_GX_DISPLAY0, flip));
renderSystem.SwapBuffers();
renderSystem.SetRenderTarget(Util::GetRenderTarget(NN_GX_DISPLAY1, flip));
renderSystem.Clear();
renderSystem.DrawText(0, 0, "SerialNo.");
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 = 12;
/* 誤り訂正レベル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 */