mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-29 14:44:17 +01:00
418 lines
12 KiB
C++
418 lines
12 KiB
C++
/****************************************************************************
|
|
* Copyright (C) 2011
|
|
* by Dimok
|
|
*
|
|
* This software is provided 'as-is', without any express or implied
|
|
* warranty. In no event will the authors be held liable for any
|
|
* damages arising from the use of this software.
|
|
*
|
|
* Permission is granted to anyone to use this software for any
|
|
* purpose, including commercial applications, and to alter it and
|
|
* redistribute it freely, subject to the following restrictions:
|
|
*
|
|
* 1. The origin of this software must not be misrepresented; you
|
|
* must not claim that you wrote the original software. If you use
|
|
* this software in a product, an acknowledgment in the product
|
|
* documentation would be appreciated but is not required.
|
|
*
|
|
* 2. Altered source versions must be plainly marked as such, and
|
|
* must not be misrepresented as being the original software.
|
|
*
|
|
* 3. This notice may not be removed or altered from any source
|
|
* distribution.
|
|
***************************************************************************/
|
|
#include "BoxCover.hpp"
|
|
#include "BoxMesh.hpp"
|
|
#include "settings/CSettings.h"
|
|
#include "themes/CTheme.h"
|
|
#include "menu.h"
|
|
|
|
BoxCover::BoxCover(GuiImageData * img, bool flat)
|
|
: GuiImage(img),
|
|
boxBorder(Resources::GetFile("boxBorder.png"), Resources::GetFileSize("boxBorder.png")),
|
|
defaultBox(NULL)
|
|
{
|
|
flatCover = flat;
|
|
Zoomable = false;
|
|
moveChan = -1;
|
|
moveStartPosX = 0;
|
|
moveStartPosY = 0;
|
|
movePosX = 0.0f;
|
|
movePosY = 0.0f;
|
|
RotX = 0.0f;
|
|
RotY = 0.0f;
|
|
RotZ = 0.0f;
|
|
PosX = 0.0f;
|
|
PosY = 0.0f;
|
|
PosZ = -27.f;
|
|
AnimRotate = 0.0f;
|
|
last_manual_move_frame = 0;
|
|
guVector camera = (guVector) {0.0F, 0.0F, 0.0F};
|
|
guVector up = (guVector) {0.0F, 1.0F, 0.0F};
|
|
guVector look = (guVector) {0.0F, 0.0F, -1.0F};
|
|
boxColor = (GXColor) {233, 233, 233, 255};
|
|
|
|
guLookAt(view, &camera, &up, &look);
|
|
guPerspective(projection, 8, 640.f/480.f, 1.0f, 300.0F);
|
|
|
|
if(flatCover || !image)
|
|
{
|
|
defaultBox = Resources::GetImageData("nocoverFull.png");
|
|
GX_InitTexObj(&defaultBoxTex, defaultBox->GetImage(), defaultBox->GetWidth(), defaultBox->GetHeight(), defaultBox->GetTextureFormat(),GX_CLAMP, GX_CLAMP,GX_FALSE);
|
|
}
|
|
|
|
if(!image)
|
|
{
|
|
GX_InitTexObj(&coverTex, defaultBox->GetImage(), defaultBox->GetWidth(), defaultBox->GetHeight(), defaultBox->GetTextureFormat(),GX_CLAMP, GX_CLAMP,GX_FALSE);
|
|
flatCover = false;
|
|
}
|
|
else
|
|
GX_InitTexObj(&coverTex, image, width,height, GX_TF_RGBA8,GX_CLAMP, GX_CLAMP,GX_FALSE);
|
|
|
|
GX_InitTexObj(&boxBorderTex, boxBorder.GetImage(), boxBorder.GetWidth(), boxBorder.GetHeight(), boxBorder.GetTextureFormat(),GX_CLAMP, GX_CLAMP,GX_FALSE);
|
|
}
|
|
|
|
BoxCover::~BoxCover()
|
|
{
|
|
delete defaultBox;
|
|
|
|
for(int i = 0; i < 4; ++i)
|
|
{
|
|
char name[50];
|
|
snprintf(name, sizeof(name), "player%i_point.png", i+1);
|
|
pointer[i]->SetImage(name);
|
|
}
|
|
}
|
|
|
|
//! Remove me later
|
|
void BoxCover::WiiPADControl(GuiTrigger *t)
|
|
{
|
|
if((t->wpad.btns_d & WPAD_BUTTON_A) || (t->wpad.btns_h & WPAD_CLASSIC_BUTTON_A) || (t->pad.btns_h & PAD_BUTTON_A))
|
|
{
|
|
if(t->wpad.ir.valid)
|
|
{
|
|
moveChan = t->chan;
|
|
moveStartPosX = t->wpad.ir.x;
|
|
moveStartPosY = t->wpad.ir.y;
|
|
PosX += movePosX;
|
|
PosY += movePosY;
|
|
movePosX = 0.0f;
|
|
movePosY = 0.0f;
|
|
|
|
// GameCube and Classic Controller
|
|
s8 movX = fabs(t->pad.stickX) > 10.0f ? t->pad.stickX : t->WPAD_Stick(0, 0);
|
|
s8 movY = fabs(t->pad.stickY) > 10.0f ? t->pad.stickY : t->WPAD_Stick(0, 1);
|
|
|
|
// WiiU Pro Classic Controller
|
|
// Todo : Proper stick calibration required to allow moving cover
|
|
|
|
//! Drop stick moves of less than 10 because of sensitivity
|
|
if(fabs(movX) < 10.0f) movX = 0;
|
|
if(fabs(movY) < 10.0f) movY = 0;
|
|
if(movX < -PADCAL)
|
|
PosX += (movX + PADCAL) * Settings.PointerSpeed * fabs(PosZ)/3400.f;
|
|
if(movX > PADCAL)
|
|
PosX += (movX - PADCAL) * Settings.PointerSpeed * fabs(PosZ)/3400.f;
|
|
if(movY < -PADCAL)
|
|
PosY += (movY + PADCAL) * Settings.PointerSpeed * fabs(PosZ)/3400.f;
|
|
if(movY > PADCAL)
|
|
PosY += (movY - PADCAL) * Settings.PointerSpeed * fabs(PosZ)/3400.f;
|
|
|
|
if(moveChan >= 0 && moveChan < 4)
|
|
{
|
|
char name[50];
|
|
snprintf(name, sizeof(name), "player%i_grab.png", moveChan+1);
|
|
pointer[moveChan]->SetImage(name);
|
|
}
|
|
}
|
|
else
|
|
moveChan = -1;
|
|
}
|
|
else if(((t->wpad.btns_h & WPAD_BUTTON_A) || (t->wpad.btns_h & WPAD_CLASSIC_BUTTON_A) || (t->pad.btns_h & PAD_BUTTON_A)) && moveChan == t->chan && t->wpad.ir.valid && !effects)
|
|
{
|
|
movePosX = (t->wpad.ir.x-moveStartPosX) * fabs(PosZ)/3400.f;
|
|
movePosY = (moveStartPosY-t->wpad.ir.y) * fabs(PosZ)/3400.f;
|
|
last_manual_move_frame = frameCount;
|
|
}
|
|
else if(!(t->wpad.btns_h & WPAD_BUTTON_A) && !(t->wpad.btns_h & WPAD_CLASSIC_BUTTON_A) && !(t->pad.btns_h & PAD_BUTTON_A) && moveChan == t->chan)
|
|
{
|
|
if(moveChan >= 0 && moveChan < 4)
|
|
{
|
|
char name[50];
|
|
snprintf(name, sizeof(name), "player%i_point.png", moveChan+1);
|
|
pointer[moveChan]->SetImage(name);
|
|
}
|
|
}
|
|
|
|
if((t->wpad.btns_h & WPAD_BUTTON_UP) || (t->pad.substickY > PADCAL) )
|
|
{
|
|
RotX -= 2.0f;
|
|
last_manual_move_frame = frameCount;
|
|
}
|
|
if((t->wpad.btns_h & WPAD_BUTTON_DOWN) || (t->pad.substickY < -PADCAL) )
|
|
{
|
|
RotX += 2.0f;
|
|
last_manual_move_frame = frameCount;
|
|
}
|
|
if((t->wpad.btns_h & WPAD_BUTTON_LEFT) || (t->pad.substickX < -PADCAL) )
|
|
{
|
|
RotY -= 2.0f;
|
|
last_manual_move_frame = frameCount;
|
|
}
|
|
if((t->wpad.btns_h & WPAD_BUTTON_RIGHT) || (t->pad.substickX > PADCAL) )
|
|
{
|
|
RotY += 2.0f;
|
|
last_manual_move_frame = frameCount;
|
|
}
|
|
if((t->wpad.btns_d & WPAD_BUTTON_2) || (t->pad.btns_d & PAD_BUTTON_X) || (t->wpad.btns_d & WPAD_CLASSIC_BUTTON_X) )
|
|
{
|
|
if(RotY < 180.0f)
|
|
SetEffect(EFFECT_BOX_ROTATE_X, 10, 180);
|
|
else
|
|
SetEffect(EFFECT_BOX_ROTATE_X, -10, -180);
|
|
last_manual_move_frame = frameCount;
|
|
}
|
|
if((t->wpad.btns_h & WPAD_BUTTON_PLUS) || (t->pad.btns_h & PAD_TRIGGER_R) || (t->wpad.btns_h & WPAD_CLASSIC_BUTTON_FULL_R) )
|
|
{
|
|
if(PosZ < -2.8f)
|
|
PosZ += 0.4f*fabs(PosZ)/19.f;
|
|
}
|
|
if((t->wpad.btns_h & WPAD_BUTTON_MINUS) || (t->pad.btns_h & PAD_TRIGGER_L) || (t->wpad.btns_h & WPAD_CLASSIC_BUTTON_FULL_L) )
|
|
{
|
|
if(PosZ > -43.0f)
|
|
PosZ -= 0.4f*fabs(PosZ)/19.f;
|
|
}
|
|
}
|
|
|
|
void BoxCover::Update(GuiTrigger * t)
|
|
{
|
|
s8 movY = t->WPAD_Stick((t->wpad.exp.type == WPAD_EXP_CLASSIC), 0);
|
|
s8 movX = t->WPAD_Stick((t->wpad.exp.type == WPAD_EXP_CLASSIC), 1);
|
|
//! Drop stick moves of less than 10 because of sensitivity
|
|
if(fabs(movY) < 10.0f) movY = 0;
|
|
if(fabs(movX) < 10.0f) movX = 0;
|
|
|
|
if(movY != 0 || movX != 0)
|
|
last_manual_move_frame = frameCount;
|
|
|
|
RotY += (f32) movY / 50.0f;
|
|
RotX -= (f32) movX / 50.0f;
|
|
|
|
if(Zoomable)
|
|
WiiPADControl(t);
|
|
|
|
//! Stop movement for about 5 sec after manual move
|
|
if(frameCount-last_manual_move_frame < 250)
|
|
return;
|
|
|
|
Animation = sinf(DegToRad(AnimRotate))*2.0f;
|
|
Animation2 = cosf(DegToRad(AnimRotate))*5.0f;
|
|
AnimRotate += 0.1f;
|
|
if(AnimRotate > 360.0f)
|
|
AnimRotate = 0.0f;
|
|
}
|
|
|
|
void BoxCover::Draw()
|
|
{
|
|
u8 BoxAlpha = (int) (alpha+alphaDyn) & 0xFF;
|
|
|
|
GX_LoadProjectionMtx(projection, GX_PERSPECTIVE);
|
|
|
|
GX_ClearVtxDesc();
|
|
GX_InvVtxCache();
|
|
GX_SetVtxDesc(GX_VA_POS, GX_INDEX8);
|
|
GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT);
|
|
GX_SetVtxDesc(GX_VA_TEX0, GX_INDEX8);
|
|
|
|
//! don't draw inside of the box
|
|
GX_SetCullMode(GX_CULL_FRONT);
|
|
|
|
Mtx modelView;
|
|
Mtx modelView2;
|
|
Mtx modelView3;
|
|
|
|
guVector cubeAxis = {0,0,1};
|
|
guVector cubeAxis2 = {0,1,0};
|
|
guVector cubeAxis3 = {1,0,0};
|
|
guMtxIdentity(modelView);
|
|
guMtxRotAxisDeg(modelView3, &cubeAxis3, RotX-Animation2);
|
|
guMtxRotAxisDeg(modelView2, &cubeAxis2, RotY+Animation2+xoffsetDyn/2.0f);
|
|
guMtxRotAxisDeg(modelView, &cubeAxis, RotZ-Animation);
|
|
guMtxConcat(modelView3, modelView2, modelView2);
|
|
guMtxConcat(modelView2, modelView, modelView);
|
|
if(Settings.widescreen)
|
|
guMtxScaleApply(modelView, modelView, Settings.WSFactor, 1.0f, 1.0f);
|
|
guMtxTransApply(modelView, modelView, PosX+xoffsetDyn/680.0f+movePosX, PosY+yoffsetDyn/680.0f+movePosY, PosZ);
|
|
guMtxConcat(view,modelView,modelView);
|
|
|
|
GX_LoadPosMtxImm(modelView, GX_PNMTX0);
|
|
|
|
//! Border quads
|
|
GX_LoadTexObj(&boxBorderTex, GX_TEXMAP0);
|
|
GX_InvalidateTexAll();
|
|
|
|
GX_SetArray(GX_VA_POS, (void *) &g_boxMeshQ[0].pos, sizeof(g_boxMeshQ[0]));
|
|
GX_SetArray(GX_VA_TEX0, (void *) &g_boxMeshQ[0].texCoord, sizeof(g_boxMeshQ[0]));
|
|
|
|
GX_Begin(GX_QUADS, GX_VTXFMT0, g_boxMeshQSize);
|
|
for (u32 j = 0; j < g_boxMeshQSize; ++j)
|
|
{
|
|
GX_Position1x8(j);
|
|
GX_Color4u8(boxColor.r, boxColor.g, boxColor.b, BoxAlpha);
|
|
GX_TexCoord1x8(j);
|
|
}
|
|
GX_End();
|
|
|
|
//! Border triangles
|
|
GX_SetArray(GX_VA_POS, (void *) &g_boxMeshT[0].pos, sizeof(g_boxMeshT[0]));
|
|
GX_SetArray(GX_VA_TEX0, (void *) &g_boxMeshT[0].texCoord, sizeof(g_boxMeshT[0]));
|
|
|
|
GX_Begin(GX_TRIANGLES, GX_VTXFMT0, g_boxMeshTSize);
|
|
for (u32 j = 0; j < g_boxMeshTSize; ++j)
|
|
{
|
|
GX_Position1x8(j);
|
|
GX_Color4u8(boxColor.r, boxColor.g, boxColor.b, BoxAlpha);
|
|
GX_TexCoord1x8(j);
|
|
}
|
|
GX_End();
|
|
|
|
//! Back Cover (Might be flat)
|
|
GX_LoadTexObj(flatCover ? &defaultBoxTex : &coverTex, GX_TEXMAP0);
|
|
GX_InvalidateTexAll();
|
|
|
|
GX_SetArray(GX_VA_POS, (void *) &g_boxBackCoverMesh[0].pos, sizeof(g_boxBackCoverMesh[0]));
|
|
GX_SetArray(GX_VA_TEX0, (void *) &g_boxBackCoverMesh[0].texCoord, sizeof(g_boxBackCoverMesh[0]));
|
|
|
|
GX_Begin(GX_QUADS, GX_VTXFMT0, g_boxBackCoverMeshSize);
|
|
for (u32 j = 0; j < g_boxBackCoverMeshSize; ++j)
|
|
{
|
|
GX_Position1x8(j);
|
|
if(flatCover)
|
|
GX_Color4u8(boxColor.r, boxColor.g, boxColor.b, BoxAlpha);
|
|
else
|
|
GX_Color4u8(0xff, 0xff, 0xff, BoxAlpha);
|
|
GX_TexCoord1x8(j);
|
|
}
|
|
GX_End();
|
|
|
|
if(flatCover)
|
|
{
|
|
//! Front Flat Cover
|
|
GX_LoadTexObj(&coverTex, GX_TEXMAP0);
|
|
GX_InvalidateTexAll();
|
|
|
|
GX_SetArray(GX_VA_POS, (void *) &g_flatCoverMesh[0].pos, sizeof(g_flatCoverMesh[0]));
|
|
GX_SetArray(GX_VA_TEX0, (void *) &g_flatCoverMesh[0].texCoord, sizeof(g_flatCoverMesh[0]));
|
|
|
|
GX_Begin(GX_QUADS, GX_VTXFMT0, g_flatCoverMeshSize);
|
|
for (u32 j = 0; j < g_flatCoverMeshSize; ++j)
|
|
{
|
|
GX_Position1x8(j);
|
|
GX_Color4u8(0xff, 0xff, 0xff, 0xff);
|
|
GX_TexCoord1x8(j);
|
|
}
|
|
GX_End();
|
|
}
|
|
else
|
|
{
|
|
//! Front Cover
|
|
GX_SetArray(GX_VA_POS, (void *) &g_boxCoverMesh[0].pos, sizeof(g_boxCoverMesh[0]));
|
|
GX_SetArray(GX_VA_TEX0, (void *) &g_boxCoverMesh[0].texCoord, sizeof(g_boxCoverMesh[0]));
|
|
|
|
GX_Begin(GX_QUADS, GX_VTXFMT0, g_boxCoverMeshSize);
|
|
for (u32 j = 0; j < g_boxCoverMeshSize; ++j)
|
|
{
|
|
GX_Position1x8(j);
|
|
GX_Color4u8(0xff, 0xff, 0xff, BoxAlpha);
|
|
GX_TexCoord1x8(j);
|
|
}
|
|
GX_End();
|
|
}
|
|
|
|
//! stop cull
|
|
GX_SetCullMode(GX_CULL_NONE);
|
|
|
|
UpdateEffects();
|
|
}
|
|
|
|
void BoxCover::SetEffect(int eff, int amount, int target)
|
|
{
|
|
GuiImage::SetEffect(eff, amount, target);
|
|
}
|
|
|
|
void BoxCover::UpdateEffects()
|
|
{
|
|
GuiImage::UpdateEffects();
|
|
|
|
if(effects & EFFECT_BOX_FLY_CENTRE)
|
|
{
|
|
if(PosX > 0.1f)
|
|
PosX -= effectAmount/1200.f;
|
|
if(PosY > 0.1f)
|
|
PosY -= effectAmount/1200.f;
|
|
if(PosX < -0.1f)
|
|
PosX += effectAmount/1200.f;
|
|
if(PosY < -0.1f)
|
|
PosY += effectAmount/1200.f;
|
|
|
|
movePosX = 0.0f;
|
|
movePosY = 0.0f;
|
|
PosZ += 0.4f;
|
|
RotY += effectAmount/4.9f;
|
|
|
|
if(fabs(PosX) < 0.1f && fabs(PosY) < 0.1f)
|
|
{
|
|
PosX = 0.0f;
|
|
PosY = 0.0f;
|
|
effects = 0;
|
|
effectAmount = 0;
|
|
}
|
|
}
|
|
else if(effects & EFFECT_BOX_FLY_BACK)
|
|
{
|
|
if(PosX > PosXOrig+0.1f)
|
|
PosX -= effectAmount/1200.f;
|
|
if(PosY > PosYOrig+0.1f)
|
|
PosY -= effectAmount/1200.f;
|
|
if(PosX < PosXOrig-0.1f)
|
|
PosX += effectAmount/1200.f;
|
|
if(PosY < PosYOrig-0.1f)
|
|
PosY += effectAmount/1200.f;
|
|
|
|
PosZ -= 0.4f;
|
|
RotY -= effectAmount/4.9f;
|
|
|
|
if(movePosX > 0.1f)
|
|
movePosX -= 0.1f;
|
|
else if(movePosX < 0.1f)
|
|
movePosX += 0.1f;
|
|
if(movePosY > 0.1f)
|
|
movePosY -= 0.1f;
|
|
else if(movePosY < 0.1f)
|
|
movePosY += 0.1f;
|
|
|
|
if(fabs(PosXOrig-PosX) < 0.1f && fabs(PosYOrig-PosY) < 0.1f)
|
|
{
|
|
movePosX = 0.0f;
|
|
movePosY = 0.0f;
|
|
PosX = PosXOrig;
|
|
PosY = PosYOrig;
|
|
PosZ = PosZOrig;
|
|
effects = 0;
|
|
effectAmount = 0;
|
|
}
|
|
}
|
|
else if(effects & EFFECT_BOX_ROTATE_X)
|
|
{
|
|
RotY += effectAmount;
|
|
effectTarget -= effectAmount;
|
|
|
|
if(fabs(effectTarget) < fabs(effectAmount))
|
|
{
|
|
effects = 0;
|
|
effectAmount = 0;
|
|
effectTarget = 0;
|
|
}
|
|
}
|
|
}
|