Created
June 25, 2012 18:25
-
-
Save ToadKing/2990347 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/Makefile.wii b/Makefile.wii | |
index 89364c3..c6a6c38 100644 | |
--- a/Makefile.wii | |
+++ b/Makefile.wii | |
@@ -14,6 +14,8 @@ CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc | |
CXX = $(DEVKITPPC)/bin/powerpc-eabi-g++ | |
LD = $(DEVKITPPC)/bin/powerpc-eabi-ld | |
+FREETYPECONFIG = $(DEVKITPRO)/portlibs/ppc/bin/freetype-config | |
+ | |
DOL_TARGET := retroarch.dol | |
ELF_TARGET := retroarch.elf | |
@@ -21,10 +23,10 @@ INCLUDE := -I. -I$(DEVKITPRO)/libogc/include | |
LIBDIRS := -L$(DEVKITPRO)/libogc/lib/wii -L. | |
MACHDEP := -DGEKKO -DHW_RVL -mrvl -mcpu=750 -meabi -mhard-float | |
-CFLAGS += -Wall -std=gnu99 $(MACHDEP) $(INCLUDE) | |
-CXXFLAGS += -Wall -std=gnu99 $(MACHDEP) $(INCLUDE) | |
-LDFLAGS := $(MACHDEP) | |
-LIBS := -lfat -lretro -lwiiuse -logc -lbte -lfreetype | |
+CFLAGS += -Wall -std=gnu99 $(MACHDEP) $(INCLUDE) $(shell $(FREETYPECONFIG) --cflags) | |
+CXXFLAGS += -Wall -std=gnu99 $(MACHDEP) $(INCLUDE) $(shell $(FREETYPECONFIG) --cflags) | |
+LDFLAGS := $(MACHDEP) $(shell $(FREETYPECONFIG) --libs) | |
+LIBS := -lfat -lretro -lwiiuse -logc -lbte | |
OBJ = console/griffin/griffin.o console/font.bmpobj console/rzlib/rzlib.o | |
diff --git a/wii/audio.c b/wii/audio.c | |
index 06ba4b3..541946a 100644 | |
--- a/wii/audio.c | |
+++ b/wii/audio.c | |
@@ -23,9 +23,9 @@ | |
#include <gccore.h> | |
#include <ogcsys.h> | |
-#define CHUNK_FRAMES 256 | |
+#define CHUNK_FRAMES 8 | |
#define CHUNK_SIZE (CHUNK_FRAMES * sizeof(uint32_t)) | |
-#define BLOCKS 4 | |
+#define BLOCKS 128 | |
typedef struct | |
{ | |
@@ -40,7 +40,7 @@ typedef struct | |
bool nonblock; | |
} wii_audio_t; | |
-static wii_audio_t *g_audio; | |
+static wii_audio_t *g_audio = NULL; | |
static void dma_callback(void) | |
{ | |
@@ -55,19 +55,33 @@ static void dma_callback(void) | |
static void *wii_audio_init(const char *device, unsigned rate, unsigned latency) | |
{ | |
- static bool inited = false; | |
- if (!inited) | |
+ AUDIO_Init(NULL); | |
+ AUDIO_RegisterDMACallback(dma_callback); | |
+ | |
+ if (abs((int) rate - 32000) < 1000) | |
+ { | |
+ AUDIO_SetDSPSampleRate(AI_SAMPLERATE_32KHZ); | |
+ g_settings.audio.out_rate = 32000; | |
+ } | |
+ else | |
{ | |
- AUDIO_Init(NULL); | |
AUDIO_SetDSPSampleRate(AI_SAMPLERATE_48KHZ); | |
g_settings.audio.out_rate = 48000; | |
- AUDIO_RegisterDMACallback(dma_callback); | |
- inited = true; | |
} | |
- g_audio = memalign(32, sizeof(*g_audio)); | |
- memset(g_audio, 0, sizeof(*g_audio)); | |
- LWP_InitQueue(&g_audio->cond); | |
+ if (!g_audio) | |
+ { | |
+ g_audio = memalign(32, sizeof(*g_audio)); | |
+ memset(g_audio, 0, sizeof(*g_audio)); | |
+ LWP_InitQueue(&g_audio->cond); | |
+ } | |
+ else | |
+ { | |
+ memset(g_audio->data, 0, sizeof(g_audio->data)); | |
+ g_audio->dma_busy = g_audio->dma_next = 0; | |
+ g_audio->write_ptr = 0; | |
+ g_audio->nonblock = false; | |
+ } | |
g_audio->dma_write = BLOCKS - 1; | |
DCFlushRange(g_audio->data, sizeof(g_audio->data)); | |
@@ -130,6 +144,12 @@ static bool wii_audio_start(void *data) | |
static void wii_audio_free(void *data) | |
{ | |
AUDIO_StopDMA(); | |
+ AUDIO_RegisterDMACallback(NULL); | |
+ if (g_audio && g_audio->cond) | |
+ { | |
+ LWP_CloseQueue(g_audio->cond); | |
+ g_audio->cond = 0; | |
+ } | |
if (data) | |
free(data); | |
g_audio = NULL; | |
diff --git a/wii/main.c b/wii/main.c | |
index e12dca3..9cf0ef2 100644 | |
--- a/wii/main.c | |
+++ b/wii/main.c | |
@@ -158,6 +158,8 @@ int main(void) | |
do{ | |
repeat = rarch_main_iterate(); | |
}while(repeat && !g_console.frame_advance_enable); | |
+ | |
+ audio_stop_func(); | |
} | |
if(g_console.emulator_initialized) | |
diff --git a/wii/video.c b/wii/video.c | |
index 338f8b0..55f4665 100644 | |
--- a/wii/video.c | |
+++ b/wii/video.c | |
@@ -25,12 +25,13 @@ | |
// All very hardcoded for now. | |
-static void *g_framebuf[3]; | |
-static unsigned g_vi_framebuf; | |
-static unsigned g_render_framebuf; | |
+static void *g_framebuf[2]; | |
+static unsigned g_current_framebuf; | |
static unsigned g_filter; | |
static bool g_vsync; | |
+static lwpq_t g_video_cond; | |
+static volatile bool g_draw_done; | |
struct | |
{ | |
@@ -45,25 +46,24 @@ static size_t display_list_size; | |
static void retrace_callback(u32 retrace_count) | |
{ | |
(void)retrace_count; | |
- VIDEO_SetNextFramebuffer(g_framebuf[g_vi_framebuf % 3]); | |
- VIDEO_Flush(); | |
- if (g_vi_framebuf < g_render_framebuf) | |
- g_vi_framebuf++; | |
+ g_draw_done = true; | |
+ LWP_ThreadSignal(g_video_cond); | |
} | |
static void setup_video_mode(GXRModeObj *mode) | |
{ | |
VIDEO_Configure(mode); | |
- for (unsigned i = 0; i < 3; i++) | |
+ for (unsigned i = 0; i < 2; i++) | |
{ | |
g_framebuf[i] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(mode)); | |
VIDEO_ClearFrameBuffer(mode, g_framebuf[i], COLOR_BLACK); | |
} | |
- g_vi_framebuf = 0; | |
- g_render_framebuf = 1; | |
+ g_current_framebuf = 0; | |
+ g_draw_done = true; | |
+ LWP_InitQueue(&g_video_cond); | |
VIDEO_SetNextFramebuffer(g_framebuf[0]); | |
- VIDEO_SetPreRetraceCallback(retrace_callback); | |
+ VIDEO_SetPostRetraceCallback(retrace_callback); | |
VIDEO_SetBlack(false); | |
VIDEO_Flush(); | |
VIDEO_WaitVSync(); | |
@@ -171,7 +171,7 @@ void wii_video_deinit(void) | |
VIDEO_SetBlack(true); | |
VIDEO_Flush(); | |
- for (unsigned i = 0; i < 3; i++) | |
+ for (unsigned i = 0; i < 2; i++) | |
free(MEM_K1_TO_K0(g_framebuf[i])); | |
} | |
@@ -186,6 +186,84 @@ static void *wii_init(const video_info_t *video, | |
return (void*)-1; | |
} | |
+static void update_texture_asm(const uint32_t *src, | |
+ unsigned width, unsigned height, unsigned pitch) | |
+{ | |
+ register uint32_t tmp0, tmp1, tmp2, tmp3, line2, line2b, line3, line3b, line4, line4b, line5; | |
+ register uint32_t ormask = 0x80008000u; | |
+ register uint32_t *dst = g_tex.data; | |
+ | |
+ __asm__ __volatile__ ( | |
+ " srwi %[width], %[width], 2 \n" | |
+ " srwi %[height], %[height], 2 \n" | |
+ " subi %[tmp3], %[dst], 4 \n" | |
+ " mr %[dst], %[tmp3] \n" | |
+ " subi %[dst], %[dst], 4 \n" | |
+ " mr %[line2], %[pitch] \n" | |
+ " addi %[line2b], %[line2], 4 \n" | |
+ " mulli %[line3], %[pitch], 2 \n" | |
+ " addi %[line3b], %[line3], 4 \n" | |
+ " mulli %[line4], %[pitch], 3 \n" | |
+ " addi %[line4b], %[line4], 4 \n" | |
+ " mulli %[line5], %[pitch], 4 \n" | |
+ | |
+ "2: mtctr %[width] \n" | |
+ " mr %[tmp0], %[src] \n" | |
+ | |
+ "1: lwz %[tmp1], 0(%[src]) \n" | |
+ " or %[tmp1], %[tmp1], %[ormask] \n" | |
+ " stwu %[tmp1], 8(%[dst]) \n" | |
+ " lwz %[tmp2], 4(%[src]) \n" | |
+ " or %[tmp2], %[tmp2], %[ormask] \n" | |
+ " stwu %[tmp2], 8(%[tmp3]) \n" | |
+ | |
+ " lwzx %[tmp1], %[line2], %[src] \n" | |
+ " or %[tmp1], %[tmp1], %[ormask] \n" | |
+ " stwu %[tmp1], 8(%[dst]) \n" | |
+ " lwzx %[tmp2], %[line2b], %[src] \n" | |
+ " or %[tmp2], %[tmp2], %[ormask] \n" | |
+ " stwu %[tmp2], 8(%[tmp3]) \n" | |
+ | |
+ " lwzx %[tmp1], %[line3], %[src] \n" | |
+ " or %[tmp1], %[tmp1], %[ormask] \n" | |
+ " stwu %[tmp1], 8(%[dst]) \n" | |
+ " lwzx %[tmp2], %[line3b], %[src] \n" | |
+ " or %[tmp2], %[tmp2], %[ormask] \n" | |
+ " stwu %[tmp2], 8(%[tmp3]) \n" | |
+ | |
+ " lwzx %[tmp1], %[line4], %[src] \n" | |
+ " or %[tmp1], %[tmp1], %[ormask] \n" | |
+ " stwu %[tmp1], 8(%[dst]) \n" | |
+ " lwzx %[tmp2], %[line4b], %[src] \n" | |
+ " or %[tmp2], %[tmp2], %[ormask] \n" | |
+ " stwu %[tmp2], 8(%[tmp3]) \n" | |
+ | |
+ " addi %[src], %[src], 8 \n" | |
+ " bdnz 1b \n" | |
+ | |
+ " add %[src], %[tmp0], %[line5] \n" | |
+ " subic. %[height], %[height], 1 \n" | |
+ " bne 2b \n" | |
+ : [tmp0] "=&b" (tmp0), | |
+ [tmp1] "=&b" (tmp1), | |
+ [tmp2] "=&b" (tmp2), | |
+ [tmp3] "=&b" (tmp3), | |
+ [line2] "=&b" (line2), | |
+ [line2b] "=&b" (line2b), | |
+ [line3] "=&b" (line3), | |
+ [line3b] "=&b" (line3b), | |
+ [line4] "=&b" (line4), | |
+ [line4b] "=&b" (line4b), | |
+ [line5] "=&b" (line5), | |
+ [dst] "+b" (dst) | |
+ : [src] "b" (src), | |
+ [width] "b" (width), | |
+ [height] "b" (height), | |
+ [pitch] "b" (pitch), | |
+ [ormask] "b" (ormask) | |
+ ); | |
+} | |
+ | |
// Set MSB to get full RGB555. | |
#define RGB15toRGB5A3(col) ((col) | 0x80008000u) | |
@@ -193,7 +271,7 @@ static void *wii_init(const video_info_t *video, | |
{ \ | |
const uint32_t *tmp_src = src; \ | |
uint32_t *tmp_dst = dst; \ | |
- for (unsigned x = 0; x < width; x += 8, tmp_src += 8, tmp_dst += 32) \ | |
+ for (unsigned x = 0; x < width2; x += 8, tmp_src += 8, tmp_dst += 32) \ | |
{ \ | |
tmp_dst[ 0 + off] = RGB15toRGB5A3(tmp_src[0]); \ | |
tmp_dst[ 1 + off] = RGB15toRGB5A3(tmp_src[1]); \ | |
@@ -210,23 +288,30 @@ static void *wii_init(const video_info_t *video, | |
static void update_texture(const uint32_t *src, | |
unsigned width, unsigned height, unsigned pitch) | |
{ | |
- pitch >>= 2; | |
- width &= ~15; | |
- height &= ~3; | |
- width >>= 1; | |
- | |
- // Texture data is 4x4 tiled @ 15bpp. | |
- // Use 32-bit to transfer more data per cycle. | |
- uint32_t *dst = g_tex.data; | |
- for (unsigned i = 0; i < height; i += 4, dst += 4 * width) | |
+ if (!(width & 3) && !(height & 3)) | |
+ { | |
+ update_texture_asm(src, width, height, pitch); | |
+ } | |
+ else | |
{ | |
- BLIT_LINE(0) | |
- BLIT_LINE(2) | |
- BLIT_LINE(4) | |
- BLIT_LINE(6) | |
+ pitch >>= 2; | |
+ width &= ~15; | |
+ height &= ~3; | |
+ unsigned width2 = width >> 1; | |
+ | |
+ // Texture data is 4x4 tiled @ 15bpp. | |
+ // Use 32-bit to transfer more data per cycle. | |
+ uint32_t *dst = g_tex.data; | |
+ for (unsigned i = 0; i < height; i += 4, dst += 4 * width2) | |
+ { | |
+ BLIT_LINE(0) | |
+ BLIT_LINE(2) | |
+ BLIT_LINE(4) | |
+ BLIT_LINE(6) | |
+ } | |
} | |
- | |
- init_texture(width << 1, height); | |
+ | |
+ init_texture(width, height); | |
DCFlushRange(g_tex.data, sizeof(g_tex.data)); | |
GX_InvalidateTexAll(); | |
} | |
@@ -238,16 +323,19 @@ static bool wii_frame(void *data, const void *frame, | |
(void)data; | |
(void)msg; | |
+ while (g_vsync && !g_draw_done) | |
+ LWP_ThreadSleep(g_video_cond); | |
+ | |
+ g_draw_done = false; | |
+ g_current_framebuf ^= 1; | |
update_texture(frame, width, height, pitch); | |
GX_CallDispList(display_list, display_list_size); | |
GX_DrawDone(); | |
- GX_CopyDisp(g_framebuf[g_render_framebuf % 3], GX_TRUE); | |
+ GX_CopyDisp(g_framebuf[g_current_framebuf], GX_TRUE); | |
GX_Flush(); | |
- | |
- g_render_framebuf++; | |
- if (g_vsync && g_render_framebuf >= g_vi_framebuf + 2) | |
- VIDEO_WaitVSync(); | |
+ VIDEO_SetNextFramebuffer(g_framebuf[g_current_framebuf]); | |
+ VIDEO_Flush(); | |
return true; | |
} | |
@@ -255,7 +343,7 @@ static bool wii_frame(void *data, const void *frame, | |
static void wii_set_nonblock_state(void *data, bool state) | |
{ | |
(void)data; | |
- (void)state; | |
+ g_vsync = !state; | |
} | |
static bool wii_alive(void *data) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment