mirror of
https://github.com/dborth/snes9xgx.git
synced 2024-12-18 07:11:50 +01:00
161 lines
6.1 KiB
C++
161 lines
6.1 KiB
C++
#include <xenos/xe.h>
|
|
#include <stdio.h>
|
|
|
|
#include "gfx.h"
|
|
|
|
extern "C" void do_edram_foo(struct XenosDevice *xe, int complete);
|
|
|
|
struct XenosSurface *gfxplane;
|
|
struct XenosDevice _xe, *xe;
|
|
struct XenosShader *sh_ps, *sh_vs;
|
|
struct XenosVertexBuffer *vb;
|
|
struct XenosIndexBuffer *ib;
|
|
|
|
static unsigned char content_datapspsu[] = {
|
|
0x10, 0x2a, 0x11, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x4b,
|
|
0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x30, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x73, 0x00, 0xab, 0xab, 0x00, 0x04, 0x00, 0x0c,
|
|
0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40,
|
|
0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0xab, 0xab,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x21, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
|
|
0x00, 0x00, 0xf0, 0x50, 0x00, 0x01, 0x10, 0x02, 0x00, 0x00, 0x12, 0x00, 0xc4, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01,
|
|
0x1f, 0x1f, 0xf6, 0x88, 0x00, 0x00, 0x40, 0x00, 0xc8, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
|
|
static unsigned char content_datavsvsu[] = {
|
|
0x10, 0x2a, 0x11, 0x01, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x23,
|
|
0xff, 0xfe, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x1c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40,
|
|
0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
|
|
0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x21,
|
|
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x90,
|
|
0x00, 0x10, 0x00, 0x03, 0x00, 0x30, 0x50, 0x04, 0x00, 0x00, 0xf0, 0x50, 0x00, 0x00, 0x10, 0x06,
|
|
0x30, 0x05, 0x20, 0x03, 0x00, 0x00, 0x12, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x05,
|
|
0x00, 0x00, 0x12, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x06, 0x00, 0x00, 0x22, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x05, 0xf8, 0x10, 0x00, 0x00, 0x00, 0x06, 0x88, 0x00, 0x00, 0x00, 0x00,
|
|
0x05, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x06, 0x88, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x0f, 0x80, 0x3e,
|
|
0x00, 0x00, 0x00, 0x00, 0xe2, 0x01, 0x01, 0x00, 0xc8, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
|
|
void videoInit(void)
|
|
{
|
|
xe = &_xe;
|
|
/* initialize the GPU */
|
|
Xe_Init(xe);
|
|
|
|
gfxplane = Xe_CreateTexture(xe, MAX_SNES_WIDTH, MAX_SNES_HEIGHT, 1, 4 | 0x40, 0);
|
|
|
|
GFX.Screen = (uint16*)(((unsigned char*)gfxplane->base) + gfxplane->pitch * 2 + 2 * 2);
|
|
GFX.Pitch = gfxplane->pitch;
|
|
|
|
/* create a render target (the framebuffer) */
|
|
struct XenosSurface *fb = Xe_GetFramebufferSurface(xe);
|
|
Xe_SetRenderTarget(xe, fb);
|
|
|
|
printf("framebuffer at: %p, pitch %d\n", fb->base, fb->pitch);
|
|
|
|
/* let's define a vertex buffer format */
|
|
static const struct XenosVBFFormat vbf =
|
|
{
|
|
2, {
|
|
{XE_USAGE_POSITION, 0, XE_TYPE_FLOAT2},
|
|
{XE_USAGE_TEXCOORD, 0, XE_TYPE_FLOAT2},
|
|
}
|
|
};
|
|
|
|
float rect[] = {
|
|
-1, 1, 0, 0,
|
|
-1, -1, 0, 1,
|
|
1, 1, 1, 0,
|
|
1, -1, 1, 1
|
|
};
|
|
|
|
unsigned short rect_indices[] = {0, 2, 1, 1, 2, 3};
|
|
|
|
printf("loading pixel shader...\n");
|
|
/* load pixel shader */
|
|
sh_ps = Xe_LoadShaderFromMemory(xe, content_datapspsu);
|
|
Xe_InstantiateShader(xe, sh_ps, 0);
|
|
|
|
printf("loading vertex shader...\n");
|
|
/* load vertex shader */
|
|
sh_vs = Xe_LoadShaderFromMemory(xe, content_datavsvsu);
|
|
Xe_InstantiateShader(xe, sh_vs, 0);
|
|
Xe_ShaderApplyVFetchPatches(xe, sh_vs, 0, &vbf);
|
|
|
|
printf("create vb...\n");
|
|
/* create and fill vertex buffer */
|
|
vb = Xe_CreateVertexBuffer(xe, sizeof(rect));
|
|
void *v = Xe_VB_Lock(xe, vb, 0, sizeof(rect), XE_LOCK_WRITE);
|
|
memcpy(v, rect, sizeof(rect));
|
|
Xe_VB_Unlock(xe, vb);
|
|
|
|
printf("create ib...\n");
|
|
/* create and fill index buffer */
|
|
ib = Xe_CreateIndexBuffer(xe, sizeof(rect_indices), XE_FMT_INDEX16);
|
|
unsigned short *i = (unsigned short*)Xe_IB_Lock(xe, ib, 0, sizeof(rect_indices), XE_LOCK_WRITE);
|
|
memcpy(i, rect_indices, sizeof(rect_indices));
|
|
Xe_IB_Unlock(xe, ib);
|
|
|
|
do_edram_foo(xe, 1);
|
|
}
|
|
|
|
|
|
/* void waitVBlank(void)
|
|
{
|
|
while (!Xe_IsVBlank(xe));
|
|
} */
|
|
|
|
void videoBlit(int xres, int yres)
|
|
{
|
|
/* flush cache */
|
|
Xe_Surface_LockRect(xe, gfxplane, 0, 0, 0, 0, XE_LOCK_WRITE);
|
|
Xe_Surface_Unlock(xe, gfxplane);
|
|
|
|
|
|
/* we don't want the border. Note that because of interpolation, some fractional pixel values might get through. */
|
|
float *v = (float*)Xe_VB_Lock(xe, vb, 0, 16*4, XE_LOCK_WRITE);
|
|
v[2] = v[6] = 2.0 / xres;
|
|
v[3] = v[11] = 2.0 / yres;
|
|
Xe_VB_Unlock(xe, vb);
|
|
|
|
/* create new surface with right size */
|
|
XenosSurface surface = *gfxplane;
|
|
surface.width = xres;
|
|
surface.height = yres;
|
|
/* begin a new frame, i.e. reset all renderstates to the default */
|
|
Xe_InvalidateState(xe);
|
|
|
|
int max_vertices = 4;
|
|
int nr_primitives = 2;
|
|
|
|
/* draw cube */
|
|
Xe_SetShader(xe, SHADER_TYPE_PIXEL, sh_ps, 0);
|
|
Xe_SetShader(xe, SHADER_TYPE_VERTEX, sh_vs, 0);
|
|
Xe_SetStreamSource(xe, 0, vb, 0, 4); /* using this vertex buffer */
|
|
Xe_SetIndices(xe, ib); /* ... this index buffer... */
|
|
Xe_SetTexture(xe, 0, &surface); /* ... and this texture */
|
|
Xe_DrawIndexedPrimitive(xe, XE_PRIMTYPE_TRIANGLELIST, 0, 0, max_vertices, 0, nr_primitives);
|
|
|
|
/* clear to white */
|
|
Xe_SetClearColor(xe, ~0);
|
|
|
|
// waitVBlank();
|
|
|
|
/* resolve (and clear) */
|
|
Xe_Resolve(xe);
|
|
|
|
/* wait for render finish */
|
|
Xe_Sync(xe);
|
|
}
|
|
|