Merge branch 'master' into qt

This commit is contained in:
radius 2016-11-17 00:12:23 -05:00
commit 9a163164f3
41 changed files with 1662 additions and 762 deletions

3
.gitignore vendored
View File

@ -85,3 +85,6 @@ pkg/apple/iOS/modules/
obj-unix/
.vagrant/
.MAKEFILE_DEFINES
.CONFIG_DEFINES

View File

@ -507,7 +507,6 @@ endif
ifeq ($(HAVE_LAKKA), 1)
DEFINES += -DHAVE_LAKKA
DEFINES += -DLAKKA_PROJECT=$(LAKKA_PROJECT)
endif
ifeq ($(HAVE_MENU_COMMON), 1)

View File

@ -213,7 +213,7 @@ else ifeq ($(platform), vita)
INCLUDE += -Ideps/zlib
PLATCFLAGS := -marm -mfloat-abi=hard -fsingle-precision-constant \
-mword-relocations -fno-unwind-tables -fno-asynchronous-unwind-tables -ftree-vectorize -fno-optimize-sibling-calls
LIBS += -lSceKernel_stub -lSceDisplay_stub -lSceGxm_stub -lSceNet_stub -lSceNetCtl_stub\
LIBS += -lSceDisplay_stub -lSceGxm_stub -lSceNet_stub -lSceNetCtl_stub\
-lSceSysmodule_stub -lSceCtrl_stub -lSceTouch_stub -lSceAudio_stub -lSceFiber_stub\
-lScePower_stub -lSceRtc_stub -lSceCommonDialog_stub -lScePgf_stub \
-lSceMotion_stub -lSceAppMgr_stub -lpng -lm -lc

View File

@ -1,16 +1,23 @@
TARGET := retroarch_wiiu
RPX_BUILD = 0
DEBUG = 0
GRIFFIN_BUILD = 0
WHOLE_ARCHIVE_LINK = 0
OBJ :=
OBJ += wiiu/system/memory.o
OBJ += wiiu/system/exception_handler.o
OBJ += wiiu/fs/sd_fat_devoptab.o
OBJ += wiiu/fs/fs_utils.o
OBJ += wiiu/system/dynamic.o
OBJ += wiiu/system/dyn_stubs.o
OBJ += wiiu/tex_shader.o
PC_DEVELOPMENT_IP_ADDRESS =
PC_DEVELOPMENT_TCP_PORT =
OBJ :=
OBJ += wiiu/system/memory.o
OBJ += wiiu/system/exception_handler.o
OBJ += wiiu/fs/sd_fat_devoptab.o
OBJ += wiiu/fs/fs_utils.o
OBJ += wiiu/tex_shader.o
ifneq ($(RPX_BUILD), 1)
OBJ += wiiu/system/dynamic.o
OBJ += wiiu/system/dyn_stubs.o
endif
DEFINES :=
@ -93,6 +100,7 @@ STRIP := $(PREFIX)strip
NM := $(PREFIX)nm
LD := $(CXX)
ELF2RPL := $(WUT_ROOT)/tools/bin/elf2rpl
INCDIRS := -I. -Ideps/zlib -Ideps/7zip -Ilibretro-common/include -Iwiiu -I$(WUT_ROOT)/include
LIBDIRS := -L.
@ -101,9 +109,9 @@ CFLAGS := -mrvl -mcpu=750 -meabi -mhard-float
LDFLAGS :=
ifeq ($(DEBUG), 1)
CFLAGS += -O0 -g
CFLAGS += -O0 -g
else
CFLAGS += -O3
CFLAGS += -O3
endif
LDFLAGS := $(CFLAGS)
@ -118,24 +126,43 @@ CFLAGS += -DHAVE_MAIN
CFLAGS += -DRARCH_INTERNAL -DRARCH_CONSOLE -DSINC_LOWEST_QUALITY
CFLAGS += -DHAVE_FILTERS_BUILTIN $(DEFINES)
ifneq ($(PC_DEVELOPMENT_IP_ADDRESS),)
CFLAGS += -DPC_DEVELOPMENT_IP_ADDRESS='"$(PC_DEVELOPMENT_IP_ADDRESS)"'
endif
ifneq ($(PC_DEVELOPMENT_TCP_PORT),)
CFLAGS += -DPC_DEVELOPMENT_TCP_PORT=$(PC_DEVELOPMENT_TCP_PORT)
endif
ifeq ($(WHOLE_ARCHIVE_LINK), 1)
WHOLE_START := -Wl,--whole-archive
WHOLE_END := -Wl,--no-whole-archive
endif
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
LDFLAGS += -nostartfiles -Wl,-Map,$(notdir $@).map,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc
LDFLAGS += -Wl,-wrap,malloc_usable_size,-wrap,_malloc_r,-wrap,_free_r,-wrap,_realloc_r,-wrap,_calloc_r,-wrap,_memalign_r
LDFLAGS += -Wl,-wrap,_malloc_usable_size_r,-wrap,valloc,-wrap,_valloc_r,-wrap,_pvalloc_r,--gc-sections
ifeq ($(RPX_BUILD), 1)
CFLAGS += -fno-builtin -ffreestanding -DRPX_BUILD
LIBDIRS += -L$(WUT_ROOT)/lib -L$(DEVKITPPC)/lib
LDFLAGS += -pie -fPIE
LDFLAGS += -z common-page-size=64 -z max-page-size=64
LDFLAGS += -lcoreinit -lgx2 -lnsysnet -lproc_ui -lsndcore2 -lsysapp -lvpad
LDFLAGS += -T $(WUT_ROOT)/rules/rpl.ld
# LDFLAGS += -T wiiu/link_rpl.ld
LDFLAGS += -nostartfiles
else
LDFLAGS += -T wiiu/link_elf.ld
endif
LDFLAGS += -Wl,--gc-sections
LIBS := $(WHOLE_START) -lretro_wiiu $(WHOLE_END) -lm
all: $(TARGET)
$(TARGET): $(TARGET).elf
ifeq ($(RPX_BUILD), 1)
all: $(TARGET).elf $(TARGET).rpx
else
all: $(TARGET).elf
endif
%.o: %.cpp
$(CXX) -c -o $@ $< $(CXXFLAGS) $(INCDIRS)
@ -152,11 +179,15 @@ $(TARGET): $(TARGET).elf
%.a:
$(AR) -rc $@ $^
$(TARGET).elf: $(OBJ) libretro_wiiu.a wiiu/link_ra.ld
$(LD) -n -T wiiu/link_ra.ld $(OBJ) $(LDFLAGS) $(LIBDIRS) $(LIBS) -o $@
$(TARGET).elf: $(OBJ) libretro_wiiu.a wiiu/link_elf.ld wiiu/link_rpl.ld
$(LD) $(OBJ) $(LDFLAGS) $(LIBDIRS) $(LIBS) -o $@
%.rpx: %.elf
$(ELF2RPL) $(notdir $<) $@
clean:
rm -f $(OBJ)
rm -f $(TARGET).elf
rm -f $(TARGET).rpx
.PHONY: $(BUILD) clean all
.PHONY: clean all

View File

@ -28,6 +28,7 @@
#include "wiiu/wiiu_dbg.h"
#include "wiiu/system/memory.h"
#include "audio/audio_driver.h"
#include "configuration.h"
@ -40,42 +41,40 @@ typedef struct
AXVoice* voice_r;
uint16_t* buffer_l;
uint16_t* buffer_r;
AXVoiceOffsets offsets_l;
AXVoiceOffsets offsets_r;
bool nonblocking;
bool playing;
uint32_t pos;
uint32_t playpos;
uint32_t cpu_ticks_last;
} ax_audio_t;
#define AX_AUDIO_COUNT (1u << 14u)
#define AX_AUDIO_COUNT_MASK (AX_AUDIO_COUNT - 1u)
#define AX_AUDIO_SIZE (AX_AUDIO_COUNT * sizeof(int16_t))
#define AX_AUDIO_SIZE_MASK (AX_AUDIO_SIZE - 1u)
#define AX_AUDIO_COUNT_SHIFT 13u
#define AX_AUDIO_COUNT (1u << AX_AUDIO_COUNT_SHIFT)
#define AX_AUDIO_COUNT_MASK (AX_AUDIO_COUNT - 1u)
#define AX_AUDIO_SIZE (AX_AUDIO_COUNT << 1u)
#define AX_AUDIO_SIZE_MASK (AX_AUDIO_SIZE - 1u)
//#define AX_AUDIO_FRAME_COUNT 144
#define AX_AUDIO_FRAME_COUNT 160
#define AX_AUDIO_RATE 48000
//#define ax_audio_ticks_to_samples(ticks) (((ticks) * 64) / 82875)
//#define ax_audio_samples_to_ticks(samples) (((samples) * 82875) / 64)
#define AX_AUDIO_RATE 48000
#define ax_audio_ticks_to_samples(ticks) (((ticks) * 64) / 82875)
#define ax_audio_samples_to_ticks(samples) (((samples) * 82875) / 64)
static void ax_voice_callback(ax_audio_t* ax_audio)
static inline int ax_diff(int v1, int v2)
{
DEBUG_LINE();
return ((v1 - v2) << (32u - AX_AUDIO_COUNT_SHIFT)) >> (32u - AX_AUDIO_COUNT_SHIFT);
}
static void ax_audio_update_playpos(ax_audio_t* ax_audio)
AXResult ax_aux_callback(void* data, ax_audio_t* ax)
{
uint32_t samples_played = ax_audio_ticks_to_samples(OSGetSystemTick() - ax_audio->cpu_ticks_last);
AXVoiceOffsets offsets;
AXGetVoiceOffsets(ax->voice_l, &offsets);
ax_audio->playpos = (ax_audio->playpos + samples_played) & AX_AUDIO_COUNT_MASK;
ax_audio->cpu_ticks_last += ax_audio_samples_to_ticks(samples_played);
}
if (ax_diff(offsets.currentOffset, ax->pos) < 0)
{
AXSetVoiceState(ax->voice_l, AX_VOICE_STATE_STOPPED);
AXSetVoiceState(ax->voice_r, AX_VOICE_STATE_STOPPED);
}
void ax_frame_callback(void)
{
DEBUG_LINE();
return AX_RESULT_SUCCESS;
}
static void* ax_audio_init(const char* device, unsigned rate, unsigned latency)
@ -89,45 +88,39 @@ static void* ax_audio_init(const char* device, unsigned rate, unsigned latency)
AXInitWithParams(&init);
ax->voice_l = AXAcquireVoice(10, (AXVoiceCallbackFn)ax_voice_callback, ax);
ax->voice_r = AXAcquireVoice(10, (AXVoiceCallbackFn)ax_voice_callback, ax);
if(!ax->voice_l || !ax->voice_r)
ax->voice_l = AXAcquireVoice(10, NULL, ax);
ax->voice_r = AXAcquireVoice(10, NULL, ax);
if (!ax->voice_l || !ax->voice_r)
{
free(ax);
return NULL;
}
ax->buffer_l = malloc(AX_AUDIO_SIZE);
ax->buffer_r = malloc(AX_AUDIO_SIZE);
memset(ax->buffer_l,0,AX_AUDIO_SIZE);
memset(ax->buffer_r,0,AX_AUDIO_SIZE);
DCFlushRange(ax->buffer_l,AX_AUDIO_SIZE);
DCFlushRange(ax->buffer_r,AX_AUDIO_SIZE);
ax->offsets_l.data = ax->buffer_l;
ax->offsets_l.currentOffset = 0;
ax->offsets_l.loopOffset = 0;
ax->offsets_l.endOffset = AX_AUDIO_COUNT;
ax->offsets_l.loopingEnabled = AX_VOICE_LOOP_ENABLED;
ax->offsets_l.dataType = AX_VOICE_FORMAT_LPCM16;
ax->buffer_l = MEM1_alloc(AX_AUDIO_SIZE, 0x100);
ax->buffer_r = MEM1_alloc(AX_AUDIO_SIZE, 0x100);
ax->offsets_r.data = ax->buffer_r;
ax->offsets_r.currentOffset = 0;
ax->offsets_r.loopOffset = 0;
ax->offsets_r.endOffset = AX_AUDIO_COUNT;
ax->offsets_r.loopingEnabled = AX_VOICE_LOOP_ENABLED;
ax->offsets_r.dataType = AX_VOICE_FORMAT_LPCM16;
AXVoiceOffsets offsets;
AXSetVoiceOffsets(ax->voice_l, &ax->offsets_l);
AXSetVoiceOffsets(ax->voice_r, &ax->offsets_r);
offsets.data = ax->buffer_l;
offsets.currentOffset = 0;
offsets.loopOffset = 0;
offsets.endOffset = AX_AUDIO_COUNT - 1;
offsets.loopingEnabled = AX_VOICE_LOOP_ENABLED;
offsets.dataType = AX_VOICE_FORMAT_LPCM16;
AXSetVoiceOffsets(ax->voice_l, &offsets);
offsets.data = ax->buffer_r;
AXSetVoiceOffsets(ax->voice_r, &offsets);
AXSetVoiceSrcType(ax->voice_l, AX_VOICE_SRC_TYPE_NONE);
AXSetVoiceSrcType(ax->voice_r, AX_VOICE_SRC_TYPE_NONE);
AXSetVoiceSrcRatio(ax->voice_l, 1.0f);
AXSetVoiceSrcRatio(ax->voice_r, 1.0f);
AXVoiceVeData ve = {0x4000, 0};
AXVoiceVeData ve = {0x8000, 0};
AXSetVoiceVe(ax->voice_l, &ve);
AXSetVoiceVe(ax->voice_r, &ve);
u32 mix[24]= {0};
u32 mix[24] = {0};
mix[0] = 0x80000000;
AXSetVoiceDeviceMix(ax->voice_l, AX_DEVICE_TYPE_DRC, 0, (AXVoiceDeviceMixData*)mix);
AXSetVoiceDeviceMix(ax->voice_l, AX_DEVICE_TYPE_TV, 0, (AXVoiceDeviceMixData*)mix);
@ -136,16 +129,15 @@ static void* ax_audio_init(const char* device, unsigned rate, unsigned latency)
AXSetVoiceDeviceMix(ax->voice_r, AX_DEVICE_TYPE_DRC, 0, (AXVoiceDeviceMixData*)mix);
AXSetVoiceDeviceMix(ax->voice_r, AX_DEVICE_TYPE_TV, 0, (AXVoiceDeviceMixData*)mix);
AXSetVoiceState(ax->voice_l, AX_VOICE_STATE_PLAYING);
AXSetVoiceState(ax->voice_r, AX_VOICE_STATE_PLAYING);
AXSetVoiceState(ax->voice_l, AX_VOICE_STATE_STOPPED);
AXSetVoiceState(ax->voice_r, AX_VOICE_STATE_STOPPED);
ax->pos = 0;
ax->playpos = 0;
ax->playing = true;
ax->cpu_ticks_last = OSGetSystemTick();
config_get_ptr()->audio.out_rate = AX_AUDIO_RATE;
AXRegisterAuxCallback(AX_DEVICE_TYPE_DRC, 0, 0, (AXAuxCallback)ax_aux_callback, ax);
return ax;
}
@ -153,58 +145,95 @@ static void ax_audio_free(void* data)
{
ax_audio_t* ax = (ax_audio_t*)data;
free(ax->buffer_l);
free(ax->buffer_r);
AXRegisterAuxCallback(AX_DEVICE_TYPE_DRC, 0, 0, NULL, NULL);
MEM1_free(ax->buffer_l);
MEM1_free(ax->buffer_r);
free(ax);
AXQuit();
}
static void ax_audio_buffer_write(ax_audio_t* ax, const uint16_t* src, int count)
{
uint16_t* dst_l = ax->buffer_l + ax->pos;
uint16_t* dst_r = ax->buffer_r + ax->pos;
uint16_t* dst_l_max = ax->buffer_l + AX_AUDIO_COUNT;
while(count-- && (dst_l < dst_l_max))
{
*dst_l++ = *src++;
*dst_r++ = *src++;
}
DCFlushRange(ax->buffer_l + ax->pos, (dst_l - ax->pos - ax->buffer_l) << 1);
DCFlushRange(ax->buffer_r + ax->pos, (dst_r - ax->pos - ax->buffer_r) << 1);
if(++count)
{
dst_l = ax->buffer_l;
dst_r = ax->buffer_r;
while(count-- && (dst_l < dst_l_max))
{
*dst_l++ = *src++;
*dst_r++ = *src++;
}
DCFlushRange(ax->buffer_l, (dst_l - ax->buffer_l) << 1);
DCFlushRange(ax->buffer_r, (dst_r - ax->buffer_r) << 1);
}
ax->pos = dst_l - ax->buffer_l;
ax->pos &= AX_AUDIO_COUNT_MASK;
}
static ssize_t ax_audio_write(void* data, const void* buf, size_t size)
{
int i;
static struct retro_perf_counter ax_audio_write_perf = {0};
ax_audio_t* ax = (ax_audio_t*)data;
const uint16_t* src = buf;
uint32_t samples_played = 0;
uint64_t current_tick = 0;
int i;
performance_counter_init(&ax_audio_write_perf, "ax_audio_write");
performance_counter_start(&ax_audio_write_perf);
ax_audio_update_playpos(ax);
int count = size >> 2;
AXVoiceOffsets offsets;
AXGetVoiceOffsets(ax->voice_l, &offsets);
if ((((ax->playpos - ax->pos) & AX_AUDIO_COUNT_MASK) < (AX_AUDIO_COUNT >> 2)) ||
(((ax->pos - ax->playpos) & AX_AUDIO_COUNT_MASK) < (AX_AUDIO_COUNT >> 4)) ||
(((ax->playpos - ax->pos) & AX_AUDIO_COUNT_MASK) < (size >> 2)))
if((((offsets.currentOffset - ax->pos) & AX_AUDIO_COUNT_MASK) < (AX_AUDIO_COUNT >> 2)) ||
(((ax->pos - offsets.currentOffset ) & AX_AUDIO_COUNT_MASK) < (AX_AUDIO_COUNT >> 4)) ||
(((offsets.currentOffset - ax->pos) & AX_AUDIO_COUNT_MASK) < (size >> 2)))
{
if (ax->nonblocking)
ax->pos = (ax->playpos + (AX_AUDIO_COUNT >> 1)) & AX_AUDIO_COUNT_MASK;
ax->pos = (offsets.currentOffset + (AX_AUDIO_COUNT >> 1)) & AX_AUDIO_COUNT_MASK;
else
{
do
{
/* todo: compute the correct sleep period */
do{
retro_sleep(1);
ax_audio_update_playpos(ax);
}
while (((ax->playpos - ax->pos) & AX_AUDIO_COUNT_MASK) < (AX_AUDIO_COUNT >> 1)
|| (((ax->pos - ax->playpos) & AX_AUDIO_COUNT_MASK) < (AX_AUDIO_COUNT >> 4)));
AXGetVoiceOffsets(ax->voice_l, &offsets);
}while(AXIsVoiceRunning(ax->voice_l) &&
(((offsets.currentOffset - ax->pos) & AX_AUDIO_COUNT_MASK) < (AX_AUDIO_COUNT >> 1) ||
(((ax->pos - offsets.currentOffset) & AX_AUDIO_COUNT_MASK) < (AX_AUDIO_COUNT >> 4))));
}
}
uint16_t* dst_l = (uint16_t*)ax->buffer_l;
// ax_audio_buffer_write(ax, buf, count);
for (i = 0; i < (size >> 1); i += 2)
{
// ax->l[ax->pos] = src[i];
// ax->r[ax->pos] = src[i + 1];
ax->buffer_l[ax->pos] = (src[i]);
ax->buffer_r[ax->pos] = (src[i + 1]);
ax->buffer_l[ax->pos] = src[i];
ax->buffer_r[ax->pos] = src[i + 1];
ax->pos++;
ax->pos &= AX_AUDIO_COUNT_MASK;
}
DCFlushRange(ax->buffer_l, AX_AUDIO_SIZE);
DCFlushRange(ax->buffer_r, AX_AUDIO_SIZE);
// if(!AXIsVoiceRunning(ax->voice_l) && (((ax->pos - offsets.currentOffset) & AX_AUDIO_COUNT_MASK) > AX_AUDIO_FRAME_COUNT))
// {
AXSetVoiceState(ax->voice_l, AX_VOICE_STATE_PLAYING);
AXSetVoiceState(ax->voice_r, AX_VOICE_STATE_PLAYING);
// }
performance_counter_stop(&ax_audio_write_perf);
@ -215,23 +244,15 @@ static bool ax_audio_stop(void* data)
{
ax_audio_t* ax = (ax_audio_t*)data;
/* TODO */
if(ax->playing)
{
// AXSetVoiceVeDelta(ax->voice, -128);
AXVoiceVeData ve = {0};
AXSetVoiceVe(ax->voice_l, &ve);
AXSetVoiceVe(ax->voice_r, &ve);
ax->playing = false;
}
AXSetVoiceState(ax->voice_l, AX_VOICE_STATE_STOPPED);
AXSetVoiceState(ax->voice_r, AX_VOICE_STATE_STOPPED);
return true;
}
static bool ax_audio_alive(void* data)
{
ax_audio_t* ax = (ax_audio_t*)data;
return ax->playing;
return AXIsVoiceRunning(ax->voice_l);
}
static bool ax_audio_start(void* data)
@ -244,17 +265,8 @@ static bool ax_audio_start(void* data)
if (runloop_ctl(RUNLOOP_CTL_IS_SHUTDOWN, NULL))
return true;
/* TODO */
if(!ax->playing)
{
AXVoiceVeData ve = {0x4000, 0};
AXSetVoiceVe(ax->voice_l, &ve);
AXSetVoiceVe(ax->voice_r, &ve);
// AXSetVoiceVeDelta(ax->voice, 128);
ax->playing = true;
}
AXSetVoiceState(ax->voice_l, AX_VOICE_STATE_PLAYING);
AXSetVoiceState(ax->voice_r, AX_VOICE_STATE_PLAYING);
return true;
}
@ -263,9 +275,8 @@ static void ax_audio_set_nonblock_state(void* data, bool state)
{
ax_audio_t* ax = (ax_audio_t*)data;
// if (ax)
// ax->nonblocking = state;
ax->nonblocking = true;
if (ax)
ax->nonblocking = state;
}
static bool ax_audio_use_float(void* data)
@ -278,8 +289,10 @@ static size_t ax_audio_write_avail(void* data)
{
ax_audio_t* ax = (ax_audio_t*)data;
ax_audio_update_playpos(ax);
return (ax->playpos - ax->pos) & AX_AUDIO_COUNT_MASK;
AXVoiceOffsets offsets;
AXGetVoiceOffsets(ax->voice_l, &offsets);
return (offsets.currentOffset - ax->pos) & AX_AUDIO_COUNT_MASK;
}
static size_t ax_audio_buffer_size(void* data)
@ -302,6 +315,6 @@ audio_driver_t audio_ax =
"AX",
NULL,
NULL,
ax_audio_write_avail,
ax_audio_buffer_size
// ax_audio_write_avail,
// ax_audio_buffer_size
};

