diff --git a/SDL/src/audio/wii/SDL_wiiaudio.c b/SDL/src/audio/wii/SDL_wiiaudio.c index 5adfff9..fd474cf 100644 --- a/SDL/src/audio/wii/SDL_wiiaudio.c +++ b/SDL/src/audio/wii/SDL_wiiaudio.c @@ -44,8 +44,10 @@ static Uint8 whichab = 0; #define AUDIOSTACK 16384*2 static lwpq_t audioqueue; -static lwp_t athread; +static lwp_t athread = LWP_THREAD_NULL; static Uint8 astack[AUDIOSTACK]; +static bool stopaudio = false; +static int currentfreq; /**************************************************************************** * Audio Threading @@ -53,10 +55,11 @@ static Uint8 astack[AUDIOSTACK]; static void * AudioThread (void *arg) { - LWP_InitQueue (&audioqueue); - while (1) { + if(stopaudio) + break; + whichab ^= 1; memset(dma_buffers[whichab], 0, sizeof(dma_buffers[0])); @@ -92,7 +95,6 @@ AudioThread (void *arg) } LWP_ThreadSleep (audioqueue); } - return NULL; } @@ -107,10 +109,37 @@ DMACallback() DCFlushRange (dma_buffers[whichab], sizeof(dma_buffers[0])); AUDIO_InitDMA ((Uint32)dma_buffers[whichab], SAMPLES_PER_DMA_BUFFER*4); AUDIO_StartDMA (); - LWP_ThreadSignal (audioqueue); } +void WII_AudioStop() +{ + AUDIO_StopDMA (); + AUDIO_RegisterDMACallback(0); + stopaudio = true; + LWP_ThreadSignal(audioqueue); + LWP_JoinThread(athread, NULL); + LWP_CloseQueue (audioqueue); + athread = LWP_THREAD_NULL; +} + +void WII_AudioStart() +{ + if (currentfreq == 32000) + AUDIO_SetDSPSampleRate(AI_SAMPLERATE_32KHZ); + else + AUDIO_SetDSPSampleRate(AI_SAMPLERATE_48KHZ); + + // startup conversion thread + stopaudio = false; + LWP_InitQueue (&audioqueue); + LWP_CreateThread (&athread, AudioThread, NULL, astack, AUDIOSTACK, 67); + + // Start the first chunk of audio playing + AUDIO_RegisterDMACallback(DMACallback); + DMACallback(); +} + static int WIIAUD_OpenAudio(_THIS, SDL_AudioSpec *spec) { if (spec->freq != 32000 && spec->freq != 48000) @@ -126,16 +155,8 @@ static int WIIAUD_OpenAudio(_THIS, SDL_AudioSpec *spec) memset(dma_buffers[0], 0, sizeof(dma_buffers[0])); memset(dma_buffers[1], 0, sizeof(dma_buffers[0])); - if (spec->freq == 32000) - AUDIO_SetDSPSampleRate(AI_SAMPLERATE_32KHZ); - else - AUDIO_SetDSPSampleRate(AI_SAMPLERATE_48KHZ); - - // startup conversion thread - LWP_CreateThread (&athread, AudioThread, NULL, astack, AUDIOSTACK, 90); - - // Start the first chunk of audio playing - DMACallback(); + currentfreq = spec->freq; + WII_AudioStart(); return 1; } @@ -201,7 +222,6 @@ static SDL_AudioDevice *WIIAUD_CreateDevice(int devindex) // Initialise the Wii side of the audio system AUDIO_Init(0); - AUDIO_RegisterDMACallback(DMACallback); /* Set the function pointers */ this->OpenAudio = WIIAUD_OpenAudio; diff --git a/SDL/src/video/wii/SDL_wiivideo.c b/SDL/src/video/wii/SDL_wiivideo.c index f00c4bc..e5ab434 100644 --- a/SDL/src/video/wii/SDL_wiivideo.c +++ b/SDL/src/video/wii/SDL_wiivideo.c @@ -39,7 +39,7 @@ #include "SDL_wiievents_c.h" static const char WIIVID_DRIVER_NAME[] = "wii"; -static SDL_Thread * videothread = 0; +static lwp_t videothread = LWP_THREAD_NULL; static SDL_mutex * videomutex = 0; /*** SDL ***/ @@ -60,7 +60,8 @@ static SDL_Rect* modes_descending[] = unsigned int *xfb[2] = { NULL, NULL }; // Double buffered int whichfb = 0; // Switch -static GXRModeObj* vmode = 0; +GXRModeObj* vmode = 0; +u8 * screenTex = NULL; // screen capture static unsigned char texturemem[TEXTUREMEM_SIZE] __attribute__((aligned(32))); // GX texture static unsigned char textureconvert[TEXTUREMEM_SIZE] __attribute__((aligned(32))); // 565 mem @@ -173,34 +174,61 @@ draw_square (Mtx v) GX_End (); } +/**************************************************************************** + * TakeScreenshot + * + * Copies the current screen into a GX texture + ***************************************************************************/ + +static void TakeScreenshot() +{ + int texSize = vmode->fbWidth * vmode->efbHeight * 4; + + if(screenTex) free(screenTex); + screenTex = (u8 *)memalign(32, texSize); + if(screenTex == NULL) return; + GX_SetTexCopySrc(0, 0, vmode->fbWidth, vmode->efbHeight); + GX_SetTexCopyDst(vmode->fbWidth, vmode->efbHeight, GX_TF_RGBA8, GX_FALSE); + GX_CopyTex(screenTex, GX_FALSE); + GX_PixModeSync(); + DCFlushRange(screenTex, texSize); +} + static int quit_flip_thread = 0; int flip_thread(void * arg) { while(1) { - if (quit_flip_thread) + if(quit_flip_thread == 2) break; - whichfb ^= 1; - - SDL_mutexP(videomutex); - // clear texture objects GX_InvVtxCache(); GX_InvalidateTexAll(); + + SDL_mutexP(videomutex); // load texture into GX DCFlushRange(texturemem, TEXTUREMEM_SIZE); - GX_SetNumChans(1); GX_LoadTexObj(&texobj, GX_TEXMAP0); draw_square(view); // render textured quad - GX_CopyDisp(xfb[whichfb], GX_TRUE); GX_DrawDone (); - + GX_SetColorUpdate(GX_TRUE); + SDL_mutexV(videomutex); + if (quit_flip_thread == 1) + { + quit_flip_thread = 2; + TakeScreenshot(); + } + + whichfb ^= 1; + + GX_CopyDisp(xfb[whichfb], GX_TRUE); + VIDEO_SetNextFramebuffer(xfb[whichfb]); VIDEO_Flush(); VIDEO_WaitVSync(); @@ -212,7 +240,7 @@ static void SetupGX() { Mtx44 p; - int df = 1; + int df = 1; // deflicker on/off GX_SetViewport (0, 0, vmode->fbWidth, vmode->efbHeight, 0, 1); GX_SetDispCopyYScale ((f32) vmode->xfbHeight / (f32) vmode->efbHeight); @@ -220,7 +248,7 @@ SetupGX() GX_SetDispCopySrc (0, 0, vmode->fbWidth, vmode->efbHeight); GX_SetDispCopyDst (vmode->fbWidth, vmode->xfbHeight); - GX_SetCopyFilter (vmode->aa, vmode->sample_pattern, (df == 1) ? GX_TRUE : GX_FALSE, vmode->vfilter); // deflicker ON only for filtered mode + GX_SetCopyFilter (vmode->aa, vmode->sample_pattern, (df == 1) ? GX_TRUE : GX_FALSE, vmode->vfilter); GX_SetFieldMode (vmode->field_rendering, ((vmode->viHeight == 2 * vmode->xfbHeight) ? GX_ENABLE : GX_DISABLE)); GX_SetPixelFmt (GX_PF_RGB8_Z24, GX_ZC_LINEAR); @@ -230,6 +258,7 @@ SetupGX() GX_SetZMode (GX_TRUE, GX_LEQUAL, GX_TRUE); GX_SetColorUpdate (GX_TRUE); + GX_SetNumChans(1); guOrtho(p, 480/2, -(480/2), -(640/2), 640/2, 100, 1000); // matrix, t, b, l, r, n, f GX_LoadProjectionMtx (p, GX_ORTHOGRAPHIC); @@ -238,10 +267,10 @@ SetupGX() static void StartVideoThread() { - if(videothread == 0) + if(videothread == LWP_THREAD_NULL) { quit_flip_thread = 0; - videothread = SDL_CreateThread(flip_thread, NULL); + LWP_CreateThread (&videothread, flip_thread, NULL, NULL, 0, 68); } } @@ -730,8 +759,8 @@ void WII_VideoStart() void WII_VideoStop() { quit_flip_thread = 1; - SDL_WaitThread(videothread, NULL); - videothread = 0; + LWP_JoinThread(videothread, NULL); + videothread = LWP_THREAD_NULL; } void WII_VideoQuit(_THIS)