Merge pull request #3940 from aliaspider/master

(WIIU) GX2
This commit is contained in:
Twinaphex 2016-11-05 15:07:31 +01:00 committed by GitHub
commit 92b3a24943
25 changed files with 1074 additions and 362 deletions

View File

@ -10,6 +10,7 @@ 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
DEFINES :=
@ -79,10 +80,7 @@ $(error "Please set WUT_ROOT in your environment. export WUT_ROOT=<path to>WUT")
endif
export PATH := $(PATH):$(DEVKITPPC)/bin:$(PORTLIBS)/bin
export LIBOGC_INC := $(DEVKITPRO)/libogc/include
export LIBOGC_LIB := $(DEVKITPRO)/libogc/lib/wii
export PORTLIBS := $(DEVKITPRO)/portlibs/ppc
export PATH := $(PATH):$(DEVKITPPC)/bin
PREFIX := powerpc-eabi-
@ -96,7 +94,7 @@ NM := $(PREFIX)nm
LD := $(CXX)
INCDIRS := -I. -Ideps/zlib -Ideps/7zip -Ilibretro-common/include -Iwiiu -I$(WUT_ROOT)/include -I$(LIBOGC_INC)
INCDIRS := -I. -Ideps/zlib -Ideps/7zip -Ilibretro-common/include -Iwiiu -I$(WUT_ROOT)/include
LIBDIRS := -L.
CFLAGS := -mrvl -mcpu=750 -meabi -mhard-float
@ -138,7 +136,6 @@ all: $(TARGET)
$(TARGET): $(TARGET).elf
$(TARGET).elf: $(OBJ) libretro_wiiu.a wiiu/link.ld
%.o: %.cpp
$(CXX) -c -o $@ $< $(CXXFLAGS) $(INCDIRS)
@ -155,9 +152,8 @@ $(TARGET).elf: $(OBJ) libretro_wiiu.a wiiu/link.ld
%.a:
$(AR) -rc $@ $^
$(TARGET).elf: wiiu/link.ld $(OBJ)
# $(LD) -T wiiu/link.ld $(OBJ) $(LDFLAGS) $(LIBDIRS) $(LIBS) -o $@
$(LD) -n -T wiiu/link.ld $(OBJ) $(LDFLAGS) $(LIBDIRS) $(LIBS) -o $@
$(TARGET).elf: $(OBJ) libretro_wiiu.a wiiu/link_ra.ld
$(LD) -n -T wiiu/link_ra.ld $(OBJ) $(LDFLAGS) $(LIBDIRS) $(LIBS) -o $@
clean:
rm -f $(OBJ)

View File