View File

@ -24,7 +24,13 @@
#endif
.align 4
.globl resampler_CC_downsample_neon
#ifndef __MACH__
.type resampler_CC_downsample_neon, %function
#endif
.globl _resampler_CC_downsample_neon
#ifndef __MACH__
.type _resampler_CC_downsample_neon, %function
#endif
# size_t resampler_CC_downsample_neon(float *outp, const float *inp,
# rarch_CC_resampler_t* re_, size_t input_frames, float ratio);
@ -196,7 +202,13 @@ bx lr
.align 4
.globl resampler_CC_upsample_neon
#ifndef __MACH__
.type resampler_CC_upsample_neon, %function
#endif
.globl _resampler_CC_upsample_neon
#ifndef __MACH__
.type _resampler_CC_upsample_neon, %function
#endif
# size_t resampler_CC_upsample_neon(float *outp, const float *inp,
# rarch_CC_resampler_t* re_, size_t input_frames, float ratio);

View File

@ -19,7 +19,13 @@
#endif
.align 4
.globl process_sinc_neon_asm
#ifndef __MACH__
.type process_sinc_neon_asm, %function
#endif
.globl _process_sinc_neon_asm
#ifndef __MACH__
.type _process_sinc_neon_asm, %function
#endif
# void process_sinc_neon(float *out, const float *left, const float *right, const float *coeff, unsigned taps)
# Assumes taps is >= 8, and a multiple of 8.
process_sinc_neon_asm:

428
cheevos.c
View File

