ctr_Repair/branches/CardCupForNBD/CardSaveData/common/gui/gui.cpp
N2614 b6024ff808 セルフCUPツール NBDリリース向けブランチ
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@337 385bec56-5757-e545-9c3a-d8741f4650f1
2011-06-14 00:36:31 +00:00

655 lines
17 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*---------------------------------------------------------------------------*
Project: Horizon
File: main.cpp
Copyright (C)2010 Nintendo Co., Ltd. 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.
*---------------------------------------------------------------------------*/
#include <string.h>
#include <nn.h>
#include <nn/os.h>
#include <nn/hid.h>
#include "demo.h"
#include "gui.h"
#include "../shfnt.h"
//----------- types etc ---------------
typedef struct{
u16 x,y;
}tU16xy;
typedef struct{
f32 r;
f32 g;
f32 b;
f32 a;
}tCol;
typedef struct{
uptr image;
tCol color;
f32 width;
}tStyle;
typedef void (*FUNCPTR)(u32 value);
//------------------ コンポーネントクラス
class cmBase{
public:
FUNCPTR callback;
tU16xy pos;
tU16xy size;
bool enable;
bool visible;
u8 scr;
u8 padding[1];
public:
cmBase():enable(false),visible(false){callback = 0;};
virtual ~cmBase(){};
void SetCallback(uptr adrs){ callback = (FUNCPTR)adrs;};
};
//PADボタン
class cmButton: public cmBase
{
public:
u32 mask;//PadStatus.Trigger のマスク
public:
cmButton(){mask=0;};
};
//パネル
class cmPanel: public cmBase
{
public:
tStyle style;
char *caption;
public:
cmPanel(){
caption="None";
style.image = 0;
style.color.r = 1.0f;
style.color.g = 1.0f;
style.color.b = 1.0f;
style.color.a = 1.0f;
style.width = 2.0f;
}
};
//メッセージ
class cmMessage: public cmPanel
{
public:
u32 parent;//親コンポーネントID
public:
cmMessage(){style.width = 8.0f;}
};
#define LINES_MAX 20
#define CHARS_MAX 128
//メモ
class cmMemo: public cmBase
{
private:
char strlst[LINES_MAX][CHARS_MAX];
public:
tStyle style;
u32 lines;//行サイズ:strlen配列数以下であること
u32 parent;//親コンポーネントID
public:
cmMemo();
bool setline(char *p,u16 ln);
char* line(u16 ln);
void clr(){
for (int i=0;i<lines;i++)strlst[i][0]=0;
}
};
cmMemo::cmMemo():lines(10)
{
int i;
for (i=0;i<LINES_MAX;i++){
strlst[i][0]=0;
strlst[i][CHARS_MAX-1]=0;
}
}
//文字列の登録
bool cmMemo::setline(char *p,u16 ln)
{
if(lines < ln)return false;
char c;
int i = 0;
while(1){
c = p[i];
strlst[ln][i]=c;
if (c == 0)break;
if (i == CHARS_MAX-2)break;
i++;
}
return true;
}
char* cmMemo::line(u16 ln)
{
if(lines < ln)return 0;
return &strlst[ln][0];
}
//------------- sub routin -------------------
#define PANEL_MAX 20
#define MEMO_MAX 2
#define MESS_MAX 50
static cmButton s_Button;
static cmPanel s_Panel[PANEL_MAX];
static cmMessage s_Message[MESS_MAX];
static cmMemo s_Memo[MEMO_MAX];
static demo::RenderSystemDrawing s_RenderSystem;
void ColorFromCode(eColor c,tCol *col);
//(2011.3.10)本体内蔵フォントに変更
//作成時のフォントで画面&タッチ位置を調整
int pos2tpx(int x)
{
if (x > 80 )
{
if (x < 160) return -10;
else if (x <230) return -30;
else return -50;
}
return 0;
}
//PANEL上の座標かチェック
bool onPanel(u16 x,u16 y,cmPanel *p)
{
int px = pos2tpx(p->pos.x);
int pw = pos2tpx(p->size.x);
int py = 20;
if (x <= (p->pos.x + px))return false;
if (x >= (p->pos.x + p->size.x + pw))return false;
if (y <= p->pos.y + py )return false;
if (y >= (p->pos.y + p->size.y))return false;
return true;
}
#define setText(x,y,s) shf_DrawText_0(x,y,s)
#define setSize(sz) shf_SetSize(sz)
void setColor(tCol *col)
{
//s_RenderSystem.SetColor(col->r, col->g, col->b,col->a);
shf_SetColor(col->r,col->g,col->b,col->a);
}
//void setSize(f32 sz)
//{
// s_RenderSystem.SetFontSize(sz);
//}
/*
#define FONT_CAPTION_SIZE 12
//caption付きBox描画
void drawBox(tU16xy top,tU16xy size,tStyle *st,char* str = 0)
{
u16 xe = top.x + size.x -1;
u16 ye = top.y + size.y -1;
setColor(&st->color);
s_RenderSystem.SetLineWidth(st->width);
s_RenderSystem.DrawLine(top.x, top.y, xe, top.y);
s_RenderSystem.DrawLine(xe, top.y, xe, ye);
s_RenderSystem.DrawLine(xe, ye, top.x, ye);
s_RenderSystem.DrawLine(top.x, ye, top.x, top.y);
if (str != 0){
int w = (size.x - strlen(str)*FONT_CAPTION_SIZE) >> 1;
int h = (size.y - FONT_CAPTION_SIZE) >> 1;
if ((w>0) && (h>0)){
setSize(FONT_CAPTION_SIZE);
s_RenderSystem.DrawText(top.x + w,top.y + h,str);
}
}
}
*/
//上画面、メッセージ枠表示
void drawBox(tU16xy top,tU16xy size,tStyle *st,char* str = 0)
{
int i;
shf_SetScale(2.0f,2.0f);
setColor(&st->color);
for (i=0;i<size.x/16;i++)setText(top.x+i*16,top.y-32,"-");
for (i=0;i<size.y/36;i++)setText(top.x-10,top.y+i*36-10,"|");
for (i=0;i<size.x/16;i++)setText(top.x+i*16,top.y+size.y-40,"-");
for (i=0;i<size.y/36;i++)setText(top.x+size.x-16,top.y+i*36-10,"|");
if (str != 0){
shf_SetScale(1.0f,1.0f);
int w = shf_GetFontWidth()/2;
int h = shf_GetFontHeight();
w = (size.x - strlen(str)*w) >> 1;
h = (size.y - h) >> 1;
if ((w>0) && (h>0)){
setText(top.x + w+10,top.y + h,str);
}
}
}
//下画面ボタン表示
void drawBox2(tU16xy top,tU16xy size,tStyle *st,char* str = 0)
{
int i;
setColor(&st->color);
shf_SetScale(2.0f,2.0f);
for (i=0;i<size.x/16+2;i++)setText(top.x+i*16,top.y-24,"-");
for (i=0;i<size.y/40;i++)setText(top.x-8,top.y+i*40,"|");
for (i=0;i<size.x/16+2;i++)setText(top.x+i*16,top.y+size.y-28,"-");
for (i=0;i<size.y/40;i++)setText(top.x+size.x+24,top.y+i*40,"|");
if (str != 0){
shf_SetScale(1.0f,1.0f);
int w = shf_GetFontWidth()/2;
int h = shf_GetFontHeight();
w = (size.x - strlen(str)*w) >> 1;
h = (size.y - h) >> 1;
if ((w>0) && (h>0)){
setText(top.x + w+10,top.y + h+10,str);
}
}
}
//描画
void drawDisp()
{
//NN_LOG("draw\n");
//上
s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0);
s_RenderSystem.Clear();
int i,j;
for (i=0;i<PANEL_MAX;i++){
if ((s_Panel[i].visible) && (s_Panel[i].scr == 0)){
drawBox(s_Panel[i].pos,s_Panel[i].size,&s_Panel[i].style,s_Panel[i].caption);
}
}
for (i=0;i<MESS_MAX;i++){
if ( s_Message[i].visible && s_Panel[s_Message[i].parent].visible ){
setSize(s_Message[i].style.width);
setColor(&s_Message[i].style.color);
//s_RenderSystem.DrawText(s_Panel[s_Message[i].parent].pos.x+s_Message[i].pos.x,
// s_Panel[s_Message[i].parent].pos.y+s_Message[i].pos.y,s_Message[i].caption);
setText(s_Panel[s_Message[i].parent].pos.x+s_Message[i].pos.x,
s_Panel[s_Message[i].parent].pos.y+s_Message[i].pos.y,s_Message[i].caption);
//NN_LOG(s_Message[i].caption);
//NN_LOG(" %d\n",i);
}
}
for (i=0;i<MEMO_MAX;i++){
if ( s_Memo[i].visible && s_Panel[s_Memo[i].parent].visible ){
setColor(&s_Memo[i].style.color);
setSize(s_Memo[i].style.width);
u16 x = s_Panel[s_Memo[i].parent].pos.x+s_Memo[i].pos.x;
u16 y = s_Panel[s_Memo[i].parent].pos.y+s_Memo[i].pos.y;
for (j=0;j<s_Memo[i].lines;j++){
s_RenderSystem.DrawText(x,y,s_Memo[i].line(j));
y+=10;
}
}
}
s_RenderSystem.SwapBuffers();
nngxWaitVSync(NN_GX_DISPLAY0);
//下
tCol col;
s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY1);
s_RenderSystem.Clear();
for (i=0;i<PANEL_MAX;i++){
if ((s_Panel[i].visible) && (s_Panel[i].scr != 0)){
if (s_Panel[i].enable==false){
col.r = s_Panel[i].style.color.r;
col.g = s_Panel[i].style.color.g;
col.b = s_Panel[i].style.color.b;
ColorFromCode(COLOR_GRAY,&s_Panel[i].style.color);
}
//drawBox(s_Panel[i].pos,s_Panel[i].size,&s_Panel[i].style,s_Panel[i].caption);
drawBox2(s_Panel[i].pos,s_Panel[i].size,&s_Panel[i].style,s_Panel[i].caption);
if (s_Panel[i].enable==false){
s_Panel[i].style.color.r = col.r;
s_Panel[i].style.color.g = col.g;
s_Panel[i].style.color.b = col.b;
}
}
}
s_RenderSystem.SwapBuffers();
nngxWaitVSync(NN_GX_DISPLAY1);
}
void ColorFromCode(eColor c,tCol *col)
{
switch(c){
case COLOR_BLACK:
col->r = 0.0;
col->g = 0.0;
col->b = 0.0;
break;
case COLOR_GRAY:
col->r = 0.5f;
col->g = 0.5f;
col->b = 0.5f;
break;
case COLOR_RED:
col->r = 1.0f;
col->g = 0.0f;
col->b = 0.0f;
break;
case COLOR_BLUE:
col->r = 0.0f;
col->g = 0.0f;
col->b = 1.0f;
break;
case COLOR_GREEN:
col->r = 0.0f;
col->g = 1.0f;
col->b = 0.0f;
break;
case COLOR_YELLO:
col->r = 1.0f;
col->g = 1.0f;
col->b = 0.0f;
break;
case COLOR_WHITE:
col->r = 1.0f;
col->g = 1.0f;
col->b = 1.0f;
break;
case COLOR_PARPL:
col->r = 1.0f;
col->g = 0.0f;
col->b = 1.0f;
break;
case COLOR_SKY:
col->r = 0.5f;
col->g = 1.0f;
col->b = 1.0f;
break;
default:
col->r = 1.0f;
col->g = 1.0f;
col->b = 1.0f;
break;
}
col->a = 1.0f;
}
//------------------ class code ----------------------------
nn::os::Thread s_thread;
//thread
//void Gui::thUpdate()
void thUpdate(nn::os::LightEvent* pEvnt)
{
nn::hid::PadReader padReader;
nn::hid::PadStatus padStatus;
nn::hid::TouchPanelStatus tpStatus;
tU16xy tpOld = {0,0};
nn::hid::TouchPanelReader tpReader;
u32 value;
int i;
while(1)
{
if (pEvnt->TryWait())break;
if (s_Button.enable && (s_Button.callback !=0))//PADボタン
{
padReader.ReadLatest(&padStatus);
value = (padStatus.trigger & s_Button.mask) | ((padStatus.hold & s_Button.mask) << 16);
if (value)(*s_Button.callback)(value);
}
tpReader.ReadLatest(&tpStatus);//タッチ
if((tpStatus.x != tpOld.x) || (tpStatus.y != tpOld.y))
{
tpOld.x = tpStatus.x;
tpOld.y = tpStatus.y;
if (tpStatus.touch)
{
NN_LOG("x =%d , y=%d\n",tpStatus.x,tpStatus.y);
for (i=0;i<PANEL_MAX;i++)//PANEL枠内か
{
if (s_Panel[i].enable && (s_Panel[i].callback !=0))
{
if(onPanel(tpStatus.x,tpStatus.y,&s_Panel[i]))
(*s_Panel[i].callback)(tpStatus.x | (tpStatus.y<<16));
}
}
}
}
nn::os::Thread::Yield();//MAINスレッドへ
}
nn::hid::Finalize();
pEvnt->ClearSignal();
}
Gui::~Gui()
{
Finalize();
}
//初期化、終了
bool Gui::Initialize(uptr pHeap,u32 size,nn::os::LightEvent* pEvnt)
{
if (Initialized)return false;
Initialized = true;
//コンポーネントの初期化
int i;
for (i=0;i< PANEL_MAX;i++)PanelEffective(i,false,false);
for (i=0;i< MEMO_MAX;i++)MemoEffective(i,false,false);
for (i=0;i< MESS_MAX;i++)MessEffective(i,false,false);
//Render
s_RenderSystem.Initialize(pHeap, size);
SharedFontInit();
//HID
nn::hid::Initialize();
//Thread
NN_LOG("Thread Start\n");
nn::Result res =s_thread.TryStartUsingAutoStack(thUpdate,pEvnt,8192);
if (res.IsFailure()){
NN_LOG("failed :res.desc = %d\n",res.GetDescription());
return false;
}
return true;
}
void Gui::Finalize()
{
if (Initialized != true) return;
if (s_thread.IsAlive())
{
s_thread.Join();
s_thread.Finalize();
}
Initialized = false;
//nn::hid::Finalize();
// nngxFinalize 関数呼び出しと VSync 割り込みが同時に発生すると
// 画面が暗転したまま止まる不具合を回避するために VSync 待ちを行う
nngxWaitVSync(NN_GX_DISPLAY_BOTH);
SharedFontFinalize();
nngxWaitVSync(NN_GX_DISPLAY_BOTH);
s_RenderSystem.Finalize();
}
void Gui::ButtonCallback(uptr adrs)
{
s_Button.SetCallback(adrs);
}
void Gui::ButtonMask(u32 mask)
{
s_Button.mask = mask;
s_Button.enable = true;
}
myResult Gui::PanelSet(const tPanel *panel)
{
if (panel->id >= PANEL_MAX)return RESULT_BAD_PARAM;
s_Panel[panel->id].pos.x = panel->x;
s_Panel[panel->id].pos.y = panel->y;
s_Panel[panel->id].size.x = panel->width;
s_Panel[panel->id].size.y = panel->height;
//if (panel->caption[0] != 0 )
s_Panel[panel->id].caption = panel->caption;
s_Panel[panel->id].SetCallback(panel->callback);
s_Panel[panel->id].scr = panel->scr;
s_Panel[panel->id].visible = false;
s_Panel[panel->id].enable = false;
return RESULT_OK;
}
myResult Gui::PanelEffective(u8 id,bool enable,bool visible)
{
if (id >= PANEL_MAX)return RESULT_BAD_PARAM;
s_Panel[id].enable = enable;
s_Panel[id].visible = visible;
return RESULT_OK;
}
myResult Gui::PanelLineStyle(u8 id,eColor col,u8 width)
{
if (id >= PANEL_MAX)return RESULT_BAD_PARAM;
ColorFromCode(col,&s_Panel[id].style.color);
s_Panel[id].style.width = width;
return RESULT_OK;
}
myResult Gui::MessEffective(u8 id,bool enable,bool visible)
{
if (id >= MESS_MAX)return RESULT_BAD_PARAM;
s_Message[id].enable = enable;
s_Message[id].visible = visible;
return RESULT_OK;
}
myResult Gui::MessSet(const tMessage *mes)
{
if ((mes->parent >= PANEL_MAX) || (mes->id >= MESS_MAX))return RESULT_BAD_PARAM;
s_Message[mes->id].pos.x = mes->x;
s_Message[mes->id].pos.y = mes->y;
s_Message[mes->id].caption = mes->str;
s_Message[mes->id].parent = mes->parent;
s_Message[mes->id].style.width = mes->size;
ColorFromCode(mes->color,&s_Message[mes->id].style.color);
s_Message[mes->id].visible = false;
s_Message[mes->id].enable = false;
return RESULT_OK;
}
myResult Gui::MessStr(u8 id,char *str)
{
if (id >= MESS_MAX)return RESULT_BAD_PARAM;
s_Message[id].caption = str;
return RESULT_OK;
}
myResult Gui::MessCol(u8 id,eColor col)
{
if (id >= MESS_MAX)return RESULT_BAD_PARAM;
ColorFromCode(col,&s_Message[id].style.color);
return RESULT_OK;
}
myResult Gui::MemoSet(const tMemo *m)
{
if ((m->parent >= PANEL_MAX) || (m->id >= MEMO_MAX))return RESULT_BAD_PARAM;
if (m->lines > LINES_MAX)return RESULT_BAD_PARAM;
s_Memo[m->id].lines = m->lines;
s_Memo[m->id].pos.x = m->x;
s_Memo[m->id].pos.y = m->y;
s_Memo[m->id].parent = m->parent;
s_Memo[m->id].style.width = m->size;
ColorFromCode(m->color,&s_Memo[m->id].style.color);
s_Memo[m->id].clr();
s_Memo[m->id].visible = false;
s_Memo[m->id].enable = false;
return RESULT_OK;
}
myResult Gui::MemoStr(u8 id,char *str,u16 ln)
{
if ((id < MEMO_MAX) && s_Memo[id].setline(str,ln) )return RESULT_OK;
return RESULT_BAD_PARAM;
}
myResult Gui::MemoEffective(u8 id,bool enable,bool visible)
{
if (id >= MEMO_MAX)return RESULT_BAD_PARAM;
s_Memo[id].enable = enable;
s_Memo[id].visible = visible;
return RESULT_OK;
}
void Gui::Draw()
{
//s_drawFlag = true;
drawDisp();
}
void Gui::DisableAll()
{
for (int i=0;i<PANEL_MAX;i++){
s_Panel[i].enable = false;
s_Panel[i].visible = false;
}
}
/*---------------------------------------------------------------------------*
End of file
*---------------------------------------------------------------------------*/