ctr_Repair/trunk/ConsoleDataMigration/sources/common/QrImage.cpp
N2614 707ab24a28 XボタンでデバイスIDをQRコード表示できるように
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@661 385bec56-5757-e545-9c3a-d8741f4650f1
2012-03-12 07:31:40 +00:00

214 lines
7.1 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, bool flip)
{
using namespace mw::qre;
char deviceIdStr[32];
QREncoder *encoder = new QREncoder;
nn::nstd::TSNPrintf(deviceIdStr, sizeof(deviceIdStr), "%llu", deviceId);
u32 dataSize = std::strlen(deviceIdStr);
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;
/* バージョンは15とする */
info.version = 12;
/* 誤り訂正レベルH */
info.ecc_level = ECC_LEVEL_H;
/* コンテンツ文字列の情報 */
info.size = dataSize;
info.data = reinterpret_cast<u8*>(deviceIdStr);
/*
* コンテンツサイズに合わせて分割、
* このサンプルでは分割するほど大きなデータを入力することは想定していない
*/
info.total = 0;
/* セルのサイズ設定 */
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;
renderSystem.SetRenderTarget(Util::GetRenderTarget(NN_GX_DISPLAY0, flip));
renderSystem.Clear();
DrawImage(renderSystem, QRImage.rgb888Data, QRImage.width, QRImage.height, flip);
common::ForceFree(QRImage.rgb888Data);
}
void QrImage::DrawImage(demo::RenderSystemDrawing& renderSystem, u8* textureDataPtr, u32 width, u32 height, bool flip)
{
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 (!flip)
{
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 */