@ -226,45 +226,35 @@ void net_print(const char* str)
log_write(NULL, 0, str, strlen(str));
}
void net_print_exp(const char* str)
{
send(log_socket, str, strlen(str), 0);
}
static devoptab_t dotab_stdout = {
"stdout", // device name
0, // size of file structure
NULL, // device open
NULL, // device close
log_write, // device write
NULL, // device read
NULL, // device seek
NULL, // device fstat
NULL, // device stat
NULL, // device link
NULL, // device unlink
NULL, // device chdir
NULL, // device rename
NULL, // device mkdir
0, // dirStateSize
NULL, // device diropen_r
NULL, // device dirreset_r
NULL, // device dirnext_r
NULL, // device dirclose_r
NULL, // device statvfs_r
NULL, // device ftrunctate_r
NULL, // device fsync_r
NULL, // deviceData;
"stdout_net", // device name
0, // size of file structure
NULL, // device open
NULL, // device close
log_write, // device write
NULL,
};
int __entry_menu(int argc, char **argv)
{
InitFunctionPointers();
#if 1
setup_os_exceptions();
#else
InstallExceptionHandler();
#endif
socket_lib_init();
log_init("10.42.0.1");
devoptab_list[STD_OUT] = &dotab_stdout;
devoptab_list[STD_ERR] = &dotab_stdout;
memoryInitialize();
mount_sd_fat("sd");
setup_os_exceptions();
// InstallExceptionHandler();
VPADInit();
OSScreenInit();
verbosity_enable();
DEBUG_VAR(argc);
@ -272,7 +262,9 @@ int __entry_menu(int argc, char **argv)
DEBUG_STR(argv[1]);
#if 0
int argc_ = 2;
char* argv_[] = {"sd:/retroarch/retroarch.elf", "sd:/smb3.nes", NULL};
// char* argv_[] = {"sd:/retroarch/retroarch.elf", "sd:/rom.nes", NULL};
char* argv_[] = {"sd:/retroarch/retroarch.elf", "sd:/content/rom.sfc", NULL};
rarch_main(argc_, argv_, NULL);
#else
rarch_main(argc, argv, NULL);
@ -293,12 +285,10 @@ int __entry_menu(int argc, char **argv)
// }while(frames++ < 300);
main_exit(NULL);
printf("Unmount SD\n");
unmount_sd_fat("sd");
printf("Release memory\n");
memoryRelease();
fflush(stdout);
fflush(stderr);
log_deinit();
return 0;

View File

@ -17,40 +17,132 @@
#include "../../configuration.h"
#include "../../verbosity.h"
#include <string.h>
#include <coreinit/screen.h>
#include <coreinit/cache.h>
#include "gx2.h"
#include "system/memory.h"
#include "string.h"
#include "tex_shader.h"
#include "wiiu_dbg.h"
#define _X 0x00
#define _Y 0x01
#define _Z 0x02
#define _W 0x03
#define _R 0x00
#define _G 0x01
#define _B 0x02
#define _A 0x03
#define _0 0x04
#define _1 0x05
#define GX2_COMP_SEL(c0, c1, c2, c3) (((c0) << 24) | ((c1) << 16) | ((c2) << 8) | (c3))
typedef struct
{
void* screen_buffer0;
int screen_buffer0_size;
void* screen_buffer1;
int screen_buffer1_size;
int screen_buffer0_id;
int screen_buffer1_id;
int width;
int height;
GX2TVRenderMode mode;
} wiiu_render_mode_t;
typedef struct
{
float x;
float y;
}position_t;
typedef struct
{
float u;
float v;
}tex_coord_t;
typedef struct
{
tex_shader_t* shader;
struct
{
void* texture;
int tex_width;
int tex_height;
GX2Texture texture;
int width;
int height;
bool enable;
position_t* position;
tex_coord_t* tex_coord;
} menu;
void* texture;
int tex_width;
int tex_height;
GX2Sampler sampler_nearest;
GX2Sampler sampler_linear;
GX2Texture texture;
position_t* position;
tex_coord_t* tex_coord;
int width;
int height;
void* drc_scan_buffer;
void* tv_scan_buffer;
GX2ColorBuffer color_buffer;
GX2ContextState* ctx_state;
void* cmd_buffer;
wiiu_render_mode_t render_mode;
int frames;
} wiiu_video_t;
static const wiiu_render_mode_t wiiu_render_mode_map[] =
{
{0}, /* GX2_TV_SCAN_MODE_NONE */
{854, 480, GX2_TV_RENDER_MODE_WIDE_480P}, /* GX2_TV_SCAN_MODE_576I */
{854, 480, GX2_TV_RENDER_MODE_WIDE_480P}, /* GX2_TV_SCAN_MODE_480I */
{854, 480, GX2_TV_RENDER_MODE_WIDE_480P}, /* GX2_TV_SCAN_MODE_480P */
{1280, 720, GX2_TV_RENDER_MODE_WIDE_720P}, /* GX2_TV_SCAN_MODE_720P */
{0}, /* GX2_TV_SCAN_MODE_unk */
{1920, 1080, GX2_TV_RENDER_MODE_WIDE_1080P}, /* GX2_TV_SCAN_MODE_1080I */
{1920, 1080, GX2_TV_RENDER_MODE_WIDE_1080P} /* GX2_TV_SCAN_MODE_1080P */
};
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;
DEBUG_FLOAT(position[0].x);
DEBUG_FLOAT(position[0].y);
DEBUG_FLOAT(position[1].x);
DEBUG_FLOAT(position[1].y);
DEBUG_FLOAT(position[2].x);
DEBUG_FLOAT(position[2].y);
DEBUG_FLOAT(position[3].x);
DEBUG_FLOAT(position[3].y);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, position, 4 * sizeof(*position));
}
static void wiiu_set_tex_coords(tex_coord_t* tex_coord, GX2Texture* texture, float u0, float v0, float u1, float v1)
{
tex_coord[0].u = u0 / texture->surface.width;
tex_coord[0].v = (v1 / texture->surface.height);
tex_coord[1].u = u1 / texture->surface.width;
tex_coord[1].v = (v1 / texture->surface.height);
tex_coord[2].u = u1 / texture->surface.width;
tex_coord[2].v = (v0 / texture->surface.height);
tex_coord[3].u = u0 / texture->surface.width;
tex_coord[3].v = (v0 / texture->surface.height);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, tex_coord, 4 * sizeof(*tex_coord));
}
static void* wiiu_gfx_init(const video_info_t* video,
const input_driver_t** input, void** input_data)
{
int i;
*input = NULL;
*input_data = NULL;
@ -59,37 +151,179 @@ static void* wiiu_gfx_init(const video_info_t* video,
if (!wiiu)
return NULL;
wiiu->screen_buffer0_size = OSScreenGetBufferSizeEx(0);
wiiu->screen_buffer0 = MEM1_alloc(wiiu->screen_buffer0_size, 0x40);
wiiu->screen_buffer1_size = OSScreenGetBufferSizeEx(1);
wiiu->screen_buffer1 = MEM1_alloc(wiiu->screen_buffer1_size, 0x40);
/* video init */
wiiu->cmd_buffer = MEM2_alloc(0x400000, 0x40);
u32 init_attributes[] =
{
GX2_INIT_CMD_BUF_BASE, (u32)wiiu->cmd_buffer,
GX2_INIT_CMD_BUF_POOL_SIZE, 0x400000,
GX2_INIT_ARGC, 0,
GX2_INIT_ARGV, 0,
GX2_INIT_END
};
GX2Init(init_attributes);
DEBUG_INT(wiiu->screen_buffer0_size);
DEBUG_INT(wiiu->screen_buffer1_size);
/* setup scanbuffers */
u32 size = 0;
u32 tmp = 0;
wiiu->render_mode = wiiu_render_mode_map[GX2GetSystemTVScanMode()];
GX2CalcTVSize(wiiu->render_mode.mode, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8, GX2_BUFFERING_MODE_DOUBLE, &size, &tmp);
wiiu->tv_scan_buffer = MEMBucket_alloc(size, GX2_SCAN_BUFFER_ALIGNMENT);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, wiiu->tv_scan_buffer, size);
GX2SetTVBuffer(wiiu->tv_scan_buffer, size, wiiu->render_mode.mode, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8,
GX2_BUFFERING_MODE_DOUBLE);
OSScreenSetBufferEx(0, wiiu->screen_buffer0);
OSScreenSetBufferEx(1, wiiu->screen_buffer1);
OSScreenEnableEx(0, 1);
OSScreenEnableEx(1, 1);
OSScreenClearBufferEx(0, 0);
OSScreenClearBufferEx(1, 0);
GX2CalcDRCSize(GX2_DRC_RENDER_MODE_SINGLE, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8, GX2_BUFFERING_MODE_DOUBLE, &size,
&tmp);
wiiu->drc_scan_buffer = MEMBucket_alloc(size, GX2_SCAN_BUFFER_ALIGNMENT);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, wiiu->drc_scan_buffer, size);
GX2SetDRCBuffer(wiiu->drc_scan_buffer, size, GX2_DRC_RENDER_MODE_SINGLE, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8,
GX2_BUFFERING_MODE_DOUBLE);
DCFlushRange(wiiu->screen_buffer0, wiiu->screen_buffer0_size);
DCFlushRange(wiiu->screen_buffer1, wiiu->screen_buffer1_size);
memset(&wiiu->color_buffer, 0, sizeof(GX2ColorBuffer));
wiiu->color_buffer.surface.dim = GX2_SURFACE_DIM_TEXTURE_2D;
wiiu->color_buffer.surface.width = wiiu->render_mode.width;
wiiu->color_buffer.surface.height = wiiu->render_mode.height;
wiiu->color_buffer.surface.depth = 1;
wiiu->color_buffer.surface.mipLevels = 1;
wiiu->color_buffer.surface.format = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
wiiu->color_buffer.surface.use = GX2_SURFACE_USE_TEXTURE_COLOR_BUFFER_TV;
wiiu->color_buffer.viewNumSlices = 1;
GX2CalcSurfaceSizeAndAlignment(&wiiu->color_buffer.surface);
GX2InitColorBufferRegs(&wiiu->color_buffer);
OSScreenFlipBuffersEx(0);
wiiu->screen_buffer0_id = 0;
OSScreenFlipBuffersEx(1);
wiiu->screen_buffer1_id = 0;
wiiu->color_buffer.surface.image = MEM1_alloc(wiiu->color_buffer.surface.imageSize,
wiiu->color_buffer.surface.alignment);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, wiiu->color_buffer.surface.image, wiiu->color_buffer.surface.imageSize);
wiiu->menu.tex_width = 512;
wiiu->menu.tex_height = 512;
wiiu->menu.texture = malloc(wiiu->menu.tex_width * wiiu->menu.tex_height * sizeof(uint16_t));
wiiu->ctx_state = (GX2ContextState*)MEM2_alloc(sizeof(GX2ContextState), GX2_CONTEXT_STATE_ALIGNMENT);
GX2SetupContextStateEx(wiiu->ctx_state, GX2_TRUE);
wiiu->tex_width = video->input_scale * RARCH_SCALE_BASE;;
wiiu->tex_height = video->input_scale * RARCH_SCALE_BASE;;
wiiu->texture = malloc(wiiu->tex_width * wiiu->tex_height * sizeof(uint16_t));
GX2SetContextState(wiiu->ctx_state);
GX2SetColorBuffer(&wiiu->color_buffer, GX2_RENDER_TARGET_0);
GX2SetViewport(0.0f, 0.0f, wiiu->color_buffer.surface.width, wiiu->color_buffer.surface.height, 0.0f, 1.0f);
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,
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);
/* init shader */
// wiiu->shader = MEM2_alloc(sizeof(*wiiu->shader), GX2_VERTEX_BUFFER_ALIGNMENT);
wiiu->shader = MEM2_alloc(sizeof(tex_shader), 0x1000);
memcpy(wiiu->shader, &tex_shader, sizeof(tex_shader));
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, wiiu->shader, sizeof(tex_shader));
wiiu->shader->vs.program = MEM2_alloc(wiiu->shader->vs.size, GX2_SHADER_ALIGNMENT);
memcpy(wiiu->shader->vs.program, tex_shader.vs.program, wiiu->shader->vs.size);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_SHADER, wiiu->shader->vs.program, wiiu->shader->vs.size);
wiiu->shader->vs.attribVars = MEM2_alloc(wiiu->shader->vs.attribVarCount * sizeof(GX2AttribVar),
GX2_SHADER_ALIGNMENT);
memcpy(wiiu->shader->vs.attribVars, tex_shader.vs.attribVars ,
wiiu->shader->vs.attribVarCount * sizeof(GX2AttribVar));
wiiu->shader->ps.program = MEM2_alloc(wiiu->shader->ps.size, GX2_SHADER_ALIGNMENT);
memcpy(wiiu->shader->ps.program, tex_shader.ps.program, wiiu->shader->ps.size);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_SHADER, wiiu->shader->ps.program, wiiu->shader->ps.size);
wiiu->shader->ps.samplerVars = MEM2_alloc(wiiu->shader->ps.samplerVarCount * sizeof(GX2SamplerVar),
GX2_SHADER_ALIGNMENT);
memcpy(wiiu->shader->ps.samplerVars, tex_shader.ps.samplerVars,
wiiu->shader->ps.samplerVarCount * sizeof(GX2SamplerVar));
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,
sizeof(wiiu->shader->attribute_stream) / sizeof(GX2AttribStream),
(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);
wiiu->position = MEM2_alloc(4 * sizeof(*wiiu->position), GX2_VERTEX_BUFFER_ALIGNMENT);
wiiu_set_position(wiiu->position, &wiiu->color_buffer, 0, 0, wiiu->color_buffer.surface.width, wiiu->color_buffer.surface.height);
wiiu->tex_coord = MEM2_alloc(4 * sizeof(*wiiu->tex_coord), GX2_VERTEX_BUFFER_ALIGNMENT);
wiiu_set_tex_coords(wiiu->tex_coord, &wiiu->texture, 0, 0, wiiu->texture.surface.width, wiiu->texture.surface.height);
GX2SetAttribBuffer(0, 4 * sizeof(*wiiu->position), sizeof(*wiiu->position), wiiu->position);
GX2SetAttribBuffer(1, 4 * sizeof(*wiiu->tex_coord), sizeof(*wiiu->tex_coord), wiiu->tex_coord);
wiiu->menu.position = MEM2_alloc(4 * sizeof(*wiiu->menu.position), GX2_VERTEX_BUFFER_ALIGNMENT);
wiiu_set_position(wiiu->menu.position, &wiiu->color_buffer, 0, 0, wiiu->color_buffer.surface.width, wiiu->color_buffer.surface.height);
wiiu->menu.tex_coord = MEM2_alloc(4 * sizeof(*wiiu->menu.tex_coord), GX2_VERTEX_BUFFER_ALIGNMENT);
wiiu_set_tex_coords(wiiu->menu.tex_coord, &wiiu->menu.texture, 0, 0, wiiu->menu.texture.surface.width, wiiu->menu.texture.surface.height);
/* init frame texture */
memset(&wiiu->texture, 0, sizeof(GX2Texture));
wiiu->texture.surface.width = video->input_scale * RARCH_SCALE_BASE;
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);
GX2CalcSurfaceSizeAndAlignment(&wiiu->texture.surface);
GX2InitTextureRegs(&wiiu->texture);
wiiu->texture.surface.image = MEM2_alloc(wiiu->texture.surface.imageSize,
wiiu->texture.surface.alignment);
// memset(wiiu->texture.surface.image, 0x88, wiiu->texture.surface.imageSize);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, wiiu->texture.surface.image,
wiiu->texture.surface.imageSize);
/* init menu texture */
memset(&wiiu->menu.texture, 0, sizeof(GX2Texture));
wiiu->menu.texture.surface.width = 512;
wiiu->menu.texture.surface.height = 512;
wiiu->menu.texture.surface.depth = 1;
wiiu->menu.texture.surface.dim = GX2_SURFACE_DIM_TEXTURE_2D;
wiiu->menu.texture.surface.format = GX2_SURFACE_FORMAT_UNORM_R4_G4_B4_A4;
wiiu->menu.texture.surface.tileMode = GX2_TILE_MODE_LINEAR_ALIGNED;
wiiu->menu.texture.viewNumSlices = 1;
wiiu->menu.texture.compMap = GX2_COMP_SEL(_A, _R, _G, _B);
GX2CalcSurfaceSizeAndAlignment(&wiiu->menu.texture.surface);
GX2InitTextureRegs(&wiiu->menu.texture);
wiiu->menu.texture.surface.image = MEM2_alloc(wiiu->menu.texture.surface.imageSize,
wiiu->menu.texture.surface.alignment);
for (i = 0; i < wiiu->menu.texture.surface.imageSize / 4; i++)
((uint32_t*)wiiu->menu.texture.surface.image)[i] = 0xFFFFFFFF;
((uint32_t*)wiiu->menu.texture.surface.image)[0] = 0xFF0000FF;
DEBUG_VAR(wiiu->menu.texture.surface.width);
DEBUG_VAR(wiiu->menu.texture.surface.height);
DEBUG_VAR(wiiu->menu.texture.surface.alignment);
DEBUG_VAR(wiiu->menu.texture.surface.imageSize);
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, wiiu->menu.texture.surface.image,
wiiu->menu.texture.surface.imageSize);
/* init samplers */
GX2InitSampler(&wiiu->sampler_nearest, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_POINT);
GX2InitSampler(&wiiu->sampler_linear, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_LINEAR);
/* set Texture and Sampler */
GX2SetPixelTexture(&wiiu->texture, wiiu->shader->sampler.location);
GX2SetPixelSampler(&wiiu->sampler_linear, wiiu->shader->sampler.location);
GX2SetTVEnable(GX2_ENABLE);
GX2SetDRCEnable(GX2_ENABLE);
if (input && input_data)
{
@ -110,13 +344,41 @@ static void wiiu_gfx_free(void* data)
if (!wiiu)
return;
MEM1_free(wiiu->screen_buffer0);
MEM1_free(wiiu->screen_buffer1);
free(wiiu->menu.texture);
free(wiiu->texture);
GX2Flush();
GX2DrawDone();
GX2Shutdown();
GX2SetTVEnable(GX2_DISABLE);
GX2SetDRCEnable(GX2_DISABLE);
MEM2_free(wiiu->ctx_state);
MEM2_free(wiiu->cmd_buffer);
MEM2_free(wiiu->texture.surface.image);
MEM2_free(wiiu->menu.texture.surface.image);
MEM1_free(wiiu->color_buffer.surface.image);
MEMBucket_free(wiiu->tv_scan_buffer);
MEMBucket_free(wiiu->drc_scan_buffer);
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);
MEM2_free(wiiu->position);
MEM2_free(wiiu->tex_coord);
MEM2_free(wiiu->menu.position);
MEM2_free(wiiu->menu.tex_coord);
free(wiiu);
DEBUG_LINE();
}
static bool wiiu_gfx_frame(void* data, const void* frame,
@ -131,68 +393,73 @@ static bool wiiu_gfx_frame(void* data, const void* frame,
int i;
wiiu_video_t* wiiu = (wiiu_video_t*) data;
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);
static int frames = 0;
char frames_str [512];
snprintf(frames_str, sizeof(frames_str), "frames : %i", frames++);
if (!width || !height)
{
GX2WaitForVsync();
return;
}
OSScreenClearBufferEx(1, 0);
if(frame)
{
if (width > wiiu->texture.surface.width)
width = wiiu->texture.surface.width;
if (height > wiiu->texture.surface.height)
height = wiiu->texture.surface.height;
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++)
{
// 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;
}
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, wiiu->texture.surface.image,
wiiu->texture.surface.imageSize);
wiiu_set_tex_coords(wiiu->tex_coord, &wiiu->texture, 0, 0, width, height);
}
GX2SetAttribBuffer(0, 4 * sizeof(*wiiu->position), sizeof(*wiiu->position), wiiu->position);
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);
GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
if (wiiu->menu.enable)
{
const uint16_t* src = (uint16_t*)wiiu->menu.texture;
uint32_t* dst = (uint32_t*)((uint8_t*)wiiu->screen_buffer1 + wiiu->screen_buffer1_id * wiiu->screen_buffer1_size / 2);
GX2SetAttribBuffer(0, 4 * sizeof(*wiiu->menu.position), sizeof(*wiiu->menu.position), wiiu->menu.position);
GX2SetAttribBuffer(1, 4 * sizeof(*wiiu->menu.tex_coord), sizeof(*wiiu->menu.tex_coord), wiiu->menu.tex_coord);
dst += 896 * (480 - wiiu->menu.height) / 2 + (896 - wiiu->menu.width) / 2;
int x, y;
GX2SetPixelTexture(&wiiu->menu.texture, wiiu->shader->sampler.location);
GX2SetPixelSampler(&wiiu->sampler_linear, wiiu->shader->sampler.location);
for (y = 0; y < wiiu->menu.height; y++)
{
for (x = 0; x < wiiu->menu.width; x++)
{
int r = ((src[x] >> 12) & 0xF) << 4;
int g = ((src[x] >> 8) & 0xF) << 4;
int b = ((src[x] >> 4) & 0xF) << 4;
dst[x] = (r << 0) | (b << 8) | (g << 16);
}
src += wiiu->menu.tex_width;
dst += 896;
}
}
else
{
const uint16_t* src = (uint16_t*)frame;
uint32_t* dst = (uint32_t*)((uint8_t*)wiiu->screen_buffer1 + wiiu->screen_buffer1_id * wiiu->screen_buffer1_size / 2);
dst += (896 * (480 - height) + width) / 2;
int x, y;
for (y = 0; y < height; y++)
{
for (x = 0; x < width; x++)
{
int r = ((src[x] >> 11) & 0x1F) << 3;
int g = ((src[x] >> 5) & 0x3F) << 2;
int b = ((src[x] >> 0) & 0x1F) << 3;
dst[x] = (r << 0) | (b << 8) | (g << 16);
}
src += pitch/2;
dst += 896;
}
GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
}
GX2CopyColorBufferToScanBuffer(&wiiu->color_buffer, GX2_SCAN_TARGET_DRC);
GX2CopyColorBufferToScanBuffer(&wiiu->color_buffer, GX2_SCAN_TARGET_TV);
OSScreenPutFontEx(1, 0, 16, frames_str);
DCFlushRange(((uint8_t*)wiiu->screen_buffer1 + wiiu->screen_buffer1_id * wiiu->screen_buffer1_size / 2)
, wiiu->screen_buffer1_size / 2);
OSScreenFlipBuffersEx(1);
wiiu->screen_buffer1_id ^= 1;
GX2SwapScanBuffers();
GX2Flush();
GX2WaitForVsync();
printf("\rframe : %5i", wiiu->frames++);
fflush(stdout);
return true;
}
@ -302,24 +569,33 @@ static void wiiu_set_texture_frame(void* data, const void* frame, bool rgb32,
if (!frame || !width || !height)
return;
if (width > wiiu->menu.tex_width)
width = wiiu->menu.tex_width;
if (width > wiiu->menu.texture.surface.width)
width = wiiu->menu.texture.surface.width;
if (height > wiiu->menu.tex_height)
height = wiiu->menu.tex_height;
if (height > wiiu->menu.texture.surface.height)
height = wiiu->menu.texture.surface.height;
wiiu->menu.width = width;
wiiu->menu.height = height;
const uint16_t* src = frame;
uint16_t* dst = (uint16_t*)wiiu->menu.texture;
uint16_t* dst = (uint16_t*)wiiu->menu.texture.surface.image;
DEBUG_VAR(width);
DEBUG_VAR(height);
for (i = 0; i < height; i++)
{
memcpy(dst, src, width * sizeof(uint16_t));
dst += wiiu->menu.tex_width;
dst += wiiu->menu.texture.surface.pitch;
src += width;
}
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, wiiu->menu.texture.surface.image,
wiiu->menu.texture.surface.imageSize);
wiiu_set_tex_coords(wiiu->menu.tex_coord, &wiiu->menu.texture, 0, 0, width, height);
// 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)

