usbloadergx/source/BoxCover/BoxCover.cpp
2019-08-26 18:53:21 +01:00

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;
}
}
}