ctr_Repair/trunk/CardSaveData/common/gui/gui.cpp

605 lines
16 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 <wchar.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;
tChar *caption;
public:
cmPanel(){
#ifdef USE_WCHAR
caption=L"None";
#else
caption="None";
#endif
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;}
};
//------------- 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 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;
}
#ifdef USE_WCHAR
tChar* Wak_H = L"-";
tChar* Wak_V = L"|";
#define setText(x,y,s) shf_DrawText_0w(x,y,s)
#define setSize(sz) shf_SetSizeW(sz)
#define setScale(h,v) shf_SetScaleW(h,v)
#define getFontwidth shf_GetFontWidthW()
#define getFontheight shf_GetFontHeightW()
#define getLen(s) wcslen(s)
void setColor(tCol *col)
{
shf_SetColorW(col->r,col->g,col->b,col->a);
}
#else
tChar* Wak_H = "-";
tChar* Wak_V = "|";
#define setText(x,y,s) shf_DrawText_0(x,y,s)
#define setSize(sz) shf_SetSize(sz)
#define setScale(h,v) shf_SetScale(h,v)
#define getFontwidth shf_GetFontWidth()
#define getFontheight shf_GetFontHeight()
#define getLen(s) strlen(s)
void setColor(tCol *col)
{
shf_SetColor(col->r,col->g,col->b,col->a);
}
#endif
//上画面、メッセージ枠表示
void drawBox(tU16xy top,tU16xy size,tStyle *st,tChar* str = 0)
{
int i;
setScale(2.0f,2.0f);
setColor(&st->color);
for (i=0;i<size.x/16;i++)setText(top.x+i*16,top.y-32,Wak_H);
for (i=0;i<size.y/36;i++)setText(top.x-10,top.y+i*36-10,Wak_V);
for (i=0;i<size.x/16;i++)setText(top.x+i*16,top.y+size.y-40,Wak_H);
for (i=0;i<size.y/36;i++)setText(top.x+size.x-16,top.y+i*36-10,Wak_V);
if (str != 0){
int w = getFontwidth/2;
int h = getFontheight;
setScale(1.0f,1.0f);
w = (size.x - getLen(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,tChar* str = 0)
{
int i;
setColor(&st->color);
setScale(2.0f,2.0f);
for (i=0;i<size.x/16+2;i++)setText(top.x+i*16,top.y-24,Wak_H);
for (i=0;i<size.y/40;i++)setText(top.x-8,top.y+i*40,Wak_V);
for (i=0;i<size.x/16+2;i++)setText(top.x+i*16,top.y+size.y-28,Wak_H);
for (i=0;i<size.y/40;i++)setText(top.x+size.x+24,top.y+i*40,Wak_V);
if (str != 0){
setScale(1.0f,1.0f);
int w = getFontwidth/2;
int h = getFontheight;
w = (size.x - getLen(str)*w) >> 1;
h = (size.y - h) >> 1;
if ((w>0) && (h>0)){
setText(top.x + w+10,top.y + h+10,str);
}
}
}
static int si;
//描画
void drawDisp()
{
//NN_LOG("draw\n");
//上
s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0);
s_RenderSystem.Clear();
int i;
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 (si=0;si<MESS_MAX;si++){
if ( s_Message[si].visible && s_Panel[s_Message[si].parent].visible ){
setSize(s_Message[si].style.width);
setColor(&s_Message[si].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[si].parent].pos.x+s_Message[si].pos.x,
s_Panel[s_Message[si].parent].pos.y+s_Message[si].pos.y,s_Message[si].caption);
//NN_LOG(s_Message[i].caption);
//NN_LOG(" %d\n",i);
}
}
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 drawDisp_U()
{
//NN_LOG("draw\n");
//上
s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0);
s_RenderSystem.Clear();
int i;
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 (si=0;si<MESS_MAX;si++){
if ( s_Message[si].visible && s_Panel[s_Message[si].parent].visible ){
setSize(s_Message[si].style.width);
setColor(&s_Message[si].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[si].parent].pos.x+s_Message[si].pos.x,
s_Panel[s_Message[si].parent].pos.y+s_Message[si].pos.y,s_Message[si].caption);
//NN_LOG(s_Message[i].caption);
//NN_LOG(" %d\n",i);
}
}
s_RenderSystem.SwapBuffers();
}
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::PanelCaption(u8 id,tChar *str)
{
if (id >= PANEL_MAX)return RESULT_BAD_PARAM;
s_Panel[id].caption = str;
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,tChar *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;
}
void Gui::Draw()
{
//s_drawFlag = true;
drawDisp();
}
void Gui::Draw_U()
{
drawDisp_U();
}
void Gui::WaitVsnc()
{
nngxWaitVSync(NN_GX_DISPLAY0);
nngxWaitVSync(NN_GX_DISPLAY1);
}
void Gui::DisableAll()
{
for (int i=0;i<PANEL_MAX;i++){
s_Panel[i].enable = false;
s_Panel[i].visible = false;
}
}
/*---------------------------------------------------------------------------*
End of file
*---------------------------------------------------------------------------*/