@ -58,20 +58,25 @@
/* Define this macro to get extra-verbose log for cheevos. */
#undef CHEEVOS_VERBOSE
#define JSON_KEY_GAMEID 0xb4960eecU
#define JSON_KEY_ACHIEVEMENTS 0x69749ae1U
#define JSON_KEY_ID 0x005973f2U
#define JSON_KEY_MEMADDR 0x1e76b53fU
#define JSON_KEY_TITLE 0x0e2a9a07U
#define JSON_KEY_DESCRIPTION 0xe61a1f69U
#define JSON_KEY_POINTS 0xca8fce22U
#define JSON_KEY_AUTHOR 0xa804edb8U
#define JSON_KEY_MODIFIED 0xdcea4fe6U
#define JSON_KEY_CREATED 0x3a84721dU
#define JSON_KEY_BADGENAME 0x887685d9U
#define JSON_KEY_CONSOLE_ID 0x071656e5U
#define JSON_KEY_TOKEN 0x0e2dbd26U
#define JSON_KEY_FLAGS 0x0d2e96b2U
/* Define this macro to load a JSON file from disk instead of downloading
* from retroachievements.org. */
#undef CHEEVOS_JSON_OVERRIDE
/* C89 wants only int values in enums. */
#define CHEEVOS_JSON_KEY_GAMEID 0xb4960eecU
#define CHEEVOS_JSON_KEY_ACHIEVEMENTS 0x69749ae1U
#define CHEEVOS_JSON_KEY_ID 0x005973f2U
#define CHEEVOS_JSON_KEY_MEMADDR 0x1e76b53fU
#define CHEEVOS_JSON_KEY_TITLE 0x0e2a9a07U
#define CHEEVOS_JSON_KEY_DESCRIPTION 0xe61a1f69U
#define CHEEVOS_JSON_KEY_POINTS 0xca8fce22U
#define CHEEVOS_JSON_KEY_AUTHOR 0xa804edb8U
#define CHEEVOS_JSON_KEY_MODIFIED 0xdcea4fe6U
#define CHEEVOS_JSON_KEY_CREATED 0x3a84721dU
#define CHEEVOS_JSON_KEY_BADGENAME 0x887685d9U
#define CHEEVOS_JSON_KEY_CONSOLE_ID 0x071656e5U
#define CHEEVOS_JSON_KEY_TOKEN 0x0e2dbd26U
#define CHEEVOS_JSON_KEY_FLAGS 0x0d2e96b2U
enum
{
@ -184,10 +189,14 @@ typedef struct
{
cheevos_cond_t *conds;
unsigned count;
const char* expression;
} cheevos_condset_t;
typedef struct
{
cheevos_condset_t *condsets;
unsigned count;
} cheevos_condition_t;
typedef struct
{
unsigned id;
@ -201,8 +210,7 @@ typedef struct
int last;
int modified;
cheevos_condset_t *condsets;
unsigned count;
cheevos_condition_t condition;
} cheevo_t;
typedef struct
@ -406,7 +414,7 @@ static void cheevos_log_cheevo(const cheevo_t* cheevo,
RARCH_LOG("CHEEVOS author: %s\n", cheevo->author);
RARCH_LOG("CHEEVOS badge: %s\n", cheevo->badge);
RARCH_LOG("CHEEVOS points: %u\n", cheevo->points);
RARCH_LOG("CHEEVOS sets: %u\n", cheevo->count);
RARCH_LOG("CHEEVOS sets: TBD\n");
RARCH_LOG("CHEEVOS memaddr: %s\n", memaddr);
}
@ -458,16 +466,36 @@ static void cheevos_add_var_size(char** aux, size_t* left,
}
}
static void cheevos_post_log_cheevo(const cheevo_t* cheevo)
static void cheevos_add_var(const cheevos_var_t* var, char** memaddr,
size_t *left)
{
if ( var->type == CHEEVOS_VAR_TYPE_ADDRESS
|| var->type == CHEEVOS_VAR_TYPE_DELTA_MEM)
{
if (var->type == CHEEVOS_VAR_TYPE_DELTA_MEM)
cheevos_add_char(memaddr, left, 'd');
cheevos_add_string(memaddr, left, "0x");
cheevos_add_var_size(memaddr, left, var);
cheevos_add_hex(memaddr, left, var->value);
}
else if (var->type == CHEEVOS_VAR_TYPE_VALUE_COMP)
{
cheevos_add_uint(memaddr, left, var->value);
}
}
static void cheevos_build_memaddr(const cheevos_condition_t* condition,
char* memaddr, size_t left)
{
char memaddr[256];
char *aux = memaddr;
size_t left = sizeof(memaddr);
const cheevos_condset_t* condset;
const cheevos_cond_t* cond;
size_t i, j;
for (i = 0, condset = cheevo->condsets; i < cheevo->count; i++, condset++)
left--; /* reserve one char for the null terminator */
for (i = 0, condset = condition->condsets; i < condition->count; i++, condset++)
{
if (i != 0)
cheevos_add_char(&aux, &left, 'S');
@ -482,20 +510,7 @@ static void cheevos_post_log_cheevo(const cheevo_t* cheevo)
else if (cond->type == CHEEVOS_COND_TYPE_PAUSE_IF)
cheevos_add_string(&aux, &left, "P:");
if ( cond->source.type == CHEEVOS_VAR_TYPE_ADDRESS
|| cond->source.type == CHEEVOS_VAR_TYPE_DELTA_MEM)
{
if (cond->source.type == CHEEVOS_VAR_TYPE_DELTA_MEM)
cheevos_add_char(&aux, &left, 'd');
cheevos_add_string(&aux, &left, "0x");
cheevos_add_var_size(&aux, &left, &cond->source);
cheevos_add_hex(&aux, &left, cond->source.value);
}
else if (cond->source.type == CHEEVOS_VAR_TYPE_VALUE_COMP)
{
cheevos_add_uint(&aux, &left, cond->source.value);
}
cheevos_add_var(&cond->source, &aux, &left);
switch (cond->op)
{
@ -519,20 +534,7 @@ static void cheevos_post_log_cheevo(const cheevo_t* cheevo)
break;
}
if ( cond->target.type == CHEEVOS_VAR_TYPE_ADDRESS
|| cond->target.type == CHEEVOS_VAR_TYPE_DELTA_MEM)
{
if (cond->target.type == CHEEVOS_VAR_TYPE_DELTA_MEM)
cheevos_add_char(&aux, &left, 'd');
cheevos_add_string(&aux, &left, "0x");
cheevos_add_var_size(&aux, &left, &cond->target);
cheevos_add_hex(&aux, &left, cond->target.value);
}
else if (cond->target.type == CHEEVOS_VAR_TYPE_VALUE_COMP)
{
cheevos_add_uint(&aux, &left, cond->target.value);
}
cheevos_add_var(&cond->target, &aux, &left);
if (cond->req_hits > 0)
{
@ -543,9 +545,13 @@ static void cheevos_post_log_cheevo(const cheevo_t* cheevo)
}
}
cheevos_add_char(&aux, &left, 0);
memaddr[sizeof(memaddr) - 1] = 0;
*aux = 0;
}
static void cheevos_post_log_cheevo(const cheevo_t* cheevo)
{
char memaddr[256];
cheevos_build_memaddr(&cheevo->condition, memaddr, sizeof(memaddr));
RARCH_LOG("CHEEVOS memaddr (computed): %s\n", memaddr);
}
#endif
@ -706,7 +712,7 @@ static int cheevos_count__json_key(void *userdata,
cheevos_countud_t* ud = (cheevos_countud_t*)userdata;
ud->field_hash = cheevos_djb2(name, length);
if (ud->field_hash == JSON_KEY_ACHIEVEMENTS)
if (ud->field_hash == CHEEVOS_JSON_KEY_ACHIEVEMENTS)
ud->in_cheevos = 1;
return 0;
@ -717,21 +723,14 @@ static int cheevos_count__json_number(void *userdata,
{
cheevos_countud_t* ud = (cheevos_countud_t*)userdata;
if (ud->in_cheevos && ud->field_hash == JSON_KEY_FLAGS)
if (ud->in_cheevos && ud->field_hash == CHEEVOS_JSON_KEY_FLAGS)
{
long flags = strtol(number, NULL, 10);
switch (flags)
{
case 3: /* Core achievements */
ud->core_count++;
break;
case 5: /* Unofficial achievements */
ud->unofficial_count++;
break;
default:
break;
}
if (flags == 3)
ud->core_count++; /* Core achievements */
else if (flags == 5)
ud->unofficial_count++; /* Unofficial achievements */
}
return 0;
@ -878,6 +877,29 @@ static unsigned cheevos_parse_operator(const char **memaddr)
return op;
}
static size_t cheevos_reduce(size_t addr, size_t mask)
{
while (mask)
{
size_t tmp = (mask - 1) & ~mask;
addr = (addr & tmp) | ((addr >> 1) & ~tmp);
mask = (mask & (mask - 1)) >> 1;
}
return addr;
}
static size_t cheevos_highest_bit(size_t n)
{
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
return n ^ (n >> 1);
}
void cheevos_parse_guest_addr(cheevos_var_t *var, unsigned value)
{
rarch_system_info_t *system;
@ -892,8 +914,8 @@ void cheevos_parse_guest_addr(cheevos_var_t *var, unsigned value)
if (system->mmaps.num_descriptors != 0)
{
const struct retro_memory_descriptor *desc = NULL;
const struct retro_memory_descriptor *end = NULL;
const rarch_memory_descriptor_t *desc = NULL;
const rarch_memory_descriptor_t *end = NULL;
switch (cheevos_locals.console_id)
{
@ -917,10 +939,17 @@ void cheevos_parse_guest_addr(cheevos_var_t *var, unsigned value)
for (; desc < end; desc++)
{
if ((var->value & desc->select) == desc->start)
if (((desc->core.start ^ var->value) & desc->core.select) == 0)
{
var->bank_id = desc - system->mmaps.descriptors;
var->value = var->value - desc->start + desc->offset;
var->value = cheevos_reduce(
(var->value - desc->core.start) & desc->disconnect_mask,
desc->core.disconnect);
if (var->value >= desc->core.len)
var->value -= cheevos_highest_bit(var->value);
var->value += desc->core.offset;
break;
}
}
@ -1118,9 +1147,52 @@ static void cheevos_parse_memaddr(cheevos_cond_t *cond, const char *memaddr, uns
memaddr++;
}
}
if (*memaddr != '"')
RARCH_LOG("CHEEVOS error parsing memaddr\n");
static int cheevos_parse_condition(cheevos_condition_t *condition, const char* memaddr)
{
condition->count = cheevos_count_cond_sets(memaddr);
if (condition->count)
{
unsigned set = 0;
cheevos_condset_t *condset = NULL;
cheevos_condset_t *conds = (cheevos_condset_t*)
calloc(condition->count, sizeof(cheevos_condset_t));
const cheevos_condset_t* end;
if (!conds)
return -1;
condition->condsets = conds;
end = condition->condsets + condition->count;
for (condset = condition->condsets; condset < end; condset++, set++)
{
condset->count =
cheevos_count_conds_in_set(memaddr, set);
condset->conds = NULL;
#ifdef CHEEVOS_VERBOSE
RARCH_LOG("CHEEVOS set %p (index=%u)\n", condset, set);
RARCH_LOG("CHEEVOS conds: %u\n", condset->count);
#endif
if (condset->count)
{
cheevos_cond_t *conds = (cheevos_cond_t*)
calloc(condset->count, sizeof(cheevos_cond_t));
if (!conds)
return -1;
condset->conds = conds;
cheevos_parse_memaddr(condset->conds, memaddr, set);
}
}
}
return 0;
}
/*****************************************************************************
@ -1163,51 +1235,12 @@ static int cheevos_new_cheevo(cheevos_readud_t *ud)
if (!cheevo->title || !cheevo->description || !cheevo->author || !cheevo->badge)
goto error;
cheevo->count = cheevos_count_cond_sets(ud->memaddr.string);
#ifdef CHEEVOS_VERBOSE
cheevos_log_cheevo(cheevo, &ud->memaddr);
#endif
if (cheevo->count)
{
unsigned set = 0;
cheevos_condset_t *condset = NULL;
cheevos_condset_t *conds = (cheevos_condset_t*)
calloc(cheevo->count, sizeof(cheevos_condset_t));
const cheevos_condset_t* end;
if (!conds)
return -1;
cheevo->condsets = conds;
end = cheevo->condsets + cheevo->count;
for (condset = cheevo->condsets; condset < end; condset++, set++)
{
condset->count =
cheevos_count_conds_in_set(ud->memaddr.string, set);
condset->conds = NULL;
#ifdef CHEEVOS_VERBOSE
RARCH_LOG("CHEEVOS set %p (index=%u)\n", condset, set);
RARCH_LOG("CHEEVOS conds: %u\n", condset->count);
#endif
if (condset->count)
{
cheevos_cond_t *conds = (cheevos_cond_t*)
calloc(condset->count, sizeof(cheevos_cond_t));
if (!conds)
return -1;
condset->conds = conds;
condset->expression = cheevos_dupstr(&ud->memaddr);
cheevos_parse_memaddr(condset->conds, ud->memaddr.string, set);
}
}
}
if (cheevos_parse_condition(&cheevo->condition, ud->memaddr.string))
goto error;
#ifdef CHEEVOS_VERBOSE
cheevos_post_log_cheevo(cheevo);
@ -1233,49 +1266,49 @@ static int cheevos_read__json_key( void *userdata,
switch (hash)
{
case JSON_KEY_ACHIEVEMENTS:
ud->in_cheevos = 1;
case CHEEVOS_JSON_KEY_ACHIEVEMENTS:
ud->in_cheevos = 1;
break;
case JSON_KEY_CONSOLE_ID:
case CHEEVOS_JSON_KEY_CONSOLE_ID:
ud->is_console_id = 1;
break;
case JSON_KEY_ID:
case CHEEVOS_JSON_KEY_ID:
if (ud->in_cheevos)
ud->field = &ud->id;
break;
case JSON_KEY_MEMADDR:
case CHEEVOS_JSON_KEY_MEMADDR:
if (ud->in_cheevos)
ud->field = &ud->memaddr;
break;
case JSON_KEY_TITLE:
case CHEEVOS_JSON_KEY_TITLE:
if (ud->in_cheevos)
ud->field = &ud->title;
break;
case JSON_KEY_DESCRIPTION:
case CHEEVOS_JSON_KEY_DESCRIPTION:
if (ud->in_cheevos)
ud->field = &ud->desc;
break;
case JSON_KEY_POINTS:
case CHEEVOS_JSON_KEY_POINTS:
if (ud->in_cheevos)
ud->field = &ud->points;
break;
case JSON_KEY_AUTHOR:
case CHEEVOS_JSON_KEY_AUTHOR:
if (ud->in_cheevos)
ud->field = &ud->author;
break;
case JSON_KEY_MODIFIED:
case CHEEVOS_JSON_KEY_MODIFIED:
if (ud->in_cheevos)
ud->field = &ud->modified;
break;
case JSON_KEY_CREATED:
case CHEEVOS_JSON_KEY_CREATED:
if (ud->in_cheevos)
ud->field = &ud->created;
break;
case JSON_KEY_BADGENAME:
case CHEEVOS_JSON_KEY_BADGENAME:
if (ud->in_cheevos)
ud->field = &ud->badge;
break;
case JSON_KEY_FLAGS:
case CHEEVOS_JSON_KEY_FLAGS:
if (ud->in_cheevos)
ud->field = &ud->flags;
break;
@ -1355,25 +1388,28 @@ static int cheevos_parse(const char *json)
};
unsigned core_count, unofficial_count;
int res;
cheevos_readud_t ud;
settings_t *settings = config_get_ptr();
settings_t *settings = config_get_ptr();
/* Just return OK if cheevos are disabled. */
if (!settings->cheevos.enable)
return 0;
/* Count the number of achievements in the JSON file. */
if (cheevos_count_cheevos(json, &core_count, &unofficial_count) != JSONSAX_OK)
res = cheevos_count_cheevos(json, &core_count, &unofficial_count);
if (res != JSONSAX_OK)
return -1;
/* Allocate the achievements. */
cheevos_locals.core.cheevos = (cheevo_t*)
malloc(core_count * sizeof(cheevo_t));
calloc(core_count, sizeof(cheevo_t));
cheevos_locals.core.count = core_count;
cheevos_locals.unofficial.cheevos = (cheevo_t*)
malloc(unofficial_count * sizeof(cheevo_t));
calloc(unofficial_count, sizeof(cheevo_t));
cheevos_locals.unofficial.count = unofficial_count;
if (!cheevos_locals.core.cheevos || !cheevos_locals.unofficial.cheevos)
@ -1385,11 +1421,6 @@ static int cheevos_parse(const char *json)
return -1;
}
memset((void*)cheevos_locals.core.cheevos,
0, core_count * sizeof(cheevo_t));
memset((void*)cheevos_locals.unofficial.cheevos,
0, unofficial_count * sizeof(cheevo_t));
/* Load the achievements. */
ud.in_cheevos = 0;
ud.is_console_id = 0;
@ -1420,7 +1451,7 @@ uint8_t *cheevos_get_memory(const cheevos_var_t *var)
runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system);
if (system->mmaps.num_descriptors != 0)
return (uint8_t *)system->mmaps.descriptors[var->bank_id].ptr + var->value;
return (uint8_t *)system->mmaps.descriptors[var->bank_id].core.ptr + var->value;
return (uint8_t *)cheevos_locals.meminfo[var->bank_id].data + var->value;
}
@ -1444,31 +1475,48 @@ static unsigned cheevos_get_var_value(cheevos_var_t *var)
{
live_val = memory[0];
if (var->size > CHEEVOS_VAR_SIZE_BIT_0
&& var->size <= CHEEVOS_VAR_SIZE_BIT_7)
live_val = (live_val &
(1 << (var->size - CHEEVOS_VAR_SIZE_BIT_0))) != 0;
else
switch (var->size)
{
switch (var->size)
{
case CHEEVOS_VAR_SIZE_NIBBLE_LOWER:
live_val &= 0x0f;
break;
case CHEEVOS_VAR_SIZE_NIBBLE_UPPER:
live_val = (live_val >> 4) & 0x0f;
break;
case CHEEVOS_VAR_SIZE_EIGHT_BITS:
break;
case CHEEVOS_VAR_SIZE_SIXTEEN_BITS:
live_val |= memory[1] << 8;
break;
case CHEEVOS_VAR_SIZE_THIRTYTWO_BITS:
live_val |= memory[1] << 8;
live_val |= memory[2] << 16;
live_val |= memory[3] << 24;
break;
}
case CHEEVOS_VAR_SIZE_BIT_0:
live_val &= 1;
break;
case CHEEVOS_VAR_SIZE_BIT_1:
live_val = (live_val >> 1) & 1;
break;
case CHEEVOS_VAR_SIZE_BIT_2:
live_val = (live_val >> 2) & 1;
break;
case CHEEVOS_VAR_SIZE_BIT_3:
live_val = (live_val >> 3) & 1;
break;
case CHEEVOS_VAR_SIZE_BIT_4:
live_val = (live_val >> 4) & 1;
break;
case CHEEVOS_VAR_SIZE_BIT_5:
live_val = (live_val >> 5) & 1;
break;
case CHEEVOS_VAR_SIZE_BIT_6:
live_val = (live_val >> 6) & 1;
break;
case CHEEVOS_VAR_SIZE_BIT_7:
live_val = (live_val >> 7) & 1;
break;
case CHEEVOS_VAR_SIZE_NIBBLE_LOWER:
live_val &= 0x0f;
break;
case CHEEVOS_VAR_SIZE_NIBBLE_UPPER:
live_val = (live_val >> 4) & 0x0f;
break;
case CHEEVOS_VAR_SIZE_EIGHT_BITS:
break;
case CHEEVOS_VAR_SIZE_SIXTEEN_BITS:
live_val |= memory[1] << 8;
break;
case CHEEVOS_VAR_SIZE_THIRTYTWO_BITS:
live_val |= memory[1] << 8;
live_val |= memory[2] << 16;
live_val |= memory[3] << 24;
break;
}
}
@ -1626,9 +1674,9 @@ static int cheevos_test_cheevo(cheevo_t *cheevo)
int dirty_conds = 0;
int reset_conds = 0;
int ret_val = 0;
int ret_val_sub_cond = cheevo->count == 1;
cheevos_condset_t *condset = cheevo->condsets;
const cheevos_condset_t *end = condset + cheevo->count;
int ret_val_sub_cond = cheevo->condition.count == 1;
cheevos_condset_t *condset = cheevo->condition.condsets;
const cheevos_condset_t *end = condset + cheevo->condition.count;
if (condset < end)
{
@ -1649,7 +1697,7 @@ static int cheevos_test_cheevo(cheevo_t *cheevo)
{
dirty = 0;
for (condset = cheevo->condsets; condset < end; condset++)
for (condset = cheevo->condition.condsets; condset < end; condset++)
dirty |= cheevos_reset_cond_set(condset, 0);
if (dirty)
@ -1733,12 +1781,12 @@ static int cheevos_login(retro_time_t *timeout)
request[sizeof(request) - 1] = 0;
#ifdef CHEEVOS_LOG_URLS
RARCH_LOG("CHEEVOS url to login: %s.\n", request);
RARCH_LOG("CHEEVOS url to login: %s\n", request);
#endif
if (!cheevos_http_get(&json, NULL, request, timeout))
{
res = cheevos_get_value(json, JSON_KEY_TOKEN,
res = cheevos_get_value(json, CHEEVOS_JSON_KEY_TOKEN,
cheevos_locals.token, sizeof(cheevos_locals.token));
free((void*)json);
@ -1770,7 +1818,7 @@ static void cheevos_make_unlock_url(const cheevo_t *cheevo, char* url, size_t ur
url[url_size - 1] = 0;
#ifdef CHEEVOS_LOG_URLS
RARCH_LOG("CHEEVOS url to award the cheevo: %s.\n", url);
RARCH_LOG("CHEEVOS url to award the cheevo: %s\n", url);
#endif
}
@ -1852,7 +1900,7 @@ static void cheevos_free_cheevo(const cheevo_t *cheevo)
free((void*)cheevo->description);
free((void*)cheevo->author);
free((void*)cheevo->badge);
cheevos_free_condset(cheevo->condsets);
cheevos_free_condset(cheevo->condition.condsets);
}
static void cheevos_free_cheevo_set(const cheevoset_t *set)
@ -1894,7 +1942,7 @@ static int cheevos_get_by_game_id(const char **json,
request[sizeof(request) - 1] = 0;
#ifdef CHEEVOS_LOG_URLS
RARCH_LOG("CHEEVOS url to get the list of cheevos: %s.\n", request);
RARCH_LOG("CHEEVOS url to get the list of cheevos: %s\n", request);
#endif
if (!cheevos_http_get(json, NULL, request, timeout))
@ -1939,12 +1987,12 @@ static unsigned cheevos_get_game_id(unsigned char *hash, retro_time_t *timeout)
request[sizeof(request) - 1] = 0;
#ifdef CHEEVOS_LOG_URLS
RARCH_LOG("CHEEVOS url to get the game's id: %s.\n", request);
RARCH_LOG("CHEEVOS url to get the game's id: %s\n", request);
#endif
if (!cheevos_http_get(&json, NULL, request, timeout))
{
res = cheevos_get_value(json, JSON_KEY_GAMEID,
res = cheevos_get_value(json, CHEEVOS_JSON_KEY_GAMEID,
game_id, sizeof(game_id));
free((void*)json);
@ -1973,7 +2021,7 @@ static void cheevos_make_playing_url(unsigned game_id, char* url, size_t url_siz
url[url_size - 1] = 0;
#ifdef CHEEVOS_LOG_URLS
RARCH_LOG("CHEEVOS url to post the 'playing' activity: %s.\n", url);
RARCH_LOG("CHEEVOS url to post the 'playing' activity: %s\n", url);
#endif
}
@ -2100,7 +2148,7 @@ static int cheevos_deactivate_unlocks(unsigned game_id, retro_time_t *timeout)
request[sizeof(request) - 1] = 0;
#ifdef CHEEVOS_LOG_URLS
RARCH_LOG("CHEEVOS url to get the list of unlocked cheevos in softcore: %s.\n", request);
RARCH_LOG("CHEEVOS url to get the list of unlocked cheevos in softcore: %s\n", request);
#endif
if (!cheevos_http_get(&json, NULL, request, timeout))
@ -2129,7 +2177,7 @@ static int cheevos_deactivate_unlocks(unsigned game_id, retro_time_t *timeout)
request[sizeof(request) - 1] = 0;
#ifdef CHEEVOS_LOG_URLS
RARCH_LOG("CHEEVOS url to get the list of unlocked cheevos in hardcore: %s.\n", request);
RARCH_LOG("CHEEVOS url to get the list of unlocked cheevos in hardcore: %s\n", request);
#endif
if (!cheevos_http_get(&json, NULL, request, timeout))
@ -2457,6 +2505,17 @@ bool cheevos_load(const void *data)
cheevos_locals.meminfo[3].id = RETRO_MEMORY_RTC;
core_get_memory(&cheevos_locals.meminfo[3]);
#ifdef CHEEVOS_VERBOSE
RARCH_LOG("CHEEVOS system RAM: %p %u\n",
cheevos_locals.meminfo[0].data, cheevos_locals.meminfo[0].size);
RARCH_LOG("CHEEVOS save RAM: %p %u\n",
cheevos_locals.meminfo[1].data, cheevos_locals.meminfo[1].size);
RARCH_LOG("CHEEVOS video RAM: %p %u\n",
cheevos_locals.meminfo[2].data, cheevos_locals.meminfo[2].size);
RARCH_LOG("CHEEVOS RTC: %p %u\n",
cheevos_locals.meminfo[3].data, cheevos_locals.meminfo[3].size);
#endif
/* Bail out if cheevos are disabled.
* But set the above anyways, command_read_ram needs it. */
if (!settings->cheevos.enable)
@ -2525,7 +2584,24 @@ bool cheevos_load(const void *data)
return false;
found:
#ifdef CHEEVOS_JSON_OVERRIDE
{
FILE* file;
size_t size;
file = fopen(CHEEVOS_JSON_OVERRIDE, "rb");
fseek(file, 0, SEEK_END);
size = ftell(file);
fseek(file, 0, SEEK_SET);
json = (const char*)malloc(size);
fread((void*)json, 1, size, file);
fclose(file);
}
#else
if (!cheevos_get_by_game_id(&json, game_id, &timeout))
#endif
{
if (!cheevos_parse(json))
{
@ -2748,6 +2824,10 @@ bool cheevos_test(void)
if (settings->cheevos.test_unofficial)
cheevos_test_cheevo_set(&cheevos_locals.unofficial);
#if 0
cheevos_test_leaderboards();
#endif
}
return true;

14
core.h
View File

@ -43,6 +43,18 @@ enum
POLL_TYPE_LATE
};
typedef struct rarch_memory_descriptor
{
struct retro_memory_descriptor core;
size_t disconnect_mask;
} rarch_memory_descriptor_t;
typedef struct rarch_memory_map
{
rarch_memory_descriptor_t *descriptors;
unsigned num_descriptors;
} rarch_memory_map_t;
typedef struct rarch_system_info
{
struct retro_system_info info;
@ -68,7 +80,7 @@ typedef struct rarch_system_info
unsigned size;
} ports;
struct retro_memory_map mmaps;
rarch_memory_map_t mmaps;
} rarch_system_info_t;
typedef struct retro_ctx_input_state_info

View File

@ -778,52 +778,51 @@ static size_t mmap_highest_bit(size_t n)
return n ^ (n >> 1);
}
static bool mmap_preprocess_descriptors(struct retro_memory_descriptor *first, unsigned count)
static bool mmap_preprocess_descriptors(rarch_memory_descriptor_t *first, unsigned count)
{
size_t disconnect_mask;
size_t top_addr = 1;
struct retro_memory_descriptor *desc = NULL;
const struct retro_memory_descriptor *end = first + count;
size_t top_addr = 1;
rarch_memory_descriptor_t *desc = NULL;
const rarch_memory_descriptor_t *end = first + count;
for (desc = first; desc < end; desc++)
{
if (desc->select != 0)
top_addr |= desc->select;
if (desc->core.select != 0)
top_addr |= desc->core.select;
else
top_addr |= desc->start + desc->len - 1;
top_addr |= desc->core.start + desc->core.len - 1;
}
top_addr = mmap_add_bits_down(top_addr);
for (desc = first; desc < end; desc++)
{
if (desc->select == 0)
if (desc->core.select == 0)
{
if (desc->len == 0)
if (desc->core.len == 0)
return false;
if ((desc->len & (desc->len - 1)) != 0)
if ((desc->core.len & (desc->core.len - 1)) != 0)
return false;
desc->select = top_addr & ~mmap_inflate(mmap_add_bits_down(desc->len - 1), desc->disconnect);
desc->core.select = top_addr & ~mmap_inflate(mmap_add_bits_down(desc->core.len - 1), desc->core.disconnect);
}
if (desc->len == 0)
desc->len = mmap_add_bits_down(mmap_reduce(top_addr & ~desc->select, desc->disconnect)) + 1;
if (desc->core.len == 0)
desc->core.len = mmap_add_bits_down(mmap_reduce(top_addr & ~desc->core.select, desc->core.disconnect)) + 1;
if (desc->start & ~desc->select)
if (desc->core.start & ~desc->core.select)
return false;
while (mmap_reduce(top_addr & ~desc->select, desc->disconnect) >> 1 > desc->len - 1)
desc->disconnect |= mmap_highest_bit(top_addr & ~desc->select & ~desc->disconnect);
while (mmap_reduce(top_addr & ~desc->core.select, desc->core.disconnect) >> 1 > desc->core.len - 1)
desc->core.disconnect |= mmap_highest_bit(top_addr & ~desc->core.select & ~desc->core.disconnect);
disconnect_mask = mmap_add_bits_down(desc->len - 1);
desc->disconnect &= disconnect_mask;
desc->disconnect_mask = mmap_add_bits_down(desc->core.len - 1);
desc->core.disconnect &= desc->disconnect_mask;
while ((~disconnect_mask) >> 1 & desc->disconnect)
while ((~desc->disconnect_mask) >> 1 & desc->core.disconnect)
{
disconnect_mask >>= 1;
desc->disconnect &= disconnect_mask;
desc->disconnect_mask >>= 1;
desc->core.disconnect &= desc->disconnect_mask;
}
}
@ -1486,22 +1485,24 @@ bool rarch_environment_cb(unsigned cmd, void *data)
unsigned i;
const struct retro_memory_map *mmaps =
(const struct retro_memory_map*)data;
struct retro_memory_descriptor *descriptors = NULL;
rarch_memory_descriptor_t *descriptors = NULL;
RARCH_LOG("Environ SET_MEMORY_MAPS.\n");
free((void*)system->mmaps.descriptors);
system->mmaps.num_descriptors = 0;
descriptors = (struct retro_memory_descriptor*)
descriptors = (rarch_memory_descriptor_t*)
calloc(mmaps->num_descriptors,
sizeof(*system->mmaps.descriptors));
sizeof(*descriptors));
if (!descriptors)
return false;
system->mmaps.descriptors = descriptors;
memcpy((void*)system->mmaps.descriptors, mmaps->descriptors,
mmaps->num_descriptors * sizeof(*system->mmaps.descriptors));
system->mmaps.num_descriptors = mmaps->num_descriptors;
for (i = 0; i < mmaps->num_descriptors; i++)
system->mmaps.descriptors[i].core = mmaps->descriptors[i];
mmap_preprocess_descriptors(descriptors, mmaps->num_descriptors);
if (sizeof(void *) == 8)
@ -1511,38 +1512,38 @@ bool rarch_environment_cb(unsigned cmd, void *data)
for (i = 0; i < system->mmaps.num_descriptors; i++)
{
const struct retro_memory_descriptor *desc =
const rarch_memory_descriptor_t *desc =
&system->mmaps.descriptors[i];
char flags[7];
flags[0] = 'M';
if ((desc->flags & RETRO_MEMDESC_MINSIZE_8) == RETRO_MEMDESC_MINSIZE_8)
if ((desc->core.flags & RETRO_MEMDESC_MINSIZE_8) == RETRO_MEMDESC_MINSIZE_8)
flags[1] = '8';
else if ((desc->flags & RETRO_MEMDESC_MINSIZE_4) == RETRO_MEMDESC_MINSIZE_4)
else if ((desc->core.flags & RETRO_MEMDESC_MINSIZE_4) == RETRO_MEMDESC_MINSIZE_4)
flags[1] = '4';
else if ((desc->flags & RETRO_MEMDESC_MINSIZE_2) == RETRO_MEMDESC_MINSIZE_2)
else if ((desc->core.flags & RETRO_MEMDESC_MINSIZE_2) == RETRO_MEMDESC_MINSIZE_2)
flags[1] = '2';
else
flags[1] = '1';
flags[2] = 'A';
if ((desc->flags & RETRO_MEMDESC_ALIGN_8) == RETRO_MEMDESC_ALIGN_8)
if ((desc->core.flags & RETRO_MEMDESC_ALIGN_8) == RETRO_MEMDESC_ALIGN_8)
flags[3] = '8';
else if ((desc->flags & RETRO_MEMDESC_ALIGN_4) == RETRO_MEMDESC_ALIGN_4)
else if ((desc->core.flags & RETRO_MEMDESC_ALIGN_4) == RETRO_MEMDESC_ALIGN_4)
flags[3] = '4';
else if ((desc->flags & RETRO_MEMDESC_ALIGN_2) == RETRO_MEMDESC_ALIGN_2)
else if ((desc->core.flags & RETRO_MEMDESC_ALIGN_2) == RETRO_MEMDESC_ALIGN_2)
flags[3] = '2';
else
flags[3] = '1';
flags[4] = (desc->flags & RETRO_MEMDESC_BIGENDIAN) ? 'B' : 'b';
flags[5] = (desc->flags & RETRO_MEMDESC_CONST) ? 'C' : 'c';
flags[4] = (desc->core.flags & RETRO_MEMDESC_BIGENDIAN) ? 'B' : 'b';
flags[5] = (desc->core.flags & RETRO_MEMDESC_CONST) ? 'C' : 'c';
flags[6] = 0;
RARCH_LOG(" %03u %s %p %08X %08X %08X %08X %08X %s\n",
i + 1, flags, desc->ptr, desc->offset, desc->start,
desc->select, desc->disconnect, desc->len,
desc->addrspace ? desc->addrspace : "");
i + 1, flags, desc->core.ptr, desc->core.offset, desc->core.start,
desc->core.select, desc->core.disconnect, desc->core.len,
desc->core.addrspace ? desc->core.addrspace : "");
}
}
else

View File

@ -45,8 +45,10 @@
#include "system/exception.h"
#include <sys/iosupport.h>
#include <coreinit/screen.h>
#include <coreinit/foreground.h>
#include <proc_ui/procui.h>
#include <vpad/input.h>
#include <sysapp/launch.h>
#include "wiiu_dbg.h"
@ -54,8 +56,11 @@
#include "../../menu/menu_driver.h"
#endif
//#define WIIU_SD_PATH "/vol/external01/"
#define WIIU_SD_PATH "sd:/"
static enum frontend_fork wiiu_fork_mode = FRONTEND_FORK_NONE;
static const char* elf_path_cst = "sd:/retroarch/retroarch.elf";
static const char* elf_path_cst = WIIU_SD_PATH "retroarch/retroarch.elf";
static void frontend_wiiu_get_environment_settings(int *argc, char *argv[],
void *args, void *params_data)
@ -134,7 +139,7 @@ static int frontend_wiiu_parse_drive_list(void *data)
return -1;
menu_entries_append_enum(list,
"sd:/", "", MSG_UNKNOWN, FILE_TYPE_DIRECTORY, 0, 0);
WIIU_SD_PATH, "", MSG_UNKNOWN, FILE_TYPE_DIRECTORY, 0, 0);
return 0;
}
@ -169,7 +174,7 @@ frontend_ctx_driver_t frontend_ctx_wiiu = {
static int log_socket = -1;
static volatile int log_lock = 0;
void log_init(const char * ipString)
void log_init(const char * ipString, int port)
{
log_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (log_socket < 0)
@ -178,7 +183,7 @@ void log_init(const char * ipString)
struct sockaddr_in connect_addr;
memset(&connect_addr, 0, sizeof(connect_addr));
connect_addr.sin_family = AF_INET;
connect_addr.sin_port = 4405;
connect_addr.sin_port = port;
inet_aton(ipString, &connect_addr.sin_addr);
if(connect(log_socket, (struct sockaddr*)&connect_addr, sizeof(connect_addr)) < 0)
@ -237,40 +242,46 @@ static devoptab_t dotab_stdout = {
NULL, // device close
log_write, // device write
NULL,
/* ... */
};
int __entry_menu(int argc, char **argv)
void SaveCallback()
{
InitFunctionPointers();
OSSavesDone_ReadyToRelease();
}
int main(int argc, char **argv)
{
#if 1
setup_os_exceptions();
#else
InstallExceptionHandler();
#endif
ProcUIInit(&SaveCallback);
socket_lib_init();
#if 0
log_init("10.42.0.1");
#endif
#if defined(PC_DEVELOPMENT_IP_ADDRESS) && defined(PC_DEVELOPMENT_TCP_PORT)
log_init(PC_DEVELOPMENT_IP_ADDRESS, PC_DEVELOPMENT_TCP_PORT);
devoptab_list[STD_OUT] = &dotab_stdout;
devoptab_list[STD_ERR] = &dotab_stdout;
memoryInitialize();
mount_sd_fat("sd");
#endif
VPADInit();
verbosity_enable();
DEBUG_VAR(argc);
DEBUG_STR(argv[0]);
DEBUG_STR(argv[1]);
fflush(stdout);
#if 0
int argc_ = 2;
// char* argv_[] = {"sd:/retroarch/retroarch.elf", "sd:/rom.nes", NULL};
char* argv_[] = {"sd:/retroarch/retroarch.elf", "sd:/rom.sfc", NULL};
// char* argv_[] = {WIIU_SD_PATH "retroarch/retroarch.elf", WIIU_SD_PATH "rom.nes", NULL};
char* argv_[] = {WIIU_SD_PATH "retroarch/retroarch.elf", WIIU_SD_PATH "rom.sfc", NULL};
rarch_main(argc_, argv_, NULL);
#else
rarch_main(argc, argv, NULL);
#endif
// int frames = 0;
do
{
unsigned sleep_ms = 0;
@ -278,20 +289,20 @@ int __entry_menu(int argc, char **argv)
if (ret == 1 && sleep_ms > 0)
retro_sleep(sleep_ms);
task_queue_ctl(TASK_QUEUE_CTL_CHECK, NULL);
task_queue_ctl(TASK_QUEUE_CTL_WAIT, NULL);
if (ret == -1)
break;
}while(1);
// }while(frames++ < 300);
main_exit(NULL);
unmount_sd_fat("sd");
memoryRelease();
fflush(stdout);
fflush(stderr);
log_deinit();
ProcUIShutdown();
#if defined(PC_DEVELOPMENT_IP_ADDRESS) && defined(PC_DEVELOPMENT_TCP_PORT)
log_deinit();
#endif
return 0;
}
@ -299,3 +310,41 @@ unsigned long _times_r(struct _reent *r, struct tms *tmsbuf)
{
return 0;
}
void __eabi()
{
}
void __init();
void __fini();
int __entry_menu(int argc, char **argv)
{
InitFunctionPointers();
memoryInitialize();
mount_sd_fat("sd");
__init();
int ret = main(argc, argv);
__fini();
unmount_sd_fat("sd");
memoryRelease();
return ret;
}
__attribute__((noreturn))
void _start(int argc, char **argv)
{
memoryInitialize();
mount_sd_fat("sd");
// __init();
int ret = main(argc, argv);
// __fini();
unmount_sd_fat("sd");
memoryRelease();
SYSRelaunchTitle(argc, argv);
exit(ret);
}

View File

@ -22,6 +22,7 @@
#include <coreinit/cache.h>
#include "gx2.h"
#include "system/memory.h"
#include "system/wiiu.h"
#include "tex_shader.h"
#include "wiiu_dbg.h"
@ -38,6 +39,8 @@
#define _1 0x05
#define GX2_COMP_SEL(c0, c1, c2, c3) (((c0) << 24) | ((c1) << 16) | ((c2) << 8) | (c3))
//#define GX2_CAN_ACCESS_DATA_SECTION
typedef struct
{
int width;
@ -86,9 +89,16 @@ typedef struct
void* cmd_buffer;
wiiu_render_mode_t render_mode;
video_viewport_t vp;
int frames;
bool noblock;
int syncframes;
OSTime last_vsync;
bool vsync;
bool rgb32;
bool smooth;
unsigned rotation;
bool keep_aspect;
bool should_resize;
} wiiu_video_t;
static const wiiu_render_mode_t wiiu_render_mode_map[] =
@ -105,15 +115,14 @@ static const wiiu_render_mode_t wiiu_render_mode_map[] =
static wiiu_set_position(position_t* position, GX2ColorBuffer* draw_buffer, float x0, float y0, float x1, float y1)
{
position[0].x = -1.0f;
position[0].y = -1.0f;
position[1].x = 1.0f;
position[1].y = -1.0f;
position[2].x = 1.0f;
position[2].y = 1.0f;
position[3].x = -1.0f;
position[3].y = 1.0f;
position[0].x = (2.0f * x0 / draw_buffer->surface.width) - 1.0f;
position[0].y = (2.0f * y0 / draw_buffer->surface.height) - 1.0f;
position[1].x = (2.0f * x1 / draw_buffer->surface.width) - 1.0f;;
position[1].y = (2.0f * y0 / draw_buffer->surface.height) - 1.0f;
position[2].x = (2.0f * x1 / draw_buffer->surface.width) - 1.0f;;
position[2].y = (2.0f * y1 / draw_buffer->surface.height) - 1.0f;
position[3].x = (2.0f * x0 / draw_buffer->surface.width) - 1.0f;;
position[3].y = (2.0f * y1 / draw_buffer->surface.height) - 1.0f;
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, position, 4 * sizeof(*position));
}
@ -131,6 +140,123 @@ static void wiiu_set_tex_coords(tex_coord_t* tex_coord, GX2Texture* texture, flo
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, tex_coord, 4 * sizeof(*tex_coord));
}
static void wiiu_gfx_update_viewport(wiiu_video_t* wiiu)
{
int x = 0;
int y = 0;
float width = wiiu->vp.full_width;
float height = wiiu->vp.full_height;
settings_t *settings = config_get_ptr();
float desired_aspect = video_driver_get_aspect_ratio();
if(wiiu->rotation & 0x1)
desired_aspect = 1.0 / desired_aspect;
if (settings->video.scale_integer)
{
video_viewport_get_scaled_integer(&wiiu->vp, wiiu->vp.full_width,
wiiu->vp.full_height, desired_aspect, wiiu->keep_aspect);
}
else if (wiiu->keep_aspect)
{
#if defined(HAVE_MENU)
if (settings->video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM)
{
struct video_viewport *custom = video_viewport_get_custom();
if (custom)
{
x = custom->x;
y = custom->y;
width = custom->width;
height = custom->height;
}
}
else
#endif
{
float delta;
float device_aspect = ((float)wiiu->vp.full_width) / wiiu->vp.full_height;
if (fabsf(device_aspect - desired_aspect) < 0.0001f)
{
/* If the aspect ratios of screen and desired aspect
* ratio are sufficiently equal (floating point stuff),
* assume they are actually equal.
*/
}
else if (device_aspect > desired_aspect)
{
delta = (desired_aspect / device_aspect - 1.0f)
/ 2.0f + 0.5f;
x = (int)roundf(width * (0.5f - delta));
width = (unsigned)roundf(2.0f * width * delta);
}
else
{
delta = (device_aspect / desired_aspect - 1.0f)
/ 2.0f + 0.5f;
y = (int)roundf(height * (0.5f - delta));
height = (unsigned)roundf(2.0f * height * delta);
}
}
wiiu->vp.x = x;
wiiu->vp.y = y;
wiiu->vp.width = width;
wiiu->vp.height = height;
}
else
{
wiiu->vp.x = wiiu->vp.y = 0;
wiiu->vp.width = width;
wiiu->vp.height = height;
}
float scale_w = wiiu->color_buffer.surface.width / 854.0;
float scale_h = wiiu->color_buffer.surface.height / 480.0;
wiiu_set_position(wiiu->position, &wiiu->color_buffer,
wiiu->vp.x * scale_w,
wiiu->vp.y * scale_h,
(wiiu->vp.x + wiiu->vp.width) * scale_w,
(wiiu->vp.y + wiiu->vp.height) * scale_h);
wiiu->should_resize = false;
DEBUG_LINE();
}
static void wiiu_gfx_set_aspect_ratio(void* data, unsigned aspect_ratio_idx)
{
wiiu_video_t *wiiu = (wiiu_video_t*)data;
switch (aspect_ratio_idx)
{
case ASPECT_RATIO_SQUARE:
video_driver_set_viewport_square_pixel();
break;
case ASPECT_RATIO_CORE:
video_driver_set_viewport_core();
break;
case ASPECT_RATIO_CONFIG:
video_driver_set_viewport_config();
break;
default:
break;
}
video_driver_set_aspect_ratio_value(aspectratio_lut[aspect_ratio_idx].value);
if(!wiiu)
return;
wiiu->keep_aspect = true;
wiiu->should_resize = true;
}
static void* wiiu_gfx_init(const video_info_t* video,
const input_driver_t** input, void** input_data)
@ -206,17 +332,17 @@ static void* wiiu_gfx_init(const video_info_t* video,
GX2SetScissor(0, 0, wiiu->color_buffer.surface.width, wiiu->color_buffer.surface.height);
GX2SetDepthOnlyControl(GX2_DISABLE, GX2_DISABLE, GX2_COMPARE_FUNC_ALWAYS);
GX2SetColorControl(GX2_LOGIC_OP_COPY, 1, GX2_DISABLE, GX2_ENABLE);
#if 0
GX2SetBlendControl(GX2_RENDER_TARGET_0, GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA,
GX2_BLEND_COMBINE_MODE_ADD,
#if 1
GX2SetBlendControl(GX2_RENDER_TARGET_0, GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA, GX2_BLEND_COMBINE_MODE_ADD,
GX2_ENABLE, GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA, GX2_BLEND_COMBINE_MODE_ADD);
#else
GX2SetBlendControl(GX2_RENDER_TARGET_0, GX2_BLEND_MODE_ONE, GX2_BLEND_MODE_ZERO, GX2_BLEND_COMBINE_MODE_ADD,
GX2_DISABLE, GX2_BLEND_MODE_ONE, GX2_BLEND_MODE_ZERO, GX2_BLEND_COMBINE_MODE_ADD);
#endif
GX2SetCullOnlyControl(GX2_FRONT_FACE_CCW, GX2_DISABLE, GX2_DISABLE);
GX2SetSwapInterval(1);
#ifdef GX2_CAN_ACCESS_DATA_SECTION
wiiu->shader = &tex_shader;
#else
/* init shader */
// wiiu->shader = MEM2_alloc(sizeof(*wiiu->shader), GX2_VERTEX_BUFFER_ALIGNMENT);
wiiu->shader = MEM2_alloc(sizeof(tex_shader), 0x1000);
@ -239,6 +365,7 @@ static void* wiiu_gfx_init(const video_info_t* video,
memcpy(wiiu->shader->ps.samplerVars, tex_shader.ps.samplerVars,
wiiu->shader->ps.samplerVarCount * sizeof(GX2SamplerVar));
#endif
wiiu->shader->fs.size = GX2CalcFetchShaderSizeEx(2, GX2_FETCH_SHADER_TESSELLATION_NONE, GX2_TESSELLATION_MODE_DISCRETE);
wiiu->shader->fs.program = MEM2_alloc(wiiu->shader->fs.size, GX2_SHADER_ALIGNMENT);
GX2InitFetchShaderEx(&wiiu->shader->fs, (uint8_t*)wiiu->shader->fs.program,
@ -246,7 +373,6 @@ static void* wiiu_gfx_init(const video_info_t* video,
(GX2AttribStream*)&wiiu->shader->attribute_stream,
GX2_FETCH_SHADER_TESSELLATION_NONE, GX2_TESSELLATION_MODE_DISCRETE);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_SHADER, wiiu->shader->fs.program, wiiu->shader->fs.size);
GX2SetVertexShader(&wiiu->shader->vs);
GX2SetPixelShader(&wiiu->shader->ps);
GX2SetFetchShader(&wiiu->shader->fs);
@ -272,10 +398,19 @@ static void* wiiu_gfx_init(const video_info_t* video,
wiiu->texture.surface.height = video->input_scale * RARCH_SCALE_BASE;
wiiu->texture.surface.depth = 1;
wiiu->texture.surface.dim = GX2_SURFACE_DIM_TEXTURE_2D;
wiiu->texture.surface.format = GX2_SURFACE_FORMAT_UNORM_R5_G6_B5;
wiiu->texture.surface.tileMode = GX2_TILE_MODE_LINEAR_ALIGNED;
wiiu->texture.viewNumSlices = 1;
wiiu->texture.compMap = GX2_COMP_SEL(_B, _G, _R, _1);
wiiu->rgb32 = video->rgb32;
if(wiiu->rgb32)
{
wiiu->texture.surface.format = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
wiiu->texture.compMap = GX2_COMP_SEL(_G, _B, _A, _1);
}
else
{
wiiu->texture.surface.format = GX2_SURFACE_FORMAT_UNORM_R5_G6_B5;
wiiu->texture.compMap = GX2_COMP_SEL(_B, _G, _R, _1);
}
GX2CalcSurfaceSizeAndAlignment(&wiiu->texture.surface);
GX2InitTextureRegs(&wiiu->texture);
@ -325,8 +460,19 @@ static void* wiiu_gfx_init(const video_info_t* video,
GX2SetTVEnable(GX2_ENABLE);
GX2SetDRCEnable(GX2_ENABLE);
wiiu->noblock = false;
wiiu->syncframes = 60;
wiiu->keep_aspect = true;
wiiu->should_resize = true;
wiiu->smooth = video->smooth;
wiiu->vsync = video->vsync;
GX2SetSwapInterval(!!video->vsync);
wiiu->vp.x = 0;
wiiu->vp.y = 0;
wiiu->vp.width = 854;
wiiu->vp.height = 480;
wiiu->vp.full_width = 854;
wiiu->vp.full_height = 480;
video_driver_set_size(&wiiu->vp.width, &wiiu->vp.height);
return wiiu;
}
@ -361,16 +507,17 @@ static void wiiu_gfx_free(void* data)
MEMBucket_free(wiiu->tv_scan_buffer);
MEMBucket_free(wiiu->drc_scan_buffer);
MEM2_free(wiiu->shader->fs.program);
#ifndef GX2_CAN_ACCESS_DATA_SECTION
MEM2_free(wiiu->shader->vs.program);
MEM2_free(wiiu->shader->vs.attribVars);
MEM2_free(wiiu->shader->ps.program);
MEM2_free(wiiu->shader->ps.samplerVars);
MEM2_free(wiiu->shader->fs.program);
MEM2_free(wiiu->shader);
#endif
MEM2_free(wiiu->position);
MEM2_free(wiiu->tex_coord);
MEM2_free(wiiu->menu.position);
@ -384,29 +531,67 @@ static bool wiiu_gfx_frame(void* data, const void* frame,
unsigned width, unsigned height, uint64_t frame_count,
unsigned pitch, const char* msg)
{
(void)frame;
(void)width;
(void)height;
(void)pitch;
(void)msg;
int i;
wiiu_video_t* wiiu = (wiiu_video_t*) data;
if(wiiu->menu.enable || wiiu->noblock == false)
wiiu->syncframes = 60;
else if(wiiu->syncframes > 0)
wiiu->syncframes--;
GX2ClearColor(&wiiu->color_buffer, 0.0f, 0.0f, 0.0f, 1.0f);
// GX2ClearColor(&wiiu->color_buffer, 0.0f, 0.3f, 0.8f, 1.0f);
/* can't call GX2ClearColor after GX2SetContextState for whatever reason */
GX2SetContextState(wiiu->ctx_state);
if (!width || !height)
{
GX2WaitForVsync();
return;
return true;
}
if(wiiu->vsync)
{
uint32_t swap_count;
uint32_t flip_count;
OSTime last_flip;
OSTime last_vsync;
GX2GetSwapStatus(&swap_count, &flip_count, &last_flip, &last_vsync);
if(wiiu->last_vsync >= last_vsync)
{
GX2WaitForVsync();
wiiu->last_vsync = last_vsync + ms_to_ticks(17);
}
else
wiiu->last_vsync = last_vsync;
}
GX2WaitForFlip();
static u32 lastTick , currentTick;
currentTick = OSGetSystemTick();
u32 diff = currentTick - lastTick;
static float fps;
static u32 frames;
frames++;
if(diff > wiiu_timer_clock)
{
fps = (float)frames * ((float) wiiu_timer_clock / (float) diff);
lastTick = currentTick;
frames = 0;
}
#if 0
static u32 last_frame_tick;
if (!(wiiu->menu.enable))
printf("\r frame time : %10.6f ms \n", (float)(currentTick - last_frame_tick) * 1000.0f / (float)wiiu_timer_clock);
last_frame_tick = currentTick;
#endif
printf("\rfps: %8.8f frames : %5i", fps, wiiu->frames++);
fflush(stdout);
if (wiiu->should_resize)
wiiu_gfx_update_viewport(wiiu);
GX2ClearColor(&wiiu->color_buffer, 0.0f, 0.0f, 0.0f, 1.0f);
/* can't call GX2ClearColor after GX2SetContextState for whatever reason */
GX2SetContextState(wiiu->ctx_state);
if(frame)
{
if (width > wiiu->texture.surface.width)
@ -417,19 +602,35 @@ static bool wiiu_gfx_frame(void* data, const void* frame,
wiiu->width = width;
wiiu->height = height;
const uint16_t* src = frame;
uint16_t* dst = (uint16_t*)wiiu->texture.surface.image;
for (i = 0; i < height; i++)
if(wiiu->rgb32)
{
// memcpy(dst, src, width * sizeof(uint16_t));
int j;
for(j = 0; j < width; j++)
dst[j] = __builtin_bswap16(src[j]);
dst += wiiu->texture.surface.pitch;
src += pitch / 2;
const uint32_t* src = frame;
uint32_t* dst = (uint32_t*)wiiu->texture.surface.image;
for (i = 0; i < height; i++)
{
int j;
for(j = 0; j < width; j++)
dst[j] = src[j];
dst += wiiu->texture.surface.pitch;
src += pitch / 4;
}
}
else
{
const uint16_t* src = frame;
uint16_t* dst = (uint16_t*)wiiu->texture.surface.image;
for (i = 0; i < height; i++)
{
int j;
for(j = 0; j < width; j++)
dst[j] = __builtin_bswap16(src[j]);
dst += wiiu->texture.surface.pitch;
src += pitch / 2;
}
}
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, wiiu->texture.surface.image,
wiiu->texture.surface.imageSize);
@ -440,7 +641,8 @@ static bool wiiu_gfx_frame(void* data, const void* frame,
GX2SetAttribBuffer(1, 4 * sizeof(*wiiu->tex_coord), sizeof(*wiiu->tex_coord), wiiu->tex_coord);
GX2SetPixelTexture(&wiiu->texture, wiiu->shader->sampler.location);
GX2SetPixelSampler(&wiiu->sampler_linear, wiiu->shader->sampler.location);
GX2SetPixelSampler(wiiu->smooth? &wiiu->sampler_linear : &wiiu->sampler_nearest,
wiiu->shader->sampler.location);
GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
@ -460,10 +662,6 @@ static bool wiiu_gfx_frame(void* data, const void* frame,
GX2SwapScanBuffers();
GX2Flush();
if(wiiu->syncframes)
GX2WaitForVsync();
printf("\rframe : %5i", wiiu->frames++);
fflush(stdout);
return true;
}
@ -475,7 +673,8 @@ static void wiiu_gfx_set_nonblock_state(void* data, bool toggle)
if (!wiiu)
return;
wiiu->noblock = toggle;
wiiu->vsync = !toggle;
GX2SetSwapInterval(!toggle); /* do we need this ? */
}
static bool wiiu_gfx_alive(void* data)
@ -516,15 +715,17 @@ static bool wiiu_gfx_set_shader(void* data,
static void wiiu_gfx_set_rotation(void* data,
unsigned rotation)
{
(void)data;
(void)rotation;
wiiu_video_t* wiiu = (wiiu_video_t*) data;
if(wiiu)
wiiu->rotation = rotation;
}
static void wiiu_gfx_viewport_info(void* data,
struct video_viewport* vp)
{
(void)data;
(void)vp;
wiiu_video_t* wiiu = (wiiu_video_t*) data;
if(wiiu)
*vp = wiiu->vp;
}
static bool wiiu_gfx_read_viewport(void* data, uint8_t* buffer)
@ -535,37 +736,34 @@ static bool wiiu_gfx_read_viewport(void* data, uint8_t* buffer)
return true;
}
static uintptr_t wiiu_load_texture(void* video_data, void* data,
static uintptr_t wiiu_gfx_load_texture(void* video_data, void* data,
bool threaded, enum texture_filter_type filter_type)
{
return 0;
}
static void wiiu_unload_texture(void* data, uintptr_t handle)
static void wiiu_gfx_unload_texture(void* data, uintptr_t handle)
{
}
static void wiiu_set_filtering(void* data, unsigned index, bool smooth)
static void wiiu_gfx_set_filtering(void* data, unsigned index, bool smooth)
{
wiiu_video_t* wiiu = (wiiu_video_t*) data;
if(wiiu)
wiiu->smooth = smooth;
}
static void wiiu_set_aspect_ratio(void* data, unsigned aspect_ratio_idx)
{
}
static void wiiu_apply_state_changes(void* data)
static void wiiu_gfx_apply_state_changes(void* data)
{
wiiu_video_t* wiiu = (wiiu_video_t*)data;
if (wiiu)
wiiu->should_resize = true;
}
static void wiiu_viewport_info(void* data, struct video_viewport* vp)
{
vp->full_width = 800;
vp->full_height = 480;
vp->width = 800;
vp->height = 480;
vp->x = 0;
vp->y = 0;
}
static void wiiu_set_texture_frame(void* data, const void* frame, bool rgb32,
static void wiiu_gfx_set_texture_frame(void* data, const void* frame, bool rgb32,
unsigned width, unsigned height, float alpha)
{
int i;
@ -603,15 +801,16 @@ static void wiiu_set_texture_frame(void* data, const void* frame, bool rgb32,
// wiiu_set_tex_coords(wiiu->menu.tex_coord, &wiiu->menu.texture, 0, 0, wiiu->menu.texture.surface.width, wiiu->menu.texture.surface.height);
}
static void wiiu_set_texture_enable(void* data, bool state, bool full_screen)
static void wiiu_gfx_set_texture_enable(void* data, bool state, bool full_screen)
{
(void) full_screen;
wiiu_video_t* wiiu = (wiiu_video_t*) data;
wiiu->menu.enable = state;
if(wiiu)
wiiu->menu.enable = state;
}
static void wiiu_set_osd_msg(void* data, const char* msg,
static void wiiu_gfx_set_osd_msg(void* data, const char* msg,
const struct font_params* params, void* font)
{
}
@ -620,21 +819,21 @@ static void wiiu_set_osd_msg(void* data, const char* msg,
static const video_poke_interface_t wiiu_poke_interface =
{
wiiu_load_texture,
wiiu_unload_texture,
wiiu_gfx_load_texture,
wiiu_gfx_unload_texture,
NULL,
wiiu_set_filtering,
wiiu_gfx_set_filtering,
NULL, /* get_video_output_size */
NULL, /* get_video_output_prev */
NULL, /* get_video_output_next */
NULL, /* get_current_framebuffer */
NULL,
wiiu_set_aspect_ratio,
wiiu_apply_state_changes,
wiiu_gfx_set_aspect_ratio,
wiiu_gfx_apply_state_changes,
#ifdef HAVE_MENU
wiiu_set_texture_frame,
wiiu_set_texture_enable,
wiiu_set_osd_msg,
wiiu_gfx_set_texture_frame,
wiiu_gfx_set_texture_enable,
wiiu_gfx_set_osd_msg,
#endif
NULL,
NULL,

View File

@ -125,9 +125,7 @@ static void create_gl_context(HWND hwnd, bool *quit)
hwr = video_driver_get_hw_context();
debug = hwr->debug_context;
#ifdef _WIN32
dll_handle = dylib_load("OpenGL32.dll");
#endif
g_hdc = GetDC(hwnd);
setup_pixel_format(g_hdc);
@ -591,9 +589,9 @@ static bool gfx_ctx_wgl_has_windowed(void *data)
static gfx_ctx_proc_t gfx_ctx_wgl_get_proc_address(const char *symbol)
{
#if defined(HAVE_OPENGL) || defined(HAVE_VULKAN)
void *func = (void *)wglGetProcAddress(symbol);
gfx_ctx_proc_t func = (gfx_ctx_proc_t)wglGetProcAddress(symbol);
if (func)
return (gfx_ctx_proc_t)wglGetProcAddress(symbol);
return func;
#endif
return (gfx_ctx_proc_t)GetProcAddress((HINSTANCE)dll_handle, symbol);
}

View File

@ -1354,17 +1354,26 @@ static bool gl_glsl_set_coords(void *handle_data, void *shader_data, const struc
if (!glsl || !glsl->shader->modern || !coords)
goto fallback;
attr = attribs;
uni = &glsl->uniforms[glsl->active_idx];
buffer = short_buffer;
if (coords->vertices > 4)
buffer = (GLfloat*)calloc(coords->vertices *
(2 + 2 + 4 + 2), sizeof(*buffer));
{
size_t elems = 0;
elems += (uni->color >= 0) * 4;
elems += (uni->tex_coord >= 0) * 2;
elems += (uni->vertex_coord >= 0) * 2;
elems += (uni->lut_tex_coord >= 0) * 2;
elems *= coords->vertices * sizeof(GLfloat);
buffer = (GLfloat*)malloc(elems);
}
if (!buffer)
goto fallback;
attr = attribs;
uni = &glsl->uniforms[glsl->active_idx];
if (uni->tex_coord >= 0)
gl_glsl_set_coord_array(attr, uni->tex_coord, coords->tex_coord, coords, size, 2);

View File

@ -129,6 +129,9 @@ static void wiiu_joypad_poll(void)
VPADReadError vpadError;
VPADRead(0, &vpad, 1, &vpadError);
if(vpadError)
return;
pad_state = 0;
pad_state |= (vpad.hold & VPAD_BUTTON_LEFT) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0;
pad_state |= (vpad.hold & VPAD_BUTTON_DOWN) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0;
@ -154,7 +157,8 @@ static void wiiu_joypad_poll(void)
BIT64_CLEAR(lifecycle_state, RARCH_MENU_TOGGLE);
if((vpad.tpNormal.touched) && (vpad.tpNormal.x > 200) && (vpad.tpNormal.validity) == 0)
if(((vpad.tpNormal.touched) && (vpad.tpNormal.x > 200) && (vpad.tpNormal.validity) == 0) ||
(vpad.trigger & VPAD_BUTTON_HOME))
BIT64_SET(lifecycle_state, RARCH_MENU_TOGGLE);
/* panic button */

View File

@ -3126,6 +3126,7 @@ const char *msg_hash_to_str_chs(enum msg_hash_enums msg)
case MENU_ENUM_LABEL_VALUE_CHEEVOS_DESCRIPTION:
return "描述";
case MENU_ENUM_LABEL_VALUE_CHEEVOS_HARDCORE_MODE_ENABLE:
/* FIXME? Translate 'Achievements Hardcore Mode' */
return "专家模式";
case MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ACHIEVEMENTS:
return "已解锁的成就:";
@ -3134,6 +3135,7 @@ const char *msg_hash_to_str_chs(enum msg_hash_enums msg)
case MENU_ENUM_LABEL_VALUE_CHEEVOS_SETTINGS:
return "Retro 成就";
case MENU_ENUM_LABEL_VALUE_CHEEVOS_TEST_UNOFFICIAL:
/* FIXME? Translate 'Test Unofficial Achievements' */
return "非官方测试";
case MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ACHIEVEMENTS:
return "未解锁的成就:";
@ -3268,12 +3270,14 @@ const char *msg_hash_to_str_chs(enum msg_hash_enums msg)
case MENU_ENUM_LABEL_VALUE_DRIVER_SETTINGS:
return "驱动";
case MENU_ENUM_LABEL_VALUE_DUMMY_ON_CORE_SHUTDOWN:
return "Dummy On Core Shutdown";
/* FIXME? Translate 'Load Dummy on Core Shutdown' */
return "Load Dummy on Core Shutdown";
case MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPER:
return "动态壁纸";
case MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPERS_DIRECTORY:
return "动态壁纸目录";
case MENU_ENUM_LABEL_VALUE_CHEEVOS_ENABLE:
/* FIXME? Translate 'Enable Achievements' */
return "启用";
case MENU_ENUM_LABEL_VALUE_ENTRY_HOVER_COLOR:
return "菜单项悬停颜色";

View File

@ -1272,10 +1272,11 @@ const char *msg_hash_to_str_es(enum msg_hash_enums msg)
case MENU_ENUM_LABEL_VALUE_CHEEVOS_DESCRIPTION:
return "Descripción";
case MENU_ENUM_LABEL_VALUE_CHEEVOS_HARDCORE_MODE_ENABLE:
return "Modo Extremo";
return "Logros Modo Extremo";
case MENU_ENUM_LABEL_VALUE_CHEEVOS_SETTINGS:
return "Retrologros";
case MENU_ENUM_LABEL_VALUE_CHEEVOS_TEST_UNOFFICIAL:
/* FIXME? Translate 'Test Unofficial Achievements' */
return "Probar versión no oficial";
case MENU_ENUM_LABEL_VALUE_CONTENT_SETTINGS:
return "Menú rápido";
@ -1697,6 +1698,7 @@ const char *msg_hash_to_str_es(enum msg_hash_enums msg)
case MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPERS_DIRECTORY:
return "Carpeta de fondos de pantalla dinámicos";
case MENU_ENUM_LABEL_VALUE_CHEEVOS_ENABLE:
/* FIXME? Translate 'Enable Achievements' */
return "Activar";
case MENU_ENUM_LABEL_VALUE_ENTRY_HOVER_COLOR:
return "Color de entrada resaltada del menú";

View File

@ -1146,12 +1146,14 @@ const char *msg_hash_to_str_it(enum msg_hash_enums msg)
case MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_TOGGLE_MENU:
return "Menù a comparsa";
case MENU_ENUM_LABEL_VALUE_CHEEVOS_HARDCORE_MODE_ENABLE:
/* FIXME? Translate 'Achievements Hardcore Mode' */
return "Modalità Hardcore";
case MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ACHIEVEMENTS:
return "Obiettivi bloccati:";
case MENU_ENUM_LABEL_VALUE_CHEEVOS_SETTINGS:
return "Retro Obiettivi";
case MENU_ENUM_LABEL_VALUE_CHEEVOS_TEST_UNOFFICIAL:
/* FIXME? Translate 'Test Unofficial Achievements' */
return "Prova non ufficiali";
case MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ACHIEVEMENTS:
return "Obiettivi sbloccati:";
@ -2127,6 +2129,7 @@ const char *msg_hash_to_str_it(enum msg_hash_enums msg)
case MENU_ENUM_LABEL_VALUE_USE_BUILTIN_IMAGE_VIEWER:
return "Usa visualizzatore di immagini interno";
case MENU_ENUM_LABEL_VALUE_CHEEVOS_ENABLE:
/* FIXME? Translate 'Enable Achievements' */
return "Attivare";
case MENU_ENUM_LABEL_VALUE_START_CORE:
return "Avvia Core";

View File

@ -892,7 +892,8 @@ const char *msg_hash_to_str_nl(enum msg_hash_enums msg)
case MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_AS:
return "Shader Preset Opslaan Als";
case MENU_ENUM_LABEL_VALUE_VIDEO_SHARED_CONTEXT:
return "HW Shared Context Activeren";
/* FIXME? Translate 'Enable Hardware Shared Context' */
return "Activeren Hardware Shared Context";
case MENU_ENUM_LABEL_VALUE_VIDEO_SMOOTH:
return "Hardware Bilinear Filtering";
case MENU_ENUM_LABEL_VALUE_VIDEO_SOFT_FILTER:

View File

@ -829,7 +829,7 @@ const char *msg_hash_to_str_pl(enum msg_hash_enums msg)
case MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_AS:
return "Zapisz preset shadera jako";
case MENU_ENUM_LABEL_VALUE_VIDEO_SHARED_CONTEXT:
return "HW Shared Context Enable";
return "Enable Hardware Shared Context";
case MENU_ENUM_LABEL_VALUE_VIDEO_SMOOTH:
return "Sprzętowe filtrowanie dwuliniowe";
case MENU_ENUM_LABEL_VALUE_VIDEO_SOFT_FILTER:

View File

@ -38,6 +38,10 @@ MSG_HASH(
MSG_WAITING_FOR_CLIENT,
"Waiting for client ..."
)
MSG_HASH(
MENU_ENUM_SUBLABEL_VIDEO_SHARED_CONTEXT,
"Give hardware-rendered cores their own private context. Avoids having to assume hardware state changes inbetween frames."
)
MSG_HASH(
MENU_ENUM_SUBLABEL_MENU_SETTINGS,
"Adjusts settings related to the appearance of the menu screen."
@ -341,7 +345,7 @@ MSG_HASH(
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_CHEEVOS_HARDCORE_MODE_ENABLE,
"Hardcore Mode"
"Achievements Hardcore Mode"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ACHIEVEMENTS,
@ -357,7 +361,7 @@ MSG_HASH(
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_CHEEVOS_TEST_UNOFFICIAL,
"Test unofficial"
"Test Unofficial Achievements"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ACHIEVEMENTS,
@ -451,7 +455,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_OPTIONS,
MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_SETTINGS,
"Core")
MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_SET_SUPPORTS_NO_CONTENT_ENABLE,
"Automatically start a core")
"Start a Core Automatically")
MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_SPECIFIC_CONFIG,
"Configuration Per-Core")
MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE,
@ -515,13 +519,13 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_DPI_OVERRIDE_VALUE,
MSG_HASH(MENU_ENUM_LABEL_VALUE_DRIVER_SETTINGS,
"Driver")
MSG_HASH(MENU_ENUM_LABEL_VALUE_DUMMY_ON_CORE_SHUTDOWN,
"Dummy On Core Shutdown")
"Load Dummy on Core Shutdown")
MSG_HASH(MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPER,
"Dynamic Wallpaper")
MSG_HASH(MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPERS_DIRECTORY,
"Dynamic Wallpapers Dir")
MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEEVOS_ENABLE,
"Enable")
"Enable Achievements")
MSG_HASH(MENU_ENUM_LABEL_VALUE_ENTRY_HOVER_COLOR,
"Menu entry hover color")
MSG_HASH(MENU_ENUM_LABEL_VALUE_ENTRY_NORMAL_COLOR,
@ -1511,7 +1515,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_CORE,
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_GAME,
"Save Game Preset")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHARED_CONTEXT,
"HW Shared Context Enable")
"Enable Hardware Shared Context")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SMOOTH,
"HW Bilinear Filtering")
MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SOFT_FILTER,
@ -1604,6 +1608,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_YES,
"Yes")
MSG_HASH(MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_TWO,
"Shader Preset")
MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_HARDCORE_MODE_ENABLE,
"Enable or disable savestates, cheats, rewind, fast-forward, pause, and slow-motion for all games.")
MSG_HASH(MENU_ENUM_SUBLABEL_CORE_SETTINGS,
"Change settings for the core.")
MSG_HASH(MENU_ENUM_SUBLABEL_ADD_CONTENT_LIST,
"Scan contents and add to the database.")
MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_SETTINGS,
@ -1628,6 +1636,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_LOG_VERBOSITY,
"Enable or disable logging to the terminal.")
MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY,
"Join or host a netplay session.")
MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION_LIST_LIST,
"Display information for core, network, and system.\nDisplay manager for database and cursor.")
MSG_HASH(MENU_ENUM_SUBLABEL_ONLINE_UPDATER,
"Download add-ons, components and contents for RetroArch.")
MSG_HASH(MENU_ENUM_SUBLABEL_SAMBA_ENABLE,

View File

@ -3240,7 +3240,8 @@ const char *msg_hash_to_str_vn(enum msg_hash_enums msg)
case MENU_ENUM_LABEL_VALUE_CORE_SETTINGS:
return "Core";
case MENU_ENUM_LABEL_VALUE_CORE_SET_SUPPORTS_NO_CONTENT_ENABLE:
return "Automatically start a core";
/* FIXME? Translate 'Start a Core Automatically' */
return "Start a Core Automatically";
case MENU_ENUM_LABEL_VALUE_CORE_SPECIFIC_CONFIG:
return "Configuration Per-Core";
case MENU_ENUM_LABEL_VALUE_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE:
@ -3304,7 +3305,8 @@ const char *msg_hash_to_str_vn(enum msg_hash_enums msg)
case MENU_ENUM_LABEL_VALUE_DRIVER_SETTINGS:
return "Driver";
case MENU_ENUM_LABEL_VALUE_DUMMY_ON_CORE_SHUTDOWN:
return "Dummy On Core Shutdown";
/* FIXME? Translate 'Load Dummy on Core Shutdown' */
return "Load Dummy on Core Shutdown";
case MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPER:
return "Dynamic Wallpaper";
case MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPERS_DIRECTORY:
@ -4296,7 +4298,8 @@ const char *msg_hash_to_str_vn(enum msg_hash_enums msg)
case MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_GAME:
return "Save Game Preset";
case MENU_ENUM_LABEL_VALUE_VIDEO_SHARED_CONTEXT:
return "HW Shared Context Enable";
/* FIXME? Translate 'Enable Hardware Shared Context' */
return "Enable Hardware Shared Context";
case MENU_ENUM_LABEL_VALUE_VIDEO_SMOOTH:
return "HW Bilinear Filtering";
case MENU_ENUM_LABEL_VALUE_VIDEO_SOFT_FILTER:

View File

@ -27,7 +27,13 @@
.align 4
.globl convert_float_s16_asm
#ifndef __MACH__
.type convert_float_s16_asm, %function
#endif
.globl _convert_float_s16_asm
#ifndef __MACH__
.type _convert_float_s16_asm, %function
#endif
# convert_float_s16_asm(int16_t *out, const float *in, size_t samples)
convert_float_s16_asm:
_convert_float_s16_asm:

View File

@ -27,7 +27,13 @@
.align 4
.globl convert_s16_float_asm
#ifndef __MACH__
.type convert_s16_float_asm, %function
#endif
.globl _convert_s16_float_asm
#ifndef __MACH__
.type _convert_s16_float_asm, %function
#endif
# convert_s16_float_asm(float *out, const int16_t *in, size_t samples, const float *gain)
convert_s16_float_asm:
_convert_s16_float_asm:

View File

@ -43,15 +43,17 @@ retro_perf_tick_t cpu_features_get_perf_counter(void);
/**
* cpu_features_get_time_usec:
*
* Gets time in microseconds. *
* Returns: time in microseconds.
* Gets time in microseconds, from an undefined epoch.
* The epoch may change between computers or across reboots.
*
* Returns: time in microseconds
**/
retro_time_t cpu_features_get_time_usec(void);
/**
* cpu_features_get:
*
* Gets CPU features..
* Gets CPU features.
*
* Returns: bitmask of all CPU features available.
**/

View File

@ -13,7 +13,7 @@
@ void* memcpy(void *destination, const void *source, size_t num)
.global memcpy_neon
.type memcpy_neon, %function
/*
* ENABLE_UNALIGNED_MEM_ACCESSES macro can be defined to permit the use
* of unaligned load/store memory accesses supported since ARMv6. This

View File

@ -82,6 +82,25 @@ size_t hack_shader_pass = 0;
char *core_buf;
size_t core_len;
#ifdef HAVE_LAKKA
static char lakka_project[128];
static char *lakka_get_project(void)
{
size_t len;
FILE *command_file = popen("cat /etc/release | cut -d - -f 1", "r");
fgets(lakka_project, sizeof(lakka_project), command_file);
len = strlen(lakka_project);
if (len > 0 && lakka_project[len-1] == '\n')
lakka_project[--len] = '\0';
pclose(command_file);
return lakka_project;
}
#endif
static void cb_net_generic_subdir(void *task_data, void *user_data, const char *err)
{
char subdir_path[PATH_MAX_LENGTH];
@ -2107,7 +2126,7 @@ static int generic_action_ok_network(const char *path,
/* TODO unhardcode this path */
fill_pathname_join(url_path,
file_path_str(FILE_PATH_LAKKA_URL),
LAKKA_PROJECT, sizeof(url_path));
lakka_get_project(), sizeof(url_path));
fill_pathname_join(url_path, url_path,
file_path_str(FILE_PATH_INDEX_URL),
sizeof(url_path));
@ -2376,7 +2395,7 @@ static int action_ok_download_generic(const char *path,
#ifdef HAVE_LAKKA
/* TODO unhardcode this path*/
fill_pathname_join(s, file_path_str(FILE_PATH_LAKKA_URL),
LAKKA_PROJECT, sizeof(s));
lakka_get_project(), sizeof(s));
#endif
break;
case MENU_ENUM_LABEL_CB_UPDATE_ASSETS:

View File

@ -40,6 +40,36 @@ static int action_bind_sublabel_generic(
return 0;
}
static int action_bind_sublabel_core_settings_list(
file_list_t *list,
unsigned type, unsigned i,
const char *label, const char *path,
char *s, size_t len)
{
strlcpy(s, msg_hash_to_str(MENU_ENUM_SUBLABEL_CORE_SETTINGS), len);
return 0;
}
static int action_bind_sublabel_information_list_list(
file_list_t *list,
unsigned type, unsigned i,
const char *label, const char *path,
char *s, size_t len)
{
strlcpy(s, msg_hash_to_str(MENU_ENUM_SUBLABEL_INFORMATION_LIST_LIST), len);
return 0;
}
static int action_bind_sublabel_cheevos_hardcore_mode_enable(
file_list_t *list,
unsigned type, unsigned i,
const char *label, const char *path,
char *s, size_t len)
{
strlcpy(s, msg_hash_to_str(MENU_ENUM_SUBLABEL_CHEEVOS_HARDCORE_MODE_ENABLE), len);
return 0;
}
static int action_bind_sublabel_menu_settings_list(
file_list_t *list,
unsigned type, unsigned i,
@ -364,6 +394,17 @@ static int action_bind_sublabel_config_save_on_exit(
return 0;
}
static int action_bind_sublabel_video_shared_context(
file_list_t *list,
unsigned type, unsigned i,
const char *label, const char *path,
char *s, size_t len)
{
strlcpy(s, msg_hash_to_str(MENU_ENUM_SUBLABEL_VIDEO_SHARED_CONTEXT), len);
return 0;
}
int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
const char *path, const char *label, unsigned type, size_t idx)
{
@ -376,10 +417,16 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
{
switch (cbs->enum_idx)
{
case MENU_ENUM_LABEL_VIDEO_SHARED_CONTEXT:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_shared_context);
break;
case MENU_ENUM_LABEL_CHEEVOS_UNLOCKED_ENTRY:
case MENU_ENUM_LABEL_CHEEVOS_LOCKED_ENTRY:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheevos_entry);
break;
case MENU_ENUM_LABEL_CHEEVOS_HARDCORE_MODE_ENABLE:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheevos_hardcore_mode_enable);
break;
case MENU_ENUM_LABEL_CONFIG_SAVE_ON_EXIT:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_config_save_on_exit);
break;
@ -440,6 +487,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_INPUT_USER_16_BINDS:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_user_bind_settings);
break;
case MENU_ENUM_LABEL_INFORMATION_LIST:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_information_list_list);
break;
case MENU_ENUM_LABEL_NETPLAY:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_netplay_settings);
break;
@ -461,6 +511,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_AUDIO_SETTINGS:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_audio_settings_list);
break;
case MENU_ENUM_LABEL_CORE_SETTINGS:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_core_settings_list);
break;
case MENU_ENUM_LABEL_INPUT_SETTINGS:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_settings_list);
break;

