ctr_Repair/branches/2-1-1/sources/common/ResFont.cpp
N2614 fa59af905c 2ndNUP修正版2-1-1
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@548 385bec56-5757-e545-9c3a-d8741f4650f1
2011-12-21 08:21:20 +00:00

416 lines
13 KiB
C++

/*---------------------------------------------------------------------------*
Project: Horizon
File: ResFont.cpp
Copyright 2009 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$
*---------------------------------------------------------------------------*/
//------------------------------------------------------------------
// デモ: ResFont
//
// 概要
// nn::font::ResFont の構築と破棄のサンプルです。
//
// 操作
// なし。
//
//------------------------------------------------------------------
#include <nn.h>
#include <nn/fs.h>
#include <nn/font.h>
#include <nn/math.h>
#include <nn/util.h>
#include "ResFont.h"
#include "demo.h"
#include "HeapManager.h"
namespace common
{
namespace
{
const char s_ShaderBinaryFilePath[] = "rom:/nnfont_RectDrawerShader.shbin";
const char s_FontFilePath[] = "rom:/lc.bcfnt";
const u8 s_Color = 255;
nn::font::RectDrawer s_Drawer;
void* s_DrawerBuf;
nn::font::ResFont s_Font;
nn::font::DispStringBuffer *s_pDrawStringBuf0;
nn::font::TextWriter s_TextWriter;
void (*s_DrawTextFunc)() = NULL;
//---------------------------------------------------------------------------
//! @brief シェーダの初期化を行います。
//!
//! @param[in,out] pResource 描画用リソースを管理するオブジェクトへのポインタ。
//---------------------------------------------------------------------------
void*
InitShaders(nn::font::RectDrawer* pDrawer)
{
nn::fs::FileReader shaderReader(s_ShaderBinaryFilePath);
const u32 fileSize = (u32)shaderReader.GetSize();
void* shaderBinary = ForceAllocate(fileSize);
NN_NULL_ASSERT(shaderBinary);
#ifndef NN_BUILD_RELEASE
s32 read =
#endif // NN_BUILD_RELEASE
shaderReader.Read(shaderBinary, fileSize);
NN_ASSERT(read == fileSize);
const u32 vtxBufCmdBufSize =
nn::font::RectDrawer::GetVertexBufferCommandBufferSize(shaderBinary, fileSize);
void *const vtxBufCmdBuf = ForceAllocate(vtxBufCmdBufSize);
NN_NULL_ASSERT(vtxBufCmdBuf);
pDrawer->Initialize(vtxBufCmdBuf, shaderBinary, fileSize);
return vtxBufCmdBuf;
}
//---------------------------------------------------------------------------
//! @brief 描画の初期設定を行います。
//!
//! @param[in] width 画面の幅。
//! @param[in] height 画面の高さ。
//---------------------------------------------------------------------------
void
InitDraw(
s32 width,
s32 height
)
{
// カラーバッファ情報
// LCDの向きに合わせて、幅と高さを入れ替えています。
const nn::font::ColorBufferInfo colBufInfo = { width, height, PICA_DATA_DEPTH24_STENCIL8_EXT };
const u32 screenSettingCommands[] =
{
// ビューポートの設定
NN_FONT_CMD_SET_VIEWPORT( 0, 0, colBufInfo.width, colBufInfo.height ),
// シザー処理を無効
NN_FONT_CMD_SET_DISABLE_SCISSOR( colBufInfo ),
// wバッファの無効化
// デプスレンジの設定
// ポリゴンオフセットの無効化
NN_FONT_CMD_SET_WBUFFER_DEPTHRANGE_POLYGONOFFSET(
0.0f, // wScale : 0.0 でWバッファが無効
0.0f, // depth range near
1.0f, // depth range far
0, // polygon offset units : 0.0 で ポリゴンオフセットが無効
colBufInfo),
};
nngxAdd3DCommand(screenSettingCommands, sizeof(screenSettingCommands), true);
static const u32 s_InitCommands[] =
{
// カリングを無効
NN_FONT_CMD_SET_CULL_FACE( NN_FONT_CMD_CULL_FACE_DISABLE ),
// ステンシルテストを無効
NN_FONT_CMD_SET_DISABLE_STENCIL_TEST(),
// デプステストを無効
// カラーバッファの全ての成分を書き込み可
NN_FONT_CMD_SET_DEPTH_FUNC_COLOR_MASK(
false, // isDepthTestEnabled
0, // depthFunc
true, // depthMask
true, // red
true, // green
true, // blue
true), // alpha
// アーリーデプステストを無効
NN_FONT_CMD_SET_ENABLE_EARLY_DEPTH_TEST( false ),
// フレームバッファアクセス制御
NN_FONT_CMD_SET_FBACCESS(
true, // colorRead
true, // colorWrite
false, // depthRead
false, // depthWrite
false, // stencilRead
false), // stencilWrite
};
nngxAdd3DCommand(s_InitCommands, sizeof(s_InitCommands), true);
}
//---------------------------------------------------------------------------
//! @brief ResFontを構築します。
//!
//! @param[out] pFont 構築するフォントへのポインタ。
//! @param[in] filePath ロードするフォントリソースファイル名。
//!
//! @return ResFont構築の成否を返します。
//---------------------------------------------------------------------------
bool
InitFont(
nn::font::ResFont* pFont,
const char* filePath
)
{
// フォントリソースをロードします
nn::fs::FileReader fontReader(filePath);
s32 fileSize = (s32)fontReader.GetSize();
if ( fileSize <= 0 )
{
return false;
}
void* buffer = common::ForceAllocate(fileSize, nn::font::GlyphDataAlignment);
if (buffer == NULL)
{
return false;
}
s32 readSize = fontReader.Read(buffer, fileSize);
if (readSize != fileSize)
{
common::ForceFree(buffer);
return false;
}
// フォントリソースをセットします
bool bSuccess = pFont->SetResource(buffer);
NN_ASSERT(bSuccess);
//--- 既にリソースをセット済みであるか,ロード済みであるか、リソースが不正な場合に失敗します。
if (! bSuccess)
{
common::ForceFree(buffer);
}
// 描画用バッファを設定します。
const u32 drawBufferSize = nn::font::ResFont::GetDrawBufferSize(buffer);
void* drawBuffer = common::ForceAllocate(drawBufferSize, 4);
NN_NULL_ASSERT(drawBuffer);
pFont->SetDrawBuffer(drawBuffer);
return bSuccess;
}
//---------------------------------------------------------------------------
//! @brief ResFontを破棄します。
//!
//! @param[in] pFont 破棄するフォントへのポインタ。
//---------------------------------------------------------------------------
void
CleanupFont(nn::font::ResFont* pFont)
{
// 描画用バッファの無効化
// 描画用バッファがセットされているなら 構築時に SetDrawBuffer に渡したバッファへの
// ポインタが返ってきます。
void *const drawBuffer = pFont->SetDrawBuffer(NULL);
if (drawBuffer != NULL)
{
ForceFree(drawBuffer);
}
// フォントがセットされているなら SetResource 時に渡したリソースへの
// ポインタが返ってきます。
void *const resource = pFont->RemoveResource();
if (resource != NULL)
{
ForceFree(resource);
}
// RemoveResource 後は再度 SetResource するまでフォントとして使用できません。
}
//---------------------------------------------------------------------------
//! @brief 表示文字列用バッファを確保します。
//!
//! @param[in] charMax 表示する文字列の最大文字数。
//!
//! @return 確保した表示文字列用バッファへのポインタを返します。
//---------------------------------------------------------------------------
nn::font::DispStringBuffer*
AllocDispStringBuffer(s32 charMax)
{
const u32 DrawBufferSize = nn::font::CharWriter::GetDispStringBufferSize(charMax);
void *const bufMem = ForceAllocate(DrawBufferSize);
NN_NULL_ASSERT(bufMem);
return nn::font::CharWriter::InitDispStringBuffer(bufMem, charMax);
}
//---------------------------------------------------------------------------
//! @brief 文字列表示用にモデルビュー行列と射影行列を設定します。
//!
//! @param[in] pDrawer RectDrawerオブジェクトへのポインタ。
//! @param[in] width 画面の幅。
//! @param[in] height 画面の高さ。
//---------------------------------------------------------------------------
void
SetupTextCamera(
nn::font::RectDrawer* pDrawer,
s32 width,
s32 height
)
{
// 射影行列を正射影に設定
{
// 左上原点とし、Y軸とZ軸の向きが逆になるように設定します。
nn::math::MTX44 proj;
f32 znear = 0.0f;
f32 zfar = -1.0f;
f32 t = 0;
f32 b = static_cast<f32>(width);
f32 l = 0;
f32 r = static_cast<f32>(height);
nn::math::MTX44OrthoPivot(&proj, l, r, b, t, znear, zfar, nn::math::PIVOT_UPSIDE_TO_TOP);
pDrawer->SetProjectionMtx(proj);
}
// モデルビュー行列を単位行列に設定
{
nn::math::MTX34 mv;
nn::math::MTX34Identity(&mv);
pDrawer->SetViewMtxForText(mv);
}
}
//---------------------------------------------------------------------------
//! @brief ASCII文字列を描画します。
//!
//! @param[in] pDrawer RectDrawerオブジェクトへのポインタ。
//! @param[in] pDrawStringBuf DispStringBufferオブジェクトへのポインタ。
//! @param[in] pFont フォントへのポインタ。
//! @param[in] width 画面の幅。
//! @param[in] height 画面の高さ。
//---------------------------------------------------------------------------
void
DrawAscii(
nn::font::RectDrawer* pDrawer,
nn::font::DispStringBuffer* pDrawStringBuf,
nn::font::ResFont* pFont,
s32 width,
s32 height
)
{
s_TextWriter.SetDispStringBuffer(pDrawStringBuf);
s_TextWriter.SetFont(pFont);
s_TextWriter.SetCursor(0, 0, 1.f);
s_TextWriter.StartPrint();
if(s_DrawTextFunc != NULL)
{
s_DrawTextFunc();
}
s_TextWriter.EndPrint();
pDrawer->BuildTextCommand(&s_TextWriter);
// 文字の色は、文字列の描画コマンドを再作成しなくても変更できます。
s_TextWriter.SetTextColor(nn::util::Color8(s_Color, s_Color, s_Color, s_Color));
pDrawer->DrawBegin();
SetupTextCamera(pDrawer, width, height);
s_TextWriter.UseCommandBuffer();
pDrawer->DrawEnd();
}
} // namespace <unnnamed>
void SetDrawTextHandler(void (*func)())
{
s_DrawTextFunc = func;
}
//---------------------------------------------------------------------------
//! @brief サンプルのメイン関数です。
//---------------------------------------------------------------------------
void
InitializeResFont()
{
const size_t ROMFS_BUFFER_SIZE = 1024 * 64;
static char buffer[ROMFS_BUFFER_SIZE];
NN_UTIL_PANIC_IF_FAILED(
nn::fs::MountRom(16, 16, buffer, ROMFS_BUFFER_SIZE));
// フォントの構築
{
#ifndef NN_BUILD_RELEASE
bool bSuccess =
#endif // NN_BUILD_RELEASE
InitFont(&s_Font, s_FontFilePath);
NN_ASSERTMSG(bSuccess, "Fail to load ResFont.");
}
// 描画リソースの構築
s_DrawerBuf = InitShaders(&s_Drawer);
// 描画文字列用バッファの確保
s_pDrawStringBuf0 = AllocDispStringBuffer(512);
nn::fs::Unmount("rom:");
}
void DrawResFont(s32 display)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if(display == NN_GX_DISPLAY0)
{
InitDraw(NN_GX_DISPLAY0_WIDTH, NN_GX_DISPLAY0_HEIGHT);
DrawAscii(&s_Drawer, s_pDrawStringBuf0, &s_Font, NN_GX_DISPLAY0_WIDTH, NN_GX_DISPLAY0_HEIGHT);
}
else if(display == NN_GX_DISPLAY1)
{
InitDraw(NN_GX_DISPLAY1_WIDTH, NN_GX_DISPLAY1_HEIGHT);
DrawAscii(&s_Drawer, s_pDrawStringBuf0, &s_Font, NN_GX_DISPLAY1_WIDTH, NN_GX_DISPLAY1_HEIGHT);
}
nngxUpdateState(NN_GX_STATE_ALL);
}
void FinalizeResFont()
{
s_Drawer.Finalize();
// 描画リソースの破棄
ForceFree(s_DrawerBuf);
// フォントの破棄
CleanupFont(&s_Font);
// 描画文字列用バッファの解放
ForceFree(s_pDrawStringBuf0);
}
nn::font::TextWriter* GetTextWriter()
{
return &s_TextWriter;
}
}