diff --git a/Makefile b/Makefile index 0eaffc23d2..7baff23a57 100644 --- a/Makefile +++ b/Makefile @@ -310,7 +310,7 @@ ifneq ($(V),1) Q := @ endif -OPTIMIZE_FLAG = -O3 +OPTIMIZE_FLAG = -O3 -ffast-math ifeq ($(DEBUG), 1) OPTIMIZE_FLAG = -O0 endif diff --git a/Makefile.ngc b/Makefile.ngc index 54936e616b..6c09ad822a 100644 --- a/Makefile.ngc +++ b/Makefile.ngc @@ -1,4 +1,4 @@ -RARCH_VERSION = "0.9.8.3" +RARCH_VERSION = "0.9.8.4" DEBUG = 0 HAVE_LOGGER = 1 @@ -53,7 +53,7 @@ CFLAGS += -DHAVE_FILE_LOGGER CFLAGS += -Iconsole/logger endif -CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DHAVE_RMENU -DHAVE_RGUI -DHAVE_THREAD -DRARCH_CONSOLE -DHAVE_LIBRETRO_MANAGEMENT -DHAVE_RARCH_EXEC -DGEKKO -DHAVE_ZLIB -DWANT_RZLIB -DHAVE_RARCH_MAIN_WRAP -DHAVE_GRIFFIN=1 -DHAVE_SCREENSHOTS -DPACKAGE_VERSION=\"$(RARCH_VERSION)\" -Dmain=rarch_main -Wno-char-subscripts +CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DHAVE_RMENU -DHAVE_RGUI -DHAVE_THREAD -DRARCH_CONSOLE -DGEKKO -DHAVE_ZLIB -DWANT_RZLIB -DHAVE_RARCH_MAIN_WRAP -DHAVE_GRIFFIN=1 -DHAVE_SCREENSHOTS -DPACKAGE_VERSION=\"$(RARCH_VERSION)\" -Dmain=rarch_main -Wno-char-subscripts ifeq ($(DEBUG), 1) CFLAGS += -O0 -g diff --git a/Makefile.ngc.salamander b/Makefile.ngc.salamander deleted file mode 100644 index d72430a7bd..0000000000 --- a/Makefile.ngc.salamander +++ /dev/null @@ -1,83 +0,0 @@ - -## -# Makefile for RetroArch GameCube. -## - -DEBUG = 0 -HAVE_LOGGER = 0 -HAVE_FILE_LOGGER = 0 - -# system platform -system_platform = unix -ifeq ($(shell uname -a),) -EXE_EXT = .exe - system_platform = win -else ifneq ($(findstring Darwin,$(shell uname -a)),) - system_platform = osx -else ifneq ($(findstring MINGW,$(shell uname -a)),) - system_platform = win -endif - -PC_DEVELOPMENT_IP_ADDRESS = "192.168.1.7" -PC_DEVELOPMENT_UDP_PORT = 3490 - -CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT) -CXX = $(DEVKITPPC)/bin/powerpc-eabi-g++$(EXE_EXT) -LD = $(DEVKITPPC)/bin/powerpc-eabi-ld$(EXE_EXT) -ELF2DOL = $(DEVKITPPC)/bin/elf2dol$(EXE_EXT) - -DOL_TARGET := retroarch-salamander_ngc.dol -ELF_TARGET := retroarch-salamander_ngc.elf - -INCLUDE := -I. -I$(DEVKITPRO)/libogc/include -LIBDIRS := -L$(DEVKITPRO)/libogc/lib/cube -L. - -MACHDEP := -DGEKKO -DHW_DOL -mogc -mcpu=750 -meabi -mhard-float -CFLAGS += -Wall -std=gnu99 $(MACHDEP) $(INCLUDE) -LDFLAGS := $(MACHDEP) -Wl,-Map,$(notdir $(ELF_TARGET)).map -LIBS := -lfat -logc - -OBJ = frontend/frontend_console.o file_path.o compat/compat.o conf/config_file.o ngc/ssaram.o ngc/sidestep.o - -ifeq ($(HAVE_LOGGER), 1) -CFLAGS += -DHAVE_LOGGER -CFLAGS += -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT) -CFLAGS += -Iconsole/logger -OBJ += console/logger/logger.o -LIBS += -lbba -endif - -ifeq ($(HAVE_FILE_LOGGER), 1) -CFLAGS += -DHAVE_FILE_LOGGER -CFLAGS += -Iconsole/logger -endif - -CFLAGS += -std=gnu99 -DHAVE_DEFAULT_RETROPAD_INPUT -DIS_SALAMANDER -DRARCH_CONSOLE -DHAVE_RARCH_EXEC -DGEKKO -DPACKAGE_VERSION=\"0.9.8\" -Wno-char-subscripts - -ifeq ($(DEBUG), 1) - CFLAGS += -O0 -g -else - CFLAGS += -O3 -endif - -all: $(DOL_TARGET) - -%.dol: %.elf - $(ELF2DOL) $< $@ - -$(ELF_TARGET): $(OBJ) - $(CXX) -o $@ $(LDFLAGS) $(LIBDIRS) $(OBJ) $(LIBS) - -%.o: %.c - $(CC) $(CFLAGS) -c -o $@ $< - -pkg: all - cp -r $(DOL_TARGET) ngc/pkg/boot.dol - -clean: - rm -f $(DOL_TARGET) - rm -f $(ELF_TARGET) - rm -f $(OBJ) - -.PHONY: clean - diff --git a/Makefile.ps3 b/Makefile.ps3 index 9abf5bd488..188beb84cc 100644 --- a/Makefile.ps3 +++ b/Makefile.ps3 @@ -1,4 +1,4 @@ -RARCH_VERSION = "0.9.8.3" +RARCH_VERSION = "0.9.8.4" #which compiler to build with - GCC or SNC #set to GCC for debug builds for use with debugger diff --git a/Makefile.wii b/Makefile.wii index 3e03db212d..891683ada6 100644 --- a/Makefile.wii +++ b/Makefile.wii @@ -1,10 +1,9 @@ -RARCH_VERSION = "0.9.8.3" +RARCH_VERSION = "0.9.8.4" DEBUG = 0 HAVE_LOGGER = 0 HAVE_FILE_LOGGER = 0 PERF_TEST = 0 -HAVE_WIIUSE_MOD = 0 WHOLE_ARCHIVE_LINK = 0 PC_DEVELOPMENT_IP_ADDRESS = "192.168.1.100" @@ -21,11 +20,7 @@ else ifneq ($(findstring MINGW,$(shell uname -a)),) system_platform = win endif -ifeq ($(HAVE_WIIUSE_MOD), 1) -CFLAGS += -DHAVE_WIIUSE -else LDFLAGS_WIIUSE := -lwiiuse -endif CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT) CXX = $(DEVKITPPC)/bin/powerpc-eabi-g++$(EXE_EXT) diff --git a/Makefile.win b/Makefile.win index ff02d01eea..79396f99bc 100644 --- a/Makefile.win +++ b/Makefile.win @@ -221,8 +221,8 @@ ifeq ($(DEBUG), 1) CFLAGS += -O0 -g CXXFLAGS += -O0 -g else - CFLAGS += -O3 - CXXFLAGS += -O3 + CFLAGS += -O3 -ffast-math + CXXFLAGS += -O3 -ffast-math LDCXXFLAGS += -s endif diff --git a/Makefile.xenon b/Makefile.xenon index a23fb407df..b560aba850 100644 --- a/Makefile.xenon +++ b/Makefile.xenon @@ -1,4 +1,4 @@ -RARCH_VERSION = "0.9.8.3" +RARCH_VERSION = "0.9.8.4" DEBUG = 0 diff --git a/android/native/jni/input_android.c b/android/native/jni/input_android.c index 7c64fdb914..9cd31572da 100644 --- a/android/native/jni/input_android.c +++ b/android/native/jni/input_android.c @@ -132,14 +132,24 @@ static void android_input_poll(void *data) long_msg_enable = true; } - if (keycode == AKEYCODE_BACK ) + if (keycode == AKEYCODE_BACK) { - int meta = AKeyEvent_getMetaState(event); - if (!(meta & AMETA_ALT_ON)) + uint8_t unpacked = (keycode_lut[AKEYCODE_BACK] >> ((state_id+1) << 3)) - 1; + uint64_t input_state = (1ULL << unpacked); + + if (type_event == AINPUT_EVENT_TYPE_KEY && input_state < (1ULL << RARCH_FIRST_META_KEY) + && input_state > 0) { - *lifecycle_state |= (1ULL << RARCH_QUIT_KEY); - AInputQueue_finishEvent(android_app->inputQueue, event, handled); - break; + } + else + { + int meta = AKeyEvent_getMetaState(event); + if (!(meta & AMETA_ALT_ON)) + { + *lifecycle_state |= (1ULL << RARCH_QUIT_KEY); + AInputQueue_finishEvent(android_app->inputQueue, event, handled); + break; + } } } diff --git a/android/native/jni/input_autodetect.c b/android/native/jni/input_autodetect.c index 8af5c568d5..96ae198480 100644 --- a/android/native/jni/input_autodetect.c +++ b/android/native/jni/input_autodetect.c @@ -175,6 +175,7 @@ void input_autodetect_setup (void *data, char *msg, size_t sizeof_msg, unsigned keycode_lut[AKEYCODE_BUTTON_THUMBL] |= ((RETRO_DEVICE_ID_JOYPAD_L3+1) << shift); keycode_lut[AKEYCODE_BUTTON_THUMBR] |= ((RETRO_DEVICE_ID_JOYPAD_R3+1) << shift); keycode_lut[AKEYCODE_BUTTON_SELECT] |= ((RETRO_DEVICE_ID_JOYPAD_SELECT+1) << shift); + keycode_lut[AKEYCODE_BACK] |= ((RETRO_DEVICE_ID_JOYPAD_SELECT+1) << shift); keycode_lut[AKEYCODE_BUTTON_START] |= ((RETRO_DEVICE_ID_JOYPAD_START+1) << shift); } } @@ -206,7 +207,7 @@ void input_autodetect_setup (void *data, char *msg, size_t sizeof_msg, unsigned keycode_lut[AKEYCODE_BUTTON_C] |= ((RETRO_DEVICE_ID_JOYPAD_SELECT+1) << shift); keycode_lut[AKEYCODE_BUTTON_X] |= ((RETRO_DEVICE_ID_JOYPAD_START+1) << shift); } - else if (strstr(name_buf, "Madcatz")) + else if (strstr(name_buf, "MadCatz")) { if (strstr(name_buf, "PC USB Wired Stick")) { @@ -216,9 +217,12 @@ void input_autodetect_setup (void *data, char *msg, size_t sizeof_msg, unsigned keycode_lut[AKEYCODE_BUTTON_X] |= ((RETRO_DEVICE_ID_JOYPAD_X+1) << shift); keycode_lut[AKEYCODE_BUTTON_Y] |= ((RETRO_DEVICE_ID_JOYPAD_L+1) << shift); - keycode_lut[AKEYCODE_BUTTON_Z] |= ((RETRO_DEVICE_ID_JOYPAD_R+1) << shift); + + keycode_lut[AKEYCODE_BUTTON_Z] |= ((RETRO_DEVICE_ID_JOYPAD_L+1) << shift); /* request hack */ + keycode_lut[AKEYCODE_BUTTON_L1] |= ((RETRO_DEVICE_ID_JOYPAD_L2+1) << shift); - keycode_lut[AKEYCODE_BUTTON_R1] |= ((RETRO_DEVICE_ID_JOYPAD_R2+1) << shift); + + keycode_lut[AKEYCODE_BUTTON_R1] |= ((RETRO_DEVICE_ID_JOYPAD_R+1) << shift); /* request hack */ keycode_lut[AKEYCODE_BUTTON_L2] |= ((RETRO_DEVICE_ID_JOYPAD_SELECT+1) << shift); keycode_lut[AKEYCODE_BUTTON_R2] |= ((RETRO_DEVICE_ID_JOYPAD_START+1) << shift); @@ -479,7 +483,7 @@ void input_autodetect_setup (void *data, char *msg, size_t sizeof_msg, unsigned keycode_lut[AKEYCODE_BUTTON_THUMBL] |= ((RETRO_DEVICE_ID_JOYPAD_L3+1) << shift); keycode_lut[AKEYCODE_BUTTON_THUMBR] |= ((RETRO_DEVICE_ID_JOYPAD_R3+1) << shift); } - else if (strstr(name_buf, "2-Axis , 8 -Button")) + else if (strstr(name_buf, "2-Axis, 8-Button")) { /* Genius MaxFire G-08XU */ keycode_lut[AKEYCODE_BUTTON_B] |= ((RETRO_DEVICE_ID_JOYPAD_A+1) << shift); diff --git a/android/phoenix/AndroidManifest.xml b/android/phoenix/AndroidManifest.xml index 3344cfb734..53bf4fe6ae 100644 --- a/android/phoenix/AndroidManifest.xml +++ b/android/phoenix/AndroidManifest.xml @@ -1,6 +1,6 @@ diff --git a/audio/hermite.c b/audio/hermite.c index 1dc80e3a6f..a74e66d76a 100644 --- a/audio/hermite.c +++ b/audio/hermite.c @@ -18,13 +18,20 @@ #include "resampler.h" #include #include +#include #include "../boolean.h" -#include "../general.h" #ifdef HAVE_CONFIG_H #include "../config.h" #endif +#ifndef RESAMPLER_TEST +#include "../general.h" +#else +#define RARCH_LOG(...) fprintf(stderr, __VA_ARGS__) +#define RARCH_WARN(...) fprintf(stderr, __VA_ARGS__) +#endif + #define CHANNELS 2 typedef struct rarch_hermite_resampler @@ -51,8 +58,11 @@ static inline float hermite_kernel(float mu1, float a, float b, float c, float d return (a0 * b) + (a1 * m0) + (a2 * m1) + (a3 * c); } -void *resampler_hermite_new(void) +void *resampler_hermite_new(double bandwidth_mod) { + if (bandwidth_mod < 1.0) + RARCH_WARN("Hermite resampler is likely to sound absolutely terrible when downsampling.\n"); + #ifndef RESAMPLER_TEST RARCH_LOG("Hermite resampler [C]\n"); #endif diff --git a/audio/resampler.c b/audio/resampler.c index 8ee2f3e36a..644c23882a 100644 --- a/audio/resampler.c +++ b/audio/resampler.c @@ -29,7 +29,7 @@ static const rarch_resampler_t *backends[] = { &hermite_resampler, }; -bool rarch_resampler_realloc(void **re, const rarch_resampler_t **backend, const char *ident) +bool rarch_resampler_realloc(void **re, const rarch_resampler_t **backend, const char *ident, double bw_ratio) { if (*re && *backend) (*backend)->free(*re); @@ -54,7 +54,7 @@ bool rarch_resampler_realloc(void **re, const rarch_resampler_t **backend, const if (!*backend) return false; - *re = (*backend)->init(); + *re = (*backend)->init(bw_ratio); if (!*re) { *backend = NULL; diff --git a/audio/resampler.h b/audio/resampler.h index a865f2ab5a..981c44f541 100644 --- a/audio/resampler.h +++ b/audio/resampler.h @@ -46,7 +46,7 @@ struct resampler_data typedef struct rarch_resampler { - void *(*init)(void); + void *(*init)(double bandwidth_mod); // Bandwidth factor. Will be < 1.0 for downsampling, > 1.0 for upsamling. Corresponds to expected resampling ratio. void (*process)(void *re, struct resampler_data *data); void (*free)(void *re); const char *ident; @@ -57,7 +57,7 @@ extern const rarch_resampler_t sinc_resampler; // Reallocs resampler. Will free previous handle before allocating a new one. // If ident is NULL, first resampler will be used. -bool rarch_resampler_realloc(void **re, const rarch_resampler_t **backend, const char *ident); +bool rarch_resampler_realloc(void **re, const rarch_resampler_t **backend, const char *ident, double bw_ratio); // Convenience macros. // freep makes sure to set handles to NULL to avoid double-free in rarch_resampler_realloc. diff --git a/audio/sinc.c b/audio/sinc.c index fb912a3371..483e148a73 100644 --- a/audio/sinc.c +++ b/audio/sinc.c @@ -14,7 +14,7 @@ */ // Bog-standard windowed SINC implementation. -// Only suitable as an upsampler, as there is no low-pass filter stage. +// Only suitable as an upsampler, as cutoff frequency isn't dynamically configurable (yet). #include "resampler.h" #include "../performance.h" @@ -22,27 +22,67 @@ #include #include #include +#include #ifndef RESAMPLER_TEST #include "../general.h" #else -#define RARCH_LOG(...) +#define RARCH_LOG(...) fprintf(stderr, __VA_ARGS__) #endif #ifdef __SSE__ #include #endif -#ifdef SINC_LOWER_QUALITY +// Rough SNR values for upsampling: +// LOWEST: 40 dB +// LOWER: 55 dB +// NORMAL: 70 dB +// HIGHER: 110 dB +// HIGHEST: 140 dB + +// TODO, make all this more configurable. +#if defined(SINC_LOWEST_QUALITY) +#define SINC_WINDOW_LANCZOS +#define CUTOFF 0.98 #define PHASE_BITS 12 +#define SINC_COEFF_LERP 0 +#define SUBPHASE_BITS 10 +#define SIDELOBES 2 +#define ENABLE_AVX 0 +#elif defined(SINC_LOWER_QUALITY) +#define SINC_WINDOW_LANCZOS +#define CUTOFF 0.98 +#define PHASE_BITS 12 +#define SUBPHASE_BITS 10 +#define SINC_COEFF_LERP 0 #define SIDELOBES 4 #define ENABLE_AVX 0 #elif defined(SINC_HIGHER_QUALITY) -#define PHASE_BITS 16 +#define SINC_WINDOW_KAISER +#define SINC_WINDOW_KAISER_BETA 10.5 +#define CUTOFF 0.90 +#define PHASE_BITS 10 +#define SUBPHASE_BITS 14 +#define SINC_COEFF_LERP 1 #define SIDELOBES 32 #define ENABLE_AVX 1 +#elif defined(SINC_HIGHEST_QUALITY) +#define SINC_WINDOW_KAISER +#define SINC_WINDOW_KAISER_BETA 14.5 +#define CUTOFF 0.95 +#define PHASE_BITS 10 +#define SUBPHASE_BITS 14 +#define SINC_COEFF_LERP 1 +#define SIDELOBES 128 +#define ENABLE_AVX 1 #else -#define PHASE_BITS 16 +#define SINC_WINDOW_KAISER +#define SINC_WINDOW_KAISER_BETA 5.5 +#define CUTOFF 0.825 +#define PHASE_BITS 8 +#define SUBPHASE_BITS 16 +#define SINC_COEFF_LERP 1 #define SIDELOBES 8 #define ENABLE_AVX 0 #endif @@ -56,20 +96,26 @@ #include #endif -#define SUBPHASE_BITS 10 #define PHASES (1 << (PHASE_BITS + SUBPHASE_BITS)) #define TAPS (SIDELOBES * 2) -#define CUTOFF 0.98 +#define SUBPHASE_MASK ((1 << SUBPHASE_BITS) - 1) +#define SUBPHASE_MOD (1.0f / (1 << SUBPHASE_BITS)) typedef struct rarch_sinc_resampler { - sample_t phase_table[1 << PHASE_BITS][TAPS]; - sample_t buffer_l[2 * TAPS]; - sample_t buffer_r[2 * TAPS]; + sample_t *phase_table; + sample_t *buffer_l; + sample_t *buffer_r; + + unsigned taps; unsigned ptr; uint32_t time; + + // A buffer for phase_table, buffer_l and buffer_r are created in a single calloc(). + // Ensure that we get as good cache locality as we can hope for. + sample_t *main_buffer; } rarch_sinc_resampler_t; static inline double sinc(double val) @@ -80,23 +126,90 @@ static inline double sinc(double val) return sin(val) / val; } -static inline double lanzcos(double index) +#if defined(SINC_WINDOW_LANCZOS) +static inline double window_function(double index) { - return sinc(index); + return sinc(M_PI * index); +} +#elif defined(SINC_WINDOW_KAISER) +// Modified Bessel function of first order. +// Check Wiki for mathematical definition ... +static inline double besseli0(double x) +{ + double sum = 0.0; + + double factorial = 1.0; + double factorial_mult = 0.0; + double x_pow = 1.0; + double two_div_pow = 1.0; + double x_sqr = x * x; + + // Approximate. This is an infinite sum. + // Luckily, it converges rather fast. + for (unsigned i = 0; i < 18; i++) + { + sum += x_pow * two_div_pow / (factorial * factorial); + + factorial_mult += 1.0; + x_pow *= x_sqr; + two_div_pow *= 0.25; + factorial *= factorial_mult; + } + + return sum; } -static void init_sinc_table(rarch_sinc_resampler_t *resamp) +static inline double window_function(double index) { - // Sinc phases: [..., p + 3, p + 2, p + 1, p + 0, p - 1, p - 2, p - 3, p - 4, ...] - for (int i = 0; i < (1 << PHASE_BITS); i++) - { - for (int j = 0; j < TAPS; j++) - { - double p = (double)i / (1 << PHASE_BITS); - double sinc_phase = M_PI * (p + (SIDELOBES - 1 - j)); + return besseli0(SINC_WINDOW_KAISER_BETA * sqrt(1 - index * index)); +} +#else +#error "No SINC window function defined." +#endif - float val = CUTOFF * sinc(CUTOFF * sinc_phase) * lanzcos(sinc_phase / SIDELOBES); - resamp->phase_table[i][j] = val; +static void init_sinc_table(rarch_sinc_resampler_t *resamp, double cutoff, + float *phase_table, int phases, int taps, bool calculate_delta) +{ + double window_mod = window_function(0.0); // Need to normalize w(0) to 1.0. + int stride = calculate_delta ? 2 : 1; + + double sidelobes = taps / 2.0; + for (int i = 0; i < phases; i++) + { + for (int j = 0; j < taps; j++) + { + int n = j * phases + i; + double window_phase = (double)n / (phases * taps); // [0, 1). + window_phase = 2.0 * window_phase - 1.0; // [-1, 1) + double sinc_phase = sidelobes * window_phase; + + float val = cutoff * sinc(M_PI * sinc_phase * cutoff) * window_function(window_phase) / window_mod; + phase_table[i * stride * taps + j] = val; + } + } + + if (calculate_delta) + { + for (int p = 0; p < phases - 1; p++) + { + for (int j = 0; j < taps; j++) + { + float delta = phase_table[(p + 1) * stride * taps + j] - phase_table[p * stride * taps + j]; + phase_table[(p * stride + 1) * taps + j] = delta; + } + } + + int phase = phases - 1; + for (int j = 0; j < taps; j++) + { + int n = j * phases + (phase + 1); + double window_phase = (double)n / (phases * taps); // (0, 1]. + window_phase = 2.0 * window_phase - 1.0; // (-1, 1] + double sinc_phase = sidelobes * window_phase; + + float val = cutoff * sinc(M_PI * sinc_phase * cutoff) * window_function(window_phase) / window_mod; + float delta = (val - phase_table[phase * stride * taps + j]); + phase_table[(phase * stride + 1) * taps + j] = delta; } } } @@ -128,12 +241,23 @@ static inline void process_sinc_C(rarch_sinc_resampler_t *resamp, float *out_buf const float *buffer_l = resamp->buffer_l + resamp->ptr; const float *buffer_r = resamp->buffer_r + resamp->ptr; + unsigned taps = resamp->taps; unsigned phase = resamp->time >> SUBPHASE_BITS; - const float *phase_table = resamp->phase_table[phase]; +#if SINC_COEFF_LERP + const float *phase_table = resamp->phase_table + phase * taps * 2; + const float *delta_table = phase_table + taps; + float delta = (float)(resamp->time & SUBPHASE_MASK) * SUBPHASE_MOD; +#else + const float *phase_table = resamp->phase_table + phase * taps; +#endif - for (unsigned i = 0; i < TAPS; i++) + for (unsigned i = 0; i < taps; i++) { +#if SINC_COEFF_LERP + float sinc_val = phase_table[i] + delta_table[i] * delta; +#else float sinc_val = phase_table[i]; +#endif sum_l += buffer_l[i] * sinc_val; sum_r += buffer_r[i] * sinc_val; } @@ -152,15 +276,27 @@ static void process_sinc(rarch_sinc_resampler_t *resamp, float *out_buffer) const float *buffer_l = resamp->buffer_l + resamp->ptr; const float *buffer_r = resamp->buffer_r + resamp->ptr; + unsigned taps = resamp->taps; unsigned phase = resamp->time >> SUBPHASE_BITS; - const float *phase_table = resamp->phase_table[phase]; +#if SINC_COEFF_LERP + const float *phase_table = resamp->phase_table + phase * taps * 2; + const float *delta_table = phase_table + taps; + __m256 delta = _mm256_set1_ps((float)(resamp->time & SUBPHASE_MASK) * SUBPHASE_MOD); +#else + const float *phase_table = resamp->phase_table + phase * taps; +#endif - for (unsigned i = 0; i < TAPS; i += 8) + for (unsigned i = 0; i < taps; i += 8) { __m256 buf_l = _mm256_loadu_ps(buffer_l + i); __m256 buf_r = _mm256_loadu_ps(buffer_r + i); +#if SINC_COEFF_LERP + __m256 deltas = _mm256_load_ps(delta_table + i); + __m256 sinc = _mm256_add_ps(_mm256_load_ps(phase_table + i), _mm256_mul_ps(deltas, delta)); +#else __m256 sinc = _mm256_load_ps(phase_table + i); +#endif sum_l = _mm256_add_ps(sum_l, _mm256_mul_ps(buf_l, sinc)); sum_r = _mm256_add_ps(sum_r, _mm256_mul_ps(buf_r, sinc)); } @@ -188,15 +324,27 @@ static void process_sinc(rarch_sinc_resampler_t *resamp, float *out_buffer) const float *buffer_l = resamp->buffer_l + resamp->ptr; const float *buffer_r = resamp->buffer_r + resamp->ptr; + unsigned taps = resamp->taps; unsigned phase = resamp->time >> SUBPHASE_BITS; - const float *phase_table = resamp->phase_table[phase]; +#if SINC_COEFF_LERP + const float *phase_table = resamp->phase_table + phase * taps * 2; + const float *delta_table = phase_table + taps; + __m128 delta = _mm_set1_ps((float)(resamp->time & SUBPHASE_MASK) * SUBPHASE_MOD); +#else + const float *phase_table = resamp->phase_table + phase * taps; +#endif - for (unsigned i = 0; i < TAPS; i += 4) + for (unsigned i = 0; i < taps; i += 4) { __m128 buf_l = _mm_loadu_ps(buffer_l + i); __m128 buf_r = _mm_loadu_ps(buffer_r + i); +#if SINC_COEFF_LERP + __m128 deltas = _mm_load_ps(delta_table + i); + __m128 sinc = _mm_add_ps(_mm_load_ps(phase_table + i), _mm_mul_ps(deltas, delta)); +#else __m128 sinc = _mm_load_ps(phase_table + i); +#endif sum_l = _mm_add_ps(sum_l, _mm_mul_ps(buf_l, sinc)); sum_r = _mm_add_ps(sum_r, _mm_mul_ps(buf_r, sinc)); } @@ -224,6 +372,10 @@ static void process_sinc(rarch_sinc_resampler_t *resamp, float *out_buffer) } #elif defined(HAVE_NEON) +#if SINC_COEFF_LERP +#error "NEON asm does not support SINC lerp." +#endif + // Need to make this function pointer as Android doesn't have built-in targets // for NEON and plain ARMv7a. static void (*process_sinc_func)(rarch_sinc_resampler_t *resamp, float *out_buffer); @@ -239,7 +391,7 @@ static void process_sinc_neon(rarch_sinc_resampler_t *resamp, float *out_buffer) unsigned phase = resamp->time >> SUBPHASE_BITS; const float *phase_table = resamp->phase_table[phase]; - process_sinc_neon_asm(out_buffer, buffer_l, buffer_r, phase_table, TAPS); + process_sinc_neon_asm(out_buffer, buffer_l, buffer_r, phase_table, resamp->taps); } #else // Plain ol' C99 #define process_sinc_func process_sinc_C @@ -249,9 +401,6 @@ static void resampler_sinc_process(void *re_, struct resampler_data *data) { rarch_sinc_resampler_t *re = (rarch_sinc_resampler_t*)re_; - // If data->ratio is < 1, we are downsampling. - // The sinc table is not set up for this, as it always assumes upsampling. - // Downsampling will work, but with some added noise due to aliasing might be present. uint32_t ratio = PHASES / data->ratio; const sample_t *input = data->data_in; @@ -263,9 +412,13 @@ static void resampler_sinc_process(void *re_, struct resampler_data *data) { while (frames && re->time >= PHASES) { - re->buffer_l[re->ptr + TAPS] = re->buffer_l[re->ptr] = *input++; - re->buffer_r[re->ptr + TAPS] = re->buffer_r[re->ptr] = *input++; - re->ptr = (re->ptr + 1) & (TAPS - 1); + // Push in reverse to make filter more obvious. + if (!re->ptr) + re->ptr = re->taps; + re->ptr--; + + re->buffer_l[re->ptr + re->taps] = re->buffer_l[re->ptr] = *input++; + re->buffer_r[re->ptr + re->taps] = re->buffer_r[re->ptr] = *input++; re->time -= PHASES; frames--; @@ -285,18 +438,52 @@ static void resampler_sinc_process(void *re_, struct resampler_data *data) static void resampler_sinc_free(void *re) { - aligned_free__(re); + rarch_sinc_resampler_t *resampler = (rarch_sinc_resampler_t*)re; + if (resampler) + aligned_free__(resampler->main_buffer); + free(resampler); } -static void *resampler_sinc_new(void) +static void *resampler_sinc_new(double bandwidth_mod) { - rarch_sinc_resampler_t *re = (rarch_sinc_resampler_t*)aligned_alloc__(128, sizeof(*re)); + rarch_sinc_resampler_t *re = (rarch_sinc_resampler_t*)calloc(1, sizeof(*re)); if (!re) return NULL; memset(re, 0, sizeof(*re)); - init_sinc_table(re); + re->taps = TAPS; + double cutoff = CUTOFF; + + // Downsampling, must lower cutoff, and extend number of taps accordingly to keep same stopband attenuation. + if (bandwidth_mod < 1.0) + { + cutoff *= bandwidth_mod; + re->taps = (unsigned)ceil(re->taps / bandwidth_mod); + } + + // Be SIMD-friendly. +#if (defined(__AVX__) && ENABLE_AVX) || defined(HAVE_NEON) + re->taps = (re->taps + 7) & ~7; +#else + re->taps = (re->taps + 3) & ~3; +#endif + + size_t phase_elems = (1 << PHASE_BITS) * re->taps; +#if SINC_COEFF_LERP + phase_elems *= 2; +#endif + size_t elems = phase_elems + 4 * re->taps; + + re->main_buffer = (sample_t*)aligned_alloc__(128, sizeof(sample_t) * elems); + if (!re->main_buffer) + goto error; + + re->phase_table = re->main_buffer; + re->buffer_l = re->main_buffer + phase_elems; + re->buffer_r = re->buffer_l + 2 * re->taps; + + init_sinc_table(re, cutoff, re->phase_table, 1 << PHASE_BITS, re->taps, SINC_COEFF_LERP); #if defined(__AVX__) && ENABLE_AVX RARCH_LOG("Sinc resampler [AVX]\n"); @@ -311,9 +498,12 @@ static void *resampler_sinc_new(void) RARCH_LOG("Sinc resampler [C]\n"); #endif - RARCH_LOG("SINC params (%u phase bits, %u taps).\n", PHASE_BITS, TAPS); - + RARCH_LOG("SINC params (%u phase bits, %u taps).\n", PHASE_BITS, re->taps); return re; + +error: + resampler_sinc_free(re); + return NULL; } const rarch_resampler_t sinc_resampler = { diff --git a/audio/test/Makefile b/audio/test/Makefile index 55ea3498ea..10f700ba15 100644 --- a/audio/test/Makefile +++ b/audio/test/Makefile @@ -1,20 +1,25 @@ -TESTS := test-hermite test-sinc test-snr-sinc test-snr-hermite +TESTS := test-hermite \ + test-snr-hermite \ + test-sinc-lowest \ + test-snr-sinc-lowest \ + test-sinc-lower \ + test-snr-sinc-lower \ + test-sinc \ + test-snr-sinc \ + test-sinc-higher \ + test-snr-sinc-higher \ + test-sinc-highest \ + test-snr-sinc-highest -CFLAGS += -O3 -g -Wall -pedantic -std=gnu99 -DRESAMPLER_TEST +CFLAGS += -O3 -ffast-math -g -Wall -pedantic -march=native -std=gnu99 -DRESAMPLER_TEST LDFLAGS += -lm all: $(TESTS) -test-hermite: ../hermite.o ../utils.o main.o resampler-hermite.o +test-hermite: hermite.o ../utils.o main.o resampler-hermite.o $(CC) -o $@ $^ $(LDFLAGS) -test-sinc: ../sinc.o ../utils.o main.o ../hermite.o resampler-sinc.o - $(CC) -o $@ $^ $(LDFLAGS) - -test-snr-sinc: ../sinc.o ../utils.o snr.o ../hermite.o resampler-sinc.o - $(CC) -o $@ $^ $(LDFLAGS) - -test-snr-hermite: ../hermite.o ../utils.o snr.o resampler-hermite.o +test-snr-hermite: hermite.o ../utils.o snr.o resampler-hermite.o $(CC) -o $@ $^ $(LDFLAGS) resampler-sinc.o: ../resampler.c @@ -23,6 +28,54 @@ resampler-sinc.o: ../resampler.c resampler-hermite.o: ../resampler.c $(CC) -c -o $@ $< $(CFLAGS) +hermite.o: ../hermite.c + $(CC) -c -o $@ $< $(CFLAGS) + +sinc-lowest.o: ../sinc.c + $(CC) -c -o $@ $< $(CFLAGS) -DHAVE_SINC -DSINC_LOWEST_QUALITY + +sinc-lower.o: ../sinc.c + $(CC) -c -o $@ $< $(CFLAGS) -DHAVE_SINC -DSINC_LOWER_QUALITY + +sinc.o: ../sinc.c + $(CC) -c -o $@ $< $(CFLAGS) -DHAVE_SINC + +sinc-higher.o: ../sinc.c + $(CC) -c -o $@ $< $(CFLAGS) -DHAVE_SINC -DSINC_HIGHER_QUALITY + +sinc-highest.o: ../sinc.c + $(CC) -c -o $@ $< $(CFLAGS) -DHAVE_SINC -DSINC_HIGHEST_QUALITY + +test-sinc-lowest: sinc-lowest.o ../utils.o main.o ../hermite.o resampler-sinc.o + $(CC) -o $@ $^ $(LDFLAGS) + +test-snr-sinc-lowest: sinc-lowest.o ../utils.o snr.o ../hermite.o resampler-sinc.o + $(CC) -o $@ $^ $(LDFLAGS) + +test-sinc-lower: sinc-lower.o ../utils.o main.o ../hermite.o resampler-sinc.o + $(CC) -o $@ $^ $(LDFLAGS) + +test-snr-sinc-lower: sinc-lower.o ../utils.o snr.o ../hermite.o resampler-sinc.o + $(CC) -o $@ $^ $(LDFLAGS) + +test-sinc: sinc.o ../utils.o main.o ../hermite.o resampler-sinc.o + $(CC) -o $@ $^ $(LDFLAGS) + +test-snr-sinc: sinc.o ../utils.o snr.o ../hermite.o resampler-sinc.o + $(CC) -o $@ $^ $(LDFLAGS) + +test-sinc-higher: sinc-higher.o ../utils.o main.o ../hermite.o resampler-sinc.o + $(CC) -o $@ $^ $(LDFLAGS) + +test-snr-sinc-higher: sinc-higher.o ../utils.o snr.o ../hermite.o resampler-sinc.o + $(CC) -o $@ $^ $(LDFLAGS) + +test-sinc-highest: sinc-highest.o ../utils.o main.o ../hermite.o resampler-sinc.o + $(CC) -o $@ $^ $(LDFLAGS) + +test-snr-sinc-highest: sinc-highest.o ../utils.o snr.o ../hermite.o resampler-sinc.o + $(CC) -o $@ $^ $(LDFLAGS) + %.o: %.c $(CC) -c -o $@ $< $(CFLAGS) diff --git a/audio/test/kaiser_window.m b/audio/test/kaiser_window.m new file mode 100644 index 0000000000..a55517f08e --- /dev/null +++ b/audio/test/kaiser_window.m @@ -0,0 +1,6 @@ +function win = kaiser_window(N, beta) +% Create an N-point kaiser window with given beta. + +indices = 2 * (0 : N - 1) / (N - 1) - 1; +mod = modified_bessel(beta); +win = modified_bessel(beta * sqrt(1 - indices.^2)) / mod; \ No newline at end of file diff --git a/audio/test/main.c b/audio/test/main.c index b51cdb4e04..531efd80cd 100644 --- a/audio/test/main.c +++ b/audio/test/main.c @@ -47,7 +47,7 @@ int main(int argc, char *argv[]) const rarch_resampler_t *resampler = NULL; void *re = NULL; - if (!rarch_resampler_realloc(&re, &resampler, NULL)) + if (!rarch_resampler_realloc(&re, &resampler, NULL, out_rate / in_rate)) { fprintf(stderr, "Failed to allocate resampler ...\n"); return 1; diff --git a/audio/test/modified_bessel.m b/audio/test/modified_bessel.m new file mode 100644 index 0000000000..3ffa6d7c03 --- /dev/null +++ b/audio/test/modified_bessel.m @@ -0,0 +1,21 @@ +function val = modified_bessel(x) + +% Mirrors operation as done in RetroArch. Verify accuracy against Matlab's +% implementation. + +sum = zeros(size(x)); +factorial = ones(size(x)); +factorial_mult = zeros(size(x)); +x_pow = ones(size(x)); +two_div_pow = ones(size(x)); +x_sqr = x .* x; + +for i = 0 : 17 + sum = sum + x_pow .* two_div_pow ./ (factorial .* factorial); + factorial_mult = factorial_mult + 1.0; + x_pow = x_pow .* x_sqr; + two_div_pow = two_div_pow * 0.25; + factorial = factorial .* factorial_mult; +end + +val = sum; \ No newline at end of file diff --git a/audio/test/sinc_test.m b/audio/test/sinc_test.m new file mode 100644 index 0000000000..57173ce833 --- /dev/null +++ b/audio/test/sinc_test.m @@ -0,0 +1,49 @@ +% MATLAB test case for RetroArch SINC upsampler. +close all; + +%% +% Test RetroArch's kaiser function. +real_kaiser = kaiser(1024, 10.0)'; +rarch_kaiser = kaiser_window(1024, 10.0); +figure('name', 'Bessel function test'); +subplot(2, 1, 1), plot(rarch_kaiser), title('RetroArch kaiser'); +subplot(2, 1, 2), plot(rarch_kaiser - real_kaiser), title('Error'); + +%% +% 4-tap and 8-tap are Lanczos windowed, but include here for completeness. +phases = 256; +bw = 0.375; +downsample = round(phases / bw); +cutoffs = bw * [0.65 0.75 0.825 0.90 0.95]; +betas = [2.0 3.0 5.5 10.5 14.5]; + +sidelobes = round([2 4 8 32 128] / bw); +taps = sidelobes * 2; + +freqs = 0.05 : 0.02 : 0.99; + +filters = length(taps); +for i = 1 : filters + filter_length = taps(i) * phases; + + % Generate SINC. + sinc_indices = 2 * ((0 : (filter_length - 1)) / (filter_length - 1)) - 1; + s = cutoffs(i) * sinc(cutoffs(i) * sinc_indices * sidelobes(i)); + win = kaiser(filter_length, betas(i))'; + filter = s .* win; + + impulse_response_half = 0.5 * upfirdn(1, filter, phases, downsample); + figure('name', sprintf('Response SINC: %d taps', taps(i))); + freqz(impulse_response_half); + ylim([-200 0]); + + signal = zeros(1, 8001); + for freq = freqs + signal = signal + sin(pi * freq * (0 : 8000)); + end + + resampled = upfirdn(signal, filter, phases, downsample); + figure('name', sprintf('Kaiser SINC: %d taps, w = %.f', taps(i), freq)); + freqz(resampled .* kaiser(length(resampled), 40.0)'); + ylim([-80 70]); +end \ No newline at end of file diff --git a/audio/test/snr.c b/audio/test/snr.c index ab55461528..f3095fdf69 100644 --- a/audio/test/snr.c +++ b/audio/test/snr.c @@ -23,6 +23,9 @@ #include #include +#undef min +#define min(a, b) (((a) < (b)) ? (a) : (b)) + static void gen_signal(float *out, double omega, double bias_samples, size_t samples) { for (size_t i = 0; i < samples; i += 2) @@ -244,15 +247,9 @@ int main(int argc, char *argv[]) const unsigned fft_samples = 1024 * 128; unsigned out_rate = fft_samples / 2; - unsigned in_rate = out_rate / ratio; + unsigned in_rate = round(out_rate / ratio); ratio = (double)out_rate / in_rate; - if (ratio <= 1.0) - { - fprintf(stderr, "Ratio too low ...\n"); - return 1; - } - static const float freq_list[] = { 0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.007, 0.008, 0.009, 0.010, 0.015, 0.020, 0.025, 0.030, 0.035, 0.040, 0.045, 0.050, @@ -265,19 +262,18 @@ int main(int argc, char *argv[]) unsigned samples = in_rate * 4; float *input = calloc(sizeof(float), samples); - float *output = calloc(sizeof(float), (fft_samples + 1) * 2); + float *output = calloc(sizeof(float), (fft_samples + 16) * 2); complex double *butterfly_buf = calloc(sizeof(complex double), fft_samples / 2); assert(input); assert(output); void *re = NULL; const rarch_resampler_t *resampler = NULL; - if (!rarch_resampler_realloc(&re, &resampler, NULL)) + if (!rarch_resampler_realloc(&re, &resampler, NULL, ratio)) return 1; test_fft(); - printf("Omega,SNR,Gain\n"); for (unsigned i = 0; i < sizeof(freq_list) / sizeof(freq_list[0]); i++) { unsigned freq = freq_list[i] * in_rate; @@ -293,12 +289,13 @@ int main(int argc, char *argv[]) rarch_resampler_process(resampler, re, &data); - unsigned out_samples = data.output_frames * 2; - assert(out_samples >= fft_samples * 2); - // We generate 2 seconds worth of audio, however, only the last second is considered so phase has stabilized. - struct snr_result res; - calculate_snr(&res, freq, in_rate / 2, output + fft_samples, butterfly_buf, fft_samples); + struct snr_result res = {0}; + unsigned max_freq = min(in_rate, out_rate) / 2; + if (freq > max_freq) + continue; + + calculate_snr(&res, freq, max_freq, output + fft_samples - 2048, butterfly_buf, fft_samples); printf("SNR @ w = %5.3f : %6.2lf dB, Gain: %6.1lf dB\n", freq_list[i], res.snr, res.gain); diff --git a/console/griffin/griffin.c b/console/griffin/griffin.c index 6fc2a6efbf..950d609075 100644 --- a/console/griffin/griffin.c +++ b/console/griffin/griffin.c @@ -37,7 +37,6 @@ CONSOLE EXTENSIONS #ifdef HW_DOL #include "../../ngc/ssaram.c" -#include "../../ngc/sidestep.c" #endif #ifdef HAVE_DEFAULT_RETROPAD_INPUT @@ -229,22 +228,6 @@ INPUT #include "../../input/overlay.c" #endif -#ifdef HAVE_WIIUSE -#include "../../wii/wiiuse/classic.c" -#include "../../wii/wiiuse/dynamics.c" -#include "../../wii/wiiuse/events.c" -#include "../../wii/wiiuse/io.c" -#include "../../wii/wiiuse/io_wii.c" -#include "../../wii/wiiuse/ir.c" -#include "../../wii/wiiuse/motion_plus.c" -#include "../../wii/wiiuse/nunchuk.c" -#ifdef HAVE_WIIUSE_SPEAKER -#include "../../wii/wiiuse/speaker.c" -#endif -#include "../../wii/wiiuse/wiiuse.c" -#include "../../wii/wiiuse/wpad.c" -#endif - #if defined(__CELLOS_LV2__) #include "../../ps3/ps3_input.c" #elif defined(SN_TARGET_PSP2) || defined(PSP) diff --git a/dist-scripts/ngc-cores.sh b/dist-scripts/ngc-cores.sh new file mode 100755 index 0000000000..e9eb06f5da --- /dev/null +++ b/dist-scripts/ngc-cores.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +make -C ../ -f Makefile.ngc clean || exit 1 + +for f in *_ngc.a ; do + name=`echo "$f" | sed 's/\(_libretro\|\)_ngc.a$//'` + whole_archive= + if [ $name = "nxengine" ] ; then + whole_archive="WHOLE_ARCHIVE_LINK=1" + echo $name yes + fi + cp -f "$f" ../libretro_ngc.a + make -C ../ -f Makefile.ngc $whole_archive -j3 || exit 1 + mv -f ../retroarch_ngc.dol ../ngc/pkg/$name.dol + rm -f ../retroarch_ngc.dol ../retroarch_ngc.elf ../retroarch_ngc.elf.map +done diff --git a/dist-scripts/retroarch-360-README.txt b/dist-scripts/retroarch-360-README.txt index b49abcea34..e30a1964c9 100644 --- a/dist-scripts/retroarch-360-README.txt +++ b/dist-scripts/retroarch-360-README.txt @@ -1,5 +1,5 @@ ------------------------------------------------------------------------------ -RETROARCH 360 - 0.9.8.3 +RETROARCH 360 - 0.9.8.4 ------------------------------------------------------------------------------ RetroConsole Level: 2 Author: Themaister, Squarepusher/Twin Aphex diff --git a/dist-scripts/retroarch-CHANGELOG.txt b/dist-scripts/retroarch-CHANGELOG.txt index ce5aa01f3d..09ae09e38f 100644 --- a/dist-scripts/retroarch-CHANGELOG.txt +++ b/dist-scripts/retroarch-CHANGELOG.txt @@ -1,5 +1,14 @@ RETROARCH CONSOLE ------------------------------------------------------------------------------ +v0.9.8.4 +------------------------------------------------------------------------------ +* [FBA core] [For Wii/Gamecube/Xbox 1 only] The main FBA version now has CPS1/CPS2/ +Neogeo and Mega Drive/PC Engine drivers removed. To play CPS1, use FBA Cores CPS1. + To play CPS2, use FBA Cores CPS2. To play NeoGoe, use FBA Cores Neo. +* [FBA core] Made FBA Cores CPS1 - use this to play CPS1 games (all CPS1 ROMs +fit into memory on Gamecube). +* [Gamecube] Made RetroArch cores 'standalone' - ie. no core switching. +------------------------------------------------------------------------------ v0.9.8.3 ------------------------------------------------------------------------------ * [FBA core] Various changes/fixes diff --git a/dist-scripts/retroarch-ngc-readme.txt b/dist-scripts/retroarch-ngc-readme.txt new file mode 100644 index 0000000000..75c4e21c81 --- /dev/null +++ b/dist-scripts/retroarch-ngc-readme.txt @@ -0,0 +1,226 @@ +------------------------------------------------------------------------------ +RETROARCH GX - GAMECUBE - 0.9.8.4 +------------------------------------------------------------------------------ +RetroConsole Level: 0 +Author: Themaister, Toad King, Squarepusher/Twin Aphex +------------------------------------------------------------------------------ + +------------------------------------------------------------------------------ +HOW TO INSTALL THIS +------------------------------------------------------------------------------ +Copy the entire directory (retroarch-ngc) to your SD card in your 'apps' +directory. Start up something like SDLOAD (or whatever you're using for +loading DOL files) and load any of the cores. + + +On first startup, RetroArch will create a folder in the root of your storage +device called 'retroarch'. All RetroArch configuration files are stored here. + +------------------------------------------------------------------------------ +HOW TO USE THIS +------------------------------------------------------------------------------ +On first startup, RetroArch will select one of the dozen or so +emulator/game cores. The name of the core currently loaded will be +shown at the bottom side of the screen. + +You can now select a ROM that this core supports and load it in the Filebrowser. + +To select a different core - go to the Settings menu (see 'Ingame controls'). +Select the option 'Core' and hit the A button. A filebrowser will appear +where you can select a different core. Press A to switch to the +emulator/game core. + +After doing so, select 'Restart RetroArch' to load the newly selected core. + +------------------------------------------------------------------------------ +CONTROLS +------------------------------------------------------------------------------ +RetroArch will create a new input config file for each core you load. +All input settings will be saved when RetroArch exits. + +NOTE: When starting up a new core for the first time, you might have to first +initialize the input settings. Go to the Settings menu (see 'Ingame controls') +and go to 'Controller #number config'. Re-set the 'Device' by going back and +forth between a previous device. The controls will be automatically applied. + +This only has to be done once per core. + +------------------------------------------------------------------------------ +INGAME CONTROLS +------------------------------------------------------------------------------ +During ingame operation you can do some extra actions: + + +Gamecube pad Z - Go to Settings +Gamecube pad L + R + LStick Up + Rstick Up - Go back to 'Menu' +Gamecube pad L + R + LStick Down + Rstick Down - Quit RetroArch + +Right Thumb Stick - Down - Fast-forwards the game +Right Thumb Stick - Up - Rewinds the game in real-time + ('Rewind' has to be enabled in the + 'Settings' menu - warning - comes at a + performance decrease but will be worth it + if you love this feature) +RStick Left + Z - Decrease save state slot +Rtick Right + Z - Increase save state slot +RStick Up + Z - Load selected save state slot +RStick Down + Z - Save selected save state slot + +------------------------------------------------------------------------------ +WHAT IS RETROARCH? +------------------------------------------------------------------------------ +RetroArch is a modular multi-system emulator system that is designed to +be fast, lightweight and portable. + +------------------------------------------------------------------------------ +WHAT IS LIBRETRO? +------------------------------------------------------------------------------ +Libretro is the API that RetroArch uses. It makes it easy to port games +and emulators to a single core backend, such as RetroArch. + +For the user, this means - more ports to play with, more crossplatform +portability, less worrying about developers having to reinvent the wheel +writing boilerplate UI/port code - so that they can get busy with writing +the emulator/porting the emulator/game. + +------------------------------------------------------------------------------ +WHAT'S THE BIG DEAL? +------------------------------------------------------------------------------ +Right now it's unique in that it runs the same emulator cores on +multiple systems (such as Xbox 360, Xbox 1, PS3, PC, Wii, Android, +etc). + +For each emulator 'core', RetroArch makes use of a library API that we +like to call 'libretro'. + +Think of libretro as an interface for emulator and game ports. You can +make a libretro port once and expect the same code to run on all the +platforms that RetroArch supports. It's designed with simplicity and +ease of use in mind so that the porter can worry about the port at hand +instead of having to wrestle with an obfuscatory API. + +The purpose of libretro is to help ease the work of the emulator/game +porter by giving him an API that allows him to target multiple platforms +at once without having to redo any code. He doesn't have to worry about +writing input/video/audio drivers - all of that is supplied to him by +RetroArch. All he has to do is to have the emulator port hook into the +libretro API and that's it - we take care of the rest. + +------------------------------------------------------------------------------ +WII PORT +------------------------------------------------------------------------------ +The Gamecube port of RetroArch has the following features: + +- Real-time rewinding (probably too slow for most cores) +- Switching between emulator cores seamlessly, and ability to install +new libretro cores + +------------------------------------------------------------------------------ +EMULATOR/GAME CORES BUNDLED WITH WII PORT +------------------------------------------------------------------------------ +The following emulators/games have been ported to RetroArch and are included in +the Gamecube release of RetroArch. + +For more information about them, see the included +'retroarch-libretro-README.txt' file. + +- Final Burn Alpha [version 0.2.97.28] +- Final Burn Alpha Cores (CPS1 - CPS2 - NeoGeo) [version 0.2.97.28] (**) +- FCEUmm (Nintendo Entertainment System) [recent SVN version] +- NEStopia (Nintendo Entertainment System) [1.44] +- Gambatte (Game Boy | Super Game Boy | Game Boy Color) [version 0.5.0 WIP] +- Genesis Plus GX (Sega SG-1000 | Master System | Game Gear | Genesis/Mega Drive | + Sega CD) [version 1.7.3] +- SNES9x Next (Super Nintendo/Super Famicom) +- VBA Next (Game Boy Advance) (*) +- Prboom (for playing Doom 1/Doom 2/Ultimate Doom/Final Doom) +- Mednafen PCE Fast (PC Engine/PC Engine CD/Turbografx 16) +- Mednafen Wonderswan (WonderSwan/WonderSwan Color/WonderSwan Crystal) +- Mednafen NGP (Neo Geo Pocket Color) +- Mednafen VB (Virtual Boy) + +All of the emulators listed above are the latest versions currently +available. Most of them have been specifically optimized so that +they will run better on Gamecube (some games would not reach fullspeed +without these optimizations). + +* Most (all) games don't run at fullspeed on Gamecube (VBA Next is a +RetroConsole Level 2 emulator port). + +------------------------------------------------------------------------------ +WHAT EXTENSIONS ARE SUPPORTED BY EACH CORE +------------------------------------------------------------------------------ +- Prboom WAD|wad +- SNES9x Next smc|fig|sfc|gd3|gd7|dx2|bsx|swc|zip|SMC|FIG|SFC|BSX|GD3| + GD7|DX2|SWC +- Genesis Plus GX md|smd|bin|gen|zip|MD|SMD|bin|GEN|ZIP|sms|SMS|gg|GG|sg|SG| + cue|CUE +- VBA Next GBA|gba +- FCEUmm nes|NES|unif|UNIF +- NEStopia nes|NES|fds|FDS +- Gambatte gb|gbc|dmg|zip|GB|GBC|DMG|ZIP +- Final Burn Alpha zip|ZIP +- Mednafen PCE pce|PCE|cue|CUE +- Mednafen Wonderswan ws|WS|wsc|WSC +- Mednafen NGP ngp|NGP +- Mednafen VB vb|VB + +------------------------------------------------------------------------------ +ZIP SUPPORT (IN GENERAL) +------------------------------------------------------------------------------ +Selecting a ZIP file will temporarily unzip that file to the harddrive. The +temporary file will be deleted as soon as the game gets unloaded and/or when +you quit RetroArch. + +NOTE: For the FBA core (and other cores that have 'block_extract' set to +true) - selecting a ZIP file from the Filebrowser will load that game +directly. + +------------------------------------------------------------------------------ +Troubleshooting +------------------------------------------------------------------------------ + +If you find that RetroArch no longer works for whatever reason, there is +a way to get it back to work - + +- Remove retroarch.cfg from the 'retroarch' folder on your storage device, +then start up again. The Libretro management service in RetroArch should +automatically pick a random libretro core and write this to the config file. + +------------------------------------------------------------------------------ +What can you expect in the future? +------------------------------------------------------------------------------ +- Do a Blackberry Playbook/Blackberry 10 RetroArch port +- Do an iOS port of RetroArch (will need hardware for this - gifts appreciated) +- Make the libxenon port release-worthy. +- Add console-friendly features (nicely formatted names for FBA, some better +way to do core switching, etc) +- Fix NxEngine issues on consoles +- Finish up MAME 0.72 port +- Finish up ScummVM port +- Port of VICE to libretro +- More emulators, more games that will run on RetroArch +- Lots of other crazy ideas that might or might not pan out + +------------------------------------------------------------------------------ +Credits +------------------------------------------------------------------------------ +- Hyllian for the xBR shader family. +- Opium2k for the nice manual shaders (bundled with PS3 release). +- Deank for assistance with RetroArch Salamander on CFW PS3s and +- Mudlord for his Waterpaint/Noise shaders. + Multiman interoperability. +- FBA devs for adopting the libretro port. +- Ekeeke for help with the Genesis Plus GX port. +- ToadKing for having done a lot of work on RetroArch Wii. +- Freakdave for helping out with the Xbox 1 port. + +------------------------------------------------------------------------------ +Websites +------------------------------------------------------------------------------ +Twitter: http://twitter.com/libretro +Source: http://github.com/libretro +Homepage: http://www.libretro.org +IRC: #retroarch (freenode) + +------------------------------------------------------------------------------ diff --git a/dist-scripts/retroarch-ps3-README.txt b/dist-scripts/retroarch-ps3-README.txt index bef61e3d54..f88f5d83ff 100644 --- a/dist-scripts/retroarch-ps3-README.txt +++ b/dist-scripts/retroarch-ps3-README.txt @@ -1,5 +1,5 @@ ------------------------------------------------------------------------------ -RETROARCH PS3 - 0.9.8.3 +RETROARCH PS3 - 0.9.8.4 ------------------------------------------------------------------------------ RetroConsole Level: 2 Author: Themaister, Squarepusher/Twin Aphex diff --git a/dist-scripts/retroarch-wii-readme.txt b/dist-scripts/retroarch-wii-readme.txt index eb28304084..e5e956ab59 100644 --- a/dist-scripts/retroarch-wii-readme.txt +++ b/dist-scripts/retroarch-wii-readme.txt @@ -1,5 +1,5 @@ ------------------------------------------------------------------------------ -RETROARCH WII - 0.9.8.3 +RETROARCH GX - WII - 0.9.8.4 ------------------------------------------------------------------------------ RetroConsole Level: 1 Author: Themaister, Toad King, Squarepusher/Twin Aphex diff --git a/dist-scripts/retroarch-xbox1-README.txt b/dist-scripts/retroarch-xbox1-README.txt index f60efa1329..b9aa4c17bf 100644 --- a/dist-scripts/retroarch-xbox1-README.txt +++ b/dist-scripts/retroarch-xbox1-README.txt @@ -1,5 +1,5 @@ ------------------------------------------------------------------------------ -RETROARCH XBOX 1 - 0.9.8.3 +RETROARCH XBOX 1 - 0.9.8.4 ------------------------------------------------------------------------------ RetroConsole Level: 1 Author: Themaister, Squarepusher/Twin Aphex, Freakdave diff --git a/driver.c b/driver.c index 471eb50025..b120f18cad 100644 --- a/driver.c +++ b/driver.c @@ -409,9 +409,13 @@ void init_audio(void) g_extern.audio_data.chunk_size = g_extern.audio_data.nonblock_chunk_size; } + g_extern.audio_data.orig_src_ratio = + g_extern.audio_data.src_ratio = + (double)g_settings.audio.out_rate / g_settings.audio.in_rate; + const char *resampler = *g_settings.audio.resampler ? g_settings.audio.resampler : NULL; if (!rarch_resampler_realloc(&g_extern.audio_data.resampler_data, &g_extern.audio_data.resampler, - resampler)) + resampler, g_extern.audio_data.orig_src_ratio)) { RARCH_ERR("Failed to initialize resampler \"%s\".\n", resampler ? resampler : "(default)"); g_extern.audio_active = false; @@ -424,10 +428,6 @@ void init_audio(void) rarch_assert(g_settings.audio.out_rate < g_settings.audio.in_rate * AUDIO_MAX_RATIO); rarch_assert(g_extern.audio_data.outsamples = (sample_t*)malloc(outsamples_max * sizeof(sample_t))); - g_extern.audio_data.orig_src_ratio = - g_extern.audio_data.src_ratio = - (double)g_settings.audio.out_rate / g_settings.audio.in_rate; - if (g_extern.audio_active && g_settings.audio.rate_control) { if (driver.audio->buffer_size && driver.audio->write_avail) diff --git a/frontend/frontend_console.c b/frontend/frontend_console.c index fbeadc3e54..dc818f4eb7 100644 --- a/frontend/frontend_console.c +++ b/frontend/frontend_console.c @@ -28,7 +28,9 @@ #include "platform/platform_ps3_exec.c" #elif defined(GEKKO) #include "platform/platform_gx.c" +#ifdef HW_RVL #include "platform/platform_gx_exec.c" +#endif #elif defined(_XBOX) #include "platform/platform_xdk.c" #include "platform/platform_xdk_exec.c" @@ -111,8 +113,6 @@ static void verbose_log_init(void) RARCH_LOG("Turning on verbose logging...\n"); } -#ifdef HAVE_LIBRETRO_MANAGEMENT - // Transforms a library id to a name suitable as a pathname. static void get_libretro_core_name(char *name, size_t size) { @@ -141,6 +141,8 @@ static void get_libretro_core_name(char *name, size_t size) } } +#ifdef HAVE_LIBRETRO_MANAGEMENT + // If a CORE executable of name CORE.extension exists, rename filename // to a more sane name. static bool install_libretro_core(const char *core_exe_path, const char *tmp_path, const char *extension) diff --git a/frontend/frontend_console.h b/frontend/frontend_console.h index e414521d23..2b6362ffee 100644 --- a/frontend/frontend_console.h +++ b/frontend/frontend_console.h @@ -18,7 +18,9 @@ #define _FRONTEND_CONSOLE_H //optional RetroArch forward declarations +#ifdef HAVE_RARCH_EXEC static void rarch_console_exec(const char *path); +#endif static void verbose_log_init(void); #ifdef IS_SALAMANDER @@ -28,8 +30,6 @@ static void find_first_libretro_core(char *first_file, const char * ext); #endif -#ifdef HAVE_LIBRETRO_MANAGEMENT static void get_libretro_core_name(char *name, size_t size); -#endif #endif diff --git a/frontend/menu/rgui.c b/frontend/menu/rgui.c index 322c627de9..ed035fa0d8 100644 --- a/frontend/menu/rgui.c +++ b/frontend/menu/rgui.c @@ -380,9 +380,12 @@ static void render_text(rgui_handle_t *rgui) rgui_file_type_t menu_type = 0; rgui_list_back(rgui->path_stack, &dir, &menu_type, NULL); +#ifdef HAVE_LIBRETRO_MANAGEMENT if (menu_type == RGUI_SETTINGS_CORE) snprintf(title, sizeof(title), "CORE SELECTION"); - else if (rgui_is_controller_menu(menu_type) || rgui_is_viewport_menu(menu_type) || menu_type == RGUI_SETTINGS) + else +#endif + if (rgui_is_controller_menu(menu_type) || rgui_is_viewport_menu(menu_type) || menu_type == RGUI_SETTINGS) snprintf(title, sizeof(title), "SETTINGS: %s", dir); else snprintf(title, sizeof(title), "FILE BROWSER: %s", dir); @@ -481,7 +484,9 @@ static void render_text(rgui_handle_t *rgui) snprintf(type_str, sizeof(type_str), (g_extern.lifecycle_mode_state & (1ULL << MODE_FPS_DRAW)) ? "ON" : "OFF"); break; case RGUI_SETTINGS_CUSTOM_VIEWPORT: +#ifdef HAVE_LIBRETRO_MANAGEMENT case RGUI_SETTINGS_CORE: +#endif case RGUI_SETTINGS_CONTROLLER_1: case RGUI_SETTINGS_CONTROLLER_2: case RGUI_SETTINGS_CONTROLLER_3: @@ -668,9 +673,11 @@ static int rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t { if(rgui_current_gx_resolution < GX_RESOLUTIONS_LAST - 1) { +#ifdef HW_RVL if ((rgui_current_gx_resolution + 1) > GX_RESOLUTIONS_640_480) if (CONF_GetVideo() != CONF_VIDEO_PAL) return 0; +#endif rgui_current_gx_resolution++; gx_set_video_mode(rgui_gx_resolutions[rgui_current_gx_resolution][0], rgui_gx_resolutions[rgui_current_gx_resolution][1]); @@ -784,7 +791,7 @@ static int rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t if (g_extern.main_is_init && changed) { if (!rarch_resampler_realloc(&g_extern.audio_data.resampler_data, &g_extern.audio_data.resampler, - g_settings.audio.resampler)) + g_settings.audio.resampler, g_extern.audio_data.orig_src_ratio == 0.0 ? 1.0 : g_extern.audio_data.orig_src_ratio)) { RARCH_ERR("Failed to initialize resampler \"%s\".\n", g_settings.audio.resampler); g_extern.audio_active = false; @@ -924,7 +931,9 @@ static void rgui_settings_populate_entries(rgui_handle_t *rgui) RGUI_MENU_ITEM("Audio Resampler", RGUI_SETTINGS_RESAMPLER_TYPE); RGUI_MENU_ITEM("SRAM Saves in \"sram\" Dir", RGUI_SETTINGS_SRAM_DIR); RGUI_MENU_ITEM("State Saves in \"state\" Dir", RGUI_SETTINGS_STATE_DIR); +#ifdef HAVE_LIBRETRO_MANAGEMENT RGUI_MENU_ITEM("Core", RGUI_SETTINGS_CORE); +#endif RGUI_MENU_ITEM("Controller #1 Config", RGUI_SETTINGS_CONTROLLER_1); RGUI_MENU_ITEM("Controller #2 Config", RGUI_SETTINGS_CONTROLLER_2); RGUI_MENU_ITEM("Controller #3 Config", RGUI_SETTINGS_CONTROLLER_3); @@ -1085,8 +1094,10 @@ int rgui_settings_iterate(rgui_handle_t *rgui, rgui_action_t action) rgui_file_type_t type = 0; const char *label = 0; rgui_list_at(rgui->folder_buf, rgui->directory_ptr, &label, &type, NULL); +#ifdef HAVE_LIBRETRO_MANAGEMENT if (type == RGUI_SETTINGS_CORE) label = default_paths.core_dir; +#endif const char *dir = 0; rgui_file_type_t menu_type = 0; size_t directory_ptr = 0; @@ -1122,7 +1133,12 @@ int rgui_settings_iterate(rgui_handle_t *rgui, rgui_action_t action) case RGUI_ACTION_RIGHT: case RGUI_ACTION_OK: case RGUI_ACTION_START: - if ((rgui_is_controller_menu(type) || type == RGUI_SETTINGS_CORE) && action == RGUI_ACTION_OK) + if ((rgui_is_controller_menu(type) +#ifdef HAVE_LIBRETRO_MANAGEMENT + || type == RGUI_SETTINGS_CORE +#endif + ) + && action == RGUI_ACTION_OK) { rgui_list_push(rgui->path_stack, label, type, rgui->directory_ptr); rgui->directory_ptr = 0; @@ -1158,7 +1174,11 @@ int rgui_settings_iterate(rgui_handle_t *rgui, rgui_action_t action) rgui_list_back(rgui->path_stack, &dir, &menu_type, &directory_ptr); - if (rgui->need_refresh && !(menu_type == RGUI_FILE_DIRECTORY || menu_type == RGUI_FILE_DEVICE || menu_type == RGUI_SETTINGS_CORE)) + if (rgui->need_refresh && !(menu_type == RGUI_FILE_DIRECTORY || menu_type == RGUI_FILE_DEVICE +#ifdef HAVE_LIBRETRO_MANAGEMENT + || menu_type == RGUI_SETTINGS_CORE +#endif + )) { rgui->need_refresh = false; if (rgui_is_controller_menu(menu_type)) @@ -1260,6 +1280,7 @@ int rgui_iterate(rgui_handle_t *rgui, rgui_action_t action) } else { +#ifdef HAVE_LIBRETRO_MANAGEMENT if (menu_type == RGUI_SETTINGS_CORE) { strlcpy(g_settings.libretro, path, sizeof(g_settings.libretro)); @@ -1275,6 +1296,7 @@ int rgui_iterate(rgui_handle_t *rgui, rgui_action_t action) g_extern.lifecycle_mode_state |= (1ULL << MODE_EXITSPAWN); } else +#endif { snprintf(rgui->path_buf, sizeof(rgui->path_buf), "%s/%s", dir, path); @@ -1297,6 +1319,7 @@ int rgui_iterate(rgui_handle_t *rgui, rgui_action_t action) break; case RGUI_ACTION_SETTINGS: +#ifdef HAVE_LIBRETRO_MANAGEMENT if (menu_type == RGUI_SETTINGS_CORE) { rgui->directory_ptr = directory_ptr; @@ -1304,6 +1327,7 @@ int rgui_iterate(rgui_handle_t *rgui, rgui_action_t action) rgui_list_pop(rgui->path_stack); } else +#endif { rgui_list_push(rgui->path_stack, "", RGUI_SETTINGS, rgui->directory_ptr); rgui->directory_ptr = 0; @@ -1321,7 +1345,11 @@ int rgui_iterate(rgui_handle_t *rgui, rgui_action_t action) // refresh values in case the stack changed rgui_list_back(rgui->path_stack, &dir, &menu_type, &directory_ptr); - if (rgui->need_refresh && (menu_type == RGUI_FILE_DIRECTORY || menu_type == RGUI_FILE_DEVICE || menu_type == RGUI_SETTINGS_CORE)) + if (rgui->need_refresh && (menu_type == RGUI_FILE_DIRECTORY || menu_type == RGUI_FILE_DEVICE +#ifdef HAVE_LIBRETRO_MANAGEMENT + || menu_type == RGUI_SETTINGS_CORE +#endif + )) { rgui->need_refresh = false; rgui_list_clear(rgui->folder_buf); diff --git a/frontend/menu/rgui.h b/frontend/menu/rgui.h index e6be443ad6..f187d41c2b 100644 --- a/frontend/menu/rgui.h +++ b/frontend/menu/rgui.h @@ -58,7 +58,9 @@ typedef enum RGUI_SETTINGS_ZIP_EXTRACT, RGUI_SETTINGS_SRAM_DIR, RGUI_SETTINGS_STATE_DIR, +#ifdef HAVE_LIBRETRO_MANAGEMENT RGUI_SETTINGS_CORE, +#endif RGUI_SETTINGS_CONTROLLER_1, RGUI_SETTINGS_CONTROLLER_2, RGUI_SETTINGS_CONTROLLER_3, diff --git a/frontend/menu/rmenu.c b/frontend/menu/rmenu.c index 91b23db716..851d5a5005 100644 --- a/frontend/menu/rmenu.c +++ b/frontend/menu/rmenu.c @@ -1341,8 +1341,10 @@ static int set_setting_action(void *data, unsigned switchvalue, uint64_t input) case SETTING_DEFAULT_VIDEO_ALL: if(input & (1ULL << RMENU_DEVICE_NAV_START)) { +#if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) set_setting_action(NULL, SETTING_SHADER, 1ULL << RMENU_DEVICE_NAV_START); set_setting_action(NULL, SETTING_SHADER_2, 1ULL << RMENU_DEVICE_NAV_START); +#endif } break; case SETTING_SOUND_MODE: diff --git a/frontend/menu/rmenu_gx.c b/frontend/menu/rmenu_gx.c index b2fa934d93..57601058a3 100644 --- a/frontend/menu/rmenu_gx.c +++ b/frontend/menu/rmenu_gx.c @@ -68,7 +68,11 @@ enum static bool folder_cb(const char *directory, rgui_file_enum_cb_t file_cb, void *userdata, void *ctx) { +#ifdef HAVE_LIBRETRO_MANAGEMENT bool core_chooser = (userdata) ? *(rgui_file_type_t *)userdata == RGUI_SETTINGS_CORE : false; +#else + bool core_chooser = false; +#endif if (!*directory) { diff --git a/frontend/platform/platform_gx.c b/frontend/platform/platform_gx.c index cd3c9a529f..06aea8bd5f 100644 --- a/frontend/platform/platform_gx.c +++ b/frontend/platform/platform_gx.c @@ -334,9 +334,9 @@ static void system_init(void) static void system_exitspawn(void) { -#ifdef IS_SALAMANDER +#if defined(IS_SALAMANDER) rarch_console_exec(default_paths.libretro_path); -#else +#elif defined(HW_RVL) // try to launch the core directly first, then fallback to salamander rarch_console_exec(g_settings.libretro); rarch_console_exec(g_extern.fullpath); diff --git a/gfx/context/drm_egl_ctx.c b/gfx/context/drm_egl_ctx.c index 41fb4c041f..6172dcb10b 100644 --- a/gfx/context/drm_egl_ctx.c +++ b/gfx/context/drm_egl_ctx.c @@ -250,21 +250,7 @@ static bool gfx_ctx_init(void) if (g_inited) return false; - static const char *modules[] = { - "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos", NULL - }; - - for (int i = 0; modules[i]; i++) - { - RARCH_LOG("[KMS/EGL]: Trying to load module %s ...\n", modules[i]); - g_drm_fd = drmOpen(modules[i], NULL); - if (g_drm_fd >= 0) - { - RARCH_LOG("[KMS/EGL]: Found module %s.\n", modules[i]); - break; - } - } - + g_drm_fd = open("/dev/dri/card0", O_RDWR); if (g_drm_fd < 0) { RARCH_ERR("[KMS/EGL]: Couldn't open DRM device.\n"); @@ -281,58 +267,48 @@ static bool gfx_ctx_init(void) for (int i = 0; i < g_resources->count_connectors; i++) { g_connector = drmModeGetConnector(g_drm_fd, g_resources->connectors[i]); - if (g_connector->connection == DRM_MODE_CONNECTED) + + if (!g_connector) + continue; + if (g_connector->connection == DRM_MODE_CONNECTED && g_connector->count_modes > 0) break; drmModeFreeConnector(g_connector); g_connector = NULL; } - // TODO: Figure out what index for crtcs to use ... - g_orig_crtc = drmModeGetCrtc(g_drm_fd, g_resources->crtcs[0]); - if (!g_orig_crtc) - RARCH_WARN("[KMS/EGL]: Cannot find original CRTC.\n"); - if (!g_connector) { RARCH_ERR("[KMS/EGL]: Couldn't get device connector.\n"); goto error; } - for (int i = 0, area = 0; i < g_connector->count_modes; i++) + for (int i = 0; i < g_resources->count_encoders; i++) { - drmModeModeInfo *current_mode = &g_connector->modes[i]; - int current_area = current_mode->hdisplay * current_mode->vdisplay; - if (current_area > area) - { - g_drm_mode = current_mode; - area = current_area; - } + g_encoder = drmModeGetEncoder(g_drm_fd, g_resources->encoders[i]); + + if (!g_encoder) + continue; + if (g_encoder->encoder_id == g_connector->encoder_id) + break; + + drmModeFreeEncoder(g_encoder); + g_encoder = NULL; } - if (!g_drm_mode) - { - RARCH_ERR("[KMS/EGL]: Couldn't find DRM mode.\n"); - goto error; - } - - for (int i = 0; i < g_resources->count_encoders; i++) - { - g_encoder = drmModeGetEncoder(g_drm_fd, g_resources->encoders[i]); - if (g_encoder->encoder_id == g_connector->encoder_id) - break; - - drmModeFreeEncoder(g_encoder); - g_encoder = NULL; - } - - if (!g_encoder) + if (!g_encoder) { RARCH_ERR("[KMS/EGL]: Couldn't find DRM encoder.\n"); goto error; } - g_crtc_id = g_encoder->crtc_id; + g_drm_mode = &g_connector->modes[0]; + + g_crtc_id = g_encoder->crtc_id; + g_orig_crtc = drmModeGetCrtc(g_drm_fd, g_crtc_id); + if (!g_orig_crtc) + RARCH_WARN("[KMS/EGL]: Cannot find original CRTC.\n"); + g_connector_id = g_connector->connector_id; g_fb_width = g_drm_mode->hdisplay; @@ -381,6 +357,8 @@ static struct drm_fb *drm_fb_get_from_bo(struct gbm_bo *bo) unsigned stride = gbm_bo_get_stride(bo); unsigned handle = gbm_bo_get_handle(bo).u32; + RARCH_LOG("[KMS/EGL]: New FB: %ux%u (stride: %u).\n", width, height, stride); + int ret = drmModeAddFB(g_drm_fd, width, height, 24, 32, stride, handle, &fb->fb_id); if (ret < 0) { @@ -412,11 +390,11 @@ static bool gfx_ctx_set_video_mode( #define EGL_ATTRIBS_BASE \ EGL_SURFACE_TYPE, EGL_WINDOW_BIT, \ - EGL_RED_SIZE, 0, \ - EGL_GREEN_SIZE, 0, \ - EGL_BLUE_SIZE, 0, \ - EGL_DEPTH_SIZE, 0, \ - EGL_STENCIL_SIZE, 0 + EGL_RED_SIZE, 1, \ + EGL_GREEN_SIZE, 1, \ + EGL_BLUE_SIZE, 1, \ + EGL_ALPHA_SIZE, 0, \ + EGL_DEPTH_SIZE, 0 static const EGLint egl_attribs_gl[] = { EGL_ATTRIBS_BASE, @@ -575,7 +553,7 @@ void gfx_ctx_destroy(void) g_next_bo = NULL; if (g_drm_fd >= 0) - drmClose(g_drm_fd); + close(g_drm_fd); g_drm_fd = -1; unsigned frames = last_page_flip - first_page_flip; diff --git a/gfx/context/glx_ctx.c b/gfx/context/glx_ctx.c index 7f7a0efadd..c181dcf8fa 100644 --- a/gfx/context/glx_ctx.c +++ b/gfx/context/glx_ctx.c @@ -30,6 +30,7 @@ static Display *g_dpy; static Window g_win; +static GLXWindow g_glx_win; static Colormap g_cmap; static Atom g_quit_atom; static bool g_has_focus; @@ -229,7 +230,7 @@ static void gfx_ctx_check_window(bool *quit, static void gfx_ctx_swap_buffers(void) { if (g_is_double) - glXSwapBuffers(g_dpy, g_win); + glXSwapBuffers(g_dpy, g_glx_win); } static void gfx_ctx_set_resize(unsigned width, unsigned height) @@ -281,6 +282,8 @@ static bool gfx_ctx_init(void) if (g_inited) return false; + XInitThreads(); + static const int visual_attribs[] = { GLX_X_RENDERABLE , True, GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT, @@ -402,6 +405,8 @@ static bool gfx_ctx_set_video_mode( CWBorderPixel | CWColormap | CWEventMask | (true_full ? CWOverrideRedirect : 0), &swa); XSetWindowBackground(g_dpy, g_win, 0); + g_glx_win = glXCreateWindow(g_dpy, g_fbc, g_win, 0); + gfx_ctx_update_window_title(true); x11_set_window_attr(g_dpy, g_win); @@ -444,7 +449,7 @@ static bool gfx_ctx_set_video_mode( goto error; } - glXMakeCurrent(g_dpy, g_win, g_ctx); + glXMakeContextCurrent(g_dpy, g_glx_win, g_glx_win, g_ctx); XSync(g_dpy, False); g_quit_atom = XInternAtom(g_dpy, "WM_DELETE_WINDOW", False); @@ -493,13 +498,16 @@ static void gfx_ctx_destroy(void) { if (g_dpy && g_ctx) { - glXMakeCurrent(g_dpy, None, NULL); + glXMakeContextCurrent(g_dpy, None, None, NULL); glXDestroyContext(g_dpy, g_ctx); g_ctx = NULL; } if (g_win) { + glXDestroyWindow(g_dpy, g_glx_win); + g_glx_win = 0; + // Save last used monitor for later. #ifdef HAVE_XINERAMA XWindowAttributes target; diff --git a/gfx/context/xegl_ctx.c b/gfx/context/xegl_ctx.c index 61f93be874..85b8b7d591 100644 --- a/gfx/context/xegl_ctx.c +++ b/gfx/context/xegl_ctx.c @@ -180,13 +180,15 @@ static bool gfx_ctx_init(void) if (g_inited) return false; + XInitThreads(); + #define EGL_ATTRIBS_BASE \ EGL_SURFACE_TYPE, EGL_WINDOW_BIT, \ - EGL_RED_SIZE, 0, \ - EGL_GREEN_SIZE, 0, \ - EGL_BLUE_SIZE, 0, \ - EGL_DEPTH_SIZE, 0, \ - EGL_STENCIL_SIZE, 0 + EGL_RED_SIZE, 1, \ + EGL_GREEN_SIZE, 1, \ + EGL_BLUE_SIZE, 1, \ + EGL_ALPHA_SIZE, 0, \ + EGL_DEPTH_SIZE, 0 static const EGLint egl_attribs_gl[] = { EGL_ATTRIBS_BASE, diff --git a/gx/gx_video.c b/gx/gx_video.c index 25cb678a86..c7ddc86e56 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -229,12 +229,8 @@ void gx_set_video_mode(unsigned fbWidth, unsigned lines) VIDEO_SetPostRetraceCallback(retrace_callback); VIDEO_SetBlack(false); VIDEO_Flush(); - //VIDEO_WaitVSync(); - //if (gx_mode.viTVMode & VI_NON_INTERLACE) - // VIDEO_WaitVSync(); GX_SetViewport(0, 0, gx_mode.fbWidth, gx_mode.efbHeight, 0, 1); - //GX_SetScissor(0, 0, gx_mode.fbWidth, gx_mode.efbHeight); GX_SetDispCopySrc(0, 0, gx_mode.fbWidth, gx_mode.efbHeight); f32 y_scale = GX_GetYScaleFactor(gx_mode.efbHeight, gx_mode.xfbHeight); @@ -693,6 +689,8 @@ static void gx_resize(void *data) unsigned width = gx->win_width, height = gx->win_height; uint64_t lifecycle_mode_state = g_extern.lifecycle_mode_state; + (void)lifecycle_mode_state; + #ifdef HW_RVL VIDEO_SetTrapFilter(lifecycle_mode_state & (1ULL << MODE_VIDEO_SOFT_FILTER_ENABLE)); #endif diff --git a/msvc/RetroArch-360/RetroArch-360.vcxproj b/msvc/RetroArch-360/RetroArch-360.vcxproj index d5c2f6b889..4b83a3d88d 100644 --- a/msvc/RetroArch-360/RetroArch-360.vcxproj +++ b/msvc/RetroArch-360/RetroArch-360.vcxproj @@ -113,7 +113,7 @@ true false MultiThreadedDebug - _DEBUG;_XBOX;HAVE_XINPUT2;PACKAGE_VERSION="0.9.8.3";%(PreprocessorDefinitions);HAVE_DEFAULT_RETROPAD_INPUT;_CRT_SECURE_NO_WARNINGS;main=rarch_main;RARCH_CONSOLE;HAVE_RMENU;HAVE_FILEBROWSER;HAVE_NETPLAY;HAVE_SOCKET_LEGACY;HAVE_ZLIB;HAVE_RARCH_MAIN_WRAP;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_VID_CONTEXT;HAVE_D3D9;_XBOX360;HAVE_FBO;HAVE_SCREENSHOTS;WANT_RZLIB;HAVE_SINC;SINC_LOWER_QUALITY;HAVE_XAUDIO + _DEBUG;_XBOX;HAVE_XINPUT2;PACKAGE_VERSION="0.9.8.4";%(PreprocessorDefinitions);HAVE_DEFAULT_RETROPAD_INPUT;_CRT_SECURE_NO_WARNINGS;main=rarch_main;RARCH_CONSOLE;HAVE_RMENU;HAVE_FILEBROWSER;HAVE_NETPLAY;HAVE_SOCKET_LEGACY;HAVE_ZLIB;HAVE_RARCH_MAIN_WRAP;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_VID_CONTEXT;HAVE_D3D9;_XBOX360;HAVE_FBO;HAVE_SCREENSHOTS;WANT_RZLIB;HAVE_SINC;SINC_LOWER_QUALITY;HAVE_XAUDIO Callcap @@ -151,7 +151,7 @@ AnalyzeOnly false MultiThreadedDebug - _DEBUG;_XBOX;%(PreprocessorDefinitions);HAVE_XINPUT2;PACKAGE_VERSION="0.9.8.3";HAVE_DEFAULT_RETROPAD_INPUT;_CRT_SECURE_NO_WARNINGS;main=rarch_main;HAVE_FILEBROWSER;RARCH_CONSOLE;HAVE_RMENU;HAVE_ZLIB;HAVE_RARCH_MAIN_WRAP;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_VID_CONTEXT;HAVE_D3D9;_XBOX360;HAVE_FBO;HAVE_SCREENSHOTS;WANT_RZLIB;HAVE_SINC;SINC_LOWER_QUALITY + _DEBUG;_XBOX;%(PreprocessorDefinitions);HAVE_XINPUT2;PACKAGE_VERSION="0.9.8.4";HAVE_DEFAULT_RETROPAD_INPUT;_CRT_SECURE_NO_WARNINGS;main=rarch_main;HAVE_FILEBROWSER;RARCH_CONSOLE;HAVE_RMENU;HAVE_ZLIB;HAVE_RARCH_MAIN_WRAP;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_VID_CONTEXT;HAVE_D3D9;_XBOX360;HAVE_FBO;HAVE_SCREENSHOTS;WANT_RZLIB;HAVE_SINC;SINC_LOWER_QUALITY Callcap @@ -190,7 +190,7 @@ Size false MultiThreaded - NDEBUG;_XBOX;PROFILE;%(PreprocessorDefinitions);HAVE_XINPUT2;PACKAGE_VERSION="0.9.8.3";HAVE_DEFAULT_RETROPAD_INPUT;_CRT_SECURE_NO_WARNINGS;RARCH_CONSOLE;HAVE_RMENU;main=rarch_main;HAVE_FILEBROWSER;HAVE_ZLIB;HAVE_RARCH_MAIN_WRAP;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_VID_CONTEXT;HAVE_D3D9;_XBOX360;HAVE_FBO;HAVE_SCREENSHOTS;WANT_RZLIB;HAVE_SINC;SINC_LOWER_QUALITY;HAVE_XAUDIO + NDEBUG;_XBOX;PROFILE;%(PreprocessorDefinitions);HAVE_XINPUT2;PACKAGE_VERSION="0.9.8.4";HAVE_DEFAULT_RETROPAD_INPUT;_CRT_SECURE_NO_WARNINGS;RARCH_CONSOLE;HAVE_RMENU;main=rarch_main;HAVE_FILEBROWSER;HAVE_ZLIB;HAVE_RARCH_MAIN_WRAP;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_VID_CONTEXT;HAVE_D3D9;_XBOX360;HAVE_FBO;HAVE_SCREENSHOTS;WANT_RZLIB;HAVE_SINC;SINC_LOWER_QUALITY;HAVE_XAUDIO Callcap @@ -234,7 +234,7 @@ Size false MultiThreaded - NDEBUG;_XBOX;PROFILE;FASTCAP;%(PreprocessorDefinitions);HAVE_XINPUT2;PACKAGE_VERSION="0.9.8.3";HAVE_DEFAULT_RETROPAD_INPUT;_CRT_SECURE_NO_WARNINGS;main=rarch_main;HAVE_FILEBROWSER;HAVE_ZLIB;HAVE_RARCH_MAIN_WRAP;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_VID_CONTEXT;HAVE_D3D9;_XBOX360;HAVE_FBO;HAVE_SCREENSHOTS;WANT_RZLIB;HAVE_SINC;SINC_LOWER_QUALITY;HAVE_RMENU;HAVE_XAUDIO + NDEBUG;_XBOX;PROFILE;FASTCAP;%(PreprocessorDefinitions);HAVE_XINPUT2;PACKAGE_VERSION="0.9.8.4";HAVE_DEFAULT_RETROPAD_INPUT;_CRT_SECURE_NO_WARNINGS;main=rarch_main;HAVE_FILEBROWSER;HAVE_ZLIB;HAVE_RARCH_MAIN_WRAP;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_VID_CONTEXT;HAVE_D3D9;_XBOX360;HAVE_FBO;HAVE_SCREENSHOTS;WANT_RZLIB;HAVE_SINC;SINC_LOWER_QUALITY;HAVE_RMENU;HAVE_XAUDIO true @@ -275,7 +275,7 @@ false false MultiThreaded - NDEBUG;_XBOX;%(PreprocessorDefinitions);HAVE_XINPUT2;PACKAGE_VERSION="0.9.8.3";_CRT_SECURE_NO_WARNINGS;HAVE_DEFAULT_RETROPAD_INPUT;main=rarch_main;RARCH_CONSOLE=1;HAVE_FILEBROWSER;HAVE_NETPLAY;HAVE_SOCKET_LEGACY;HAVE_ZLIB;HAVE_RARCH_MAIN_WRAP;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_VID_CONTEXT;HAVE_D3D9;_XBOX360;HAVE_FBO;HAVE_SCREENSHOTS;WANT_RZLIB;HAVE_SINC;SINC_LOWER_QUALITY;HAVE_RMENU;HAVE_XAUDIO + NDEBUG;_XBOX;%(PreprocessorDefinitions);HAVE_XINPUT2;PACKAGE_VERSION="0.9.8.4";_CRT_SECURE_NO_WARNINGS;HAVE_DEFAULT_RETROPAD_INPUT;main=rarch_main;RARCH_CONSOLE=1;HAVE_FILEBROWSER;HAVE_NETPLAY;HAVE_SOCKET_LEGACY;HAVE_ZLIB;HAVE_RARCH_MAIN_WRAP;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_VID_CONTEXT;HAVE_D3D9;_XBOX360;HAVE_FBO;HAVE_SCREENSHOTS;WANT_RZLIB;HAVE_SINC;SINC_LOWER_QUALITY;HAVE_RMENU;HAVE_XAUDIO true @@ -316,7 +316,7 @@ false false MultiThreaded - NDEBUG;_XBOX;LTCG;%(PreprocessorDefinitions);HAVE_XINPUT2;PACKAGE_VERSION="0.9.8.3";_CRT_SECURE_NO_WARNINGS;HAVE_DEFAULT_RETROPAD_INPUT;RARCH_CONSOLE;HAVE_RMENU;main=rarch_main;HAVE_FILEBROWSER;HAVE_NETPLAY;HAVE_SOCKET_LEGACY;HAVE_ZLIB;HAVE_RARCH_MAIN_WRAP;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_VID_CONTEXT;HAVE_D3D9;_XBOX360;HAVE_FBO;HAVE_SCREENSHOTS;WANT_RZLIB;HAVE_SINC;SINC_LOWER_QUALITY;HAVE_XAUDIO + NDEBUG;_XBOX;LTCG;%(PreprocessorDefinitions);HAVE_XINPUT2;PACKAGE_VERSION="0.9.8.4";_CRT_SECURE_NO_WARNINGS;HAVE_DEFAULT_RETROPAD_INPUT;RARCH_CONSOLE;HAVE_RMENU;main=rarch_main;HAVE_FILEBROWSER;HAVE_NETPLAY;HAVE_SOCKET_LEGACY;HAVE_ZLIB;HAVE_RARCH_MAIN_WRAP;HAVE_RARCH_EXEC;HAVE_LIBRETRO_MANAGEMENT;D3DCOMPILE_USEVOIDS;HAVE_GRIFFIN;HAVE_HLSL;HAVE_VID_CONTEXT;HAVE_D3D9;_XBOX360;HAVE_FBO;HAVE_SCREENSHOTS;WANT_RZLIB;HAVE_SINC;SINC_LOWER_QUALITY;HAVE_XAUDIO true diff --git a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj index c25481a4a2..47e31faa2e 100644 --- a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj +++ b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj @@ -22,7 +22,7 @@ Optimization="3" OptimizeForProcessor="2" AdditionalIncludeDirectories=""$(SolutionDir)\msvc-stdint";"$(SolutionDir)\msvc-71"" - PreprocessorDefinitions="_DEBUG;_XBOX;_XBOX1;HAVE_RMENU;HAVE_RMENU_GUI;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.8.3\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;HAVE_GRIFFIN;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER;HAVE_SCREENSHOTS;WANT_RZLIB;HAVE_SINC;SINC_LOWER_QUALITY" + PreprocessorDefinitions="_DEBUG;_XBOX;_XBOX1;HAVE_RMENU;HAVE_RMENU_GUI;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.8.4\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;HAVE_GRIFFIN;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER;HAVE_SCREENSHOTS;WANT_RZLIB;HAVE_SINC;SINC_LOWER_QUALITY" MinimalRebuild="TRUE" BasicRuntimeChecks="0" RuntimeLibrary="1" @@ -72,7 +72,7 @@ OmitFramePointers="TRUE" OptimizeForProcessor="2" AdditionalIncludeDirectories=""$(SolutionDir)\msvc-stdint";"$(SolutionDir)\msvc-71"" - PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RMENU;HAVE_RMENU_GUI;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.8.3\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;PROFILE;HAVE_GRIFFIN;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER;HAVE_SCREENSHOTS;WANT_RZLIB;HAVE_SINC;SINC_LOWER_QUALITY" + PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RMENU;HAVE_RMENU_GUI;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.8.4\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;PROFILE;HAVE_GRIFFIN;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER;HAVE_SCREENSHOTS;WANT_RZLIB;HAVE_SINC;SINC_LOWER_QUALITY" StringPooling="TRUE" RuntimeLibrary="0" BufferSecurityCheck="TRUE" @@ -127,7 +127,7 @@ OmitFramePointers="TRUE" OptimizeForProcessor="2" AdditionalIncludeDirectories=""$(SolutionDir)\msvc-stdint";"$(SolutionDir)\msvc-71"" - PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RMENU;HAVE_RMENU_GUI;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.8.3\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;PROFILE;FASTCAP;HAVE_GRIFFIN;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER;HAVE_SCREENSHOTS;WANT_RZLIB;HAVE_SINC;SINC_LOWER_QUALITY" + PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RMENU;HAVE_RMENU_GUI;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.8.4\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;PROFILE;FASTCAP;HAVE_GRIFFIN;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER;HAVE_SCREENSHOTS;WANT_RZLIB;HAVE_SINC;SINC_LOWER_QUALITY" StringPooling="TRUE" RuntimeLibrary="0" BufferSecurityCheck="TRUE" @@ -188,7 +188,7 @@ EnableFiberSafeOptimizations="TRUE" OptimizeForProcessor="2" AdditionalIncludeDirectories=""$(SolutionDir)\msvc-stdint";"$(SolutionDir)\msvc-71"" - PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RMENU;HAVE_RMENU_GUI;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.8.3\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;HAVE_GRIFFIN;inline=_inline;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER;HAVE_SCREENSHOTS;WANT_RZLIB;HAVE_SINC;SINC_LOWER_QUALITY" + PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RMENU;HAVE_RMENU_GUI;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.8.4\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;HAVE_GRIFFIN;inline=_inline;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER;HAVE_SCREENSHOTS;WANT_RZLIB;HAVE_SINC;SINC_LOWER_QUALITY" StringPooling="TRUE" RuntimeLibrary="0" BufferSecurityCheck="TRUE" @@ -241,7 +241,7 @@ OmitFramePointers="TRUE" OptimizeForProcessor="2" AdditionalIncludeDirectories=""$(SolutionDir)\msvc-stdint";"$(SolutionDir)\msvc-71"" - PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RMENU;HAVE_RMENU_GUI;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.8.3\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;LTCG;HAVE_GRIFFIN;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER;HAVE_SCREENSHOTS;WANT_RZLIB;HAVE_SINC;SINC_LOWER_QUALITY" + PreprocessorDefinitions="NDEBUG;_XBOX;_XBOX1;HAVE_RMENU;HAVE_RMENU_GUI;RARCH_CONSOLE;HAVE_XINPUT_XBOX1;PACKAGE_VERSION=\"0.9.8.4\";__STDC_CONSTANT_MACROS;HAVE_ZLIB;LTCG;HAVE_GRIFFIN;HAVE_RARCH_MAIN_WRAP;HAVE_LIBRETRO_MANAGEMENT;HAVE_RARCH_EXEC;HAVE_DEFAULT_RETROPAD_INPUT;HAVE_VID_CONTEXT;HAVE_DSOUND;HAVE_D3D8;HAVE_FILEBROWSER;HAVE_SCREENSHOTS;WANT_RZLIB;HAVE_SINC;SINC_LOWER_QUALITY" StringPooling="TRUE" RuntimeLibrary="0" BufferSecurityCheck="TRUE" diff --git a/ngc/sidestep.c b/ngc/sidestep.c deleted file mode 100644 index 733e28feb6..0000000000 --- a/ngc/sidestep.c +++ /dev/null @@ -1,329 +0,0 @@ -/** This code is licensed to you under the terms of the GNU GPL, version 2; - see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt */ - -/**************************************************************************** -* SideStep DOL Loading -* -* This module runs a DOL file from Auxilliary RAM. This removes any memory -* issues which might occur - and also means you can easily overwrite yourself! -* -* softdev March 2007 -***************************************************************************/ -#ifndef HW_RVL -#include -#include -#include -#include -#include -#include -#include - -#include "sidestep.h" -#include "ssaram.h" -#include "../retroarch_logger.h" - -#define ARAMSTART 0x8000 - -/*** A global or two ***/ -static DOLHEADER *dolhdr; -static u32 minaddress = 0; -static u32 maxaddress = 0; -static char dol_readbuf[2048]; - -typedef int (*BOOTSTUB) (u32 entrypoint, u32 dst, u32 src, int len, u32 invlen, u32 invaddress); - -/*--- Auxilliary RAM Support ----------------------------------------------*/ -/**************************************************************************** -* ARAMStub -* -* This is an assembly routine and should only be called through ARAMRun -* *DO NOT CALL DIRECTLY!* -****************************************************************************/ -static void ARAMStub(void) -{ - /*** The routine expects to receive - R3 = entrypoint - R4 = Destination in main RAM - R5 = Source from ARAM - R6 = Data length - R7 = Invalidate Length / 32 - R8 = Invalidate Start Address - ***/ - - asm("mtctr 7"); - asm("Invalidate:"); - asm("dcbi 0,8"); - asm("addi 8,8,32"); - asm("bdnz Invalidate"); - - asm("lis 8,0xcc00"); - asm("ori 8,8,0x3004"); - asm("lis 7,0"); - asm("stw 7,0(8)"); - - asm("mfmsr 8"); - asm("ori 8,8,2"); - asm("rlwinm 8,8,0,17,15"); - asm("mtmsr 8"); - - asm("lis 7,0xcc00"); - asm("ori 7,7,0x5020"); - asm("stw 4,0(7)"); /*** Store Memory Address ***/ - asm("stw 5,4(7)"); /*** Store ARAM Address ***/ - asm("stw 6,8(7)"); /*** Store Length ***/ - - asm("lis 7,0xcc00"); - asm("ori 7,7,0x500a"); - asm("WaitDMA:"); - asm("lhz 5,0(7)"); - asm("andi. 5,5,0x200"); - asm("cmpwi 5,5,0"); - asm("bne WaitDMA"); /*** Wait DMA Complete ***/ - - /*** Update exceptions ***/ - asm("lis 8,0x8000"); - asm("lis 5,0x4c00"); - asm("ori 5,5,0x64"); - asm("stw 5,0x100(8)"); - asm("stw 5,0x200(8)"); - asm("stw 5,0x300(8)"); - asm("stw 5,0x400(8)"); - asm("stw 5,0x500(8)"); - asm("stw 5,0x600(8)"); - asm("stw 5,0x700(8)"); - asm("stw 5,0x800(8)"); - asm("stw 5,0x900(8)"); - asm("stw 5,0xC00(8)"); - asm("stw 5,0xD00(8)"); - asm("stw 5,0xF00(8)"); - asm("stw 5,0x1300(8)"); - asm("stw 5,0x1400(8)"); - asm("stw 5,0x1700(8)"); - - /*** Flush it all again ***/ - asm("lis 7,0x30"); - asm("lis 8,0x8000"); - asm("mtctr 7"); - asm("flush:"); - asm("dcbst 0,8"); - asm("sync"); - asm("icbi 0,8"); - asm("addi 8,8,8"); - asm("bdnz flush"); - asm("isync"); - - /*** Fix ints ***/ - asm("mfmsr 8"); - asm("rlwinm 8,8,0,17,15"); - asm("mtmsr 8"); - - asm("mfmsr 8"); - asm("ori 8,8,8194"); - asm("mtmsr 8"); - - /*** Party! ***/ - asm("mtlr 3"); - asm("blr"); /*** Boot DOL ***/ - -} - -/**************************************************************************** -* ARAMRun -* -* This actually runs the new DOL ... eventually ;) -****************************************************************************/ -void ARAMRun(u32 entrypoint, u32 dst, u32 src, u32 len) -{ - char *p; - char *s = (char *) ARAMStub; - BOOTSTUB stub; - - /*** Shutdown libOGC ***/ - SYS_ResetSystem(SYS_SHUTDOWN, 0, 0); - - /*** Copy ARAMStub to 81300000 ***/ - if (dst + len < 0x81300000) p = (void *) 0x81300000; - else p = (void *) 0x80003100; - memcpy(p, s, 256); /*** Way too much - but who cares ***/ - - /*** Round length to 32 bytes ***/ - if (len & 0x1f) len = (len & ~0x1f) + 0x20; - - /*** Flush everything! ***/ - DCFlushRange((void *) 0x80000000, 0x1800000); - - /*** Boot the bugger :D ***/ - stub = (BOOTSTUB) p; - RARCH_LOG("Launching relocated stub at %08x\n", (unsigned) p); - stub((u32) entrypoint, dst, src, len | 0x80000000, len >> 5, dst); -} - -/**************************************************************************** -* ARAMClear -* -* To make life easy, just clear out the Auxilliary RAM completely. -****************************************************************************/ -static void ARAMClear(void) -{ - int i; - char *buffer = memalign(32, 2048); /*** A little 2k buffer ***/ - - memset(buffer, 0, 2048); - DCFlushRange(buffer, 2048); - - for (i = ARAMSTART; i < 0x1000000; i += 2048) - { - ARAMPut(buffer, (char *) i, 2048); - while (AR_GetDMAStatus()); - } - - free(buffer); -} - -/*--- DOL Decoding functions -----------------------------------------------*/ -/**************************************************************************** -* DOLMinMax -* -* Calculate the DOL minimum and maximum memory addresses -****************************************************************************/ -static void DOLMinMax(DOLHEADER * dol) -{ - int i; - - maxaddress = 0; - minaddress = 0x87100000; - - /*** Go through DOL sections ***/ - /*** Text sections ***/ - for (i = 0; i < MAXTEXTSECTION; i++) - { - if (dol->textAddress[i] && dol->textLength[i]) - { - if (dol->textAddress[i] < minaddress) - minaddress = dol->textAddress[i]; - if ((dol->textAddress[i] + dol->textLength[i]) > maxaddress) - maxaddress = dol->textAddress[i] + dol->textLength[i]; - } - } - - /*** Data sections ***/ - for (i = 0; i < MAXDATASECTION; i++) - { - if (dol->dataAddress[i] && dol->dataLength[i]) - { - if (dol->dataAddress[i] < minaddress) - minaddress = dol->dataAddress[i]; - if ((dol->dataAddress[i] + dol->dataLength[i]) > maxaddress) - maxaddress = dol->dataAddress[i] + dol->dataLength[i]; - } - } - - /*** And of course, any BSS section ***/ - if (dol->bssAddress) - { - if ((dol->bssAddress + dol->bssLength) > maxaddress) - maxaddress = dol->bssAddress + dol->bssLength; - } - - /*** Some OLD dols, Xrick in particular, require ~128k clear memory ***/ - maxaddress += 0x20000; - - RARCH_LOG("Min Address: %08x Max Address: %08x\n", minaddress, maxaddress); -} - -/**************************************************************************** -* DOLtoARAM -* -* Moves the DOL from main memory to ARAM, positioning as it goes -* -* Pass in a memory pointer to a previously loaded DOL -****************************************************************************/ -int DOLtoARAM(const char *dol_name) -{ - u32 sizeinbytes; - int i, j; - static DOLHEADER dolhead; - FILE *f = fopen(dol_name, "rb"); - - if (!f) - { - RARCH_ERR("Could not open\"%s\"\n", dol_name); - return 0; - } - - fread(&dolhead, 1, sizeof(DOLHEADER), f); - /*** Make sure ARAM subsystem is alive! ***/ - AR_Init(NULL, 0); /*** No stack - we need it all ***/ - ARAMClear(); - - /*** Get DOL header ***/ - dolhdr = (DOLHEADER *) &dolhead; - - /*** First, does this look like a DOL? ***/ - if (dolhdr->textOffset[0] != DOLHDRLENGTH) - { - RARCH_ERR("\"%s\" is not a .dol file\n", dol_name); - return 0; - } - - /*** Get DOL stats ***/ - DOLMinMax(dolhdr); - sizeinbytes = maxaddress - minaddress; - - /*** Move all DOL sections into ARAM ***/ - /*** Move text sections ***/ - for (i = 0; i < MAXTEXTSECTION; i++) - { - /*** This may seem strange, but in developing d0lLZ we found some with section addresses with zero length ***/ - if (dolhdr->textAddress[i] && dolhdr->textLength[i]) - { - fseek(f, dolhdr->textOffset[i], SEEK_SET); - unsigned count = dolhdr->textLength[i] / sizeof(dol_readbuf); - for (j = 0; j < count; j++) - { - fread(dol_readbuf, 1, sizeof(dol_readbuf), f); - ARAMPut(dol_readbuf, (char *) ((dolhdr->textAddress[i] - minaddress) + (sizeof(dol_readbuf) * j) + ARAMSTART), - sizeof(dol_readbuf)); - } - unsigned remaining = dolhdr->textLength[i] % sizeof(dol_readbuf); - if (remaining) - { - fread(dol_readbuf, 1, remaining, f); - ARAMPut(dol_readbuf, (char *) ((dolhdr->textAddress[i] - minaddress) + (sizeof(dol_readbuf) * count) + ARAMSTART), - remaining); - } - } - } - - /*** Move data sections ***/ - for (i = 0; i < MAXDATASECTION; i++) - { - if (dolhdr->dataAddress[i] && dolhdr->dataLength[i]) - { - fseek(f, dolhdr->dataOffset[i], SEEK_SET); - unsigned count = dolhdr->dataLength[i] / sizeof(dol_readbuf); - for (j = 0; j < count; j++) - { - fread(dol_readbuf, 1, sizeof(dol_readbuf), f); - ARAMPut(dol_readbuf, (char *) ((dolhdr->dataAddress[i] - minaddress) + (sizeof(dol_readbuf) * j) + ARAMSTART), - sizeof(dol_readbuf)); - } - unsigned remaining = dolhdr->dataLength[i] % sizeof(dol_readbuf); - if (remaining) - { - fread(dol_readbuf, 1, remaining, f); - ARAMPut(dol_readbuf, (char *) ((dolhdr->dataAddress[i] - minaddress) + (sizeof(dol_readbuf) * count) + ARAMSTART), - remaining); - } - } - } - - fclose(f); - - /*** Now go run it ***/ - ARAMRun(dolhdr->entryPoint, minaddress, ARAMSTART, sizeinbytes); - - /*** Will never return ***/ - return 1; -} -#endif diff --git a/ngc/sidestep.h b/ngc/sidestep.h deleted file mode 100644 index faeaafc76f..0000000000 --- a/ngc/sidestep.h +++ /dev/null @@ -1,39 +0,0 @@ -/**************************************************************************** -* SideStep DOL Loading -* -* This module runs a DOL file from Auxilliary RAM. This removes any memory -* issues which might occur - and also means you can easily overwrite yourself! -* -* softdev March 2007 -***************************************************************************/ -#ifndef HW_RVL -#ifndef __SIDESTEP__ -#define __SIDESTEP__ - -/*** A standard DOL header ***/ -#define DOLHDRLENGTH 256 /*** All DOLS must have a 256 byte header ***/ -#define MAXTEXTSECTION 7 -#define MAXDATASECTION 11 - -/*** A handy DOL structure ***/ -typedef struct { - unsigned int textOffset[MAXTEXTSECTION]; - unsigned int dataOffset[MAXDATASECTION]; - - unsigned int textAddress[MAXTEXTSECTION]; - unsigned int dataAddress[MAXDATASECTION]; - - unsigned int textLength[MAXTEXTSECTION]; - unsigned int dataLength[MAXDATASECTION]; - - unsigned int bssAddress; - unsigned int bssLength; - - unsigned int entryPoint; - unsigned int unused[MAXTEXTSECTION]; -} DOLHEADER; - -int DOLtoARAM(const char *dol_name); - -#endif -#endif diff --git a/record/ffemu.c b/record/ffemu.c index 4728c7ac44..a7ffffe4ff 100644 --- a/record/ffemu.c +++ b/record/ffemu.c @@ -281,7 +281,8 @@ static bool ffemu_init_audio(ffemu_t *handle) rarch_resampler_realloc(&audio->resampler_data, &audio->resampler, - *g_settings.audio.resampler ? g_settings.audio.resampler : NULL); + *g_settings.audio.resampler ? g_settings.audio.resampler : NULL, + audio->ratio); } else { diff --git a/wii/pkg/meta.xml b/wii/pkg/meta.xml index 677c2e8975..f0cf97defb 100644 --- a/wii/pkg/meta.xml +++ b/wii/pkg/meta.xml @@ -2,7 +2,7 @@ RetroArch GX Maister, Squarepusher, ToadKing - 0.9.8.3 + 0.9.8.4 2012-2013 Multi-system emulator A port of RetroArch to the GameCube/Wii. diff --git a/wii/wiiuse/classic.c b/wii/wiiuse/classic.c deleted file mode 100644 index 629c1277de..0000000000 --- a/wii/wiiuse/classic.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * wiiuse - * - * Written By: - * Michael Laforest < para > - * Email: < thepara (--AT--) g m a i l [--DOT--] com > - * - * Copyright 2006-2007 - * - * This file is part of wiiuse. - * - * This program 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 Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 this program. If not, see . - * - * $Header: /lvm/shared/ds/ds/cvs/devkitpro-cvsbackup/libogc/wiiuse/classic.c,v 1.7 2008-11-14 13:34:57 shagkur Exp $ - * - */ - -/** - * @file - * @brief Classic controller expansion device. - */ - -/* This source as presented is a modified version of original wiiuse for use - * with RetroArch, and must not be confused with the original software. */ - -#include -#include -#include -#include - -#ifdef WIN32 - #include -#endif - -#include "definitions.h" -#include "wiiuse_internal.h" -#include "dynamics.h" -#include "events.h" -#include "classic.h" -#include "io.h" - -static void classic_ctrl_pressed_buttons(struct classic_ctrl_t* cc, short now); - -/** - * @brief Handle the handshake data from the classic controller. - * - * @param cc A pointer to a classic_ctrl_t structure. - * @param data The data read in from the device. - * @param len The length of the data block, in bytes. - * - * @return Returns 1 if handshake was successful, 0 if not. - */ - -#define HANDSHAKE_BYTES_USED 12 - -int classic_ctrl_handshake(struct wiimote_t* wm, struct classic_ctrl_t* cc, ubyte* data, uword len) { - //int i; - //int offset = 0; - - cc->btns = 0; - cc->btns_held = 0; - cc->btns_released = 0; - - /* decrypt data */ - /* - for (i = 0; i < len; ++i) - data[i] = (data[i] ^ 0x17) + 0x17; - */ - if (data[0] == 0xFF || len < HANDSHAKE_BYTES_USED) { - /* - * Sometimes the data returned here is not correct. - * This might happen because the wiimote is lagging - * behind our initialization sequence. - * To fix this just request the handshake again. - * - * Other times it's just the first 16 bytes are 0xFF, - * but since the next 16 bytes are the same, just use - * those. - */ - if (len < 17 || len < HANDSHAKE_BYTES_USED + 16 || data[16] == 0xFF) { - /* get the calibration data again */ - //WIIUSE_DEBUG("Classic controller handshake appears invalid, trying again."); - wiiuse_read_data(wm, data, WM_EXP_MEM_CALIBR, EXP_HANDSHAKE_LEN, wiiuse_handshake_expansion); - } else - data += 16; - } - - - /* joystick stuff */ - cc->ljs.max.x = data[0] / 4; - cc->ljs.min.x = data[1] / 4; - cc->ljs.center.x = data[2] / 4; - cc->ljs.max.y = data[3] / 4; - cc->ljs.min.y = data[4] / 4; - cc->ljs.center.y = data[5] / 4; - - cc->rjs.max.x = data[6] / 8; - cc->rjs.min.x = data[7] / 8; - cc->rjs.center.x = data[8] / 8; - cc->rjs.max.y = data[9] / 8; - cc->rjs.min.y = data[10] / 8; - cc->rjs.center.y = data[11] / 8; - - /* handshake done */ - wm->event = WIIUSE_CLASSIC_CTRL_INSERTED; - wm->exp.type = EXP_CLASSIC; - - #ifdef WIN32 - wm->timeout = WIIMOTE_DEFAULT_TIMEOUT; - #endif - - return 1; -} - - -/** - * @brief The classic controller disconnected. - * - * @param cc A pointer to a classic_ctrl_t structure. - */ -void classic_ctrl_disconnected(struct classic_ctrl_t* cc) -{ - memset(cc, 0, sizeof(struct classic_ctrl_t)); -} - - - -/** - * @brief Handle classic controller event. - * - * @param cc A pointer to a classic_ctrl_t structure. - * @param msg The message specified in the event packet. - */ -void classic_ctrl_event(struct classic_ctrl_t* cc, ubyte* msg) { - //int i; - - /* decrypt data */ - /* - for (i = 0; i < 6; ++i) - msg[i] = (msg[i] ^ 0x17) + 0x17; - */ - classic_ctrl_pressed_buttons(cc, BIG_ENDIAN_SHORT(*(short*)(msg + 4))); - - /* left/right buttons */ - cc->ls_raw = (((msg[2] & 0x60) >> 2) | ((msg[3] & 0xE0) >> 5)); - cc->rs_raw = (msg[3] & 0x1F); - - /* - * TODO - LR range hardcoded from 0x00 to 0x1F. - * This is probably in the calibration somewhere. - */ -#ifndef GEKKO - cc->r_shoulder = ((float)r / 0x1F); - cc->l_shoulder = ((float)l / 0x1F); -#endif - /* calculate joystick orientation */ - cc->ljs.pos.x = (msg[0] & 0x3F); - cc->ljs.pos.y = (msg[1] & 0x3F); - cc->rjs.pos.x = ((msg[0] & 0xC0) >> 3) | ((msg[1] & 0xC0) >> 5) | ((msg[2] & 0x80) >> 7); - cc->rjs.pos.y = (msg[2] & 0x1F); -#ifndef GEKKO - calc_joystick_state(&cc->ljs, cc->ljs.pos.x, cc->ljs.pos.y); - calc_joystick_state(&cc->rjs, cc->rjs.pos.x, cc->rjs.pos.y); -#endif -} - - -/** - * @brief Find what buttons are pressed. - * - * @param cc A pointer to a classic_ctrl_t structure. - * @param msg The message byte specified in the event packet. - */ -static void classic_ctrl_pressed_buttons(struct classic_ctrl_t* cc, short now) { - /* message is inverted (0 is active, 1 is inactive) */ - now = ~now & CLASSIC_CTRL_BUTTON_ALL; - - /* preserve old btns pressed */ - cc->btns_last = cc->btns; - - /* pressed now & were pressed, then held */ - cc->btns_held = (now & cc->btns); - - /* were pressed or were held & not pressed now, then released */ - cc->btns_released = ((cc->btns | cc->btns_held) & ~now); - - /* buttons pressed now */ - cc->btns = now; -} diff --git a/wii/wiiuse/classic.h b/wii/wiiuse/classic.h deleted file mode 100644 index 2e741efca5..0000000000 --- a/wii/wiiuse/classic.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * wiiuse - * - * Written By: - * Michael Laforest < para > - * Email: < thepara (--AT--) g m a i l [--DOT--] com > - * - * Copyright 2006-2007 - * - * This file is part of wiiuse. - * - * This program 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 Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 this program. If not, see . - * - * $Header: /lvm/shared/ds/ds/cvs/devkitpro-cvsbackup/libogc/wiiuse/classic.h,v 1.1 2008-05-08 09:42:14 shagkur Exp $ - * - */ - -/** - * @file - * @brief Classic controller expansion device. - */ - -/* This source as presented is a modified version of original wiiuse for use - * with RetroArch, and must not be confused with the original software. */ - -#ifndef CLASSIC_H_INCLUDED -#define CLASSIC_H_INCLUDED - -#include "wiiuse_internal.h" - -#ifdef __cplusplus -extern "C" { -#endif - -int classic_ctrl_handshake(struct wiimote_t* wm, struct classic_ctrl_t* cc, ubyte* data, uword len); - -void classic_ctrl_disconnected(struct classic_ctrl_t* cc); - -void classic_ctrl_event(struct classic_ctrl_t* cc, ubyte* msg); - -#ifdef __cplusplus -} -#endif - -#endif // CLASSIC_H_INCLUDED diff --git a/wii/wiiuse/definitions.h b/wii/wiiuse/definitions.h deleted file mode 100644 index 04dc5be6d8..0000000000 --- a/wii/wiiuse/definitions.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef __DEFINITIONS_H__ -#define __DEFINITIONS_H__ - -#include "os.h" - -#define WIIMOTE_PI 3.14159265f - -//#define WITH_WIIUSE_DEBUG - -/* Error output macros */ -#define WIIUSE_ERROR(fmt, ...) fprintf(stderr, "[ERROR] " fmt "\n", ##__VA_ARGS__) - -/* Warning output macros */ -#define WIIUSE_WARNING(fmt, ...) fprintf(stderr, "[WARNING] " fmt "\n", ##__VA_ARGS__) - -/* Information output macros */ -#define WIIUSE_INFO(fmt, ...) fprintf(stderr, "[INFO] " fmt "\n", ##__VA_ARGS__) - -#ifdef WITH_WIIUSE_DEBUG - #ifdef WIN32 - #define WIIUSE_DEBUG(fmt, ...) do { \ - char* file = __FILE__; \ - int i = strlen(file) - 1; \ - for (; i && (file[i] != '\\'); --i); \ - fprintf(stderr, "[DEBUG] %s:%i: " fmt "\n", file+i+1, __LINE__, ##__VA_ARGS__); \ - } while (0) - #else - #define WIIUSE_DEBUG(fmt, ...) fprintf(stderr, "[DEBUG] " __FILE__ ":%i: " fmt "\n", __LINE__, ##__VA_ARGS__) - #endif -#else - #define WIIUSE_DEBUG(fmt, ...) -#endif - -#if 1 -#define WII_DEBUG(fmt, ...) do { \ - printf("[WDEBUG] " __FILE__ ":%i: " fmt "\n", __LINE__, ##__VA_ARGS__); \ - usleep(3000000); \ - } while (0) -#else - #define WII_DEBUG(fmt, ...) -#endif - - -/* Convert between radians and degrees */ -#define RAD_TO_DEGREE(r) ((r * 180.0f) / WIIMOTE_PI) -#define DEGREE_TO_RAD(d) (d * (WIIMOTE_PI / 180.0f)) - -/* Convert to big endian */ -#define BIG_ENDIAN_LONG(i) (htonl(i)) -#define BIG_ENDIAN_SHORT(i) (htons(i)) - -#define absf(x) ((x >= 0) ? (x) : (x * -1.0f)) -#define diff_f(x, y) ((x >= y) ? (absf(x - y)) : (absf(y - x))) - -#endif diff --git a/wii/wiiuse/dynamics.c b/wii/wiiuse/dynamics.c deleted file mode 100644 index f8f1b81676..0000000000 --- a/wii/wiiuse/dynamics.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * wiiuse - * - * Written By: - * Michael Laforest < para > - * Email: < thepara (--AT--) g m a i l [--DOT--] com > - * - * Copyright 2006-2007 - * - * This file is part of wiiuse. - * - * This program 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 Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 this program. If not, see . - * - * $Header: /lvm/shared/ds/ds/cvs/devkitpro-cvsbackup/libogc/wiiuse/dynamics.c,v 1.2 2008-11-14 13:34:57 shagkur Exp $ - * - */ - -/** - * @file - * @brief Handles the dynamics of the wiimote. - * - * The file includes functions that handle the dynamics - * of the wiimote. Such dynamics include orientation and - * motion sensing. - */ - -#include -#include -#include - -#ifdef WIN32 - #include -#endif - -#include "definitions.h" -#include "wiiuse_internal.h" -#include "ir.h" -#include "dynamics.h" - -/** - * @brief Calculate the roll, pitch, yaw. - * - * @param ac An accelerometer (accel_t) structure. - * @param accel [in] Pointer to a vec3w_t structure that holds the raw acceleration data. - * @param orient [out] Pointer to a orient_t structure that will hold the orientation data. - * @param rorient [out] Pointer to a orient_t structure that will hold the non-smoothed orientation data. - * @param smooth If smoothing should be performed on the angles calculated. 1 to enable, 0 to disable. - * - * Given the raw acceleration data from the accelerometer struct, calculate - * the orientation of the device and set it in the \a orient parameter. - */ -void calculate_orientation(struct accel_t* ac, struct vec3w_t* accel, struct orient_t* orient, int smooth) { - float xg, yg, zg; - float x, y, z; - - /* - * roll - use atan(z / x) [ ranges from -180 to 180 ] - * pitch - use atan(z / y) [ ranges from -180 to 180 ] - * yaw - impossible to tell without IR - */ - - /* yaw - set to 0, IR will take care of it if it's enabled */ - orient->yaw = 0.0f; - - /* find out how much it has to move to be 1g */ - xg = (float)ac->cal_g.x; - yg = (float)ac->cal_g.y; - zg = (float)ac->cal_g.z; - - /* find out how much it actually moved and normalize to +/- 1g */ - x = ((float)accel->x - (float)ac->cal_zero.x) / xg; - y = ((float)accel->y - (float)ac->cal_zero.y) / yg; - z = ((float)accel->z - (float)ac->cal_zero.z) / zg; - - /* make sure x,y,z are between -1 and 1 for the tan functions */ - if (x < -1.0f) x = -1.0f; - else if (x > 1.0f) x = 1.0f; - if (y < -1.0f) y = -1.0f; - else if (y > 1.0f) y = 1.0f; - if (z < -1.0f) z = -1.0f; - else if (z > 1.0f) z = 1.0f; - - /* if it is over 1g then it is probably accelerating and not reliable */ - if (abs(accel->x - ac->cal_zero.x) <= (ac->cal_g.x+10)) { - /* roll */ - x = RAD_TO_DEGREE(atan2f(x, z)); - if(isfinite(x)) { - orient->roll = x; - orient->a_roll = x; - } - } - - if (abs(accel->y - ac->cal_zero.y) <= (ac->cal_g.y+10)) { - /* pitch */ - y = RAD_TO_DEGREE(atan2f(y, z)); - if(isfinite(y)) { - orient->pitch = y; - orient->a_pitch = y; - } - } - - /* smooth the angles if enabled */ - if (smooth) { - apply_smoothing(ac, orient, SMOOTH_ROLL); - apply_smoothing(ac, orient, SMOOTH_PITCH); - } -} - - -/** - * @brief Calculate the gravity forces on each axis. - * - * @param ac An accelerometer (accel_t) structure. - * @param accel [in] Pointer to a vec3w_t structure that holds the raw acceleration data. - * @param gforce [out] Pointer to a gforce_t structure that will hold the gravity force data. - */ -void calculate_gforce(struct accel_t* ac, struct vec3w_t* accel, struct gforce_t* gforce) { - float xg, yg, zg; - - /* find out how much it has to move to be 1g */ - xg = (float)ac->cal_g.x; - yg = (float)ac->cal_g.y; - zg = (float)ac->cal_g.z; - - /* find out how much it actually moved and normalize to +/- 1g */ - gforce->x = ((float)accel->x - (float)ac->cal_zero.x) / xg; - gforce->y = ((float)accel->y - (float)ac->cal_zero.y) / yg; - gforce->z = ((float)accel->z - (float)ac->cal_zero.z) / zg; -} - -static float applyCalibration(float inval,float minval, float maxval,float centerval) -{ - float ret; - /* We don't use the exact ranges but the ranges +1 in case we get bad calibration - * data - avoid div0 */ - - if (inval == centerval) - ret = 0; - else if (inval < centerval) - ret = (inval - centerval) / (centerval - minval + 1); - else - ret = (inval - centerval) / (maxval - centerval + 1); - return ret; -} - -/** - * @brief Calculate the angle and magnitude of a joystick. - * - * @param js [out] Pointer to a joystick_t structure. - * @param x The raw x-axis value. - * @param y The raw y-axis value. - */ -void calc_joystick_state(struct joystick_t* js, float x, float y) { - float rx, ry, ang; - - /* - * Since the joystick center may not be exactly: - * (min + max) / 2 - * Then the range from the min to the center and the center to the max - * may be different. - * Because of this, depending on if the current x or y value is greater - * or less than the assoicated axis center value, it needs to be interpolated - * between the center and the minimum or maxmimum rather than between - * the minimum and maximum. - * - * So we have something like this: - * (x min) [-1] ---------*------ [0] (x center) [0] -------- [1] (x max) - * Where the * is the current x value. - * The range is therefore -1 to 1, 0 being the exact center rather than - * the middle of min and max. - */ - rx = applyCalibration(x, js->min.x, js->max.x, js->center.x); - ry = applyCalibration(y, js->min.y, js->max.y, js->center.y); - - /* calculate the joystick angle and magnitude */ - ang = RAD_TO_DEGREE(atan2f(ry, rx)); - js->mag = sqrtf((rx * rx) + (ry * ry)); - js->ang = ang + 180.0f; -} - - -void apply_smoothing(struct accel_t* ac, struct orient_t* orient, int type) { - switch (type) { - case SMOOTH_ROLL: - { - /* it's possible last iteration was nan or inf, so set it to 0 if that happened */ - if (isnan(ac->st_roll) || isinf(ac->st_roll)) - ac->st_roll = 0.0f; - - /* - * If the sign changes (which will happen if going from -180 to 180) - * or from (-1 to 1) then don't smooth, just use the new angle. - */ - if (((ac->st_roll < 0) && (orient->roll > 0)) || ((ac->st_roll > 0) && (orient->roll < 0))) { - ac->st_roll = orient->roll; - } else { - orient->roll = ac->st_roll + (ac->st_alpha * (orient->a_roll - ac->st_roll)); - ac->st_roll = orient->roll; - } - - return; - } - - case SMOOTH_PITCH: - { - if (isnan(ac->st_pitch) || isinf(ac->st_pitch)) - ac->st_pitch = 0.0f; - - if (((ac->st_pitch < 0) && (orient->pitch > 0)) || ((ac->st_pitch > 0) && (orient->pitch < 0))) { - ac->st_pitch = orient->pitch; - } else { - orient->pitch = ac->st_pitch + (ac->st_alpha * (orient->a_pitch - ac->st_pitch)); - ac->st_pitch = orient->pitch; - } - - return; - } - } -} diff --git a/wii/wiiuse/dynamics.h b/wii/wiiuse/dynamics.h deleted file mode 100644 index 7d6f1ae642..0000000000 --- a/wii/wiiuse/dynamics.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * wiiuse - * - * Written By: - * Michael Laforest < para > - * Email: < thepara (--AT--) g m a i l [--DOT--] com > - * - * Copyright 2006-2007 - * - * This file is part of wiiuse. - * - * This program 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 Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 this program. If not, see . - * - * $Header: /lvm/shared/ds/ds/cvs/devkitpro-cvsbackup/libogc/wiiuse/dynamics.h,v 1.2 2008-11-14 13:34:57 shagkur Exp $ - * - */ - -/** - * @file - * @brief Handles the dynamics of the wiimote. - * - * The file includes functions that handle the dynamics - * of the wiimote. Such dynamics include orientation and - * motion sensing. - */ - -/* This source as presented is a modified version of original wiiuse for use - * with RetroArch, and must not be confused with the original software. */ - -#ifndef DYNAMICS_H_INCLUDED -#define DYNAMICS_H_INCLUDED - -#include "wiiuse_internal.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void calculate_orientation(struct accel_t* ac, struct vec3w_t* accel, struct orient_t* orient, int smooth); -void calculate_gforce(struct accel_t* ac, struct vec3w_t* accel, struct gforce_t* gforce); -void calc_joystick_state(struct joystick_t* js, float x, float y); -void apply_smoothing(struct accel_t* ac, struct orient_t* orient, int type); - -#ifdef __cplusplus -} -#endif - -#endif // DYNAMICS_H_INCLUDED diff --git a/wii/wiiuse/events.c b/wii/wiiuse/events.c deleted file mode 100644 index 4c435af2ee..0000000000 --- a/wii/wiiuse/events.c +++ /dev/null @@ -1,336 +0,0 @@ -/* This source as presented is a modified version of original wiiuse for use - * with RetroArch, and must not be confused with the original software. */ - -#include - -#ifndef WIN32 - #include - #include - #include -#else - #include -#endif - -#include -#include -#include -#include - -#include "dynamics.h" -#include "definitions.h" -#include "wiiuse_internal.h" -#include "events.h" -#include "nunchuk.h" -#include "classic.h" -#include "motion_plus.h" -#include "ir.h" -#include "io.h" - - -static void event_data_read(struct wiimote_t *wm,ubyte *msg) -{ - ubyte err; - ubyte len; - uword offset; - struct op_t *op; - struct cmd_blk_t *cmd = wm->cmd_head; - - wiiuse_pressed_buttons(wm,msg); - - if(!cmd) return; - if(!(cmd->state==CMD_SENT && cmd->data[0]==WM_CMD_READ_DATA)) return; - - //printf("event_data_read(%p)\n",cmd); - - err = msg[2]&0x0f; - op = (struct op_t*)cmd->data; - if(err) { - wm->cmd_head = cmd->next; - - cmd->state = CMD_DONE; - if(cmd->cb!=NULL) cmd->cb(wm,op->buffer,(op->readdata.size - op->wait)); - - __lwp_queue_append(&wm->cmdq,&cmd->node); - wiiuse_send_next_command(wm); - return; - } - - len = ((msg[2]&0xf0)>>4)+1; - offset = BIG_ENDIAN_SHORT(*(uword*)(msg+3)); - - //printf("addr: %08x\noffset: %d\nlen: %d\n",req->addr,offset,len); - - op->readdata.addr = (op->readdata.addr&0xffff); - op->wait -= len; - if(op->wait>=op->readdata.size) op->wait = 0; - - memcpy((op->buffer+offset-op->readdata.addr),(msg+5),len); - if(!op->wait) { - wm->cmd_head = cmd->next; - - wm->event = WIIUSE_READ_DATA; - cmd->state = CMD_DONE; - if(cmd->cb!=NULL) cmd->cb(wm,op->buffer,op->readdata.size); - - __lwp_queue_append(&wm->cmdq,&cmd->node); - wiiuse_send_next_command(wm); - } -} - -static void event_ack(struct wiimote_t *wm,ubyte *msg) -{ - struct cmd_blk_t *cmd = wm->cmd_head; - - wiiuse_pressed_buttons(wm,msg); - - if(!cmd || cmd->state!=CMD_SENT || cmd->data[0]==WM_CMD_READ_DATA || cmd->data[0]==WM_CMD_CTRL_STATUS || cmd->data[0]!=msg[2] || msg[3]) { - //WIIUSE_WARNING("Unsolicited event ack: report %02x status %02x", msg[2], msg[3]); - return; - } - - //WIIUSE_DEBUG("Received ack for command %02x %02x", cmd->data[0], cmd->data[1]); - - wm->cmd_head = cmd->next; - - wm->event = WIIUSE_ACK; - cmd->state = CMD_DONE; - if(cmd->cb) cmd->cb(wm,NULL,0); - - __lwp_queue_append(&wm->cmdq,&cmd->node); - wiiuse_send_next_command(wm); -} - -static void event_status(struct wiimote_t *wm,ubyte *msg) -{ - int ir = 0; - int attachment = 0; -#ifdef HAVE_WIIUSE_SPEAKER - int speaker = 0; -#endif - //int led[4]= {0}; - struct cmd_blk_t *cmd = wm->cmd_head; - - wiiuse_pressed_buttons(wm,msg); - - wm->event = WIIUSE_STATUS; - //if(msg[2]&WM_CTRL_STATUS_BYTE1_LED_1) led[0] = 1; - //if(msg[2]&WM_CTRL_STATUS_BYTE1_LED_2) led[1] = 1; - //if(msg[2]&WM_CTRL_STATUS_BYTE1_LED_3) led[2] = 1; - //if(msg[2]&WM_CTRL_STATUS_BYTE1_LED_4) led[3] = 1; - - if((msg[2]&WM_CTRL_STATUS_BYTE1_ATTACHMENT)==WM_CTRL_STATUS_BYTE1_ATTACHMENT) attachment = 1; -#ifdef HAVE_WIIUSE_SPEAKER - if((msg[2]&WM_CTRL_STATUS_BYTE1_SPEAKER_ENABLED)==WM_CTRL_STATUS_BYTE1_SPEAKER_ENABLED) speaker = 1; -#endif - if((msg[2]&WM_CTRL_STATUS_BYTE1_IR_ENABLED)==WM_CTRL_STATUS_BYTE1_IR_ENABLED) ir = 1; - - wm->battery_level = msg[5]; - - if(!ir && WIIMOTE_IS_SET(wm,WIIMOTE_STATE_IR_INIT)) { - WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR_INIT); - wiiuse_set_ir(wm, 1); - goto done; - } - if(ir && !WIIMOTE_IS_SET(wm,WIIMOTE_STATE_IR)) WIIMOTE_ENABLE_STATE(wm,WIIMOTE_STATE_IR); - else if(!ir && WIIMOTE_IS_SET(wm,WIIMOTE_STATE_IR)) WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR); - -#ifdef HAVE_WIIUSE_SPEAKER - if(!speaker && WIIMOTE_IS_SET(wm,WIIMOTE_STATE_SPEAKER_INIT)) { - WIIMOTE_DISABLE_STATE(wm,WIIMOTE_STATE_SPEAKER_INIT); - wiiuse_set_speaker(wm,1); - goto done; - } - if(speaker && !WIIMOTE_IS_SET(wm,WIIMOTE_STATE_SPEAKER)) WIIMOTE_ENABLE_STATE(wm,WIIMOTE_STATE_SPEAKER); - else if(!speaker && WIIMOTE_IS_SET(wm,WIIMOTE_STATE_SPEAKER)) WIIMOTE_DISABLE_STATE(wm,WIIMOTE_STATE_SPEAKER); -#endif - - if(attachment) { - if(!WIIMOTE_IS_SET(wm,WIIMOTE_STATE_EXP) && !WIIMOTE_IS_SET(wm,WIIMOTE_STATE_EXP_FAILED) && !WIIMOTE_IS_SET(wm,WIIMOTE_STATE_EXP_HANDSHAKE)) { - wiiuse_handshake_expansion_start(wm); - goto done; - } - } else { - WIIMOTE_DISABLE_STATE(wm,WIIMOTE_STATE_EXP_FAILED); - if(WIIMOTE_IS_SET(wm,WIIMOTE_STATE_EXP)) { - wiiuse_disable_expansion(wm); - goto done; - } - } - wiiuse_set_report_type(wm,NULL); - -done: - if(!cmd) return; - if(!(cmd->state==CMD_SENT && cmd->data[0]==WM_CMD_CTRL_STATUS)) return; - - wm->cmd_head = cmd->next; - - cmd->state = CMD_DONE; - if(cmd->cb!=NULL) cmd->cb(wm,msg,6); - - __lwp_queue_append(&wm->cmdq,&cmd->node); - wiiuse_send_next_command(wm); -} - -static void handle_expansion(struct wiimote_t *wm,ubyte *msg) -{ - switch (wm->exp.type) { - case EXP_NUNCHUK: - nunchuk_event(&wm->exp.nunchuk, msg); - break; - case EXP_CLASSIC: - classic_ctrl_event(&wm->exp.classic, msg); - break; - case EXP_MOTION_PLUS: - motion_plus_event(&wm->exp.mp, msg); - break; - default: - break; - } -} - -/** - * @brief Called on a cycle where no significant change occurs. - * - * @param wm Pointer to a wiimote_t structure. - */ -void idle_cycle(struct wiimote_t* wm) -{ - /* - * Smooth the angles. - * - * This is done to make sure that on every cycle the orientation - * angles are smoothed. Normally when an event occurs the angles - * are updated and smoothed, but if no packet comes in then the - * angles remain the same. This means the angle wiiuse reports - * is still an old value. Smoothing needs to be applied in this - * case in order for the angle it reports to converge to the true - * angle of the device. - */ - //printf("idle_cycle()\n");/// - if (WIIUSE_USING_ACC(wm) && WIIMOTE_IS_FLAG_SET(wm, WIIUSE_SMOOTHING)) { - apply_smoothing(&wm->accel_calib, &wm->orient, SMOOTH_ROLL); - apply_smoothing(&wm->accel_calib, &wm->orient, SMOOTH_PITCH); - } -} - -void parse_event(struct wiimote_t *wm) -{ - ubyte event; - ubyte *msg; - - event = wm->event_buf[0]; - msg = wm->event_buf+1; - //printf("parse_event(%02x,%p)\n",event,msg); - switch(event) { - case WM_RPT_CTRL_STATUS: - event_status(wm,msg); - return; - case WM_RPT_READ: - event_data_read(wm,msg); - return; - case WM_RPT_ACK: - event_ack(wm,msg); - return; - case WM_RPT_BTN: - wiiuse_pressed_buttons(wm,msg); - break; - case WM_RPT_BTN_ACC: - wiiuse_pressed_buttons(wm,msg); - - wm->accel.x = (msg[2]<<2)|((msg[0]>>5)&3); - wm->accel.y = (msg[3]<<2)|((msg[1]>>4)&2); - wm->accel.z = (msg[4]<<2)|((msg[1]>>5)&2); -#ifndef GEKKO - /* calculate the remote orientation */ - calculate_orientation(&wm->accel_calib, &wm->accel, &wm->orient, WIIMOTE_IS_FLAG_SET(wm, WIIUSE_SMOOTHING)); - - /* calculate the gforces on each axis */ - calculate_gforce(&wm->accel_calib, &wm->accel, &wm->gforce); -#endif - break; - case WM_RPT_BTN_ACC_IR: - wiiuse_pressed_buttons(wm,msg); - - wm->accel.x = (msg[2]<<2)|((msg[0]>>5)&3); - wm->accel.y = (msg[3]<<2)|((msg[1]>>4)&2); - wm->accel.z = (msg[4]<<2)|((msg[1]>>5)&2); -#ifndef GEKKO - /* calculate the remote orientation */ - calculate_orientation(&wm->accel_calib, &wm->accel, &wm->orient, WIIMOTE_IS_FLAG_SET(wm, WIIUSE_SMOOTHING)); - - /* calculate the gforces on each axis */ - calculate_gforce(&wm->accel_calib, &wm->accel, &wm->gforce); -#endif - calculate_extended_ir(wm, msg+5); - break; - case WM_RPT_BTN_EXP: - wiiuse_pressed_buttons(wm,msg); - handle_expansion(wm,msg+2); - break; - case WM_RPT_BTN_ACC_EXP: - /* button - motion - expansion */ - wiiuse_pressed_buttons(wm, msg); - - wm->accel.x = (msg[2]<<2)|((msg[0]>>5)&3); - wm->accel.y = (msg[3]<<2)|((msg[1]>>4)&2); - wm->accel.z = (msg[4]<<2)|((msg[1]>>5)&2); -#ifndef GEKKO - calculate_orientation(&wm->accel_calib, &wm->accel, &wm->orient, WIIMOTE_IS_FLAG_SET(wm, WIIUSE_SMOOTHING)); - calculate_gforce(&wm->accel_calib, &wm->accel, &wm->gforce); -#endif - handle_expansion(wm, msg+5); - break; - case WM_RPT_BTN_IR_EXP: - wiiuse_pressed_buttons(wm,msg); - calculate_basic_ir(wm, msg+2); - handle_expansion(wm,msg+12); - break; - case WM_RPT_BTN_ACC_IR_EXP: - /* button - motion - ir - expansion */ - wiiuse_pressed_buttons(wm, msg); - - wm->accel.x = (msg[2]<<2)|((msg[0]>>5)&3); - wm->accel.y = (msg[3]<<2)|((msg[1]>>4)&2); - wm->accel.z = (msg[4]<<2)|((msg[1]>>5)&2); -#ifndef GEKKO - calculate_orientation(&wm->accel_calib, &wm->accel, &wm->orient, WIIMOTE_IS_FLAG_SET(wm, WIIUSE_SMOOTHING)); - calculate_gforce(&wm->accel_calib, &wm->accel, &wm->gforce); -#endif - /* ir */ - calculate_basic_ir(wm, msg+5); - - handle_expansion(wm, msg+15); - break; - default: - WIIUSE_WARNING("Unknown event, can not handle it [Code 0x%x].", event); - return; - } - - /* was there an event? */ - wm->event = WIIUSE_EVENT; -} - -/** - * @brief Find what buttons are pressed. - * - * @param wm Pointer to a wiimote_t structure. - * @param msg The message specified in the event packet. - */ -void wiiuse_pressed_buttons(struct wiimote_t* wm, ubyte* msg) { - short now; - - /* convert to big endian */ - now = BIG_ENDIAN_SHORT(*(short*)msg) & WIIMOTE_BUTTON_ALL; - - /* preserve old btns pressed */ - wm->btns_last = wm->btns; - - /* pressed now & were pressed, then held */ - wm->btns_held = (now & wm->btns); - - /* were pressed or were held & not pressed now, then released */ - wm->btns_released = ((wm->btns | wm->btns_held) & ~now); - - /* buttons pressed now */ - wm->btns = now; -} diff --git a/wii/wiiuse/events.h b/wii/wiiuse/events.h deleted file mode 100644 index a7de3380bd..0000000000 --- a/wii/wiiuse/events.h +++ /dev/null @@ -1,17 +0,0 @@ -/* This source as presented is a modified version of original wiiuse for use - * with RetroArch, and must not be confused with the original software. */ - -#ifndef __EVENTS_H__ -#define __EVENTS_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -void wiiuse_pressed_buttons(struct wiimote_t* wm, ubyte* msg); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/wii/wiiuse/io.c b/wii/wiiuse/io.c deleted file mode 100644 index f5bd1a7e9f..0000000000 --- a/wii/wiiuse/io.c +++ /dev/null @@ -1,152 +0,0 @@ -/* This source as presented is a modified version of original wiiuse for use - * with RetroArch, and must not be confused with the original software. */ - -#include -#include - -#include "definitions.h" -#include "wiiuse_internal.h" -#include "nunchuk.h" -#include "classic.h" -#include "motion_plus.h" -#include "io.h" - -void wiiuse_handshake(struct wiimote_t *wm,ubyte *data,uword len) -{ - ubyte *buf = NULL; - struct accel_t *accel = &wm->accel_calib; - - //printf("wiiuse_handshake(%d,%p,%d)\n",wm->handshake_state,data,len); - - switch(wm->handshake_state) { - case 0: - wm->handshake_state++; - - wiiuse_set_leds(wm,WIIMOTE_LED_NONE,NULL); - - buf = __lwp_heap_allocate(&__wkspace_heap, sizeof(ubyte) * 8); - wiiuse_read_data(wm,buf,WM_MEM_OFFSET_CALIBRATION,7,wiiuse_handshake); - break; - case 1: - wm->handshake_state++; - - accel->cal_zero.x = ((data[0]<<2)|((data[3]>>4)&3)); - accel->cal_zero.y = ((data[1]<<2)|((data[3]>>2)&3)); - accel->cal_zero.z = ((data[2]<<2)|(data[3]&3)); - - accel->cal_g.x = (((data[4]<<2)|((data[7]>>4)&3)) - accel->cal_zero.x); - accel->cal_g.y = (((data[5]<<2)|((data[7]>>2)&3)) - accel->cal_zero.y); - accel->cal_g.z = (((data[6]<<2)|(data[7]&3)) - accel->cal_zero.z); - __lwp_heap_free(&__wkspace_heap, data); - - WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE); - WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE_COMPLETE); - - wm->event = WIIUSE_CONNECT; - wiiuse_status(wm,NULL); - break; - default: - break; - - } -} - -void wiiuse_handshake_expansion_start(struct wiimote_t *wm) -{ - if(WIIMOTE_IS_SET(wm,WIIMOTE_STATE_EXP) || WIIMOTE_IS_SET(wm,WIIMOTE_STATE_EXP_FAILED) || WIIMOTE_IS_SET(wm,WIIMOTE_STATE_EXP_HANDSHAKE)) - return; - - wm->expansion_state = 0; - WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_EXP_HANDSHAKE); - wiiuse_handshake_expansion(wm, NULL, 0); -} - -void wiiuse_handshake_expansion(struct wiimote_t *wm,ubyte *data,uword len) -{ - int id; - ubyte val; - ubyte *buf = NULL; - - switch(wm->expansion_state) { - /* These two initialization writes disable the encryption */ - case 0: - wm->expansion_state = 1; - val = 0x55; - wiiuse_write_data(wm,WM_EXP_MEM_ENABLE1,&val,1,wiiuse_handshake_expansion); - break; - case 1: - wm->expansion_state = 2; - val = 0x00; - wiiuse_write_data(wm,WM_EXP_MEM_ENABLE2,&val,1,wiiuse_handshake_expansion); - break; - case 2: - wm->expansion_state = 3; - buf = __lwp_heap_allocate(&__wkspace_heap, sizeof(ubyte) * EXP_HANDSHAKE_LEN); - wiiuse_read_data(wm,buf,WM_EXP_MEM_CALIBR,EXP_HANDSHAKE_LEN,wiiuse_handshake_expansion); - break; - case 3: - if(!data || !len) return; - id = BIG_ENDIAN_LONG(*(int*)(&data[220])); - - switch(id) { - case EXP_ID_CODE_NUNCHUK: - if(!nunchuk_handshake(wm,&wm->exp.nunchuk,data,len)) return; - break; - case EXP_ID_CODE_CLASSIC_CONTROLLER: - case EXP_ID_CODE_CLASSIC_CONTROLLER_NYKOWING: - case EXP_ID_CODE_CLASSIC_CONTROLLER_NYKOWING2: - case EXP_ID_CODE_CLASSIC_CONTROLLER_NYKOWING3: - case EXP_ID_CODE_CLASSIC_CONTROLLER_GENERIC: - case EXP_ID_CODE_CLASSIC_CONTROLLER_GENERIC2: - case EXP_ID_CODE_CLASSIC_CONTROLLER_GENERIC3: - case EXP_ID_CODE_CLASSIC_CONTROLLER_GENERIC4: - case EXP_ID_CODE_CLASSIC_CONTROLLER_GENERIC5: - if(!classic_ctrl_handshake(wm,&wm->exp.classic,data,len)) return; - break; - default: - if(!classic_ctrl_handshake(wm,&wm->exp.classic,data,len)) return; - /*WIIMOTE_DISABLE_STATE(wm,WIIMOTE_STATE_EXP_HANDSHAKE); - WIIMOTE_ENABLE_STATE(wm,WIIMOTE_STATE_EXP_FAILED); - _lwp_heap_free(&__wkspace_heap, data); - wiiuse_status(wm,NULL); - return;*/ - } - __lwp_heap_free(&__wkspace_heap, data); - - WIIMOTE_DISABLE_STATE(wm,WIIMOTE_STATE_EXP_HANDSHAKE); - WIIMOTE_ENABLE_STATE(wm,WIIMOTE_STATE_EXP); - wiiuse_set_ir_mode(wm); - wiiuse_status(wm,NULL); - break; - } -} - -void wiiuse_disable_expansion(struct wiimote_t *wm) -{ - if(!WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP)) return; - - /* tell the associated module the expansion was removed */ - switch(wm->exp.type) { - case EXP_NUNCHUK: - nunchuk_disconnected(&wm->exp.nunchuk); - wm->event = WIIUSE_NUNCHUK_REMOVED; - break; - case EXP_CLASSIC: - classic_ctrl_disconnected(&wm->exp.classic); - wm->event = WIIUSE_CLASSIC_CTRL_REMOVED; - break; - case EXP_MOTION_PLUS: - motion_plus_disconnected(&wm->exp.mp); - wm->event = WIIUSE_MOTION_PLUS_REMOVED; - break; - - default: - break; - } - - WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP); - wm->exp.type = EXP_NONE; - - wiiuse_set_ir_mode(wm); - wiiuse_status(wm,NULL); -} diff --git a/wii/wiiuse/io.h b/wii/wiiuse/io.h deleted file mode 100644 index 738ceea137..0000000000 --- a/wii/wiiuse/io.h +++ /dev/null @@ -1,26 +0,0 @@ -/* This source as presented is a modified version of original wiiuse for use - * with RetroArch, and must not be confused with the original software. */ - -#ifndef __IO_H__ -#define __IO_H__ - -#include "wiiuse_internal.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void wiiuse_handshake(struct wiimote_t* wm,ubyte *data,uword len); -void wiiuse_handshake_expansion_start(struct wiimote_t *wm); -void wiiuse_handshake_expansion(struct wiimote_t *wm,ubyte *data,uword len); -void wiiuse_disable_expansion(struct wiimote_t *wm); - -int wiiuse_io_read(struct wiimote_t* wm); -int wiiuse_io_write(struct wiimote_t* wm, ubyte* buf, int len); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/wii/wiiuse/io_wii.c b/wii/wiiuse/io_wii.c deleted file mode 100644 index 63e4b7b56a..0000000000 --- a/wii/wiiuse/io_wii.c +++ /dev/null @@ -1,181 +0,0 @@ -/* This source as presented is a modified version of original wiiuse for use - * with RetroArch, and must not be confused with the original software. */ - -#ifdef GEKKO - -#include -#include -#include -#include - -#include "definitions.h" -#include "wiiuse_internal.h" -#include "events.h" -#include "io.h" -#include "lwp_wkspace.h" - -#define MAX_COMMANDS 0x100 -#define MAX_WIIMOTES 5 - -static vu32* const _ipcReg = (u32*)0xCD000000; -static u8 *__queue_buffer[MAX_WIIMOTES] = { 0, 0, 0, 0, 0 }; - -extern void parse_event(struct wiimote_t *wm); -extern void idle_cycle(struct wiimote_t* wm); -extern void hexdump(void *d, int len); - -static __inline__ u32 ACR_ReadReg(u32 reg) -{ - return _ipcReg[reg>>2]; -} - -static __inline__ void ACR_WriteReg(u32 reg,u32 val) -{ - _ipcReg[reg>>2] = val; -} - -static s32 __wiiuse_disconnected(void *arg,struct bte_pcb *pcb,u8 err) -{ - struct wiimote_listen_t *wml = (struct wiimote_listen_t*)arg; - struct wiimote_t *wm = wml->wm; - - if(!wm) return ERR_OK; - - //printf("wiimote disconnected\n"); - WIIMOTE_DISABLE_STATE(wm, (WIIMOTE_STATE_IR|WIIMOTE_STATE_IR_INIT)); -#ifdef HAVE_WIIUSE_SPEAKER - WIIMOTE_DISABLE_STATE(wm, (WIIMOTE_STATE_SPEAKER|WIIMOTE_STATE_SPEAKER_INIT)); -#endif - WIIMOTE_DISABLE_STATE(wm, (WIIMOTE_STATE_EXP|WIIMOTE_STATE_EXP_HANDSHAKE|WIIMOTE_STATE_EXP_FAILED)); - WIIMOTE_DISABLE_STATE(wm,(WIIMOTE_STATE_CONNECTED|WIIMOTE_STATE_HANDSHAKE|WIIMOTE_STATE_HANDSHAKE_COMPLETE)); - - while(wm->cmd_head) { - __lwp_queue_append(&wm->cmdq,&wm->cmd_head->node); - wm->cmd_head = wm->cmd_head->next; - } - wm->cmd_tail = NULL; - - if(wm->event_cb) wm->event_cb(wm,WIIUSE_DISCONNECT); - - wml->wm = NULL; - return ERR_OK; -} - -static s32 __wiiuse_receive(void *arg,void *buffer,u16 len) -{ - struct wiimote_listen_t *wml = (struct wiimote_listen_t*)arg; - struct wiimote_t *wm = wml->wm; - - if(!wm || !buffer || len==0) return ERR_OK; - - //printf("__wiiuse_receive[%02x]\n",*(char*)buffer); - wm->event = WIIUSE_NONE; - - memcpy(wm->event_buf,buffer,len); - memset(&(wm->event_buf[len]),0,(MAX_PAYLOAD - len)); - parse_event(wm); - - if(wm->event!=WIIUSE_NONE) { - if(wm->event_cb) wm->event_cb(wm,wm->event); - } - - return ERR_OK; -} - -static s32 __wiiuse_connected(void *arg,struct bte_pcb *pcb,u8 err) -{ - struct wiimote_listen_t *wml = (struct wiimote_listen_t*)arg; - struct wiimote_t *wm; - - wm = wml->assign_cb(&wml->bdaddr); - - if(!wm) { - bte_disconnect(wml->sock); - return ERR_OK; - } - - wml->wm = wm; - - wm->sock = wml->sock; - wm->bdaddr = wml->bdaddr; - - //printf("__wiiuse_connected()\n"); - WIIMOTE_ENABLE_STATE(wm,(WIIMOTE_STATE_CONNECTED|WIIMOTE_STATE_HANDSHAKE)); - - wm->handshake_state = 0; - wiiuse_handshake(wm,NULL,0); - - return ERR_OK; -} - -void __wiiuse_sensorbar_enable(int enable) -{ - u32 val; - u32 level; - - level = IRQ_Disable(); - val = (ACR_ReadReg(0xc0)&~0x100); - if(enable) val |= 0x100; - ACR_WriteReg(0xc0,val); - IRQ_Restore(level); -} - -int wiiuse_register(struct wiimote_listen_t *wml, struct bd_addr *bdaddr, struct wiimote_t *(*assign_cb)(struct bd_addr *bdaddr)) -{ - s32 err; - - if(!wml || !bdaddr || !assign_cb) return 0; - - wml->wm = NULL; - wml->bdaddr = *bdaddr; - wml->sock = bte_new(); - wml->assign_cb = assign_cb; - if(wml->sock==NULL) return 0; - - bte_arg(wml->sock,wml); - bte_received(wml->sock,__wiiuse_receive); - bte_disconnected(wml->sock,__wiiuse_disconnected); - - err = bte_registerdeviceasync(wml->sock,bdaddr,__wiiuse_connected); - if(err==ERR_OK) return 1; - - return 0; -} - -void wiiuse_disconnect(struct wiimote_t *wm) -{ - if(wm==NULL || wm->sock==NULL) return; - - WIIMOTE_DISABLE_STATE(wm,WIIMOTE_STATE_CONNECTED); - bte_disconnect(wm->sock); -} - -void wiiuse_sensorbar_enable(int enable) -{ - __wiiuse_sensorbar_enable(enable); -} - - -void wiiuse_init_cmd_queue(struct wiimote_t *wm) -{ - u32 size; - - if (!__queue_buffer[wm->unid]) { - size = (MAX_COMMANDS*sizeof(struct cmd_blk_t)); - __queue_buffer[wm->unid] = __lwp_heap_allocate(&__wkspace_heap,size); - if(!__queue_buffer[wm->unid]) return; - } - - __lwp_queue_initialize(&wm->cmdq,__queue_buffer[wm->unid],MAX_COMMANDS,sizeof(struct cmd_blk_t)); -} - -int wiiuse_io_write(struct wiimote_t *wm,ubyte *buf,int len) -{ - if(wm->sock) { - return bte_senddata(wm->sock,buf,len); - } - - return ERR_CONN; -} - -#endif diff --git a/wii/wiiuse/ir.c b/wii/wiiuse/ir.c deleted file mode 100644 index f118ea6e58..0000000000 --- a/wii/wiiuse/ir.c +++ /dev/null @@ -1,837 +0,0 @@ -/* This source as presented is a modified version of original wiiuse for use - * with RetroArch, and must not be confused with the original software. */ - -#include -#include -#include - -#ifndef WIN32 - #include -#endif -#ifdef GEKKO - #include -#endif -#include "definitions.h" -#include "wiiuse_internal.h" -#include "ir.h" - -static int ir_correct_for_bounds(float* x, float* y, enum aspect_t aspect, int offset_x, int offset_y); -static void ir_convert_to_vres(float* x, float* y, enum aspect_t aspect, unsigned int vx, unsigned int vy); - -/** - * @brief Get the IR sensitivity settings. - * - * @param wm Pointer to a wiimote_t structure. - * @param block1 [out] Pointer to where block1 will be set. - * @param block2 [out] Pointer to where block2 will be set. - * - * @return Returns the sensitivity level. - */ -static int get_ir_sens(struct wiimote_t* wm, char** block1, char** block2) { - if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR_SENS_LVL1)) { - *block1 = WM_IR_BLOCK1_LEVEL1; - *block2 = WM_IR_BLOCK2_LEVEL1; - return 1; - } else if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR_SENS_LVL2)) { - *block1 = WM_IR_BLOCK1_LEVEL2; - *block2 = WM_IR_BLOCK2_LEVEL2; - return 2; - } else if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR_SENS_LVL3)) { - *block1 = WM_IR_BLOCK1_LEVEL3; - *block2 = WM_IR_BLOCK2_LEVEL3; - return 3; - } else if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR_SENS_LVL4)) { - *block1 = WM_IR_BLOCK1_LEVEL4; - *block2 = WM_IR_BLOCK2_LEVEL4; - return 4; - } else if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR_SENS_LVL5)) { - *block1 = WM_IR_BLOCK1_LEVEL5; - *block2 = WM_IR_BLOCK2_LEVEL5; - return 5; - } - - *block1 = NULL; - *block2 = NULL; - return 0; -} - -static void rotate_dots(struct fdot_t* in, struct fdot_t *out, int count, float ang) { - float s, c; - int i; - - if (ang == 0) { - for (i = 0; i < count; ++i) { - out[i].x = in[i].x; - out[i].y = in[i].y; - } - return; - } - - s = sin(DEGREE_TO_RAD(ang)); - c = cos(DEGREE_TO_RAD(ang)); - - /* - * [ cos(theta) -sin(theta) ][ ir->rx ] - * [ sin(theta) cos(theta) ][ ir->ry ] - */ - - for (i = 0; i < count; ++i) { - out[i].x = (c * in[i].x) + (-s * in[i].y); - out[i].y = (s * in[i].x) + (c * in[i].y); - } -} - -/** - * @brief Correct for the IR bounding box. - * - * @param x [out] The current X, it will be updated if valid. - * @param y [out] The current Y, it will be updated if valid. - * @param aspect Aspect ratio of the screen. - * @param offset_x The X offset of the bounding box. - * @param offset_y The Y offset of the bounding box. - * - * @return Returns 1 if the point is valid and was updated. - * - * Nintendo was smart with this bit. They sacrifice a little - * precision for a big increase in usability. - */ -static int ir_correct_for_bounds(float* x, float* y, enum aspect_t aspect, int offset_x, int offset_y) { - float x0, y0; - int xs, ys; - - if (aspect == WIIUSE_ASPECT_16_9) { - xs = WM_ASPECT_16_9_X; - ys = WM_ASPECT_16_9_Y; - } else { - xs = WM_ASPECT_4_3_X; - ys = WM_ASPECT_4_3_Y; - } - - x0 = ((1024 - xs) / 2) + offset_x; - y0 = ((768 - ys) / 2) + offset_y; - - if ((*x >= x0) - && (*x <= (x0 + xs)) - && (*y >= y0) - && (*y <= (y0 + ys))) - { - *x -= offset_x; - *y -= offset_y; - - return 1; - } - - return 0; -} - - -/** - * @brief Interpolate the point to the user defined virtual screen resolution. - */ -static void ir_convert_to_vres(float* x, float* y, enum aspect_t aspect, unsigned int vx, unsigned int vy) { - int xs, ys; - - if (aspect == WIIUSE_ASPECT_16_9) { - xs = WM_ASPECT_16_9_X; - ys = WM_ASPECT_16_9_Y; - } else { - xs = WM_ASPECT_4_3_X; - ys = WM_ASPECT_4_3_Y; - } - - *x -= ((1024-xs)/2); - *y -= ((768-ys)/2); - - *x = (*x / (float)xs) * vx; - *y = (*y / (float)ys) * vy; -} - -void wiiuse_set_ir_mode(struct wiimote_t *wm) -{ - ubyte buf = 0x00; - - if(!wm) return; - if(!WIIMOTE_IS_SET(wm,WIIMOTE_STATE_IR)) return; - - if(WIIMOTE_IS_SET(wm,WIIMOTE_STATE_EXP)) buf = WM_IR_TYPE_BASIC; - else buf = WM_IR_TYPE_EXTENDED; - wiiuse_write_data(wm,WM_REG_IR_MODENUM, &buf, 1, NULL); -} - -void wiiuse_set_ir(struct wiimote_t *wm,int status) -{ - ubyte buf = 0x00; - int ir_level = 0; - char* block1 = NULL; - char* block2 = NULL; - - if(!wm) return; - - /* - * Wait for the handshake to finish first. - * When it handshake finishes and sees that - * IR is enabled, it will call this function - * again to actually enable IR. - */ - if(!WIIMOTE_IS_SET(wm,WIIMOTE_STATE_HANDSHAKE_COMPLETE)) { - WIIUSE_DEBUG("Tried to enable IR, will wait until handshake finishes.\n"); - if(status) - WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_INIT); - else - WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR_INIT); - return; - } - - /* - * Check to make sure a sensitivity setting is selected. - */ - ir_level = get_ir_sens(wm, &block1, &block2); - if (!ir_level) { - WIIUSE_ERROR("No IR sensitivity setting selected."); - return; - } - - if (status) { - /* if already enabled then stop */ - if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR)) { - wiiuse_status(wm,NULL); - return; - } - } else { - /* if already disabled then stop */ - if (!WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR)) { - wiiuse_status(wm,NULL); - return; - } - } - - buf = (status ? 0x04 : 0x00); - wiiuse_sendcmd(wm,WM_CMD_IR,&buf,1,NULL); - wiiuse_sendcmd(wm,WM_CMD_IR_2,&buf,1,NULL); - - if (!status) { - WIIUSE_DEBUG("Disabled IR cameras for wiimote id %i.", wm->unid); - wiiuse_status(wm,NULL); - return; - } - - /* enable IR, set sensitivity */ - buf = 0x08; - wiiuse_write_data(wm,WM_REG_IR,&buf,1,NULL); - - wiiuse_write_data(wm, WM_REG_IR_BLOCK1, (ubyte*)block1, 9, NULL); - wiiuse_write_data(wm, WM_REG_IR_BLOCK2, (ubyte*)block2, 2, NULL); - - if(WIIMOTE_IS_SET(wm,WIIMOTE_STATE_EXP)) buf = WM_IR_TYPE_BASIC; - else buf = WM_IR_TYPE_EXTENDED; - wiiuse_write_data(wm,WM_REG_IR_MODENUM, &buf, 1, NULL); - - wiiuse_status(wm,NULL); - return; -} - -/** - * @brief Set the virtual screen resolution for IR tracking. - * - * @param wm Pointer to a wiimote_t structure. - * @param status 1 to enable, 0 to disable. - */ -void wiiuse_set_ir_vres(struct wiimote_t* wm, unsigned int x, unsigned int y) { - if (!wm) return; - - wm->ir.vres[0] = (x-1); - wm->ir.vres[1] = (y-1); -} - -/** - * @brief Set the XY position for the IR cursor. - * - * @param wm Pointer to a wiimote_t structure. - */ -void wiiuse_set_ir_position(struct wiimote_t* wm, enum ir_position_t pos) { - if (!wm) return; - - wm->ir.pos = pos; - - switch (pos) { - - case WIIUSE_IR_ABOVE: - wm->ir.offset[0] = 0; - - if (wm->ir.aspect == WIIUSE_ASPECT_16_9) - wm->ir.offset[1] = WM_ASPECT_16_9_Y/2 - 70; - else if (wm->ir.aspect == WIIUSE_ASPECT_4_3) - wm->ir.offset[1] = WM_ASPECT_4_3_Y/2 - 100; - - return; - - case WIIUSE_IR_BELOW: - wm->ir.offset[0] = 0; - - if (wm->ir.aspect == WIIUSE_ASPECT_16_9) - wm->ir.offset[1] = -WM_ASPECT_16_9_Y/2 + 70; - else if (wm->ir.aspect == WIIUSE_ASPECT_4_3) - wm->ir.offset[1] = -WM_ASPECT_4_3_Y/2 + 100; - - return; - - default: - return; - }; -} - -/** - * @brief Set the aspect ratio of the TV/monitor. - * - * @param wm Pointer to a wiimote_t structure. - * @param aspect Either WIIUSE_ASPECT_16_9 or WIIUSE_ASPECT_4_3 - */ -void wiiuse_set_aspect_ratio(struct wiimote_t* wm, enum aspect_t aspect) { - if (!wm) return; - - wm->ir.aspect = aspect; - - if (aspect == WIIUSE_ASPECT_4_3) { - wm->ir.vres[0] = WM_ASPECT_4_3_X; - wm->ir.vres[1] = WM_ASPECT_4_3_Y; - } else { - wm->ir.vres[0] = WM_ASPECT_16_9_X; - wm->ir.vres[1] = WM_ASPECT_16_9_Y; - } - - /* reset the position offsets */ - wiiuse_set_ir_position(wm, wm->ir.pos); -} - - -/** - * @brief Set the IR sensitivity. - * - * @param wm Pointer to a wiimote_t structure. - * @param level 1-5, same as Wii system sensitivity setting. - * - * If the level is < 1, then level will be set to 1. - * If the level is > 5, then level will be set to 5. - */ -void wiiuse_set_ir_sensitivity(struct wiimote_t* wm, int level) { - char* block1 = NULL; - char* block2 = NULL; - - if (!wm) return; - - if (level > 5) level = 5; - if (level < 1) level = 1; - - WIIMOTE_DISABLE_STATE(wm, (WIIMOTE_STATE_IR_SENS_LVL1 | - WIIMOTE_STATE_IR_SENS_LVL2 | - WIIMOTE_STATE_IR_SENS_LVL3 | - WIIMOTE_STATE_IR_SENS_LVL4 | - WIIMOTE_STATE_IR_SENS_LVL5)); - - switch (level) { - case 1: - WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL1); - break; - case 2: - WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL2); - break; - case 3: - WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL3); - break; - case 4: - WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL4); - break; - case 5: - WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL5); - break; - default: - return; - } - - if(!WIIMOTE_IS_SET(wm,WIIMOTE_STATE_IR)) return; - - /* set the new sensitivity */ - get_ir_sens(wm, &block1, &block2); - - wiiuse_write_data(wm, WM_REG_IR_BLOCK1, (ubyte*)block1, 9,NULL); - wiiuse_write_data(wm, WM_REG_IR_BLOCK2, (ubyte*)block2, 2,NULL); - - WIIUSE_DEBUG("Set IR sensitivity to level %i (unid %i)", level, wm->unid); -} - - -/** - * @brief Calculate the data from the IR spots. Basic IR mode. - * - * @param wm Pointer to a wiimote_t structure. - * @param data Data returned by the wiimote for the IR spots. - */ -void calculate_basic_ir(struct wiimote_t* wm, ubyte* data) { - struct ir_dot_t* dot = wm->ir.dot; - int i; - - dot[0].rx = 1023 - (data[0] | ((data[2] & 0x30) << 4)); - dot[0].ry = data[1] | ((data[2] & 0xC0) << 2); - - dot[1].rx = 1023 - (data[3] | ((data[2] & 0x03) << 8)); - dot[1].ry = data[4] | ((data[2] & 0x0C) << 6); - - dot[2].rx = 1023 - (data[5] | ((data[7] & 0x30) << 4)); - dot[2].ry = data[6] | ((data[7] & 0xC0) << 2); - - dot[3].rx = 1023 - (data[8] | ((data[7] & 0x03) << 8)); - dot[3].ry = data[9] | ((data[7] & 0x0C) << 6); - - /* set each IR spot to visible if spot is in range */ - for (i = 0; i < 4; ++i) { - dot[i].rx = BIG_ENDIAN_SHORT(dot[i].rx); - dot[i].ry = BIG_ENDIAN_SHORT(dot[i].ry); - - if (dot[i].ry == 1023) - dot[i].visible = 0; - else { - dot[i].visible = 1; - dot[i].size = 0; /* since we don't know the size, set it as 0 */ - } - } -#ifndef GEKKO - interpret_ir_data(&wm->ir,&wm->orient,WIIMOTE_IS_SET(wm, WIIMOTE_STATE_ACC)); -#endif -} - -/** - * @brief Calculate the data from the IR spots. Extended IR mode. - * - * @param wm Pointer to a wiimote_t structure. - * @param data Data returned by the wiimote for the IR spots. - */ -void calculate_extended_ir(struct wiimote_t* wm, ubyte* data) { - struct ir_dot_t* dot = wm->ir.dot; - int i; - - for (i = 0; i < 4; ++i) { - dot[i].rx = 1023 - (data[3*i] | ((data[(3*i)+2] & 0x30) << 4)); - dot[i].ry = data[(3*i)+1] | ((data[(3*i)+2] & 0xC0) << 2); - - dot[i].size = data[(3*i)+2]; - - dot[i].rx = BIG_ENDIAN_SHORT(dot[i].rx); - dot[i].ry = BIG_ENDIAN_SHORT(dot[i].ry); - - dot[i].size = dot[i].size&0x0f; - - /* if in range set to visible */ - if (dot[i].ry == 1023) - dot[i].visible = 0; - else - dot[i].visible = 1; - } -#ifndef GEKKO - interpret_ir_data(&wm->ir,&wm->orient,WIIMOTE_IS_SET(wm, WIIMOTE_STATE_ACC)); -#endif -} - -enum { - IR_STATE_DEAD = 0, - IR_STATE_GOOD, - IR_STATE_SINGLE, - IR_STATE_LOST, -}; - -// half-height of the IR sensor if half-width is 1 -#define HEIGHT (384.0f / 512.0f) -// maximum sensor bar slope (tan(35 degrees)) -#define MAX_SB_SLOPE 0.7f -// minimum sensor bar width in view, relative to half of the IR sensor area -#define MIN_SB_WIDTH 0.1f -// reject "sensor bars" that happen to have a dot towards the middle -#define SB_MIDDOT_REJECT 0.05f - -// physical dimensions -// cm center to center of emitters -#define SB_WIDTH 19.5f -// half-width in cm of emitters -#define SB_DOT_WIDTH 2.25f -// half-height in cm of emitters (with some tolerance) -#define SB_DOT_HEIGHT 1.0f - -#define SB_DOT_WIDTH_RATIO (SB_DOT_WIDTH / SB_WIDTH) -#define SB_DOT_HEIGHT_RATIO (SB_DOT_HEIGHT / SB_WIDTH) - -// dots further out than these coords are allowed to not be picked up -// otherwise assume something's wrong -//#define SB_OFF_SCREEN_X 0.8f -//#define SB_OFF_SCREEN_Y (0.8f * HEIGHT) - -// disable, may be doing more harm than good due to sensor pickup glitches -#define SB_OFF_SCREEN_X 0.0f -#define SB_OFF_SCREEN_Y 0.0f - -// if a point is closer than this to one of the previous SB points -// when it reappears, consider it the same instead of trying to guess -// which one of the two it is -#define SB_SINGLE_NOGUESS_DISTANCE (100.0 * 100.0) - -// width of the sensor bar in pixels at one meter from the Wiimote -#define SB_Z_COEFFICIENT 256.0f - -// distance in meters from the center of the FOV to the left or right edge, -// when the wiimote is at one meter -#define WIIMOTE_FOV_COEFFICIENT 0.39f - -#define SQUARED(x) ((x)*(x)) -#define WMAX(x,y) ((x>y)?(x):(y)) -#define WMIN(x,y) ((xroll); - - /* count visible dots and populate dots structure */ - /* dots[] is in -1..1 units for width */ - ir->num_dots = 0; - for (i = 0; i < 4; i++) { - if (ir->dot[i].visible) { - dots[ir->num_dots].x = (ir->dot[i].rx - 512.0f) / 512.0f; - dots[ir->num_dots].y = (ir->dot[i].ry - 384.0f) / 512.0f; - WIIUSE_DEBUG("IR: dot %d at (%d,%d) (%.03f,%.03f)\n",ir->num_dots,ir->dot[i].rx,ir->dot[i].ry,dots[ir->num_dots].x,dots[ir->num_dots].y); - ir->num_dots++; - } - } - - WIIUSE_DEBUG("IR: found %d dots\n",ir->num_dots); - - // nothing to track - if(ir->num_dots == 0) { - if(ir->state != IR_STATE_DEAD) - ir->state = IR_STATE_LOST; - ir->ax = 0; - ir->ay = 0; - ir->distance = 0.0f; - ir->raw_valid = 0; - return; - } - - /* ==== Find the Sensor Bar ==== */ - - // first rotate according to accelerometer orientation - rotate_dots(dots, acc_dots, ir->num_dots, orient->roll); - if(ir->num_dots > 1) { - WIIUSE_DEBUG("IR: locating sensor bar candidates\n"); - - // iterate through all dot pairs - for(first=0; first < (ir->num_dots-1); first++) { - for(second=(first+1); second < ir->num_dots; second++) { - WIIUSE_DEBUG("IR: trying dots %d and %d\n",first,second); - // order the dots leftmost first into cand - // storing both the raw dots and the accel-rotated dots - if(acc_dots[first].x > acc_dots[second].x) { - cand.dots[0] = dots[second]; - cand.dots[1] = dots[first]; - cand.acc_dots[0] = acc_dots[second]; - cand.acc_dots[1] = acc_dots[first]; - } else { - cand.dots[0] = dots[first]; - cand.dots[1] = dots[second]; - cand.acc_dots[0] = acc_dots[first]; - cand.acc_dots[1] = acc_dots[second]; - } - difference.x = cand.acc_dots[1].x - cand.acc_dots[0].x; - difference.y = cand.acc_dots[1].y - cand.acc_dots[0].y; - - // check angle - if(fabsf(difference.y / difference.x) > MAX_SB_SLOPE) - continue; - WIIUSE_DEBUG("IR: passed angle check\n"); - // rotate to the true sensor bar angle - cand.off_angle = -RAD_TO_DEGREE(atan2(difference.y, difference.x)); - cand.angle = cand.off_angle + orient->roll; - rotate_dots(cand.dots, cand.rot_dots, 2, cand.angle); - WIIUSE_DEBUG("IR: off_angle: %.02f, angle: %.02f\n", cand.off_angle, cand.angle); - // recalculate x distance - y should be zero now, so ignore it - difference.x = cand.rot_dots[1].x - cand.rot_dots[0].x; - - // check distance - if(difference.x < MIN_SB_WIDTH) - continue; - // middle dot check. If there's another source somewhere in the - // middle of this candidate, then this can't be a sensor bar - - for(i=0; inum_dots; i++) { - float wadj, hadj; - struct fdot_t tdot; - if(i==first || i==second) continue; - hadj = SB_DOT_HEIGHT_RATIO * difference.x; - wadj = SB_DOT_WIDTH_RATIO * difference.x; - rotate_dots(&dots[i], &tdot, 1, cand.angle); - if( ((cand.rot_dots[0].x + wadj) < tdot.x) && - ((cand.rot_dots[1].x - wadj) > tdot.x) && - ((cand.rot_dots[0].y + hadj) > tdot.y) && - ((cand.rot_dots[0].y - hadj) < tdot.y)) - break; - } - // failed middle dot check - if(i < ir->num_dots) continue; - WIIUSE_DEBUG("IR: passed middle dot check\n"); - - cand.score = 1 / (cand.rot_dots[1].x - cand.rot_dots[0].x); - - // we have a candidate, store it - WIIUSE_DEBUG("IR: new candidate %d\n",num_candidates); - candidates[num_candidates++] = cand; - } - } - } - - if(num_candidates == 0) { - int closest = -1; - int closest_to = 0; - float best = 999.0f; - float d; - float dx[2]; - struct sb_t sbx[2]; - // no sensor bar candidates, try to work with a lone dot - WIIUSE_DEBUG("IR: no candidates\n"); - switch(ir->state) { - case IR_STATE_DEAD: - WIIUSE_DEBUG("IR: we're dead\n"); - // we've never seen a sensor bar before, so we're screwed - ir->ax = 0.0f; - ir->ay = 0.0f; - ir->distance = 0.0f; - ir->raw_valid = 0; - return; - case IR_STATE_GOOD: - case IR_STATE_SINGLE: - case IR_STATE_LOST: - WIIUSE_DEBUG("IR: trying to keep track of single dot\n"); - // try to find the dot closest to the previous sensor bar position - for(i=0; inum_dots; i++) { - WIIUSE_DEBUG("IR: checking dot %d (%.02f, %.02f)\n",i, acc_dots[i].x,acc_dots[i].y); - for(j=0; j<2; j++) { - WIIUSE_DEBUG(" to dot %d (%.02f, %.02f)\n",j, ir->sensorbar.acc_dots[j].x,ir->sensorbar.acc_dots[j].y); - d = SQUARED(acc_dots[i].x - ir->sensorbar.acc_dots[j].x); - d += SQUARED(acc_dots[i].y - ir->sensorbar.acc_dots[j].y); - if(d < best) { - best = d; - closest_to = j; - closest = i; - } - } - } - WIIUSE_DEBUG("IR: closest dot is %d to %d\n",closest,closest_to); - if(ir->state != IR_STATE_LOST || best < SB_SINGLE_NOGUESS_DISTANCE) { - // now work out where the other dot would be, in the acc frame - sb.acc_dots[closest_to] = acc_dots[closest]; - sb.acc_dots[closest_to^1].x = ir->sensorbar.acc_dots[closest_to^1].x - ir->sensorbar.acc_dots[closest_to].x + acc_dots[closest].x; - sb.acc_dots[closest_to^1].y = ir->sensorbar.acc_dots[closest_to^1].y - ir->sensorbar.acc_dots[closest_to].y + acc_dots[closest].y; - // get the raw frame - rotate_dots(sb.acc_dots, sb.dots, 2, -orient->roll); - if((fabsf(sb.dots[closest_to^1].x) < SB_OFF_SCREEN_X) && (fabsf(sb.dots[closest_to^1].y) < SB_OFF_SCREEN_Y)) { - // this dot should be visible but isn't, since the candidate section failed. - // fall through and try to pick out the sensor bar without previous information - WIIUSE_DEBUG("IR: dot falls on screen, falling through\n"); - } else { - // calculate the rotated dots frame - // angle tends to drift, so recalculate - sb.off_angle = -RAD_TO_DEGREE(atan2(sb.acc_dots[1].y - sb.acc_dots[0].y, sb.acc_dots[1].x - sb.acc_dots[0].x)); - sb.angle = ir->sensorbar.off_angle + orient->roll; - rotate_dots(sb.acc_dots, sb.rot_dots, 2, ir->sensorbar.off_angle); - WIIUSE_DEBUG("IR: kept track of single dot\n"); - break; - } - } else { - WIIUSE_DEBUG("IR: lost the dot and new one is too far away\n"); - } - // try to find the dot closest to the sensor edge - WIIUSE_DEBUG("IR: trying to find best dot\n"); - for(i=0; inum_dots; i++) { - d = WMIN(1.0f - fabsf(dots[i].x), HEIGHT - fabsf(dots[i].y)); - if(d < best) { - best = d; - closest = i; - } - } - WIIUSE_DEBUG("IR: best dot: %d\n",closest); - // now try it as both places in the sensor bar - // and pick the one that places the other dot furthest off-screen - for(i=0; i<2; i++) { - sbx[i].acc_dots[i] = acc_dots[closest]; - sbx[i].acc_dots[i^1].x = ir->sensorbar.acc_dots[i^1].x - ir->sensorbar.acc_dots[i].x + acc_dots[closest].x; - sbx[i].acc_dots[i^1].y = ir->sensorbar.acc_dots[i^1].y - ir->sensorbar.acc_dots[i].y + acc_dots[closest].y; - rotate_dots(sbx[i].acc_dots, sbx[i].dots, 2, -orient->roll); - dx[i] = WMAX(fabsf(sbx[i].dots[i^1].x),fabsf(sbx[i].dots[i^1].y / HEIGHT)); - } - if(dx[0] > dx[1]) { - WIIUSE_DEBUG("IR: dot is LEFT: %.02f > %.02f\n",dx[0],dx[1]); - sb = sbx[0]; - } else { - WIIUSE_DEBUG("IR: dot is RIGHT: %.02f < %.02f\n",dx[0],dx[1]); - sb = sbx[1]; - } - // angle tends to drift, so recalculate - sb.off_angle = -RAD_TO_DEGREE(atan2(sb.acc_dots[1].y - sb.acc_dots[0].y, sb.acc_dots[1].x - sb.acc_dots[0].x)); - sb.angle = ir->sensorbar.off_angle + orient->roll; - rotate_dots(sb.acc_dots, sb.rot_dots, 2, ir->sensorbar.off_angle); - WIIUSE_DEBUG("IR: found new dot to track\n"); - break; - } - sb.score = 0; - ir->state = IR_STATE_SINGLE; - } else { - int bestidx = 0; - float best = 0.0f; - WIIUSE_DEBUG("IR: finding best candidate\n"); - // look for the best candidate - // for now, the formula is simple: pick the one with the smallest distance - for(i=0; i best) { - bestidx = i; - best = candidates[i].score; - } - } - WIIUSE_DEBUG("IR: best candidate: %d\n",bestidx); - sb = candidates[bestidx]; - ir->state = IR_STATE_GOOD; - } - - ir->raw_valid = 1; - ir->ax = ((sb.rot_dots[0].x + sb.rot_dots[1].x) / 2) * 512.0 + 512.0; - ir->ay = ((sb.rot_dots[0].y + sb.rot_dots[1].y) / 2) * 512.0 + 384.0; - ir->sensorbar = sb; - ir->distance = (sb.rot_dots[1].x - sb.rot_dots[0].x) * 512.0; - -} - -#define SMOOTH_IR_RADIUS 8.0f -#define SMOOTH_IR_SPEED 0.25f -#define SMOOTH_IR_DEADZONE 2.5f - -/** - * @brief Smooth the IR pointer position - * - * @param ir Pointer to an ir_t structure. - */ -void apply_ir_smoothing(struct ir_t *ir) { - f32 dx, dy, d, theta; - - WIIUSE_DEBUG("Smooth: OK (%.02f, %.02f) LAST (%.02f, %.02f) ", ir->ax, ir->ay, ir->sx, ir->sy); - dx = ir->ax - ir->sx; - dy = ir->ay - ir->sy; - d = sqrtf(dx*dx + dy*dy); - if (d > SMOOTH_IR_DEADZONE) { - if (d < SMOOTH_IR_RADIUS) { - WIIUSE_DEBUG("INSIDE\n"); - ir->sx += dx * SMOOTH_IR_SPEED; - ir->sy += dy * SMOOTH_IR_SPEED; - } else { - WIIUSE_DEBUG("OUTSIDE\n"); - theta = atan2f(dy, dx); - ir->sx = ir->ax - cosf(theta) * SMOOTH_IR_RADIUS; - ir->sy = ir->ay - sinf(theta) * SMOOTH_IR_RADIUS; - } - } else { - WIIUSE_DEBUG("DEADZONE\n"); - } -} - -// max number of errors before cooked data drops out -#define ERROR_MAX_COUNT 8 -// max number of glitches before cooked data updates -#define GLITCH_MAX_COUNT 5 -// squared delta over which we consider something a glitch -#define GLITCH_DIST (150.0f * 150.0f) - -/** - * @brief Interpret IR data into more user friendly variables. - * - * @param ir Pointer to an ir_t structure. - * @param orient Pointer to an orient_t structure. - */ -void interpret_ir_data(struct ir_t* ir, struct orient_t *orient) { - - float x,y; - float d; - - find_sensorbar(ir, orient); - - if(ir->raw_valid) { - ir->angle = ir->sensorbar.angle; - ir->z = SB_Z_COEFFICIENT / ir->distance; - orient->yaw = calc_yaw(ir); - if(ir->error_cnt >= ERROR_MAX_COUNT) { - ir->sx = ir->ax; - ir->sy = ir->ay; - ir->glitch_cnt = 0; - } else { - d = SQUARED(ir->ax - ir->sx) + SQUARED(ir->ay - ir->sy); - if(d > GLITCH_DIST) { - if(ir->glitch_cnt > GLITCH_MAX_COUNT) { - apply_ir_smoothing(ir); - ir->glitch_cnt = 0; - } else { - ir->glitch_cnt++; - } - } else { - ir->glitch_cnt = 0; - apply_ir_smoothing(ir); - } - } - ir->smooth_valid = 1; - ir->error_cnt = 0; - } else { - if(ir->error_cnt >= ERROR_MAX_COUNT) { - ir->smooth_valid = 0; - } else { - ir->smooth_valid = 1; - ir->error_cnt++; - } - } - if(ir->smooth_valid) { - x = ir->sx; - y = ir->sy; - if (ir_correct_for_bounds(&x, &y, ir->aspect, ir->offset[0], ir->offset[1])) { - ir_convert_to_vres(&x, &y, ir->aspect, ir->vres[0], ir->vres[1]); - ir->x = x; - ir->y = y; - ir->valid = 1; - } else { - ir->valid = 0; - } - } else { - ir->valid = 0; - } -} - -/** - * @brief Calculate yaw given the IR data. - * - * @param ir IR data structure. - */ -float calc_yaw(struct ir_t* ir) { - float x; - - x = ir->ax - 512; - x *= WIIMOTE_FOV_COEFFICIENT / 512.0; - - return RAD_TO_DEGREE( atanf(x) ); -} - diff --git a/wii/wiiuse/ir.h b/wii/wiiuse/ir.h deleted file mode 100644 index 0ac683b8d1..0000000000 --- a/wii/wiiuse/ir.h +++ /dev/null @@ -1,25 +0,0 @@ -/* This source as presented is a modified version of original wiiuse for use - * with RetroArch, and must not be confused with the original software. */ - -#ifndef __IR_H__ -#define __IR_H__ - -#include "wiiuse_internal.h" - -#define WII_VRES_X 560 -#define WII_VRES_Y 340 - -#ifdef __cplusplus -extern "C" { -#endif - -void calculate_basic_ir(struct wiimote_t* wm, ubyte* data); -void calculate_extended_ir(struct wiimote_t* wm, ubyte* data); -float calc_yaw(struct ir_t* ir); -void interpret_ir_data(struct ir_t* ir, struct orient_t *orient); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/wii/wiiuse/license_libogc.txt b/wii/wiiuse/license_libogc.txt deleted file mode 100644 index a149fce1ce..0000000000 --- a/wii/wiiuse/license_libogc.txt +++ /dev/null @@ -1,641 +0,0 @@ -This license is valid ONLY for libogc and what this license -defines as a "covered work" or a "combined work" with libogc. - - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an officialder -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - 18. Exceptions - - Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole combination. - - As a special exception, the copyright holders of this library give -you permission to link this library with independent modules to produce -an executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from or -based on this library. If you modify this library, you may extend this -exception to your version of the library, but you are not obligated to -do so. If you do not wish to do so, delete this exception statement from -your version. - diff --git a/wii/wiiuse/motion_plus.c b/wii/wiiuse/motion_plus.c deleted file mode 100644 index 8d37d7063f..0000000000 --- a/wii/wiiuse/motion_plus.c +++ /dev/null @@ -1,95 +0,0 @@ -/* This source as presented is a modified version of original wiiuse for use - * with RetroArch, and must not be confused with the original software. */ - -#include -#include -#include -#include - -#ifdef WIN32 - #include -#endif - -#include "definitions.h" -#include "wiiuse_internal.h" -#include "dynamics.h" -#include "events.h" -#include "io.h" - -void wiiuse_motion_plus_check(struct wiimote_t *wm,ubyte *data,uword len) -{ - u32 val; - if(data == NULL) - { - wiiuse_read_data(wm, wm->motion_plus_id, WM_EXP_ID, 6, wiiuse_motion_plus_check); - } - else - { - WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP); - WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP_FAILED); - WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP_HANDSHAKE); - val = (data[3] << 16) | (data[2] << 24) | (data[4] << 8) | data[5]; - if(val == EXP_ID_CODE_MOTION_PLUS) - { - /* handshake done */ - wm->event = WIIUSE_MOTION_PLUS_ACTIVATED; - wm->exp.type = EXP_MOTION_PLUS; - - WIIMOTE_ENABLE_STATE(wm,WIIMOTE_STATE_EXP); - wiiuse_set_ir_mode(wm); - } - } -} - -static void wiiuse_set_motion_plus_clear2(struct wiimote_t *wm,ubyte *data,uword len) -{ - WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP); - WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP_FAILED); - WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP_HANDSHAKE); - wiiuse_set_ir_mode(wm); - wiiuse_status(wm,NULL); -} - -static void wiiuse_set_motion_plus_clear1(struct wiimote_t *wm,ubyte *data,uword len) -{ - ubyte val = 0x00; - wiiuse_write_data(wm,WM_EXP_MEM_ENABLE1,&val,1,wiiuse_set_motion_plus_clear2); -} - - -void wiiuse_set_motion_plus(struct wiimote_t *wm, int status) -{ - ubyte val; - - if(WIIMOTE_IS_SET(wm,WIIMOTE_STATE_EXP_HANDSHAKE)) - return; - - WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_EXP_HANDSHAKE); - if(status) - { - val = 0x04; - wiiuse_write_data(wm,WM_EXP_MOTION_PLUS_ENABLE,&val,1,wiiuse_motion_plus_check); - } - else - { - wiiuse_disable_expansion(wm); - val = 0x55; - wiiuse_write_data(wm,WM_EXP_MEM_ENABLE1,&val,1,wiiuse_set_motion_plus_clear1); - } -} - -void motion_plus_disconnected(struct motion_plus_t* mp) -{ - WIIUSE_DEBUG("Motion plus disconnected"); - memset(mp, 0, sizeof(struct motion_plus_t)); -} - -void motion_plus_event(struct motion_plus_t* mp, ubyte* msg) -{ - mp->rx = ((msg[5] & 0xFC) << 6) | msg[2]; // Pitch - mp->ry = ((msg[4] & 0xFC) << 6) | msg[1]; // Roll - mp->rz = ((msg[3] & 0xFC) << 6) | msg[0]; // Yaw - - mp->ext = msg[4] & 0x1; - mp->status = (msg[3] & 0x3) | ((msg[4] & 0x2) << 1); // roll, yaw, pitch -} diff --git a/wii/wiiuse/motion_plus.h b/wii/wiiuse/motion_plus.h deleted file mode 100644 index 628d9c6492..0000000000 --- a/wii/wiiuse/motion_plus.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * @file - * @brief Motion plus extension - */ - -/* This source as presented is a modified version of original wiiuse for use - * with RetroArch, and must not be confused with the original software. */ - -#ifndef MOTION_PLUS_H_INCLUDED -#define MOTION_PLUS_H_INCLUDED - -#include "wiiuse_internal.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void motion_plus_disconnected(struct motion_plus_t* mp); - -void motion_plus_event(struct motion_plus_t* mp, ubyte* msg); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/wii/wiiuse/nunchuk.c b/wii/wiiuse/nunchuk.c deleted file mode 100644 index 468db73a31..0000000000 --- a/wii/wiiuse/nunchuk.c +++ /dev/null @@ -1,157 +0,0 @@ -/* This source as presented is a modified version of original wiiuse for use - * with RetroArch, and must not be confused with the original software. */ - -#include -#include -#include -#include - -#include "dynamics.h" -#include "definitions.h" -#include "wiiuse_internal.h" -#include "nunchuk.h" -#include "io.h" - -/** - * @brief Find what buttons are pressed. - * - * @param nc Pointer to a nunchuk_t structure. - * @param msg The message byte specified in the event packet. - */ -static void nunchuk_pressed_buttons(struct nunchuk_t* nc, ubyte now) { - /* message is inverted (0 is active, 1 is inactive) */ - now = ~now & NUNCHUK_BUTTON_ALL; - - /* preserve old btns pressed */ - nc->btns_last = nc->btns; - - /* pressed now & were pressed, then held */ - nc->btns_held = (now & nc->btns); - - /* were pressed or were held & not pressed now, then released */ - nc->btns_released = ((nc->btns | nc->btns_held) & ~now); - - /* buttons pressed now */ - nc->btns = now; -} - -int nunchuk_handshake(struct wiimote_t *wm,struct nunchuk_t *nc,ubyte *data,uword len) -{ - //int i; - int offset = 0; - - nc->btns = 0; - nc->btns_held = 0; - nc->btns_released = 0; - nc->flags = &wm->flags; - nc->accel_calib = wm->accel_calib; - - //for(i=0;iaccel_calib.cal_zero.x = (data[offset + 0]<<2)|((data[offset + 3]>>4)&3); - nc->accel_calib.cal_zero.y = (data[offset + 1]<<2)|((data[offset + 3]>>2)&3); - nc->accel_calib.cal_zero.z = (data[offset + 2]<<2)|(data[offset + 3]&3); - nc->accel_calib.cal_g.x = (data[offset + 4]<<2)|((data[offset + 7]>>4)&3); - nc->accel_calib.cal_g.y = (data[offset + 5]<<2)|((data[offset + 7]>>2)&3); - nc->accel_calib.cal_g.z = (data[offset + 6]<<2)|(data[offset + 7]&3); - nc->js.max.x = data[offset + 8]; - nc->js.min.x = data[offset + 9]; - nc->js.center.x = data[offset + 10]; - nc->js.max.y = data[offset + 11]; - nc->js.min.y = data[offset + 12]; - nc->js.center.y = data[offset + 13]; - - // set to defaults (averages from 5 nunchuks) if calibration data is invalid - if(nc->accel_calib.cal_zero.x == 0) - nc->accel_calib.cal_zero.x = 499; - if(nc->accel_calib.cal_zero.y == 0) - nc->accel_calib.cal_zero.y = 509; - if(nc->accel_calib.cal_zero.z == 0) - nc->accel_calib.cal_zero.z = 507; - if(nc->accel_calib.cal_g.x == 0) - nc->accel_calib.cal_g.x = 703; - if(nc->accel_calib.cal_g.y == 0) - nc->accel_calib.cal_g.y = 709; - if(nc->accel_calib.cal_g.z == 0) - nc->accel_calib.cal_g.z = 709; - if(nc->js.max.x == 0) - nc->js.max.x = 223; - if(nc->js.min.x == 0) - nc->js.min.x = 27; - if(nc->js.center.x == 0) - nc->js.center.x = 126; - if(nc->js.max.y == 0) - nc->js.max.y = 222; - if(nc->js.min.y == 0) - nc->js.min.y = 30; - if(nc->js.center.y == 0) - nc->js.center.y = 131; - - wm->event = WIIUSE_NUNCHUK_INSERTED; - wm->exp.type = EXP_NUNCHUK; - - return 1; -} - -/** - * @brief The nunchuk disconnected. - * - * @param nc A pointer to a nunchuk_t structure. - */ -void nunchuk_disconnected(struct nunchuk_t* nc) -{ - //printf("nunchuk_disconnected()\n"); - memset(nc, 0, sizeof(struct nunchuk_t)); -} - -/** - * @brief Handle nunchuk event. - * - * @param nc A pointer to a nunchuk_t structure. - * @param msg The message specified in the event packet. - */ -void nunchuk_event(struct nunchuk_t* nc, ubyte* msg) { - //int i; - - /* decrypt data */ - /* - for (i = 0; i < 6; ++i) - msg[i] = (msg[i] ^ 0x17) + 0x17; - */ - /* get button states */ - nunchuk_pressed_buttons(nc, msg[5]); - - nc->js.pos.x = msg[0]; - nc->js.pos.y = msg[1]; - - /* extend min and max values to physical range of motion */ - if (nc->js.center.x) { - if (nc->js.min.x > nc->js.pos.x) nc->js.min.x = nc->js.pos.x; - if (nc->js.max.x < nc->js.pos.x) nc->js.max.x = nc->js.pos.x; - } - if (nc->js.center.y) { - if (nc->js.min.y > nc->js.pos.y) nc->js.min.y = nc->js.pos.y; - if (nc->js.max.y < nc->js.pos.y) nc->js.max.y = nc->js.pos.y; - } - -#ifndef GEKKO - /* calculate joystick state */ - calc_joystick_state(&nc->js, nc->js.pos.x, nc->js.pos.y); -#endif - /* calculate orientation */ - nc->accel.x = (msg[2]<<2) + ((msg[5]>>2)&3); - nc->accel.y = (msg[3]<<2) + ((msg[5]>>4)&3); - nc->accel.z = (msg[4]<<2) + ((msg[5]>>6)&3); -#ifndef GEKKO - calculate_orientation(&nc->accel_calib, &nc->accel, &nc->orient, NUNCHUK_IS_FLAG_SET(nc, WIIUSE_SMOOTHING)); - calculate_gforce(&nc->accel_calib, &nc->accel, &nc->gforce); -#endif -} - diff --git a/wii/wiiuse/nunchuk.h b/wii/wiiuse/nunchuk.h deleted file mode 100644 index 7545aa7b6e..0000000000 --- a/wii/wiiuse/nunchuk.h +++ /dev/null @@ -1,21 +0,0 @@ -/* This source as presented is a modified version of original wiiuse for use - * with RetroArch, and must not be confused with the original software. */ - -#ifndef __NUNCHUK_H__ -#define __NUNCHUK_H__ - -#include "wiiuse_internal.h" - -#ifdef __cplusplus -extern "C" { -#endif - -int nunchuk_handshake(struct wiimote_t* wm, struct nunchuk_t* nc, ubyte* data, uword len); -void nunchuk_disconnected(struct nunchuk_t* nc); -void nunchuk_event(struct nunchuk_t* nc, ubyte* msg); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/wii/wiiuse/os.h b/wii/wiiuse/os.h deleted file mode 100644 index 16571047cd..0000000000 --- a/wii/wiiuse/os.h +++ /dev/null @@ -1,31 +0,0 @@ -/* This source as presented is a modified version of original wiiuse for use - * with RetroArch, and must not be confused with the original software. */ - -#ifndef __OS_H__ -#define __OS_H__ - -#ifdef WIN32 - /* windows */ - #define isnan(x) _isnan(x) - #define isinf(x) !_finite(x) - - /* disable warnings I don't care about */ - #pragma warning(disable:4244) /* possible loss of data conversion */ - #pragma warning(disable:4273) /* inconsistent dll linkage */ - #pragma warning(disable:4217) -#else - /* nix/gekko */ - #ifdef GEKKO - #include - #include - #include - #include "network.h" - #include - #include - #include - #include - #else - #endif -#endif - -#endif diff --git a/wii/wiiuse/speaker.c b/wii/wiiuse/speaker.c deleted file mode 100644 index 43ca994275..0000000000 --- a/wii/wiiuse/speaker.c +++ /dev/null @@ -1,145 +0,0 @@ -/* This source as presented is a modified version of original wiiuse for use - * with RetroArch, and must not be confused with the original software. */ - -#include -#include -#include -#include - -#ifndef WIN32 -#include -#endif -#ifdef GEKKO -#include -#endif -#include "definitions.h" -#include "wiiuse_internal.h" -#include "speaker.h" - -#define WENCMIN(a,b) ((a)>(b)?(b):(a)) -#define ABS(x) ((s32)(x)>0?(s32)(x):-((s32)(x))) - -static const int yamaha_indexscale[] = { - 230, 230, 230, 230, 307, 409, 512, 614, - 230, 230, 230, 230, 307, 409, 512, 614 -}; - -static const int yamaha_difflookup[] = { - 1, 3, 5, 7, 9, 11, 13, 15, - -1, -3, -5, -7, -9, -11, -13, -15 -}; - -static ubyte __wiiuse_speaker_vol = 0x40; -static ubyte __wiiuse_speaker_defconf[7] = { 0x00,0x00,0xD0,0x07,0x40,0x0C,0x0E }; - -static __inline__ short wenc_clip_short(int a) -{ - if((a+32768)&~65535) return (a>>31)^32767; - else return a; -} - -static __inline__ int wenc_clip(int a,int amin,int amax) -{ - if(aamax) return amax; - else return a; -} - -ubyte wencdata(WENCStatus *info,short sample) -{ - int nibble,delta; - - if(!info->step) { - info->predictor = 0; - info->step = 127; - } - - delta = sample - info->predictor; - nibble = WENCMIN(7,(ABS(delta)*4)/info->step) + ((delta<0)*8); - - info->predictor += ((info->step*yamaha_difflookup[nibble])/8); - info->predictor = wenc_clip_short(info->predictor); - info->step = (info->step*yamaha_indexscale[nibble])>>8; - info->step = wenc_clip(info->step,127,24576); - - return nibble; -} - -void wiiuse_set_speaker(struct wiimote_t *wm,int status) -{ - ubyte conf[7]; - ubyte buf = 0x00; - - if(!wm) return; - - if(!WIIMOTE_IS_SET(wm,WIIMOTE_STATE_HANDSHAKE_COMPLETE)) { - WIIUSE_DEBUG("Tried to enable speaker, will wait until handshake finishes.\n"); - if(status) - WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_SPEAKER_INIT); - else - WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_SPEAKER_INIT); - return; - } - - if(status) { - if(WIIMOTE_IS_SET(wm,WIIMOTE_STATE_SPEAKER)) { - wiiuse_status(wm,NULL); - return; - } - } else { - if(!WIIMOTE_IS_SET(wm,WIIMOTE_STATE_SPEAKER)) { - wiiuse_status(wm,NULL); - return; - } - } - - - buf = 0x04; - wiiuse_sendcmd(wm,WM_CMD_SPEAKER_MUTE,&buf,1,NULL); - - if (!status) { - WIIUSE_DEBUG("Disabled speaker for wiimote id %i.", wm->unid); - - buf = 0x01; - wiiuse_write_data(wm,WM_REG_SPEAKER_REG1,&buf,1,NULL); - - buf = 0x00; - wiiuse_write_data(wm,WM_REG_SPEAKER_REG3,&buf,1,NULL); - - buf = 0x00; - wiiuse_sendcmd(wm,WM_CMD_SPEAKER_ENABLE,&buf,1,NULL); - - wiiuse_status(wm,NULL); - return; - } - - memcpy(conf,__wiiuse_speaker_defconf,7); - - buf = 0x04; - wiiuse_sendcmd(wm,WM_CMD_SPEAKER_ENABLE,&buf,1,NULL); - - buf = 0x01; - wiiuse_write_data(wm,WM_REG_SPEAKER_REG3,&buf,1,NULL); - - buf = 0x08; - wiiuse_write_data(wm,WM_REG_SPEAKER_REG1,&buf,1,NULL); - - conf[2] = 0xd0; - conf[3] = 0x07; - conf[4] = __wiiuse_speaker_vol; - wiiuse_write_data(wm,WM_REG_SPEAKER_BLOCK,conf,7,NULL); - - buf = 0x01; - wiiuse_write_data(wm,WM_REG_SPEAKER_REG2,&buf,1,NULL); - - buf = 0x00; - wiiuse_sendcmd(wm,WM_CMD_SPEAKER_MUTE,&buf,1,NULL); - - wiiuse_status(wm,NULL); - return; -} - -void set_speakervol(struct wiimote_t *wm,ubyte vol) -{ - __wiiuse_speaker_vol = vol; -} diff --git a/wii/wiiuse/speaker.h b/wii/wiiuse/speaker.h deleted file mode 100644 index b7b9229126..0000000000 --- a/wii/wiiuse/speaker.h +++ /dev/null @@ -1,33 +0,0 @@ -/* This source as presented is a modified version of original wiiuse for use - * with RetroArch, and must not be confused with the original software. */ - -#ifndef __SPEAKER_H__ -#define __SPEAKER_H__ - -#include "wiiuse_internal.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct _wencstatus -{ - s32 predictor; - s16 step_index; - s32 step; - s32 prev_sample; - s16 sample1; - s16 sample2; - s32 coeff1; - s32 coeff2; - s32 idelta; -} WENCStatus; - -u8 wencdata(WENCStatus *info,s16 sample); -void set_speakervol(struct wiimote_t *wm,ubyte vol); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/wii/wiiuse/wiiuse.c b/wii/wiiuse/wiiuse.c deleted file mode 100644 index 73e813063a..0000000000 --- a/wii/wiiuse/wiiuse.c +++ /dev/null @@ -1,337 +0,0 @@ -/* This source as presented is a modified version of original wiiuse for use - * with RetroArch, and must not be confused with the original software. */ - -#include -#include -#include - -#ifndef WIN32 - #include -#else - #include -#endif - -#include "definitions.h" -#include "wiiuse_internal.h" -#include "io.h" - -static struct wiimote_t** __wm = NULL; - -void wiiuse_send_next_command(struct wiimote_t *wm) -{ - struct cmd_blk_t *cmd = wm->cmd_head; - - if(!wm || !WIIMOTE_IS_CONNECTED(wm)) return; - - if(!cmd) return; - if(cmd->state!=CMD_READY) return; - - cmd->state = CMD_SENT; -#ifdef HAVE_WIIUSE_RUMBLE - if(WIIMOTE_IS_SET(wm,WIIMOTE_STATE_RUMBLE)) cmd->data[1] |= 0x01; -#endif - - //WIIUSE_DEBUG("Sending command: %02x %02x", cmd->data[0], cmd->data[1]); - wiiuse_io_write(wm,cmd->data,cmd->len); -} - -static inline void __wiiuse_push_command(struct wiimote_t *wm,struct cmd_blk_t *cmd) -{ - uint level; - - if(!wm || !cmd) return; - - cmd->next = NULL; - cmd->state = CMD_READY; - - _CPU_ISR_Disable(level); - if(wm->cmd_head==NULL) { - wm->cmd_head = wm->cmd_tail = cmd; - wiiuse_send_next_command(wm); - } else { - wm->cmd_tail->next = cmd; - wm->cmd_tail = cmd; - } - _CPU_ISR_Restore(level); -} - -#ifndef GEKKO -struct wiimote_t** wiiuse_init(int wiimotes) { -#else -extern void __wiiuse_sensorbar_enable(int enable); -struct wiimote_t** wiiuse_init(int wiimotes, wii_event_cb event_cb) { -#endif - int i = 0; - - if (!wiimotes) - return NULL; - - if (!__wm) { - __wm = __lwp_heap_allocate(&__wkspace_heap, sizeof(struct wiimote_t*) * wiimotes); - if(!__wm) return NULL; - memset(__wm, 0, sizeof(struct wiimote_t*) * wiimotes); - } - - for (i = 0; i < wiimotes; ++i) { - if(!__wm[i]) - __wm[i] = __lwp_heap_allocate(&__wkspace_heap, sizeof(struct wiimote_t)); - - memset(__wm[i], 0, sizeof(struct wiimote_t)); - __wm[i]->unid = i; - - #if defined(WIN32) - __wm[i]->dev_handle = 0; - __wm[i]->stack = WIIUSE_STACK_UNKNOWN; - __wm[i]->normal_timeout = WIIMOTE_DEFAULT_TIMEOUT; - __wm[i]->exp_timeout = WIIMOTE_EXP_TIMEOUT; - __wm[i]->timeout = __wm[i]->normal_timeout; - #elif defined(GEKKO) - __wm[i]->sock = NULL; - __wm[i]->bdaddr = *BD_ADDR_ANY; - __wm[i]->event_cb = event_cb; - wiiuse_init_cmd_queue(__wm[i]); - #elif defined(unix) - __wm[i]->bdaddr = *BDADDR_ANY; - __wm[i]->out_sock = -1; - __wm[i]->in_sock = -1; - #endif - - __wm[i]->state = WIIMOTE_INIT_STATES; - __wm[i]->flags = WIIUSE_INIT_FLAGS; - - __wm[i]->event = WIIUSE_NONE; - - __wm[i]->exp.type = EXP_NONE; - - wiiuse_set_aspect_ratio(__wm[i], WIIUSE_ASPECT_4_3); - wiiuse_set_ir_position(__wm[i], WIIUSE_IR_ABOVE); - - __wm[i]->accel_calib.st_alpha = WIIUSE_DEFAULT_SMOOTH_ALPHA; - } - - return __wm; -} - -/** - * @brief Set flags for the specified wiimote. - * - * @param wm Pointer to a wiimote_t structure. - * @param enable Flags to enable. - * @param disable Flags to disable. - * - * @return The flags set after 'enable' and 'disable' have been applied. - * - * The values 'enable' and 'disable' may be any flags OR'ed together. - * Flags are defined in wiiuse.h. - */ -int wiiuse_set_flags(struct wiimote_t* wm, int enable, int disable) { - if (!wm) return 0; - - /* remove mutually exclusive flags */ - enable &= ~disable; - disable &= ~enable; - - wm->flags |= enable; - wm->flags &= ~disable; - - return wm->flags; -} - -/** - * @brief Set if the wiimote should report motion sensing. - * - * @param wm Pointer to a wiimote_t structure. - * @param status 1 to enable, 0 to disable. - * - * Since reporting motion sensing sends a lot of data, - * the wiimote saves power by not transmitting it - * by default. - */ -void wiiuse_motion_sensing(struct wiimote_t* wm, int status) -{ - if (status) { - if(WIIMOTE_IS_SET(wm,WIIMOTE_STATE_ACC)) return; - WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_ACC); - } else { - if(!WIIMOTE_IS_SET(wm,WIIMOTE_STATE_ACC)) return; - WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_ACC); - } - - if(!WIIMOTE_IS_SET(wm,WIIMOTE_STATE_HANDSHAKE_COMPLETE)) return; - - wiiuse_status(wm,NULL); -} - -/** - * @brief Toggle the state of the rumble. - * - * @param wm Pointer to a wiimote_t structure. - */ -#ifdef HAVE_WIIUSE_RUMBLE -void wiiuse_toggle_rumble(struct wiimote_t* wm) -{ - if (!wm) return; - - WIIMOTE_TOGGLE_STATE(wm, WIIMOTE_STATE_RUMBLE); - if(!WIIMOTE_IS_SET(wm,WIIMOTE_STATE_HANDSHAKE_COMPLETE)) return; - - wiiuse_set_leds(wm,wm->leds,NULL); -} - -/** - * @brief Enable or disable the rumble. - * - * @param wm Pointer to a wiimote_t structure. - * @param status 1 to enable, 0 to disable. - */ -void wiiuse_rumble(struct wiimote_t* wm, int status) -{ - if (status && WIIMOTE_IS_SET(wm,WIIMOTE_STATE_RUMBLE)) return; - else if(!status && !WIIMOTE_IS_SET(wm,WIIMOTE_STATE_RUMBLE)) return; - wiiuse_toggle_rumble(wm); -} -#endif - -void wiiuse_set_leds(struct wiimote_t *wm,int leds,cmd_blk_cb cb) -{ - ubyte buf; - - if(!wm || !WIIMOTE_IS_CONNECTED(wm)) return; - - wm->leds = (leds&0xf0); - - buf = wm->leds; - wiiuse_sendcmd(wm,WM_CMD_LED,&buf,1,cb); -} - -int wiiuse_set_report_type(struct wiimote_t *wm,cmd_blk_cb cb) -{ - ubyte buf[2]; - int motion,ir,exp; - - if(!wm || !WIIMOTE_IS_CONNECTED(wm)) return 0; - - buf[0] = (WIIMOTE_IS_FLAG_SET(wm, WIIUSE_CONTINUOUS) ? 0x04 : 0x00); /* set to 0x04 for continuous reporting */ - buf[1] = 0x00; - - motion = WIIMOTE_IS_SET(wm, WIIMOTE_STATE_ACC) || WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR); - exp = WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP); - ir = WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR); - - if (motion && ir && exp) buf[1] = WM_RPT_BTN_ACC_IR_EXP; - else if (motion && exp) buf[1] = WM_RPT_BTN_ACC_EXP; - else if (motion && ir) buf[1] = WM_RPT_BTN_ACC_IR; - else if (ir && exp) buf[1] = WM_RPT_BTN_IR_EXP; - else if (ir) buf[1] = WM_RPT_BTN_ACC_IR; - else if (exp) buf[1] = WM_RPT_BTN_EXP; - else if (motion) buf[1] = WM_RPT_BTN_ACC; - else buf[1] = WM_RPT_BTN; - - //WIIUSE_DEBUG("Setting report type: 0x%x", buf[1]); - - wiiuse_sendcmd(wm,WM_CMD_REPORT_TYPE,buf,2,cb); - return buf[1]; -} - -void wiiuse_status(struct wiimote_t *wm,cmd_blk_cb cb) -{ - ubyte buf; - - if(!wm || !WIIMOTE_IS_CONNECTED(wm)) return; - - buf = 0x00; - wiiuse_sendcmd(wm,WM_CMD_CTRL_STATUS,&buf,1,cb); -} - -int wiiuse_read_data(struct wiimote_t *wm,ubyte *buffer,uint addr,uword len,cmd_blk_cb cb) -{ - struct op_t *op; - struct cmd_blk_t *cmd; - - if(!wm || !WIIMOTE_IS_CONNECTED(wm)) return 0; - if(!buffer || !len) return 0; - - cmd = (struct cmd_blk_t*)__lwp_queue_get(&wm->cmdq); - if(!cmd) return 0; - - cmd->cb = cb; - cmd->len = 7; - - op = (struct op_t*)cmd->data; - op->cmd = WM_CMD_READ_DATA; - op->buffer = buffer; - op->wait = len; - op->readdata.addr = BIG_ENDIAN_LONG(addr); - op->readdata.size = BIG_ENDIAN_SHORT(len); - __wiiuse_push_command(wm,cmd); - - return 1; -} - -int wiiuse_write_data(struct wiimote_t *wm,uint addr,ubyte *data,ubyte len,cmd_blk_cb cb) -{ - struct op_t *op; - struct cmd_blk_t *cmd; - - if(!wm || !WIIMOTE_IS_CONNECTED(wm)) return 0; - if(!data || !len) return 0; - - cmd = (struct cmd_blk_t*)__lwp_queue_get(&wm->cmdq); - if(!cmd) return 0; - - cmd->cb = cb; - cmd->len = 22; - - op = (struct op_t*)cmd->data; - op->cmd = WM_CMD_WRITE_DATA; - op->buffer = NULL; - op->wait = 0; - op->writedata.addr = BIG_ENDIAN_LONG(addr); - op->writedata.size = (len&0x0f); - memcpy(op->writedata.data,data,len); - memset(op->writedata.data+len,0,(16 - len)); - __wiiuse_push_command(wm,cmd); - - return 1; -} - -int wiiuse_write_streamdata(struct wiimote_t *wm,ubyte *data,ubyte len,cmd_blk_cb cb) -{ - struct cmd_blk_t *cmd; - - if(!wm || !WIIMOTE_IS_CONNECTED(wm)) return 0; - if(!data || !len || len>20) return 0; - - cmd = (struct cmd_blk_t*)__lwp_queue_get(&wm->cmdq); - if(!cmd) return 0; - - cmd->cb = cb; - cmd->len = 22; - cmd->data[0] = WM_CMD_STREAM_DATA; - cmd->data[1] = (len<<3); - memcpy(cmd->data+2,data,len); - __wiiuse_push_command(wm,cmd); - - return 1; -} - -int wiiuse_sendcmd(struct wiimote_t *wm,ubyte report_type,ubyte *msg,int len,cmd_blk_cb cb) -{ - struct cmd_blk_t *cmd; - - cmd = (struct cmd_blk_t*)__lwp_queue_get(&wm->cmdq); - if(!cmd) return 0; - - cmd->cb = cb; - cmd->len = (1+len); - - cmd->data[0] = report_type; - memcpy(cmd->data+1,msg,len); - if(report_type!=WM_CMD_READ_DATA && report_type!=WM_CMD_CTRL_STATUS) - cmd->data[1] |= 0x02; - - //WIIUSE_DEBUG("Pushing command: %02x %02x", cmd->data[0], cmd->data[1]); - __wiiuse_push_command(wm,cmd); - - return 1; -} diff --git a/wii/wiiuse/wiiuse_internal.h b/wii/wiiuse/wiiuse_internal.h deleted file mode 100644 index 6350bbbf28..0000000000 --- a/wii/wiiuse/wiiuse_internal.h +++ /dev/null @@ -1,278 +0,0 @@ -/* - * wiiuse - * - * Written By: - * Michael Laforest < para > - * Email: < thepara (--AT--) g m a i l [--DOT--] com > - * - * Copyright 2006-2007 - * - * This file is part of wiiuse. - * - * This program 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 Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 this program. If not, see . - * - * $Header: /lvm/shared/ds/ds/cvs/devkitpro-cvsbackup/libogc/wiiuse/wiiuse_internal.h,v 1.8 2008-12-10 16:16:40 shagkur Exp $ - * - */ - -/** - * @file - * @brief General internal wiiuse stuff. - * - * Since Wiiuse is a library, wiiuse.h is a duplicate - * of the API header. - * - * The code that would normally go in that file, but - * which is not needed by third party developers, - * is put here. - * - * So wiiuse_internal.h is included by other files - * internally, wiiuse.h is included only here. - */ - -/* This source as presented is a modified version of original wiiuse for use - * with RetroArch, and must not be confused with the original software. */ - -#ifndef WIIUSE_INTERNAL_H_INCLUDED -#define WIIUSE_INTERNAL_H_INCLUDED - -#if defined(__linux__) - #include /* htons() */ - #include -#endif - -#include "definitions.h" - -/* wiiuse version */ -#define WIIUSE_VERSION "0.12" - -/******************** - * - * Wiimote internal codes - * - ********************/ - -/* Communication channels */ -#define WM_OUTPUT_CHANNEL 0x11 -#define WM_INPUT_CHANNEL 0x13 - -#define WM_SET_REPORT 0x50 -#define WM_DATA 0xA0 - -/* commands */ -#define WM_CMD_RUMBLE 0x10 -#define WM_CMD_LED 0x11 -#define WM_CMD_REPORT_TYPE 0x12 -#define WM_CMD_IR 0x13 -#define WM_CMD_SPEAKER_ENABLE 0x14 -#define WM_CMD_CTRL_STATUS 0x15 -#define WM_CMD_WRITE_DATA 0x16 -#define WM_CMD_READ_DATA 0x17 -#define WM_CMD_STREAM_DATA 0x18 -#define WM_CMD_SPEAKER_MUTE 0x19 -#define WM_CMD_IR_2 0x1A - -/* input report ids */ -#define WM_RPT_CTRL_STATUS 0x20 -#define WM_RPT_READ 0x21 -#define WM_RPT_ACK 0x22 -#define WM_RPT_BTN 0x30 -#define WM_RPT_BTN_ACC 0x31 -#define WM_RPT_BTN_ACC_IR 0x33 -#define WM_RPT_BTN_EXP 0x34 -#define WM_RPT_BTN_ACC_EXP 0x35 -#define WM_RPT_BTN_IR_EXP 0x36 -#define WM_RPT_BTN_ACC_IR_EXP 0x37 - -#define WM_BT_INPUT 0x01 -#define WM_BT_OUTPUT 0x02 - -/* Identify the wiimote device by its class */ -#define WM_DEV_CLASS_0 0x04 -#define WM_DEV_CLASS_1 0x25 -#define WM_DEV_CLASS_2 0x00 -#define WM_VENDOR_ID 0x057E -#define WM_PRODUCT_ID 0x0306 - -/* controller status stuff */ -#define WM_MAX_BATTERY_CODE 0xC8 - -/* offsets in wiimote memory */ -#define WM_MEM_OFFSET_CALIBRATION 0x16 -#define WM_EXP_MEM_BASE 0x04A40000 -#define WM_EXP_MEM_ENABLE1 0x04A400F0 -#define WM_EXP_MEM_ENABLE2 0x04A400FB -#define WM_EXP_MEM_KEY 0x04A40040 -#define WM_EXP_MEM_CALIBR 0x04A40020 -#define WM_EXP_MOTION_PLUS_ENABLE 0x04A600FE -#define WM_EXP_ID 0x04A400FA - -#define WM_REG_IR 0x04B00030 -#define WM_REG_IR_BLOCK1 0x04B00000 -#define WM_REG_IR_BLOCK2 0x04B0001A -#define WM_REG_IR_MODENUM 0x04B00033 - -#define WM_REG_SPEAKER_REG1 0x04A20001 -#define WM_REG_SPEAKER_REG2 0x04A20008 -#define WM_REG_SPEAKER_REG3 0x04A20009 -#define WM_REG_SPEAKER_BLOCK 0x04A20001 - -/* ir block data */ -#define WM_IR_BLOCK1_LEVEL1 "\x02\x00\x00\x71\x01\x00\x64\x00\xfe" -#define WM_IR_BLOCK2_LEVEL1 "\xfd\x05" -#define WM_IR_BLOCK1_LEVEL2 "\x02\x00\x00\x71\x01\x00\x96\x00\xb4" -#define WM_IR_BLOCK2_LEVEL2 "\xb3\x04" -#define WM_IR_BLOCK1_LEVEL3 "\x02\x00\x00\x71\x01\x00\xaa\x00\x64" -#define WM_IR_BLOCK2_LEVEL3 "\x63\x03" -#define WM_IR_BLOCK1_LEVEL4 "\x02\x00\x00\x71\x01\x00\xc8\x00\x36" -#define WM_IR_BLOCK2_LEVEL4 "\x35\x03" -#define WM_IR_BLOCK1_LEVEL5 "\x07\x00\x00\x71\x01\x00\x72\x00\x20" -#define WM_IR_BLOCK2_LEVEL5 "\x1f\x03" - -#define WM_IR_TYPE_BASIC 0x01 -#define WM_IR_TYPE_EXTENDED 0x03 -#define WM_IR_TYPE_FULL 0x05 - -/* controller status flags for the first message byte */ -/* bit 1 is unknown */ -#define WM_CTRL_STATUS_BYTE1_ATTACHMENT 0x02 -#define WM_CTRL_STATUS_BYTE1_SPEAKER_ENABLED 0x04 -#define WM_CTRL_STATUS_BYTE1_IR_ENABLED 0x08 -#define WM_CTRL_STATUS_BYTE1_LED_1 0x10 -#define WM_CTRL_STATUS_BYTE1_LED_2 0x20 -#define WM_CTRL_STATUS_BYTE1_LED_3 0x40 -#define WM_CTRL_STATUS_BYTE1_LED_4 0x80 - -/* aspect ratio */ -#define WM_ASPECT_16_9_X 660 -#define WM_ASPECT_16_9_Y 370 -#define WM_ASPECT_4_3_X 560 -#define WM_ASPECT_4_3_Y 420 - - -/** - * Expansion stuff - */ - -/* encrypted expansion id codes (located at 0x04A400FC) */ -#define EXP_ID_CODE_NUNCHUK 0xa4200000 -#define EXP_ID_CODE_CLASSIC_CONTROLLER 0xa4200101 -#define EXP_ID_CODE_CLASSIC_CONTROLLER_NYKOWING 0x90908f00 -#define EXP_ID_CODE_CLASSIC_CONTROLLER_NYKOWING2 0x9e9f9c00 -#define EXP_ID_CODE_CLASSIC_CONTROLLER_NYKOWING3 0x908f8f00 -#define EXP_ID_CODE_CLASSIC_CONTROLLER_GENERIC 0xa5a2a300 -#define EXP_ID_CODE_CLASSIC_CONTROLLER_GENERIC2 0x98999900 -#define EXP_ID_CODE_CLASSIC_CONTROLLER_GENERIC3 0xa0a1a000 -#define EXP_ID_CODE_CLASSIC_CONTROLLER_GENERIC4 0x8d8d8e00 -#define EXP_ID_CODE_CLASSIC_CONTROLLER_GENERIC5 0x93949400 -//#define EXP_ID_CODE_GUITAR 0xa4200103 -//#define EXP_ID_CODE_WIIBOARD 0xa4200402 -#define EXP_ID_CODE_MOTION_PLUS 0xa4200405 - -#define EXP_HANDSHAKE_LEN 224 - -/******************** - * - * End Wiimote internal codes - * - ********************/ - -/* wiimote state flags - (some duplicated in wiiuse.h)*/ -#define WIIMOTE_STATE_DEV_FOUND 0x00001 -//#define WIIMOTE_STATE_DEV_REGISTER 0x00002 -#define WIIMOTE_STATE_HANDSHAKE 0x00004 /* actual connection exists but no handshake yet */ -#define WIIMOTE_STATE_HANDSHAKE_COMPLETE 0x00008 /* actual connection exists but no handshake yet */ -#define WIIMOTE_STATE_CONNECTED 0x00010 -#define WIIMOTE_STATE_EXP_HANDSHAKE 0x00020 /* actual connection exists but no handshake yet */ -#define WIIMOTE_STATE_EXP_FAILED 0x00040 /* actual connection exists but no handshake yet */ -#define WIIMOTE_STATE_RUMBLE 0x00080 -#define WIIMOTE_STATE_ACC 0x00100 -#define WIIMOTE_STATE_EXP 0x00200 -#define WIIMOTE_STATE_IR 0x00400 -#define WIIMOTE_STATE_SPEAKER 0x00800 -#define WIIMOTE_STATE_IR_SENS_LVL1 0x01000 -#define WIIMOTE_STATE_IR_SENS_LVL2 0x02000 -#define WIIMOTE_STATE_IR_SENS_LVL3 0x04000 -#define WIIMOTE_STATE_IR_SENS_LVL4 0x08000 -#define WIIMOTE_STATE_IR_SENS_LVL5 0x10000 -#define WIIMOTE_STATE_IR_INIT 0x20000 -#define WIIMOTE_STATE_SPEAKER_INIT 0x40000 - -#define WIIMOTE_INIT_STATES (WIIMOTE_STATE_IR_SENS_LVL3) - -/* macro to manage states */ -#define WIIMOTE_IS_SET(wm, s) ((wm->state & (s)) == (s)) -#define WIIMOTE_ENABLE_STATE(wm, s) (wm->state |= (s)) -#define WIIMOTE_DISABLE_STATE(wm, s) (wm->state &= ~(s)) -#define WIIMOTE_TOGGLE_STATE(wm, s) ((wm->state & (s)) ? WIIMOTE_DISABLE_STATE(wm, s) : WIIMOTE_ENABLE_STATE(wm, s)) - -#define WIIMOTE_IS_FLAG_SET(wm, s) ((wm->flags & (s)) == (s)) -#define WIIMOTE_ENABLE_FLAG(wm, s) (wm->flags |= (s)) -#define WIIMOTE_DISABLE_FLAG(wm, s) (wm->flags &= ~(s)) -#define WIIMOTE_TOGGLE_FLAG(wm, s) ((wm->flags & (s)) ? WIIMOTE_DISABLE_FLAG(wm, s) : WIIMOTE_ENABLE_FLAG(wm, s)) - -#define NUNCHUK_IS_FLAG_SET(wm, s) ((*(wm->flags) & (s)) == (s)) - -/* misc macros */ -#define WIIMOTE_ID(wm) (wm->unid) -#define WIIMOTE_IS_CONNECTED(wm) (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_CONNECTED)) - -/* - * Smooth tilt calculations are computed with the - * exponential moving average formula: - * St = St_last + (alpha * (tilt - St_last)) - * alpha is between 0 and 1 - */ -#define WIIUSE_DEFAULT_SMOOTH_ALPHA 0.3f - -#define SMOOTH_ROLL 0x01 -#define SMOOTH_PITCH 0x02 - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct op_t -{ - ubyte cmd; - union { - struct { - uint addr; - uword size; - } readdata; - struct { - uint addr; - ubyte size; - ubyte data[16]; - } writedata; - ubyte __data[MAX_PAYLOAD]; - }; - - void *buffer; - int wait; -} __attribute__((packed)); - -/* not part of the api */ -void wiiuse_init_cmd_queue(struct wiimote_t *wm); -void wiiuse_send_next_command(struct wiimote_t *wm); -int wiiuse_set_report_type(struct wiimote_t* wm,cmd_blk_cb cb); -int wiiuse_sendcmd(struct wiimote_t *wm,ubyte report_type,ubyte *msg,int len,cmd_blk_cb cb); - -#ifdef __cplusplus -} -#endif - -#endif /* WIIUSE_INTERNAL_H_INCLUDED */ diff --git a/wii/wiiuse/wpad.c b/wii/wiiuse/wpad.c deleted file mode 100644 index 8e80da0de3..0000000000 --- a/wii/wiiuse/wpad.c +++ /dev/null @@ -1,1106 +0,0 @@ -/*------------------------------------------------------------- - -wpad.c -- Wiimote Application Programmers Interface - -Copyright (C) 2008 -Michael Wiedenbauer (shagkur) -Dave Murphy (WinterMute) -Hector Martin (marcan) - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you -must not claim that you wrote the original software. If you use -this software in a product, an acknowledgment in the product -documentation would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. - --------------------------------------------------------------*/ - -/* This source as presented is a modified version of original wiiuse for use - * with RetroArch, and must not be confused with the original software. */ - -#include -#include -#include -#include -#include - -#include "os.h" -#include "conf.h" -#include "ir.h" - -#ifdef HAVE_WIIUSE_SPEAKER -#include "speaker.h" -#endif - -#include "dynamics.h" -#include "wiiuse_internal.h" -#include "wiiuse/wpad.h" -#include "lwp_threads.h" -#include "ogcsys.h" - -#define MAX_STREAMDATA_LEN 20 -#define EVENTQUEUE_LENGTH 16 - -#define DISCONNECT_BATTERY_DIED 0x14 -#define DISCONNECT_POWER_OFF 0x15 - -struct _wpad_thresh{ - s32 btns; - s32 ir; - s32 js; - s32 acc; - s32 mp; -}; - -struct _wpad_cb { - wiimote *wm; - s32 data_fmt; - s32 queue_head; - s32 queue_tail; - s32 queue_full; - u32 queue_length; - u32 dropped_events; - s32 idle_time; - s32 speaker_enabled; - struct _wpad_thresh thresh; - -#ifdef HAVE_WIIUSE_SPEAKER - void *sound_data; - u32 sound_len; - u32 sound_off; - syswd_t sound_alarm; -#endif - - WPADData lstate; -#ifdef HAVE_WIIUSE_QUEUE_EXT - WPADData *queue_ext; -#endif - WPADData queue_int[EVENTQUEUE_LENGTH]; -}; - -static syswd_t __wpad_timer; -static vu32 __wpads_inited = 0; -static vs32 __wpads_ponded = 0; -static u32 __wpad_idletimeout = 300; -static vu32 __wpads_active = 0; -static vu32 __wpads_used = 0; -static wiimote **__wpads = NULL; -static wiimote_listen __wpads_listen[CONF_PAD_MAX_REGISTERED]; -static WPADData wpaddata[WPAD_MAX_WIIMOTES]; -static struct _wpad_cb __wpdcb[WPAD_MAX_WIIMOTES]; -static conf_pads __wpad_devs; -static struct linkkey_info __wpad_keys[WPAD_MAX_WIIMOTES]; - -static s32 __wpad_onreset(s32 final); -static s32 __wpad_disconnect(struct _wpad_cb *wpdcb); -static void __wpad_eventCB(struct wiimote_t *wm,s32 event); - -static void __wpad_def_powcb(s32 chan); -static WPADShutdownCallback __wpad_batcb = NULL; -static WPADShutdownCallback __wpad_powcb = __wpad_def_powcb; - -extern void __wiiuse_sensorbar_enable(int enable); -extern void __SYS_DoPowerCB(void); - -static sys_resetinfo __wpad_resetinfo = { - {}, - __wpad_onreset, - 127 -}; - -static s32 __wpad_onreset(s32 final) -{ - //printf("__wpad_onreset(%d)\n",final); - if(final==FALSE) { - WPAD_Shutdown(); - } - return 1; -} - -static void __wpad_def_powcb(s32 chan) -{ - __SYS_DoPowerCB(); -} - -static void __wpad_timeouthandler(syswd_t alarm,void *cbarg) -{ - s32 i; - struct wiimote_t *wm = NULL; - struct _wpad_cb *wpdcb = NULL; - - if(!__wpads_active) return; - - ++_thread_dispatch_disable_level; - for(i=0;iwm; - if(wm && WIIMOTE_IS_SET(wm,WIIMOTE_STATE_CONNECTED)) { - wpdcb->idle_time++; - if(wpdcb->idle_time>=__wpad_idletimeout) { - wpdcb->idle_time = 0; - wiiuse_disconnect(wm); - } - } - } - --_thread_dispatch_disable_level; -} - -#ifdef HAVE_WIIUSE_SPEAKER -static void __wpad_sounddata_alarmhandler(syswd_t alarm,void *cbarg) -{ - u8 *snd_data; - u32 snd_off; - struct wiimote_t *wm; - struct _wpad_cb *wpdcb = (struct _wpad_cb*)cbarg; - - if(!wpdcb) return; - - if(wpdcb->sound_off>=wpdcb->sound_len) { - wpdcb->sound_data = NULL; - wpdcb->sound_len = 0; - wpdcb->sound_off = 0; - SYS_CancelAlarm(wpdcb->sound_alarm); - return; - } - - wm = wpdcb->wm; - snd_data = wpdcb->sound_data; - snd_off = wpdcb->sound_off; - wpdcb->sound_off += MAX_STREAMDATA_LEN; - wiiuse_write_streamdata(wm,(snd_data+snd_off),MAX_STREAMDATA_LEN,NULL); -} -#endif - -static void __wpad_setfmt(s32 chan) -{ - switch(__wpdcb[chan].data_fmt) { - case WPAD_FMT_BTNS: - wiiuse_set_flags(__wpads[chan], 0, WIIUSE_CONTINUOUS); - wiiuse_motion_sensing(__wpads[chan],0); - wiiuse_set_ir(__wpads[chan],0); - break; - case WPAD_FMT_BTNS_ACC: - wiiuse_set_flags(__wpads[chan], WIIUSE_CONTINUOUS, 0); - wiiuse_motion_sensing(__wpads[chan],1); - wiiuse_set_ir(__wpads[chan],0); - break; - case WPAD_FMT_BTNS_ACC_IR: - wiiuse_set_flags(__wpads[chan], WIIUSE_CONTINUOUS, 0); - wiiuse_motion_sensing(__wpads[chan],1); - wiiuse_set_ir(__wpads[chan],1); - break; - default: - break; - } -} - -wiimote *__wpad_assign_slot(struct bd_addr *pad_addr) -{ - u32 i, level; - struct bd_addr bdaddr; - //printf("WPAD Assigning slot (active: 0x%02x)\n", __wpads_used); - _CPU_ISR_Disable(level); - - // Try preassigned slots - for(i=0; iwm; - if(wm && WIIMOTE_IS_SET(wm,WIIMOTE_STATE_CONNECTED)) { - wiiuse_disconnect(wm); - } - - return 0; -} - -static void __wpad_calc_data(WPADData *data,WPADData *lstate,struct accel_t *accel_calib,u32 smoothed) -{ - if(data->err!=WPAD_ERR_NONE) return; - - data->orient = lstate->orient; - - data->ir.state = lstate->ir.state; - data->ir.sensorbar = lstate->ir.sensorbar; - data->ir.x = lstate->ir.x; - data->ir.y = lstate->ir.y; - data->ir.sx = lstate->ir.sx; - data->ir.sy = lstate->ir.sy; - data->ir.ax = lstate->ir.ax; - data->ir.ay = lstate->ir.ay; - data->ir.distance = lstate->ir.distance; - data->ir.z = lstate->ir.z; - data->ir.angle = lstate->ir.angle; - data->ir.error_cnt = lstate->ir.error_cnt; - data->ir.glitch_cnt = lstate->ir.glitch_cnt; - - if(data->data_present & WPAD_DATA_ACCEL) { - calculate_orientation(accel_calib, &data->accel, &data->orient, smoothed); - calculate_gforce(accel_calib, &data->accel, &data->gforce); - } - if(data->data_present & WPAD_DATA_IR) { - interpret_ir_data(&data->ir,&data->orient); - } - if(data->data_present & WPAD_DATA_EXPANSION) { - switch(data->exp.type) { - case EXP_NUNCHUK: - { - struct nunchuk_t *nc = &data->exp.nunchuk; - - nc->orient = lstate->exp.nunchuk.orient; - calc_joystick_state(&nc->js,nc->js.pos.x,nc->js.pos.y); - calculate_orientation(&nc->accel_calib,&nc->accel,&nc->orient,smoothed); - calculate_gforce(&nc->accel_calib,&nc->accel,&nc->gforce); - data->btns_h |= (data->exp.nunchuk.btns<<16); - } - break; - - case EXP_CLASSIC: - { - struct classic_ctrl_t *cc = &data->exp.classic; - - cc->r_shoulder = ((f32)cc->rs_raw/0x1F); - cc->l_shoulder = ((f32)cc->ls_raw/0x1F); - calc_joystick_state(&cc->ljs, cc->ljs.pos.x, cc->ljs.pos.y); - calc_joystick_state(&cc->rjs, cc->rjs.pos.x, cc->rjs.pos.y); - data->btns_h |= (data->exp.classic.btns<<16); - } - break; - default: - break; - } - } - *lstate = *data; -} - -static void __save_state(struct wiimote_t* wm) { - /* wiimote */ - wm->lstate.btns = wm->btns; - wm->lstate.accel = wm->accel; - - /* ir */ - wm->lstate.ir = wm->ir; - - /* expansion */ - switch (wm->exp.type) { - case EXP_NUNCHUK: - wm->lstate.exp.nunchuk = wm->exp.nunchuk; - break; - case EXP_CLASSIC: - wm->lstate.exp.classic = wm->exp.classic; - break; - case EXP_MOTION_PLUS: - wm->lstate.exp.mp = wm->exp.mp; - break; - } -} - -#define ABS(x) ((s32)(x)>0?(s32)(x):-((s32)(x))) - -#define STATE_CHECK(thresh, a, b) \ - if(((thresh) > WPAD_THRESH_IGNORE) && (ABS((a)-(b)) > (thresh))) \ - state_changed = 1; - -#define STATE_CHECK_SIMPLE(thresh, a, b) \ - if(((thresh) > WPAD_THRESH_IGNORE) && ((a) != (b))) \ - state_changed = 1; - -static u32 __wpad_read_expansion(struct wiimote_t *wm,WPADData *data, struct _wpad_thresh *thresh) -{ - int state_changed = 0; - switch(data->exp.type) { - case EXP_NUNCHUK: - data->exp.nunchuk = wm->exp.nunchuk; - STATE_CHECK_SIMPLE(thresh->btns, wm->exp.nunchuk.btns, wm->lstate.exp.nunchuk.btns); - STATE_CHECK(thresh->acc, wm->exp.nunchuk.accel.x, wm->lstate.exp.nunchuk.accel.x); - STATE_CHECK(thresh->acc, wm->exp.nunchuk.accel.y, wm->lstate.exp.nunchuk.accel.y); - STATE_CHECK(thresh->acc, wm->exp.nunchuk.accel.z, wm->lstate.exp.nunchuk.accel.z); - STATE_CHECK(thresh->js, wm->exp.nunchuk.js.pos.x, wm->lstate.exp.nunchuk.js.pos.x); - STATE_CHECK(thresh->js, wm->exp.nunchuk.js.pos.y, wm->lstate.exp.nunchuk.js.pos.y); - break; - case EXP_CLASSIC: - data->exp.classic = wm->exp.classic; - STATE_CHECK_SIMPLE(thresh->btns, wm->exp.classic.btns, wm->lstate.exp.classic.btns); - STATE_CHECK(thresh->js, wm->exp.classic.rs_raw, wm->lstate.exp.classic.rs_raw); - STATE_CHECK(thresh->js, wm->exp.classic.ls_raw, wm->lstate.exp.classic.ls_raw); - STATE_CHECK(thresh->js, wm->exp.classic.ljs.pos.x, wm->lstate.exp.classic.ljs.pos.x); - STATE_CHECK(thresh->js, wm->exp.classic.ljs.pos.y, wm->lstate.exp.classic.ljs.pos.y); - STATE_CHECK(thresh->js, wm->exp.classic.rjs.pos.x, wm->lstate.exp.classic.rjs.pos.x); - STATE_CHECK(thresh->js, wm->exp.classic.rjs.pos.y, wm->lstate.exp.classic.rjs.pos.y); - break; - case EXP_MOTION_PLUS: - data->exp.mp = wm->exp.mp; - STATE_CHECK(thresh->mp,wm->exp.mp.rx,wm->lstate.exp.mp.rx); - STATE_CHECK(thresh->mp,wm->exp.mp.ry,wm->lstate.exp.mp.ry); - STATE_CHECK(thresh->mp,wm->exp.mp.rz,wm->lstate.exp.mp.rz); - break; - } - return state_changed; -} - -static void __wpad_read_wiimote(struct wiimote_t *wm, WPADData *data, s32 *idle_time, struct _wpad_thresh *thresh) -{ - int i; - int state_changed = 0; - data->err = WPAD_ERR_TRANSFER; - data->data_present = 0; - data->battery_level = wm->battery_level; - data->exp.type = wm->exp.type; - if(wm && WIIMOTE_IS_SET(wm,WIIMOTE_STATE_CONNECTED)) { - if(WIIMOTE_IS_SET(wm,WIIMOTE_STATE_HANDSHAKE_COMPLETE)) { - switch(wm->event_buf[0]) { - case WM_RPT_BTN: - case WM_RPT_BTN_ACC: - case WM_RPT_BTN_ACC_IR: - case WM_RPT_BTN_EXP: - case WM_RPT_BTN_ACC_EXP: - case WM_RPT_BTN_IR_EXP: - case WM_RPT_BTN_ACC_IR_EXP: - data->btns_h = (wm->btns&0xffff); - data->data_present |= WPAD_DATA_BUTTONS; - STATE_CHECK_SIMPLE(thresh->btns, wm->btns, wm->lstate.btns); - } - switch(wm->event_buf[0]) { - case WM_RPT_BTN_ACC: - case WM_RPT_BTN_ACC_IR: - case WM_RPT_BTN_ACC_EXP: - case WM_RPT_BTN_ACC_IR_EXP: - data->accel = wm->accel; - data->data_present |= WPAD_DATA_ACCEL; - STATE_CHECK(thresh->acc, wm->accel.x, wm->lstate.accel.x); - STATE_CHECK(thresh->acc, wm->accel.y, wm->lstate.accel.y); - STATE_CHECK(thresh->acc, wm->accel.z, wm->lstate.accel.z); - } - switch(wm->event_buf[0]) { - //IR requires acceleration - //case WM_RPT_BTN_IR_EXP: - case WM_RPT_BTN_ACC_IR: - case WM_RPT_BTN_ACC_IR_EXP: - data->ir = wm->ir; - data->data_present |= WPAD_DATA_IR; - for(i=0; iir, wm->ir.dot[i].visible, wm->lstate.ir.dot[i].visible); - STATE_CHECK(thresh->ir, wm->ir.dot[i].rx, wm->lstate.ir.dot[i].rx); - STATE_CHECK(thresh->ir, wm->ir.dot[i].ry, wm->lstate.ir.dot[i].ry); - } - } - switch(wm->event_buf[0]) { - case WM_RPT_BTN_EXP: - case WM_RPT_BTN_ACC_EXP: - case WM_RPT_BTN_IR_EXP: - case WM_RPT_BTN_ACC_IR_EXP: - state_changed |= __wpad_read_expansion(wm,data,thresh); - data->data_present |= WPAD_DATA_EXPANSION; - } - data->err = WPAD_ERR_NONE; - if(state_changed) { - *idle_time = 0; - __save_state(wm); - } - } else - data->err = WPAD_ERR_NOT_READY; - } else - data->err = WPAD_ERR_NO_CONTROLLER; -} - -static void __wpad_eventCB(struct wiimote_t *wm,s32 event) -{ - s32 chan; - u32 maxbufs; - WPADData *wpadd = NULL; - struct _wpad_cb *wpdcb = NULL; - - switch(event) { - case WIIUSE_EVENT: - chan = wm->unid; - wpdcb = &__wpdcb[chan]; - -#ifdef HAVE_WIIUSE_QUEUE_EXT - if(wpdcb->queue_ext!=NULL) { - maxbufs = wpdcb->queue_length; - wpadd = &(wpdcb->queue_ext[wpdcb->queue_tail]); - } - else -#endif - { - maxbufs = EVENTQUEUE_LENGTH; - wpadd = &(wpdcb->queue_int[wpdcb->queue_tail]); - } - if(wpdcb->queue_full == maxbufs) { - wpdcb->queue_head++; - wpdcb->queue_head %= maxbufs; - wpdcb->dropped_events++; - } else { - wpdcb->queue_full++; - } - - __wpad_read_wiimote(wm, wpadd, &wpdcb->idle_time, &wpdcb->thresh); - - wpdcb->queue_tail++; - wpdcb->queue_tail %= maxbufs; - - break; - case WIIUSE_STATUS: - break; - case WIIUSE_CONNECT: - chan = wm->unid; - wpdcb = &__wpdcb[chan]; - wpdcb->wm = wm; - wpdcb->queue_head = 0; - wpdcb->queue_tail = 0; - wpdcb->queue_full = 0; - wpdcb->idle_time = 0; - memset(&wpdcb->lstate,0,sizeof(WPADData)); - memset(&wpaddata[chan],0,sizeof(WPADData)); - memset(wpdcb->queue_int,0,(sizeof(WPADData)*EVENTQUEUE_LENGTH)); - wiiuse_set_ir_position(wm,(CONF_GetSensorBarPosition()^1)); - wiiuse_set_ir_sensitivity(wm,CONF_GetIRSensitivity()); - wiiuse_set_leds(wm,(WIIMOTE_LED_1<<(chan%WPAD_BALANCE_BOARD)),NULL); -#ifdef HAVE_WIIUSE_SPEAKER - wiiuse_set_speaker(wm,wpdcb->speaker_enabled); -#endif - __wpad_setfmt(chan); - __wpads_active |= (0x01<unid; - wpdcb = &__wpdcb[chan]; - wpdcb->wm = wm; - wpdcb->queue_head = 0; - wpdcb->queue_tail = 0; - wpdcb->queue_full = 0; - wpdcb->queue_length = 0; -#ifdef HAVE_WIIUSE_QUEUE_EXT - wpdcb->queue_ext = NULL; -#endif - wpdcb->idle_time = -1; - memset(&wpdcb->lstate,0,sizeof(WPADData)); - memset(&wpaddata[chan],0,sizeof(WPADData)); - memset(wpdcb->queue_int,0,(sizeof(WPADData)*EVENTQUEUE_LENGTH)); - __wpads_active &= ~(0x01< CONF_PAD_MAX_REGISTERED) { - WPAD_Shutdown(); - _CPU_ISR_Restore(level); - return WPAD_ERR_BADCONF; - } - - __wpads = wiiuse_init(WPAD_MAX_WIIMOTES,__wpad_eventCB); - if(__wpads==NULL) { - WPAD_Shutdown(); - _CPU_ISR_Restore(level); - return WPAD_ERR_UNKNOWN; - } - - __wiiuse_sensorbar_enable(1); - - BTE_Init(); - BTE_SetDisconnectCallback(__wpad_disconnectCB); - BTE_InitCore(__initcore_finished); - - if (SYS_CreateAlarm(&__wpad_timer) < 0) - { - WPAD_Shutdown(); - _CPU_ISR_Restore(level); - return WPAD_ERR_UNKNOWN; - } - - SYS_RegisterResetFunc(&__wpad_resetinfo); - - tb.tv_sec = 1; - tb.tv_nsec = 0; - SYS_SetPeriodicAlarm(__wpad_timer,&tb,&tb,__wpad_timeouthandler,NULL); - __wpads_inited = WPAD_STATE_ENABLING; - } - _CPU_ISR_Restore(level); - return WPAD_ERR_NONE; -} - -s32 WPAD_ReadEvent(s32 chan, WPADData *data) -{ - u32 level; - u32 maxbufs,smoothed = 0; - struct accel_t *accel_calib = NULL; - struct _wpad_cb *wpdcb = NULL; - WPADData *lstate = NULL,*wpadd = NULL; - - //if(chan=WPAD_MAX_WIIMOTES) return WPAD_ERR_BAD_CHANNEL; - - _CPU_ISR_Disable(level); - if(__wpads_inited==WPAD_STATE_DISABLED) { - _CPU_ISR_Restore(level); - return WPAD_ERR_NOT_READY; - } - - if(__wpads[chan] && WIIMOTE_IS_SET(__wpads[chan],WIIMOTE_STATE_CONNECTED)) { - if(WIIMOTE_IS_SET(__wpads[chan],WIIMOTE_STATE_HANDSHAKE_COMPLETE)) { - wpdcb = &__wpdcb[chan]; -#ifdef HAVE_WIIUSE_QUEUE_EXT - if(wpdcb->queue_ext!=NULL) { - maxbufs = wpdcb->queue_length; - wpadd = wpdcb->queue_ext; - } - else -#endif - { - maxbufs = EVENTQUEUE_LENGTH; - wpadd = wpdcb->queue_int; - } - if(wpdcb->queue_full == 0) { - _CPU_ISR_Restore(level); - return WPAD_ERR_QUEUE_EMPTY; - } - if(data) - *data = wpadd[wpdcb->queue_head]; - wpdcb->queue_head++; - wpdcb->queue_head %= maxbufs; - wpdcb->queue_full--; - lstate = &wpdcb->lstate; - accel_calib = &__wpads[chan]->accel_calib; - smoothed = WIIMOTE_IS_FLAG_SET(__wpads[chan], WIIUSE_SMOOTHING); - } else { - _CPU_ISR_Restore(level); - return WPAD_ERR_NOT_READY; - } - } else { - _CPU_ISR_Restore(level); - return WPAD_ERR_NO_CONTROLLER; - } - - _CPU_ISR_Restore(level); - if(data) - __wpad_calc_data(data,lstate,accel_calib,smoothed); - return 0; -} - -static s32 pad_readpending_temp(s32 chan) -{ - s32 count = 0; - s32 ret; - - while(1) - { - ret = WPAD_ReadEvent(chan, &wpaddata[chan]); - if(ret < WPAD_ERR_NONE) - break; - count++; - } - if(ret == WPAD_ERR_QUEUE_EMPTY) return count; - return ret; -} - -s32 WPAD_ReadPending(s32 chan, WPADDataCallback datacb) -{ - u32 i; - s32 count = 0; - s32 ret; - - for(i= WPAD_CHAN_0; i < WPAD_MAX_WIIMOTES; i++) - if((ret = pad_readpending_temp(i)) >= WPAD_ERR_NONE) - count += ret; - return count; -} - -s32 WPAD_SetMotionPlus(s32 chan, u8 enable) -{ - u32 level; - s32 ret; - int i; - - if(chan == WPAD_CHAN_ALL) { - for(i=WPAD_CHAN_0; i=WPAD_MAX_WIIMOTES) return WPAD_ERR_BAD_CHANNEL; - - _CPU_ISR_Disable(level); - if(__wpads_inited==WPAD_STATE_DISABLED) { - _CPU_ISR_Restore(level); - return WPAD_ERR_NOT_READY; - } - - if(__wpads[chan]!=NULL) { - wiiuse_set_motion_plus(__wpads[chan], enable); - } - _CPU_ISR_Restore(level); - return WPAD_ERR_NONE; -} - -s32 WPAD_SetVRes(s32 chan,u32 xres,u32 yres) -{ - u32 level; - s32 ret; - int i; - - if(chan == WPAD_CHAN_ALL) { - for(i=WPAD_CHAN_0; i=WPAD_MAX_WIIMOTES) return WPAD_ERR_BAD_CHANNEL; - - _CPU_ISR_Disable(level); - if(__wpads_inited==WPAD_STATE_DISABLED) { - _CPU_ISR_Restore(level); - return WPAD_ERR_NOT_READY; - } - - if(__wpads[chan]!=NULL) - wiiuse_set_ir_vres(__wpads[chan],xres,yres); - - _CPU_ISR_Restore(level); - return WPAD_ERR_NONE; -} - -s32 WPAD_GetStatus() -{ - s32 ret; - u32 level; - - _CPU_ISR_Disable(level); - ret = __wpads_inited; - _CPU_ISR_Restore(level); - - return ret; -} - -s32 WPAD_Probe(s32 chan,u32 *type) -{ - s32 ret; - u32 level,dev; - wiimote *wm = NULL; - - //if(chan=WPAD_MAX_WIIMOTES) return WPAD_ERR_BAD_CHANNEL; - - _CPU_ISR_Disable(level); - if(__wpads_inited==WPAD_STATE_DISABLED) { - _CPU_ISR_Restore(level); - return WPAD_ERR_NOT_READY; - } - - wm = __wpads[chan]; - if(wm && WIIMOTE_IS_SET(wm,WIIMOTE_STATE_CONNECTED)) { - if(WIIMOTE_IS_SET(wm,WIIMOTE_STATE_HANDSHAKE_COMPLETE)) { - dev = WPAD_EXP_NONE; - if(WIIMOTE_IS_SET(wm,WIIMOTE_STATE_EXP)) { - switch(wm->exp.type) { - case WPAD_EXP_NUNCHUK: - case WPAD_EXP_CLASSIC: - dev = wm->exp.type; - break; - } - } - if(type!=NULL) *type = dev; - ret = WPAD_ERR_NONE; - } else - ret = WPAD_ERR_NOT_READY; - } else - ret = WPAD_ERR_NO_CONTROLLER; - _CPU_ISR_Restore(level); - - return ret; -} - -#ifdef HAVE_WIIUSE_QUEUE_EXT -s32 WPAD_SetEventBufs(s32 chan, WPADData *bufs, u32 cnt) -{ - u32 level; - struct _wpad_cb *wpdcb = NULL; - - if(chan=WPAD_MAX_WIIMOTES) return WPAD_ERR_BAD_CHANNEL; - - _CPU_ISR_Disable(level); - wpdcb = &__wpdcb[chan]; - wpdcb->queue_head = 0; - wpdcb->queue_tail = 0; - wpdcb->queue_full = 0; - wpdcb->queue_length = cnt; - wpdcb->queue_ext = bufs; - _CPU_ISR_Restore(level); - return WPAD_ERR_NONE; -} -#endif - -void WPAD_SetPowerButtonCallback(WPADShutdownCallback cb) -{ - u32 level; - - _CPU_ISR_Disable(level); - if(cb) - __wpad_powcb = cb; - else - __wpad_powcb = __wpad_def_powcb; - _CPU_ISR_Restore(level); -} - -void WPAD_SetBatteryDeadCallback(WPADShutdownCallback cb) -{ - u32 level; - - _CPU_ISR_Disable(level); - __wpad_batcb = cb; - _CPU_ISR_Restore(level); -} - -s32 WPAD_Disconnect(s32 chan) -{ - u32 level, cnt = 0; - struct _wpad_cb *wpdcb = NULL; - - if(chan=WPAD_MAX_WIIMOTES) return WPAD_ERR_BAD_CHANNEL; - - _CPU_ISR_Disable(level); - if(__wpads_inited==WPAD_STATE_DISABLED) { - _CPU_ISR_Restore(level); - return WPAD_ERR_NOT_READY; - } - - wpdcb = &__wpdcb[chan]; - __wpad_disconnect(wpdcb); - - _CPU_ISR_Restore(level); - - while(__wpads_active&(0x01< 3000) break; - } - - return WPAD_ERR_NONE; -} - -void WPAD_Shutdown() -{ - s32 i; - u32 level; - u32 cnt = 0; - struct _wpad_cb *wpdcb = NULL; - - _CPU_ISR_Disable(level); - - __wpads_inited = WPAD_STATE_DISABLED; - SYS_RemoveAlarm(__wpad_timer); - for(i=0;isound_alarm); -#endif - __wpad_disconnect(wpdcb); - } - - __wiiuse_sensorbar_enable(0); - _CPU_ISR_Restore(level); - - while(__wpads_active) { - usleep(50); - if(++cnt > 3000) break; - } - - BTE_Shutdown(); -} - -void WPAD_SetIdleTimeout(u32 seconds) -{ - u32 level; - - _CPU_ISR_Disable(level); - __wpad_idletimeout = seconds; - _CPU_ISR_Restore(level); -} - -#ifdef HAVE_WIIUSE_RUMBLE -s32 WPAD_Rumble(s32 chan, int status) -{ - int i; - s32 ret; - u32 level; - - if(chan == WPAD_CHAN_ALL) { - for(i=WPAD_CHAN_0; i=WPAD_MAX_WIIMOTES) return WPAD_ERR_BAD_CHANNEL; - - _CPU_ISR_Disable(level); - if(__wpads_inited==WPAD_STATE_DISABLED) { - _CPU_ISR_Restore(level); - return WPAD_ERR_NOT_READY; - } - - if(__wpads[chan]!=NULL) - wiiuse_rumble(__wpads[chan],status); - - _CPU_ISR_Restore(level); - return WPAD_ERR_NONE; -} -#endif - -#ifdef HAVE_WIIUSE_SPEAKER -s32 WPAD_ControlSpeaker(s32 chan,s32 enable) -{ - int i; - s32 ret; - u32 level; - - if(chan == WPAD_CHAN_ALL) { - for(i=WPAD_CHAN_0; i=WPAD_MAX_WIIMOTES) return WPAD_ERR_BAD_CHANNEL; - - _CPU_ISR_Disable(level); - if(__wpads_inited==WPAD_STATE_DISABLED) { - _CPU_ISR_Restore(level); - return WPAD_ERR_NOT_READY; - } - - if(__wpads[chan]!=NULL) { - __wpdcb[chan].speaker_enabled = enable; - wiiuse_set_speaker(__wpads[chan],enable); - } - - _CPU_ISR_Restore(level); - return WPAD_ERR_NONE; -} - -s32 WPAD_IsSpeakerEnabled(s32 chan) -{ - s32 ret; - u32 level; - wiimote *wm = NULL; - - if(chan=WPAD_MAX_WIIMOTES) return WPAD_ERR_BAD_CHANNEL; - - _CPU_ISR_Disable(level); - if(__wpads_inited==WPAD_STATE_DISABLED) { - _CPU_ISR_Restore(level); - return WPAD_ERR_NOT_READY; - } - - wm = __wpads[chan]; - ret = WPAD_ERR_NOT_READY; - if(wm && WIIMOTE_IS_SET(wm,WIIMOTE_STATE_CONNECTED)) { - if(WIIMOTE_IS_SET(wm,WIIMOTE_STATE_HANDSHAKE_COMPLETE) - && WIIMOTE_IS_SET(wm,WIIMOTE_STATE_SPEAKER)) ret = WPAD_ERR_NONE; - } - - _CPU_ISR_Restore(level); - return ret; -} - -void WPAD_EncodeData(WPADEncStatus *info,u32 flag,const s16 *pcmSamples,s32 numSamples,u8 *encData) -{ - int n; - short *samples = (short*)pcmSamples; - WENCStatus *status = (WENCStatus*)info; - - if(!(flag&WPAD_ENC_CONT)) status->step = 0; - - n = (numSamples+1)/2; - for(;n>0;n--) { - int nibble; - nibble = (wencdata(status,samples[0]))<<4; - nibble |= (wencdata(status,samples[1])); - *encData++ = nibble; - samples += 2; - } -} -#endif - -WPADData *WPAD_Data(int chan) -{ - //if(chan<0 || chan>=WPAD_MAX_WIIMOTES) return NULL; - return &wpaddata[chan]; -} - -u8 WPAD_BatteryLevel(int chan) -{ - //if(chan<0 || chan>=WPAD_MAX_WIIMOTES) return 0; - return wpaddata[chan].battery_level; -} - -void WPAD_IR(int chan, struct ir_t *ir) -{ - //if(chan<0 || chan>=WPAD_MAX_WIIMOTES || ir==NULL ) return; - *ir = wpaddata[chan].ir; -} - -void WPAD_Orientation(int chan, struct orient_t *orient) -{ - //if(chan<0 || chan>=WPAD_MAX_WIIMOTES || orient==NULL ) return; - *orient = wpaddata[chan].orient; -} - -void WPAD_GForce(int chan, struct gforce_t *gforce) -{ - //if(chan<0 || chan>=WPAD_MAX_WIIMOTES || gforce==NULL ) return; - *gforce = wpaddata[chan].gforce; -} - -void WPAD_Accel(int chan, struct vec3w_t *accel) -{ - //if(chan<0 || chan>=WPAD_MAX_WIIMOTES || accel==NULL ) return; - *accel = wpaddata[chan].accel; -}