mirror of
https://github.com/gligli/nulldc-360.git
synced 2025-04-02 11:11:56 -04:00
543 lines
No EOL
14 KiB
C++
543 lines
No EOL
14 KiB
C++
/****************************************************************************
|
|
* libwiigui Template
|
|
* Tantric 2009
|
|
*
|
|
* video.cpp
|
|
* Video routines
|
|
***************************************************************************/
|
|
|
|
#include <xetypes.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <input/input.h>
|
|
#include <console/console.h>
|
|
|
|
#include <ppc/timebase.h>
|
|
#include <time/time.h>
|
|
|
|
#include <xenos/xe.h>
|
|
#include <xenos/xenos.h>
|
|
#include <xenos/edram.h>
|
|
#include <xenos/xenos.h>
|
|
|
|
#include "input.h"
|
|
#include "gui/gui.h"
|
|
#include "emu.h"
|
|
#include <Vec.h>
|
|
|
|
#include <debug.h>
|
|
|
|
int LoadTextureFromFile(char * pSrcFile, XenosSurface **ppTexture);
|
|
|
|
typedef unsigned int DWORD;
|
|
//#include "ps.h"
|
|
//#include "vs.h"
|
|
#include "shaders/vs.h"
|
|
#include "shaders/ps.t.h"
|
|
#include "shaders/ps.c.h"
|
|
//#include "shaders/ps.snes.h"
|
|
|
|
#include "shaders/simple.ps.h"
|
|
#include "shaders/simple.vs.h"
|
|
|
|
#define DEFAULT_FIFO_SIZE 256 * 1024
|
|
|
|
//static GXRModeObj *vmode; // Menu video mode
|
|
//static unsigned char gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN(32);
|
|
//static Mtx GXmodelView2D;
|
|
int screenheight;
|
|
int screenwidth;
|
|
u32 FrameTimer = 0;
|
|
|
|
static void * fb_ptr;
|
|
|
|
#define r32(o) g_pVideoDevice->regs[(o)/4]
|
|
#define w32(o, v) g_pVideoDevice->regs[(o)/4] = (v)
|
|
|
|
#define MAX_VERTEX_COUNT 65536
|
|
|
|
static struct XenosDevice _xe;
|
|
static struct XenosVertexBuffer *vb = NULL;
|
|
|
|
struct XenosDevice * g_pVideoDevice = NULL;
|
|
static struct XenosShader * g_pVertexShader = NULL;
|
|
static struct XenosShader * g_pPixelTexturedShader = NULL;
|
|
static struct XenosShader * g_pPixelColoredShader = NULL;
|
|
static struct XenosSurface * g_pEmuSurface = NULL;
|
|
//XenosSurface * g_pTexture;
|
|
|
|
matrix4x4 modelView2D;
|
|
matrix4x4 projection;
|
|
//matrix4x4 WVP;
|
|
static int nb_vertices = 0;
|
|
|
|
typedef struct {
|
|
float x, y, z, w; // 32
|
|
unsigned int color; // 36
|
|
unsigned int padding; // 40
|
|
float u, v; // 48
|
|
} __attribute__((packed)) DrawVerticeFormats;
|
|
|
|
// Init Matrices
|
|
|
|
void InitMatrices() {
|
|
matrix4x4 WVP;
|
|
matrixLoadIdentity(&WVP);
|
|
|
|
matrixLoadIdentity(&projection);
|
|
matrixOrthoRH(&projection, 640, 480, 0, 300);
|
|
|
|
matrixLoadIdentity(&modelView2D);
|
|
matrixTranslation(&modelView2D, 0, 0, -50.f);
|
|
}
|
|
|
|
/****************************************************************************
|
|
* ResetVideo_Menu
|
|
*
|
|
* Reset the video/rendering mode for the menu
|
|
****************************************************************************/
|
|
void
|
|
ResetVideo_Menu() {
|
|
// Init Matrices
|
|
InitMatrices();
|
|
}
|
|
void CreateVbText(float x, float y, float w, float h, uint32_t color, DrawVerticeFormats * Rect) {
|
|
// bottom left
|
|
Rect[0].x = x - w;
|
|
Rect[0].y = y + h;
|
|
Rect[0].u = 0;
|
|
Rect[0].v = 1;
|
|
Rect[0].color = color;
|
|
|
|
// bottom right
|
|
Rect[1].x = x + w;
|
|
Rect[1].y = y + h;
|
|
Rect[1].u = 1;
|
|
Rect[1].v = 1;
|
|
Rect[1].color = color;
|
|
|
|
// top right
|
|
Rect[2].x = x + w;
|
|
Rect[2].y = y - h;
|
|
Rect[2].u = 1;
|
|
Rect[2].v = 0;
|
|
Rect[2].color = color;
|
|
|
|
// Top left
|
|
Rect[3].x = x - w;
|
|
Rect[3].y = y - h;
|
|
Rect[3].u = 0;
|
|
Rect[3].v = 0;
|
|
Rect[3].color = color;
|
|
|
|
int i = 0;
|
|
for (i = 0; i < 4; i++) {
|
|
Rect[i].z = 0.0;
|
|
Rect[i].w = 1.0;
|
|
}
|
|
}
|
|
|
|
void CreateVb(float x, float y, float w, float h, uint32_t color, DrawVerticeFormats * Rect) {
|
|
// bottom left
|
|
Rect[0].x = x - w;
|
|
Rect[0].y = y - h;
|
|
Rect[0].u = 0;
|
|
Rect[0].v = 0;
|
|
Rect[0].color = color;
|
|
|
|
// bottom right
|
|
Rect[1].x = x + w;
|
|
Rect[1].y = y - h;
|
|
Rect[1].u = 1;
|
|
Rect[1].v = 0;
|
|
Rect[1].color = color;
|
|
|
|
// top right
|
|
Rect[2].x = x + w;
|
|
Rect[2].y = y + h;
|
|
Rect[2].u = 1;
|
|
Rect[2].v = 1;
|
|
Rect[2].color = color;
|
|
|
|
// Top left
|
|
Rect[3].x = x - w;
|
|
Rect[3].y = y + h;
|
|
Rect[3].u = 0;
|
|
Rect[3].v = 1;
|
|
Rect[3].color = color;
|
|
|
|
int i = 0;
|
|
for (i = 0; i < 4; i++) {
|
|
Rect[i].z = 0.0;
|
|
Rect[i].w = 1.0;
|
|
}
|
|
}
|
|
|
|
void CreateVbQuad(float width, float height, uint32_t color, DrawVerticeFormats * Rect) {
|
|
// bottom left
|
|
Rect[0].x = -width;
|
|
Rect[0].y = -height;
|
|
Rect[0].u = 0;
|
|
Rect[0].v = 0;
|
|
Rect[0].color = color;
|
|
|
|
// bottom right
|
|
Rect[1].x = width;
|
|
Rect[1].y = -height;
|
|
Rect[1].u = 1;
|
|
Rect[1].v = 0;
|
|
Rect[1].color = color;
|
|
|
|
// top right
|
|
Rect[2].x = width;
|
|
Rect[2].y = height;
|
|
Rect[2].u = 1;
|
|
Rect[2].v = 1;
|
|
Rect[2].color = color;
|
|
|
|
// Top left
|
|
Rect[3].x = -width;
|
|
Rect[3].y = height;
|
|
Rect[3].u = 0;
|
|
Rect[3].v = 1;
|
|
Rect[3].color = color;
|
|
|
|
int i = 0;
|
|
for (i = 0; i < 4; i++) {
|
|
Rect[i].z = 0.0;
|
|
Rect[i].w = 1.0;
|
|
}
|
|
}
|
|
|
|
void oCreateVbQuad(float width, float height, uint32_t color, DrawVerticeFormats * Rect) {
|
|
// bottom left
|
|
Rect[0].x = -width;
|
|
Rect[0].y = -height;
|
|
Rect[0].u = 0;
|
|
Rect[0].v = 0;
|
|
Rect[0].color = color;
|
|
|
|
// bottom right
|
|
Rect[1].x = width;
|
|
Rect[1].y = -height;
|
|
Rect[1].u = 1;
|
|
Rect[1].v = 0;
|
|
Rect[1].color = color;
|
|
|
|
// top right
|
|
Rect[2].x = width;
|
|
Rect[2].y = height;
|
|
Rect[2].u = 1;
|
|
Rect[2].v = 1;
|
|
Rect[2].color = color;
|
|
|
|
// Top left
|
|
Rect[3].x = -width;
|
|
Rect[3].y = height;
|
|
Rect[3].u = 0;
|
|
Rect[3].v = 1;
|
|
Rect[3].color = color;
|
|
|
|
int i = 0;
|
|
for (i = 0; i < 4; i++) {
|
|
Rect[i].z = 0.0;
|
|
Rect[i].w = 1.0;
|
|
}
|
|
}
|
|
|
|
extern "C" struct XenosDevice * GetVideoDevice() {
|
|
return g_pVideoDevice;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* InitVideo
|
|
*
|
|
* This function MUST be called at startup.
|
|
* - also sets up menu video mode
|
|
***************************************************************************/
|
|
void
|
|
InitVideo() {
|
|
xenos_init(VIDEO_MODE_AUTO);
|
|
//console_init();
|
|
|
|
g_pVideoDevice = &_xe;
|
|
|
|
Xe_Init(g_pVideoDevice);
|
|
|
|
// save real fb
|
|
fb_ptr = (void*) r32(0x6110);
|
|
|
|
XenosSurface * fb = Xe_GetFramebufferSurface(g_pVideoDevice);
|
|
|
|
screenheight = ((float) fb->height)*(720.f / (float) fb->height);
|
|
screenwidth = ((float) fb->width)*(1280.f / (float) fb->width);
|
|
|
|
Xe_Init(g_pVideoDevice);
|
|
|
|
Xe_SetRenderTarget(g_pVideoDevice, Xe_GetFramebufferSurface(g_pVideoDevice));
|
|
|
|
static const struct XenosVBFFormat vbf = {
|
|
4,
|
|
{
|
|
{XE_USAGE_POSITION, 0, XE_TYPE_FLOAT4},
|
|
{XE_USAGE_COLOR, 0, XE_TYPE_UBYTE4},
|
|
{XE_USAGE_COLOR, 1, XE_TYPE_UBYTE4}, //padding
|
|
{XE_USAGE_TEXCOORD, 0, XE_TYPE_FLOAT2},
|
|
}
|
|
};
|
|
|
|
g_pPixelTexturedShader = Xe_LoadShaderFromMemory(g_pVideoDevice, (void*) g_xps_psT);
|
|
Xe_InstantiateShader(g_pVideoDevice, g_pPixelTexturedShader, 0);
|
|
|
|
g_pPixelColoredShader = Xe_LoadShaderFromMemory(g_pVideoDevice, (void*) g_xps_psC);
|
|
Xe_InstantiateShader(g_pVideoDevice, g_pPixelColoredShader, 0);
|
|
|
|
g_pVertexShader = Xe_LoadShaderFromMemory(g_pVideoDevice, (void*) g_xvs_VSmain);
|
|
Xe_InstantiateShader(g_pVideoDevice, g_pVertexShader, 0);
|
|
|
|
Xe_ShaderApplyVFetchPatches(g_pVideoDevice, g_pVertexShader, 0, &vbf);
|
|
|
|
edram_init(g_pVideoDevice);
|
|
|
|
vb = Xe_CreateVertexBuffer(g_pVideoDevice, MAX_VERTEX_COUNT * sizeof (DrawVerticeFormats));
|
|
|
|
Xe_SetClearColor(g_pVideoDevice, 0xFFFFFFFF);
|
|
|
|
Xe_InvalidateState(g_pVideoDevice);
|
|
|
|
g_pEmuSurface = Xe_CreateTexture(g_pVideoDevice, fb->width, fb->height, 0, XE_FMT_8888 | XE_FMT_BGRA, 1);
|
|
memset(g_pEmuSurface->base, 0, g_pEmuSurface->wpitch * g_pEmuSurface->hpitch);
|
|
|
|
InitEmuVideo();
|
|
int m = 500;
|
|
while(m--){
|
|
Xe_InvalidateState(g_pVideoDevice);
|
|
Xe_Sync(g_pVideoDevice);
|
|
}
|
|
|
|
ResetVideo_Menu();
|
|
}
|
|
|
|
/****************************************************************************
|
|
* StopGX
|
|
*
|
|
* Stops GX (when exiting)
|
|
***************************************************************************/
|
|
void StopGX() {
|
|
// GX_AbortFrame();
|
|
// GX_Flush();
|
|
//
|
|
// VIDEO_SetBlack(TRUE);
|
|
// VIDEO_Flush();
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Menu_Render
|
|
*
|
|
* Renders everything current sent to GX, and flushes video
|
|
***************************************************************************/
|
|
void Menu_Render(bool vblank) {
|
|
|
|
// disable scissor
|
|
Xe_SetScissor(g_pVideoDevice,0,0,0,0,0);
|
|
|
|
FrameTimer++;
|
|
|
|
// update the hole vb
|
|
Xe_VB_Lock(g_pVideoDevice, vb, 0, MAX_VERTEX_COUNT * sizeof (DrawVerticeFormats), XE_LOCK_WRITE);
|
|
Xe_VB_Unlock(g_pVideoDevice, vb);
|
|
|
|
Xe_InvalidateState(g_pVideoDevice);
|
|
|
|
Xe_Resolve(g_pVideoDevice);
|
|
|
|
if (vblank)
|
|
while (!Xe_IsVBlank(g_pVideoDevice));
|
|
|
|
Xe_Sync(g_pVideoDevice);
|
|
|
|
nb_vertices = 4096;
|
|
}
|
|
|
|
void SetRS() {
|
|
Xe_SetBlendOp(g_pVideoDevice, XE_BLENDOP_ADD);
|
|
Xe_SetSrcBlend(g_pVideoDevice, XE_BLEND_SRCALPHA);
|
|
Xe_SetDestBlend(g_pVideoDevice, XE_BLEND_INVSRCALPHA);
|
|
Xe_SetAlphaTestEnable(g_pVideoDevice, 1);
|
|
|
|
Xe_SetCullMode(g_pVideoDevice, XE_CULL_NONE);
|
|
Xe_SetStreamSource(g_pVideoDevice, 0, vb, nb_vertices, sizeof (DrawVerticeFormats));
|
|
}
|
|
|
|
void Draw() {
|
|
SetRS();
|
|
Xe_DrawPrimitive(g_pVideoDevice, XE_PRIMTYPE_RECTLIST, 0, 1);
|
|
//nb_vertices += 4 * sizeof (DrawVerticeFormats);
|
|
nb_vertices += 512; // fixe aligement
|
|
}
|
|
|
|
void UpdatesMatrices(f32 xpos, f32 ypos, f32 width, f32 height, f32 degrees, f32 scaleX, f32 scaleY) {
|
|
#define DegToRad(a) ( (a) * 0.01745329252f )
|
|
matrix4x4 m;
|
|
matrix4x4 rotation;
|
|
matrix4x4 scale;
|
|
matrix4x4 translation;
|
|
matrix4x4 WVP;
|
|
|
|
matrixLoadIdentity(&WVP);
|
|
matrixLoadIdentity(&m);
|
|
matrixLoadIdentity(&rotation);
|
|
matrixLoadIdentity(&scale);
|
|
matrixLoadIdentity(&translation);
|
|
|
|
matrixRotationZ(&rotation, DegToRad(degrees));
|
|
matrixTranslation(&translation, xpos + width, ypos + height, 0);
|
|
matrixScaling(&scale, scaleX, scaleY, 1.0f);
|
|
//matrixScaling(&scale, width, height, 1.0f);
|
|
|
|
// // scale => rotate => translate
|
|
matrixMultiply(&m, &scale, &rotation);
|
|
matrixMultiply(&WVP, &m, &translation);
|
|
|
|
Xe_SetVertexShaderConstantF(g_pVideoDevice, 0, (float*) &WVP, 4);
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Menu_DrawImg
|
|
*
|
|
* Draws the specified image on screen using GX
|
|
***************************************************************************/
|
|
void Menu_DrawImg(f32 xpos, f32 ypos, u16 width, u16 height, XenosSurface * data,
|
|
f32 degrees, f32 scaleX, f32 scaleY, u8 alpha) {
|
|
|
|
if (data == NULL)
|
|
return;
|
|
|
|
float x, y, w, h;
|
|
|
|
x = (float) xpos;
|
|
y = (float) ypos;
|
|
w = (float) width;
|
|
h = (float) height;
|
|
|
|
x = (x / ((float) (screenwidth - 1) / 2.f)) - 1.f; // 1280/2
|
|
y = (y / ((float) (screenheight - 1) / 2.f)) - 1.f; // 720/2
|
|
|
|
w = (float) w / ((float) screenwidth - 1);
|
|
h = (float) h / ((float) screenheight - 1);
|
|
|
|
XeColor color;
|
|
|
|
color.a = alpha;
|
|
color.r = 0xFF;
|
|
color.g = 0xFF;
|
|
color.b = 0xFF;
|
|
|
|
DrawVerticeFormats* Rect = (DrawVerticeFormats*) Xe_VB_Lock(g_pVideoDevice, vb, nb_vertices, 4 * sizeof (DrawVerticeFormats), XE_LOCK_WRITE);
|
|
{
|
|
CreateVbQuad(w, h, color.lcol, Rect);
|
|
}
|
|
Xe_VB_Unlock(g_pVideoDevice, vb);
|
|
|
|
Xe_SetTexture(g_pVideoDevice, 0, data);
|
|
|
|
UpdatesMatrices(x, y, w, h, degrees, scaleX, scaleY);
|
|
|
|
Xe_SetShader(g_pVideoDevice, SHADER_TYPE_PIXEL, g_pPixelTexturedShader, 0);
|
|
Xe_SetShader(g_pVideoDevice, SHADER_TYPE_VERTEX, g_pVertexShader, 0);
|
|
|
|
Draw();
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Menu_DrawRectangle
|
|
*
|
|
* Draws a rectangle at the specified coordinates using GX
|
|
***************************************************************************/
|
|
void Menu_DrawRectangle(f32 x, f32 y, f32 width, f32 height, GXColor color, u8 filled) {
|
|
float w, h;
|
|
|
|
x = (float) x;
|
|
y = (float) y;
|
|
w = (float) width;
|
|
h = (float) height;
|
|
|
|
x = (x / ((float) (screenwidth - 1) / 2.f)) - 1.f; // 1280/2
|
|
y = (y / ((float) (screenheight - 1) / 2.f)) - 1.f; // 720/2
|
|
|
|
w = (float) w / ((float) screenwidth - 1);
|
|
h = (float) h / ((float) screenheight - 1);
|
|
|
|
|
|
XeColor _color;
|
|
|
|
_color.a = color.a;
|
|
_color.r = color.r;
|
|
_color.g = color.g;
|
|
_color.b = color.b;
|
|
|
|
DrawVerticeFormats* Rect = (DrawVerticeFormats*) Xe_VB_Lock(g_pVideoDevice, vb, nb_vertices, 4 * sizeof (DrawVerticeFormats), XE_LOCK_WRITE);
|
|
{
|
|
CreateVbQuad(w, h, _color.lcol, Rect);
|
|
//CreateVb(x,y,w,h,_color.lcol,Rect);
|
|
}
|
|
Xe_VB_Unlock(g_pVideoDevice, vb);
|
|
|
|
Xe_SetTexture(g_pVideoDevice, 0, NULL);
|
|
|
|
UpdatesMatrices(x, y, w, h, 0, 1, 1);
|
|
|
|
Xe_SetShader(g_pVideoDevice, SHADER_TYPE_PIXEL, g_pPixelColoredShader, 0);
|
|
Xe_SetShader(g_pVideoDevice, SHADER_TYPE_VERTEX, g_pVertexShader, 0);
|
|
|
|
Draw();
|
|
}
|
|
|
|
void Menu_T(XenosSurface * surf, f32 texWidth, f32 texHeight, int16_t screenX, int16_t screenY, GXColor color) {
|
|
float x, y, w, h;
|
|
if (surf == NULL)
|
|
return;
|
|
|
|
x = (float) screenX;
|
|
y = (float) screenY;
|
|
w = (float) texWidth;
|
|
h = (float) texHeight;
|
|
|
|
x = (x / ((float) (screenwidth - 1) / 2.f)) - 1.f; // 1280/2
|
|
y = (y / ((float) (screenheight - 1) / 2.f)) - 1.f; // 720/2
|
|
|
|
w = (float) w / ((float) screenwidth - 1);
|
|
h = (float) h / ((float) screenheight - 1);
|
|
|
|
DrawVerticeFormats* Rect = (DrawVerticeFormats*) Xe_VB_Lock(g_pVideoDevice, vb, nb_vertices, 4 * sizeof (DrawVerticeFormats), XE_LOCK_WRITE);
|
|
{
|
|
XeColor _color;
|
|
|
|
_color.a = color.a;
|
|
_color.r = color.r;
|
|
_color.g = color.g;
|
|
_color.b = color.b;
|
|
|
|
CreateVbText(0, 0, w, h, _color.lcol, Rect);
|
|
}
|
|
Xe_VB_Unlock(g_pVideoDevice, vb);
|
|
|
|
Xe_SetTexture(g_pVideoDevice, 0, surf);
|
|
|
|
UpdatesMatrices(x, y, w, h, 0, 1, 1);
|
|
|
|
Xe_SetShader(g_pVideoDevice, SHADER_TYPE_PIXEL, g_pPixelTexturedShader, 0);
|
|
Xe_SetShader(g_pVideoDevice, SHADER_TYPE_VERTEX, g_pVertexShader, 0);
|
|
|
|
Draw();
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Update Video
|
|
***************************************************************************/
|
|
XenosSurface * get_video_surface()
|
|
{
|
|
return g_pEmuSurface;
|
|
} |