View File

@ -18,6 +18,7 @@
#include <stddef.h>
#include <compat/strl.h>
#include <compat/strcasestr.h>
#include <lists/file_list.h>
#include <lists/dir_list.h>
@ -2822,12 +2823,16 @@ static int menu_displaylist_parse_horizontal_content_actions(
static int menu_displaylist_parse_information_list(
menu_displaylist_info_t *info)
{
core_info_t *core_info = NULL;
menu_entries_append_enum(info->list,
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_INFORMATION),
msg_hash_to_str(MENU_ENUM_LABEL_CORE_INFORMATION),
MENU_ENUM_LABEL_CORE_INFORMATION,
MENU_SETTING_ACTION, 0, 0);
core_info_get_current_core(&core_info);
if (core_info && core_info->config_data)
menu_entries_append_enum(info->list,
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_INFORMATION),
msg_hash_to_str(MENU_ENUM_LABEL_CORE_INFORMATION),
MENU_ENUM_LABEL_CORE_INFORMATION,
MENU_SETTING_ACTION, 0, 0);
#ifdef HAVE_NETWORKING
#ifndef HAVE_SOCKET_LEGACY
@ -3290,10 +3295,7 @@ static int menu_displaylist_parse_playlists(
path = str_list->elems[i].data;
if (!strstr(path, file_path_str(FILE_PATH_LPL_EXTENSION)) ||
(strstr(path, file_path_str(FILE_PATH_CONTENT_HISTORY))) ||
(strstr(path, file_path_str(FILE_PATH_CONTENT_MUSIC_HISTORY))) ||
(strstr(path, file_path_str(FILE_PATH_CONTENT_VIDEO_HISTORY))) ||
(strstr(path, file_path_str(FILE_PATH_CONTENT_IMAGE_HISTORY))))
((strcasestr(path, "content") && strcasestr(path, "history"))))
continue;
file_type = FILE_TYPE_PLAYLIST_COLLECTION;
@ -4958,6 +4960,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data)
PARSE_ONLY_BOOL, false) != -1)
count++;
if (menu_displaylist_parse_settings_enum(menu, info,
MENU_ENUM_LABEL_UPDATER_SETTINGS, PARSE_ACTION, false) != -1)
count++;
if (count == 0)
menu_entries_append_enum(info->list,
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND),
@ -5225,9 +5231,6 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data)
menu_displaylist_parse_settings_enum(menu, info,
MENU_ENUM_LABEL_DUMMY_ON_CORE_SHUTDOWN,
PARSE_ONLY_BOOL, false);
menu_displaylist_parse_settings_enum(menu, info,
MENU_ENUM_LABEL_CORE_SET_SUPPORTS_NO_CONTENT_ENABLE,
PARSE_ONLY_BOOL, false);
info->need_refresh = true;
info->need_push = true;
@ -5376,8 +5379,6 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data)
ret = menu_displaylist_parse_settings_enum(menu, info,
MENU_ENUM_LABEL_RETRO_ACHIEVEMENTS_SETTINGS, PARSE_ACTION, false);
#endif
ret = menu_displaylist_parse_settings_enum(menu, info,
MENU_ENUM_LABEL_UPDATER_SETTINGS, PARSE_ACTION, false);
ret = menu_displaylist_parse_settings_enum(menu, info,
MENU_ENUM_LABEL_WIFI_SETTINGS, PARSE_ACTION, false);
ret = menu_displaylist_parse_settings_enum(menu, info,

View File

@ -190,7 +190,10 @@ static int setting_uint_action_left_custom_viewport_width(void *data, bool wrapa
if (custom->width <= 1)
custom->width = 1;
else if (settings->video.scale_integer)
custom->width -= geom->base_width;
{
if (custom->width > geom->base_width)
custom->width -= geom->base_width;
}
else
custom->width -= 1;
@ -242,7 +245,10 @@ static int setting_uint_action_left_custom_viewport_height(void *data, bool wrap
if (custom->height <= 1)
custom->height = 1;
else if (settings->video.scale_integer)
custom->height -= geom->base_height;
{
if (custom->height > geom->base_height)
custom->height -= geom->base_height;
}
else
custom->height -= 1;

View File

@ -611,10 +611,13 @@ enum msg_hash_enums
MENU_ENUM_LABEL_VIDEO_VIEWPORT_CUSTOM_Y,
MENU_ENUM_LABEL_VIDEO_VIEWPORT_CUSTOM_WIDTH,
MENU_ENUM_LABEL_VIDEO_VIEWPORT_CUSTOM_HEIGHT,
MENU_ENUM_LABEL_VIDEO_SHARED_CONTEXT,
MENU_ENUM_LABEL_VIDEO_GAMMA,
MENU_ENUM_LABEL_VIDEO_ALLOW_ROTATE,
MENU_ENUM_LABEL_VIDEO_SHARED_CONTEXT,
MENU_ENUM_LABEL_VALUE_VIDEO_SHARED_CONTEXT,
MENU_ENUM_SUBLABEL_VIDEO_SHARED_CONTEXT,
MENU_ENUM_LABEL_VALUE_VIDEO_VI_WIDTH,
MENU_ENUM_LABEL_VALUE_VIDEO_SETTINGS,
MENU_ENUM_LABEL_VALUE_VIDEO_FILTER,
@ -643,7 +646,6 @@ enum msg_hash_enums
MENU_ENUM_LABEL_VALUE_VIDEO_GPU_RECORD,
MENU_ENUM_LABEL_VALUE_VIDEO_GAMMA,
MENU_ENUM_LABEL_VALUE_VIDEO_ALLOW_ROTATE,
MENU_ENUM_LABEL_VALUE_VIDEO_SHARED_CONTEXT,
MENU_ENUM_LABEL_VALUE_VIDEO_MONITOR_INDEX,
MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE,
MENU_ENUM_LABEL_VALUE_VIDEO_WINDOWED_FULLSCREEN,
@ -832,28 +834,16 @@ enum msg_hash_enums
MENU_ENUM_LABEL_MENU_ENUM_THROTTLE_FRAMERATE,
MENU_ENUM_LABEL_VALUE_MENU_ENUM_THROTTLE_FRAMERATE,
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DYNAMIC_SUPPORT,
MENU_ENUM_LABEL_CHEEVOS_HARDCORE_MODE_ENABLE,
MENU_ENUM_LABEL_VALUE_CHEEVOS_HARDCORE_MODE_ENABLE,
MENU_ENUM_LABEL_CHEEVOS_TEST_UNOFFICIAL,
MENU_ENUM_LABEL_VALUE_CHEEVOS_TEST_UNOFFICIAL,
MENU_ENUM_LABEL_VALUE_CHEEVOS_SETTINGS,
MENU_ENUM_LABEL_CHEEVOS_ENABLE,
MENU_ENUM_LABEL_VALUE_CHEEVOS_ENABLE,
MENU_ENUM_LABEL_CHEEVOS_DESCRIPTION,
MENU_ENUM_LABEL_VALUE_CHEEVOS_DESCRIPTION,
MENU_ENUM_LABEL_STATE_SLOT,
MENU_ENUM_LABEL_VALUE_STATE_SLOT,
MENU_ENUM_LABEL_PLAYLIST_SETTINGS_BEGIN,
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DYNAMIC_SUPPORT,
MENU_ENUM_LABEL_VALUE_CHEEVOS_SETTINGS,
MENU_ENUM_LABEL_CHEEVOS_USERNAME,
MENU_ENUM_LABEL_CHEEVOS_PASSWORD,
@ -863,6 +853,18 @@ enum msg_hash_enums
MENU_ENUM_LABEL_ACCOUNTS_CHEEVOS_USERNAME,
MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_USERNAME,
MENU_ENUM_LABEL_CHEEVOS_HARDCORE_MODE_ENABLE,
MENU_ENUM_LABEL_VALUE_CHEEVOS_HARDCORE_MODE_ENABLE,
MENU_ENUM_LABEL_CHEEVOS_TEST_UNOFFICIAL,
MENU_ENUM_LABEL_VALUE_CHEEVOS_TEST_UNOFFICIAL,
MENU_ENUM_LABEL_CHEEVOS_ENABLE,
MENU_ENUM_LABEL_VALUE_CHEEVOS_ENABLE,
MENU_ENUM_LABEL_CHEEVOS_DESCRIPTION,
MENU_ENUM_LABEL_VALUE_CHEEVOS_DESCRIPTION,
MENU_ENUM_LABEL_CHEEVOS_UNLOCKED_ACHIEVEMENTS,
MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ACHIEVEMENTS,
@ -1923,59 +1925,63 @@ enum msg_hash_enums
MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_BOXARTS,
/* Callback strings */
MENU_ENUM_LABEL_CB_THUMBNAILS_UPDATER_DOWNLOAD,
MENU_ENUM_LABEL_CB_DOWNLOAD_URL,
MENU_ENUM_LABEL_CB_UPDATE_OVERLAYS,
MENU_ENUM_LABEL_CB_CORE_UPDATER_LIST,
MENU_ENUM_LABEL_CB_MENU_WALLPAPER,
MENU_ENUM_LABEL_CB_MENU_THUMBNAIL,
MENU_ENUM_LABEL_CB_THUMBNAILS_UPDATER_LIST,
MENU_ENUM_LABEL_CB_LAKKA_LIST,
MENU_ENUM_LABEL_CB_CORE_CONTENT_LIST,
MENU_ENUM_LABEL_CB_CORE_CONTENT_DIRS_LIST,
MENU_ENUM_LABEL_CB_UPDATE_DATABASES,
MENU_ENUM_LABEL_CB_CORE_CONTENT_DOWNLOAD,
MENU_ENUM_LABEL_CB_CORE_CONTENT_LIST,
MENU_ENUM_LABEL_CB_CORE_THUMBNAILS_DOWNLOAD,
MENU_ENUM_LABEL_CB_CORE_UPDATER_DOWNLOAD,
MENU_ENUM_LABEL_CB_CORE_UPDATER_LIST,
MENU_ENUM_LABEL_CB_DOWNLOAD_URL,
MENU_ENUM_LABEL_CB_LAKKA_DOWNLOAD,
MENU_ENUM_LABEL_CB_LAKKA_LIST,
MENU_ENUM_LABEL_CB_MENU_THUMBNAIL,
MENU_ENUM_LABEL_CB_MENU_WALLPAPER,
MENU_ENUM_LABEL_CB_THUMBNAILS_UPDATER_DOWNLOAD,
MENU_ENUM_LABEL_CB_THUMBNAILS_UPDATER_LIST,
MENU_ENUM_LABEL_CB_UPDATE_ASSETS,
MENU_ENUM_LABEL_CB_UPDATE_AUTOCONFIG_PROFILES,
MENU_ENUM_LABEL_CB_UPDATE_CHEATS,
MENU_ENUM_LABEL_CB_UPDATE_CORE_INFO_FILES,
MENU_ENUM_LABEL_CB_UPDATE_DATABASES,
MENU_ENUM_LABEL_CB_UPDATE_OVERLAYS,
MENU_ENUM_LABEL_CB_UPDATE_SHADERS_CG,
MENU_ENUM_LABEL_CB_UPDATE_SHADERS_GLSL,
MENU_ENUM_LABEL_CB_UPDATE_SHADERS_SLANG,
MENU_ENUM_LABEL_CB_UPDATE_ASSETS,
MENU_ENUM_LABEL_CB_CORE_CONTENT_DOWNLOAD,
MENU_ENUM_LABEL_CB_UPDATE_CORE_INFO_FILES,
MENU_ENUM_LABEL_CB_UPDATE_AUTOCONFIG_PROFILES,
MENU_ENUM_LABEL_CB_CORE_UPDATER_DOWNLOAD,
MENU_ENUM_LABEL_CB_CORE_THUMBNAILS_DOWNLOAD,
MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC_FRAMES,
MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO,
MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX,
MENU_ENUM_SUBLABEL_LOG_VERBOSITY,
MENU_ENUM_SUBLABEL_SHOW_HIDDEN_FILES,
MENU_ENUM_SUBLABEL_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO,
/* Sublabels */
MENU_ENUM_SUBLABEL_ADD_CONTENT_LIST,
MENU_ENUM_SUBLABEL_AUDIO_SETTINGS,
MENU_ENUM_SUBLABEL_BLUETOOTH_ENABLE,
MENU_ENUM_SUBLABEL_CHEEVOS_HARDCORE_MODE_ENABLE,
MENU_ENUM_SUBLABEL_CONFIG_SAVE_ON_EXIT,
MENU_ENUM_SUBLABEL_CORE_SETTINGS,
MENU_ENUM_SUBLABEL_CPU_CORES,
MENU_ENUM_SUBLABEL_FPS_SHOW,
MENU_ENUM_SUBLABEL_INFORMATION_LIST_LIST,
MENU_ENUM_SUBLABEL_INPUT_HOTKEY_BINDS,
MENU_ENUM_SUBLABEL_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO,
MENU_ENUM_SUBLABEL_INPUT_SETTINGS,
MENU_ENUM_SUBLABEL_INPUT_USER_BINDS,
MENU_ENUM_SUBLABEL_LOG_VERBOSITY,
MENU_ENUM_SUBLABEL_MENU_SETTINGS,
MENU_ENUM_SUBLABEL_NETPLAY,
MENU_ENUM_SUBLABEL_ONLINE_UPDATER,
MENU_ENUM_SUBLABEL_SAMBA_ENABLE,
MENU_ENUM_SUBLABEL_SERVICES_SETTINGS,
MENU_ENUM_SUBLABEL_SHOW_HIDDEN_FILES,
MENU_ENUM_SUBLABEL_SSH_ENABLE,
MENU_ENUM_SUBLABEL_SUSPEND_SCREENSAVER_ENABLE,
MENU_ENUM_SUBLABEL_USER_LANGUAGE,
MENU_ENUM_SUBLABEL_VIDEO_BLACK_FRAME_INSERTION,
MENU_ENUM_SUBLABEL_VIDEO_FRAME_DELAY,
MENU_ENUM_SUBLABEL_ADD_CONTENT_LIST,
MENU_ENUM_SUBLABEL_INPUT_USER_BINDS,
MENU_ENUM_SUBLABEL_INPUT_HOTKEY_BINDS,
MENU_ENUM_SUBLABEL_VIDEO_SETTINGS,
MENU_ENUM_SUBLABEL_AUDIO_SETTINGS,
MENU_ENUM_SUBLABEL_INPUT_SETTINGS,
MENU_ENUM_SUBLABEL_WIFI_SETTINGS,
MENU_ENUM_SUBLABEL_SERVICES_SETTINGS,
MENU_ENUM_SUBLABEL_SSH_ENABLE,
MENU_ENUM_SUBLABEL_SAMBA_ENABLE,
MENU_ENUM_SUBLABEL_BLUETOOTH_ENABLE,
MENU_ENUM_SUBLABEL_USER_LANGUAGE,
MENU_ENUM_SUBLABEL_SUSPEND_SCREENSAVER_ENABLE,
MENU_ENUM_SUBLABEL_FPS_SHOW,
MENU_ENUM_SUBLABEL_VIDEO_MAX_SWAPCHAIN_IMAGES,
MENU_ENUM_SUBLABEL_ONLINE_UPDATER,
MENU_ENUM_SUBLABEL_NETPLAY,
MENU_ENUM_SUBLABEL_MENU_SETTINGS,
MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC,
MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC_FRAMES,
MENU_ENUM_SUBLABEL_VIDEO_MAX_SWAPCHAIN_IMAGES,
MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX,
MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO,
MENU_ENUM_SUBLABEL_VIDEO_SETTINGS,
MENU_ENUM_SUBLABEL_VIDEO_THREADED,
MENU_ENUM_SUBLABEL_CONFIG_SAVE_ON_EXIT
MENU_ENUM_SUBLABEL_WIFI_SETTINGS
};

View File

@ -299,7 +299,9 @@ static ssize_t sd_fat_write_r (struct _reent *r, int fd, const char *ptr, size_t
memcpy(tmpBuf, ptr + done, write_size);
int result = FSWriteFile(file->dev->pClient, file->dev->pCmd, tmpBuf, 0x01, write_size, file->fd, 0, -1);
#if 0
FSFlushFile(file->dev->pClient, file->dev->pCmd, file->fd, -1);
#endif
if(result < 0)
{
r->_errno = result;

259
wiiu/link_elf.ld Normal file
View File

@ -0,0 +1,259 @@
/*
* Linkscript for WiiU
*/
OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc");
OUTPUT_ARCH(powerpc:common);
ENTRY(__entry_menu);
PHDRS
{
stub PT_LOAD FLAGS(5);
text PT_LOAD FLAGS(5);
data PT_LOAD FLAGS(6);
bss1 PT_LOAD;
bss2 PT_LOAD;
}
SECTIONS
{
. = 0x00802000;
.stub :
{
KEEP(*(.stub))
} :stub = 0
/* Program */
.init :
{
KEEP (*crt0.o(*.init))
KEEP (*(.init))
} :text = 0
.plt : { *(.plt) }
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rel.init : { *(.rel.init) }
.rela.init : { *(.rela.init) }
.rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
.rel.fini : { *(.rel.fini) }
.rela.fini : { *(.rela.fini) }
.rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
.rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
.rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
.rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
.rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
.rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rela.got1 : { *(.rela.got1) }
.rela.got2 : { *(.rela.got2) }
.rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) }
.rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) }
.rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) }
.rela.sbss : { *(.rela.sbss .rela.sbss.* .rel.gnu.linkonce.sb.*) }
.rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) }
.rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) }
.rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) }
.rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }
.rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.text :
{
*(.text)
*(.text.*)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.gnu.linkonce.t.*)
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
} = 0
.fini :
{
KEEP (*(.fini))
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
} = 0
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
.rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*) } :data
.rodata1 : { *(.rodata1) }
.sdata2 : { *(.sdata2) *(.sdata2.*) *(.gnu.linkonce.s2.*) }
.sbss2 : { *(.sbss2) *(.sbss2.*) *(.gnu.linkonce.sb2.*) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
/* Ensure the __preinit_array_start label is properly aligned. We
could instead move the label definition inside the section, but
the linker would then create the section even if it turns out to
be empty, which isn't pretty. */
. = ALIGN(32 / 8);
PROVIDE (__preinit_array_start = .);
.preinit_array : { *(.preinit_array) }
PROVIDE (__preinit_array_end = .);
PROVIDE (__init_array_start = .);
.init_array : { *(.init_array) }
PROVIDE (__init_array_end = .);
PROVIDE (__fini_array_start = .);
.fini_array : { *(.fini_array) }
PROVIDE (__fini_array_end = .);
.data :
{
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
}
.data1 : { *(.data1) }
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
.eh_frame : { KEEP (*(.eh_frame)) }
.gcc_except_table : { *(.gcc_except_table) }
.fixup : { *(.fixup) }
.got1 : { *(.got1) }
.got2 : { *(.got2) }
.dynamic : { *(.dynamic) }
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
}
.jcr : { KEEP (*(.jcr)) }
.got : { *(.got.plt) *(.got) }
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
.sdata :
{
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
}
_edata = .;
PROVIDE (edata = .);
.sbss :
{
__sbss_start = .;
PROVIDE (__sbss_start = .);
PROVIDE (___sbss_start = .);
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
*(.scommon)
PROVIDE (__sbss_end = .);
PROVIDE (___sbss_end = .);
. = ALIGN(32); /* REQUIRED. LD is flaky without it. */
__sbss_end = .;
} :bss1
.bss :
{
__bss_start = .;
PROVIDE (__bss_start = .);
*(.dynbss)
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections. */
. = ALIGN(32);
PROVIDE (__bss_end = .);
__bss_end = .;
} :bss2
_end = .;
PROVIDE(end = .);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* These must appear regardless of . */
}