View File

@ -53,7 +53,7 @@ static int16_t wiiu_input_state(void *data, const struct retro_keybind **binds,
{
wiiu_input_t *wiiu = (wiiu_input_t*)data;
if (port > 0)
if(!wiiu || (port > 0) || !binds || !binds[port])
return 0;
switch (device)

View File

@ -177,7 +177,7 @@ static int sd_fat_open_r (struct _reent *r, void *fileStruct, const char *path,
return -1;
}
int result = FSOpenFile(dev->pClient, dev->pCmd, real_path, mode_str, &fd, -1);
int result = FSOpenFile(dev->pClient, dev->pCmd, real_path, mode_str, (FSFileHandle*)&fd, -1);
free(real_path);
@ -740,7 +740,7 @@ static DIR_ITER *sd_fat_diropen_r (struct _reent *r, DIR_ITER *dirState, const c
int dirHandle;
int result = FSOpenDir(dev->pClient, dev->pCmd, real_path, &dirHandle, -1);
int result = FSOpenDir(dev->pClient, dev->pCmd, real_path, (FSDirectoryHandle*)&dirHandle, -1);
free(real_path);

33
wiiu/gx2.h Normal file
View File

@ -0,0 +1,33 @@
#ifndef GX2_H
#define GX2_H
#include <gx2/clear.h>
#include <gx2/context.h>
#include <gx2/display.h>
#include <gx2/displaylist.h>
#include <gx2/draw.h>
#include <gx2/enum.h>
#include <gx2/event.h>
#include <gx2/mem.h>
#include <gx2/registers.h>
#include <gx2/sampler.h>
#include <gx2/shaders.h>
#include <gx2/state.h>
#include <gx2/surface.h>
#include <gx2/swap.h>
#include <gx2/tessellation.h>
#include <gx2/texture.h>
#define GX2_SCAN_BUFFER_ALIGNMENT 0x1000
#define GX2_SHADER_ALIGNMENT 0x100
#define GX2_CONTEXT_STATE_ALIGNMENT 0x100
#define GX2_DISPLAY_LIST_ALIGNMENT 0x20
#define GX2_VERTEX_BUFFER_ALIGNMENT 0x40
#define GX2_INDEX_BUFFER_ALIGNMENT 0x20
#define GX2_ENABLE TRUE
#define GX2_DISABLE FALSE
#define GX2_TRUE TRUE
#define GX2_FALSE FALSE
#endif // GX2_H

167
wiiu/gx2_shader_inl.h Normal file
View File

@ -0,0 +1,167 @@
#ifndef GX2_SHADER_INL_H
#define GX2_SHADER_INL_H
#ifdef MSB_FIRST
#define to_LE(x) __builtin_bswap32(x)
#else
#define to_LE(x) x
#endif
/* CF */
#define CF_WORD0(addr) to_LE(addr)
#define CF_WORD1(popCount, cfConst, cond, count, callCount, inst) \
to_LE(popCount | (cfConst << 3) | (cond << 8) | (count << 10) | (callCount << 13) | (inst << 23) | (1 << 31))
#define CF_ALU_WORD0(addr, kcacheBank0, kcacheBank1, kcacheMode0) \
to_LE(addr | (kcacheBank0 << 16) | (kcacheBank1 << 20) | (kcacheMode0 << 22))
#define CF_ALU_WORD1(kcacheMode1, kcacheAddr0, kcacheAddr1, count, altConst, inst) \
to_LE(kcacheMode1 | (kcacheAddr0 << 2) | (kcacheAddr1 << 10) | (count << 18) | (altConst << 25) | (inst << 26) | (1 << 31))
#define CF_EXP_WORD0(dstReg_and_type, srcReg, srcRel, indexGpr, elemSize)\
to_LE(dstReg_and_type | (srcReg << 15) | (srcRel << 22) | (indexGpr << 23) | (elemSize << 30))
#define CF_EXP_WORD1(srcSelX, srcSelY, srcSelZ, srcSelW, validPixelMode, inst) \
to_LE(srcSelX | (srcSelY << 3) | (srcSelZ << 6) | (srcSelW << 9) | (validPixelMode << 22) | (inst << 23) | (1 << 31))
#define NO_BARRIER & to_LE(~(1 << 31))
#define END_OF_PROGRAM | to_LE(1 << 21)
#define VALID_PIX | to_LE(1 << 22)
#define WHOLE_QUAD_MODE | to_LE(1 << 30)
#define ALU_LAST to_LE(1 << 31) |
/* ALU */
#define ALU_WORD0(src0Sel, src0Rel, src0Chan, src0Neg, src1Sel, src1Rel, src1Chan, src1Neg, indexMode, predSel) \
to_LE(src0Sel | (src0Rel << 9) | (src0Chan << 10) | (src0Neg << 12) | (src1Sel << 13) | (src1Rel << 22) \
| (src1Chan << 23) | (src1Neg << 25) | (indexMode << 26) | (predSel << 29))
#define ALU_WORD1_OP2(src0Abs, src1Abs, updateExecuteMask, updatePred, writeMask, omod, inst, encoding, bankSwizzle, dstGpr, dstRel, dstChan, clamp) \
to_LE(src0Abs | (src1Abs << 1) | (updateExecuteMask << 2) | (updatePred << 3) | (writeMask << 4) | (omod << 5) | (inst << 7) | \
(encoding << 15) | (bankSwizzle << 18) | (dstGpr << 21) | (dstRel << 28) | (dstChan << 29) | (clamp << 31))
#define ALU_WORD1_OP3(src2Sel, src2Rel, src2Chan, src2Neg, inst, encoding, bankSwizzle, dstGpr, dstRel, dstChan, clamp) \
to_LE(src2Sel | (src2Rel << 9) | (src2Chan << 10) | (src2Neg << 12) | (inst << 13) | \
(encoding << 15) | (bankSwizzle << 18) | (dstGpr << 21) | (dstRel << 28) | (dstChan << 29) | (clamp << 31)
/* TEX */
#define TEX_WORD0(inst, bcFracMode, fetchWholeQuad, resourceID, srcReg, srcRel, altConst) \
to_LE(inst | (bcFracMode << 5) | (fetchWholeQuad << 7) | (resourceID << 8) | (srcReg << 16) | (srcRel << 23) | (altConst << 24))
#define TEX_WORD1(dstReg, dstRel, dstSelX, dstSelY, dstSelZ, dstSelW, lodBias, coordTypeX, coordTypeY, coordTypeZ, coordTypeW) \
to_LE(dstReg | (dstRel << 7) | (dstSelX << 9) | (dstSelY << 12) | (dstSelZ << 15) | (dstSelW << 18) | \
(lodBias << 21) | (coordTypeX << 28) | (coordTypeY << 29) | (coordTypeZ << 30) | (coordTypeW << 31))
#define TEX_WORD2(offsetX, offsetY, offsetZ, samplerID, srcSelX, srcSelY, srcSelZ, srcSelW) \
to_LE(offsetX | (offsetY << 5) | (offsetZ << 10) | (samplerID << 15) | (srcSelX << 20) | (srcSelY << 23) | (srcSelZ << 26) | (srcSelW << 29))
#define _X 0
#define _Y 1
#define _Z 2
#define _W 3
#define _0 4
#define _1 5
#define GX2_COMP_SEL(c0, c1, c2, c3) (((c0) << 24) | ((c1) << 16) | ((c2) << 8) | (c3))
#define ALU_LITERAL(v) to_LE(v)
/* SRCx_SEL special constants */
#define ALU_SRC_1_DBL_L 0xF4
#define ALU_SRC_1_DBL_M 0xF5
#define ALU_SRC_0_5_DBL_L 0xF6
#define ALU_SRC_0_5_DBL_M 0xF7
#define ALU_SRC_0 0xF8
#define ALU_SRC_1 0xF9
#define ALU_SRC_1_INT 0xFA
#define ALU_SRC_M_1_INT 0xFB
#define ALU_SRC_0_5 0xFC
#define ALU_SRC_LITERAL 0xFD
#define ALU_SRC_PV 0xFE
#define ALU_SRC_PS 0xFF
/* CF defines */
#define CF_COND_ACTIVE 0x0
#define CF_COND_FALSE 0x1
#define CF_COND_BOOL 0x2
#define CF_COND_NOT_BOOL 0x3
/* TEX defines */
#define TEX_UNNORMALIZED 0x0
#define TEX_NORMALIZED 0x1
/* instructions */
/* CF */
#define CF_INST_TEX 0x01
#define CF_INST_CALL_FS 0x13
/* ALU */
#define ALU_INST_ALU 0x8
#define OP2_INST_MOV 0x19
/* EXP */
#define CF_INST_EXP_DONE 0x28
/* TEX */
#define TEX_INST_SAMPLE 0x10
/* EXPORT_TYPE */
#define EXPORT_TYPE_PIXEL 0x0
#define EXPORT_TYPE_POS 0x1
#define EXPORT_TYPE_PARAM 0x2
#define EXPORT_ARRAY_BASE_POS(id) (0x3C + id) // [0, 3]
#define EXPORT_ARRAY_BASE_PARAM(id) id // [0, 31]
#define EXPORT_ARRAY_BASE_PIX(id) id
/* exports */
#define POS(id) EXPORT_ARRAY_BASE_POS(id) | (EXPORT_TYPE_POS << 13)
#define PARAM(id) EXPORT_ARRAY_BASE_PARAM(id) | (EXPORT_TYPE_PARAM << 13)
#define PIX(id) EXPORT_ARRAY_BASE_PIX(id) | (EXPORT_TYPE_PIXEL << 13)
#define POS0 POS(0)
#define PARAM0 PARAM(0)
#define PIX0 PIX(0)
/* registers */
#define _R(x) x
#define _R0 _R(0x0)
#define _R1 _R(0x1)
#define _R2 _R(0x2)
/* texture */
#define _t(x) x
#define _t0 _t(0x0)
/* sampler */
#define _s(x) x
#define _s0 _s(0x0)
#define CALL_FS CF_WORD0(0), CF_WORD1(0,0,0,0,0,CF_INST_CALL_FS)
#define TEX(addr, cnt) CF_WORD0(addr), CF_WORD1(0x0, 0x0, CF_COND_ACTIVE, 0x0, (cnt - 1), CF_INST_TEX)
#define ALU(addr, cnt) CF_ALU_WORD0(addr, 0x0, 0x0, 0x0), CF_ALU_WORD1(0x0, 0x0, 0x0, (cnt - 1), 0x0, ALU_INST_ALU)
#define EXP_DONE(dstReg_and_type, srcReg, srcSelX, srcSelY, srcSelZ, srcSelW) CF_EXP_WORD0(dstReg_and_type, srcReg, 0x0, 0x0, 0x0), \
CF_EXP_WORD1(srcSelX, srcSelY, srcSelZ, srcSelW, 0x0, CF_INST_EXP_DONE)
#define ALU_MOV(dstGpr, dstChan, src0Sel, src0Chan) ALU_WORD0(src0Sel, 0x0, src0Chan, 0x0, ALU_SRC_0, 0x0, 0x0, 0x0, 0x0, 0x0), \
ALU_WORD1_OP2(0x0, 0x0, 0x0, 0x0, 0x1, 0x0, OP2_INST_MOV, 0x0, 0x0, dstGpr, 0x0, dstChan, 0x0)
#define TEX_SAMPLE(dstReg, dstSelX, dstSelY, dstSelZ, dstSelW, srcReg, srcSelX, srcSelY, srcSelZ, srcSelW, resourceID, samplerID)\
TEX_WORD0(TEX_INST_SAMPLE, 0x0, 0x0, resourceID, srcReg, 0x0, 0x0), \
TEX_WORD1(dstReg, 0x0, dstSelX, dstSelY, dstSelZ, dstSelW, 0x0, TEX_NORMALIZED, TEX_NORMALIZED, TEX_NORMALIZED, TEX_NORMALIZED), \
TEX_WORD2(0x0, 0x0, 0x0, samplerID, _X, _Y, _0, _X)
#define _x2(v) v, v
#define _x4(v) _x2(v), _x2(v)
#define _x8(v) _x4(v), _x4(v)
#define _x16(v) _x8(v), _x8(v)
#define _x9(v) _x8(v), v
#define _x30(v) _x16(v), _x8(v), _x4(v),_x2(v)
#define _x31(v) _x30(v), v
#endif // GX2_SHADER_INL_H

View File

@ -9,6 +9,7 @@ SECTIONS {
.rodata : {
*(.rodata*);
}
. = 0x10000000;
.data : {
*(.data*);

View File

@ -1,4 +1,9 @@
export WIILOAD=tcp:$1
powerpc-eabi-strip retroarch_wiiu.elf -o retroarch_wiiu_stripped.elf
wiiload retroarch_wiiu_stripped.elf
netcat -p 4405 -l $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

View File

@ -13,15 +13,13 @@
ori %r11, %r11, addr_##name@l; \
lwz %r11, 0(%r11); \
mtctr %r11; \
bctr;
bctr
#define EXPORT_BEGIN(lib)
#define EXPORT_END()
.align 2;
.section ".text";
#include "../rpl/libcoreinit/exports.h"
#include "../rpl/libnsysnet/exports.h"
#include "../rpl/libgx2/exports.h"
#include "../rpl/libproc_ui/exports.h"
#include "../rpl/libsndcore2/exports.h"
#include "../rpl/libsysapp/exports.h"
#include "../rpl/libvpad/exports.h"
#include "exports/all.h"

View File

@ -2,16 +2,17 @@
#include <coreinit/debug.h>
#define EXPORT(name) void* addr_##name
#include "../rpl/libcoreinit/exports.h"
#include "../rpl/libnsysnet/exports.h"
#include "../rpl/libgx2/exports.h"
#include "../rpl/libproc_ui/exports.h"
#include "../rpl/libsndcore2/exports.h"
#include "../rpl/libsysapp/exports.h"
#include "../rpl/libvpad/exports.h"
#define EXPORT_BEGIN(lib)
#define EXPORT_END()
#include "exports/all.h"
#undef EXPORT
#define EXPORT(name) do{if(OSDynLoad_FindExport(handle, 0, #name, &addr_##name) < 0)OSFatal("Function " # name " is NULL");} while(0)
#undef EXPORT_BEGIN
#undef EXPORT_END
#define EXPORT(name) do{if(OSDynLoad_FindExport(handle, 0, #name, &addr_##name) < 0)OSFatal("Function " # name " is NULL");} while(0)
#define EXPORT_BEGIN(lib) OSDynLoad_Acquire(#lib, &handle)
#define EXPORT_END() OSDynLoad_Release(handle)
void InitFunctionPointers(void)
{
@ -19,33 +20,6 @@ void InitFunctionPointers(void)
addr_OSDynLoad_Acquire = *(void**)0x00801500;
addr_OSDynLoad_FindExport = *(void**)0x00801504;
OSDynLoad_Acquire("coreinit.rpl", &handle);
OSDynLoad_FindExport(handle, 0, "OSFatal", &addr_OSFatal);
#include "../rpl/libcoreinit/exports.h"
OSDynLoad_Release(handle);
OSDynLoad_Acquire("nsysnet.rpl", &handle);
#include "../rpl/libnsysnet/exports.h"
OSDynLoad_Release(handle);
OSDynLoad_Acquire("gx2.rpl", &handle);
#include "../rpl/libgx2/exports.h"
OSDynLoad_Release(handle);
OSDynLoad_Acquire("proc_ui.rpl", &handle);
#include "../rpl/libproc_ui/exports.h"
OSDynLoad_Release(handle);
OSDynLoad_Acquire("sndcore2.rpl", &handle);
#include "../rpl/libsndcore2/exports.h"
OSDynLoad_Release(handle);
OSDynLoad_Acquire("sysapp.rpl", &handle);
#include "../rpl/libsysapp/exports.h"
OSDynLoad_Release(handle);
OSDynLoad_Acquire("vpad.rpl", &handle);
#include "../rpl/libvpad/exports.h"
OSDynLoad_Release(handle);
#include "exports/all.h"
}

View File

@ -1,5 +1,6 @@
/* source: https://github.com/QuarkTheAwesome/URetro */
#include <coreinit/thread.h>
#include <coreinit/exception.h>
#include <coreinit/debug.h>
#include <coreinit/dynload.h>
@ -39,8 +40,10 @@ unsigned char exception_handler(void* contextIn) {
DisassemblePPCRange((void*)context[38]-0x18, (void*)context[38]+0x4, (void*)exception_disassembly_helper, 0, 0);
char buf[2048];
__os_snprintf(buf, 2048, "SP:%08X LR:%08X PC:%08X CR:%08X CTR:%08X\nXER:%08X SR0:%08X SR1:%08X EX0:%08X EX1:%08X\nr0:%08X r2:%08X r3:%08X r4:%08X r5:%08X\nr6:%08X r7:%08X r8:%08X r9:%08X r10:%08X\nr11:%08X r12:%08X r13:%08X r14:%08X r15:%08X\nr16:%08X r17:%08X r18:%08X r19:%08X r20:%08X\nr21:%08X r22:%08X r23:%08X r24:%08X r25:%08X\nr26:%08X r27:%08X r28:%08X r29:%08X r30:%08X\nr31:%08X\n%s", context[3], context[35], context[38], context[34], context[36], context[37], context[38], context[39], context[40], context[41], context[2], context[4], context[5], context[6], context[7], context[8], context[9], context[10], context[11], context[12], context[13], context[14], context[15], context[16], context[17], context[18], context[19], context[20], context[21], context[22], context[23], context[24], context[25], context[26], context[27], context[28], context[29], context[30], context[31], context[32], context[33], buf2);
void net_print(const char* str);
net_print(buf);
void net_print_exp(const char* str);
void log_deinit(void);
net_print_exp(buf);
log_deinit();
OSFatal(buf);
return 0;

View File

@ -2,8 +2,9 @@
#include <coreinit/thread.h>
#include <coreinit/exception.h>
#include <coreinit/debug.h>
#include <coreinit/internal.h>
#include "exception_handler.h"
#include "wiiu/wiiu_dbg.h"
#include "wiiu_dbg.h"
#define OS_EXCEPTION_MODE_GLOBAL_ALL_CORES 4
@ -14,160 +15,197 @@
/* Exceptions */
typedef struct OSContext_
{
/* OSContext identifier */
uint32_t tag1;
uint32_t tag2;
/* OSContext identifier */
uint32_t tag1;
uint32_t tag2;
/* GPRs */
uint32_t gpr[32];
/* GPRs */
uint32_t gpr[32];
/* Special registers */
uint32_t cr;
uint32_t lr;
uint32_t ctr;
uint32_t xer;
/* Special registers */
uint32_t cr;
uint32_t lr;
uint32_t ctr;
uint32_t xer;
/* Initial PC and MSR */
uint32_t srr0;
uint32_t srr1;
/* Initial PC and MSR */
uint32_t srr0;
uint32_t srr1;
/* Only valid during DSI exception */
uint32_t exception_specific0;
uint32_t exception_specific1;
/* Only valid during DSI exception */
uint32_t exception_specific0;
uint32_t exception_specific1;
/* There is actually a lot more here but we don't need the rest*/
/* There is actually a lot more here but we don't need the rest*/
} OSContext_;
#define CPU_STACK_TRACE_DEPTH 10
#define __stringify(rn) #rn
#define CPU_STACK_TRACE_DEPTH 10
#define __stringify(rn) #rn
#define mfspr(_rn) \
({ register uint32_t _rval = 0; \
asm volatile("mfspr %0," __stringify(_rn) \
: "=r" (_rval));\
_rval; \
({ register uint32_t _rval = 0; \
asm volatile("mfspr %0," __stringify(_rn) \
: "=r" (_rval));\
_rval; \
})
typedef struct _framerec {
struct _framerec *up;
void *lr;
typedef struct _framerec
{
struct _framerec* up;
void* lr;
} frame_rec, *frame_rec_t;
static const char *exception_names[] = {
"DSI",
"ISI",
"PROGRAM"
static const char* exception_names[] =
{
"DSI",
"ISI",
"PROGRAM"
};
static const char exception_print_formats[18][45] = {
"Exception type %s occurred!\n", // 0
"GPR00 %08X GPR08 %08X GPR16 %08X GPR24 %08X\n", // 1
"GPR01 %08X GPR09 %08X GPR17 %08X GPR25 %08X\n", // 2
"GPR02 %08X GPR10 %08X GPR18 %08X GPR26 %08X\n", // 3
"GPR03 %08X GPR11 %08X GPR19 %08X GPR27 %08X\n", // 4
"GPR04 %08X GPR12 %08X GPR20 %08X GPR28 %08X\n", // 5
"GPR05 %08X GPR13 %08X GPR21 %08X GPR29 %08X\n", // 6
"GPR06 %08X GPR14 %08X GPR22 %08X GPR30 %08X\n", // 7
"GPR07 %08X GPR15 %08X GPR23 %08X GPR31 %08X\n", // 8
"LR %08X SRR0 %08x SRR1 %08x\n", // 9
"DAR %08X DSISR %08X\n", // 10
"STACK DUMP:", // 11
" --> ", // 12
" -->\n", // 13
"\n", // 14
"%p", // 15
"\nCODE DUMP:\n", // 16
"%p: %08X %08X %08X %08X\n", // 17
static const char exception_print_formats[18][45] =
{
"Exception type %s occurred!\n", // 0
"GPR00 %08X GPR08 %08X GPR16 %08X GPR24 %08X\n", // 1
"GPR01 %08X GPR09 %08X GPR17 %08X GPR25 %08X\n", // 2
"GPR02 %08X GPR10 %08X GPR18 %08X GPR26 %08X\n", // 3
"GPR03 %08X GPR11 %08X GPR19 %08X GPR27 %08X\n", // 4
"GPR04 %08X GPR12 %08X GPR20 %08X GPR28 %08X\n", // 5
"GPR05 %08X GPR13 %08X GPR21 %08X GPR29 %08X\n", // 6
"GPR06 %08X GPR14 %08X GPR22 %08X GPR30 %08X\n", // 7
"GPR07 %08X GPR15 %08X GPR23 %08X GPR31 %08X\n", // 8
"LR %08X SRR0 %08x SRR1 %08x\n", // 9
"DAR %08X DSISR %08X\n", // 10
"STACK DUMP:", // 11
" --> ", // 12
" -->\n", // 13
"\n", // 14
"%p", // 15
"\nCODE DUMP:\n", // 16
"%p: %08X %08X %08X %08X\n", // 17
};
void net_print_exp(const char* str);
void log_deinit(void);
static unsigned char exception_cb(void * c, unsigned char exception_type) {
char buf[4096];
int pos = 0;
static unsigned char exception_cb(void* c, unsigned char exception_type)
{
char gdb_buf[512];
char* gdb_buf_ptr = gdb_buf;
char buf[4096];
int pos = 0;
OSContext_ *context = (OSContext_ *) c;
/*
* This part is mostly from libogc. Thanks to the devs over there.
*/
pos += sprintf(buf + pos, exception_print_formats[0], exception_names[exception_type]);
pos += sprintf(buf + pos, exception_print_formats[1], context->gpr[0], context->gpr[8], context->gpr[16], context->gpr[24]);
pos += sprintf(buf + pos, exception_print_formats[2], context->gpr[1], context->gpr[9], context->gpr[17], context->gpr[25]);
pos += sprintf(buf + pos, exception_print_formats[3], context->gpr[2], context->gpr[10], context->gpr[18], context->gpr[26]);
pos += sprintf(buf + pos, exception_print_formats[4], context->gpr[3], context->gpr[11], context->gpr[19], context->gpr[27]);
pos += sprintf(buf + pos, exception_print_formats[5], context->gpr[4], context->gpr[12], context->gpr[20], context->gpr[28]);
pos += sprintf(buf + pos, exception_print_formats[6], context->gpr[5], context->gpr[13], context->gpr[21], context->gpr[29]);
pos += sprintf(buf + pos, exception_print_formats[7], context->gpr[6], context->gpr[14], context->gpr[22], context->gpr[30]);
pos += sprintf(buf + pos, exception_print_formats[8], context->gpr[7], context->gpr[15], context->gpr[23], context->gpr[31]);
pos += sprintf(buf + pos, exception_print_formats[9], context->lr, context->srr0, context->srr1);
OSContext_ *context = (OSContext_*) c;
/*
* This part is mostly from libogc. Thanks to the devs over there.
*/
pos += sprintf(buf + pos, exception_print_formats[0], exception_names[exception_type]);
pos += sprintf(buf + pos, exception_print_formats[1], context->gpr[0], context->gpr[8], context->gpr[16],
context->gpr[24]);
pos += sprintf(buf + pos, exception_print_formats[2], context->gpr[1], context->gpr[9], context->gpr[17],
context->gpr[25]);
pos += sprintf(buf + pos, exception_print_formats[3], context->gpr[2], context->gpr[10], context->gpr[18],
context->gpr[26]);
pos += sprintf(buf + pos, exception_print_formats[4], context->gpr[3], context->gpr[11], context->gpr[19],
context->gpr[27]);
pos += sprintf(buf + pos, exception_print_formats[5], context->gpr[4], context->gpr[12], context->gpr[20],
context->gpr[28]);
pos += sprintf(buf + pos, exception_print_formats[6], context->gpr[5], context->gpr[13], context->gpr[21],
context->gpr[29]);
pos += sprintf(buf + pos, exception_print_formats[7], context->gpr[6], context->gpr[14], context->gpr[22],
context->gpr[30]);
pos += sprintf(buf + pos, exception_print_formats[8], context->gpr[7], context->gpr[15], context->gpr[23],
context->gpr[31]);
pos += sprintf(buf + pos, exception_print_formats[9], context->lr, context->srr0, context->srr1);
//if(exception_type == OS_EXCEPTION_DSI) {
pos += sprintf(buf + pos, exception_print_formats[10], context->exception_specific1, context->exception_specific0); // this freezes
//}
//if(exception_type == OS_EXCEPTION_DSI) {
pos += sprintf(buf + pos, exception_print_formats[10], context->exception_specific1,
context->exception_specific0); // this freezes
//}
void *pc = (void*)context->srr0;
void *lr = (void*)context->lr;
void *r1 = (void*)context->gpr[1];
register uint32_t i = 0;
register frame_rec_t l,p = (frame_rec_t)lr;
void* pc = (void*)context->srr0;
void* lr = (void*)context->lr;
void* r1 = (void*)context->gpr[1];
register uint32_t i = 0;
register frame_rec_t l, p = (frame_rec_t)lr;
l = p;
p = r1;
if(!p)
asm volatile("mr %0,%%r1" : "=r"(p));
l = p;
p = r1;
pos += sprintf(buf + pos, exception_print_formats[11]);
if (!p)
asm volatile("mr %0,%%r1" : "=r"(p));
for(i = 0; i < CPU_STACK_TRACE_DEPTH-1 && p->up; p = p->up, i++) {
if(i % 4)
pos += sprintf(buf + pos, exception_print_formats[12]);
else {
if(i > 0)
pos += sprintf(buf + pos, exception_print_formats[13]);
else
pos += sprintf(buf + pos, exception_print_formats[14]);
}
pos += sprintf(buf + pos, exception_print_formats[11]);
switch(i) {
case 0:
if(pc)
pos += sprintf(buf + pos, exception_print_formats[15],pc);
break;
case 1:
if(!l)
l = (frame_rec_t)mfspr(8);
pos += sprintf(buf + pos, exception_print_formats[15],(void*)l);
break;
default:
pos += sprintf(buf + pos, exception_print_formats[15],(void*)(p->up->lr));
break;
}
}
for (i = 0; i < CPU_STACK_TRACE_DEPTH - 1 && p->up; p = p->up, i++)
{
if (i % 4)
pos += sprintf(buf + pos, exception_print_formats[12]);
else
{
if (i > 0)
pos += sprintf(buf + pos, exception_print_formats[13]);
else
pos += sprintf(buf + pos, exception_print_formats[14]);
}
//if(exception_type == OS_EXCEPTION_DSI) {
uint32_t *pAdd = (uint32_t*)context->srr0;
pos += sprintf(buf + pos, exception_print_formats[16]);
// TODO by Dimok: this was actually be 3 instead of 2 lines in libogc .... but there is just no more space anymore on the screen
for (i = 0; i < 8; i += 4)
pos += sprintf(buf + pos, exception_print_formats[17], &(pAdd[i]),pAdd[i], pAdd[i+1], pAdd[i+2], pAdd[i+3]);
//}
void net_print(const char* str);
switch (i)
{
case 0:
if (pc)
{
pos += sprintf(buf + pos, exception_print_formats[15], pc);
gdb_buf_ptr += __os_snprintf(gdb_buf_ptr, &gdb_buf[sizeof(gdb_buf)] - gdb_buf_ptr, "info line *0x%08X\n", pc);
net_print(buf);
OSFatal(buf);
return 1;
}
break;
case 1:
if (!l)
l = (frame_rec_t)mfspr(8);
pos += sprintf(buf + pos, exception_print_formats[15], (void*)l);
gdb_buf_ptr += __os_snprintf(gdb_buf_ptr, &gdb_buf[sizeof(gdb_buf)] - gdb_buf_ptr, "info line *0x%08X\n", l);
break;
default:
pos += sprintf(buf + pos, exception_print_formats[15], (void*)(p->up->lr));
gdb_buf_ptr += __os_snprintf(gdb_buf_ptr, &gdb_buf[sizeof(gdb_buf)] - gdb_buf_ptr, "info line *0x%08X\n", p->up->lr);
break;
}
}
//if(exception_type == OS_EXCEPTION_DSI) {
uint32_t* pAdd = (uint32_t*)context->srr0;
pos += sprintf(buf + pos, exception_print_formats[16]);
// TODO by Dimok: this was actually be 3 instead of 2 lines in libogc .... but there is just no more space anymore on the screen
for (i = 0; i < 8; i += 4)
pos += sprintf(buf + pos, exception_print_formats[17], &(pAdd[i]), pAdd[i], pAdd[i + 1], pAdd[i + 2], pAdd[i + 3]);
//}
net_print_exp(gdb_buf);
// net_print_exp(buf);
log_deinit();
OSFatal(buf);
return 1;
}
static unsigned char dsi_exception_cb(void * context) {
return exception_cb(context, 0);
static unsigned char dsi_exception_cb(void* context)
{
return exception_cb(context, 0);
}
static unsigned char isi_exception_cb(void * context) {
return exception_cb(context, 1);
static unsigned char isi_exception_cb(void* context)
{
return exception_cb(context, 1);
}
static unsigned char program_exception_cb(void * context) {
return exception_cb(context, 2);
static unsigned char program_exception_cb(void* context)
{
return exception_cb(context, 2);
}
void setup_os_exceptions(void) {
OSSetExceptionCallback(OS_EXCEPTION_DSI, (OSExceptionCallbackFn)&dsi_exception_cb);
OSSetExceptionCallback(OS_EXCEPTION_ISI, (OSExceptionCallbackFn)&isi_exception_cb);
OSSetExceptionCallback(OS_EXCEPTION_PROGRAM, (OSExceptionCallbackFn)&program_exception_cb);
void setup_os_exceptions(void)
{
OSSetExceptionCallback(OS_EXCEPTION_DSI, (OSExceptionCallbackFn)&dsi_exception_cb);
OSSetExceptionCallback(OS_EXCEPTION_ISI, (OSExceptionCallbackFn)&isi_exception_cb);
OSSetExceptionCallback(OS_EXCEPTION_PROGRAM, (OSExceptionCallbackFn)&program_exception_cb);
}

View File

@ -0,0 +1,8 @@
#include "libcoreinit.h"
#include "libnsysnet.h"
#include "libgx2.h"
#include "libproc_ui.h"
#include "libsndcore2.h"
#include "libsysapp.h"
#include "libvpad.h"

View File

@ -0,0 +1,7 @@
EXPORT_BEGIN(coreinit.rpl);
/* OSFatal should preferably be put first in the list */
#include "../rpl/libcoreinit/exports.h"
EXPORT_END();

View File

@ -0,0 +1,6 @@
EXPORT_BEGIN(gx2.rpl);
#include "../rpl/libgx2/exports.h"
EXPORT_END();

View File

@ -0,0 +1,6 @@
EXPORT_BEGIN(nsysnet.rpl);
#include "../rpl/libnsysnet/exports.h"
EXPORT_END();

View File

@ -0,0 +1,6 @@
EXPORT_BEGIN(proc_ui.rpl);
#include "../rpl/libproc_ui/exports.h"
EXPORT_END();

View File

@ -0,0 +1,6 @@
EXPORT_BEGIN(sndcore2.rpl);
#include "../rpl/libsndcore2/exports.h"
EXPORT_END();

View File

@ -0,0 +1,6 @@
EXPORT_BEGIN(sysapp.rpl);
#include "../rpl/libsysapp/exports.h"
EXPORT_END();

View File

@ -0,0 +1,6 @@
EXPORT_BEGIN(vpad.rpl);
#include "../rpl/libvpad/exports.h"
EXPORT_END();

188
wiiu/tex_shader.c Normal file
View File

@ -0,0 +1,188 @@
#include <stddef.h>
#include <malloc.h>
#include <string.h>
#include "tex_shader.h"
#include "gx2_shader_inl.h"
/*******************************************************
*******************************************************
*
* Vertex Shader GLSL source:
*
*******************************************************
*******************************************************
*
* attribute vec2 position;
* attribute vec2 tex_coord_in;
* varying vec2 tex_coord;
* void main()
* {
* gl_Position = vec4(position, 0.0, 1.0);
* tex_coord = tex_coord_in;
* }
*
******************************************************
******************************************************
*
* assembly output from AMD's GPU ShaderAnalyzer :
*
******************************************************
******************************************************
*
* 00 CALL_FS NO_BARRIER
* 01 ALU: ADDR(32) CNT(5)
* 0 x: MOV R2.x, R2.x
* y: MOV R2.y, R2.y
* z: MOV R1.z, 0.0f
* w: MOV R1.w, (0x3F800000, 1.0f).x
* 02 EXP_DONE: POS0, R1
* 03 EXP_DONE: PARAM0, R2.xyzz NO_BARRIER
* END_OF_PROGRAM
*
******************************************************
******************************************************
*/
__attribute__((aligned(GX2_SHADER_ALIGNMENT)))
static struct
{
u32 cf[32 * 2]; /* first ADDR() * 2 */
u32 alu[5 * 2]; /* CNT() sum * 2 */
} vs_program =
{
{
CALL_FS NO_BARRIER,
ALU(32, 5),
EXP_DONE(POS0, _R1, _X, _Y, _Z, _W),
EXP_DONE(PARAM0, _R2, _X, _Y, _Z, _Z) NO_BARRIER
END_OF_PROGRAM
},
{
ALU_MOV(_R2, _X, _R2, _X),
ALU_MOV(_R2, _Y, _R2, _Y),
ALU_MOV(_R1, _Z, ALU_SRC_0, _X),
ALU_LAST ALU_MOV(_R1, _W, ALU_SRC_LITERAL, _X), ALU_LITERAL(0x3F800000)
}
};
/*******************************************************
*******************************************************
*
* Pixel Shader GLSL source:
*
*******************************************************
*******************************************************
*
* varying vec2 tex_coord;
* uniform sampler2D s;
* void main()
* {
* gl_FragColor = texture2D(s, tex_coord);
* }
*
******************************************************
******************************************************
*
* assembly output from AMD's GPU ShaderAnalyzer :
*
******************************************************
******************************************************
*
* 00 TEX: ADDR(16) CNT(1) VALID_PIX
* 0 SAMPLE R0, R0.xy0x, t0, s0
* 01 EXP_DONE: PIX0, R0
* END_OF_PROGRAM
*
*******************************************************
*******************************************************
*/
__attribute__((aligned(GX2_SHADER_ALIGNMENT)))
static struct
{
u32 cf[16 * 2]; /* first ADDR() * 2 */
u32 tex[1 * 3]; /* CNT() sum * 3 */
} ps_program =
{
{
TEX(16, 1) VALID_PIX,
EXP_DONE(PIX0, _R0, _X, _Y, _Z, _W)
END_OF_PROGRAM
},
{
TEX_SAMPLE(_R0, _X, _Y, _Z, _W, _R0, _X, _Y, _0, _X, _t0, _s0)
}
};
tex_shader_t tex_shader =
{
{
{
0x00000103, 0x00000000, 0x00000000, 0x00000001, /* sq_pgm_resources_vs, vgt_primitiveid_en, spi_vs_out_config, num_spi_vs_out_id */
{ 0xffffff00, _x9(0xffffffff) }, /* spi_vs_out_id @10 */
0x00000000, 0xfffffffc, 0x00000002, /* pa_cl_vs_out_cntl, sq_vtx_semantic_clear, num_sq_vtx_semantic */
{
0x00000000, 0x00000001, _x30(0x000000ff) /* sq_vtx_semantic @32 */
},
0x00000000, 0x0000000e, 0x00000010 /* vgt_strmout_buffer_en, vgt_vertex_reuse_block_cntl, vgt_hos_reuse_depth */
}, /* regs */
sizeof(vs_program), /* size */
(uint8_t*)&vs_program, /* program */
GX2_SHADER_MODE_UNIFORM_REGISTER, /* mode */
0, /* uniformBlockCount */
NULL, /* uniformBlocks */
0, /* uniformVarCount */
NULL, /* uniformVars */
0, /* initialValueCount */
NULL, /* initialValues */
0, /* loopVarCount */
NULL, /* loopVars */
0, /* samplerVarCount */
NULL, /* samplerVars */
sizeof(tex_shader.attributes) / sizeof(GX2AttribVar), /* attribVarCount */
(GX2AttribVar*) &tex_shader.attributes, /* attribVars */
0, /* ringItemsize */
FALSE, /* hasStreamOut */
{0}, /* streamOutStride @4 */
{} /* gx2rBuffer */
},
{
{
0x00000001, 0x00000002, 0x14000001, 0x00000000, /* sq_pgm_resources_ps, sq_pgm_exports_ps, spi_ps_in_control_0, spi_ps_in_control_1 */
0x00000001, /* num_spi_ps_input_cntl */
{ 0x00000100, _x30(0x00000000)}, /* spi_ps_input_cntls @ 32*/
0x0000000f, 0x00000001, 0x00000010, 0x00000000 /* cb_shader_mask, cb_shader_control, db_shader_control, spi_input_z */
}, /* regs */
sizeof(ps_program), /* size */
(uint8_t*)&ps_program, /* program */
GX2_SHADER_MODE_UNIFORM_REGISTER, /* mode */
0, /* uniformBlockCount */
NULL, /* uniformBlocks */
0, /* uniformVarCount */
NULL, /* uniformVars */
0, /* initialValueCount */
NULL, /* initialValues */
0, /* loopVarCount */
NULL, /* loopVars */
1, /* samplerVarCount */
(GX2SamplerVar*) &tex_shader.sampler, /* samplerVars */
{} /* gx2rBuffer */
},
{ "s", GX2_SAMPLER_VAR_TYPE_SAMPLER_2D, 0 },
{
{ "position", GX2_SHADER_VAR_TYPE_FLOAT2, 0, 0},
{ "tex_coord_in", GX2_SHADER_VAR_TYPE_FLOAT2, 0, 1}
},
{
{
0, 0, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32,
GX2_ATTRIB_INDEX_PER_VERTEX, 0, GX2_COMP_SEL(_X, _Y, _0, _1), GX2_ENDIAN_SWAP_DEFAULT
},
{
1, 1, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32,
GX2_ATTRIB_INDEX_PER_VERTEX, 0, GX2_COMP_SEL(_X, _Y, _0, _1), GX2_ENDIAN_SWAP_DEFAULT
}
},
{},
};

34
wiiu/tex_shader.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef TEX_SHADER_H
#define TEX_SHADER_H
#include <gx2.h>
#include "system/memory.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct __attribute__((aligned(GX2_VERTEX_BUFFER_ALIGNMENT)))
{
GX2VertexShader vs;
GX2PixelShader ps;
GX2SamplerVar sampler;
struct
{
GX2AttribVar position;
GX2AttribVar tex_coord;
} attributes;
struct
{
GX2AttribStream position;
GX2AttribStream tex_coord;
} attribute_stream;
GX2FetchShader fs;
}tex_shader_t;
extern tex_shader_t tex_shader;
#ifdef __cplusplus
}
#endif
#endif // TEX_SHADER_H

View File

@ -1,43 +0,0 @@
#!/usr/bin/python
import os, sys, zlib, socket, struct
#ip = os.getenv("WIILOAD")
ip = "tcp:10.42.0.170"
assert ip.startswith("tcp:")
wii_ip = (ip[4:], 4299)
filename = sys.argv[1]
WIILOAD_VERSION_MAJOR=0
WIILOAD_VERSION_MINOR=5
len_uncompressed = os.path.getsize(filename)
c_data = zlib.compress(open(filename).read(), 6)
chunk_size = 1024*128
chunks = [c_data[i:i+chunk_size] for i in range(0, len(c_data), chunk_size)]
args = [os.path.basename(filename)]+sys.argv[2:]
args = "\x00".join(args) + "\x00"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(wii_ip)
s.send("HAXX")
s.send(struct.pack("B", WIILOAD_VERSION_MAJOR)) # one byte, unsigned
s.send(struct.pack("B", WIILOAD_VERSION_MINOR)) # one byte, unsigned
s.send(struct.pack(">H",len(args))) # bigendian, 2 bytes, unsigned
s.send(struct.pack(">L",len(c_data))) # bigendian, 4 bytes, unsigned
s.send(struct.pack(">L",len_uncompressed)) # bigendian, 4 bytes, unsigned
print len(chunks),"chunks to send"
for piece in chunks:
s.send(piece)
sys.stdout.write("."); sys.stdout.flush()
sys.stdout.write("\n")
s.send(args)
s.close()
print "done"

View File

@ -17,10 +17,11 @@ extern "C" {
#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_INT(X) printf( "%-20s: %10i\n", #X, (s32)(X))
#define DEBUG_FLOAT(X) printf( "%-20s: %10.3f\n", #X, (float)(X))
#define DEBUG_VAR64(X) printf( #X"\r\t\t\t\t : 0x%016llX\n", (u64)(X))
//#define DEBUG_ERROR(X) do{if(X)dump_result_value(X);}while(0)
#define PRINTFPOS(X,Y) "\x1b["#X";"#Y"H"
#define PRINTFPOS_STR(X,Y) "\x1b["X";"Y"H"
#define PRINTF_LINE(X) "\x1b["X";0H"
#define PRINTFPOS_STR(X,Y) "\x1b[" X ";" Y "H"
#define PRINTF_LINE(X) "\x1b[" X ";0H"
#endif // WIIU_DBG_H