mirror of
https://github.com/nitraiolo/CfgUSBLoader.git
synced 2024-12-04 09:04:14 +01:00
424 lines
15 KiB
C
424 lines
15 KiB
C
/*------------------------------------------------------------------------------
|
|
Copyright (c) 2010 The GRRLIB Team
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
THE SOFTWARE.
|
|
------------------------------------------------------------------------------*/
|
|
|
|
#include <math.h>
|
|
|
|
#include <grrlib.h>
|
|
|
|
extern GRRLIB_drawSettings GRRLIB_Settings;
|
|
extern Mtx GXmodelView2D;
|
|
|
|
static guVector axis = (guVector){0, 0, 1};
|
|
|
|
/**
|
|
* Draw a texture.
|
|
* @param xpos Specifies the x-coordinate of the upper-left corner.
|
|
* @param ypos Specifies the y-coordinate of the upper-left corner.
|
|
* @param tex The texture to draw.
|
|
* @param degrees Angle of rotation.
|
|
* @param scaleX Specifies the x-coordinate scale. -1 could be used for flipping the texture horizontally.
|
|
* @param scaleY Specifies the y-coordinate scale. -1 could be used for flipping the texture vertically.
|
|
* @param color Color in RGBA format.
|
|
*/
|
|
void GRRLIB_DrawImg (const f32 xpos, const f32 ypos, const GRRLIB_texImg *tex, const f32 degrees, const f32 scaleX, const f32 scaleY, const u32 color) {
|
|
GXTexObj texObj;
|
|
u16 width, height;
|
|
Mtx m, m1, m2, mv;
|
|
|
|
if (tex == NULL || tex->data == NULL) return;
|
|
|
|
GX_InitTexObj(&texObj, tex->data, tex->w, tex->h,
|
|
GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
|
|
|
if (GRRLIB_Settings.antialias == false) {
|
|
GX_InitTexObjLOD(&texObj, GX_NEAR, GX_NEAR,
|
|
0.0f, 0.0f, 0.0f, 0, 0, GX_ANISO_1);
|
|
GX_SetCopyFilter(GX_FALSE, rmode->sample_pattern, GX_FALSE, rmode->vfilter);
|
|
}
|
|
else {
|
|
GX_SetCopyFilter(rmode->aa, rmode->sample_pattern, GX_TRUE, rmode->vfilter);
|
|
}
|
|
|
|
GX_LoadTexObj(&texObj, GX_TEXMAP0);
|
|
GX_SetTevOp (GX_TEVSTAGE0, GX_MODULATE);
|
|
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
|
|
|
|
guMtxIdentity (m1);
|
|
guMtxScaleApply(m1, m1, scaleX, scaleY, 1.0);
|
|
guMtxRotAxisDeg(m2, &axis, degrees);
|
|
guMtxConcat (m2, m1, m);
|
|
|
|
width = tex->w * 0.5;
|
|
height = tex->h * 0.5;
|
|
|
|
guMtxTransApply(m, m,
|
|
xpos +width +tex->handlex
|
|
-tex->offsetx +( scaleX *(-tex->handley *sin(-DegToRad(degrees))
|
|
-tex->handlex *cos(-DegToRad(degrees))) ),
|
|
ypos +height +tex->handley
|
|
-tex->offsety +( scaleY *(-tex->handley *cos(-DegToRad(degrees))
|
|
+tex->handlex *sin(-DegToRad(degrees))) ),
|
|
0);
|
|
guMtxConcat(GXmodelView2D, m, mv);
|
|
|
|
GX_LoadPosMtxImm(mv, GX_PNMTX0);
|
|
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
|
|
GX_Position3f32(-width, -height, 0);
|
|
GX_Color1u32 (color);
|
|
GX_TexCoord2f32(0, 0);
|
|
|
|
GX_Position3f32(width, -height, 0);
|
|
GX_Color1u32 (color);
|
|
GX_TexCoord2f32(1, 0);
|
|
|
|
GX_Position3f32(width, height, 0);
|
|
GX_Color1u32 (color);
|
|
GX_TexCoord2f32(1, 1);
|
|
|
|
GX_Position3f32(-width, height, 0);
|
|
GX_Color1u32 (color);
|
|
GX_TexCoord2f32(0, 1);
|
|
GX_End();
|
|
GX_LoadPosMtxImm(GXmodelView2D, GX_PNMTX0);
|
|
|
|
GX_SetTevOp (GX_TEVSTAGE0, GX_PASSCLR);
|
|
GX_SetVtxDesc(GX_VA_TEX0, GX_NONE);
|
|
}
|
|
|
|
/**
|
|
* Draw a textured quad.
|
|
* @param pos Vector array of the 4 points.
|
|
* @param tex The texture to draw.
|
|
* @param color Color in RGBA format.
|
|
*/
|
|
void GRRLIB_DrawImgQuad (const guVector pos[4], GRRLIB_texImg *tex, const u32 color) {
|
|
GXTexObj texObj;
|
|
Mtx m, m1, m2, mv;
|
|
|
|
if (tex == NULL || tex->data == NULL) return;
|
|
|
|
GX_InitTexObj(&texObj, tex->data, tex->w, tex->h,
|
|
GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
|
|
|
if (GRRLIB_Settings.antialias == false) {
|
|
GX_InitTexObjLOD(&texObj, GX_NEAR, GX_NEAR,
|
|
0.0f, 0.0f, 0.0f, 0, 0, GX_ANISO_1);
|
|
GX_SetCopyFilter(GX_FALSE, rmode->sample_pattern, GX_FALSE, rmode->vfilter);
|
|
}
|
|
else {
|
|
GX_SetCopyFilter(rmode->aa, rmode->sample_pattern, GX_TRUE, rmode->vfilter);
|
|
}
|
|
|
|
GX_LoadTexObj(&texObj, GX_TEXMAP0);
|
|
GX_SetTevOp (GX_TEVSTAGE0, GX_MODULATE);
|
|
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
|
|
|
|
guMtxIdentity (m1);
|
|
guMtxScaleApply(m1, m1, 1, 1, 1.0);
|
|
guMtxRotAxisDeg(m2, &axis, 0);
|
|
guMtxConcat (m2, m1, m);
|
|
guMtxConcat (GXmodelView2D, m, mv);
|
|
|
|
GX_LoadPosMtxImm(mv, GX_PNMTX0);
|
|
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
|
|
GX_Position3f32(pos[0].x, pos[0].y, 0);
|
|
GX_Color1u32 (color);
|
|
GX_TexCoord2f32(0, 0);
|
|
|
|
GX_Position3f32(pos[1].x, pos[1].y, 0);
|
|
GX_Color1u32 (color);
|
|
GX_TexCoord2f32(1, 0);
|
|
|
|
GX_Position3f32(pos[2].x, pos[2].y, 0);
|
|
GX_Color1u32 (color);
|
|
GX_TexCoord2f32(1, 1);
|
|
|
|
GX_Position3f32(pos[3].x, pos[3].y, 0);
|
|
GX_Color1u32 (color);
|
|
GX_TexCoord2f32(0, 1);
|
|
GX_End();
|
|
GX_LoadPosMtxImm(GXmodelView2D, GX_PNMTX0);
|
|
|
|
GX_SetTevOp (GX_TEVSTAGE0, GX_PASSCLR);
|
|
GX_SetVtxDesc(GX_VA_TEX0, GX_NONE);
|
|
}
|
|
|
|
/**
|
|
* Draw a tile.
|
|
* @param xpos Specifies the x-coordinate of the upper-left corner.
|
|
* @param ypos Specifies the y-coordinate of the upper-left corner.
|
|
* @param tex The texture containing the tile to draw.
|
|
* @param degrees Angle of rotation.
|
|
* @param scaleX Specifies the x-coordinate scale. -1 could be used for flipping the texture horizontally.
|
|
* @param scaleY Specifies the y-coordinate scale. -1 could be used for flipping the texture vertically.
|
|
* @param color Color in RGBA format.
|
|
* @param frame Specifies the frame to draw.
|
|
*/
|
|
void GRRLIB_DrawTile (const f32 xpos, const f32 ypos, const GRRLIB_texImg *tex, const f32 degrees, const f32 scaleX, const f32 scaleY, const u32 color, const int frame) {
|
|
GXTexObj texObj;
|
|
f32 width, height;
|
|
Mtx m, m1, m2, mv;
|
|
f32 s1, s2, t1, t2;
|
|
|
|
if (tex == NULL || tex->data == NULL) return;
|
|
|
|
// The 0.001f/x is the frame correction formula by spiffen
|
|
s1 = (frame % tex->nbtilew) * tex->ofnormaltexx;
|
|
s2 = s1 + tex->ofnormaltexx;
|
|
t1 = (int)(frame/tex->nbtilew) * tex->ofnormaltexy;
|
|
t2 = t1 + tex->ofnormaltexy;
|
|
|
|
GX_InitTexObj(&texObj, tex->data,
|
|
tex->tilew * tex->nbtilew, tex->tileh * tex->nbtileh,
|
|
GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
|
|
|
if (GRRLIB_Settings.antialias == false) {
|
|
GX_InitTexObjLOD(&texObj, GX_NEAR, GX_NEAR,
|
|
0.0f, 0.0f, 0.0f, 0, 0, GX_ANISO_1);
|
|
GX_SetCopyFilter(GX_FALSE, rmode->sample_pattern, GX_FALSE, rmode->vfilter);
|
|
}
|
|
else {
|
|
GX_SetCopyFilter(rmode->aa, rmode->sample_pattern, GX_TRUE, rmode->vfilter);
|
|
}
|
|
|
|
GX_LoadTexObj(&texObj, GX_TEXMAP0);
|
|
GX_SetTevOp (GX_TEVSTAGE0, GX_MODULATE);
|
|
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
|
|
|
|
width = tex->tilew * 0.5f;
|
|
height = tex->tileh * 0.5f;
|
|
|
|
guMtxIdentity (m1);
|
|
guMtxScaleApply(m1, m1, scaleX, scaleY, 1.0f);
|
|
guMtxRotAxisDeg(m2, &axis, degrees);
|
|
guMtxConcat (m2, m1, m);
|
|
|
|
guMtxTransApply(m, m,
|
|
xpos +width +tex->handlex
|
|
-tex->offsetx +( scaleX *(-tex->handley *sin(-DegToRad(degrees))
|
|
-tex->handlex *cos(-DegToRad(degrees))) ),
|
|
ypos +height +tex->handley
|
|
-tex->offsety +( scaleY *(-tex->handley *cos(-DegToRad(degrees))
|
|
+tex->handlex *sin(-DegToRad(degrees))) ),
|
|
0);
|
|
|
|
guMtxConcat(GXmodelView2D, m, mv);
|
|
|
|
GX_LoadPosMtxImm(mv, GX_PNMTX0);
|
|
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
|
|
GX_Position3f32(-width, -height, 0);
|
|
GX_Color1u32 (color);
|
|
GX_TexCoord2f32(s1, t1);
|
|
|
|
GX_Position3f32(width, -height, 0);
|
|
GX_Color1u32 (color);
|
|
GX_TexCoord2f32(s2, t1);
|
|
|
|
GX_Position3f32(width, height, 0);
|
|
GX_Color1u32 (color);
|
|
GX_TexCoord2f32(s2, t2);
|
|
|
|
GX_Position3f32(-width, height, 0);
|
|
GX_Color1u32 (color);
|
|
GX_TexCoord2f32(s1, t2);
|
|
GX_End();
|
|
GX_LoadPosMtxImm(GXmodelView2D, GX_PNMTX0);
|
|
|
|
GX_SetTevOp (GX_TEVSTAGE0, GX_PASSCLR);
|
|
GX_SetVtxDesc(GX_VA_TEX0, GX_NONE);
|
|
}
|
|
|
|
/**
|
|
* Draw a part of a texture.
|
|
* @param xpos Specifies the x-coordinate of the upper-left corner.
|
|
* @param ypos Specifies the y-coordinate of the upper-left corner.
|
|
* @param partx Specifies the x-coordinate of the upper-left corner in the texture.
|
|
* @param party Specifies the y-coordinate of the upper-left corner in the texture.
|
|
* @param partw Specifies the width in the texture.
|
|
* @param parth Specifies the height in the texture.
|
|
* @param tex The texture containing the tile to draw.
|
|
* @param degrees Angle of rotation.
|
|
* @param scaleX Specifies the x-coordinate scale. -1 could be used for flipping the texture horizontally.
|
|
* @param scaleY Specifies the y-coordinate scale. -1 could be used for flipping the texture vertically.
|
|
* @param color Color in RGBA format.
|
|
*/
|
|
void GRRLIB_DrawPart (const f32 xpos, const f32 ypos, const f32 partx, const f32 party, const f32 partw, const f32 parth, const GRRLIB_texImg *tex, const f32 degrees, const f32 scaleX, const f32 scaleY, const u32 color) {
|
|
GXTexObj texObj;
|
|
f32 width, height;
|
|
Mtx m, m1, m2, mv;
|
|
f32 s1, s2, t1, t2;
|
|
|
|
if (tex == NULL || tex->data == NULL) return;
|
|
|
|
// The 0.001f/x is the frame correction formula by spiffen
|
|
s1 = (partx /tex->w) +(0.001f /tex->w);
|
|
s2 = ((partx + partw)/tex->w) -(0.001f /tex->w);
|
|
t1 = (party /tex->h) +(0.001f /tex->h);
|
|
t2 = ((party + parth)/tex->h) -(0.001f /tex->h);
|
|
|
|
GX_InitTexObj(&texObj, tex->data,
|
|
tex->w, tex->h,
|
|
GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
|
|
|
if (GRRLIB_Settings.antialias == false) {
|
|
GX_InitTexObjLOD(&texObj, GX_NEAR, GX_NEAR,
|
|
0.0f, 0.0f, 0.0f, 0, 0, GX_ANISO_1);
|
|
GX_SetCopyFilter(GX_FALSE, rmode->sample_pattern, GX_FALSE, rmode->vfilter);
|
|
}
|
|
else {
|
|
GX_SetCopyFilter(rmode->aa, rmode->sample_pattern, GX_TRUE, rmode->vfilter);
|
|
}
|
|
|
|
GX_LoadTexObj(&texObj, GX_TEXMAP0);
|
|
GX_SetTevOp (GX_TEVSTAGE0, GX_MODULATE);
|
|
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
|
|
|
|
width = partw * 0.5f;
|
|
height = parth * 0.5f;
|
|
|
|
guMtxIdentity (m1);
|
|
guMtxScaleApply(m1, m1, scaleX, scaleY, 1.0f);
|
|
guMtxRotAxisDeg(m2, &axis, degrees);
|
|
guMtxConcat (m2, m1, m);
|
|
|
|
guMtxTransApply(m, m,
|
|
xpos +width +tex->handlex
|
|
-tex->offsetx +( scaleX *(-tex->handley *sin(-DegToRad(degrees))
|
|
-tex->handlex *cos(-DegToRad(degrees))) ),
|
|
ypos +height +tex->handley
|
|
-tex->offsety +( scaleY *(-tex->handley *cos(-DegToRad(degrees))
|
|
+tex->handlex *sin(-DegToRad(degrees))) ),
|
|
0);
|
|
|
|
guMtxConcat(GXmodelView2D, m, mv);
|
|
|
|
GX_LoadPosMtxImm(mv, GX_PNMTX0);
|
|
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
|
|
GX_Position3f32(-width, -height, 0);
|
|
GX_Color1u32 (color);
|
|
GX_TexCoord2f32(s1, t1);
|
|
|
|
GX_Position3f32(width, -height, 0);
|
|
GX_Color1u32 (color);
|
|
GX_TexCoord2f32(s2, t1);
|
|
|
|
GX_Position3f32(width, height, 0);
|
|
GX_Color1u32 (color);
|
|
GX_TexCoord2f32(s2, t2);
|
|
|
|
GX_Position3f32(-width, height, 0);
|
|
GX_Color1u32 (color);
|
|
GX_TexCoord2f32(s1, t2);
|
|
GX_End();
|
|
GX_LoadPosMtxImm(GXmodelView2D, GX_PNMTX0);
|
|
|
|
GX_SetTevOp (GX_TEVSTAGE0, GX_PASSCLR);
|
|
GX_SetVtxDesc(GX_VA_TEX0, GX_NONE);
|
|
}
|
|
|
|
/**
|
|
* Draw a tile in a quad.
|
|
* @param pos Vector array of the 4 points.
|
|
* @param tex The texture to draw.
|
|
* @param color Color in RGBA format.
|
|
* @param frame Specifies the frame to draw.
|
|
*/
|
|
void GRRLIB_DrawTileQuad (const guVector pos[4], GRRLIB_texImg *tex, const u32 color, const int frame) {
|
|
GXTexObj texObj;
|
|
Mtx m, m1, m2, mv;
|
|
f32 s1, s2, t1, t2;
|
|
|
|
if (tex == NULL || tex->data == NULL) return;
|
|
|
|
// The 0.001f/x is the frame correction formula by spiffen
|
|
s1 = (( (frame %tex->nbtilew) ) /(f32)tex->nbtilew) +(0.001f /tex->w);
|
|
s2 = (( (frame %tex->nbtilew) +1) /(f32)tex->nbtilew) -(0.001f /tex->w);
|
|
t1 = (((int)(frame /tex->nbtilew) ) /(f32)tex->nbtileh) +(0.001f /tex->h);
|
|
t2 = (((int)(frame /tex->nbtilew) +1) /(f32)tex->nbtileh) -(0.001f /tex->h);
|
|
|
|
GX_InitTexObj(&texObj, tex->data,
|
|
tex->tilew * tex->nbtilew, tex->tileh * tex->nbtileh,
|
|
GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
|
|
|
if (GRRLIB_Settings.antialias == false) {
|
|
GX_InitTexObjLOD(&texObj, GX_NEAR, GX_NEAR,
|
|
0.0f, 0.0f, 0.0f, 0, 0, GX_ANISO_1);
|
|
GX_SetCopyFilter(GX_FALSE, rmode->sample_pattern, GX_FALSE, rmode->vfilter);
|
|
}
|
|
else {
|
|
GX_SetCopyFilter(rmode->aa, rmode->sample_pattern, GX_TRUE, rmode->vfilter);
|
|
}
|
|
|
|
GX_LoadTexObj(&texObj, GX_TEXMAP0);
|
|
GX_SetTevOp (GX_TEVSTAGE0, GX_MODULATE);
|
|
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
|
|
|
|
guMtxIdentity (m1);
|
|
guMtxScaleApply(m1, m1, 1, 1, 1.0f);
|
|
guMtxRotAxisDeg(m2, &axis, 0);
|
|
guMtxConcat (m2, m1, m);
|
|
guMtxConcat (GXmodelView2D, m, mv);
|
|
|
|
GX_LoadPosMtxImm(mv, GX_PNMTX0);
|
|
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
|
|
GX_Position3f32(pos[0].x, pos[0].y, 0);
|
|
GX_Color1u32 (color);
|
|
GX_TexCoord2f32(s1, t1);
|
|
|
|
GX_Position3f32(pos[1].x, pos[1].y, 0);
|
|
GX_Color1u32 (color);
|
|
GX_TexCoord2f32(s2, t1);
|
|
|
|
GX_Position3f32(pos[2].x, pos[2].y, 0);
|
|
GX_Color1u32 (color);
|
|
GX_TexCoord2f32(s2, t2);
|
|
|
|
GX_Position3f32(pos[3].x, pos[3].y, 0);
|
|
GX_Color1u32 (color);
|
|
GX_TexCoord2f32(s1, t2);
|
|
GX_End();
|
|
GX_LoadPosMtxImm(GXmodelView2D, GX_PNMTX0);
|
|
|
|
GX_SetTevOp (GX_TEVSTAGE0, GX_PASSCLR);
|
|
GX_SetVtxDesc(GX_VA_TEX0, GX_NONE);
|
|
}
|
|
|
|
/**
|
|
* Call this function after drawing.
|
|
*/
|
|
void GRRLIB_Render (void) {
|
|
GX_DrawDone(); // Tell the GX engine we are done drawing
|
|
GX_InvalidateTexAll();
|
|
|
|
fb ^= 1; // Toggle framebuffer index
|
|
|
|
GX_SetZMode (GX_TRUE, GX_LEQUAL, GX_TRUE);
|
|
GX_SetColorUpdate(GX_TRUE);
|
|
GX_CopyDisp (xfb[fb], GX_TRUE);
|
|
|
|
VIDEO_SetNextFramebuffer(xfb[fb]); // Select eXternal Frame Buffer
|
|
VIDEO_Flush(); // Flush video buffer to screen
|
|
VIDEO_WaitVSync(); // Wait for screen to update
|
|
// Interlaced screens require two frames to update
|
|
if (rmode->viTVMode &VI_NON_INTERLACE) VIDEO_WaitVSync();
|
|
}
|