View File

@ -1,32 +0,0 @@
/* Tell linker where our application entry is so the garbage collect can work correct */
ENTRY(__entry_menu);
SECTIONS {
. = 0x00802000;
.text : {
*(.text*);
}
.rodata : {
*(.rodata*);
}
.data : {
*(.data*);
__sdata_start = .;
*(.sdata*);
__sdata_end = .;
__sdata2_start = .;
*(.sdata2*);
__sdata2_end = .;
}
.bss : {
__bss_start = .;
*(.bss*);
*(.sbss*);
*(COMMON);
__bss_end = .;
}
__CODE_END = .;
}

253
wiiu/link_rpl.ld Normal file
View File

@ -0,0 +1,253 @@
OUTPUT_FORMAT("elf32-powerpc")
OUTPUT_ARCH(powerpc:common)
ENTRY(_start)
MEMORY {
system (rwx) : ORIGIN = 0x01000000, LENGTH = 32M
code (rwx) : ORIGIN = 0x02000000, LENGTH = 224M
data (rw) : ORIGIN = 0x10000000, LENGTH = 800M
load (rwx) : ORIGIN = 0xC0000000, LENGTH = 128M
}
PHDRS {
hdr_text PT_LOAD FILEHDR PHDRS FLAGS(0x01 | 0x04);
hdr_data PT_LOAD FLAGS(0x02 | 0x04);
hdr_srodata PT_LOAD FLAGS(0x04);
hdr_sdata PT_LOAD FLAGS(0x02 | 0x04);
}
SECTIONS {
. = ORIGIN(code);
.syscall ALIGN(32) : { *(.syscall) } : hdr_text
/* Standard code section */
.text ALIGN(32) : {
/* .init */
KEEP( *(.crt0) )
KEEP( *(.init) )
. = ALIGN(4);
/* .text */
*(.text)
*(.text.*)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
*(.rodata1)
*(.glue_7)
*(.glue_7t)
*(.stub)
*(.gnu.warning)
*(.gnu.linkonce.t*)
. = ALIGN(4);
*(.rplTramp.text)
*(SORT(.rplTramp.text.*))
. = ALIGN(4);
/* .fini */
KEEP( *(.fini) )
. = ALIGN(4);
} : hdr_text
/* Standard data sections */
. = ORIGIN(data);
.data ALIGN(256) : {
*(.data)
*(.data.*)
*(.eh_frame)
*(.eh_frame_hdr)
*(.gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
. = ALIGN(32);
__sdata_start = .;
*(.sdata)
*(.sdata.*)
__sdata_end = .;
. = ALIGN(32);
__sdata2_start = .;
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
__sdata2_end = .;
} : hdr_sdata
.tdata ALIGN(256) :
{
__tdata_lma = .;
*(.tdata)
*(.tdata.*)
*(.gnu.linkonce.td.*)
. = ALIGN(4);
__tdata_lma_end = .;
} : hdr_data
.preinit_array ALIGN(256) :
{
PROVIDE (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE (__preinit_array_end = .);
} : hdr_data
.init_array ALIGN(256) :
{
PROVIDE (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE (__init_array_end = .);
} : hdr_data
.fini_array ALIGN(256) :
{
PROVIDE (__fini_array_start = .);
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
PROVIDE (__fini_array_end = .);
} : hdr_data
.ctors ALIGN(256) :
{
KEEP (*crtbegin.o(.ctors)) /* MUST be first -- GCC requires it */
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
} : hdr_data
.dtors ALIGN(256) :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} : hdr_data
__bss_start__ = .;
.bss ALIGN(256) :
{
*(.dynbss)
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b*)
*(COMMON)
. = ALIGN(32);
__sbss_start = .;
*(.sbss)
*(.sbss.*)
__sbss_end = .;
. = ALIGN(32);
__sbss2_start = .;
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
__sbss2_end = .;
. = ALIGN(32);
/* Reserve space for the TLS segment of the main thread */
__tls_start = .;
__tbss_start = .;
*(.tbss)
*(.tbss.*)
*(.gnu.linkonce.tb.*)
*(.tcommon)
__tbss_end = .;
. += + SIZEOF(.tdata);
__tls_end = .;
. = ALIGN(32);
} : hdr_data
__bss_end__ = .;
/* System stuff is for our elf2rpl converter to go through */
. = ORIGIN(system);
/* Contains the name of RPLs, referenced by .lib.rplLibs */
.rodata.rplNames ALIGN(32) : {
*(.rodata.rplNames)
} : hdr_data
/*
* List of RPL libraries to import, in format:
* uint32_t nameAddress -> .rodata.rplNames
* uint32_t firstFuncEntry -> .data.rplFuncStubs
*/
.lib.rplLibs ALIGN(32) : {
*(.lib.rplLibs)
KEEP (*(.lib.rplLibs*))
}
/*
* List of functions an RPL exports, in format:
* uint32_t trampAddress
*/
.data.rplFuncStubs ALIGN(32) : {
*(.data.rplFuncStubs)
}
/* Required compiler trash */
.fixup ALIGN(32) : { *(.fixup*) }
.got ALIGN(32) : { *(.got*) }
.gcc_except_table ALIGN(32) : { *(.gcc_except_table*) }
.hash ALIGN(32) : { *(.hash) }
.dynsym ALIGN(32) : { *(.dynsym) }
/* Put all dynamic loader relocations into one section */
.rela.dyn ALIGN(32) : {
*(.rela.dyn)
*(.rela.data.rplFuncStubs)
*(.rela.lib.rplLibs)
}
/* Relocations for .rodata sections */
.rela.rodata ALIGN(32) :
{
*(.rela.rodata .rela.rodata.*)
}
/* Relocations for .text sections */
.rela.text ALIGN(32) :
{
*(.rela.text .rela.text.*)
*(.rela.rplTramp.text)
}
/* Relocations for .data sections */
.rela.data ALIGN(32) :
{
*(.rela.data .rela.data.*)
}
/* Relocations for .bss sections */
.rela.bss ALIGN(32) :
{
*(.rela.bss .rela.bss.*)
}
/* Symbol tables */
.shstrtab ALIGN(32) : { *(.shstrtab) }
.symtab ALIGN(32) : { *(.symtab) }
.strtab ALIGN(32) : { *(.strtab) }
/DISCARD/ : {
*(.interp)
*(.dynstr)
*(.dynamic)
*(.comment)
}
__SDATA_START__ = __sdata_start;
__SBSS_END__ = __sbss_end;
__SDATA2_START__ = __sdata2_start;
__SBSS2_END__ = __sbss2_end;
_SDA_BASE_ = __sbss_end;
_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2);
}

