From aa4f79f23695517f45154e66060400dfb5ef31bc Mon Sep 17 00:00:00 2001 From: Themaister Date: Wed, 14 Dec 2011 14:26:40 +0100 Subject: [PATCH] Start working on video. --- config.def.h | 3 + driver.h | 1 + ps3/ps3_video_psgl.c | 40 ++++---- settings.c | 3 + wii/audio.c | 2 + wii/input.c | 8 +- wii/video.c | 238 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 269 insertions(+), 26 deletions(-) create mode 100644 wii/video.c diff --git a/config.def.h b/config.def.h index cbc7ed69d8..6887f103ee 100644 --- a/config.def.h +++ b/config.def.h @@ -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) diff --git a/driver.h b/driver.h index 450c8234c0..b9f9e685d0 100644 --- a/driver.h +++ b/driver.h @@ -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; diff --git a/ps3/ps3_video_psgl.c b/ps3/ps3_video_psgl.c index 1e5492b43d..5994266cb5 100644 --- a/ps3/ps3_video_psgl.c +++ b/ps3/ps3_video_psgl.c @@ -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; - - 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; + PSGLdeviceParameters params = { + .enable = PSGL_DEVICE_PARAMETERS_COLOR_FORMAT | + PSGL_DEVICE_PARAMETERS_DEPTH_FORMAT | + PSGL_DEVICE_PARAMETERS_MULTISAMPLING_MODE | + PSGL_DEVICE_PARAMETERS_BUFFERING_MODE, + + .colorFormat = GL_ARGB_SCE, + .depthFormat = GL_NONE, + .multisamplingMode = GL_MULTISAMPLING_NONE_SCE, + .bufferingMode = PSGL_BUFFERING_MODE_TRIPLE, + }; gl->gl_device = psglCreateDeviceExtended(¶ms); psglGetDeviceDimensions(gl->gl_device, &gl->win_width, &gl->win_height); diff --git a/settings.c b/settings.c index 9a1710ac59..9a66d4937c 100644 --- a/settings.c +++ b/settings.c @@ -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; diff --git a/wii/audio.c b/wii/audio.c index 7370a32fd1..19d98da004 100644 --- a/wii/audio.c +++ b/wii/audio.c @@ -19,6 +19,8 @@ #include #include #include "../general.h" +#include +#include #include #include diff --git a/wii/input.c b/wii/input.c index 039983b63c..cd65faa658 100644 --- a/wii/input.c +++ b/wii/input.c @@ -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; } } diff --git a/wii/video.c b/wii/video.c new file mode 100644 index 0000000000..dc3cb76f56 --- /dev/null +++ b/wii/video.c @@ -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 . + */ + +#include "../driver.h" +#include "../general.h" +#include +#include +#include +#include +#include + +// 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" +}; +