mirror of
https://github.com/rvtr/ctr_Repair.git
synced 2025-10-31 13:51:08 -04:00
558 lines
14 KiB
C++
558 lines
14 KiB
C++
/*---------------------------------------------------------------------------*
|
||
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 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,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::DisableAll()
|
||
{
|
||
for (int i=0;i<PANEL_MAX;i++){
|
||
s_Panel[i].enable = false;
|
||
s_Panel[i].visible = false;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
End of file
|
||
*---------------------------------------------------------------------------*/
|