View File

@ -1,9 +0,0 @@
export WIILOAD=tcp:$1
rm $2.stripped -rf
powerpc-eabi-strip $2 -o $2.stripped
wiiload $2.stripped
#netcat -p 4405 -l $1
# calling netcat directly after wiiload is unreliable, better use something like :
# for i in {1..20}; do echo; echo == $i ==; echo; netcat -p 4405 -l <wiiu ip>; done
# from a different terminal to continuously listen for incoming connections

14
wiiu/net_listen.sh Executable file
View File

@ -0,0 +1,14 @@
#!/bin/sh
if [ -z $1 ] ; then
echo
echo "usage: $0 <WiiU-ip>"
echo
exit 0
fi
interrupt_count=0
trap 'if [ $interrupt_count -eq 20 ]; then exit 0; else interrupt_count=$(($interrupt_count + 1)); fi' INT
while true; do echo; echo ========= `date` =========; echo; netcat -p 4405 -l $1; done

13
wiiu/net_send.sh Executable file
View File

@ -0,0 +1,13 @@
#!/bin/sh
if [ -z $1 ] ; then
echo
echo "usage: $0 <WiiU-ip> <elf>"
echo
exit 0
fi
export WIILOAD=tcp:$1
rm $2.stripped -rf
powerpc-eabi-strip $2 -o $2.stripped
wiiload $2.stripped

