Start working on video.

This commit is contained in:
Themaister 2011-12-14 14:26:40 +01:00
parent 62f5c53b72
commit aa4f79f236
7 changed files with 269 additions and 26 deletions

View File

@ -37,6 +37,7 @@
#define VIDEO_XVIDEO 11
#define VIDEO_SDL 13
#define VIDEO_EXT 14
#define VIDEO_WII 24
////////////////////////
#define AUDIO_RSOUND 1
#define AUDIO_OSS 2
@ -63,6 +64,8 @@
#if defined(HAVE_OPENGL) || defined(__CELLOS_LV2__)
#define VIDEO_DEFAULT_DRIVER VIDEO_GL
#elif defined(GEKKO)
#define VIDEO_DEFAULT_DRIVER VIDEO_WII
#elif defined(HAVE_XVIDEO)
#define VIDEO_DEFAULT_DRIVER VIDEO_XVIDEO
#elif defined(HAVE_SDL)

View File

@ -171,6 +171,7 @@ extern const audio_driver_t audio_xenon360;
extern const audio_driver_t audio_ps3;
extern const audio_driver_t audio_wii;
extern const video_driver_t video_gl;
extern const video_driver_t video_wii;
extern const video_driver_t video_xvideo;
extern const video_driver_t video_sdl;
extern const video_driver_t video_ext;

View File

@ -845,36 +845,32 @@ static void gl_set_nonblock_state(void *data, bool state)
}
}
static bool psgl_init_device(gl_t * gl, const video_info_t *video, uint32_t resolution_id)
static bool psgl_init_device(gl_t *gl, const video_info_t *video, uint32_t resolution_id)
{
PSGLdeviceParameters params;
PSGLinitOptions options;
options.enable = PSGL_INIT_MAX_SPUS | PSGL_INIT_INITIALIZE_SPUS;
#if(CELL_SDK_VERSION > 0x340000)
PSGLinitOptions options = {
.enable = PSGL_INIT_MAX_SPUS | PSGL_INIT_INITIALIZE_SPUS,
.maxSPUs = 1,
.initializeSPUs = GL_FALSE,
};
#if CELL_SDK_VERSION > 0x340000
options.enable |= PSGL_INIT_TRANSIENT_MEMORY_SIZE;
#else
options.enable |= PSGL_INIT_HOST_MEMORY_SIZE;
#endif
options.maxSPUs = 1;
options.initializeSPUs = GL_FALSE;
options.persistentMemorySize = 0;
options.transientMemorySize = 0;
options.errorConsole = 0;
options.fifoSize = 0;
options.hostMemorySize = 0;
psglInit(&options);
params.enable = PSGL_DEVICE_PARAMETERS_COLOR_FORMAT | \
PSGL_DEVICE_PARAMETERS_DEPTH_FORMAT | \
PSGL_DEVICE_PARAMETERS_MULTISAMPLING_MODE;
PSGLdeviceParameters params = {
.enable = PSGL_DEVICE_PARAMETERS_COLOR_FORMAT |
PSGL_DEVICE_PARAMETERS_DEPTH_FORMAT |
PSGL_DEVICE_PARAMETERS_MULTISAMPLING_MODE |
PSGL_DEVICE_PARAMETERS_BUFFERING_MODE,
params.colorFormat = GL_ARGB_SCE;
params.depthFormat = GL_NONE;
params.multisamplingMode = GL_MULTISAMPLING_NONE_SCE;
params.enable |= PSGL_DEVICE_PARAMETERS_BUFFERING_MODE;
params.bufferingMode = PSGL_BUFFERING_MODE_TRIPLE;
.colorFormat = GL_ARGB_SCE,
.depthFormat = GL_NONE,
.multisamplingMode = GL_MULTISAMPLING_NONE_SCE,
.bufferingMode = PSGL_BUFFERING_MODE_TRIPLE,
};
gl->gl_device = psglCreateDeviceExtended(&params);
psglGetDeviceDimensions(gl->gl_device, &gl->win_width, &gl->win_height);

View File

@ -47,6 +47,9 @@ static void set_defaults(void)
case VIDEO_GL:
def_video = "gl";
break;
case VIDEO_WII:
def_video = "wii";
break;
case VIDEO_XVIDEO:
def_video = "xvideo";
break;

View File

@ -19,6 +19,8 @@
#include <stdlib.h>
#include <stdbool.h>
#include "../general.h"
#include <malloc.h>
#include <string.h>
#include <gccore.h>
#include <ogcsys.h>

View File

@ -69,7 +69,7 @@ static void *wii_input_init(void)
return (void*)-1;
}
#define _B(btn) pad_state[i][SNES_DEVICE_ID_JOYPAD_##btn] = down & PAD_BUTTON##btn
#define _B(btn) pad_state[i][SNES_DEVICE_ID_JOYPAD_##btn] = down & PAD_BUTTON_##btn
static void wii_input_poll(void *data)
{
@ -81,7 +81,7 @@ static void wii_input_poll(void *data)
uint16_t down = PAD_ButtonsDown(i);
_B(B);
_B(Y);
pad_state[i][SNES_DEVICE_ID_JOYPAD_SELECT] = down & PAD_BUTTON_Z;
pad_state[i][SNES_DEVICE_ID_JOYPAD_SELECT] = down & PAD_TRIGGER_Z;
_B(START);
_B(UP);
_B(DOWN);
@ -89,8 +89,8 @@ static void wii_input_poll(void *data)
_B(RIGHT);
_B(A);
_B(X);
_B(L);
_B(R);
pad_state[i][SNES_DEVICE_ID_JOYPAD_L] = down & PAD_TRIGGER_L;
pad_state[i][SNES_DEVICE_ID_JOYPAD_R] = down & PAD_TRIGGER_R;
}
}

