From b42793c03c83bae5acd3f022819a658c4e771ed2 Mon Sep 17 00:00:00 2001 From: dborth Date: Tue, 28 Apr 2009 21:34:53 +0000 Subject: [PATCH] rewrite video system to use GX --- SDL/Makefile | 2 +- SDL/README.WII | 17 - SDL/src/main/wii/SDL_wii_main.c | 54 +-- SDL/src/video/wii/SDL_wiivideo.c | 682 +++++++++++++------------------ SDL/src/video/wii/SDL_wiivideo.h | 35 +- readme.txt | 13 + 6 files changed, 308 insertions(+), 495 deletions(-) delete mode 100644 SDL/README.WII create mode 100644 readme.txt diff --git a/SDL/Makefile b/SDL/Makefile index 39e9031..c28bd38 100644 --- a/SDL/Makefile +++ b/SDL/Makefile @@ -15,7 +15,7 @@ LIB_DIR := lib BIN_DIR := bin/wii SDL_OBJ_DIR := $(OBJ_DIR)/sdl SDL_SRC_DIR := src -INSTALL_HEADER_DIR ?= $(DEVKITPRO)/libogc/include/ +INSTALL_HEADER_DIR ?= $(DEVKITPRO)/libogc/include INSTALL_LIB_DIR ?= $(DEVKITPRO)/libogc/lib/wii # Tools. diff --git a/SDL/README.WII b/SDL/README.WII deleted file mode 100644 index 7b82bc8..0000000 --- a/SDL/README.WII +++ /dev/null @@ -1,17 +0,0 @@ -The SDL port to the Nintendo Wii - -This port uses the devKitPro toolchain, available from: -http://www.devkitpro.org - -todo: -use gx for display -use libfat for file access - -build with: -cp include/SDL_config_wii.h include/SDL_config.h -make -f Makefile.wii - -Original SDL gamecube port - taken from www.devkitpro.org -Port to Wii by mindcry (http://mindcry.cpl.de/wii/) -Many fixes (threading, audio among other stuff) by Yohanes Nugroho (http://tinyhack.com) -Renamed everything from GameCube to Wii. Built against SDL SVN - David Hudson (http://cs-sdl.sourceforge.net) diff --git a/SDL/src/main/wii/SDL_wii_main.c b/SDL/src/main/wii/SDL_wii_main.c index 2a965e3..4158277 100644 --- a/SDL/src/main/wii/SDL_wii_main.c +++ b/SDL/src/main/wii/SDL_wii_main.c @@ -12,25 +12,14 @@ #include #include -/* Globals */ -GXRModeObj* display_mode = 0; -Wii_Y1CBY2CR (*frame_buffer1)[][320] = 0; -Wii_Y1CBY2CR (*frame_buffer2)[][320] = 0; -Wii_Y1CBY2CR (*frame_buffer)[][320] = 0; - - extern void wii_keyboard_init(); extern void wii_mouse_init(); /* Do initialisation which has to be done first for the console to work */ -static void WII_Init(void) +/* Entry point */ +int main(int argc, char *argv[]) { - //printf("WII_Init ENTER\n"); - - /* Initialise the video system */ - VIDEO_Init(); - - display_mode = VIDEO_GetPreferredMode(NULL); + WII_InitVideoSystem(); WPAD_Init(); PAD_Init(); @@ -38,49 +27,12 @@ static void WII_Init(void) WPAD_SetDataFormat(0, WPAD_FMT_BTNS_ACC_IR); WPAD_SetVRes(0, 640, 480); - /* Allocate the frame buffer */ - frame_buffer1 = (Wii_Y1CBY2CR (*)[][320])(MEM_K0_TO_K1(SYS_AllocateFramebuffer(display_mode))); - //frame_buffer2 = (Wii_Y1CBY2CR (*)[][320])(MEM_K0_TO_K1(SYS_AllocateFramebuffer(display_mode))); - frame_buffer = frame_buffer1; - - /* Set up the video system with the chosen mode */ - VIDEO_Configure(display_mode); - - /* Set the frame buffer */ - VIDEO_SetNextFramebuffer(frame_buffer); - - // Show the screen. - VIDEO_SetBlack(FALSE); - VIDEO_Flush(); - VIDEO_WaitVSync(); - if (display_mode->viTVMode & VI_NON_INTERLACE) - { - VIDEO_WaitVSync(); - } - - // Initialise the debug console. - console_init(frame_buffer,20,20,display_mode->fbWidth,display_mode->xfbHeight,display_mode->fbWidth*VI_DISPLAY_PIX_SZ); - USB_Initialize(); wii_mouse_init(); //must be called first wii_keyboard_init(); - - //printf("WII_Init EXIT\n"); -} - -/* Entry point */ -int main(int argc, char *argv[]) -{ - printf("main ENTER\n"); - - /* Set up the screen mode */ - WII_Init(); - /* Call the user's main function */ return(SDL_main(argc, argv)); - - printf("main EXIT\n"); } /* This function isn't implemented */ diff --git a/SDL/src/video/wii/SDL_wiivideo.c b/SDL/src/video/wii/SDL_wiivideo.c index f3568af..4a43d5a 100644 --- a/SDL/src/video/wii/SDL_wiivideo.c +++ b/SDL/src/video/wii/SDL_wiivideo.c @@ -1,23 +1,22 @@ /* -SDL - Simple DirectMedia Layer -Copyright (C) 1997-2006 Sam Lantinga + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. -This library 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 -Lesser General Public License for more details. + This library 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 + Lesser General Public License for more details. -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -Sam Lantinga -slouken@libsdl.org + Tantric, 2009 */ #include "SDL_config.h" @@ -29,12 +28,16 @@ slouken@libsdl.org #include "../SDL_pixels_c.h" // SDL Wii specifics. +#include +#include +#include +#include #include "SDL_wiivideo.h" #include "SDL_wiievents_c.h" static const char WIIVID_DRIVER_NAME[] = "wii"; -static unsigned int y_gamma[256]; +/*** SDL ***/ static SDL_Rect mode_320; static SDL_Rect mode_640; @@ -45,10 +48,186 @@ static SDL_Rect* modes_descending[] = NULL }; +/*** 2D Video ***/ +#define HASPECT 320 +#define VASPECT 240 +#define TEXTUREMEM_SIZE (640*480*4) + +static unsigned int *xfb[2] = { NULL, NULL }; // Double buffered +static int whichfb = 0; // Switch +static GXRModeObj* display_mode = 0; +static unsigned char texturemem[TEXTUREMEM_SIZE] __attribute__((aligned(32))); // GX texture + +/*** GX ***/ +#define DEFAULT_FIFO_SIZE 256 * 1024 +static unsigned char gp_fifo[DEFAULT_FIFO_SIZE] __attribute__((aligned(32))); +static GXTexObj texobj; +static Mtx view; + +/* New texture based scaler */ +typedef struct tagcamera +{ + Vector pos; + Vector up; + Vector view; +} +camera; + +/*** Square Matrix + This structure controls the size of the image on the screen. + Think of the output as a -80 x 80 by -60 x 60 graph. +***/ +s16 square[] ATTRIBUTE_ALIGN (32) = +{ + /* + * X, Y, Z + * Values set are for roughly 4:3 aspect + */ + -HASPECT, VASPECT, 0, // 0 + HASPECT, VASPECT, 0, // 1 + HASPECT, -VASPECT, 0, // 2 + -HASPECT, -VASPECT, 0 // 3 +}; + + +static camera cam = { + {0.0F, 0.0F, 0.0F}, + {0.0F, 0.5F, 0.0F}, + {0.0F, 0.0F, -0.5F} +}; + +/**************************************************************************** + * Scaler Support Functions + ***************************************************************************/ +static void +draw_init (SDL_Surface *current) +{ + GX_ClearVtxDesc (); + GX_SetVtxDesc (GX_VA_POS, GX_INDEX8); + GX_SetVtxDesc (GX_VA_CLR0, GX_INDEX8); + GX_SetVtxDesc (GX_VA_TEX0, GX_DIRECT); + + GX_SetVtxAttrFmt (GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0); + GX_SetVtxAttrFmt (GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); + GX_SetVtxAttrFmt (GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); + + GX_SetArray (GX_VA_POS, square, 3 * sizeof (s16)); + + GX_SetNumTexGens (1); + GX_SetNumChans (0); + + GX_SetTexCoordGen (GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); + + GX_SetTevOp (GX_TEVSTAGE0, GX_REPLACE); + GX_SetTevOrder (GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLORNULL); + + memset (&view, 0, sizeof (Mtx)); + guLookAt(view, &cam.pos, &cam.up, &cam.view); + GX_LoadPosMtxImm (view, GX_PNMTX0); + + GX_InvVtxCache (); // update vertex cache + + // initialize the texture obj we are going to use + GX_InitTexObj (&texobj, texturemem, current->w, current->h, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE); + + // force texture filtering OFF + //GX_InitTexObjLOD(&texobj,GX_NEAR,GX_NEAR_MIP_NEAR,2.5,9.0,0.0,GX_FALSE,GX_FALSE,GX_ANISO_1); // original/unfiltered video mode: force texture filtering OFF + + GX_LoadTexObj (&texobj, GX_TEXMAP0); // load texture object so its ready to use +} + +static inline void +draw_vert (u8 pos, u8 c, f32 s, f32 t) +{ + GX_Position1x8 (pos); + GX_Color1x8 (c); + GX_TexCoord2f32 (s, t); +} + +static inline void +draw_square (Mtx v) +{ + Mtx m; // model matrix. + Mtx mv; // modelview matrix. + + guMtxIdentity (m); + guMtxTransApply (m, m, 0, 0, -100); + guMtxConcat (v, m, mv); + + GX_LoadPosMtxImm (mv, GX_PNMTX0); + GX_Begin (GX_QUADS, GX_VTXFMT0, 4); + draw_vert (0, 0, 0.0, 0.0); + draw_vert (1, 0, 1.0, 0.0); + draw_vert (2, 0, 1.0, 1.0); + draw_vert (3, 0, 0.0, 1.0); + GX_End (); +} + +void +WII_InitVideoSystem() +{ + Mtx44 p; + int df = 1; + + /* Initialise the video system */ + VIDEO_Init(); + display_mode = VIDEO_GetPreferredMode(NULL); + /* Set up the video system with the chosen mode */ + VIDEO_Configure(display_mode); + + // Allocate the video buffers + xfb[0] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (display_mode)); + xfb[1] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (display_mode)); + + // Initialise the debug console. + console_init(xfb[0],20,20,display_mode->fbWidth,display_mode->xfbHeight,display_mode->fbWidth*VI_DISPLAY_PIX_SZ); + + VIDEO_ClearFrameBuffer(display_mode, xfb[0], COLOR_BLACK); + VIDEO_ClearFrameBuffer(display_mode, xfb[1], COLOR_BLACK); + VIDEO_SetNextFramebuffer (xfb[0]); + + // Show the screen. + VIDEO_SetBlack(FALSE); + VIDEO_Flush(); + VIDEO_WaitVSync(); + if (display_mode->viTVMode & VI_NON_INTERLACE) + VIDEO_WaitVSync(); + else + while (VIDEO_GetNextField()) + VIDEO_WaitVSync(); + + /*** Clear out FIFO area ***/ + memset (&gp_fifo, 0, DEFAULT_FIFO_SIZE); + + /*** Initialise GX ***/ + GX_Init (&gp_fifo, DEFAULT_FIFO_SIZE); + + GXColor background = { 0, 0, 0, 0xff }; + GX_SetCopyClear (background, 0x00ffffff); + + GX_SetViewport (0, 0, display_mode->fbWidth, display_mode->efbHeight, 0, 1); + GX_SetDispCopyYScale ((f32) display_mode->xfbHeight / (f32) display_mode->efbHeight); + GX_SetScissor (0, 0, display_mode->fbWidth, display_mode->efbHeight); + + GX_SetDispCopySrc (0, 0, display_mode->fbWidth, display_mode->efbHeight); + GX_SetDispCopyDst (display_mode->fbWidth, display_mode->xfbHeight); + GX_SetCopyFilter (display_mode->aa, display_mode->sample_pattern, (df == 1) ? GX_TRUE : GX_FALSE, display_mode->vfilter); // deflicker ON only for filtered mode + + GX_SetFieldMode (display_mode->field_rendering, ((display_mode->viHeight == 2 * display_mode->xfbHeight) ? GX_ENABLE : GX_DISABLE)); + GX_SetPixelFmt (GX_PF_RGB8_Z24, GX_ZC_LINEAR); + GX_SetDispCopyGamma (GX_GM_1_0); + GX_SetCullMode (GX_CULL_NONE); + GX_SetBlendMode(GX_BM_BLEND,GX_BL_DSTALPHA,GX_BL_INVSRCALPHA,GX_LO_CLEAR); + + GX_SetZMode (GX_TRUE, GX_LEQUAL, GX_TRUE); + GX_SetColorUpdate (GX_TRUE); + + guOrtho(p, display_mode->efbHeight/2, -(display_mode->efbHeight/2), -(display_mode->fbWidth/2), display_mode->fbWidth/2, 100, 1000); // matrix, t, b, l, r, n, f + GX_LoadProjectionMtx (p, GX_ORTHOGRAPHIC); +} + int WII_VideoInit(_THIS, SDL_PixelFormat *vformat) { - unsigned int y; - // Set up the modes. mode_640.w = display_mode->fbWidth; mode_640.h = display_mode->xfbHeight; @@ -59,11 +238,10 @@ int WII_VideoInit(_THIS, SDL_PixelFormat *vformat) vformat->BitsPerPixel = 8; vformat->BytesPerPixel = 1; - // Initialise the gamma table. - for (y = 0; y < 256; ++y) - { - y_gamma[y] = 255.0f * powf(y / 255.0f, 0.5f); - } + this->hidden->buffer = NULL; + this->hidden->width = 0; + this->hidden->height = 0; + this->hidden->pitch = 0; /* We're done! */ return(0); @@ -74,253 +252,76 @@ SDL_Rect **WII_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) return &modes_descending[0]; } -static inline Wii_Y1CBY2CR PackY1CBY2CR(unsigned int y1, unsigned int cb, unsigned int y2, unsigned int cr) -{ - return (y1 << 24) | (cb << 16) | (y2 << 8) | cr; -} - -static inline unsigned int CalculateY(unsigned int r, unsigned int g, unsigned int b) -{ - const unsigned int y = (299 * r + 587 * g + 114 * b) / 1000; - return y_gamma[y]; -} - -static inline unsigned int CalculateCB(unsigned int r, unsigned int g, unsigned int b) -{ - return (-16874 * r - 33126 * g + 50000 * b + 12800000) / 100000; -} - -static inline unsigned int CalculateCR(unsigned int r, unsigned int g, unsigned int b) -{ - return (50000 * r - 41869 * g - 8131 * b + 12800000) / 100000; -} - -static void UpdateRow_8_1(const void* const src_start, const void* const src_end, Wii_Y1CBY2CR* const dst_start, const Wii_PackedPalette* palette) -{ - const Uint8* src = src_start; - Wii_Y1CBY2CR* dst = dst_start; - while (src != src_end) - { - const unsigned int left = *src++; - const unsigned int right = *src++; - *dst++ = palette->entries[left][right]; - } -} - -static void UpdateRow_8_2(const void* const src_start, const void* const src_end, Wii_Y1CBY2CR* const dst_start, const Wii_PackedPalette* palette) -{ - const Uint8* src = src_start; - Wii_Y1CBY2CR* dst = dst_start; - while (src != src_end) - { - const unsigned int left = *src++; - const unsigned int right = *src++; - *dst++ = palette->entries[left][left]; - *dst++ = palette->entries[right][right]; - } -} - -static inline Wii_Y1CBY2CR PackRGBs( - unsigned int r1, unsigned int g1, unsigned int b1, - unsigned int r2, unsigned int g2, unsigned int b2) -{ - const unsigned int cb1 = CalculateCB(r1, g1, b1); - const unsigned int cb2 = CalculateCB(r2, g2, b2); - const unsigned int cb = (cb1 + cb2) >> 1; - - const unsigned int cr1 = CalculateCR(r1, g1, b1); - const unsigned int cr2 = CalculateCR(r2, g2, b2); - const unsigned int cr = (cr1 + cr2) >> 1; - - return PackY1CBY2CR(CalculateY(r1, g1, b1), cb, CalculateY(r2, g2, b2), cr); -} - -static void UpdateRow_32_1(const void* const src_start, const void* const src_end, Wii_Y1CBY2CR* const dst_start, const Wii_PackedPalette* palette) -{ - const Uint32* src = src_start; - Wii_Y1CBY2CR* dst = dst_start; - while (src != src_end) - { - const unsigned int left = *src++; - const unsigned int r1 = left >> 24; - const unsigned int g1 = (left >> 16) & 0xff; - const unsigned int b1 = (left >> 8) & 0xff; - const unsigned int right = *src++; - const unsigned int r2 = right >> 24; - const unsigned int g2 = (right >> 16) & 0xff; - const unsigned int b2 = (right >> 8) & 0xff; - *dst++ = PackRGBs(r1, g1, b1, r2, g2, b2); - } -} - -static inline Wii_Y1CBY2CR PackRGB(unsigned int r, unsigned int g, unsigned int b) -{ - const unsigned int y = CalculateY(r, g, b); - const unsigned int cb = CalculateCB(r, g, b); - const unsigned int cr = CalculateCR(r, g, b); - - return PackY1CBY2CR(y, cb, y, cr); -} - -static void UpdateRow_32_2(const void* const src_start, const void* const src_end, Wii_Y1CBY2CR* const dst_start, const Wii_PackedPalette* palette) -{ - const Uint32* src = src_start; - Wii_Y1CBY2CR* dst = dst_start; - while (src != src_end) - { - const unsigned int left = *src++; - const unsigned int r1 = left >> 24; - const unsigned int g1 = (left >> 16) & 0xff; - const unsigned int b1 = (left >> 8) & 0xff; - const unsigned int right = *src++; - const unsigned int r2 = right >> 24; - const unsigned int g2 = (right >> 16) & 0xff; - const unsigned int b2 = (right >> 8) & 0xff; - *dst++ = PackRGB(r1, g1, b1); - *dst++ = PackRGB(r2, g2, b2); - } -} - SDL_Surface *WII_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) { - typedef struct ModeInfo - { - const SDL_Rect* resolution; - unsigned int magnification; - WII_UpdateRowFn* update_row_8; - WII_UpdateRowFn* update_row_32; - } ModeInfo; - - static const ModeInfo modes_ascending[] = - { - { &mode_320, 2, &UpdateRow_8_2, &UpdateRow_32_2 }, - { &mode_640, 1, &UpdateRow_8_1, &UpdateRow_32_1 }, - { NULL } - }; - - const ModeInfo* mode; - size_t bytes_per_pixel; - Uint32 r_mask; - Uint32 b_mask; - Uint32 g_mask; - WII_UpdateRowFn* update_row; + SDL_Rect* mode; + size_t bytes_per_pixel; + Uint32 r_mask = 0; + Uint32 b_mask = 0; + Uint32 g_mask = 0; /* Find a mode big enough to store the requested resolution */ - mode = &modes_ascending[0]; - while (mode->resolution) + mode = modes_descending[0]; + while (mode) { - if ((mode->resolution->w >= width) && (mode->resolution->h >= height)) - { + if ((mode->w >= width) && (mode->h >= height)) break; - } else - { ++mode; - } } // Didn't find a mode? - if (!mode->resolution) + if (!mode) { - SDL_SetError("Display mode (%dx%d) is too large to fit on the screen (%dx%d)", - width, height, modes_descending[0]->w, modes_descending[0]->h); + SDL_SetError("Display mode (%dx%d) is too large to fit on the screen", + width, height); return NULL; } - /* Handle the bpp */ - if (bpp <= 8) - { - bpp = 8; - r_mask = 0; - g_mask = 0; - b_mask = 0; - update_row = mode->update_row_8; - } - else - { - bpp = 32; - r_mask = 0xff000000; - g_mask = 0xff0000; - b_mask = 0xff00; - update_row = mode->update_row_32; - } bytes_per_pixel = bpp / 8; - // Free any existing buffer. - if (this->hidden->back_buffer) + if (this->hidden->buffer) { - SDL_free(this->hidden->back_buffer); - this->hidden->back_buffer = NULL; + free(this->hidden->buffer); + this->hidden->buffer = NULL; } - if (this->hidden->tmp_buffer) - { - SDL_free(this->hidden->tmp_buffer); - this->hidden->tmp_buffer = NULL; - } - - // Allocate the new buffer. - this->hidden->back_buffer = SDL_malloc(width * height * bytes_per_pixel); - if (!this->hidden->back_buffer ) + this->hidden->buffer = memalign(32, width * height * bytes_per_pixel); + if (!this->hidden->buffer ) { SDL_SetError("Couldn't allocate buffer for requested mode"); return(NULL); } - this->hidden->tmp_buffer = SDL_malloc((width+4) * (height+4) * bytes_per_pixel); - if (!this->hidden->tmp_buffer ) - { - SDL_free(this->hidden->back_buffer); - this->hidden->back_buffer = NULL; - SDL_SetError("Couldn't allocate buffer for requested mode"); - return(NULL); - } - - - - /* Allocate the new pixel format for the screen */ + // Allocate the new pixel format for the screen if (!SDL_ReallocFormat(current, bpp, r_mask, g_mask, b_mask, 0)) { - SDL_free(this->hidden->back_buffer); - this->hidden->back_buffer = NULL; - SDL_free(this->hidden->tmp_buffer); - this->hidden->tmp_buffer = NULL; + free(this->hidden->buffer); + this->hidden->buffer = NULL; SDL_SetError("Couldn't allocate new pixel format for requested mode"); return(NULL); } - // Clear the back buffer. - SDL_memset(this->hidden->back_buffer, 0, width * height * bytes_per_pixel); - SDL_memset(this->hidden->tmp_buffer, 0, width * height * bytes_per_pixel); + // Clear the buffer + SDL_memset(this->hidden->buffer, 0, width * height * bytes_per_pixel); - /* Set up the new mode framebuffer */ - //current->flags = SDL_DOUBLEBUF |( flags & SDL_FULLSCREEN); - current->flags = flags & SDL_FULLSCREEN; + // Set up the new mode framebuffer + current->flags = SDL_DOUBLEBUF |( flags & SDL_FULLSCREEN); current->w = width; current->h = height; current->pitch = current->w * bytes_per_pixel; - current->pixels = this->hidden->back_buffer; + current->pixels = this->hidden->buffer; /* Set the hidden data */ - this->hidden->update_row = update_row; - this->hidden->magnification = mode->magnification; + this->hidden->width = current->w; + this->hidden->height = current->h; + this->hidden->pitch = current->pitch; -#if 0 - // Clear the frame buffer. - for (y = 0; y < display_mode->xfbHeight; ++y) - { - unsigned int x; - for (x = 0; x < (display_mode->fbWidth / 2); ++x) - { - static const Wii_Y1CBY2CR black = PackRGB(0, 0, 0); - (*frame_buffer)[y][x] = black; - } - } -#endif + draw_init(current); /* We're done */ return(current); @@ -347,197 +348,85 @@ static void WII_UnlockHWSurface(_THIS, SDL_Surface *surface) return; } - -static void WII_FlipHWSurface(_THIS, SDL_Surface *surface) +static int WII_FlipHWSurface(_THIS, SDL_Surface *surface) { - Wii_Y1CBY2CR (*now)[][320] = 0; - now = frame_buffer; - if (frame_buffer==frame_buffer1) { - frame_buffer = frame_buffer2; - //this->hidden->back_buffer = frame_buffer1; - //surface->pixels = frame_buffer1; - } - else { - frame_buffer = frame_buffer1; - //this->hidden->back_buffer = frame_buffer2; - //surface->pixels = frame_buffer2; - } + int h, w; + long long int *dst = (long long int *) texturemem; + long long int *src1 = (long long int *) this->hidden->buffer; + long long int *src2 = (long long int *) (this->hidden->buffer + this->hidden->pitch); + long long int *src3 = (long long int *) (this->hidden->buffer + (this->hidden->pitch * 2)); + long long int *src4 = (long long int *) (this->hidden->buffer + (this->hidden->pitch * 3)); + int rowpitch = (this->hidden->pitch >> 3) * 3; + int rowadjust = (this->hidden->pitch % 8) * 4; + char *ra = NULL; - VIDEO_SetNextFramebuffer(now); - VIDEO_Flush(); - VIDEO_WaitVSync(); + whichfb ^= 1; -} + // clear texture objects + GX_InvVtxCache(); + GX_InvalidateTexAll(); -Uint32 blur(Uint32 now, Uint32 above, Uint32 below) -{ - const Uint32 R = 0xff000000; - const Uint32 G = 0x00ff0000; - const Uint32 B = 0x0000ff00; - - int r = ((((now & R)>>24)<<1) + ((above & R)>>24) + ((below & R)>>24))>>2; - int g = ((((now & G)>>16)<<1) + ((above & G)>>16) + ((below & G)>>16))>>2; - int b = ((((now & B)>>8)<<1) + ((above & B)>>8) + ((below & B)>>8))>>2; - - if (r>255) r = 255; - if (g>255) g = 255; - if (b>255) b = 255; - return r << 24 | g <<16 | b <<8; -} - -static void UpdateRect(_THIS, const SDL_Rect* const rect) -{ - const SDL_Surface* const screen = this->screen; - - if (screen) + for (h = 0; h < this->hidden->height; h += 4) { - // Constants. - const unsigned int x = rect->x; - const unsigned int y = rect->y; - const unsigned int w = rect->w; - const unsigned int h = rect->h; - const struct SDL_PrivateVideoData* const hidden = this->hidden; - WII_UpdateRowFn* const update_row = hidden->update_row; - const unsigned int magnification = hidden->magnification; - const Wii_PackedPalette* const palette = &hidden->packed_palette; - const unsigned int src_bytes_per_pixel = screen->format->BytesPerPixel; - const unsigned int src_pitch = screen->pitch; - const Wii_Y1CBY2CR* const last_dst_row = &(*frame_buffer)[(y + h) * magnification][(x * magnification) / 2]; - - // These variables change per row. - const Uint8* src_row_start = &hidden->back_buffer[(y * src_pitch) + (x * src_bytes_per_pixel)]; - const Uint8* src_row_end = src_row_start + (w * src_bytes_per_pixel); - Wii_Y1CBY2CR* dst_row_start = &(*frame_buffer)[y * magnification][(x * magnification) / 2]; - - - Uint32* src = (Uint32*)&hidden->back_buffer[(y * src_pitch) + (x * src_bytes_per_pixel)]; - - Uint32* dst = (Uint32*)&hidden->tmp_buffer[(y * screen->w) + x ]; - - - if (src_bytes_per_pixel==4) { - int i,j; - for (i=0; iw]; - register int below = (i>=screen->h-1)?0:src[screen->w]; - *dst = blur(*src,above,below); - //*dst = *src; - src++; - dst++; - } - src = srctmp + screen->w; - dst = dsttmp + screen->w; - } + for (w = 0; w < (this->hidden->width >> 2); w++) + { + *dst++ = *src1++; + *dst++ = *src2++; + *dst++ = *src3++; + *dst++ = *src4++; } + src1 += rowpitch; + src2 += rowpitch; + src3 += rowpitch; + src4 += rowpitch; - src_row_start = &hidden->tmp_buffer[(y * screen->w) + (x)]; - src_row_end = src_row_start + (w * src_bytes_per_pixel); - - // Update each row. - while (dst_row_start != last_dst_row) + if ( rowadjust ) { - // Update this row. - update_row(src_row_start, src_row_end, dst_row_start, palette); - if (magnification == 1) - { - // No magnification, just move on to the next row. - dst_row_start += 320; - } - else - { - unsigned int i; - Wii_Y1CBY2CR* next_row = dst_row_start + 320; - - // Copy each magnified row. - for (i = 1; i < magnification; ++i) - { - memcpy(next_row, dst_row_start, 320 * sizeof(Wii_Y1CBY2CR)); - next_row += 320; - } - - // Move on to the next unmagnified row. - dst_row_start = next_row; - } - - // Move on to the next row. - src_row_start += src_pitch; - src_row_end += src_pitch; + ra = (char *)src1; + src1 = (long long int *)(ra + rowadjust); + ra = (char *)src2; + src2 = (long long int *)(ra + rowadjust); + ra = (char *)src3; + src3 = (long long int *)(ra + rowadjust); + ra = (char *)src4; + src4 = (long long int *)(ra + rowadjust); } } + + // load texture into GX + DCFlushRange(texturemem, TEXTUREMEM_SIZE); + + GX_SetNumChans(1); + GX_LoadTexObj(&texobj, GX_TEXMAP0); + + draw_square(view); // render textured quad + GX_DrawDone (); + GX_CopyDisp(xfb[whichfb], GX_TRUE); + GX_Flush(); + VIDEO_SetNextFramebuffer(xfb[whichfb]); + VIDEO_Flush(); + + return(1); } static void WII_UpdateRects(_THIS, int numrects, SDL_Rect *rects) { - const SDL_Rect* rect; - const SDL_Rect* const last_rect = &rects[numrects]; - - /* Update each rect */ - for (rect = rects; rect != last_rect; ++rect) - { - /* Because we pack pixels together we need to align the rect. */ - const Sint16 x1 = rect->x & ~1; - const Sint16 x2 = (rect->x + rect->w + 1) & ~1; - const SDL_Rect aligned_rect = {x1, rect->y, x2 - x1, rect->h}; - - UpdateRect(this, &aligned_rect); - } } int WII_SetColors(_THIS, int first_color, int color_count, SDL_Color *colors) { - const int last_color = first_color + color_count; - Wii_Palette* const palette = &this->hidden->palette; - Wii_PackedPalette* const packed_palette = &this->hidden->packed_palette; - - int component; - int left; - int right; - - /* Build the YCBCR palette. */ - for (component = first_color; component != last_color; ++component) - { - const SDL_Color* const in = &colors[component - first_color]; - const unsigned int r = in->r; - const unsigned int g = in->g; - const unsigned int b = in->b; - (*palette)[component].y = CalculateY(r, g, b); - (*palette)[component].cb = CalculateCB(r, g, b); - (*palette)[component].cr = CalculateCR(r, g, b); - } - - /* Build the Y1CBY2CR palette from the YCBCR palette. */ - // @todo optimise - not all of the entries require recalculation. - for (left = 0; left != 256; ++left) - { - const unsigned int y1 = (*palette)[left].y; - const unsigned int cb1 = (*palette)[left].cb; - const unsigned int cr1 = (*palette)[left].cr; - for (right = 0; right != 256; ++right) - { - const unsigned int cb = (cb1 + (*palette)[right].cb) >> 1; - const unsigned int cr = (cr1 + (*palette)[right].cr) >> 1; - (*packed_palette).entries[left][right] = PackY1CBY2CR(y1, cb, (*palette)[right].y, cr); - } - } - - return(1); + return(0); } -/* Note: If we are terminated, this could be called in the middle of -another SDL video routine -- notably UpdateRects. -*/ void WII_VideoQuit(_THIS) { -/* if (this->screen->pixels != NULL) - { - SDL_free(this->screen->pixels); - this->screen->pixels = NULL; - }*/ + GX_AbortFrame(); + GX_Flush(); + + VIDEO_SetBlack(TRUE); + VIDEO_Flush(); } static void WII_DeleteDevice(SDL_VideoDevice *device) @@ -581,8 +470,7 @@ static SDL_VideoDevice *WII_CreateDevice(int devindex) device->SetHWAlpha = NULL; device->LockHWSurface = WII_LockHWSurface; device->UnlockHWSurface = WII_UnlockHWSurface; - //device->FlipHWSurface = WII_FlipHWSurface; - device->FlipHWSurface = NULL; + device->FlipHWSurface = WII_FlipHWSurface; device->FreeHWSurface = WII_FreeHWSurface; device->SetCaption = NULL; device->SetIcon = NULL; diff --git a/SDL/src/video/wii/SDL_wiivideo.h b/SDL/src/video/wii/SDL_wiivideo.h index 4423ba9..684a73f 100644 --- a/SDL/src/video/wii/SDL_wiivideo.h +++ b/SDL/src/video/wii/SDL_wiivideo.h @@ -16,8 +16,7 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - Sam Lantinga - slouken@libsdl.org + Tantric, 2009 */ #include "SDL_config.h" @@ -33,37 +32,15 @@ /* Hidden "this" pointer for the video functions */ #define _THIS SDL_VideoDevice *this -/* The Wii uses this frame buffer format */ -typedef Uint32 Wii_Y1CBY2CR; - -/* A single palette entry */ -typedef struct Wii_YCBCR -{ - Uint8 y; - Uint8 cb; - Uint8 cr; -} Wii_YCBCR; - -/* Types */ -typedef Wii_YCBCR Wii_Palette[256]; -typedef struct { Wii_Y1CBY2CR entries[256][256]; } Wii_PackedPalette; -typedef void (WII_UpdateRowFn)(const void*, const void*, Wii_Y1CBY2CR*, const Wii_PackedPalette*); - /* Private display data */ struct SDL_PrivateVideoData { - Uint8* back_buffer; - Uint32* tmp_buffer; - Wii_Palette palette; - Wii_PackedPalette packed_palette; - WII_UpdateRowFn* update_row; - unsigned int magnification; + Uint8* buffer; + int width; + int height; + int pitch; }; -/* Globals */ -extern GXRModeObj* display_mode; -extern Wii_Y1CBY2CR (*frame_buffer)[][320]; -extern Wii_Y1CBY2CR (*frame_buffer1)[][320]; -extern Wii_Y1CBY2CR (*frame_buffer2)[][320]; +void WII_InitVideoSystem(); #endif /* _SDL_wiivideo_h */ diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..6a6ed4b --- /dev/null +++ b/readme.txt @@ -0,0 +1,13 @@ +Port of SDL for the Nintendo Wii +http://code.google.com/p/sdl-wii/ + +This port uses the devKitPro toolchain, available from: +http://www.devkitpro.org + +Credits + +Original GameCube port www.devkitpro.org +Ported to Wii Mindcry (http://mindcry.cpl.de/wii/) +Many fixes (threading, audio, etc) Yohanes Nugroho (http://tinyhack.com) +Renamed to Wii, update to SDL SVN David Hudson (http://cs-sdl.sourceforge.net) +Audio + Video (using GX) systems rewrite Tantric