View File

@ -2,5 +2,5 @@
EXPORT_BEGIN(gx2.rpl);
#include "../rpl/libgx2/exports.h"
EXPORT(GX2GetSwapStatus);
EXPORT_END();

View File

@ -22,16 +22,6 @@
#include <coreinit/frameheap.h>
#include <coreinit/expandedheap.h>
#define MEMORY_ARENA_1 0
#define MEMORY_ARENA_2 1
#define MEMORY_ARENA_3 2
#define MEMORY_ARENA_4 3
#define MEMORY_ARENA_5 4
#define MEMORY_ARENA_6 5
#define MEMORY_ARENA_7 6
#define MEMORY_ARENA_8 7
#define MEMORY_ARENA_FG_BUCKET 8
static MEMExpandedHeap* mem1_heap;
static MEMExpandedHeap* bucket_heap;
@ -53,150 +43,58 @@ void memoryInitialize(void)
void memoryRelease(void)
{
MEMDestroyExpHeap(mem1_heap);
MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEMORY_ARENA_1), 3);
MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM1), MEM_FRAME_HEAP_FREE_ALL);
mem1_heap = NULL;
MEMDestroyExpHeap(bucket_heap);
MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEMORY_ARENA_FG_BUCKET), 3);
MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEM_BASE_HEAP_FG), MEM_FRAME_HEAP_FREE_ALL);
bucket_heap = NULL;
}
#if 0
//!-------------------------------------------------------------------------------------------
//! wraps
//!-------------------------------------------------------------------------------------------
void *__wrap_malloc(size_t size)
void* _memalign_r(struct _reent *r, size_t alignment, size_t size)
{
// pointer to a function resolve
if(!size)
return NULL;
return ((void * (*)(size_t))(*pMEMAllocFromDefaultHeap))(size);
return MEMAllocFromExpHeapEx(MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2), size, alignment);
}
void *__wrap_memalign(size_t align, size_t size)
void* _malloc_r(struct _reent *r, size_t size)
{
if (align < 4)
align = 4;
if(!size)
return NULL;
// pointer to a function resolve
return ((void * (*)(size_t, size_t))(*pMEMAllocFromDefaultHeapEx))(size, align);
return _memalign_r(r, 4, size);
}
void __wrap_free(void *p)
void _free_r(struct _reent *r, void *ptr)
{
// pointer to a function resolve
if(p != 0)
((void (*)(void *))(*pMEMFreeToDefaultHeap))(p);
}
void *__wrap_calloc(size_t n, size_t size)
{
void *p = __wrap_malloc(n * size);
if (p != 0) {
memset(p, 0, n * size);
}
return p;
}
size_t __wrap_malloc_usable_size(void *p)
{
//! TODO: this is totally wrong and needs to be addressed
return 0x7FFFFFFF;
}
void *__wrap_realloc(void *p, size_t size)
{
void *new_ptr = __wrap_malloc(size);
if (p != 0 && new_ptr != 0)
{
memcpy(new_ptr, p, __wrap_malloc_usable_size(p) < size ? __wrap_malloc_usable_size(p) : size);
__wrap_free(p);
}
return new_ptr;
}
//!-------------------------------------------------------------------------------------------
//! reent versions
//!-------------------------------------------------------------------------------------------
void *__wrap__malloc_r(struct _reent *r, size_t size)
{
return __wrap_malloc(size);
}
void *__wrap__calloc_r(struct _reent *r, size_t n, size_t size)
{
return __wrap_calloc(n, size);
}
void *__wrap__memalign_r(struct _reent *r, size_t align, size_t size)
{
return __wrap_memalign(align, size);
}
void __wrap__free_r(struct _reent *r, void *p)
{
__wrap_free(p);
}
size_t __wrap__malloc_usable_size_r(struct _reent *r, void *p)
{
return __wrap_malloc_usable_size(p);
}
void *__wrap__realloc_r(struct _reent *r, void *p, size_t size)
{
return __wrap_realloc(p, size);
}
#else
void *
__wrap_memalign(size_t alignment, size_t size) {
return MEMAllocFromExpHeapEx(MEMGetBaseHeapHandle(MEMORY_ARENA_2), size, alignment);
}
void *
__wrap_malloc(size_t size) {
return __wrap_memalign(4, size);
}
void
__wrap_free(void *ptr) {
if (ptr) {
MEMFreeToExpHeap(MEMGetBaseHeapHandle(MEMORY_ARENA_2), ptr);
MEMFreeToExpHeap(MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2), ptr);
}
}
size_t
__wrap_malloc_usable_size(void *ptr) {
size_t _malloc_usable_size_r(struct _reent *r, void *ptr)
{
return MEMGetSizeForMBlockExpHeap(ptr);
}
void *
__wrap_realloc(void *ptr, size_t size) {
if (!ptr) {
return __wrap_malloc(size);
}
void * _realloc_r(struct _reent *r, void *ptr, size_t size)
{
if (!ptr)
return _malloc_r(r, size);
if (__wrap_malloc_usable_size(ptr) >= size) {
if (_malloc_usable_size_r(r, ptr) >= size)
return ptr;
}
void *realloc_ptr = __wrap_malloc(size);
void *realloc_ptr = _malloc_r(r, size);
if(!realloc_ptr) {
if(!realloc_ptr)
return NULL;
}
memcpy(realloc_ptr, ptr, __wrap_malloc_usable_size(ptr));
__wrap_free(ptr);
memcpy(realloc_ptr, ptr, _malloc_usable_size_r(r, ptr));
_free_r(r, ptr);
return realloc_ptr;
}
void *
__wrap_calloc(size_t num, size_t size) {
void *ptr = __wrap_malloc(num*size);
void* _calloc_r(struct _reent *r, size_t num, size_t size)
{
void *ptr = _malloc_r(r, num*size);
if(ptr) {
memset(ptr, 0, num*size);
@ -205,60 +103,24 @@ __wrap_calloc(size_t num, size_t size) {
return ptr;
}
void *
__wrap_valloc(size_t size) {
return __wrap_memalign(64, size);
void * _valloc_r(struct _reent *r, size_t size)
{
return _memalign_r(r, 64, size);
}
void *
__wrap__memalign_r(struct _reent *r, size_t alignment, size_t size) {
return __wrap_memalign(alignment, size);
}
void *
__wrap__malloc_r(struct _reent *r, size_t size) {
return __wrap_malloc(size);
}
void
__wrap__free_r(struct _reent *r, void *ptr) {
return __wrap_free(ptr);
}
void *
__wrap__realloc_r(struct _reent *r, void *ptr, size_t size) {
return __wrap_realloc(ptr, size);
}
void *
__wrap__calloc_r(struct _reent *r, size_t num, size_t size) {
return __wrap_calloc(num, size);
}
size_t
__wrap__malloc_usable_size_r(struct _reent *r, void *ptr) {
return __wrap_malloc_usable_size(ptr);
}
void *
__wrap__valloc_r(struct _reent *r, size_t size) {
return __wrap_valloc(size);
}
#endif
//!-------------------------------------------------------------------------------------------
//! some wrappers
//!-------------------------------------------------------------------------------------------
void * MEM2_alloc(unsigned int size, unsigned int align)
{
return __wrap_memalign(align, size);
return MEMAllocFromExpHeapEx(MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2), size, align);
}
void MEM2_free(void *ptr)
{
__wrap_free(ptr);
if (ptr)
MEMFreeToExpHeap(MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2), ptr);
}
void * MEM1_alloc(unsigned int size, unsigned int align)

View File

@ -2,7 +2,7 @@
#define WIIU_DBG_H
#include <stdio.h>
#include <wut_types.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -13,7 +13,7 @@ extern "C" {
#endif
//#define DEBUG_HOLD() do{printf("%s@%s:%d.\n",__FUNCTION__, __FILE__, __LINE__);fflush(stdout);wait_for_input();}while(0)
#define DEBUG_LINE() do{printf("%s:%d.\n",__FUNCTION__, __LINE__);fflush(stdout);}while(0)
#define DEBUG_LINE() do{printf("%s@%s:%d.\n",__FUNCTION__, __FILE__, __LINE__);fflush(stdout);}while(0)
#define DEBUG_STR(X) printf( "%s: %s\n", #X, (char*)(X))
#define DEBUG_VAR(X) printf( "%-20s: 0x%08X\n", #X, (u32)(X))
#define DEBUG_VAR2(X) printf( "%-20s: 0x%08X (%i)\n", #X, (u32)(X), (int)(X))