238
wii/video.c Normal file
View File

@ -0,0 +1,238 @@
/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
* Copyright (C) 2010-2011 - Hans-Kristian Arntzen
*
* Some code herein may be based on code found in BSNES.
*
* SSNES is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with SSNES.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "../driver.h"
#include "../general.h"
#include <gccore.h>
#include <ogcsys.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
// All very hardcoded for now.
static void *g_framebuf[2];
static unsigned g_framebuf_index;
struct
{
uint16_t data[512 * 512];
GXTexObj obj;
} static g_tex ATTRIBUTE_ALIGN(32);
static uint8_t gx_fifo[256 * 1024] ATTRIBUTE_ALIGN(32);
static uint8_t display_list[256] ATTRIBUTE_ALIGN(32);
static size_t display_list_size;
static void setup_video_mode(GXRModeObj *mode, void *framebuf[2])
{
VIDEO_Configure(mode);
VIDEO_Flush();
for (unsigned i = 0; i < 2; i++)
VIDEO_ClearFrameBuffer(mode, framebuf[i], COLOR_BLACK);
VIDEO_SetNextFramebuffer(framebuf[0]);
VIDEO_SetBlack(false);
VIDEO_Flush();
VIDEO_WaitVSync();
}
static float verts[] = {
-1, -1, 0.5,
-1, 1, 0.5,
1, -1, 0.5,
1, 1, 0.5,
};
static float tex_coords[] = {
0, 0,
0, 1,
1, 0,
1, 1,
};
static void init_vtx(void)
{
GX_SetViewport(0, 0, 640, 480, 0, 1);
GX_SetDispCopyYScale(1.0f);
GX_SetScissor(0, 0, 640, 480);
GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
GX_SetZMode(GX_DISABLE, GX_NEVER, GX_DISABLE);
GX_SetColorUpdate(GX_TRUE);
Mtx m;
guMtxIdentity(m);
GX_LoadProjectionMtx(m, GX_ORTHOGRAPHIC);
GX_LoadPosMtxImm(m, GX_PNMTX0);
GX_ClearVtxDesc();
GX_SetVtxDesc(GX_VA_POS, GX_INDEX8);
GX_SetVtxDesc(GX_VA_TEX0, GX_INDEX8);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
GX_SetArray(GX_VA_POS, verts, 3 * sizeof(float));
GX_SetArray(GX_VA_TEX0, tex_coords, 2 * sizeof(float));
GX_SetNumTexGens(1);
GX_SetNumChans(0);
GX_SetTevOp(GX_TEVSTAGE0, GX_REPLACE);
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
GX_InvVtxCache();
}
static void init_texture(void)
{
GX_InitTexObj(&g_tex.obj, g_tex.data, 512, 512, GX_TF_RGB5A3, GX_MIRROR, GX_MIRROR, GX_FALSE);
GX_InitTexObjLOD(&g_tex.obj, GX_LINEAR, GX_LINEAR, 0, 10, 0, GX_ENABLE, GX_FALSE, GX_ANISO_1);
GX_LoadTexObj(&g_tex.obj, GX_TEXMAP0);
Mtx m;
guMtxIdentity(m);
GX_LoadTexMtxImm(m, GX_TEXMTX0, GX_MTX2x4);
GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX0);
GX_InvalidateTexAll();
}
static void build_disp_list(void)
{
DCInvalidateRange(display_list, sizeof(display_list));
GX_BeginDispList(display_list, sizeof(display_list));
GX_Begin(GX_TRIANGLESTRIP, GX_VTXFMT0, 4);
for (unsigned i = 0; i < 4; i++)
{
GX_Position1x8(i);
GX_TexCoord1x8(i);
}
GX_End();
display_list_size = GX_EndDispList();
}
static void *wii_init(const video_info_t *video,
const input_driver_t **input, void **input_data)
{
static bool inited = false;
if (!inited)
{
VIDEO_Init();
inited = true;
}
for (unsigned i = 0; i < 2; i++)
{
g_framebuf[i] = memalign(32, 640 * 528 * 6);
DCInvalidateRange(g_framebuf[i], 640 * 528 * 6);
g_framebuf[i] = MEM_K0_TO_K1(g_framebuf[i]);
}
setup_video_mode(VIDEO_GetPreferredMode(NULL), g_framebuf);
GX_Init(gx_fifo, sizeof(gx_fifo));
GX_SetDispCopyGamma(GX_GM_1_0);
GX_SetCullMode(GX_CULL_NONE);
init_vtx();
init_texture();
build_disp_list();
*input = NULL;
*input_data = NULL;
return (void*)-1;
}
static void update_texture(const uint16_t *src,
unsigned width, unsigned height, unsigned pitch)
{
float tex_w = (float)width / 512;
float tex_h = (float)height / 512;
tex_coords[4] = tex_coords[6] = tex_w;
tex_coords[3] = tex_coords[7] = tex_h;
uint16_t *dst = g_tex.data;
for (unsigned i = 0; i < height; i++,
dst += 512, src += pitch >> 1)
{
memcpy(dst, src, width * sizeof(uint16_t));
}
GX_InvalidateTexAll();
}
static bool wii_frame(void *data, const void *frame,
unsigned width, unsigned height, unsigned pitch,
const char *msg)
{
(void)data;
(void)msg;
GX_SetCopyClear((GXColor) { 0, 0, 0, 0xff }, GX_MAX_Z24);
update_texture(frame, width, height, pitch);
GX_CallDispList(display_list, display_list_size);
GX_DrawDone();
g_framebuf_index ^= 1;
GX_CopyDisp(g_framebuf[g_framebuf_index], GX_TRUE);
VIDEO_SetNextFramebuffer(g_framebuf[g_framebuf_index]);
VIDEO_Flush();
VIDEO_WaitVSync();
return true;
}
static void wii_set_nonblock_state(void *data, bool state)
{
(void)data;
(void)state;
}
static bool wii_alive(void *data)
{
(void)data;
return true;
}
static bool wii_focus(void *data)
{
(void)data;
return true;
}
static void wii_free(void *data)
{
(void)data;
GX_AbortFrame();
GX_Flush();
VIDEO_SetBlack(true);
VIDEO_Flush();
for (unsigned i = 0; i < 2; i++)
free(MEM_K1_TO_K0(g_framebuf[i]));
}
const video_driver_t video_wii = {
.init = wii_init,
.frame = wii_frame,
.alive = wii_alive,
.set_nonblock_state = wii_set_nonblock_state,
.focus = wii_focus,
.free = wii_free,
.ident = "wii"
};